How to get the response content of an HTTP 404 response - http

Is there an easier way of getting the content of an HTTP 404 response than directly accessing the host via tcp?
This is a sample of a 404 response with content:
HTTP/1.1 404 Object Not Found
Server: CouchDB/1.3.0 (Erlang OTP/R15B03)
Date: Wed, 24 Jul 2013 08:32:50 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 41
Cache-Control: must-revalidate
{"error":"not_found","reason":"missing"}

The Rebol HTTP scheme really isn't designed with this in mind, it's geared toward reading content the way you would in a browser, not services over HTTP.
In saying that, you can hack the protocol to subvert how Rebol 2 handles different response codes:
in-http-scheme: func [does [block!]][
do bind :does bind? last body-of get in system/schemes/http/handler 'open
]
in-http-scheme [
remove-each [code response] response-actions [find [400 403 404] code]
append response-actions [400 success 403 success 404 success]
]
The caveat here is that the HTTP protocol has to have been initiated (any http port opened/read). response-actions can still be accessed when http has not been initiated:
select body-of get in system/schemes/http/handler 'open quote response-actions:
You can get the last response line thus:
in-http-scheme [response-line]
Alternatively you are going to need a scheme designed for services over HTTP. I have a REST protocol (two versions, one that uses cURL, and one that uses a customised HTTP scheme that works, but isn't as good). Though are for Rebol 2. I have plans for a Rebol 3 version.

Christopher Ross-Gill has created a REST protocol for Rebol which allows simple access to all headers and even handles OAuth. Have a look at the details here.
http://www.ross-gill.com/page/REST_Protocol
Unfortunately it is only for Rebol 2 at the moment and it depends on the use of curl for the http requests.

Related

How to use TCP send out a HTTP response?

I try to use c++ develop a HTTP server on Windows,and when i reponse a HTTP by use WSASend to send out
char response[] =
"HTTP/1.1 200 OK\r\n\
Date: Mon, 27 Jul 2009 12:28:53 GMT\n\r\
Server: Apache/2.2.14 (Win32)\n\r\
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT\n\r\
Content-Length: 88\n\r\
Content-Type: text/html\n\r\
Connection: Closed\n\r\n\r\
<html><body><h1>Hello, World!</h1></body></html>"
Althrougn the browser did show Hello, World! when i type in 127.0.0.1,but the browser just keep show loading sigh as if the pages not yet load complete.And the browser's console never show the response message.Why?
Is there some format issue with my response message?
Content-Length: 88\n\r\
....
Connection: Closed\n\r\n\r\
There are several problems with your code. All over your code you use \n\r instead of \r\n. Therefore the response is invalid HTTP. And the Content-length header must reflect the actual length of the body: <html><body><h1>Hello, World!</h1></body></html> has 48 bytes and not 88 bytes as your code claims. Apart from that it must be Connection: Close instead of Connection: Closed.
Note that HTTP is way more complex than you think. If you really need to implement it yourself instead of using established libraries please study the actual standard (that's what standards are for!) instead of fiddling around until it seems to work. Otherwise it might work only within your specific environment and with a specific browser and you'll get strange problems later.

HTTP 400 - Hard to understand error code with minimal description

All,
My requirement is fairly simple. I have to perform a simple HTTP POST to an IP:port combination. I used simple socket programming to do that and I have been successful in sending across my request to them and also get back response from them. The only problem being that the response is always a HTTP 400: Bad Request followed by my HTTP POST message. I am not sure if the problem is with the client or the server. My only guess being that there might be a problem with my data that I am sending. This is what my POST looks like
POST /<Server Tag> HTTP/5.1
Content-Length: xxx
--Content--
and the response from the server looks something like this
HTTP/1.1 400 Bad Request
Content-Length: xxx
--Same content that I sent them--
I was not sure If I could put in the IP of the server here so kept myself to using . I am pretty sure that the problem would not be there since I get back some response from the server and confident about the connection. Can someone help me ?
PS: Some pointers about my POST:
1) HTTP 5.1 was requested by the server and I am not sure if that is correct
2) I have played around with the number of line spaces after the content length. I have tried giving one and two lines. Not sure if that would make a difference. On wireshark though I see a difference with the number of line spaces as with a single line space the protocol is specified as TCP but with two it changes to HTTP. The response is always received on HTTP protocol. Some explanation on the difference would also help
Thanks
edit: the other thing that confuses me is that the response has a HTTP 1.1 and not a 5.1 that I had sent. I have also tried changing my post to 1.1 with no success
edit2: Based on suggestion form fvu and others, I used WebClient to Upload my request. Still got back a 400. The header that was generated by the WebClient looks like this
POST <server tag> HTTP/1.1
Host: <IP:PORT>
Content-Length: 484
Expect: 100-continue
Connection: Keep-Alive
The issue I see with this might be that the server was not expecting all the details in the header. The server has requested only the Content-Length from us. Would that be a problem?
Thanks
You can use a debugging proxy to view a client request and a server response to figure out what your client socket program needs to do.
But first you need to create a simple web page that a browser displays, allows you to do a POST from the browser to the web server, and get a simple response back from the server.
HTTP/5.1 is either wrong or misused by the programmer of the server application
You should get a valid example from the server api to check your protocol implementation first.

