I am using a jBoss EAP 6.1 sevrer in which I want to Enable the GZIP Compression for my HTML, CSS and javaScript files.
I am entirely new to this compression technology, can anyone suggest me a tutorial or can directly give me a step wise process to enable a compression on Jboss EAP 6.1 server.
Apart from these I have the following doubts:
1) Do I need to compress the files on my workspace or if my jboss server will be compression enabled it will take care of compression , I just need to deploy the war.
2) When server respond my request , Do i need to explicitly convert or decode or decompress the files to use them or to interpret them?
GZIP compression for web resources is optional, so you can't compress all of them and then hope that every web client is able to handle it. That's why it's usually enabled at runtime when the client (might be a web browser) says "gzip is OK for me" with the Accept-Encoding: gzip, deflate header. See https://en.wikipedia.org/wiki/HTTP_compression
On the server side, the magic is handles by a HTTP Filter which intercepts the request, notes the header, then sends the request on to the rest of the app, intercepts the response and compresses accordingly.
JBoss has some built-in support: Enabling gzip compression for Jboss
If you want to do it yourself, you need to write a Filter and configure it in your web.xml.
Java2s has an implementation:
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String ae = request.getHeader("accept-encoding");
if (ae != null && ae.indexOf("gzip") != -1) {
GZIPResponseWrapper wrappedResponse = new GZIPResponseWrapper(response);
chain.doFilter(req, wrappedResponse);
wrappedResponse.finishResponse();
return;
}
chain.doFilter(req, res);
}
}
or you can use a performance optimization library like WebUtilities to enable compression as described here https://github.com/rpatil26/webutilities/wiki/Enable-Compression
See also:
Compress components with gzip - Java EE
In Jboss EAP 7.0 this worked for me:
edit: Standalone.xml
<subsystem xmlns="urn:jboss:domain:undertow:1.2"> <!-- SEARCH FOR THIS: urn:jboss:domain:undertow -->
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http"/>
<host name="default-host" alias="localhost">
(...)
<!-- ADD THIS FOR GZIP COMPRESSION -->
<filter-ref name="gzipFilter" predicate="exists['%{o,Content-Type}'] and regex[pattern='(?:application/javascript|text/css|text/html|text/xml|application/json)(;.*)?', value=%{o,Content-Type}, full-match=true]"/>
<!-- /GZIP COMPRESSION -->
</host>
</server>
(...)
<filters>
(...)
<!-- ADD THIS FOR GZIP COMPRESSION -->
<gzip name="gzipFilter"/>
<!-- /GZIP COMPRESSION -->
</filters>
</subsystem>
Restart the server
Related
We have recently migrated and deployed our application.EAR (API's) packages in wildfly 13.0.0.Final from GlassFish 3 in Linux environment. While testing application api's its not supporting scandic characters and giving below error (Error copied from server.log from wildfly). But the same test request working fine with the application api's deployed in GlassFish server. I tried to study so many blogs related to wildfly but could not get any solutions. Could some one help here please.
I tired below setting changes in standalone.xml file to set the charset to UTF-8, but its not helped.
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" url-charset="UTF-8"/>
<servlet-container name="default" default-encoding="UTF-8">
2018-07-13 17:06:45,189 DEBUG [io.undertow.request.io] (default I/O-4) UT005014: Failed to parse request: io.undertow.util.BadRequestException: UT000165: Invalid character ä in request-target
at io.undertow.server.protocol.http.HttpRequestParser.handleQueryParameters(HttpRequestParser.java:523)
at io.undertow.server.protocol.http.HttpRequestParser.beginQueryParameters(HttpRequestParser.java:486)
at io.undertow.server.protocol.http.HttpRequestParser.handlePath(HttpRequestParser.java:410)
at io.undertow.server.protocol.http.HttpRequestParser.handle(HttpRequestParser.java:248)
at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:187)
at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:136)
at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:147)
at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:93)
at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:52)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:291)
at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:286)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.nio.QueuedNioTcpServer$1.run(QueuedNioTcpServer.java:131)
at org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:612)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:479)
Below is the request XML which we are sending to application deployed in both Wildfly and GlassFish
<SOAP-ENV:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<StartHeader SOAP-ENV:actor="http://schemas.xmlsoap.org/soap/actor/next" SOAP-ENV:mustUnderstand="0" xmlns="http://www.openuri.org/2002/04/soap/conversation/">
<callbackLocation>http://TESTUI</callbackLocation>
</StartHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ListAttributeValues xmlns="http://www.openuri.org/" xmlns:v001="http://xml.comptel.com/NIMS/address/listAttribteValuesRequest/v002" xmlns:v0011="http://xml.comptel.com/NIMS/address/v002">
<listAttributeValuesRequest xsi:schemaLocation="http://xml.comptel.com/NIMS/address/listAttributeValuesRequest/v002 http://xml.comptel.com/NIMS/address/listAttributeValuesRequest/v002" xmlns="http://xml.comptel.com/NIMS/address/listAttributeValuesRequest/v002" xmlns:spec="http://xml.comptel.com/NIMS/address/v002" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spec:searchItemList>
<spec:attribute>
<spec:name>district</spec:name>
<spec:value>Jär</spec:value>
</spec:attribute>
</spec:searchItemList>
<spec:attributeName>district</spec:attributeName>
<spec:maxItems>100</spec:maxItems>
</listAttributeValuesRequest>
</ListAttributeValues>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Finally i managed to fix the problem with help of JBossDevelopers community
I don't think it's the contents of SOAP message that is the problem, but the URI that is used to touch the web service. Problem can be fixed using any of the below option. Option 2 will be recommended for latest wildfly versions where undertow subsystem introduced.
By adding the following Java option to startup script :
-Dorg.wildfly.undertow.ALLOW_UNESCAPED_CHARACTERS_IN_URL=true
or we can set the allow-unescaped-characters-in-url="true" and url-charset="windows-1252" flags in the undertow subsystem in standalone.xml file.
I think these options were added as part of the undertow:6.0 schema as attributes of the https-listener and http-listener elements.
See here:
wildfly/wildfly-undertow_6_0.xsd at master · wildfly/wildfly · GitHub
An example configuration:
wildfly/undertow-6.0.xml at master · wildfly/wildfly · GitHub
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);
}
}
I had done web scan for an application(built in struts and hibernate framework) deployed in jboss 5 which reported "Set-cookie does not use HTTPOnly keyword. The web application does not utilize HTTPOnly cookies". What does it mean. I looked for some post and just added one line in my jboss/deploy/jbossweb.sar/context.xml as
<SessionCookie secure="true" useHttpOnly="true" >
After setting that, I am getting error while running the application. Is there any configuration that I am missing?
try this:
<SessionCookie secure="true" httpOnly="true" />
What does it mean
The HttpOnly flag in a http response header indicates to the browser that client-side access to the JSESSION_ID or other session-cookie type identifier should not be permitted. What this is intended to prevent is a malicious access to the session token via client side scripts in an XSS(or other attack involving session hijacking from the client side). Currently almost all major browsers support this flag(see this list for supporting browsers), but it's simply ignored in browsers that don't support it. See more info on this at the OWASP site
Setting it up is similar for tomcat and forks of it, including Jboss, by including the following in your context file:
<session-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
or
<SessionCookie secure="true" httpOnly="true" />
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.
I am working on a project using Netbeans with Glassfish 3.1 and am trying to implement LDAP authorization. To do so, I also have an LDAP-enabled Apache2 server using mod_jk. The gist is, when an user visits any page on the site in the /sng/ directory, the Apache server should ask for credentials and forward the user to the Glassfish server that is running that part of the site.
Apache is properly queueing for, and accepting, LDAP credentials and then forwarding the user to the appropriate area. But it seems that the REMOTE_USER variable is either not being set by Apache and/or not sent by mod_jk. Related configuration files and code snippets follow:
httpd.conf
<Location />
AuthBasicProvider ldap
AuthLDAPURL ldap://mainframe/ou=People,dc=dtch,dc=com?uid?sub
AuthzLDAPAuthoritative off
AuthType Basic
AuthName "LDAP"
require valid-user
Options Indexes FollowSymLinks MultiViews +Includes
</Location>
conf.d/jk
JKWorersFile /path/to/workers.properties
JkShmFile /path/to/mod_jk.shm
JkLogFile /path/to/mod_jk.log
JkLogLevel info
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
workers.properties
worker.list=worker1
worker.worker1.port=8009
worker.worker1.host=127.0.0.1
worker.worker1.type=ajp13
sites-enabled/000-default
...
JkMount /*.jsp worker1
JkMount /sng/* worker1
web.xml
<filter>
<filter-name>RemoteUser</filter-name>
<filter-class>path.to.RemoteUser</filter-class>
</filter>
<filter-mapping>
<filter-name>RemoteUser</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
RemoteUser.java
//...
public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain )
throws IOException, ServletException
{
if( request instanceof HttpServletRequest )
{
HttpServletRequest httpServletRequest = ( HttpServletRequest )request;
String username = httpServletRequest.getHeader( "REMOTE_USER" );
if( username == null )
{
// enter here every time
}
// ...
}
//...
}
Finally I have registered a listener in the Glassfish control panel:
In short, I have no idea why null is being returned constantly and my searches on the internet have been of no help. Thanks in advance for any input you may provide.
note: httpServletRequest.getRemoteUser( ) provides the same null result.
I too had this problem. I found an answer by accident on another post. You have to update your server.xml in tomcat as follows:
<Connector protocol="AJP/1.3" port="..." ...
tomcatAuthentication="false" />
The tomcatAuthentication must be specified. Once I made the update, bounced tomcat, getRemoteUser() worked for me.
I was never able to retrieve a RemoteUser header, but I found a work-around in the form of the authorization header. Using getHeader( "authorization" ) returned to me a string in the form of:
Basic XXXX:YYYY
Where X is the username, and Y the password of the user accessing the page through Apache/mod_jk.
The portion of the string following 'Basic ' (X:Y) was Base64 encoded, so after decoding it with MiGBase64 I was finally provided with an username that I could use.