EOFException: null while applying gzip to dropwizard along with Filter - gzip

We are facing exception using dropwizard-core:1.1.2 while trying to add gzip content-encoding at service response headers. The details are as follows:
GzipFilter.class
public class GzipFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Content-Encoding", "gzip");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}
Service.class
#Override
public void run(DocumentServiceConfig config, Environment environment) throws Exception {
Injector injector = createInjector(config, environment);
environment.jersey().register(injector.getInstance(SomeResource.class));
environment.servlets().addFilter("Gzip-Filter", GzipFilter.class).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");
config.yml
gzip:
enabled: true
minimumEntitySize: 256B
bufferSize: 32KB
Exception stack trace for 500 API response -
WARN [2017-08-04 00:48:20,713] org.eclipse.jetty.server.HttpChannel: /clients/v2
! java.io.EOFException: null
! at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:268)
! at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:258)
! at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:164)
! at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
! at io.dropwizard.jetty.BiDiGzipHandler.wrapGzippedRequest(BiDiGzipHandler.java:100)
! at io.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.java:64)
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:56)
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:169)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
! at org.eclipse.jetty.server.Server.handle(Server.java:564)
! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
! at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
! at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
! at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
! at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:122)
! at org.eclipse.jetty.util.thread.strategy.ExecutingExecutionStrategy.invoke(ExecutingExecutionStrategy.java:58)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:201)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:133)
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
! at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
! at java.lang.Thread.run(Thread.java:745)

Confused though whether or not I should answer this myself. Yet, since the details for the update are semi resolving the issue hence answering this myself.
Went ahead describing the same to Dropwizard#Issues#2126
Quoting #arteam here to provide the solution to the current implementation.
I believe Dropwizard does gzip compression automatically. The support
for gzip is enabled by default (see
http://www.dropwizard.io/1.1.2/docs/manual/configuration.html#gzip).
So, if the client supports decompression by sending a request with the
Accept-Encoding:gzip header,
org.eclipse.jetty.server.handler.gzip.GzipHandler will compress the
response and add the Content-Encoding: gzip header.
Well the question still remains though, for which I am still not marking this as an answer to this question:
Why your custom filter doesn't work is not clear, maybe your filter is executed before the Jersey servlet and it rewrites the header.
So all that was needed was to implement the service.yml changes as:
gzip:
enabled: true
minimumEntitySize: 256B
bufferSize: 32KB
and not implement any CustomFilter which ends up overriding the current implementation and not just override but result in the titled exception.
Another point to note is, that this shall be tested against the response size of both more and less than the minimumEntitySize as specified in the configuration.

Related

Call finally if requst processing fails in jax-rs/jersey

I'm trying to implement a logic similar to what i've done with Spring:
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
MyContext.clear();
try {
filterChain.doFilter(request, response);
} finally {
MyContext.clear();
}
}
Finally here ensures that even if somewhere down the line of request processing something bad happens we still clear the context. It is important because we've faced an issue of context pollution when a thread with already initialized context is later reused (context in this case is an InheritableThreadLocal containing some value associated with a particular request).
The problem is, i don't see a way to do something similar with jax-rs - filters are not supposed to know anything about the chain it seems so obviously finally on a ContainerRequestFilter only works within this filter, not the whole chain.
Where can i place finally block so that it would be called when request processing fails?

Bluemix force HTTPS on Spring Boot application

I have a Spring Boot application that is pushed on Bluemix as a CF app.
It works efficiently with the http protocol. However if i tried to force https, I get a 502 error.
I have:
#Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel().anyRequest().requiresSecure();
//http.csrf().disable();
}
}
And I have an application.properties file with those entries:
server.ssl.key-store = classpath:**.jks
server.ssl.key-store-password = *******
server.ssl.key-password = ******
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
I am aware that Bluemix performs SSL termination; in fact it sets correctly x-forwarded-proto and x-forwarded-for. I looked for solutions like 1 and 2 but without any luck.
I then tried with the following solution, as suggested in this article but a received a redirect loop insted:
#Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory(){
return new TomcatEmbeddedServletContainerFactory() {
#Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
}
What did I miss in my approach? Many thanks for any tips/suggestions you may provide me
For the sake of the community, it would be good to see Rob's comment accepted as the answer. Rob, feel free to add your own answer if you would rather see that accepted instead.
Tomcat is not detecting the x-forwarded headers as being a trusted proxy. Try setting server.tomcat.internal-proxies=.* and logging.level.org.apache.catalina.valves=DEBUG

How can i add response header to a pdf in CQ5

I am trying add canonical tags to PDF and for that i have to update response header when PDF is loaded. I was able to add header for cq:page very easily:
#SlingServlet(
resourceTypes = "cq:Page",
extensions = "html",
methods = "GET")
#Properties({
#Property(name = "service.description", value = "Servlet to handle all incoming widget modification")
})
public class canocalizePDF extends SlingAllMethodsServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
response.addHeader(“canonical", “test");
}
#Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
}
}
But when i try to same for PDF, it is not working. I have tried dam:Asset, dam:AssetContent as resourceTypes, but nothing seems to be working.
Any help would be great.
Thanks,
Vishal
The servlet that you've written is not handling your asset requests. If you want to handle this in AEM, you will need to override the OOTB AEM's AssetDownloadServlet with your own servlet implementation. You can then add the canonical link header in your servlet response.
How to override this is explained in detail in this blog post. They've also included a link to sample code for this customization.
However, if you have a webserver (e.g. Apache) in your setup, you should really handle this there. This is shown in this Moz blog post. Moz is the pinnacle of SEO best practices. I will recommend that.

