Skip to content
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

[#120179893] Make sure compression and gzip header go together #27

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ericlemes
Copy link

  • When removing the content-encoding header, don't check for gzip anymore. The idea is to be more strict and avoid content not matching with content-encoding header.
  • After gzip compressing, compare the first 500 bytes of the compressed and uncompressed stream. If they are the same, send the original stream without setting the content encoding. A safety net to make sure we only send gzip header when the content is really gzipped.

@@ -232,8 +237,7 @@ private static boolean shouldGzip(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")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldGzip() method isn't being used anymore and can be removed

Copy link
Author

Choose a reason for hiding this comment

The 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.

entity.setContentEncoding("gzip");
}
else {
entity = new ByteArrayEntity(data);
Copy link
Contributor

@CharlesGarth CharlesGarth Nov 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is maybe missing a unit test case

String content = message.getBody();

byte[] data = content.getBytes("UTF-8");
if (data.length <= (AndroidHttpClient.getMinGzipSize(context.getContentResolver()) * 2)){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that we'll gzip everything that is over the gzip minimum regardless of whether they have the gzip header or not?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing this. Should respect the header.

@@ -100,7 +102,7 @@ public void sendMessageHappyPathShouldSetExecuteCorrectHttpPostAndReturnOK() thr

@Test
public void sendMessageHappyPathWithChineseCharactersShouldSetExecuteCorrectHttpPostAndReturnOK() throws URISyntaxException, IOException, KeyManagementException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
Message message = RepositoryTest.getMessageWithHeaders("谷歌拼音输入法");
Message message = RepositoryTest.getMessageWithHeaders("谷歌拼音输入");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you explained to me already but I'm still not quite understanding why this has changed, this test should not be gzipping anything as far as i can tell, meaning it shouldn't be limited by gzip min size and so shouldn't be entering the getCompressedEntity() method, and staying as text/plain. Or am i missing something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving back to the old version. This was failing due to the missing check for the shouldGzip function. With the check in place the previous test case works. I didn't observe that this test sets up for no compression headers (getMessageWithHeaders instead of getMessageWithGzipHeaders). Nice spot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😎

Copy link
Member

@b2mdevelopment b2mdevelopment left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know.
It seems more risky than leaving it without fix or stop using legacy AndroidHttpClient and using URLConnection.

@Youhana-Hana

@@ -244,9 +252,44 @@ private static boolean shouldGzip(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());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we leave the old logic as it is and check if the steam is compressed or not
boolean isZipped = new ZipInputStream(yourInputStream).getNextEntry() != null;
and remove the content-type "zip" if not?

Or just replace the function as you did but remove this check as this means we have to go through every single bytes if it is not compressed.

protected Clock clock;

public Dispatcher() {
public Dispatcher(OutputStreamFactory outputStreamFactory) {
Copy link
Contributor

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.

Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants