Skip to content

Commit

Permalink
Merge branch 'develop' into rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrthomas committed Oct 10, 2020
2 parents d99e5a4 + 038802f commit ceaefcd
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,11 @@
import com.intuit.karate.Config;
import com.intuit.karate.FileUtils;
import com.intuit.karate.core.ScenarioContext;
import org.apache.http.conn.ssl.LenientSslConnectionSocketFactory;

import static com.intuit.karate.http.Cookie.*;

import com.intuit.karate.http.HttpClient;
import com.intuit.karate.http.HttpRequest;
import com.intuit.karate.http.HttpResponse;
import com.intuit.karate.http.HttpUtils;
import com.intuit.karate.http.MultiPartItem;
import com.intuit.karate.http.MultiValuedMap;
import java.io.IOException;

import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import javax.net.ssl.SSLContext;

import com.intuit.karate.http.*;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CookieStore;
Expand All @@ -67,22 +41,28 @@
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.*;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.Map.Entry;

import static com.intuit.karate.http.Cookie.*;

/**
* @author pthomas3
*/
Expand Down Expand Up @@ -269,6 +249,15 @@ protected void buildCookie(com.intuit.karate.http.Cookie c) {
case PATH:
cookie.setPath(entry.getValue());
break;
case EXPIRES: // add expires field for cookie.
try {
cookie.setExpiryDate(Date.from(ZonedDateTime.parse(entry.getValue(), DTFMTR_RFC1123).toInstant()));
}
catch ( DateTimeParseException ex)
{
System.err.println("ex ->" + ex.getLocalizedMessage());
}
break;
}
}
if (cookie.getDomain() == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.intuit.karate.http.apache;

import com.intuit.karate.CallContext;
import com.intuit.karate.Config;
import com.intuit.karate.core.FeatureContext;
import com.intuit.karate.core.ScenarioContext;
import com.intuit.karate.http.Cookie;
import org.apache.http.client.CookieStore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.time.ZonedDateTime;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.intuit.karate.http.Cookie.*;
import static com.intuit.karate.http.HttpClient.construct;
import static org.junit.Assert.assertEquals;

public class ApacheHttpClientTest {

private static final Logger logger = LoggerFactory.getLogger(ApacheHttpClientTest.class);

private ScenarioContext getContext() {
FeatureContext featureContext = FeatureContext.forEnv();
CallContext callContext = new CallContext(null, true);
return new ScenarioContext(featureContext, callContext, null, null);
}

private Config getConfig() {
return new Config();
}

private Map<String, String> getCookieMapWithExpiredDate() {
ZonedDateTime currentDate = ZonedDateTime.now();
Map<String, String> cookieMap = new LinkedHashMap<>();
cookieMap.put(NAME, "testCookie");
cookieMap.put(VALUE, "tck");
cookieMap.put(DOMAIN, ".com");
cookieMap.put(PATH, "/");
cookieMap.put(EXPIRES,currentDate.minusDays(1).format(DTFMTR_RFC1123));
return cookieMap;
}

private Map<String, String> getCookieMapWithNonExpiredDate() {
ZonedDateTime currentDate = ZonedDateTime.now();
Map<String, String> cookieMap = new LinkedHashMap<>();
cookieMap.put(NAME, "testCookie");
cookieMap.put(VALUE, "tck");
cookieMap.put(DOMAIN, ".com");
cookieMap.put(PATH, "/");
cookieMap.put(EXPIRES, currentDate.plusDays(1).format(DTFMTR_RFC1123));
return cookieMap;
}

@Test
public void testExpiredCookieIsRemoved() throws NoSuchFieldException, IllegalAccessException {
com.intuit.karate.http.Cookie c = new Cookie(getCookieMapWithExpiredDate());
ApacheHttpClient httpClient = (ApacheHttpClient) construct(getConfig(), getContext());
httpClient.buildCookie(c);

Field cookieStoreField = httpClient.getClass().getDeclaredField("cookieStore");
cookieStoreField.setAccessible(true);
CookieStore fieldValue = (CookieStore) cookieStoreField.get(httpClient);
assertEquals(0, fieldValue.getCookies().size());
}

@Test
public void testNonExpiredCookieIsPersisted() throws NoSuchFieldException, IllegalAccessException {
com.intuit.karate.http.Cookie c = new Cookie(getCookieMapWithNonExpiredDate());
ApacheHttpClient httpClient = (ApacheHttpClient) construct(getConfig(), getContext());
httpClient.buildCookie(c);

Field cookieStoreField = httpClient.getClass().getDeclaredField("cookieStore");
cookieStoreField.setAccessible(true);
CookieStore fieldValue = (CookieStore) cookieStoreField.get(httpClient);
assertEquals(1, fieldValue.getCookies().size());
}
}


3 changes: 3 additions & 0 deletions karate-apache/src/test/resources/karate-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function fn() {
return { someConfig: 'someValue' }
}
2 changes: 2 additions & 0 deletions karate-apache/src/test/resources/karate-http.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
client.class=com.intuit.karate.http.apache.ApacheHttpClient

34 changes: 27 additions & 7 deletions karate-core/src/main/java/com/intuit/karate/http/Cookie.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
*/
package com.intuit.karate.http;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.*;

/**
*
Expand All @@ -44,7 +46,10 @@ public class Cookie extends LinkedHashMap<String, String> {
public static final String MAX_AGE = "max-age";
public static final String SECURE = "secure";
public static final String PERSISTENT = "persistent";
public static final String HTTP_ONLY = "http-only";
public static final String HTTP_ONLY = "http-only";
public static final DateTimeFormatter DT_FMT_V1 = DateTimeFormatter.ofPattern("EEE, dd-MMM-yy HH:mm:ss z");
public static final DateTimeFormatter DT_FMT_V2 = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss z");
public static final DateTimeFormatter DTFMTR_RFC1123 = new DateTimeFormatterBuilder().appendOptional(DT_FMT_V1).appendOptional(DT_FMT_V2).toFormatter();

// cookies can be a map of maps, so some extra processing
public static List<Cookie> toCookies(Map<String, Object> map) {
Expand Down Expand Up @@ -82,6 +87,21 @@ public String getName() {

public String getValue() {
return get(VALUE);
}
}

public boolean isCookieExpired()
{
String exprDat = get(EXPIRES);
Date expires = null;
if ( null != exprDat) {
try {
expires = Date.from(ZonedDateTime.parse(get(EXPIRES), DTFMTR_RFC1123).toInstant());
} catch (DateTimeParseException ex) {
System.err.println("ex ->" + ex.getLocalizedMessage());
}
}
return null != expires && !expires.after(new Date());

}

}
64 changes: 57 additions & 7 deletions karate-demo/src/test/java/demo/cookies/cookies.feature
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@ Scenario: one cookie, and it is sent automatically in the next request
Then status 200
And match response == '#[1]'
And match response[0] contains { name: 'foo', value: 'bar' }

Given path 'search', 'cookies'
And request {}
When method post
Then status 200
And match response == '#[1]'
And match response[0] contains { name: 'foo', value: 'bar' }
And match response[0] contains { name: 'foo', value: 'bar' }

* print 'cookies: ', responseCookies

# reset cookies
* configure cookies = null
Given path 'search', 'cookies'
Given path 'search', 'cookies'
When method get
Then status 200
And match response == []

# modify cookies
Given path 'search', 'cookies'
Given path 'search', 'cookies'
And cookie foo = 'blah'
And request {}
When method post
Expand All @@ -43,15 +43,65 @@ Scenario: one cookie, and it is sent automatically in the next request

Scenario: cookie as json
Given path 'search', 'cookies'
And cookie foo = { value: 'bar' }
And cookie foo = { value: 'bar' }
When method get
Then status 200
And match response[0] contains { name: 'foo', value: 'bar' }

Scenario: cookie returned has dots in the domain which violates RFC 2109
Given path 'search', 'cookies'
And cookie foo = { value: 'bar' }
And cookie foo = { value: 'bar' }
And param domain = '.abc.com'
When method get
Then status 200
And match response[0] contains { name: 'foo', value: 'bar', domain: '.abc.com' }

Scenario: cookie returned has dots in the domain which violates RFC 2109
Given path 'search', 'cookies'
And cookie foo = { value: 'bar' }
And param domain = '.abc.com'
When method get
Then status 200
And match response[0] contains { name: 'foo', value: 'bar', domain: '.abc.com' }

@mock-servlet-todo
Scenario: expired cookie is not in response
* def prevDate =
"""
function() {
var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
var Calendar = Java.type('java.util.Calendar');
var currCalIns = Calendar.getInstance();
currCalIns.add(java.util.Calendar.DATE, -1);
var sdf = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z");
return sdf.format(currCalIns.getTime());
}
"""
* def date = prevDate()
Given path 'search', 'cookies'
And cookie foo = {value:'bar', expires: '#(date)'}
And param domain = '.abcdfdf.com'
When method get
Then status 200
And match response == []

@mock-servlet-todo
Scenario: non-expired cookie is in response
* def futureDate =
"""
function() {
var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
var Calendar = Java.type('java.util.Calendar');
var currCalIns = Calendar.getInstance();
currCalIns.add(java.util.Calendar.DATE, +1);
var sdf = new SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z");
return sdf.format(currCalIns.getTime());
}
"""
* def date = futureDate()
Given path 'search', 'cookies'
And cookie foo = {value:'bar', expires:'#(date)', path:'/search'}
And param domain = '.abc.com'
When method get
Then status 200
And match response[0] contains { name: 'foo', value: 'bar', domain: '.abc.com' }
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.List;
import java.util.Map.Entry;
import javax.net.ssl.HttpsURLConnection;
Expand All @@ -59,6 +63,7 @@
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.media.multipart.file.StreamDataBodyPart;
import org.glassfish.jersey.message.internal.StringBuilderUtils;

/**
*
Expand Down Expand Up @@ -144,8 +149,12 @@ public void buildHeader(String name, Object value, boolean replace) {

@Override
public void buildCookie(com.intuit.karate.http.Cookie c) {
Cookie cookie = new Cookie(c.getName(), c.getValue());
builder.cookie(cookie);
// only add the cookie from request, if it isnt already expired.
if ( !c.isCookieExpired() )
{
Cookie cookie = new Cookie(c.getName(), c.getValue());
builder.cookie(cookie);
}
}

private MediaType getMediaType(String mediaType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ protected void buildParam(String name, Object... values) {
for (Object o : values) {
list.add(o == null ? null : o.toString());
}
requestBuilder.param(name, list.toArray(new String[]{}));
requestBuilder.queryParam(name, list.toArray(new String[]{}));
}

@Override
Expand Down
Loading

0 comments on commit ceaefcd

Please sign in to comment.