Jersey REST URISyntaxException - glassfish

I am facing an issue at our glassfish 3.1.2 production server. I have a Jersey REST project deployed and it is throwing URISyntaxException when there is a 'space' in path parameter for any URL. For example if I hit this URL: http://MyDomain:8080/MyApp/MyVersion/MyService/MyPathParam/My%20Path%20param
Jersey throws java.lang.IllegalArgumentException with root cause java.net.URISyntaxException: Illegal character in path at index 155: http://MyDomain:8080/MyApp/MyVersion/MyService/MyPathParam/My Path param
The error does not occurs for query parameter.
This issue is not reproducible at test environment. Is there any possibility at production glassfish which decodes path parameters before Jersey gets them and jersey throws the above exception? I gone through this link which specifies that glassfish has the facility to decode the request parameters before it reaches to our application, but I didn't get the clear idea. Please help me to get rid of this issue.

It is not a good policy to use "spaces" on URLs (URIs) - see more discussion here Is a URL allowed to contain a space?. They are considered "unsafe" (http://www.ietf.org/rfc/rfc1738.txt):
The space character is unsafe because significant spaces may disappear and insignificant spaces may be introduced when URLs are transcribed or typeset or subjected to the treatment of word-processing programs.
Not sure if some "containers" allow this on the URIs (the "query parameters" may be allowed as they are encoded), but even if some allow you should seriously consider not using them. Not sure if this fits your scenario, but you could try URLEncoder.encode() as suggested in this other questions where a similar exception is raised: What I have to do to solve "java.lang.IllegalArgumentException"? (although in the same question there is a debate about using "spaces"... but maybe this is useful for you).

The Apache Load Balancer was the culprit! mod_jk was decoding the URL and it was forwarding decoded URL to one of the glassfish server. Hence jersey jax rs was throwing URISyntaxException. Issue resolved by changing the property JkOptions of mod_jk configuration from +ForwardURICompat to +ForwardURICompatUnparsed

Related

Reverse proxy support in Quarkus

I have Embedded Jetty running which has reverse proxy servlet mapped for a particular URL. For ex: http://url1/abc is reverse proxied to http://url2. This works great, whenever someone calls http://url1/abc, data is served from http://url2.
I want to achieve the same using quarkus. Is this possible to do it in Quarkus? I think one of the option is to write own code in ContainerRequestFilter but I am looking more for OOTB support just like jetty. Can somehow undertow be leveraged here?
Please help.
UPDATE 1
I tried to do it through undertow-handlers.conf (placing it in META-INF folder). It worked well for redirect and rewrite but throwing error for reverse-proxy:
path-prefix('/a') -> redirect('/b)
path-prefix('/a1') -> rewrite('/b1')
path-prefix('/a2') -> reverse-proxy('http://localhost:7100/b')
If I have first two only, quarkus is started successfully and requests are served correctly. If I started using third one, quarkus start gets failed with below error.
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: UT000045: Error parsing predicated handler string no handler named reverse-proxy known handlers are [disallowed-methods, allowed-methods, jdbc-access-log, secure-cookie, access-log, mark-secure, response-rate-limit, canonical-path, response-code, disable-cache, ssl-headers, trace, blocking, url-decoding, access-control, redirect, set, ip-access-control, request-limit, resource, restart, clear, byte-range, done, rewrite, forwarded, stuck-thread-detector, jvm-route, learning-push, dump-request, proxy-peer-address, resolve-local-name, header, store-response, path-separator, resolve-peer-name]:
Although, I see undertow has reverse-proxy handler, not sure why it is not working for me.
http://undertow.io/undertow-docs/undertow-docs-2.0.0/index.html#predicates-attributes-and-handlers
I think the main issue is of dependency here. I see io\undertow\server\handlers package in my app libs but not io\undertow\server\handlers\proxy where I think the reverse proxy code is present.
How can I pull this dependency in my app?

Jmeter Illegal character found in host: '/' ISSUE

I tried to install Jmeter on my colleague computer when I executed http request.He has been showing this error, but I found that there is no such error in my computer. I wonder if anyone has encountered a similar problem?
My
My1
My2
Colleague
colleague1
colleague2
--
error message
java.net.MalformedURLException: Illegal character found in host: '/'
at java.base/java.net.URL.<init>(URL.java:480)
at java.base/java.net.URL.<init>(URL.java:360)
at java.base/java.net.URL.<init>(URL.java:383)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.getUrl(HTTPSamplerBase.java:1053)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1231)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1220)
at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:622)
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:546)
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:486)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:253)
at java.base/java.lang.Thread.run(Thread.java:830)
This problem occurs when using the http request sampler, putting '/' at the end of the Server Name or Ip textbox. It will work if you delete the '/' character at the end of the host information and add it to path.
This www.amazon.com/ref=nav_logo is not a valid hostname
Valid characters for hostnames are ASCII(7) letters
from a to z, the digits from 0 to 9, and the hyphen (-). A hostname
may not start with a hyphen.
In any case your URL query string is not correct, it should look like:
https://www.amazon.com/?ref=nav_logo
^mind this character
So correct HTTP Request sampler configuration would be:
Resulting into the following request observable via View Results Tree listener
Going forward be aware that you can build a JMeter Test Plan using HTTP(S) Test Script Recorder or JMeter Chrome Extension
Even though I cannot tell you why the test behaves differently on your machine vs that of your colleaugue (I would guess that you probably chose different client implementations in the advanced section of the HTTP Request Sampler), you should definitely consider what part of your URL is:
Protocol
Server Name or IP
Path
Parameter
and use the corresponding fields in JMeter accordingly.
Hint: "/ref=nav_logo" is most definitely NOT part of the Server Name.
I faced this issue and it was for simple reason. in the server name/ip address instead giving only the severname/ip address i.e server1 i had accidentally included the https://server1 and spend two hours to resolve it

