-
Notifications
You must be signed in to change notification settings - Fork 9
[#120179893] Make sure compression and gzip header go together #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package com.b2msolutions.reyna.http; | ||
|
|
||
| import org.junit.Test; | ||
| import org.junit.runner.RunWith; | ||
| import org.robolectric.RobolectricTestRunner; | ||
|
|
||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.IOException; | ||
| import java.io.OutputStream; | ||
| import java.util.zip.GZIPOutputStream; | ||
|
|
||
| import static junit.framework.Assert.*; | ||
|
|
||
| @RunWith(RobolectricTestRunner.class) | ||
| public class OutputStreamFactoryTest { | ||
|
|
||
| @Test | ||
| public void whenConstructingShouldNotThrow(){ | ||
| assertNotNull(new OutputStreamFactory()); | ||
| } | ||
|
|
||
| @Test | ||
| public void whenCreateGzipOutputStreamShouldReturnRightType() throws IOException { | ||
| OutputStreamFactory factory = new OutputStreamFactory(); | ||
| OutputStream outputStream = factory.createGzipOutputStream(new ByteArrayOutputStream()); | ||
| assertTrue(outputStream instanceof GZIPOutputStream); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,27 +10,36 @@ | |
| import com.b2msolutions.reyna.blackout.TimeRange; | ||
| import com.b2msolutions.reyna.http.HttpPost; | ||
| import com.b2msolutions.reyna.blackout.BlackoutTime; | ||
| import com.b2msolutions.reyna.http.OutputStreamFactory; | ||
| import com.b2msolutions.reyna.system.*; | ||
| import org.apache.http.HttpResponse; | ||
| import org.apache.http.client.HttpClient; | ||
| import org.apache.http.entity.AbstractHttpEntity; | ||
| import org.apache.http.entity.ByteArrayEntity; | ||
| import org.apache.http.entity.StringEntity; | ||
| import org.apache.http.impl.client.AbstractHttpClient; | ||
| import org.apache.http.protocol.HTTP; | ||
|
|
||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.OutputStream; | ||
| import java.net.URI; | ||
| import java.text.ParseException; | ||
| import java.util.ArrayList; | ||
| import java.util.GregorianCalendar; | ||
| import java.util.Locale; | ||
| import java.util.zip.GZIPOutputStream; | ||
|
|
||
| public class Dispatcher { | ||
|
|
||
| private static final String TAG = "com.b2msolutions.reyna.Dispatcher"; | ||
|
|
||
| private OutputStreamFactory outputStreamFactory; | ||
|
|
||
| protected Clock clock; | ||
|
|
||
| public Dispatcher() { | ||
| public Dispatcher(OutputStreamFactory outputStreamFactory) { | ||
| this.clock = new Clock(); | ||
| this.outputStreamFactory = outputStreamFactory; | ||
| } | ||
|
|
||
| public enum Result { | ||
|
|
@@ -179,7 +188,7 @@ private Result parseHttpPost(Message message, HttpPost httpPost, Context context | |
| URI uri = message.getURI(); | ||
| httpPost.setURI(uri); | ||
|
|
||
| AbstractHttpEntity entity = Dispatcher.getEntity(message, context); | ||
| AbstractHttpEntity entity = this.getEntity(message, context); | ||
| httpPost.setEntity(entity); | ||
|
|
||
| this.setHeaders(httpPost, message.getHeaders()); | ||
|
|
@@ -232,8 +241,7 @@ private static Header[] removeGzipEncodingHeader(Header[] headers) { | |
| ArrayList<Header> filteredHeaders = new ArrayList<Header>(); | ||
|
|
||
| for (Header header : headers) { | ||
| if (header.getKey().equalsIgnoreCase("content-encoding") | ||
| && header.getValue().equalsIgnoreCase("gzip")) { | ||
| if (header.getKey().equalsIgnoreCase("content-encoding")) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this shouldGzip() method isn't being used anymore and can be removed
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very good spot. Thanks. Actually shouldGzip should be used. If we don't receive the header from elemez (or any app using reyna lib) we should not compress at all. Fixing it. |
||
| continue; | ||
| } | ||
|
|
||
|
|
@@ -244,9 +252,44 @@ private static Header[] removeGzipEncodingHeader(Header[] headers) { | |
| return filteredHeaders.toArray(returnedHeaders); | ||
| } | ||
|
|
||
| private static AbstractHttpEntity getCompressedEntity(String content, Context context) throws Exception { | ||
| byte[] data = content.getBytes(); | ||
| return AndroidHttpClient.getCompressedEntity(data, context.getContentResolver()); | ||
| private AbstractHttpEntity getEntity(Message message, Context context) throws Exception { | ||
| String content = message.getBody(); | ||
|
|
||
| byte[] data = content.getBytes("UTF-8"); | ||
| if (!shouldGzip(message.getHeaders()) || data.length <= (AndroidHttpClient.getMinGzipSize(context.getContentResolver()) * 2)){ | ||
| return new StringEntity(content, HTTP.UTF_8); | ||
| } | ||
| else { | ||
| return getCompressedEntity(data, context); | ||
| } | ||
| } | ||
|
|
||
| private AbstractHttpEntity getCompressedEntity(byte[] data, Context context) throws Exception { | ||
| ByteArrayOutputStream arr = new ByteArrayOutputStream(); | ||
| OutputStream zipper = this.outputStreamFactory.createGzipOutputStream(arr); | ||
| zipper.write(data); | ||
| zipper.close(); | ||
|
|
||
| byte[] compressedData = arr.toByteArray(); | ||
| int end = compressedData.length > 500 ? 500 : compressedData.length; | ||
|
|
||
| Boolean equal = true; | ||
| for (int i = 0; i < end; i++){ | ||
| if (compressedData[i] != data[i]){ | ||
| equal = false; | ||
| break; | ||
| } | ||
| } | ||
| AbstractHttpEntity entity; | ||
| if (!equal){ | ||
| entity = new ByteArrayEntity(compressedData); | ||
| entity.setContentEncoding("gzip"); | ||
| } | ||
| else { | ||
| entity = new ByteArrayEntity(data); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this is maybe missing a unit test case |
||
| entity.setContentEncoding(""); | ||
| } | ||
| return entity; | ||
| } | ||
|
|
||
| private void setHeaders(HttpPost httpPost, Header[] headers) { | ||
|
|
@@ -263,16 +306,7 @@ private String getSubmittedTimestamp() { | |
| return String.valueOf(this.clock.getCurrentTimeMillis()); | ||
| } | ||
|
|
||
| private static AbstractHttpEntity getEntity(Message message, Context context) throws Exception { | ||
| String content = message.getBody(); | ||
| AbstractHttpEntity entity = new StringEntity(content, HTTP.UTF_8); | ||
|
|
||
| if (Dispatcher.shouldGzip(message.getHeaders())) { | ||
| entity = getCompressedEntity(content, context); | ||
| } | ||
|
|
||
| return entity; | ||
| } | ||
|
|
||
| public static boolean isBatteryCharging(Context context) { | ||
| Intent batteryStatus = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you leave the other constructor in as well? I think we have a few usages of Dispatcher() without args in Elemez and I can't be bothered to update them :D.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or you could follow the dependency "injection" anti-pattern we have in some of the other classes where we instantiate the dep in constructor and inject mock to the protected member... :P