0

I am using Winsock. I send a request to a server, and the HTTP Headers contain "Transfer-Encoding: chunked". If they contain "Content-Length: xxxxx", it's obvious - but how do I parse the data into a buffer using recv() if it's chunked?

Some pseudo-code or explanation would be greatly appreciated!

Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28
  • Did you try Googling *http chunked transfer encoding*? – user253751 Sep 07 '17 at 01:37
  • @immibis Of course, I'm working with C, and there was no related results. – bobbybrown6969 Sep 07 '17 at 01:37
  • There's probably a library you can use that will do the parsing for you. – Barmar Sep 07 '17 at 01:54
  • @Barmar I'm trying to figure out how to do this from scratch – bobbybrown6969 Sep 07 '17 at 01:56
  • Well then it's something that you have to work out yourself as it's specific to your program. You can see that in chunked encoding the response has a number of bytes, then that many bytes, and it ends when the number of bytes is 0. So why don't you read the number of bytes, then read that many bytes, and stop when the number of bytes is 0? – user253751 Sep 07 '17 at 01:59
  • [Search SO for `[c] parse chunked encoding`](https://stackoverflow.com/search?q=%5Bc%5D+parse+chunked+encoding) – Barmar Sep 07 '17 at 01:59
  • https://www.greenbytes.de/tech/webdav/rfc7230.html#decoding.chunked – Julian Reschke Sep 07 '17 at 05:06

1 Answers1

0

Assuming you have a socket. All HTTP headers has been received (from this socket). Here is simplified algorithm to receive chunked content from the socket.

#define MAX_SIZE 1024

char *RecvChunked(SOCKET s)
{
    int chunk_length;
    char result[MAX_SIZE];
    char *result_ptr;

    memset(result,0,sizeof(result));

    for (chunk_length=0, result_ptr=result;;)
    {
        int recv_size;
        int size;

        if (chunk_length == 0) // get chunk length
        {
            char str[MAX_SIZE];
            char *ptr;

            // RecvLn
            for (ptr=str; ptr-str+sizeof(char) < sizeof(str);)
            {
                int ret = recv(s, ptr, sizeof(char), 0);
                if (ret <= 0)
                {
                    break;
                }

                if (*ptr != '\n')
                {
                    ptr += ret;
                    continue;
                }

                if (ptr-str <= 1)
                {
                    break;
                }

                if (*(ptr-1) == '\r')
                {
                    ptr --;
                }
                break;
            }

            *ptr = '\0';

            chunk_length = (int)strtol(str, NULL, 16); // HexToInt
        }
        recv_size = MIN(sizeof(result)-(result_ptr-result)-sizeof(char), chunk_length);

        if (recv_size == 0)
        {
            break; // nothing to receive
        }

        size = recv(s, result_ptr, recv_size, 0);

        if (chunk_length >= size)
        {
            chunk_length -= size;
        }
        else
        {
            chunk_length = 0;
        }

        result_ptr += size;

        if (size == 0)
        {
            // Disconnected ?
            break;
        }

        if (chunk_length == 0) // recv '\r\n' at the end of every chunk
        {
            char str[2];
            if (recv(s, str, sizeof(str), 0) < 2)
            {
                break; // Disconnect ?
            }
        }
    }
    return strdup(result);
}

This code is just for clarify how to parse chunked content from the socket.

vadim_hr
  • 533
  • 5
  • 11