Fix a couple more bugs in new HTTP server code

This commit is contained in:
Andrew Bettison 2013-10-25 23:57:23 +10:30
parent 6488f7ad65
commit 5ff5a02bb9
4 changed files with 34 additions and 18 deletions

View File

@ -1590,18 +1590,18 @@ static void http_request_start_response(struct http_request *r)
watch(&r->alarm);
}
/* Start sending a response back to the client. The response's Content-Type is set by the
* 'mime_type' parameter (in the standard format "type/subtype"). The response's content is set
* from the 'body' and 'bytes' parameters, which need not point to static data, ie, is no longer
* used once this function returns.
/* Start sending a static (pre-computed) response back to the client. The response's Content-Type
* is set by the 'mime_type' parameter (in the standard format "type/subtype"). The response's
* content is set from the 'body' and 'bytes' parameters, which need not point to persistent data,
* ie, the memory pointed to by 'body' is no longer referenced once this function returns.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
void http_request_response(struct http_request *r, int result, const char *mime_type, const char *body, uint64_t bytes)
void http_request_response_static(struct http_request *r, int result, const char *mime_type, const char *body, uint64_t bytes)
{
assert(r->phase == RECEIVE);
assert(result >= 100);
assert(result < 600);
assert(result < 300);
assert(mime_type != NULL);
assert(mime_type[0]);
r->response.result_code = result;
@ -1613,6 +1613,20 @@ void http_request_response(struct http_request *r, int result, const char *mime_
http_request_start_response(r);
}
void http_request_response_generated(struct http_request *r, int result, const char *mime_type, HTTP_CONTENT_GENERATOR generator)
{
assert(r->phase == RECEIVE);
assert(result >= 100);
assert(result < 300);
assert(mime_type != NULL);
assert(mime_type[0]);
r->response.result_code = result;
r->response.header.content_type = mime_type;
r->response.content = NULL;
r->response.content_generator = generator;
http_request_start_response(r);
}
/* Start sending a short redirection or error response back to the client. The result code must be
* either a redirection (3xx) or client error (4xx) or server error (5xx) code. The 'body' argument
* may be a bare message which is enclosed in an HTML envelope to form the response content, so it

View File

@ -73,11 +73,13 @@ struct http_response_headers {
const char *boundary;
};
typedef int (*HTTP_CONTENT_GENERATOR)(struct http_request *);
struct http_response {
uint16_t result_code;
struct http_response_headers header;
const char *content;
int (*content_generator)(struct http_request *); // callback to produce more content
HTTP_CONTENT_GENERATOR content_generator; // callback to produce more content
};
#define MIME_FILENAME_MAXLEN 127
@ -108,7 +110,8 @@ void http_request_init(struct http_request *r, int sockfd);
void http_request_free_response_buffer(struct http_request *r);
int http_request_set_response_bufsize(struct http_request *r, size_t bufsiz);
void http_request_finalise(struct http_request *r);
void http_request_response(struct http_request *r, int result, const char *mime_type, const char *body, uint64_t bytes);
void http_request_response_static(struct http_request *r, int result, const char *mime_type, const char *body, uint64_t bytes);
void http_request_response_generated(struct http_request *r, int result, const char *mime_type, HTTP_CONTENT_GENERATOR);
void http_request_simple_response(struct http_request *r, uint16_t result, const char *body);
typedef int (*HTTP_REQUEST_PARSER)(struct http_request *);

View File

@ -160,7 +160,7 @@ int rhizome_direct_enquiry_end(struct http_request *hr)
if (http_request_set_response_bufsize(&r->http, bytes) == -1)
http_request_simple_response(&r->http, 500, "Internal Error: Out of memory");
else
http_request_response(&r->http, 200, "binary/octet-stream", (const char *)c->buffer, bytes);
http_request_response_static(&r->http, 200, "binary/octet-stream", (const char *)c->buffer, bytes);
rhizome_direct_bundle_iterator_free(&c);
} else
http_request_simple_response(&r->http, 500, "Internal Error: No response to enquiry");
@ -258,7 +258,7 @@ int rhizome_direct_addfile_end(struct http_request *hr)
if (config.debug.rhizome)
DEBUGF("Import sans-manifest appeared to succeed");
/* Respond with the manifest that was added. */
http_request_response(&r->http, 200, "text/plain", (const char *)m->manifestdata, m->manifest_bytes);
http_request_response_static(&r->http, 200, "text/plain", (const char *)m->manifestdata, m->manifest_bytes);
/* clean up after ourselves */
if (mout && mout != m)
rhizome_manifest_free(mout);

View File

@ -331,7 +331,7 @@ static int neighbour_page(rhizome_http_request *r, const char *remainder)
strbuf_puts(b, "</body></html>");
if (strbuf_overrun(b))
return -1;
http_request_response(&r->http, 200, "text/html", buf, strbuf_len(b));
http_request_response_static(&r->http, 200, "text/html", buf, strbuf_len(b));
return 0;
}
@ -351,7 +351,7 @@ static int interface_page(rhizome_http_request *r, const char *remainder)
strbuf_puts(b, "</body></html>");
if (strbuf_overrun(b))
return -1;
http_request_response(&r->http, 200, "text/html", buf, strbuf_len(b));
http_request_response_static(&r->http, 200, "text/html", buf, strbuf_len(b));
return 0;
}
@ -374,7 +374,7 @@ static int rhizome_status_page(rhizome_http_request *r, const char *remainder)
strbuf_puts(b, "</body></html>");
if (strbuf_overrun(b))
return -1;
http_request_response(&r->http, 200, "text/html", buf, strbuf_len(b));
http_request_response_static(&r->http, 200, "text/html", buf, strbuf_len(b));
return 0;
}
@ -455,8 +455,7 @@ static int rhizome_file_page(rhizome_http_request *r, const char *remainder)
r->http.response.header.resource_length = closed.last;
r->http.response.header.content_length = closed.last - closed.first;
r->read_state.offset = closed.first;
r->http.response.content_generator = rhizome_file_content;
http_request_response(&r->http, result_code, "application/binary", NULL, 0);
http_request_response_generated(&r->http, result_code, "application/binary", rhizome_file_content);
return 0;
}
@ -478,7 +477,7 @@ static int manifest_by_prefix_page(rhizome_http_request *r, const char *remainde
if (ret == -1)
http_request_simple_response(&r->http, 500, NULL);
else if (ret == 0)
http_request_response(&r->http, 200, "application/binary", (const char *)m->manifestdata, m->manifest_all_bytes);
http_request_response_static(&r->http, 200, "application/binary", (const char *)m->manifestdata, m->manifest_all_bytes);
rhizome_manifest_free(m);
return ret <= 0 ? 0 : 1;
}
@ -487,7 +486,7 @@ static int fav_icon_header(rhizome_http_request *r, const char *remainder)
{
if (*remainder)
return 1;
http_request_response(&r->http, 200, "image/vnd.microsoft.icon", (const char *)favicon_bytes, favicon_len);
http_request_response_static(&r->http, 200, "image/vnd.microsoft.icon", (const char *)favicon_bytes, favicon_len);
return 0;
}
@ -521,6 +520,6 @@ static int root_page(rhizome_http_request *r, const char *remainder)
WHY("HTTP Root page buffer overrun");
http_request_simple_response(&r->http, 500, NULL);
} else
http_request_response(&r->http, 200, "text/html", temp, strbuf_len(b));
http_request_response_static(&r->http, 200, "text/html", temp, strbuf_len(b));
return 0;
}