Force Apache to change http headers from Weblogic - apache

I've configured an Apache in front of a Weblogic. Everything, including static content is stored on Weblogic.
That Apache is configured to set Cache-control max-age and an expiration date HTTP headers of static content when the response comes from Weblogic.
Everything seems to work fine when a user makes the first request of a static content and Weblogic replies with a 200 OK but, once the expiration date is over and browser makes a conditional request, Weblogic replies with a 304 Not Modified BUT that response is not overriden by Apache config so a Cache-Control: max-age=0 arrives to the browser and no new expiration date comes to the browser.
I've seend that I'm unable to set a config to the default weblogic.servlet.FileServlet and, due some development issues, it's impossible to set a custom made Servlet that overrides the default one.
The only option then, is to force Apahe to update the headers of a 304 response from Weblogic.
How can this been achieved?

The problem was related to the configuration of Apache. I had configured the rules related with cache expiration http headers given a mime-type. On a 304 response from Weblogic there is no mime because there is no data so I've updated the rules to take into account the extension of the file types instead mimes and now is working properly

Related

How to enable safari browser caching for urls which are 302 redirects

I have a single-page application which is dependent on a javascript bundle to work. For fetching this bundle's CDN (cloudfront) url, I'm making a call to an AWS API Gateway endpoint which returns a HTTP 302 response having the Location header parameter as the CDN url. Now this CDN Url responds with cache-control headers having a sufficiently large max-age value. All the other browsers like Chrome, Firefox seem to honor this and cache the CDN Url response for further requests. But Safari isn't doing so (Version - 12). However, it does cache the response when I'm making the request to the CDN Url directly. Do I need to add some more headers or some additional metadata in the 302 response to make it work for safari?
I tried fiddling with the cache-control parameters like adding 'immutable' but nothing worked. I googled quite a lot about this issue but nothing concrete turned up.
I expected Safari to work with just the max-age parameter present in CDN's response, but it never caches it.

ResponseCache attribute does not cache data on client side

