Exemplo n.º 1
0
/* Returns 0 on success and nonzero on failure. */
int http_parse_status_line(const char *line, struct http_response *response)
{
    const char *p, *q;

    http_response_init(response);

    /* Version. */
    p = parse_http_version(line, &response->version);
    if (p == line)
        return -1;
    while (*p == ' ')
        p++;

    /* Status code. */
    errno = 0;
    response->code = parse_long(p, (char **) &q);
    if (errno != 0 || q == p)
        return -1;
    p = q;

    /* Reason phrase. */
    while (*p == ' ')
        p++;
    q = p;
    while (!is_crlf(q))
        q++;
    /* We expect that the CRLF ends the string. */
    if (*skip_crlf(q) != '\0')
        return -1;
    response->phrase = mkstr(p, q);

    return 0;
}
Exemplo n.º 2
0
/* See section 4.2 of RFC 2616 for header format. */
int http_parse_header(struct http_header **result, const char *header)
{
    const char *p, *q;
    size_t value_len, value_offset;
    struct http_header *node, **prev;

    *result = NULL;
    prev = result;

    p = header;
    while (*p != '\0' && !is_crlf(p)) {
        /* Get the field name. */
        q = p;
        while (*q != '\0' && is_token_char(*q))
            q++;
        if (*q != ':') {
            http_header_free(*result);
            return 400;
        }

        node = (struct http_header *) safe_malloc(sizeof(*node));
        node->name = mkstr(p, q);
        node->value = NULL;
        node->next = NULL;
        value_len = 0;
        value_offset = 0;

        /* Copy the header field value until we hit a CRLF. */
        p = q + 1;
        p = skip_lws(p);
        for (;;) {
            q = p;
            while (*q != '\0' && !is_space_char(*q) && !is_crlf(q)) {
                /* Section 2.2 of RFC 2616 disallows control characters. */
                if (iscntrl((int) (unsigned char) *q)) {
                    http_header_node_free(node);
                    return 400;
                }
                q++;
            }
            strbuf_append(&node->value, &value_len, &value_offset, p, q - p);
            p = skip_lws(q);
            if (is_crlf(p))
                break;
            /* Replace LWS with a single space. */
            strbuf_append_str(&node->value, &value_len, &value_offset, " ");
        }
        *prev = node;
        prev = &node->next;

        p = skip_crlf(p);
    }

    return 0;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
static int cs_complete_http(const char *buf, int len, int head_only)
{
    /* deal with HTTP request/response */
    int i, content_len = 0, chunked = 0;

    /* need at least one line followed by \n or \r .. */
    for (i = 0; ; i++)
        if (i == len)
            return 0; /* incomplete */
        else if (buf[i] == '\n' || buf[i] == '\r')
            break;

    /* check to see if it's a response with content */
    if (!head_only && !memcmp(buf, "HTTP/", 5))
    {
        int j;
        for (j = 5; j < i; j++)
            if (buf[j] == ' ')
            {
                ++j;
                if (buf[j] == '1') /* 1XX */
                    ;
                else if (!memcmp(buf + j, "204", 3))
                    ;
                else if (!memcmp(buf + j, "304", 3))
                    ;
                else
                    content_len = -1;
                break;
            }
    }
#if 0
    printf("len = %d\n", len);
    fwrite (buf, 1, len, stdout);
    printf("----------\n");
#endif
    for (i = 2; i <= len-2; )
    {
        if (i > 8192)
        {
            return i;  /* do not allow more than 8K HTTP header */
        }
        if (skip_crlf(buf, len, &i))
        {
            if (skip_crlf(buf, len, &i))
            {
                /* inside content */
                if (chunked)
                    return cs_read_chunk(buf, i, len);
                else
                {   /* not chunked ; inside body */
                    if (content_len == -1)
                        return 0;   /* no content length */
                    else if (len >= i + content_len)
                    {
                        return i + content_len;
                    }
                }
                break;
            }
            else if (i < len - 20 &&
                     !yaz_strncasecmp((const char *) buf+i,
                                      "Transfer-Encoding:", 18))
            {
                i+=18;
                while (buf[i] == ' ')
                    i++;
                if (i < len - 8)
                    if (!yaz_strncasecmp((const char *) buf+i, "chunked", 7))
                        chunked = 1;
            }
            else if (i < len - 17 &&
                     !yaz_strncasecmp((const char *)buf+i,
                                      "Content-Length:", 15))
            {
                i+= 15;
                while (buf[i] == ' ')
                    i++;
                content_len = 0;
                while (i <= len-4 && yaz_isdigit(buf[i]))
                    content_len = content_len*10 + (buf[i++] - '0');
                if (content_len < 0) /* prevent negative offsets */
                    content_len = 0;
            }
            else
                i++;
        }
        else
            i++;
    }
    return 0;
}
Exemplo n.º 5
0
int main(int argc, char **argv)
{
	int rval = 0;

	lookfile = init_args(argc, argv);

	if(lookfile == stdin){
		printf(APPTITLE " >:O MUHAHAHA. READY. SET. GO!\n");
		printf("LINE NUMBERS BETWEEN %d AND %d!\n",LINENUM_MIN,LINENUM_MAX);
		printf("\n");

		printf(INPUTLINE_START);
		fflush(stdout);

		getlook();

		for(;;){

			skipwhite();

			if(look == EOF)
				break;

			if(isdigit(look)){		/* BASIC program line */
				parse_BASIC_line();
			}else if(isalpha(look)){	/* BASIC command */
				parse_BASIC_command();
			}else{				/* Syntax error */
				read_to_eol();
				error("syntax error");
			}
			printf(INPUTLINE_START);
			fflush(stdout);


			skip_crlf();
		}
	}else{
		getlook();

		for(;;){

			skipwhite();

			if(look == EOF)
				break;

			if(!isdigit(look)){
				error("no line number");
				rval = 1;
				break;
			}

			parse_BASIC_line();
			skip_crlf();
		}
		if(rval == 0){
			command_run();
		}

		fclose(lookfile);
	}

	lineset_free();

	printf("\n");
	
	return rval;
}