I am using Delphi 7 and Indy 9 to implement a trivial HTTP server. When I upload a file to the server using the POST method, I would like to know the content-length before the OnCommandGet event, in order to show a progress bar. The event sequence is the following:
I modified the Indy sources to get a copy of the TIdHTTPRequestInfo in the ASender.Data field passed to the OnPostStream handler. Everything works, but I would like not to touch Indy.
Is there a cleaner solution? Thank you
Is there a cleaner solution?
Not for Indy 9, no. Modifying Indy's source code to expose access to the request object (or at least the request headers) is the only option.
In Indy 10, TIdHTTPServer
actually provides 2 ways that you can get the Content-Length
value before the POST data is read - there is a new OnHeadersAvailable
event that has an AHeaders
parameter, and the OnCreatePostStream
event has a new AHeaders
parameter as well (so different stream classes can be used depending on the type of request being made). You can grab the Content-Length
value from the provided TIdHeaderList
object in either event and store the value in ASender.Data
as needed for later use.
HOWEVER - do keep in mind that TIdHTTPServer
in Indy 10 supports HTTP 1.1, and HTTP 1.1 servers are required to allow HTTP 1.1 clients to post data using the chunked
transfer encoding. In which case, there will be no Content-Length
header present (or it will be 0), and thus the data length will not be known until the final chunk has been received. Fortunately, you can look at the Transfer-Encoding
header in the OnHeadersAvailable
/OnCreatePostStream
event to detect that condition and tailor your progress events accordingly.