Prevent Apache from chunking gzipped content - apache

When using mod_deflate in Apache2, Apache will chunk gzipped content, setting the Transfer-encoding: chunked header. While this results in a faster download time, I cannot display a progress bar.
If I handle the compression myself in PHP, I can gzip it completely first and set the Content-length header, so that I can display a progress bar to the user.
Is there any setting that would change Apache's default behavior, and have Apache set a Content-length header instead of chunking the response, so that I don't have to handle the compression myself?

You could maybe play with the sendBufferSize to get a value big enough to contain your response in one chunk.
Then chunked content is part of the HTTP/1.1 protocol, you could force an HTTP/1.0 response (so not chunked: “A server MUST NOT send transfer-codings to an HTTP/1.0 client.”) by setting the force-response-1.0 in your apache configuration. But PHP breaks this settings, it's a long-known-bug of PHP, there's a workaround.
We could try to modify the request on the client side with an header preventing the chunked content, but w3c says: "All HTTP/1.1 applications MUST be able to receive and decode the "chunked" transfer-coding", so I don't think there's any header like 'Accept' and such which can prevent the server from chunking content. You could however try to set your request in HTTP/1.0, it's not really an header of the request, it's the first line, should be possible with jQuery, certainly.
Last thing, HTTP/1.0 lacks one big thing, the 'host' headers is not mandatory, verify your requests in HTTP/1.0 are still using the 'host' header if you work with name based virtualhosts.
edit: by using the technique cited in the workaround you can see that you could tweak Apache env in the PHP code. This can be used to force the 1.0 mode only for your special gzipped content, and you should use it to prevent having you complete application in HTTP/1.0 (or use the request mode to set the HTTP/1.0 for you gzip requests).

Related

Why does http.sys (before IIS) return badrequest when requests have certain acceptable accept-encoding header values?

Given a web app (netcoreapp3.0 hosted in IIS) -- any requests with certain values for Accept-Encoding header never gets to the application. http.sys parses and spits out a 400 - BadRequest.
i.e., Accept-Encoding: application/gzip,gzip
The issue seems to be the '/' character.
We are not in control of the client(s) and would like to not ask to have them conform/change their client's requests. Their requests work with other (non IIS) servers.
Unless I'm reading the spec incorrectly -- I believe the above value is valid for the header.
Thought about asking or reporting a bug in github - dotnet/aspnetcore - but not sure if it's a bug.
Thanks for any advice.
Would like to avoid a Kestrel w/ apache | nginx reverse proxy.
As far as I know, the accept and accept-Encoding is not the same header. So you read the wrong article.
The right RFC article is :https://www.rfc-editor.org/rfc/rfc7231#section-5.3.4
The "Accept-Encoding" header field can be used by user agents to
indicate what response content-codings (Section 3.1.2.1) are
acceptable in the response. An "identity" token is used as a synonym
for "no encoding" in order to communicate when no encoding is
preferred.
Accept-Encoding = #( codings [ weight ] )
codings = content-coding / "identity" / "*"
So it doesn't support the "/". There is no way to modify the setting to allow IIS access the wrong header.

Vary: Accept-Encoding Response Header

I am trying to understand the response Header "Vary: Accept-Encoding".
I am noticing the response header "Vary: Accept-Encoding" appears for some of the images in the developer tools for our application, but some images doesn't have this response header.
When i tried to hit same image url in the browser, not seeing this header "Vary: Accept-Encoding".
Why this header appears only for selected images in our application? What could be possibilities?
Either Tomcat or the application could be returning this header. If Tomcat is applying e.g. gzip encoding, then it's essential to respond with a Vary: Accept-Encoding because if the client doesn't specify that it supports gzip then the origin server (web server), a proxy, etc. must respond with a different type of data.
If the client requests /myapp/something and advertises that it is willing to accept only responses with encoding gzip, then /myapp/something should really only return a response in the identity or gzip encodings, or reply with a 412 response.
The Vary header is really for proxies. It tells a proxy that clients on the other side might get a different response if they have different Accept-Encoding values in their request headers. So, if two clients request the same resource, but one says Accept-Encoding: identity,gzip and the other says Accept-Encoding: identity,compress, they will (likely) get two responses, and the proxy should understand that it's not just the URL that is important, but also the Accept-Encoding of the client that should govern any caching that the proxy might want to provide.

How to add "Vary: Accept-Encoding" header in yaws to cacheable files

I was testing my website for optimization and I got this recommendation:
The following publicly cacheable, compressible resources should have a "Vary: Accept-Encoding" header:
So, How do I add Vary: Accept-Encoding header using an embedded yaws to css and js files?
I am an arg_rewrite_mod I believe I should do something from there but i am not quite sure how.
According to the yaws.hyber.org:
Yaws will add Accept-Encoding in Vary header if the support of gzip compression is enabled or if the response is compressed.
The Vary header can be set using yaws:outh_set_vary(Fields) or by returning {header, {vary, Fields}} from scripts (where Fields is a list of header names).

Custom modules for the Apache HTTP server: what's the behavior of mod_deflate?

I wrote a custom module for the apache http server as described in: http://httpd.apache.org/docs/2.4/developer/modguide.html
ap_rprintf(r, "Hello, world!");
I've been asked about the behavior of mod_deflate http://httpd.apache.org/docs/2.2/mod/mod_deflate.html .
Will response to the client produced by my module will be compressed by mod_deflate if the client accepts the compression with Accept-Encoding: gzip ?
If my response is already gzipped , can I prevent mod_deflate to work ?
Do you have any reference/link about this ?
Thanks.
By default, it would be compressed if it met the normal conditions. You can opt out a few ways (below in rough order of intrusiveness):
set the no-gzip per-request environment variable (r->subprocess_env)
remove the mod_deflate output filter (mod_proxy_wstunnel.c has an example of moving a filter)
unset the accept-encoding header before writing your response
set a Content-Encoding: gzip response header
The only reference is mod_deflate.c + output filter basics.

Apache2: Change response headers

I'm running on my ubuntu 12.04 system apache2 and playing around with response headers. I want to change the behavior of http response headers, especially the Content-Length header. I've tried adding following lines in my apache2.conf in the IfModule mod_headers.c section:
Header set Static-Header "Static Content with nonsense"
Header set Content-Length "1338"
If I run curl -I localhost I get the expected header field Content-Length: 1338 (curl -I performs a HEAD request).
If I run curl -i the Content-Length is correctly calculated.
In RFC2616, section 9.4 is described that the HEAD request SHOULD be identical to the information sent in response to a GET request.
Can someone explain me this behavior?!
Apache2 always calculates the content-length from scratch when it actually does deliver content. You'll experience that same behavior if you change that header using PHP. This is necessary to make sure the Content-Length matches the length of the content that is sent after the server applied, for example, compression (if mod_deflate is active).
Because of this, in any request that sends content, your change to that header is nullified. But as Apache doesn't even look at the content in an head-request (only it's metadata), it does not calculate content-length. This is valid, as HEAD-requests don't have any body, so content-length is always zero.
Therefore, you should:
a) not modify the content-length header in the first place
b) not send one for HEAD requests