C разбор ответа кодирования HTTP-фрагментов передачи

Я разрабатываю клиент, которому необходимо анализировать HTTP-передачи типа Chunked. Я бился головой о стену, пытаясь понять ошибку со следующим, и был бы признателен, если бы кто-то смог немного быстрее поймать мою ошибку. Подводя итог: кажется, что клиент не получает ВЕСЬ кусок, тем самым портя остальную часть процесса. Заранее спасибо!

 while(cflag){
    pfile_chunk = malloc(CHUNK_SIZE+1);
    memset(pfile_chunk, 0, CHUNK_SIZE);
    cPtr = pfile_chunk;
    cPtr2 = NULL;
    k=0;
    while(*(cPtr-1) != '\n'){
        k++;
        recv(sock, cPtr, 1, 0);
        cPtr = pfile_chunk+k;
    }
    cPtr2 = strchr(pfile_chunk, '\r');
    *cPtr2 = '\0';
    sscanf(pfile_chunk, "%x", &l);
    if(l == 0)
        break;
    printf("\nServer wants to deliver %ld bytes.\n", l);
    pfile_chunk = realloc(pfile_chunk, l+1);
    memset(pfile_chunk, 0, l);
    recv(sock, pfile_chunk, l, 0);
    fputs(pfile_chunk, f);
    printf("GOT THIS, SIZE %ld:\n%s\n", strlen(pfile_chunk), pfile_chunk);
    //get next \r\n bytes.
    recv(sock, NULL, 2, 0);
}

person E Klonowski    schedule 23.07.2012    source источник
comment
Заранее извиняюсь за неаккуратный код, это был более или менее результат того, что я пробовал много разных вещей.   -  person E Klonowski    schedule 24.07.2012
comment
Не могли бы вы опубликовать свой окончательный, очищенный код? Я тоже мучаюсь с этой задачей. Не уверен, как согласовать то, что считывается из буфера, с фактическими фрагментами HTTP. Сохраняете ли вы весь HTTP-ответ перед разбором фрагментов?   -  person CFL_Jeff    schedule 24.08.2012


Ответы (2)


По крайней мере, вы должны проверить возвращаемое значение recv, чтобы увидеть, получаете ли вы ожидаемое количество байтов.

Короткое чтение определенно возможно в сети, так как системный вызов вернет все, что доступно в буфере приема сокета во время выполнения вызова.

Реализуйте цикл, пока не прочитаете весь фрагмент, или передайте флаг MSG_WAITALL в recv в последнем параметре. Однако вам все равно нужно проверить наличие ошибки из recv.

ssize_t r = recv(sock, pfile_chunk, l, MSG_WAITALL);
if (r < l) {
    /* check for errors ... */
} else {
    /* got the data */
}
person jxh    schedule 23.07.2012
comment
Спасибо, сэр, я даже не рассматривал флаги отправки/получения. Проверка ошибок отсутствовала, так как я очень торопился перемещать неаккуратный код. Ценить это! Кто-нибудь +1 этому парню, у меня нет нужной репутации. - person E Klonowski; 24.07.2012

Похоже, что ваше самое первое разыменование для проверки в вашем цикле while будет обращаться до начала вашего массива, что, вероятно, нежелательно. Надеюсь, эта ячейка памяти обычно не будет содержать \n. Это может испортить ваш read. Я ожидаю, что он, вероятно, содержит некоторую информацию, связанную с вашим malloc, которая вряд ли будет \n, поэтому вы никогда не увидите проблемы из-за этого.

Кроме того, надеюсь, вы можете доверять другому концу сокета, чтобы не отправлять больше CHUNK_SIZE+1, прежде чем они дадут вам \n. В противном случае он может выйти из строя. Однако обычно я ожидаю, что отправитель просто отправит 10 или меньше числовых символов ASCII и CRLF для заголовка блока, но теоретически он может отправить вместе с ним кучу длинных полей заголовка расширения блока.

Кроме того, есть более важная проблема, уже обнаруженная пользователем 315052: вы должны либо указать методу recv ждать всех запрошенных вами данных, либо проверить, сколько данных он фактически прочитал.

person Concerned Citizen    schedule 11.10.2012