In ASP.NET Core application I have a action method that returns some data. I wanted to cache this data on client side. So based on the documentation here i can use ResponseCache attribute on the action method. This attribute adds Cache-Control header in response
Response caching refers to specifying cache-related headers on HTTP
responses made by ASP.NET Core MVC actions. These headers specify how
you want client and intermediate (proxy) machines to cache responses
to certain requests (if at all). This can reduce the number of
requests a client or proxy makes to the web server, since future
requests for the same action may be served from the client or proxy’s
cache.
also
Response caching does not cache responses on the web server. It
differs from output caching, which would cache responses in memory on
the server in earlier versions of ASP.NET and ASP.NET MVC.
So this is how my action method looks
public class LookupController : Controller
{
[HttpGet]
[ResponseCache(Duration = 120)]
public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
{
return _domain.GetStateProvinces();
}
}
Then i call the method using browser as http://localhost:40004/lookup/getstateprovinces
Here is the request and response headers
Notice that Response Headers has Cache-Control: public,max-age-120 as expected.
However if refresh the page using F5 (before 120 seconds), the debugger breakpoint inside GetStateProvince action method alway hits. That means its not cahing the data on client side.
Is there anything else i need to do to enable client side caching?
Update
I have tried using IE, Chrome and also POSTMAN with no luck. Everytime i type the url in address bar or hit refresh the client ( that is browser or postman) makes a call to action method.
Actually ResponseCache attribute works as intended.
The difference is that the response is cached if you navigate through your website pages (case 1), or use back and forward buttons (not when refreshing the page).
As an example of case 1, I have the following:
you're on page http://localhost:65060/Home/Index
type another url and click enter or click a link in your webpage: http://localhost:65060/Home/Users
type again the url http://localhost:65060/Home/Index (you will see that this time the response for this url gets fetched from disk cache)
As you will see in the article Response Caching in ASP.Net Core 1.1, the following is stated:
During a browser session, browsing multiple pages within the website or using back and forward button to visit the pages, content will be served from the local browser cache (if not expired).
But when page is refreshed via F5, the request will be go to the server and page content will get refreshed. You can verify it via refreshing contact page using F5.
So when you hit F5, response caching expiration value has no role to play to serve the content. You should see 200 response for contact request.
References:
[1]. ASP.NET Core Response Caching Sample
[2]. ResponseCache attribute sample
[3]: How to control web page caching, across all browsers?
Long story short, using the ResponseCache attribute like the following is sufficient to get expiration-based client-side caching to work in a brand new, default dotnet core project (including async methods):
[HttpGet]
[ResponseCache(Duration = 120)]
public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
{
return _domain.GetStateProvinces();
}
This is working correctly in the screenshot above, as the Cache-Control: public,max-age=120 is visible there. In most cases, browsers won't send subsequent requests before the expiration (i.e. for the next 120 seconds or 2 minutes), but this is a decision of the browser (or other client).
If the request is sent regardless, you either have some middleware or server configuration overwriting your response headers, or your client ignores the caching directive. In the screenshot above, the client ignores caching, because the cache control header is there.
Common cases where the client cache is ignored and the request is sent:
Chrome prevents any kind of caching when using HTTPS without a certificate (or an invalid certificate, this is often common for local development, so make sure to use HTTP when testing your cache, or trust a self-signed cert)
Most browser dev tools disable caching by default when open, this can be disabled
Browsers usually send additional headers, Chrome sends Cache-Control: no-cache
Refreshing directly (i.e. Ctrl+F5) will instruct most browsers to not use a cache and make the request regardless of age
Browsers usually send additional headers, Chrome sends Cache-Control: max-age=0 (this is visible in your screenshot)
Postman sends the Cache-Control: no-cache header which makes it bypass the local cache, resulting in requests to be sent; you can disable it from the settings dialog, in which case requests will no longer be sent with the above client cache configuration
At this point we are beyond expiration-based client caching, and the server will receive the request in one way or another, and another layer of caching occurs: you may make the server respond with a 304 Not Modified code (which is then again up to the client to interpret in whatever way it wants) or use a server-side cache and respond with the full content. Or you may not use any subsequent caching and just perform the entire request processing again on the server.
Note: the ResponseCache attribute is not to be confused with services.AddResponseCaching() & app.UseResponseCaching() middleware in startup configuration, because that is for server-side caching (which by default uses an in-memory cache, when using the middleware). The middleware is not required for client-caching to work, the attribute by itself is enough.
First of all I want to clarify few thing and I am sure that you already knew it.
ResponseCache is not equal to OutputCache any way.
ResponseCache is as per my thinking set header but it does not cache anything on server side.
Now If you want to Cache same as OutputCache then you might have to use preview release 1.1 that just release.
ASP.net core 1.1 preview release
https://blogs.msdn.microsoft.com/webdev/2016/10/25/announcing-asp-net-core-1-1-preview-1/
They introduce new Response Caching Middleware. Response Caching Middleware
Demo of it available here . https://github.com/aspnet/ResponseCaching/blob/dev/samples/ResponseCachingSample/Startup.cs

How to ignore invalid requests - Apache

