How to C - windows socket reading textfile content - winsock

I am having problems reading a text file content via winsock on C , does anyone have any idea how it should work? actually when I try to GET HTTP header from google am able to, but when I try on my xampp machine,
it just gives me 400 bad request.
HTTP/1.1 400 Bad Request
char *message = "GET / HTTP/1.1\r\n\r\n";
Ok the problem that I was receiving 400 bad request on my localhost via winsock was the my HTTP request, i just changed the 1.1 to 1.0 .. and it worked!!! what I am wanting now is printing nothing the content of the text file and not the whole banner?! :)

Read RFC 2616, in particular sections 5.2 and 14.23. An HTTP 1.1 request is required to include a Host header, and an HTTP 1.1 server is required to send a 400 reply if the header is missing and no host is specified in the request line.
char *message = "GET / HTTP/1.1\r\nHost: hostnamehere\r\n\r\n";
As for the text content, you need to read from the socket until you encounter a \r\n\r\n sequence (which terminates the response headers), then process the headers, then read the text content accordingly. The response headers tell you how to read the raw bytes of the text content and when to stop reading (refer to RFC 2616 section 4.4 for details). Once you have the raw bytes, the Content-Type header tells you how to interpret the raw bytes (data type, charset, etc).

Related

Why is the browser satisfied with a response without content-length

Usually when I send a response to the browser I have to enter content-length in the http headers, otherwise the browser never stops loading (wait for more data)
But recently, I tested rust code:
let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);
stream.write(response.as_bytes()).unwrap();
The browser receives this without any problems, stops loading after receiving the response.(even though content-length is not specified in the response)
Can someone pls explain this?... What makes the browser satisfied with the response in this scenario (even though it does not contain: Content-length)
Content-length is optional as long as the connection is closed after the response is done. From RFC 7230 section 3.3.3 Message Body Length:
Otherwise, this is a response message without a declared message
body length, so the message body length is determined by the
number of octets received prior to the server closing the
connection.

REST API Design: Respond with 406 or 404 if a resource is not available in a requested representation

