Skip to content

Commit

Permalink
Merge pull request #29 from mrmike/support-header-modifiers
Browse files Browse the repository at this point in the history
Add support header modifiers
  • Loading branch information
mrmike authored Feb 4, 2017
2 parents 943c89c + 98dd8f4 commit 21c20c1
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dependencies {
// snapshot version
compile 'com.github.mrmike:Ok2Curl:master-SNAPSHOT'
// or use specific version
compile 'com.github.mrmike:Ok2Curl:0.3.0'
compile 'com.github.mrmike:Ok2Curl:0.3.1'
}
```

Expand Down
2 changes: 1 addition & 1 deletion ok2curl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'java'
apply plugin: 'maven'

group='com.github.mrmike'
version='0.3.0'
version='0.3.1'

targetCompatibility = '1.7'
sourceCompatibility = '1.7'
Expand Down
23 changes: 20 additions & 3 deletions ok2curl/src/main/java/com/moczul/ok2curl/CurlBuilder.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.moczul.ok2curl;

import com.moczul.ok2curl.modifier.HeaderModifier;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

Expand Down Expand Up @@ -30,10 +33,10 @@ public class CurlBuilder {
private List<Header> headers = new LinkedList<>();

public CurlBuilder(Request request) {
this(request, -1L);
this(request, -1L, Collections.<HeaderModifier>emptyList());
}

public CurlBuilder(Request request, long limit) {
public CurlBuilder(Request request, long limit, List<HeaderModifier> headerModifiers) {
this.url = request.url().toString();
this.method = request.method();
final RequestBody body = request.body();
Expand All @@ -44,10 +47,24 @@ public CurlBuilder(Request request, long limit) {

final Headers headers = request.headers();
for (int i = 0; i < headers.size(); i++) {
this.headers.add(new Header(headers.name(i), headers.value(i)));
final Header header = new Header(headers.name(i), headers.value(i));
final Header modifiedHeader = modifyHeader(header, headerModifiers);
if (modifiedHeader != null) {
this.headers.add(modifiedHeader);
}
}
}

private Header modifyHeader(Header header, List<HeaderModifier> headerModifiers) {
for (HeaderModifier modifier : headerModifiers) {
if (modifier.matches(header)) {
return modifier.modify(header);
}
}

return header;
}

private String getContentType(RequestBody body) {
final MediaType mediaType = body.contentType();
if (mediaType != null) {
Expand Down
42 changes: 27 additions & 15 deletions ok2curl/src/main/java/com/moczul/ok2curl/CurlInterceptor.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
package com.moczul.ok2curl;

import com.moczul.ok2curl.logger.Loggable;
import com.moczul.ok2curl.modifier.HeaderModifier;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class CurlInterceptor implements Interceptor {

private static final String TAG = "Ok2Curl";
private static final long DEFAULT_LIMIT = 1024L * 1024L;

private final Loggable logger;
private final long limit;
private final List<HeaderModifier> headerModifiers = new ArrayList<>();

/**
* Interceptor responsible for printing curl logs
*
* Logs are pushed to stdout with 1MB limit
*
* @param logger output of logging
*/
public CurlInterceptor() {
this(new Loggable() {
@Override
public void log(String message) {
System.out.println(TAG + " " + message);
}
});
public CurlInterceptor(Loggable logger) {
this(logger, DEFAULT_LIMIT, Collections.<HeaderModifier>emptyList());
}

/**
* Interceptor responsible for printing curl logs
*
* Logs are pushed to stdout with 1MB limit
*
* @param logger output of logging
* @param headerModifiers list of header modifiers
*/
public CurlInterceptor(Loggable logger) {
this(logger, DEFAULT_LIMIT);
public CurlInterceptor(Loggable logger, List<HeaderModifier> headerModifiers) {
this(logger, DEFAULT_LIMIT, headerModifiers);
}

/**
Expand All @@ -47,16 +48,27 @@ public CurlInterceptor(Loggable logger) {
* @param limit limit maximal bytes logged, if negative - non limited
*/
public CurlInterceptor(Loggable logger, long limit) {
this(logger, limit, Collections.<HeaderModifier>emptyList());
}

/**
* Interceptor responsible for printing curl logs
* @param logger output of logging
* @param limit limit maximal bytes logged, if negative - non limited
* @param headerModifiers list of header modifiers
*/
public CurlInterceptor(Loggable logger, long limit, List<HeaderModifier> headerModifiers) {
this.logger = logger;
this.limit = limit;
this.headerModifiers.addAll(headerModifiers);
}

@Override
public Response intercept(Chain chain) throws IOException {
final Request request = chain.request();

final Request copy = request.newBuilder().build();
final String curl = new CurlBuilder(copy, limit).build();
final String curl = new CurlBuilder(copy, limit, headerModifiers).build();

logger.log(curl);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.moczul.ok2curl.modifier;

import com.moczul.ok2curl.Header;

/**
* HeaderModifier allow for changing header name/value before creating curl log
*/
public interface HeaderModifier {

/**
* @param header
* @return true if header should be modified and false otherwise.
*/
boolean matches(Header header);

/**
* @param header
* @return modified header or null to omit header in curl log
*/
Header modify(Header header);
}
2 changes: 2 additions & 0 deletions ok2curl/src/test/java/com/moczul/ok2curl/CurlBuilderTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.moczul.ok2curl;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.concurrent.TimeUnit;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.moczul.ok2curl.util;

import com.moczul.ok2curl.CurlBuilder;
import com.moczul.ok2curl.Header;
import com.moczul.ok2curl.modifier.HeaderModifier;

import org.junit.Test;

import java.util.Collections;
import java.util.List;

import okhttp3.Request;

import static junit.framework.Assert.assertEquals;

public class HeaderModifierTest {

private final HeaderModifier cookieHeaderModifier = new HeaderModifier() {

@Override
public boolean matches(Header header) {
return "Cookie".equals(header.name());
}

@Override
public Header modify(Header header) {
return new Header(header.name(), "modifiedCookieValue");
}
};

private final HeaderModifier nullHeaderModifier = new HeaderModifier() {

@Override
public boolean matches(Header header) {
return true;
}

@Override
public Header modify(Header header) {
return null;
}
};

@Test
public void curlCommand_shouldContains_modifiedHeader() throws Exception {
final Request request = new Request.Builder()
.url("http://example.com/")
.header("Cookie", "FIRST=foo")
.build();

final List<HeaderModifier> modifiers = Collections.singletonList(cookieHeaderModifier);
final String command = new CurlBuilder(request, -1L, modifiers).build();

assertEquals("curl -X GET -H \"Cookie:modifiedCookieValue\" http://example.com/", command);
}

@Test
public void curlCommand_shouldNotBeModified_ifDoesNotContainMatchingHeader() throws Exception {
final Request request = new Request.Builder()
.url("http://example.com/")
.header("Accept", "application/json")
.build();
final List<HeaderModifier> modifiers = Collections.singletonList(cookieHeaderModifier);

final String command = new CurlBuilder(request, -1L, modifiers).build();

assertEquals("curl -X GET -H \"Accept:application/json\" http://example.com/", command);
}

@Test
public void curlCommand_shouldNotContainsAnyHeaders_forNullHeaderModifier() throws Exception {
final Request request = new Request.Builder()
.url("http://example.com/")
.header("Cookie", "FIRST=foo")
.header("Accept", "application/json")
.build();

final List<HeaderModifier> modifiers = Collections.singletonList(nullHeaderModifier);
final String command = new CurlBuilder(request, -1L, modifiers).build();

assertEquals(command, "curl -X GET http://example.com/", command);
}
}
1 change: 1 addition & 0 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@ dependencies {
compile 'com.android.support:appcompat-v7:23.1.1'

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
}
16 changes: 15 additions & 1 deletion sample/src/main/java/com/moczul/sample/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
import android.widget.TextView;

import com.moczul.ok2curl.CurlBuilder;
import com.moczul.ok2curl.modifier.HeaderModifier;
import com.moczul.sample.modifier.Base64Decoder;
import com.moczul.sample.modifier.BasicAuthorizationHeaderModifier;

import java.util.Collections;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

Expand All @@ -21,6 +27,7 @@ protected void onCreate(Bundle savedInstanceState) {

findViewById(R.id.get_request).setOnClickListener(this);
findViewById(R.id.post_request).setOnClickListener(this);
findViewById(R.id.get_request_modified).setOnClickListener(this);
}

private void sendRequest(String type) {
Expand All @@ -31,7 +38,10 @@ private void sendRequest(String type) {
}

private void displayCurlLog(String type) {
final String curl = new CurlBuilder(RequestFactory.getRequest(type)).build();
final BasicAuthorizationHeaderModifier modifier = new BasicAuthorizationHeaderModifier(new Base64Decoder());
final List<HeaderModifier> modifiers = Collections.<HeaderModifier>singletonList(modifier);

final String curl = new CurlBuilder(RequestFactory.getRequest(type), -1L, modifiers).build();
curlLog.setText(curl);
}

Expand All @@ -46,6 +56,10 @@ public void onClick(View v) {
sendRequest(RequestFactory.TYPE_POST);
displayCurlLog(RequestFactory.TYPE_POST);
break;
case R.id.get_request_modified:
sendRequest(RequestFactory.TYPE_GET_MODIFIED);
displayCurlLog(RequestFactory.TYPE_GET_MODIFIED);
break;
default:
throw new IllegalArgumentException("Invalid view id");
}
Expand Down
10 changes: 10 additions & 0 deletions sample/src/main/java/com/moczul/sample/RequestFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class RequestFactory {

public static final String TYPE_GET = "type_get";
public static final String TYPE_POST = "type_post";
public static final String TYPE_GET_MODIFIED = "type_get_modified";

private static final String NEW_REPO_BODY = "{" +
" \"name\": \"Hello-World\"," +
Expand All @@ -34,12 +35,21 @@ public static Request samplePostRequest() {
.build();
}

public static Request modifiedGetRequest() {
return new Request.Builder()
.url("https://api.github.com/repos/vmg/redcarpet/issues?state=closed")
.header("Authorization", "Basic bWFjaWVrOnRham5laGFzbG8xMjM=")
.build();
}

public static Request getRequest(String type) {
switch (type) {
case TYPE_GET:
return sampleGetRequest();
case TYPE_POST:
return samplePostRequest();
case TYPE_GET_MODIFIED:
return modifiedGetRequest();
default:
throw new IllegalArgumentException("Invalid request type");
}
Expand Down
10 changes: 9 additions & 1 deletion sample/src/main/java/com/moczul/sample/RequestService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
import android.content.Intent;

import com.moczul.ok2curl.CurlInterceptor;
import com.moczul.ok2curl.modifier.HeaderModifier;
import com.moczul.sample.modifier.Base64Decoder;
import com.moczul.sample.modifier.BasicAuthorizationHeaderModifier;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import okhttp3.OkHttpClient;
import okhttp3.Request;
Expand All @@ -20,7 +25,10 @@ public RequestService() {

@Override
protected void onHandleIntent(Intent intent) {
final CurlInterceptor curlInterceptor = new CurlInterceptor(new AndroidLogger());
final BasicAuthorizationHeaderModifier modifier = new BasicAuthorizationHeaderModifier(new Base64Decoder());
final List<HeaderModifier> modifiers = Collections.<HeaderModifier>singletonList(modifier);

final CurlInterceptor curlInterceptor = new CurlInterceptor(new AndroidLogger(), modifiers);

final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(curlInterceptor)
Expand Down
11 changes: 11 additions & 0 deletions sample/src/main/java/com/moczul/sample/modifier/Base64Decoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.moczul.sample.modifier;

import android.util.Base64;

public class Base64Decoder {

public String decode(String value) {
final byte[] decodedBytes = Base64.decode(value.getBytes(), Base64.DEFAULT);
return new String(decodedBytes);
}
}
Loading

0 comments on commit 21c20c1

Please sign in to comment.