C++ - Sending HTTP POST/GET after connection has closed - c++

I've been searching for a solution on StackOverFlow and couldn't seem to find an answer, I am using WinSock2 to log into a website and the server responds with "Connection: close" (Even if I send Connection: keep-alive) in the header. Any messages attempting to recv after returns 0. (0 = Graceful close)
Questions:
Is the connection suppose to drop after a POST request?
How do you send subsequent GET/POST requests after it has dropped?
So do you have to recycle the socket and re-establish everything again like my example below?
Example of list of events (that i'd imagine i'd need to do):
WSAStartup
Find Address
Create socket
Connect Socket with address
Send Post Request
---Connection Closes after Post---
Destroy Socket
Create socket
Connect Socket with address
Send Get Request with Authentication Cookie
This is what I picture the event chain would look like, but I am not 100% sure how browsers handle all this. But I learn from other users experience and input so if anyone knows exactly what happens let me know. Thank you for your time,

Is the connection suppose to drop after a POST request?
It can, yes. HTTP is a stateless protocol, there is no guarantee that the connection will stay alive after a response, even if a keep-alive is requested. Whether or not to close the connection after sending the response is up to the server to decide, if the client does not request the connection to be closed.
How do you send subsequent GET/POST requests after it has dropped?
You have no choice but to reconnect to the server, and everything that involves (TCP handshakes, SSL/TLS handshakes, etc) before you can send the new request.
If you:
send an HTTP 1.0 request that does not explicitly state Connection: keep-alive, or receive an HTTP 1.0 response that does not explicitly state Connection: keep-alive
send an HTTP 1.1 request that explicitly states Connection: close, or receive an HTTP 1.1 response that explicitly states Connection: close
Then you must close your end of the connection after reading the response.
Even if the response indicates a keep-alive is in effect, the connection could still timeout and be closed before you send your next request on the same connection.
So, any time you want to send a new request, if the connection has already been closed previously, or you get a connection error while sending the request, close the socket, reconnect, and resend the request.
So do you have to recycle the socket and re-establish everything again like my example below?
Potentially, yes.
I am not 100% sure how browsers handle all this.
Exactly as described above.
This is discussed further in RFC 2616 Section 8 "Connections".

Related

How to force HTTP2 client to reconnect to server?

It is needed to make a HTTP2-response, which will force a client to reconnect to the same server to the same address.
In case of HTTP/1.1 it could be done sending 307 Temporary Redirect response with Connection: close header.
In HTTP/2 Connection: close header is ignored and redirect is performed without reconnection, which brings to redirect loop error.
Also, I've tried to send 421 Misdirected Request response to client with the same url, but Chrome browser is do nothing after receiving this response.
What is the most proper way to force a HTTP/2 client to reconnect? Which server response can be send? Maybe some kind of GOAWAY frame?
Following the graceful shutdown procedure that RFC 7540 recommends should result in a reconnection:
A server that is attempting to gracefully shut down a connection
SHOULD send an initial GOAWAY frame with the last stream identifier
set to 2^31-1 and a NO_ERROR code. This signals to the client that
a shutdown is imminent and that initiating further requests is
prohibited. After allowing time for any in-flight stream creation
(at least one round-trip time), the server can send another GOAWAY
frame with an updated last stream identifier. This ensures that a
connection can be cleanly shut down without losing requests.
Regarding 421 handling in Chrome, this bug https://bugs.chromium.org/p/chromium/issues/detail?id=546991 was opened to have Chrome re-open a new connection to the server, it's seen some activity recently.
Yes, the way on HTTP/2 to ask a client to reconnect for further requests is to send a GOAWAY frame to it. How this works depends on your server side implementation or framework for HTTP/2 support. E.g. a framework could intercept your Connection: close header and treat it as a request to close the connection after the request. But I guess most HTTP/2 implementations wouldn't like to do that, since they guess the header targets only the current request scope and not the whole connection. Alternatively the framework could provide a way in the request handler to not only access the request and response data but also to get a reference to the HTTP/2 connection, which can be used to send the GOAWAY.
This may help you Google HTTP2

How can I send HTTP broadcast message with tornado?

