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:
- On the OnPostStream I create a file stream and hook the OnWork event. (here I need the content-length to set the progress bar)
- The POST body is uploaded and the OnWork fires with the transferred bytes.
- The OnCommandGet even fires and I get the TIdHTTPRequestInfo object wuth the correct content length, but at this point it is too late.
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
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 theContent-Length
value before the POST data is read - there is a newOnHeadersAvailable
event that has anAHeaders
parameter, and theOnCreatePostStream
event has a newAHeaders
parameter as well (so different stream classes can be used depending on the type of request being made). You can grab theContent-Length
value from the providedTIdHeaderList
object in either event and store the value inASender.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 thechunked
transfer encoding. In which case, there will be noContent-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 theTransfer-Encoding
header in theOnHeadersAvailable
/OnCreatePostStream
event to detect that condition and tailor your progress events accordingly.