PAGE_CACHE_FILTER_STATE HTTP Header - java

I can't find information anywhere regarding this HTTP Header: PAGE_CACHE_FILTER_STATE.
When I try to access my RSS feed from a browser, this header has the value of NoCacheRequest, but when I access it from my Java application (URL.openConnection()), I've noticed that it gets set to FromCacheRequest and my RSS doesn't appear to update.
So I have two questions:
What is this HTTP header?
How can I make PAGE_CACHE_FILTER_STATE: NoCacheRequest for all requests?

I've never heard about nor seen PAGE_CACHE_FILTER_STATE before either, so I can't help you out with the actual specifications for it. It looks like a custom header telling you whether a cached version of the content was used or not.
To avoid caching, you could try programmatically adding something different to the URL each time. For example, you might add a random number:
http://www.example.com/feed.rss?no_cache=564482
http://www.example.com/feed.rss?no_cache=984637
You should also try sending the Pragma: no-cache and Cache-Control: no-cache HTTP headers when you request the RSS feed.

Related

Setting X-Content-Type-Options response header corrupts the PNG file

I want to get the clarity on these headers in my application:
response.setHeader("Content-Security-Policy", "frame-ancestors 'self'");
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("Strict-Transport-Security", "max-age=7776000; cludeSubdomains");
String contextPath = ((HttpServletRequest) request).getContextPath();
response.setHeader("SET-COOKIE", "JSESSIONID=" +
((HttpServletRequest)request).getSession().getId() +
";Path="+contextPath+";Secure;HttpOnly");
response.setHeader("Cache-control", "no-cache, no-store,max-age=0, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("X-Frame-Options", "SAMEORIGIN");
As of now I know:
Content Security Policy is an added layer of security that helps to
detect and mitigate certain types of attacks, including Cross Site
Scripting (XSS) and data injection attacks.
X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed.
X-XSS-protection is XSS Filter.
Strict-Transport-Security is an opt-in security enhancement that is specified by a web application through the use of a special response header. Once a supported browser receives this header that browser will prevent any communications from being sent over HTTP to the specified domain and will instead send all communications over HTTPS.
Cache-control general-header field is used to specify directives for caching mechanisms in both, requests and responses.
Pragma meant to prevent the client from caching the response. However there is a difference between Cache control and Pragma response headers as they both does same work except Pragma is the HTTP/1.0 implementation and cache-control is the HTTP/1.1 implementation of the same concept..
X-Frame-Options used to indicate whether or not a browser should be allowed to render a page in a frame, iframe or object.
Now I have this code in CrossSiteScriptingFilter which is mapped in web.xml which does XSS filtering. but as a result it changes the .png files encoding and remove the ?characters which corrupt PNG file encoding and thus giving false PNG data.
Please check the screenshot, it has no ? characters and are replaced by empty string and as a result it does not allow .png files to render.
I analysed the code and found that removing response header X-Content-Type-Options is doing the job (.png files are rendering properly).
I am still not sure why this problem occurs and why X-Content-Type-Options was replacing the ? character to "" string which was creating the problem. Can somebody explain.
Thanks in advance :)
It sounds to me like you're pretty close to your answer: XSS filtering of special characters is a bad idea with binary files which may validly use characters that would be out of place in (x)html, js, or similar interpreted files.
Normally, web apps split such resources into their own directory that will have a different process applied to its contents, say, not running an XSS protection filter over it. When you configure the filter, you should exclude paths known to exclusively contain binary data, such as the aforementioned resource directories.
What seems likely is that the headers are causing/prohibiting the filter from guessing at the MIME-type, misinterpreting your binary as html or similar (probably based on the text in the PNG header) or just falling back on the filter by default, and then sanitising it. It could be that your MIME-type headers are wrong and the sniffer is fixing it (hence telling it not to do so prevents it from recovering).

response header to cache the response?

In my web app some pages, I have two scenarios for browser cache
Scenario 1 :-
I want to server from browser cache if not modified at server side. For example :-
User issues the request for all employees
Response returns 10 employees
User issues the request for all employees again
Expectation is this time it should be served from browser cache
User creates one more employee
User issues the request for all employees again
Expectation is this time it should be served latest from server instead of browser cache
I am planning to use below header
response.setHeader("Cache-Control", "no-cache");
As
no-cache is not instructing the browser or proxies about whether or
not to cache the content. It just tells the browser and proxies to
validate the cache content with the server before using it
Scenario 2 :-
But for some sensitive pages i don't want to cache at all, i am planning it to use below header
response.setHeader("Cache-Control", "no-store");
But some articles safe to use below header to make it work for all browsers. So i am going to use below
response.setHeader("Cache-Control", "no-cache, no-store");
Is my proposed implementation correct ?
For Scenario #1 you indeed need to set Cache-Control to no-cache (or set a max-age for even a better scalability but in this case you won't have necessary the latest value) but you also need to use the HTTP header ETag in order to allow the browser to check if the data content has changed such that the browser will be able to know if the cache entry can be reused or not.
For Scenario #2 you need to set Cache-Control to no-store to prevent the browser to cache the data as it is the standard way but indeed no-cache, no-store will help to work on old browsers if you need to support them too.

RESTful API - chunked response for bulk operation

