I'm implementing HTTP over TLS proxy server (sni-proxy) that make two socket connection:
Client to ProxyServer
ProxyServer to TargetServer
and transfer data between Client and TargetServer(TargetServer detected using server_name extension in ClientHello)
The problem is that the client doesn't close the connection after the response has been received and the proxy server waits for data to transfer and uses resources when the request has been done.
What is the best practice for implementing this project?
The client behavior is perfectly normal - HTTP keep alive inside the TLS connection or maybe even a Websocket connection. Given that the proxy does transparent forwarding of the encrypted traffic it is not possible to look at the HTTP traffic in order to determine exactly when the connection can be closed. A good approach is therefore to keep the connection open as long as the resources allow this and on resource shortage close the connections which were idle (no traffic) the longest time.
Related
My understanding regarding network model communication:
Application layer:
1. HTTP(Not Persistent or stateless): For exchanging messages like get, post, put etc. Here connection is made to webserver and disconnected after sending response. So server will not keep track of the previous requests.
2. Websockets(Persistent or statefull): For creating a communication channel that will be open to exchange data. Here we can keep track of the previous requests. Like we can know how many users are currently connected to our server.
Transport layer:
TCP(Persistant and Statefull): Will let the server know to which application to connect using port number. Both HTTP and web sockets will work upon this layer.
Considering working with HTTP and TCP:
I make a HTTP request from browser(application layer):
Connects to web server sends all files requested and also makes a TCP connection with the application(transport layer).
After sending response it's disconnected.
My confusion:
I got totally confused when I heard, read that TCP is Statefull and Persistant connection.
Q1. Now after step three is browser still connected to webserver because of TCP?
Q2. Is the context object we get in server side in c# code is the complete request packet with HTTP info, TCP info, function to invoke or controller to invoke in MVC etc?
Q3. If client and server are still connected with TCP. Then on next HTTP request does it will use the available TCP connection or will create new TCP and HTTP connection? Why can't it use previous TCP to communicate? Or TCP will be destroyed after HTTP? Or what's happening?
I'm not clear why the handshake for WebSocket is HTTP. Wiki says "The handshake resembles HTTP so that servers can handle HTTP connections as well as WebSocket connections on the same port." What is the benefit of this? Once you start communicating over WebSocket you are using port 80 also...so why can't the initial handshake be in WebSocket format?
Also, how do you have both WebSocket and HTTP servers listening on port 80? Or is it typically the same application functioning as HTTP and WebSocket servers?
Thanks y'all :)
WebSockets are designed to work almost flawlessly with existing web infrastructures. That is the reason why WS connections starts as HTTP and then switches to a persistent binary connection.
This way the deployment is simplified. You don't need to modify your router's port forwarding and server listen ports... Also, because it starts as HTTP it can be load balanced in the same way that a normal HTTP request, firewalls are more lean to let the connection through, etc.. etc... Last but not the least, the HTTP handshake also carry cookies, which it is great to integrate with the rest of the app in the same way that AJAX does.
Both, traditional HTTP request-response and WS, can operate in the same port. Basiclally the WS client sends a HTTP request asking for "Upgrade:websocket", then if the server accepts the WS connections, replies with a HTTP response indicating "101 Switching Protocols", from that point the connection remains open and both ends consider it as a binary connection.
I need to operate with a SOAP service from Erlang. SOAP implementation is not a subject, I have a problem with HTTP requests at a client side.
I use IBrowse as a HTTP client. This SOAP service uses a specific authorization mechanism, which relates an opened session to a client connection (socket). So, the client should use only one persistent connection to server (socket), and if it try to send a request via another socket (e.g., connection from pool) - authorization will fail.
I use IBrowse in this way:
Spawn connection process to server (ibrowse:spawn_worker_process/1)
Send request to server via spawned process with {max_sessions, 1} and {max_pipeline_size, 0}.
If I understand the docs right, this should use one socket for server connection with disabled pipelining, also, I use Connection: Keep-Alive header and HTTP version explicitly set to 1.0. But my connection is always closed after the response is received.
How can I use IBrowse (or another http-client) the way I described above?
I think you could that with hackney by reusing a connection.
Also gun is quite nice http client, easy to use, keeping connection, but with little less connection control.
I am reading that Keep-Alives is meant for performance - so that no connections need to be recreated but just reuse the existing ones. What if there is a traffic spike, will new connections be created?
Additionally, if I don't turn on Keep-Alive and in a high traffic environment, will it eventually running out of connections/socket port on client side? because a new connection has to be created for each http/web request.
HTTP is a stateless protocol.
In HTTP 1.0 each request meant opening a new TCP connection.
That caused performance issues (e.g. have to re-do the 3-way handshake for each GET or POST) so the Keep-Alive Header was added to maintain the connection across requests and in HTTP1.1 the default is persistent connection.
This means that the connection is reused across requests.
I am not really familiar with IIS but if there is a configuration to close the connection after each HTTP response, it will have impact on the performance.
Concerning the running out of sockets/ports on the client side, that could occur if the client fires a huge amount of requests and a new TCP connection must be opened per HTTP request.
After a while the ports will be depleted
My Question is related to the HTTP Streaming Method for realizing HTTP Server Push:
The "HTTP streaming" mechanism keeps a request open indefinitely. It
never terminates the request or closes the connection, even after the
server pushes data to the client. This mechanism significantly
reduces the network latency because the client and the server do not
need to open and close the connection.
The HTTP streaming mechanism is based on the capability of the server
to send several pieces of information on the same response, without
terminating the request or the connection. This result can be
achieved by both HTTP/1.1 and HTTP/1.0 servers.
The HTTP protocol allows for intermediaries
(proxies, transparent proxies, gateways, etc.) to be involved in
the transmission of a response from server to the client. There
is no requirement for an intermediary to immediately forward a
partial response and it is legal for it to buffer the entire
response before sending any data to the client (e.g., caching
transparent proxies). HTTP streaming will not work with such
intermediaries.
Do I avoid the descibed problems whith proxy servers if i use HTTPS?
HTTPS doesn't use HTTP proxies - this would make security void. HTTPS connection can be routed via some HTTP proxy or just HTTP redirector by using HTTP CONNECT command, which establishes transparent tunnel to the destination host. This tunnel is completely opaque to the proxy, and proxy can't get to know, what is transferred (it can attempt to modify the dataflow, but SSL layer will detect modification and send an alert and/or close connection), i.e. what has been encrypted by SSL.
Update: for your task you can try to use one of NULL cipher suites (if the server allows) to reduce the number of operations, such as perform no encryption, anonymous key exchange etc. (this will not affect proxy's impossibility to alter your data).