Exception while dispatching incoming RPC call : encodedRequest cannot be empty

The similar problem is described here: GWT IllegalArgumentException: encodedRequest cannot be empty
My GWT application is deployed in Tomcat6, which is linked with Apache by using Coyote/JK2 connectors. For SSO I use the mod_auth_sspi/1.0.4.
When I use IE8, pages is not displayed, but for Firefox everything OK. In Tomcat logs I see the following:
SEVERE: Exception while dispatching incoming RPC call
java.lang.IllegalArgumentException: encodedRequest cannot be empty
at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:232)
at org.spring4gwt.server.SpringGwtRemoteServiceServlet.processCall(SpringGwtRemoteServiceServlet.java:32)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at gov.department.it.server.RequestInterceptorFilter.doFilter(RequestInterceptorFilter.java:90)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:311)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:619)
What have I tried so far:
1) Can't find the registry key DisableNTLMPreAuth (IMHO it's not the solution, because in my case IE 8 is actively used).
2) I have installed and configured the Native Windows Authentication Framework WAFFLE
web.xml:
...
<filter>
<filter-name>NegotiateSecurityFilter</filter-name>
<filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>
<init-param>
<param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
<param-value>NTLM</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>NegotiateSecurityFilter</filter-name>
<url-pattern>/my-app/*</url-pattern>
</filter-mapping>
...
But it did not help.
3) In worker.properties I set socket_keepalive=0, but it did not help too -
worker.ajp13.type=ajp13
worker.ajp13.host=localhost
worker.ajp13.port=8009
worker.ajp13.lbfactor=50
worker.ajp13.cachesize=10
worker.ajp13.cache_timeout=600
worker.ajp13.socket_keepalive=0
worker.ajp13.socket_timeout=300
What else can I try to do?
You have rediscovered the 7 year old bug #1 in mod_auth_sspi which has affected numerous projects, frustrated numerous developers, and caused uncountable wasted man-hours over the years. Yet it still stands unresolved because the maintainer doesn't consider it a bug. Nor has it been addressed by Microsoft for older browsers, because indications are that IE9 doesn't have this problem.
Cause
It is caused by IE trying to be 'smart' and sending a zero content-length POST (I named it 0POST to try making it an indexable term to benefit those who rediscover it in the next 7 years.) with an NTLM auth header in anticipation of being challenged by the server. IE does this when it has been authenticated before in that protection space. So it knows that it will be challenged again. Sadly mod_auth_sspi is not as smart as IE, so bad things happen on the server side when a 0POST arrives and it is let through to the apps without being challenged. Except that sometimes this can happen even for unprotected areas, if they are under an area that requires authentication.
Other browsers don't pretend to be as smart as IE and don't try to save a few bytes on the first round trip for "performance", so they don't run into this problem. Here is Microsoft's explanation of this behavior.
Horrible Workaround
In Apache httpd.conf set
SSPIPerRequestAuth On
This is equivalent to the DisableNTLMPreAuth IE client-side fix you mentioned, which is impractical for a large user group. Plus it amounts to crippling all non-Apache apps also, which may be capable of handling a 0POST. There are literally NO examples of this setting being discussed or its side effects explained on the web, so I am including this only link I found that sheds some light on it. Anyway, making one server side change seems to be the lesser of the two evils. Although now, by changing the server config, you have crippled all other innocent browsers visiting this site as well.
The problem with this workaround is that it forces EVERY request to perform an SSPI handshake which results in a lot of extra 401 traffic and can affect performance. For performance, NTLM authentication is treated as 'session-based' not 'request-based' which means that the handshake occurs only at the start of the session. When using this setting, you should also set filters to prevent your log filling up with 401s. Also note that this requires KeepAlive to be turned on.
I am not sure your setup is the same as the one described in the WAFFLE fix; were they using Apache like you? I think WAFFLE applies to Tomcat, whereas you have Apache in front, so Apache is handling authentication. You might consider using that setup instead of Apache. If you can use that setup, it may be a better option than this workaround because WAFFLE has explicitly accounted for 0POST and can handle it. The author had also discovered this gem while working with GWT like you.
Interestingly, for jcifs, a fix for this very issue was posted 9 Years ago. The author also provided an excellent explanation later:
The code in the filter examines all HTTP POST requests and determines
if they contain an NTLM type 1 message. If the request contains an
NTLM type 1 message, the filter responds with a dummy type 2 message
to entertain IE's desire to re-negotiate NTLM prior to submitting any
POST data. The browser should then respond with an NTLM type 3
message along with the post data which the filter should then allow to
chain to the rest of the web application.
A simple patch was also created for mod_auth_sspi 5 years ago, if you are interested. See diff in the author's own repo. I am not sure if I agree with that approach though. It tries to detect IE/0POST, whereas I think the right fix should be to detect if the client is requesting auth with a NTLM Type 1 header, as in the jcifs filter. (Type 1 simply means that it is the first message of the handshake)
I wonder if anyone has used alternatives to mod_auth_sspi like mod_auth_ntlm_winbind and if they don't exhibit this behavior. If you have, please leave a comment. We already know WAFFLE works, but it is not a mod_auth_sspi replacement.
One alternative is to forget NTLM and use Kerberos, (mod_auth_kerb) but many people find that too complicated to setup. IE will behave this way on any challenge-response scheme, so odds are that kerb auth could run into the same problem, since a similar 401 sequence happens in both cases. But being a different module, its possible it is capable of handling this.
Lastly, I should mention that there is yet another issue that this per-request auth workaround doesn't seem to fix. I haven't seen it discussed anywhere, but I have found that sometimes after the 0POST, the server waits for a very long time before it responds with the final 200 response with the results of the (proper) POST. This long delay happens only in the end though, NOT immediately in response to the 0POST. That goes fine, and the handshake completes, but the server doesn't respond until after a long wait which I have noticed is suspiciously close to 90 seconds, like some sort of timeout. The practical result of this is that when users log in, IE8 will sometimes hang for 90sec waiting for server response. I thought the KeepAlive might be causing it, but it is not even explicitly defined in my config, so I assume it is at the 15sec Apache default. But I am sure this is related to the 0POST, because it happens only right after a successful 0POST auth handshake. Our server is in a separate (2-way) trusted domain across a firewall, so maybe that has something to do with it.
Diverse Examples of This Issue
https://confluence.atlassian.com/display/JIRAKB/NullPointerException+when+Authenticating+from+IE
http://trac.edgewall.org/ticket/2696
http://trac.edgewall.org/ticket/4560
https://drupal.org/node/82530
http://www.webmasterworld.com/apache/3087425.htm
Why "Content-Length: 0" in POST requests?
https://jira.springsource.org/browse/SEC-1087
The most hilarious example is how IE's smartness affected Microsoft's own products! They themselves couldn't understand how to deal with IE's behavior, causing a bug in ISA Server 2006.
http://support.microsoft.com/kb/942638

405 (POST not allowed) HttpException when trying to apply HttpResponse.Filter

We are getting a 405 error and the following exception from IIS7 when attempting to apply a ResponseStreamFilter to HttpResponse.Filter:
HttpException:
The HTTP verb POST used to access path '/app/Thing.asmx/Command' is not allowed.
We are applying the filter by using an HttpModule with code like this:
var rfs = new ResponseFilterStream(HttpContext.Current.Response.Filter);
rfs.TransformStream +=
new Func<System.IO.MemoryStream, System.IO.MemoryStream>(ProcessStream);
HttpContext.Current.Response.Filter = rfs;
Log("Response stream filter applied correctly.");
All of the code in our HttpModule works just fine... it's all wrapped in a try-catch just to be safe and isn't throwing any exceptions, and diagnostic logging like the last line above is working correctly.
But it looks like our ProcessStream method in the above code is never being called. If we apply the filter to HttpResponse.Filter at all, IIS throws the 405 exception before our filter begins processing.
Our code has worked before on several similar systems, so we suspect IIS/machine configuration on this specific server is responsible. What could be causing this?
The most commonly reported cause for a 405 error in a situation like this seems to be using Url.Rewrite. (The HTTP verb POST used to access path '/test.html' is not allowed) However, we are never using a Url.Rewrite.
Another commonly reported cause is trailing slashes in the request URL. (HTTP 405 on Error on HTTP POST IIS ASP .NET) But as mentioned above, the URL being requested does not end with a slash.
The app pool is running .NET 4.0 in a Classic pipeline (jQuery AJAX post receives 405 error (HTTP verb POST not allowed)), but our code has run without issue on many other systems under a Classic app pool, so there would still have to be something unique to this server's configuration. Changing to Integrated pipeline breaks the application our code is filtering, so that's not a possible workaround anyway.
Turns out, it was a very obscure IIS bug:
http://support.microsoft.com/kb/980368
The ExtensionlessUrl handler (*.) was incorrectly getting involved with the request instead of just the WebServiceHandlerFactory (*.asmx) as expected. The workaround was:
Manually deleting the ExtensionlessUrl handler entries from the web application's handler mappings
Manually moving the ExtensionlessUrl handler entries under anything you actually expect to be hit
Adding a web.config entry under system.webServer/handlers to remove the ExtensionslessUrl handler as needed (we went with this option to make sure it got included with app demployment)
We had to burn a Microsoft support ticket on this one, since there's no way we would have figured this out in any reasonable timeframe. Hopefully this helps someone else.

'Communication Error' When I Query Solr, Only in IE?

When I try to ping Solr, I get a failure only in IE.
if (!$solr->ping()) {
echo 'service not available';
}
The connection is identical when using var_dump in both IE and other browsers. It's running on the standard Solr port, localhost, and the path is correct. Unsure how a different browser would affect a connection to Solr.
Solr Specification Version: 1.4.1.2011.09.12.09.25.21
Oddly enough, it seems that allow_url_fopen not being enabled was the root cause of this issue. Unrelated, seemingly, so I'd assume the issue was with the WordPress plugin used. I'd have to guess some odd implementation made this fail silently and cause issues only in IE.
Probably too specific to my case to help others, but thought I'd share.