Disable WAR specific cache jBoss GWT - gwt

My applications is based on the following:
jBoss EAP 5.1
GWT
I have created additional war in jBoss/deploy/new.war where I put a lot of .wav files. I play the audio files from the browser using gwt Audio. But, the file is always cached in the browser even if I delete the file from the folder or rename it.
Could anyone tell me as to how I can disable browser caching of .wav files being played via GWT hosted on jBoss EAP 5.1. Note, I have no access to the http requests that gwt uses to play and hence cannot edit the header files. Please help me out !

If the wav files are served by JBoss, you should be able to add no-cache headers using a servlet filter mapped to the *.wav pattern, e.g.:
#WebFilter("*.wav")
public class NoCacheFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setDateHeader("Date", System.currentTimeMillis());
httpResponse.setDateHeader("Expires", System.currentTimeMillis() - 86400000L);
httpResponse.setHeader("Pragma", "no-cache");
httpResponse.setHeader("Cache-control", "no-cache, no-store, must-revalidate");
chain.doFilter(request, response);
}
}

Related

How to set http headers in JBoss EAP 6.1

I want to set the http headers for x-frame options and Strict-Transport-Security in jboss 6.1.0.
I have been searching for the proper configuration file to add these headers, am able to see some procedures for jboss 6.4, jboss 7 but I didn't get anything for jboss 6.1
Configure Http Headers in JBoss EAP 7
This is in jboss 7, I need to do the same for jboss 6.1
I have tried a lot in identifyiing the proper confiurtion changes needed for this in jboss 6.1, but am helpless.
please let me knoe if someone is aware of doing this in jboss 6.1
Thanks in advance.
If you are using Apache HTTPD as a proxy to JBoss, it is very easy to add all these headers using the Header directive. Otherwise you can set all these headers in a custom filter and place in the corresponding web application’s lib folder.
This answer is present in RedHat Knowledgebase. As it requires RedHat credentials, I'm posting the same answer here.
Solution:
A servlet filter can be used to add the additional HTTP header to the response. Below is an example filter which uses Servlet 3.0 #WebFilter. Using annotation does not require to configure web.xml to enable the filter.
/*
* This is a sample servlet filter to set "X-Frame-Options" http header to
* http response.
*/
package com.redhat.jboss.support;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebFilter;
#WebFilter("/*")
public class AddCustomHeaderFilter implements Filter {
/**
* Take this filter out of service.
*/
public void destroy() {
}
/**
* #param request The servlet request we are processing
* #param result The servlet response we are creating
* #param chain The filter chain we are processing
*
* #exception IOException if an input/output error occurs
* #exception ServletException if a servlet error occurs
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
((HttpServletResponse)response).setHeader("X-Frame-Options", "SAMEORIGIN");
chain.doFilter(request, response);
}
/**
* Place this filter into service.
*
* #param filterConfig The filter configuration object
*/
public void init(FilterConfig filterConfig) throws ServletException {
}
}
After compiling the AddCustomHeaderFilter.java, one package will be
creating named com.redhat.jboss.support with AddCustomHeaderFilter.class.
Create a jar for the AddCustomHeaderFilter.class using following
command. It will generate a jar AddCustomHeaderFilter.jar :
jar -cvf AddCustomHeaderFilter.jar com
Put this jar in your Web application's WEB-INF/lib folder. It will enable the Servlet filter in the web application.
NOTE:
The example given in AddCustomHeaderFilter.java class is for "SAMEORIGIN". There are below possible values for X-Frame-Options:
DENY: The page cannot be displayed in a frame, regardless of the
site attempting to do so.
SAMEORIGIN: The page can only be displayed in a frame on the same
origin as the page itself.

Failed to connect GWT to BigCommerce API