What, at the bare minimum, is required for an HTTP request?

I'm trying to issue a GET command to my local server using netcat by doing the following:
echo -e "GET / HTTP/1.1\nHost: localhost" | nc localhost 80
Unfortunately, I get a HTTP/1.1 400 Bad Request response for this. What, at the very minimum, is required for a HTTP request?
if the request is: "GET / HTTP/1.0\r\n\r\n" then the response contains header as well as body, and the connection closes after the response.
if the request is:"GET / HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n"
then the response contains header as well as body, and the connection closes after the response.
if the request is:"GET / HTTP/1.1\r\nHost: host:port\r\n\r\n" then the response contains header as well as body, and the connection will not close even after the response.
if your request is: "GET /\r\n\r\n" then the response contains no header and only body, and the connection closes after the response.
if your request is: "HEAD / HTTP/1.0\r\n\r\n" then the response contains only header and no body, and the connection closes after the response.
if the request is: "HEAD / HTTP/1.1\r\nHost: host:port\r\nConnection: close\r\n\r\n" then the response contains only header and no body, and the connection closes after the response.
if the request is: "HEAD / HTTP/1.1\r\nHost: host:port\r\n\r\n" then the response contains only header and no body, and the connection will not close after the response.
It must use CRLF line endings, and it must end in \r\n\r\n, i.e. a blank line. This is what I use:
printf 'GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: close\r\n\r\n' |
nc www.example.com 80
Additionally, I prefer printf over echo, and I add an extra header to have the server close the connection, but those aren’t needed.
See Wiki: HTTP Client Request (Example).
Note the following:
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.
The absolute minimum (if removing the Host is allowed ;-) is then GET / HTTP/1.0\r\n\r\n.
Happy coding
I was able to get a response from my Apache server with only the requested document, no response header, with just
GET /\r\n
If you want response headers, including the status code, you need one of the other answers here though.
The fact of the 400 Bad Request error itself does not imply that your request violates HTTP. The server very well could be giving this response for another reason.
As far as I know the absolute minimum valid HTTP request is:
GET / HTTP/1.0\r\n\r\n
Please, please, please, do not implement your own HTTP client without first reading the relevant specs. Please read and make sure that you've fully understood at least RFC 2616. (And if you're ambitious, RFC 7230 through 7235).
While HTTP looks like an easy protocol, there are actually a number of subtle points about it. Anyone who has written an HTTP server will tell you about the workarounds he had to implement in order to deal with incorrect but widely deployed clients. Unless you're into reading specifications, please use a well-established client library; Curl is a good choice, but I'm sure there are others.
If you're going to implement your own:
do not use HTTP/0.9;
HTTP/1.0 requires the query line and the empty line;
in HTTP/1.1, the Host: header is compulsory in addition to the above.
Omitting the Host: header in HTTP/1.1 is the most common cause of 400 errors.
You should add an empty line: \r\n\r\n
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Client_request
The really REALLY BARE minimum, is not using netcat, but using bash itself:
user#localhost:~$ exec 3<>/dev/tcp/127.0.0.1/80
user#localhost:~$ echo -e "GET / HTTP/1.1\n" >&3
user#localhost:~$ cat <&3
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.6
Date: Mon, 13 Oct 2014 17:55:55 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 514
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
<title>Directory listing for /</title>
<body>
<h2>Directory listing for /</h2>
<hr>
<ul>
</ul>
<hr>
</body>
</html>
user#localhost:~$

404 header - HTTP 1.0 or 1.1?

