TIdHTTPServer Getting content-length when receiving the PostStream

1.4k views Asked by At

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:

  1. On the OnPostStream I create a file stream and hook the OnWork event. (here I need the content-length to set the progress bar)
  2. The POST body is uploaded and the OnWork fires with the transferred bytes.
  3. 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

1

There are 1 answers

0
Remy Lebeau On BEST ANSWER

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.