Criteria: I'm trying to connect to a secured web service API called BigCommerce using GWT RequestBuilder.
This is my entry point:
public class GwtTest implements EntryPoint {
String url = "http://my-url-api/api/v2/products.xml"; // not the original url i'm using
#Override
public void onModuleLoad() {
url = URL.encode(url);
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
builder.setHeader("Authorization", "Basic XXX"); // I generated this from Postman app on Chrome where things work perfectly
builder.setHeader("Access-Control-Allow-Credentials", "true");
builder.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8888/");
builder.setHeader("Access-Control-Allow-Methods", "POST, GET, UPDATE, OPTIONS");
builder.setHeader("Access-Control-Allow-Headers", "x-http-method-override");
builder.setHeader("Content-Type", "application/xml");
try {
builder.sendRequest(url, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
RootPanel.get().add(new HTML("Success: "+response.getText()));
}
#Override
public void onError(Request request, Throwable exception) {
RootPanel.get().add(new HTML("Failure (Response Error): "+exception));
}
});
} catch (RequestException e) {
RootPanel.get().add(new HTML("Failure Request Exception: "+e));
}
}
}
Errors encountered: I encounter the Same Origin Policy error at first:
Then After I disabled CORS on my browser I get the Perflight error:
Work-around: I was able to get results by disabling web security on Chrome but I don't think it's the right solution.
Trivial note: Please guide me on this one, guys, because I'm new to GWT and BigCommerce thanks.
Use a proxy servlet.
This is also the solution the GWT Openlayers wrappers uses.
https://github.com/geosdi/GWT-OpenLayers/blob/c3becee0cdd5eefdc40b18e4999c2744dc23363a/gwt-openlayers-server/src/main/java/org/gwtopenmaps/openlayers/server/GwtOpenLayersProxyServlet.java
Based on Rob Newton answer, if your application is pure front end, you can host your files on nginx and add some proxy_pass directive to your configuration, for example:
location ~* ^/bigcommerce/(.*) {
proxy_pass http://api.bigcommerce.com/$1$is_args$args;
}
So whenever you call http://hostaddress/bigcommerce/something, this will be forwared to http://api.bigcommerce.com/something. Headers are not forwared in this config, you can add more directives for that.
You could include a servlet in your webapp that acts as a proxy between the client and BigCommerce.
An alternative is to run a reverse proxy such as Apache httpd that makes requests to the BigCommerce server appear to be on the same host as your webapp.
Here is an example of an Apache httpd config file that will act as a reverse proxy for your webapp and an external service on a different host. To the browser both the webapp and the external service will appear to be running on the same host, which is what your want.
# file: /etc/httpd/conf.d/mywebapp.conf
<VirtualHost *:80>
ProxyPreserveHost On
# Forward requests to path /SomeExternalService to an external service
ProxyPass /SomeExternalService http://externalhost/
# Forward all other requests to a local webserver hosting your webapp,
# such as Tomcat listening on port 8081
ProxyPass / http://127.0.0.1:8081/
ProxyPassReverse / http://127.0.0.1:8081/
</VirtualHost>

Fix CORS header Access-Control-Allow-Origin missing on plugin development on eclipse

-I am try to make a modular application using eclipse plugin development and using jax-rs.
-I want to access an event source created by jetty server and translate each event in time.
-When i try to access the event i am get this error in firefox that run my client html 5 page :
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:9050/services/events. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
-I know that i must configure the server , but i don't have .htaccess and no web-inf dir.
-Is there any to declare this file in the vm arguments using eclipse ?
-Is there any other way to do it ?
-I don't have WEB-INF directory and i don't know if it supported in this plugin development approach.
-I don't have main function I have only bundles (activator, ect.) and I don't have main function .
-I also have manifest.mf file
Any help is accepted.Thanks in advance!
Try implementing a response filter which would add your needed headers to the response.
#Provider
public class CORSFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
// the wildcard char `*` will allow any origin
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
// add anything and everything you need
responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type");
responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
// etc
}
}
Don't forget to register it.

How can I force UriBuilder to use https?

