Just a simple question:
what is the difference between a request and a command in protocols like HTML or SMTP?
Can it be that requests await a response?
Or that one is from the client side and the other from the server side?
Thanks in advance!
Similar to http, smtp requests can contain multiple commands e.g. the TLS command to enabled encryption
E.g. HELO, BYE
Ftp is similar to Smtp, where a single connection (request) exchanges multiple commands (PASV... EXIT) before the connection is closed.
The main difference is the request response for http can usually be visualized as 1 request to 1 response however when you look at how the TLS encryption is applied over http you then see similar commands being exchanged between client and server before the final response is returned to the client.
In short http separates the noise of the commands by encompassing them into the header portions of the request and response.
An example of http commands without encryption would be chucked transfer encoding where the server send a part of the response after the headers in chunks which must be put back together at the client side.
Related
how a web server respond to the right client over HTTP as HTTP is a stateless Protocol. i mean to say that there would be multiple request and response at web server, and a client get its respective response.
During the process of a single http request a socket connection is kept open (if none of the endpoints abandon in that period of time).
The stateless term means that between multiple requests from the same client the protocol alone doesn't do anything for you to keep track of any state.
I am trying to build a simple client - server - client application using the IdHTTP component.
How to use IdHttp component to send array of bytes from a client1 to a php file located on www.example.com and have this php file send the same data to be consumed by a client2 using the IdHTTp? Maybe I am taking the wrong path here.
For sending the data from client1 to the server I recommend to use Base64 encoding. This way you have a normal string instead of a byte array. Sending strings with IdHTTP is simple. An alternative is multipart form data (Java code here).
For receiving the data on client2: HTTP clients do not know when there is data on the server. Asynchronous receive (server push) is a feature of the new WebSocket protocol, which is an extension of HTTP so it needs specifix extensions on the client and server side. There are open source and commercial implementations of the WebSocket protocol for Delphi.
If your client2 is a normal HTTP client, it has no option than to continuously poll data from the server. For basic use cases, I would recommend a TIdTCPClient component instead of TidHTTP which gives you more control over the processing of incoming data. The client jst needs to open a socket connection on port 80 of the server, send a well-formed HTTP request and then run a loop to receive the response. When the server has new data, the PHP script will start to send data (maybe even without HTTP response headers) and then the Base64 encoded data.
I'm trying to get the post data from TIdHTTPProxyServer, using OnHTTPBeforeCommand or OnHTTPDocument events but all is useless.
How can I do that?
BTW, I'm using Indy 10, but other solutions (with synapse, for example) will be cool.
Thanks in advance.
POST data is not available in the OnHTTPBeforeCommand event, as it has not been read from the socket yet. Only the HTTP headers are available in that event.
POST data is available in the OnHTTPDocument event, but only under the following conditions:
the POST request uses a non-zero Content-Length header (as TIdHTTPProxyServer does not yet support the Transfer-Encoding header to handle compressed/chunked HTTP messages).
the TIdHTTPProxyServerContext.TransferMode property is tmFullDocument when the OnHTTPBeforeCommand event exits. By default, the TransferMode is set to the same value as the TIdHTTPProxyServer.DefaultTransferMode property, which is tmFullDocument by default.
the client sends the POST request directly to TIdHTTPProxyServer, specifying a full URL as the target. If the client instead sends a CONNECT request directly to TIdHTTPProxyServer to establish a tunnel to the target server and then sends the POST request through the tunnel to the target server (for instance, when establishing SSL sessions for HTTPS requests), TIdHTTPProxyServer does not expose access to that data. It is a straight pass-through from one socket to another.
I have a Delphi 6 application that uses an Indy TIdTCPClient instance to communicate with a web server. The reason I am not using an HTTP client directly is because the the server is an image streaming server that uses the same socket connection for receiving the command to start streaming as it does to start "pushing" images back to you. In other words, after you send it a typical HTTP POST request, it replies with an HTTP response, and immediately after that it starts sending out a stream of JPEG images.
I already know how to craft a proper POST request and send it using the TIdTCPClient WriteBuffer() method and then use the ReadBuffer() method to receive reply data. What I'd like to do instead is to send a POST request and then ask Indy to wait for a typical HTTP response including retrieving all the bytes in the response body if there is a Content-Length header variable. I of course want it to leave the JPEG frames intact that may have piled in after the HTTP response in the receive queue until I start requesting them (that is, I don't want it including any of the JPEG frames in the HTTP response to my streaming request command until I ask for them using a successive read call).
Is there a method that I can call on a TIdTCPClient that will retrieve completely a typical HTTP response with body content, and nothing else? I thought about using SendCmd() and checking the LastCmdResult property (type: TIdRFCReply) for the response, but I can't tell from the Indy documentation if it retrieves the response body content too if there is a Content-Length header variable as part of the response it returns, nor can I tell if it leaves the rest of the receive queue after the response intact.
What is the best way to accomplish this mixed mode interaction with an HTTP web server that pushes out a stream of JPEG frames right after you make the HTTP request to start streaming?
Also, if there is a clever way to have Indy split the frames using the JPEG frame WINBONDBOUDARY delimiting string, rather than accumulating blocks of data and parsing them out myself, please share that technique.
The correct way to read an HTTP response is to first read the CRLF-delimited response headers line-by-line until a blank line is encountered, aka a CRLF+CRLF sequence, then you can use those headers to decide how to read the remaining response data. The headers will tell you not only what kind of stream is being sent (via the Content-Type header), but also how the data is being framed (Content-Length, Transfer-Encoding: chunked, something specific to the particular Content-Type, etc).
To receive the headers, you can use the connection's Capture() method, setting its ADelim parameter to a blank string.
How you read the remaining data afterwards depends on the actual formatting/framing of the stream. Without knowing exactly what kind of stream you are receiving, there is no way to advise you how best to read it, as there are several different types of streaming protocols used by HTTP servers, and most of them are not standardized. Provide that information, then I/we can show you how to implement it with Indy.
You cannot use SendCmd() as the HTTP protocol does not format its responses in a way that is compatible with that method.
I am trying my hand in server applications using Indy Internet tools.
My client sends Post data (XML) in Unicode format.
Can I convey my preference to client (HTTP Client). I prefer Text. In general can a HTTP server send its preferences to its Clients?
Thanks for any hint or help.
The problem with this is the fact, that with only one POST the server has no way to respond, until the client has already sent the data.
The solution is to make two calls: One where the client asks for the server preferences and another to send the data. The OPTIONS HTTP method can be used for this scenario.
You can handle both requests on the same URL: If the clients makes an OPTIONS request the server responds with the configuration data. (via response headers) Then the client can make a POST request on the same URL and the server handles the data appropriately.
For further information see HTTP methods and HTTP headers, especially the Accept header.