Bad CRC32 in GZIP stream

I am using DevForce 2010 and Silverlight 4.
When saving entities that contain large amount of binary data, I get this error:
Unhandled Error in Silverlight Application The remote server returned an error: NotFound.
When debuging the application I see these errors:
Unhandled Error in Silverlight Application Insufficient memory to continue the execution of the program.
Bad CRC32 in GZIP stream.
I found this thread on Ideablades forum that discusses the problem: http://www.ideablade.com/forum/forum_posts.asp?TID=3361&PN=1&title=bad-crc32-in-gzip-stream
Is this a problem on the server or client?
Is this a problem that has been resolved in any new version of DevForce 2010?
My server has 4 GB memory. Would increasing the memory resolve the problem?
Or what would be the right solution?
Yes, the OnEndpointCreated overrides on both client and server are where you should add the customization. You can add the following to remove GZIP from the binding:
public override void OnEndpointCreated(System.ServiceModel.Description.ServiceEndpoint endpoint)
{
if (endpoint.Binding is CustomBinding)
{
var binding = endpoint.Binding as CustomBinding;
var elements = binding.CreateBindingElements();
// Swap out existing (GZIP) message encoding for binary
var encoding = elements.Find<MessageEncodingBindingElement>();
if (encoding != null)
{
elements.Remove(encoding);
encoding = new BinaryMessageEncodingBindingElement();
elements.Insert(0, encoding);
endpoint.Binding = new CustomBinding(elements);
}
}
}
DevForce will find your classes if they're in an assembly probed on the client/server.
This will turn off compression for everything from your DevForce client to the EntityServer, so may be a bit heavy-handed. You can turn on IIS compression to compress data sent to the client to help.
There haven't been any changes to GZIP processing since the 6.1.7 release of DevForce 2010. That thread still contains the best information of how to work around the problem: 1) modify the save logic or your entity definition to reduce the amount of data saved; 2) turn off use of GZIP; or 3) write a custom message encoder with another compression library.
Thank you Kim Johnson,
I have looked at the samples and I feel uncomfortable adding those config files and maybe breaking something that works fine today.
If I go the code-way, will I be ably to switch off GZIP and still retain the rest of the default settings for DevForce?
I guess the code below is what I should go for?
If I save these classes on the client and server, will DevForce automatically find these classes?
//Client
using System.ServiceModel.Channels;
using IdeaBlade.Core.Wcf.Extensions;
public class ProxyEvents : IdeaBlade.EntityModel.ServiceProxyEvents {
public override void OnEndpointCreated(System.ServiceModel.Description.ServiceEndpoint endpoint) {
base.OnEndpointCreated(endpoint);
// My client code turning GZIP off comes here?
}
public override void OnFactoryCreated(System.ServiceModel.ChannelFactory factory) {
base.OnFactoryCreated(factory);
}
}
//Server
using System.ServiceModel.Channels;
using IdeaBlade.Core.Wcf.Extensions;
public class ServiceEvents : IdeaBlade.EntityModel.Server.ServiceHostEvents {
public override void OnEndpointCreated(System.ServiceModel.Description.ServiceEndpoint endpoint) {
base.OnEndpointCreated(endpoint);
// My server code turning GZIP off comes here?
}
public override void OnServiceHostCreated(System.ServiceModel.ServiceHost host) {
base.OnServiceHostCreated(host);
}
}

Nancyfx executes the route but does not return a result. (Running on Raspberry pi Mono)

Im currently running Mono JIT compiler version 2.10.8.1 (Debian 2.10.8.1-5) on my raspberry pi. I compiled the nancyfx monorelease configuration from master branch.
The application starts as expected
Nancy now listening - navigating to http://localhost:8888/nancy/.
Press enter to stop
I then run a test as follows
pi#raspberrypi ~ $ wget http://localhost:8888/nancy/
--2013-04-13 06:39:12-- http://localhost:8888/nancy/
Resolving localhost (localhost)... 127.0.0.1, ::1
Connecting to localhost (localhost)|127.0.0.1|:8888... connected.
HTTP request sent, awaiting response...
This will never complete. It just sits there.
I have added some logging and I can see that it processes the route action on the module but it never seems to return the http response.
Has anyone seen this before? Is there a way to add more exception catching?
The following revealed nothing.
public class LoggingErrorHandler : IErrorHandler
{
private readonly ILog _logger = LogManager.GetLogger(typeof(LoggingErrorHandler));
public bool HandlesStatusCode(HttpStatusCode statusCode)
{
return statusCode == HttpStatusCode.InternalServerError;
}
public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
{
return statusCode == HttpStatusCode.InternalServerError;
}
public void Handle(HttpStatusCode statusCode, NancyContext context)
{
object errorObject;
context.Items.TryGetValue(NancyEngine.ERROR_EXCEPTION, out errorObject);
var error = errorObject as Exception;
_logger.Error("Unhandled error", error);
}
}
Any ideas ?
Thanks
I've never seen this - what is it you're returning? When you create the NancyHost you can provide a HostConfiguration object, and one of the properties on that is UnhandledExceptionCallback which may shed some light on what's going wrong.