We help IT Professionals succeed at work.

How to deal with "Transfer-Encoding: chunked" in ISAPI extension?

High Priority
38 Views
Last Modified: 2020-03-24
I have an ISAPI extension web application implemented in C++
A client does a POST with the "Transfer-Encoding: chunked" header.
I cannot find an example or a documentation how to manage such type of request in ISAPI extension.
I put a debugger breakpoint in my ISAPI callback function and it hits only once with the first chunk in the available buffer.
Could somebody point me to a working example or/and documentation?
Comment
Watch Question

nociSoftware Engineer
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
Chunked encoding is HTTP/1.1    if you can transfer for HTTP/1.0  then chunked encoding is not possible.

If you need a library that can handle that mode. Check the sources of https://curl.haxx.se
zc2
CERTIFIED EXPERT

Author

Commented:
Yes, I use CURL to simulate the request when I debug the ISAPI extension code. The protocol is obviously HTTP/1.1
nociSoftware Engineer
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
libcurl has the sources for handling chunked transfers. So you can compare to that code if you need chunked encoding.
I have no windows systems, so i cannot help with IIS testing.
zc2
CERTIFIED EXPERT

Author

Commented:
noci,
thank you, but libcurl is a client library, right? And it is probably completely different from the API we have in Windows IIS server. I need not a theoretical concept (I know how the chunked HTTP works), however I need to know how to get all the chunks handling the ISAPI callback.
CERTIFIED EXPERT
Commented:
Ok, turned out, there is nothing complicated.
If I just call ecb->ReadClient() until lpdwSize is 0, I can read all the chunks.
Just don't rely on the ecb->cbTotalBytes which is -1 in this case.
Here is a function which reads all the input.
ulong ReadAll( byte *buffer, ulong buf_sz )
{
    try {
        ulong bytes = ecb->cbAvailable;
        if( bytes > buf_sz )
            bytes = buf_sz;
        memcpy( buffer, ecb->lpbData, bytes );
        while( bytes < buf_sz ) {
            ulong sz = buf_sz - bytes;
            if( !ecb->ReadClient( ecb->ConnID, buffer + bytes, &sz ) || !sz ) break;
            bytes += sz;
        }
        return bytes;
    }
    catch( ... ) {
          //
    }
    return 0;
}

Open in new window

.