I am using com.opencsv.CSVReader to read a CSV from a URL served by my nginx Web server. The CSV file content is exactly this:
0.999,1.399,1.799,2.199,2.599,2.999,3.399,3.799,4.199,4.599,4.999,5.399
The problem is that when I read the file I get no csv values:
try (InputStreamReader in = new InputStreamReader(new URL(...csv).openStream(), "UTF-8"); CSVReader r = new CSVReader(in)) {
List<String[]> csv = r.readAll();
....
After this point, csv has failed to get the data (but no errors are raised), and csv.get(0).length is incorrectly 1, an empty string. I do not know why. Tests that I have done to isolate the problem:
I have tried obtaining the file via http and https from my nginx with similar results. I must say that this code was working fine not too long ago, and with no apparent reason now it is failing.
I have used a BufferedReader to see what was in in before reading the csv and I got:
Date: Fri, 10 Aug 2018 03:11:13 GMT
Content-Type: text/plain
Content-Length: 71
Last-Modified: Wed, 12 Jul 2017 16:23:24 GMT
Connection: keep-alive
ETag: "..."
Strict-Transport-Security: max-age=31536000
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Accept-Ranges: bytes
0.999,1.399,1.799,2.199,2.599,2.999,3.399,3.799,4.199,4.599,4.999,5.399
So I am not sure if the headers were also read by the csv reader and messed with it somehow.
I have used the same code to access an external CSV instead of the one served by my nginx and it worked fine, and the test using the BufferedReader with the external CSV did not show any header, just the csv values.
That is why I am also considering that it could be an nginx problem, since I also experienced a recent error of files not finishing download and I had to change my previous keepalive_timeout 65 that was working fine to keepalive_timeout 0. I am not sure why this happened all of a sudden.
This was very hard to debug, but the solution was to reinstall nginx because my copy was corrupted. My nginx instance was sending extra \r characters that did not interfere with curl or similar but that disrupted the Java implementation.
By the way - This probably highlighted a bug in .openStream() implementation.
Related
I am currently implementing an HTTP server in Java but faced one problem when it comes to transfer encoding.
While
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Encoding: gzip
Transfer-Encoding: chunked
works properly, using gzip and chunked as transfer encoding only like this:
Transfer-Encoding: gzip, chunked
results in the browser not displaying the response correctly.
While Chrome tries downloading the resource as a .gz file, Firefox tries to display it which results in this:
The strange thing about this is that the message body generated by the server is exactly the same as when using gzip as Content-Encoding instead, because RFC7230 allows to apply multiple transfer encodings if the last one applied is chunked.
For example,
Transfer-Encoding: gzip, chunked
indicates that the payload body has been compressed using the gzip
coding and then chunked using the chunked coding while forming the
message body.
This is the original response from the server:
HTTP/1.1 200 OK
Date: Tue, 09 Jul 2019 17:52:41 GMT
Server: jPuzzle
Content-Type: text/plain
Transfer-Encoding: gzip, chunked
1c
òHÍÉÉW(Ï/ÊIQ ÿÿ
a
0
As one can guess, the body is gziped and chunked after that.
I would appreciate any help because I can't see where the specs have been violated.
You shoul use content-encoding header for end to end compression.
Transfer-Encoding is a hop-by-hop header, that is applied to a message between two nodes, not to a resource itself. Each segment of a multi-node connection can use different Transfer-Encoding values. If you want to compress data over the whole connection, use the end-to-end Content-Encoding header instead.
Also, send Accept-Encoding: gzip request header to tell the server what the client expects.
I have encountered something that i have no clue how to solve. Managing to narrow down what the issue was is a win on its on but still... Basically i have a class that implements AbstractPdfView and I use it to generate documents. After that I return it to the client and its downloaded. It is all good when i run it locally, but when i deploy it, it directly goes to 500, (faild)net::ERR_INVALID_RESPONSE. Here is the response as well:
H/1.1 500
Server: nginx/1.14.1
Date: Thu, 02 May 2019 19:18:40 GMT
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Pragma: private
Cache-Control: private, must-revalidate
Content-Disposition: attachment;
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
I am not sure what else to provide, codewise... Question is - is there any protection over receiving files as responses? Could it be that the file is directly downloaded and not through a window where you specify where to save it?
Thanks.
I cannot believe it... Turns out I had a font (which btw I was loading from the project directory) in the PDF file and it wasn't recognizing it. Switch to a basic font, all good now... Thanks to #peekay for guiding me to find a solution.
I'm trying to create a simple REST service to serve audio files (with seek support).
I'm using this example which is based on Jersey:
https://github.com/aruld/jersey-streaming/tree/jersey2
This is a quite simple example, it listens to GET and HEAD requests used by the browsers, look for the Range header and respond with 206 plus the archive slice requested (with byte ranges).
The catch here is that I'm re-writing this on spark java (a tiny framework with an embedded jetty server).
Every thing seems to be OK. The browser sends the GET and the server crates the response accordingly... though the player never loads nor plays anything. The request is made and the response header is perfect:
Request:
Host: localhost:4567
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Range: bytes=0-
Connection: keep-alive
Response:
Accept-Ranges: bytes
Content-Length: 1048577
Content-Range: bytes 0-1048576/5563904
Content-Type: audio/mp3
Date: Sat, 20 Aug 2016 05:41:23 GMT
Last-Modified: Sat Aug 20 01:12:37 BRT 2016
Server: Jetty(9.3.6.v20151106)
sasd
One thing I noticed is that seems the transfer for this request never ends. When I close the server, the transfer ends at 0,03KB (always).
My proof of concept app code:
http://pastebin.com/xjkLne7E
Found an answer!
I did some more research and found that it is a Spark feature to be implemented:
https://github.com/perwendel/spark/issues/397
User tchoulihan already tried to implement such feature with success here:
https://github.com/tchoulihan/torrenttunes-client
Here is a sample of the spark get request that handles the upload:
https://github.com/tchoulihan/torrenttunes-client/blob/master/src/main/java/com/torrenttunes/client/webservice/Platform.java#L555
I can't paste a blob here since GPLv3 would clash with cc-wiki license. Hes work is inspired on the same resource I first found. Based on that I have coded a version of my own that works on android, mozilla and chrome.
TL;DR The problem was that mozilla doesn't understand 206 request properly and I wasn't closing and flushing the ByteOutputStream. Also I tried to use the StreamingOutput from JAX as a response instead of sending a simple raw http response.
I'm using jCryption and JavaCryption, the server-side implementation of the jCryption JavaScript plug-in.
There appears to be an issue with what seems the Java implementation, in that FireFox's firebug is reporting a "not-well formed" error with the JSON that is returned to the client from the server. So, unlike the thread, "not well-formed" error in Firefox when loading JSON file with XMLHttpRequest, this is coming from the response object, NOT the request object.
I tried adding .JSON, application/json as a MIMEtype to my web server, IIS 7.5, but that didn't help. Then I tried .JSON, text/plain and that didn't help, either.
Do I have to edit the Java code to force application/json, when it sends it back to the client? Or, what can I do to resolve this issue?
Thank you for any help.
Here is the raw output for the first one causing the "not-well formed" error:
HTTP/1.1 200 OK
Content-Length: 294
Server: Microsoft-IIS/7.5
X-Powered-By: Nothing
Date: Tue, 23 Oct 2012 02:10:24 GMT
{"e":"10001","n":"b3fbbe3d2e3599e840a117be08f72726d8ee643dada3805ab24b9a9150d123a7a0902ae45f2f2e194e5462c4f5c3b91cca91b48d1f07c6cd7fab629a331148f66516df05dfa0bd95cc9f477069e60fa54eab8a5586d08436717758d9706b90c884eded7260af1ce5ff70f507b9c5ddb019b6e1313a77f4eab3b2d04a09934d8d","maxdigits":"131"}
Here is the second one:
HTTP/1.1 200 OK
Content-Length: 200
Server: Microsoft-IIS/7.5
X-Powered-By: Nothing
Date: Tue, 23 Oct 2012 02:10:24 GMT
{"challenge":"zf6iI5D8hVDCmMVuHIFy71ikKxcqVzkLplMDKP6Hgz7EPv2STfYjcBlf6ep1wu5OMCCsPKf4dRECpVvr7yIK8kCm0I5c4xTXCkmnyyzBXeHgbvkzGWVmaLzxj5RYajdWLFkvN1waV41FhR+PtK1tOmGe8k57wSZ/yyZUAsvh7NaJf6THc9P9rQ=="}
You need to look at what is in the actual response. You need to look at what the responses content-type header currently says, and what the body of the response contains. Firebug can show you both of those.
There is a good chance that the response body is not JSON at all ... but an HTML error report about some problem with the request (as the server sees it).
Either way, you can't resolve the problem properly until you have worked out what is causing it. Simply assuming that it is content type problem is not a sound strategy.
Based on the response you posted, the problem is most likely due to the fact that there is no Content-Type header. If this response comes from Java, then you probably do need to modify the Java (or JSP) to set the missing header in the response.
Set Content-Type to application/json in jsp file
Setting a Content-type header in a servlet.
(There are other ways to do this if it is impossible to change the servlet or JSP code.)
So recently I learned that in order to serve static files with a Last-Modified header from Google App Engine, I had to write my own (simple) servlet to do that. OK fine, I went and did it, results can be viewed here.
But now I find that File.lastModified() is always returning the same value, no matter that I have touched the file, even tried outright replacing it, and also re-deployed my app. The headers always come back with the same Last-Modified field:
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="java-intro.zip"
Last-Modified: Tue, 04 Aug 2009 17:48:41 GMT
Last-Modified-in-millis: 1249408121000
Date: Tue, 04 Aug 2009 20:47:59 GMT
Server: Google Frontend
Content-Length: 0
Also curious is that it comes back with zero content-length, despite the fact that I am setting that in the HttpServletResponse, and I get back the proper data when I download it using my browser.
What gives, Google App Engine?