I have a tornado HTTP server.
How can I implement broad-cast message with the tornado server?
Is there any function for that or I just have to send normal HTTP message all clients looping.
I think if I send normal HTTP message, the server should wait for the response.
It seems not the concept of broad-cast.
Otherwise, I need another third-part option for broad-cast?
Please give me any suggestion to implement broad-cast message.
Short answer: you might be interested in WebSockets. Tornado seems to have support for this.
Longer answer: I assume you're referring to broadcast from the server to all the clients.
Unfortunately that's not doable conceptually in HTTP/1.1 because of the way it's thought out. The client asks something of the server, and the server responds, independently of all the others.
Furthermore, while there is no request going on between a client and a server, that relationship can be said to not exist at all. So if you were to broadcast, you'd be missing out on clients not currently communicating with the server.
Granted, things are not as simple. Many clients keep a long-lived TCP connection when talking to the server, and pipeline HTTP requests for it on that. Also, a single request is not atomic, and the response is sent in packets. People implemented server-push/long-polling before WebSockets or HTTP/2 with this approach, but there are better ways to go about this now.
There is no built-in idea of a broadcast message in Tornado. The websocket chat demo included with Tornado demonstrates how to loop over the list of clients sending a message to each:
def send_updates(cls, chat):
logging.info("sending message to %d waiters", len(cls.waiters))
for waiter in cls.waiters:
try:
waiter.write_message(chat)
except:
logging.error("Error sending message", exc_info=True)
See https://github.com/tornadoweb/tornado/blob/master/demos/websocket/chatdemo.py

GET and CONNECT methods in a proxy

I'm making an HTTP proxy in C++; when a client sends a GET or CONNECT request to the proxy, the proxy parses the HTTP header of the packet, resolve the hostname in it, opens another socket to the server destination and send client's request. Then the proxy will send server's response to the client.
Here's the GET and CONNECT requests from the client sent by the proxy to the server:
GET http://www.gstatic.com/generate_204 HTTP/1.1
CONNECT cr-input.getspeakit.com:443 HTTP/1.1
But when I parse a GET response from server, I find a 400 status code, i.e. Bad Request: this seems to be (from Wikipedia):
a malformed request syntax, invalid request message framing, or deceptive request routing.
Do I send wrong arguments to the server in the GET request?
GET. The syntax is not wrong but if the request has not been faked by you and it is really going to www.gstatic.com you can check yourself that any kind of requests generates a 40x status code. That's a domain used for Google for offloading static content. Whether that's still the case and why it returns 40x for the requests. Go to Google.
CONNECT. If you are forwarding the CONNECT to the server, this is wrong. A CONNECT is meant to open an end to end binary connection bypassing your proxy. The sequence would be:
Get connect request from client
Open TCP connection to IP:Port (after DNS resolution obviously)
Return "200 OK" to the client if the connection was successfully opened or an error code of your choice (plus optionally some explanation in Text/HTML form for the end user)
If data is received from either end -> forward it to the other end until one of the connections is closed, when you close the other end.

Is it possible to alter the HTTP client timeout period (cpp-netlib)?

I'm using cpp-netlib (v0.11.0) to send HTTP requests.
I'd like to know if it's possible to alter the timeout period when sending an HTTP POST request.
I'm running some unit tests, one of which sends an HTTP request to an address where there is no server running. An attempt to pull information from the response times-out after about 90s with the error "Operation timed out".
When the constructor for the client class is invoked, you can pass an options class that you can set the timeout in. See the docs for the client class constructors (and then scroll down a bit) for more specific information.

How to ignore certain socket requests

I'm currently working on a TCP socket server in C++; and I'm trying to figure out how I can ignore all browser connections made to my server. Any idea's?
Thanks.
Need more details to give good feedback.
Are you going to be listening on port 80 but want to avoid all HTTP traffic? Or will your protocol be HTTP-based? Do you need to listen on 80 or can you pick any port?
If it's your own custom protocol (HTTP or not) you could just look at the first line sent up and if it's not to your liking just close() the socket.
EDIT:
Since you're going to be listening on a custom port, you probably won't get any browser traffic anyhow. Further, since you're going to be writing your own protocol, just require a handshake which establishes your client speaks your custom protocol and then ignore (close()) everything else.
Bonus points: depending on your goal, send back an HTTP error message which can be displayed to the user.
You can't stop a web-browser initiated tcp-session from connecting to your tcp server. You can (as stated above) close the connection once you've detected the client is trying to talk http to you (or any other unwanted application-layer protocol).
Just look at the differences between valid connection requests and invalid ones (i.e. dump both request types to examine each request), in your specific case, you'll want to look at the HTTP request header to ignore all such requests (assuming that valid requests do not make use of HTTP).