We have a REST API to fetch binary files from the server.
The requests look like
GET /documents/e62dd3f6-18b0-4661-92c6-51c7258f9550 HTTP/1.1
Accept: application/octet-stream
For every response indicating an error, we'd like to give a reason in JSON.
The problem is now, that as the response is not of the same content type as the client requested.
But what kind of response should the server produce?
Currently, it responds with a
HTTP / 1.1 406 Not Acceptable
Content-Type: application/json
{
reason: "blabla"
...
}
Which seems wrong to me, as the underlying issue is, that the resource is not existing and not the client requesting the wrong content type.
But the question is, what would be the right way to deal with such situations?
Is it ok, to respond with 404 + application/json although application/octet-stream was requested
Is it ok, to respond with 406 + application/json, as the client did not specify an application/json as an acceptable type
Should spec been extended so that the client should use the q-param - for example, application/octet-stream, application/json;q=0.1
Other options?
If no representation can be found for the requested resource (because it doesn't exist or because the server wishes to "hide" its existence), the server should return 404.
If the client requests a particular representation in the Accept header and the server is not available to provide such representation, the server could either:
Return 406 along with a list of the available representations. (see note** below)
Simply ignore the Accept header and return a default representation of the resource.
See the following quote from the RFC 7231, the document the defines the content and semantics of the HTTP/1.1 protocol:
A request without any Accept header field implies that the user agent will accept any media type in response. If the header field is present in a request and none of the available representations for the response have a media type that is listed as acceptable, the origin server can either honor the header field by sending a 406 (Not Acceptable) response or disregard the header field by treating the response as if it is not subject to content negotiation.
Mozilla also recommends the following regarding 406:
In practice, this error is very rarely used. Instead of responding using this error code, which would be cryptic for the end user and difficult to fix, servers ignore the relevant header and serve an actual page to the user. It is assumed that even if the user won't be completely happy, they will prefer this to an error code.
** Regarding the list of available representations, see this answer.

Accessing Docker daemon with Rust doesn't work [duplicate]

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:~$

How do i send a POST request without Transfer Encoding:chunked from Jersey ReST Client 2.22.2

When i send a POST request through Jersey ReST client it's automatically using Header transfer-encoding: [chunked].
Is there any way to force use of content-length: instead of transfer-encoding.?
WebTarget webTarget = client.target(connection.getServerUrl());
Invocation.Builder builder = webTarget.request(MediaType.APPLICATION_XML);
Response response = builder.post(Entity.xml(requestBroker));
After adding Content-Length property too the behavior is same
WebTarget webTarget = client.target(connection.getServerUrl());
Invocation.Builder builder = webTarget.request(MediaType.APPLICATION_XML);
Entity entity = Entity.xml(requestBroker);
client.property("Content-Length", entity.toString().getBytes().length);
Response response = builder.post(Entity.xml(requestBroker));
HTTP 1.1 version onwards chunked transfer encoding is default for POST, in this data is sent as chunks and hence the senders can begin transmitting dynamically-generated content before knowing the total size of that content. The size of each chunk is sent right before the chunk itself so that the receiver can tell when it has finished receiving data for that chunk. The data transfer is terminated by a final chunk of length zero.
Is there any way to force use of content-length: instead of
transfer-encoding
Set the Content-Length header before sending your POST request. But this will work only in http 1.0, and when you set the content length, and if the post request data size is more than the content length then the data received will be truncated.
In the version 1.1 of the HTTP protocol, the chunked transfer mechanism is considered to be always and anyways acceptable, even if not listed in the TE (transfer encoding) request header field, and when used with other transfer mechanisms, should always be applied last to the transferred data and never more than one time. Source Wikipedia - Chunked Transfer Encoding
Whereas in the response, we can avoid Transfer-Encoding by setting the BufferSize on response using response.setBufferSize(). But if our response size goes beyond the bufferSize it would fallback to Transfer-Encoding: Chunked.
Different Transfer Mechanisms
More Info:
Content-Length header versus chunked encoding
Remove Transfer-Encoding:chunked in the POST request?
avoiding chunked encoding of HTTP/1.1 response
Hope it Helps!

What charset SHOULD be used for a Location: header in a 301 response?

Trying to consume the URI cot.ag/o1LnfW from .NET with the HttpWebRequest, I get the 301 Moved response, the response header Location has a (incorrect) value of:
http://www.joycemeyer.org/BroadcastHome.aspx?video=Living_Beyond_Your_Feelings_â_Pt_1&utm_source=Twitter&utm_campaign=EEL&utm_medium=post&utm_term=September29&utm_content=post
From Fiddler, I get the (correct) Location header value:
http://www.joycemeyer.org/BroadcastHome.aspx?video=Living_Beyond_Your_Feelings_–_Pt_1&utm_source=Twitter&utm_campaign=EEL&utm_medium=post&utm_term=September29&utm_content=post
Noted the difference where the – occurs in the Fiddler URL. In the case of Fiddler, the bytes are E2 80 93. In the case of .Net, the bytes are E2 3F 3F. This results in an incorrect header interpretation, with subsequent failure to follow the redirection.
I think this is a .NET framework bug, but I have no idea what the RFCs say it SHOULD sent as. Should I report this as a bug to Microsoft, or is this a failure by bit.ly in serving the headers in the wrong code-page?
RFC 2616 specifies that the Location header should contain a URI as defined by RFC 1630, which requires a URI be 7-bit clean ASCII with any special characters URL encoded.
In other words, the server is delivering the URI incorrectly and should be escaping it.
I've reported this a bug over at bit.ly's support forum. They should be responding with a legal RFC 1630 URI in the ASCII character set (no octets with the high-bit set).