Exemple #1
0
static void
http_req_free(struct http_req *req)
{
    unsigned i;

    free(req->response);
    for (i = 0; i < req->num_headers; i++)
	free(req->headers[i]);
    free(req->headers);
    free(req->body);
    http_req_zero(req);
}
Exemple #2
0
static int
http_query(krb5_storage *sp,
	   const char *host, const char *page,
	   char **headers, unsigned num_headers, struct http_req *req)
{
    enum { RESPONSE, HEADER, BODY } state;
    ssize_t ret;
    char in_buf[1024];
    size_t in_len = 0, content_length;
    unsigned i;

    http_req_zero(req);
    
    if (verbose_flag) {
	for (i = 0; i < num_headers; i++)
	    printf("outheader[%d]: %s\n", i, headers[0]);
    }

    storage_printf(sp, "GET %s HTTP/1.1\r\n", page);
    for (i = 0; i < num_headers; i++)
	storage_printf(sp, "%s\r\n", headers[i]);
    storage_printf(sp, "Host: %s\r\n\r\n", host);

    state = RESPONSE;

    while (1) {
	char *p;

	ret = krb5_storage_read(sp, in_buf + in_len, 1);
	if (ret != 1)
	    errx(1, "storage foo");
	
	in_len += 1;

	in_buf[in_len] = '\0';

	p = strstr(in_buf, "\r\n");

	if (p == NULL)
	    continue;
	
	if (p == in_buf) {
	    memmove(in_buf, in_buf + 2, sizeof(in_buf) - 2);
	    state = BODY;
	    break;
	} else if (state == RESPONSE) {
	    req->response = strndup(in_buf, p - in_buf);
	    state = HEADER;
	} else {
	    req->headers = realloc(req->headers,
				   (req->num_headers + 1) * sizeof(req->headers[0]));
	    req->headers[req->num_headers] = strndup(in_buf, p - in_buf);
	    if (req->headers[req->num_headers] == NULL)
		errx(1, "strdup");
	    req->num_headers++;
	}
	in_len = 0;
    }

    if (state != BODY)
	abort();

    const char *h = http_find_header(req, "Content-Length:");
    if (h == NULL)
	errx(1, "Missing `Content-Length'");

    content_length = atoi(h);

    req->body_size = content_length;
    req->body = erealloc(req->body, content_length + 1);

    ret = krb5_storage_read(sp, req->body, req->body_size);
    if (ret < 0 || (size_t)ret != req->body_size)
	errx(1, "failed to read body");

    ((char *)req->body)[req->body_size] = '\0';
	
    if (verbose_flag) {
	printf("response: %s\n", req->response);
	for (i = 0; i < req->num_headers; i++)
	    printf("response-header[%d] %s\n", i, req->headers[i]);
	printf("body: %.*s\n", (int)req->body_size, (char *)req->body);
    }

    return 0;
}
Exemple #3
0
static int
http_query(const char *host, const char *page,
	   char **headers, int num_headers, struct http_req *req)
{
    enum { RESPONSE, HEADER, BODY } state;
    ssize_t ret;
    char in_buf[1024], *in_ptr = in_buf;
    size_t in_len = 0;
    int s, i;

    http_req_zero(req);

    s = do_connect(host, port_str);
    if (s < 0)
	errx(1, "connection failed");

    fdprintf(s, "GET %s HTTP/1.0\r\n", page);
    for (i = 0; i < num_headers; i++)
	fdprintf(s, "%s\r\n", headers[i]);
    fdprintf(s, "Host: %s\r\n\r\n", host);

    state = RESPONSE;

    while (1) {
	ret = read (s, in_ptr, sizeof(in_buf) - in_len - 1);
	if (ret == 0)
	    break;
	else if (ret < 0)
	    err (1, "read: %lu", (unsigned long)ret);

	in_buf[ret + in_len] = '\0';

	if (state == HEADER || state == RESPONSE) {
	    char *p;

	    in_len += ret;
	    in_ptr += ret;

	    while (1) {
		p = strstr(in_buf, "\r\n");

		if (p == NULL) {
		    break;
		} else if (p == in_buf) {
		    memmove(in_buf, in_buf + 2, sizeof(in_buf) - 2);
		    state = BODY;
		    in_len -= 2;
		    in_ptr -= 2;
		    break;
		} else if (state == RESPONSE) {
		    req->response = emalloc(p - in_buf + 1);
		    memcpy(req->response, in_buf, p - in_buf);
		    req->response[p - in_buf] = '\0';
		    state = HEADER;
		} else {
		    req->headers = realloc(req->headers,
					   (req->num_headers + 1) * sizeof(req->headers[0]));
		    req->headers[req->num_headers] = emalloc(p - in_buf + 1);
		    memcpy(req->headers[req->num_headers], in_buf, p - in_buf);
		    req->headers[req->num_headers][p - in_buf] = '\0';
		    if (req->headers[req->num_headers] == NULL)
			errx(1, "strdup");
		    req->num_headers++;
		}
		memmove(in_buf, p + 2, sizeof(in_buf) - (p - in_buf) - 2);
		in_len -= (p - in_buf) + 2;
		in_ptr -= (p - in_buf) + 2;
	    }
	}

	if (state == BODY) {

	    req->body = erealloc(req->body, req->body_size + ret + 1);

	    memcpy((char *)req->body + req->body_size, in_buf, ret);
	    req->body_size += ret;
	    ((char *)req->body)[req->body_size] = '\0';

	    in_ptr = in_buf;
	    in_len = 0;
	} else
	    abort();
    }

    if (verbose_flag) {
	int i;
	printf("response: %s\n", req->response);
	for (i = 0; i < req->num_headers; i++)
	    printf("header[%d] %s\n", i, req->headers[i]);
	printf("body: %.*s\n", (int)req->body_size, (char *)req->body);
    }

    close(s);
    return 0;
}