In the migration of a project that works correctly under Tomcat 7 to Tomcat 9 I am receiving the error Invalid character found in the request target when passing words with accents in the request.
The server.xml file was modified by introducing in the connector URIEncoding="UTF-8" and the clause relaxedQueryChars= áÁéÉíÍóÓúÚ was also introduced, but I still receive the same error. I can't touch the actual code of the project.
log traces show this: java.lang.IllegalArgumentException: Invalid character found in the request target [/sahab/lupaDem.do?filtro=LupaDem¶m1=1¶m2=29527¶m3=OBSERVACI0xd3N%20ANTIRR0xc1BICA
HTTP does not allow to specify an encoding for the requested path. Thus in the past servers used OS settings which were actually confusing especially for applications used world-wide.
Therefore the standard established to always encode requests as UTF-8, and even then there is the URLEncoding which would prevent UTF-8 problems by %-escaping any special characters.
In a nutshell, ensure your requests are properly encoded. Previous versions of Tomcat may not have errored on this. The requests are coming from the client, not the server itself.
Related
I noticed that Glassfish-5 web server sends responses with only one Set-Cookie header, which contains several cookies. When I looking with firebug, I can see that they are separated by unknown character. Anyway - the Firefox reads only the first cookie. How to configure Glassfish5 to send several Set-Cookie headers - one for each cookie? rfc6265 states that:
Overview ... Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single header field. The usual mechanism for
folding HTTP headers fields (i.e., as defined in [RFC2616]) might
change the semantics of the Set-Cookie header field because the
%x2C (",") character is used by Set-Cookie in a way that conflicts
with such folding. ...
Also here it is stated:
When sending an HTTP Response with multiple cookies, CFHTTPMessage
combines the cookies into a comma-separated list under a single
"Set-Cookie" HTTP header. (This is referred to as
"set-cookie-folding".)
Set-cookie-folding is NOT supported on Google Chrome, Firefox, and
Internet Explorer. Each of those browsers will completely ignore every
cookie after the first comma, rendering CFHTTPMessage completely
useless for handling HTTP responses with multiple cookies in any
browser other than Safari (which supports cookie-folding).
This is how the response looks on firebug:
Two cookies are joint by unknown character. As I noticed - other servers like Apache splits multiple cookies in one Set-Cookie header by new line character.
I've noticed that this happens only on HTTPS connections.
Also, I've opened an issue on Github here.
Tried the same web application to run on Tomcat 9 web server - Set-Cookie header cookies are separated by new line character, it's working like expected...
The same response, but on Glassfish5, and again - cookies are joined by unknown character, and are not accepted by Firefox (just the first one):
In NetBeans IDE 8.2 HTTP Server Monitor I can see, that 2 cookies are sent - it looks ok:
Once again on FireFox - 2 cookies in one Set-Cookie header:
Received only one - and the value is not correct... :
The same on Firefox Developer Edition:
Totally confused..
Glassfish 5 uses Grizzly Framework 2.4.0 - I think sources available in grizzly-http-servlet-2.4.0-sources.jar - but can not find a code piece where the cookies are joined together in one line..
I can confirm now that it is related only to HTTP/2.0 protocol, tested on firefox by enabling/disabling network.http.spdy.enabled.http2 in about:config. On HTTP/1.1 via HTTPS cookies are set as expected.
In a series of comments that we deleted since, I pointed that the weird responses were all http2, and gave directions to disable it server-side, as a work-around. Now to make room for other constructive comments (or answers) we deleted the old ones, and I rehashed them as a separate answer below.
It seems Grizzly's http2 filters are misbehaving (well let's assume that for a moment). Your Firefox screenshots are showing HTTP/2.0. NetBeans server monitor works OK likely because it does not support http2, so your server falls back to HTTP/1.1 in that case. (Edit: that was just a supposition, and a more recent comment hints that it might support http2...)
Grizzly supports HTTP2 since 2.4.0 but you have to explicitly enable it... and GlassFish does that by default.
How to configure Glassfish5 to send several Set-Cookie headers - one for each cookie?
While the Glassfish/Grizzly team works on fixing the (apparent) bug, you can disable http2 in GlassFish as a work-around.
Assuming your HTTPS listener is http-listener-2 you can do this from the command line:
asadmin set server.network-config.protocols.protocol.http-listener-2.http.http2-enabled=false
As far as I know this setting is not documented yet, I inferred the command above from this #Attribute in source code (and followed it through the code until GenericGrizzlyListener). In addition, it seems that attribute is not exposed in the admin console so I see no other way than using asadmin set as above (please note the "Version" attribute is a distinct setting).
I based my research on "latest promoted build" (b19 at that time, "latest nightly" would be b20). Links to GitHub point to b19.
You no longer need that custom nucleus-grizzly-all.jar. The issue has been released as part of the most recent Glassfish 5.0 nightlies and the most recent promoted build.
There were two different issues as I tracked the actual fix with a Grizzly issue and used the GlassFish issue for integration of Grizzly.
The problem is now solved by professional glassfish team - we should change the file nucleus-grizzly-all.jar file with new one - available here at GitHub. Once again - many thanks to glassfish developer team!
I have a Tomcat server running Java servlets. I'm trying to make a servlet that returns stored files, given their encrypted IDs.
ID: 100
Encrypted ID: +e4/E5cR/aM=
URL-encoded ID: %2Be4%2FE5cR%2FaM%3D
Resulting URL: http://localhost/file/demo/%2Be4%2FE5cR%2FaM%3D
When I try to follow that link, I don't even get into my servlet's code - the server returns this error: Failed to load resource: the server responded with a status of 400 (Bad Request)
What's wrong with this URL that's making Tomcat reject it before reaching my code? I ran it though a URL-encoder, and I don't see any invalid characters in it.
You have slash "/" encoded in the url. Apache doesn't allow them due to potential atacks. There is setting to allow them:
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
or
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
See similar post.
You are likely experiencing one of 2 issues:
1) You have not included the port in your URL. Either you have configured the Tomcat port to port 80, in which case the port is not needed, or you need to include the port, which defaults to 8080, for example:
http://localhost:8080/file/demo/%2Be4%2FE5cR%2FaM%3D
2) You are adding the encrypted ID as part of the URL itself, which would have to be mapped to a Servlet/JSP/View of some sort in your URL mappings and is not likely. Tomcat is not going to recognize a unique ID and know a corresponding handler to call to process the mapping. Assuming you intend to call the servlet/JSP/controller that is mapped to '/file/demo', you would more likely want to pass the ID as a request parameter, for example:
http://localhost:8080/file/demo?id=%2Be4%2FE5cR%2FaM%3D
We have :
a webdav server running on Linux (java application)
a client on Windows 7, using ms-word 2010
The urls to open our files end with the files' names, and are encoded in UTF-8 before to be sent to the UI :
server.com/path/my_file_name.doc
It works perfectly with file names without special characters but with an ugly url like
server.com/path/En-tête de lettre + capital 1 050 000 €.doc
, our server does not manage to access to the file.
In the stack trace, we can see that the url received by the server is
server.com/path/En-tête de lettre + capital 1 050 000 �.doc
, but the error message that ms-word is displaying contains the right url, so I think that the original url is right.
And last but not least : it works when the server is running on a windows platform.
I suppose that ms-word re-encodes the url before transmitting it to the server, but I can't guess how to decode it.
All suggestions are welcome ^^
I'm the author of http://milton.io (java webdav server lib) and I've seen an issue where MS clients do incorrect encoding of some url's, and milton has some workarounds for that. What webdav framework/server are you using?
However, the example given looks more like mangling, as suggested by Marc B. Your server is probably outputting the propfind response in UTF-8, but windows is interpreting it as win-1252.
So you should look at the response headers and check to see what character encoding is given for the response and check that it matches the actual encoding used in the PROPFIND response.
Note that earlier versions of milton had a problem where they would use the server default encoding but always report UTF-8, so this problem would occur on any server not using UTF-8 as the default character encoding.
Im exporting a set of data to excel in java, the data has certain non ascii characters, while exporting in Windows machine the data are coming correctly in UTF-8 encoded format.But when i deploy my code in Unix machine it is not working properly.UTF-8 encoding is not working properly.
Im using Tomcat 5.5 server.I have also included URIencoding="UTF_8" parameter in server.xml. But still in unix machine it is not working properly
Running Tomcat with a
-Dfile.encoding=UTF8
option will force the VM to adopt UTF8 as it's default encoding regardless of your environment. I suspect that's your problem (and it's good practise nonetheless)
When you are working with UTF-8 data it can be very fragile. Every step in the chain needs to specify utf8.
(1) In the database, be sure the table has UTF8 encoding and collation. "show table status" will tell you this. Google for "mysql alter table utf8" for more info.
(2) The JDBC connection needs to specify the UTF8 encoding. For Connector/J this will be something similar to:
useUnicode=true&characterEncoding=UTF-8
(3) Every stream read/write, every string to byte conversion in the code needs to specify UTF-8 as the encoding. It's easy to miss one. If it's missed Java will use the system default which will vary server to server.
(4) Not applicable here, but for user submitted data from a form, you need to set the request character encoding. (I do this in a servlet filter)
request.setCharacterEncoding("UTF-8");
(5) Probably not applicable here, but if you output HTML/XML/text from your servlet, set the HTTP character encoding header. (This might apply if you are generating the Excel file as an XML file).
response.setContentType("text/html; charset=UTF-8");
I'm following Scott Davis' tutorials on developing grails apps, but whenever i try to run my app (or indeed his source code) i get "Firefox has detected that the server is redirecting the request for this address in a way that will never complete." Safari gives a similar error message as does Opera.
As i've tested the original authors source code which gives the same error i'm fairly confident it's nothing to do with the code.
Is this a problem with the web server on my machine? I use Mac OS Snow Leopard so i'm assuming it's apache that's generating this error.
Edit: Seems Grails as standard uses Jetty, so probably not Apache that is causing the problem. However also tested the app on Glassfish and i get the same error.
Anyone know what i can do to fix this?
Cheers
It depends on the code and Apache configuration you are using. I assume that the web server sends cyclic HTTP redirections, eg. from /root/ to /root (without the slash) and vice versa. This causes a redirection infinite loop.
Check your configuration on conditions that cause a HTTP redirect. For example, Apache automatically adds slashes to directory URLs in standard configuration (like the /root/ example above). I don't know Grails, so I cannot give you a hint on how URLs are processed within the app.
You can also use manual HTTP requests for debugging to see whats going on behind the scenes, using telnet on a terminal:
$ telnet localhost 80
GET / HTTP/1.0
I guess the response will be something like that:
HTTP/1.0 302 Found
Location: XXX
...
Now do a second request on the URL passed in the Location header and so on.
I was getting the same error a little while ago, heres how I fixed:
Try the same page on a different internet setup (it could be your ISP)
Open up Safari, Firefox or whatever your using and empty the cache and delete ALL your cookies
Reboot your computer and try again
It may work now, but if it doesn't:
open up Firefox and type 'about:config' (without the quotes) into the URL bar
You will get some little warning, just press OK
Type 'redirect' into the Filter box
You should see a listing for 'network.http.redirection-limit'
Double click the listing and type a large number (anything above 50 and lower than 200)
Press OK, quit and re-open FireFox
Basically all that does is make FireFox's tolerance for redirect loops higher which should fix your problem - but usually, just borrowing someone else's internet connection fixes it
Hope that all helps =)
Just carefully check your URLMappings configuration:
YOUR_APP/grails-app/conf/UrlMappings.groovy
Common case:
You configured request to be handled like this:
"/anything" (controller:"someController")
So without action, request will be handled by default one, "index". "index" action usually redirects to "list", and "list", in some cases redirect back to "index"
There is your loop.
Good luck