Is there any way to configure Apache to programatically examine a request and cancel the response if the request is invalid. I mean, my intention is to skip responding and just disconnect the client. I'm currently developing a fault-tolerance server fronted by Apache which needs to (stakeholder requirement) ignore answering requests which aren't authorize (I can't even send 401). If I can't use Apache, is there any other way to do it?
Continuation of above comments ...
I dont know how much control you have in JBoss over headers and output sent to the browser, but you can mimic an closed/aborted request like this. From within an application.
Send these Headers, flush and stop all output:
HTTP/1.0 204 No Content
Content-Length: 0
Content-Type: text/html
For example, this is the recommended method the Amazon API suggests as a response to any call that does not want a response.

BlazeDS data push over SSL

I have an application that uses the data push technology of blazeDS to send data to a Flex Client event 5 seconds. The application works fine when I run it via HTTP with or without a proxy. When I run it via https the data push doesn't work anymore. I get the following error
rootCause [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2
text="Error #2032: Stream Error.
URL: https://localhost/admin/messagebroker/streamingamfsecure?command=open&version=1
Has anyone successfully got streaming to work over SSL?
Thanks,
Pratima
Questions to ask yourself (and post here)
Is the request showing up in your access logs?
Does Tomcat/whatever server up normal HTML pages via HTTPS?
What do the response headers look like? Does clearing your cache change anything?
What browser are you using?
Can you set explicate caching headers?
Try one of these:
Cache-Control: no-store
Cache-Control: no-store, must-revalidate
Cache-Control: no-store,max-age=0,must-revalidate
Cache-Control: max-age=0,must-revalidate
Cache-Control: must-revalidate
2032 is a bit of a vague error from the framework.
However, things to check (in addition to Stu's list)
Can you hit the https:// page in a browser directly?
I notice in your example that you haven't specified the port number for SSL. Unless you've gone to the trouble of setting up some Apache SSL redirects, chances are this is a mistake.
If you paste the URL into a browser, you should be able to hit it, and get an empty response. Anything else, and you've got a problem (often one that doesn't relate to BlazeDS.)
Is your certificate valid?
If you're using a Self signed cert (as is common in development), does your browser have a security exception defined? Various browsers will block attempts to hit invalid certs in different ways, but no self-resepcting browser would allow this call through until an exception has been set up.
Is your channel defined correctly?
When switching from http:// to https://, you need to update your Channel class on the flex client to SecureAMFChannel and the endpoint class in your services-config.xml to SecureAMFEndpoint.
Broadly speaking, https with BlazeDS (either push, or RPC) works just fine, assuming you configure it properly.

Caching proxy with authenticated REST requests

Consider following scenario:
I have RESTful URL /articles that returns list of articles
user provide his credentials using Authorization HTTP header on each request
articles may vary from user to user based on his privileges
Its possible to use caching proxy, like Squid, for this scenario?
Proxy will see only URL /articles so it may return list of articles only valid for first user that generates the cache. Other users requesting URL /articles can see articles they don't have access to, which is not desirable of course.
Should I roll my own cache or some caching proxy software can be configured to base its cache on Authorization HTTP header?
One possibility to try is using the Vary: Authorization response header to instruct downstream caches to be careful about caching by varying the cached documents based on the request's Authorization header.
You may already be using this header if you use response-compression. The user generally requests a resource with the header Accept-Encoding: gzip, deflate; if the server is configured to support compression, then the response might come with the headers Content-Encoding: gzip and Vary: Accept-Encoding already.
By the HTTP/1.1 RFC section 14.8 (https://www.rfc-editor.org/rfc/rfc2616#section-14.8):
When a shared cache (see section 13.7) receives a request
containing an Authorization field, it MUST NOT return the
corresponding response as a reply to any other request, unless one
of the following specific exceptions holds:
1. If the response includes the "s-maxage" cache-control
directive, the cache MAY use that response in replying to a
subsequent request. But (if the specified maximum age has
passed) a proxy cache MUST first revalidate it with the origin
server, using the request-headers from the new request to allow
the origin server to authenticate the new request. (This is the
defined behavior for s-maxage.) If the response includes "s-
maxage=0", the proxy MUST always revalidate it before re-using
it.
2. If the response includes the "must-revalidate" cache-control
directive, the cache MAY use that response in replying to a
subsequent request. But if the response is stale, all caches
MUST first revalidate it with the origin server, using the
request-headers from the new request to allow the origin server
to authenticate the new request.
3. If the response includes the "public" cache-control directive,
it MAY be returned in reply to any subsequent request.