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,
TIdHTTPServeractually provides 2 ways that you can get theContent-Lengthvalue before the POST data is read - there is a newOnHeadersAvailableevent that has anAHeadersparameter, and theOnCreatePostStreamevent has a newAHeadersparameter as well (so different stream classes can be used depending on the type of request being made). You can grab theContent-Lengthvalue from the providedTIdHeaderListobject in either event and store the value inASender.Dataas needed for later use.HOWEVER - do keep in mind that
TIdHTTPServerin Indy 10 supports HTTP 1.1, and HTTP 1.1 servers are required to allow HTTP 1.1 clients to post data using thechunkedtransfer encoding. In which case, there will be noContent-Lengthheader 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-Encodingheader in theOnHeadersAvailable/OnCreatePostStreamevent to detect that condition and tailor your progress events accordingly.