Esempio n. 1
0
static int cs_read_chunk(const char *buf, int i, int len)
{
    /* inside chunked body .. */
    while (1)
    {
        int chunk_len = 0;
#if CHUNK_DEBUG
        if (i < len-2)
        {
            int j;
            printf ("\n<<<");
            for (j = i; j <= i+3; j++)
                printf ("%c", buf[j]);
            printf (">>>\n");
        }
#endif
        /* read chunk length */
        while (1)
            if (i >= len-2) {
#if CHUNK_DEBUG
                printf ("returning incomplete read at 1\n");
                printf ("i=%d len=%d\n", i, len);
#endif
                return 0;
            } else if (yaz_isdigit(buf[i]))
                chunk_len = chunk_len * 16 +
                    (buf[i++] - '0');
            else if (yaz_isupper(buf[i]))
                chunk_len = chunk_len * 16 +
                    (buf[i++] - ('A'-10));
            else if (yaz_islower(buf[i]))
                chunk_len = chunk_len * 16 +
                    (buf[i++] - ('a'-10));
            else
                break;
        if (chunk_len == 0)
            break;
        if (chunk_len < 0)
            return i;

        while (1)
        {
            if (i >= len -1)
                return 0;
            if (skip_crlf(buf, len, &i))
                break;
            i++;
        }
        /* got CRLF */
#if CHUNK_DEBUG
        printf ("chunk_len=%d\n", chunk_len);
#endif
        i += chunk_len;
        if (i >= len-2)
            return 0;
        if (!skip_crlf(buf, len, &i))
            return 0;
    }
    /* consider trailing headers .. */
    while (i < len)
    {
        if (skip_crlf(buf, len, &i))
        {
            if (skip_crlf(buf, len, &i))
                return i;
        }
        else
            i++;
    }
#if CHUNK_DEBUG
    printf ("returning incomplete read at 2\n");
    printf ("i=%d len=%d\n", i, len);
#endif
    return 0;
}
Esempio n. 2
0
File: http.c Progetto: nla/yaz
static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers,
                                  char **content_buf, int *content_len)
{
    int i = off;
    int chunked = 0;

    *headers = 0;
    while (i < o->size-1 && o->buf[i] == '\n')
    {
        int po;
        i++;
        if (o->buf[i] == '\r' && i < o->size-1 && o->buf[i+1] == '\n')
        {
            i++;
            break;
        }
        if (o->buf[i] == '\n')
            break;
        for (po = i; ; i++)
        {
            if (i == o->size)
            {
                o->error = OHTTP;
                return 0;
            }
            else if (o->buf[i] == ':')
                break;
        }
        *headers = (Z_HTTP_Header *) odr_malloc(o, sizeof(**headers));
        (*headers)->name = (char*) odr_malloc(o, i - po + 1);
        memcpy ((*headers)->name, o->buf + po, i - po);
        (*headers)->name[i - po] = '\0';
        i++;
        while (i < o->size-1 && o->buf[i] == ' ')
            i++;
        for (po = i; i < o->size-1 && !strchr("\r\n", o->buf[i]); i++)
            ;

        (*headers)->value = (char*) odr_malloc(o, i - po + 1);
        memcpy ((*headers)->value, o->buf + po, i - po);
        (*headers)->value[i - po] = '\0';

        if (!strcasecmp((*headers)->name, "Transfer-Encoding")
            &&
            !strcasecmp((*headers)->value, "chunked"))
            chunked = 1;
        headers = &(*headers)->next;
        if (i < o->size-1 && o->buf[i] == '\r')
            i++;
    }
    *headers = 0;
    if (o->buf[i] != '\n')
    {
        o->error = OHTTP;
        return 0;
    }
    i++;

    if (chunked)
    {
        int off = 0;

        /* we know buffer will be smaller than o->size - i*/
        *content_buf = (char*) odr_malloc(o, o->size - i);

        while (1)
        {
            /* chunk length .. */
            int chunk_len = 0;
            for (; i  < o->size-2; i++)
                if (yaz_isdigit(o->buf[i]))
                    chunk_len = chunk_len * 16 +
                        (o->buf[i] - '0');
                else if (yaz_isupper(o->buf[i]))
                    chunk_len = chunk_len * 16 +
                        (o->buf[i] - ('A'-10));
                else if (yaz_islower(o->buf[i]))
                    chunk_len = chunk_len * 16 +
                        (o->buf[i] - ('a'-10));
                else
                    break;
            /* chunk extension ... */
            while (o->buf[i] != '\r' && o->buf[i+1] != '\n')
            {
                if (i >= o->size-2)
                {
                    o->error = OHTTP;
                    return 0;
                }
                i++;
            }
            i += 2;  /* skip CRLF */
            if (chunk_len == 0)
                break;
            if (chunk_len < 0 || off + chunk_len > o->size)
            {
                o->error = OHTTP;
                return 0;
            }
            /* copy chunk .. */
            memcpy (*content_buf + off, o->buf + i, chunk_len);
            i += chunk_len + 2; /* skip chunk+CRLF */
            off += chunk_len;
        }
        if (!off)
            *content_buf = 0;
        *content_len = off;
    }
    else
    {
        if (i > o->size)
        {
            o->error = OHTTP;
            return 0;
        }
        else if (i == o->size)
        {
            *content_buf = 0;
            *content_len = 0;
        }
        else
        {
            *content_len = o->size - i;
            *content_buf = (char*) odr_malloc(o, *content_len + 1);
            memcpy(*content_buf, o->buf + i, *content_len);
            (*content_buf)[*content_len] = '\0';
        }
    }
    return 1;
}