I'm currently running Dropwizard behind Apache httpd acting as a reverse proxy, configured like so:
<VirtualHost *:443>
<Location /api>
ProxyPass "http://my.app.org:8080/api"
<Location>
...
</VirtualHost>
With other Location settings serving static assets and some authentication thrown in. Now, httpd also performs SSL offloading, so my Dropwizard only receives the plain HTTP request.
In my Dropwizard API, I like to return a Location header indicating newly created resources:
#Path("/comment")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
class CommentResource() {
#PUT
fun create(#Context uri: UriInfo, entity: EventComment): Response {
val stored: EventComment = createEntity(entity)
return Response.created(uri.baseUriBuilder.path(MessageStream::class.java)
.resolveTemplate("realmish", entity.realmId)
.path(stored.id.toString()).build()).build()
}
This creates a Response with a Location header from JerseyUriBuilder:
Location http://my.app.org/api/messages/123
Which, on my SSL-only app, naturally fails to load (I'm actually surprised this didn't turn out to render as http://my.app.org:8080/api/messages/123 - probably also the reason why ProxyPassReverse didn't help).
I know I can force the scheme to be https by using baseUriBuilder.scheme("https"), but this gets repetitive and is an easy source of errors.
Thus my question: how can I either make Jersey generate correct front-end URLs or successfully make httpd rewrite those generated by Dropwizard?
For Jersey, you can use a pre-matching ContainerRequestFilter to rewrite the URI. For example
#PreMatching
public class SchemeRewriteFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext request) throws IOException {
URI newUri = request.getUriInfo().getRequestUriBuilder().scheme("https").build();
request.setRequestUri(newUri);
}
}
Then just register it with Jersey (Dropwizard)
env.jersey().register(SchemeRewriteFilter.class);
EDIT
The above only works when you use uriInfo.getAbsolutePathBuilder(). If you want to use uriInfo.getBaseUriBuilder(), then you need to use the overloaded setRequestUri that accepts the base uri as the first arg.
URI newUri = request.getUriInfo().getRequestUriBuilder().scheme("https").build();
URI baseUri = request.getUriInfo().getBaseUriBuilder().scheme("https").build();
request.setRequestUri(baseUri, newUri);
If using Jetty, then you can avoid the hacks by registering the org.eclipse.jetty.server.ForwardedRequestCustomizer with your server. This will look at the X-Forwarded-* headers to build the base URI.
Sample using embedded Jetty:
Server jettyServer = new Server();
HttpConfiguration config = new HttpConfiguration();
config.addCustomizer(new ForwardedRequestCustomizer());
ServerConnector serverConnector = new ServerConnector(jettyServer,
new HttpConnectionFactory(config));
serverConnector.setPort(8080);
jettyServer.setConnectors(new Connector[] {serverConnector});
This seems to work whether or not you are behind a reverse proxy, so I don't know why it isn't just enabled by default.

GWT Client files in one Server & GWT Servlets in other Server

I'm trying to separate GWT Client & Server. If i'm not wrong, GWT client code is getting server reponses by connecting to the servlet we mentioned in GWT Project's web.xml. If So, can i host my GWT Servlets in one Tomcat Server & GWT Client code in other tomcat server ..?
Will it work ..? If so how to do that, i have already tried something working with hosted.html in GWT Client files. But it didn't worked
Yes, you can host client files in any web-server since they are static stuff, actually what you need is to pick your index.html, the .nocache.js and all the *.cache.(js|html) files and put them in any web server (apache, nginx, iis, jetty, etc).
You could even replace the index.html by any other html generator like php, jsp etc.
But of course the server side should be hosted in a servlet container.
What you have to be aware about, is that when the server with your static files are in a different domain than the servlet server, ajax requests will fail because of security constrains (see CORS).
To avoid that restriction there are many ways in gwt (gwtquery-jsonp, gwt-xdm, etc).
What I'm using is a filter (see code above) able to enable CORS when an options request is received.
You have to modify your client code as well to configure correctly the url of the servlet-container. Here is an example for changing the url with RequestFactory.
Client side code for RF:
myFactory = GWT.create(MyRFFactory.class);
DefaultRequestTransport transport = new DefaultRequestTransport();
transport.setRequestUrl("http://my.servletcontainer.com/gwtRequest");
myFactory.initialize(eventBus, transport);
web.xml configuration
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>my.namespace.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Server filter
public class CORSFilter implements Filter {
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
String o = req.getHeader("Origin");
if ("options".equalsIgnoreCase(req.getMethod())) {
resp.setHeader("Allow", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
if (o != null) {
resp.addHeader("Access-Control-Allow-Origin", o);
resp.addHeader("Access-Control-Allow-Methods",
"POST, GET, OPTIONS");
resp.addHeader("Access-Control-Allow-Headers",
"content-type,pageurl,x-gwt-permutation");
resp.setContentType("text/plain");
}
resp.getWriter().flush();
return;
}
if (o != null) {
resp.addHeader("Access-Control-Allow-Origin", o);
}
if (filterChain != null) {
filterChain.doFilter(req, resp);
}
}
#Override public void destroy() {
}
#Override public void init(FilterConfig arg0) throws ServletException {
}
}
The same question has been asked in the past.
gwt-split-client-and-server
What you can do is use the servlet as a proxy to another server, where you have implemented your model logic.