I am writing a http server in java using ServerSocket and Socket respectively.
In specification it says that the request can be of "chunked" type. So how could I enable this option in any browser to test the parsing of the request?
You can easily make up the request on your own:
POST /search HTTP/1.1
Host: www.example.com
Transfer-Encoding: chunked
Content-Length: 25
000a
q=23456789
000a
0123456789
0005
01234
0
This request is split into three parts, and your server should receive q=23456789012345678901234 as the POST data.
Note: you need another CRLF at the end of the request, which this markup language cannot display.
AFAIK most desktop browsers don't send chunked requests because some web servers don't handle them correctly (or at all) and it's easier to calculate the length than to detect/guess/remember which servers support it.
The curl command-line tool can send chunked requests:
curl -v -d "name=value" --header "Transfer-Encoding: chunked" http://foo.com/bar
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'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 wrote a simple Grizzly/Jersey application, which you can find here:
https://github.com/boldt/stackoverflow-14526627
I want to post some form data:
curl -X POST -F "name=test" -i http://localhost:9999/files
I'm getting the following response:
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Fri, 25 Jan 2013 16:51:18 GMT
Transfer-Encoding: chunked
As you can see, the header is doubled, first a 100 Continue followed by a 200 OK. Is doesn't makes sense to get the 100 Continue.
Any suggestions?
This is normal. Curl is following the HTTP 1.1 spec. You are doing a POST which means you are going to be sending data to the server. Curl is sending a request header to the server with "Expect: 100-continue" in it.
This tells the server that the client wants permission to send a POST document and if the server responds with HTTP/1.1 100 Continue, then client sends the document (your form pairs in this case) otherwise the server may reject it for whatever reason with HTTP/1.1 417 Expectation Failed and this allows the client to not waste time sending lots of data possibly if it will be rejected.
There is nothing wrong with the two headers.
Read about the Expect header.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
Check your request headers. You are probably sending HTTP Expect with curl.
curl -vv -X POST -F "name=test" -i http://localhost:9999/files
I've replaced the Tomcat by Jetty. Now I have 400 http error code for requests sent by a third party system. As I see, the difference with my tests sent by curl and a web-browser is the url in the http verb:
POST http://10.15.1.9:49302 HTTP/1.0
Host: 10.15.1.9
Content-Type: text/xml
Content-Length: 71065
User-Agent: hpost/0.1
Pragma: no-cache
Accept: */*
this request doesn't work, but post with relative URL such as POST / HTTP/1.0 works fine. Who is wrong? I cannot change the third party system, so, is it possible to make jetty accept such requests?
I've tried Jetty v6.1.26, v7.6.4 and v8.1.4 - works the same.
Ok, I think the reason is missing trailing slash after the url, the POST http://10.15.1.9:49302/ HTTP/1.0 works fine.
Does any body know if it is jetty problem or the client sends malformed url?
While the HTTP spec RFC-2616 says that the server must accept absoluteuri's for the request line, this is generally only used for proxy requests.
To Jetty, the request line POST http://10.15.1.9:49302 HTTP/1.0 is viewed as a HTTP/1.0 request, and fall into the rules of RFC-1945 for Request Line URIs that states absoluteuri's are always Proxy requests.
I've reported the issue, it is fixed now.
I am trying to send a http request from a tcp client in java. I want to read the http request message from a text file and send the http request through my tcp client.
Http message
GET /index.html HTTP/1.1
Host:http://localhost/xampp/ (is this correct? I want to send request to my localhost)
From:xyz#something.com
Accept:text/html, text/plain
User-Agent:Mozilla/3.5.3
How can i do this?
Host:http://localhost/xampp/ (is this
correct? I want to send request to my
localhost)
I believe you should put at host only "localhost" instead of "http://localhost/xampp/".
I believe you should also modify "GET /index.html HTTP/1.1" to "GET /xampp/index.html HTTP/1.1"
Telnet
But I would first do some debugging via telnet, And if successful I would write code
telnet localhost 80
From wikipedia.com
Below is a sample conversation
between an HTTP client and an HTTP
server running on www.example.com,
port 80.
[edit] Client request
GET /index.html HTTP/1.1
Host: www.example.com
A client request (consisting in this case of the request line and only
one header) is followed by a blank
line, so that the request ends with a
double newline, each in the form of a
carriage return followed by a line
feed. The "Host" header distinguishes
between various DNS names sharing a
single IP address, allowing name-based
virtual hosting. While optional in
HTTP/1.0, it is mandatory in HTTP/1.1.
[edit] Server response
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Etag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Content-Length: 438
Connection: close
Content-Type: text/html; charset=UTF-8