I work on a REST-like API that will support bulk operations on some resources. As it may take some time to finish such a request, I would like to return statuses of the operations in a chunked response. The media type should be JSON. How to do it with JAX-RS?
(I know that there is StreamingOutput, but it needs to manually serialize the data.)
Chunked Transfer encoding is usually used in cases where the content length is unknown when the sender starts transmitting the data. The receiver can handle each chunk while the server is still producing new ones.
This implies the the server is sending the whole time. I don't think that it makes too much sense to send I'm still working|I'm still working|I'm still working| in chunks and as far as I know chunked transfer-encoding is handled transparently by most application servers. They switch automatically when the response is bigger then a certain size.
A common pattern for your use case looks like this:
The client triggers a bulk operation:
POST /batch-jobs HTTP/1.1
The server creates a resource which describes the status of the job and returns the URI in the Location header:
HTTP/1.1 202 Accepted
Location: /batch-jobs/stats/4711
The client checks this resource and receives a 200:
GET /batch-jobs/stats/4711 HTTP/1.1
This example uses JSON but you could also return plain text or add caching headers which tell the client how long he should wait for the next poll.
HTTP/1.1 200 OK
Content-Type: application/json
{ "status" : "running", "nextAttempt" : "3000ms" }
If the job is done the server should answer with a 303 and the URI of the resource he has created:
HTTP/1.1 303 See other
Location: /batch-jobs/4711

Java HttpGet doesn't accept gzip

I am making an HttpGet to an url and I do not want the server to send the data gzipped. What header should I include in my HttpGet ?
With the default headers, the server sends gzipped data from time to time. I don't want this to happen. Thanks.
You want the Accept-Encoding HTTP request header.
Update: per #Selvin's comment, leave it empty or set it to "identity".
Update: The web application has to cooperate properly to be HTTP compliant, of course. If it's not honoring Accept-Encoding, look at its Content-Encoding HTTP response header. If it's "gzip", just read the response body with Java's GZIPInputStream.html. Then add "gzip" to your Accept-Encoding request header, since your client now handles GZIP. If the web application doesn't set the Content-Encoding header properly, that's another story altogether.
You should set the Accept-Encoding header to identity.
You could try to change the Accept-Encoding header, by removing the gzip|deflate value. If this doesn't work, you should also take into account that server doesn't care if the client supports the gzipped content (which is a bug and should be fixed).

jax-ws change Content-type to Content-Type because server is hyper sensitive

I have to connect to a poorly implemented server that only understands Content-Type (capital-T) and not Content-type. How can I ask my JAX-WS client to send Content-Type?
I've tried:
Map<String, List<String>> headers = (Map<String, List<String>>)
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
But headers is null. What am I doing wrong?
I have to connect to a poorly implemented server that only understands Content-Type(capital-T) and not Content-type. How can I ask my jax-ws client to send Content-Type?
I've dug this question a bit more and, sadly, I'm afraid the answer is: you can't. Let me share my findings.
First, the code that you'll find in https://jax-ws.dev.java.net/guide/HTTP_headers.html does not give you access to the HTTP headers of the future HTTP request (that hasn't been created at this point), it allows you to set additional HTTP headers for making a request (that will be added to the HTTP request later).
So, don't expect the following code to not return null if you don't put anything before (and actually, you'll only get what you put in there):
((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);
Then, I did a little test based on the code provided in the same link:
AddNumbersImplService service = new AddNumbersImplService();
AddNumbersImpl port = service.getAddNumbersImplPort();
((BindingProvider)port).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
Collections.singletonMap("X-Client-Version",Collections.singletonList("1.0-RC")));
port.addNumbers(3, 5);
And this is what I see in the HTTP request when running the client code:
POST /q2372336/addnumbers HTTP/1.1
Content-type: text/xml;charset="utf-8"
X-client-version: 1.0-RC
Soapaction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.6 in JDK 6
Host: localhost:8080
Connection: keep-alive
Content-Length: 249
Do you notice the difference: only the first char of the X-Client-Version header is kept upper cased, the rest is lowered!
And indeed, if you check the class c.s.x.w.t.Headers that is used to represent HTTP request (and response) headers, you'll see that it "normalizes" keys when they are added (in normalize(String)):
/* Normalize the key by converting to following form.
* First char upper case, rest lower case.
* key is presumed to be ASCII
*/
private String normalize (String key) {
...
}
So, while the c.s.x.w.t.h.c.HttpTransportPipe class (my understanding is that this is where the HTTP request is created, this is also where previously added headers will be added to the HTTP request headers) actually adds "Content-Type" as key in a c.s.x.w.t.Headers instance, the key will be modified because of the previously mentioned implementation detail.
I may be wrong but I don't see how this could be changed without patching the code. And the odd part is that I don't think that this "normalizing" stuff is really RFCs compliant (didn't check what RFCs say about headers case though). I'm surprised. Actually, you should raise an issue.
So I see three options here (since waiting for a fix might not be an option):
Patch the code yourself and rebuild JAX-WS RI (with all the drawbacks of this approach).
Try another JAX-WS implementation like CFX for your client.
Let the request go through some kind of custom proxy to modify the header on the fly.
You can modify the HTTP headers from the RequestContext. If you have access to the port object you can cast it to a javax.xml.ws.BindingProvider, which will give you access to the RequestContext.
You might also want to remove the unaccepted "Content-type" header.
This page shows how to do it in a bit more detail: https://jax-ws.dev.java.net/guide/HTTP_headers.html
Let me know if you need more code samples, or if you paste some of your code I can show you how to modify it.

Categories