Синтаксический анализ 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);
}

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 */
}

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

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

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

Другие вопросы по тегам