Why does almost every example I can find (including this question from about a year ago) say that a 404 header should be HTTP/1.0 404 Not Found when we've really been using HTTP 1.1 for over a decade? Is there any reason not to send HTTP/1.1 404 Not Found instead?
(Not that it matters all that much... I'm mostly just curious.)
In PHP you should probably use:
header( $_SERVER['SERVER_PROTOCOL']." 404 Not Found", true );
or even better
header( $_ENV['SERVER_PROTOCOL']." 404 Not Found", true );
(if supported) and thus leave it to the web-server which protocol to use.
Actually, if you pass the status code as 3rd parameter, you can pass whatever you want in the 1st one, as long as it's not empty, and PHP will do the rest. See http://php.net/header
header("foobar", true, 404 );
Also: You can't request a certain protocol version from the client-side since the transaction is hop-to-hop based, and not end-to-end. The server and your browser may very well use HTTP/1.1, but if a proxy inbetween is using only HTTP/1.0, that's what you will see from your client.
The usage of HTTP version can be based on the following factors:
Your web server support for HTTP 1.0 or 1.1
The web browser's support for HTTP 1.0 or 1.1
Your preference as a web developer on which protocol version to use
Modern browsers can support both 1.0 and 1.1 well, and both the client and server will settle for the highest version both can support together. The key differences between the 2 protocol can be found: http://www8.org/w8-papers/5c-protocols/key/key.html
However there's no key differences in the usage of 404 Not Found. However do be consistent for your whole website. i.e. if you use HTTP/1.1, you use it throughout your website.
It does not matter all that much. The client is responsible for telling the server which version of HTTP it uses. Then, the server is supposed to answer with the same version. This does not always happen; I just got this response from a server:
$ telnet example.com 80
Trying 123.123.123.123...
Connected to example.com.
Escape character is '^]'.
GET /fork HTTP/1.0
HTTP/1.1 404 Not Found
Content-Length: 1635
Content-Type: text/html
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Tue, 04 May 2010 22:30:36 GMT
Connection: close
I asked the server to use HTTP 1.0, but it went ahead and responded with HTTP 1.1.
I'd have thought that the response should be HTTP/1.0 404 Not Found if the request was a HTTP 1.0, and HTTP/1.1 404 Not Found if the request was HTTP 1.1.
In practice, it's going to be easier for servers to returned canned responses, and the HTTP 1.0 response will be understood by both 1.0 and 1.1 clients, so safest to return that. If you know the client understands 1.1 (e.g. because that's what it asked for), then the 1.1 response should work.
Arguably, play it safe and send the 1.0 response.
Looking at both the 1.1 and 1.0 RFCs, 404 is there in both - so it's probably for no other reason than for the server to communicate to the client that it's operating on http 1.1.
That said - if a server responds with 404 over Http 1.1, it implies that it could have returned 410 - Gone instead to indicate a resource that used to exist but no longer does. This status code is not part of 1.0, and therefore this information could be useful to a client (especially web crawlers).
EDIT
Sorry - this answer is probably answering the other way around! I reckon you can probably count on only a few hands the number of public web servers that will be bothering to remember all the resources that used to exist and which no longer do (no way I'd code that into my web server!) - so therefore it's probably best to respond with the 1.0 404 to indicate that 'it's just not there' rather than 'that's not here, but other stuff around the site might used to have been but no longer - in which case I could have sent you a 410'.
There's also the fact that you're allowing 1.0-only clients to work with your site.
That said - it's all a bit pedantic.
With modern versions of PHP you can also use the http_response_code function and sidestep the problem entirely!
I also like this method because it means that there's no risk of making typos in the response message.
I got this error when i used "avio_http_serve_files" witch is an http server It is given as example in ffmgeg (see ffpmeg git).
In order to start the server , the syntax is for example:
./avio_http_serve_files mymovie.mp4 http://192.168.1.42:10000
At client side:
vlc ou mpv ou...
vlc http://192.168.1.42:10000/mymovie.mp4
If the file mymovie.mp4 is not int the server 's current directory you have the error HTTP/1.0 404 Not Found.
You can neither use absolute directory.

Difference between Content-Range and Range headers?

What is the difference between HTTP headers Content-Range and Range? When should each be used?
I am trying to stream an audio file from a particular byte offset. Should I use Content-Range or Range header?
Actually, the accepted answer is not complete. Content-Range is not only used in responses. It is also legal in requests that provide an entity body.
For example, an HTTP PUT provides an entity body, it might provide only a portion of an entity. Thus the PUT request can include a Content-Range header indicating to the server where the partial entity body should be merged into the entity.
For example, let's first create and then append to a file using HTTP:
Request 1:
PUT /file HTTP/1.1
Host: server
Content-Length: 1
a
Request 2:
PUT /file HTTP/1.1
Host: server
Content-Range: bytes 1-2/*
Content-Length: 1
a
How, let's see the file's contents...
Request 3:
GET /file HTTP/1.1
Host: server
HTTP/1.1 200 OK
Content-Length: 2
aa
This allows random file access, both READING and WRITING over HTTP. I just wanted to clarify, as I was researching the use of Content-Range in a WebDAV client I am developing, so perhaps this expanded information will prove useful to somebody else.
Range is used in the request, to ask for a particular range (or ranges) of bytes. Content-Range is used in the response, to indicate which bytes the server is giving you (which may be different than the range you requested), as well as how long the entire content is (if known).

Resources