forked from cory/tildefriends
Send a valid HTTP response and shutdown the connection.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4679 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
64
src/http.c
64
src/http.c
@ -6,6 +6,7 @@
|
||||
#include "picohttpparser.h"
|
||||
#include "uv.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(_WIN32)
|
||||
@ -121,16 +122,6 @@ void _http_on_read(uv_stream_t* stream, ssize_t read_size, const uv_buf_t* buffe
|
||||
.user_data = connection->user_data,
|
||||
};
|
||||
connection->callback(&request);
|
||||
|
||||
const char* payload = "HTTP/1.0 200 OK\r\nContent-Length: 13\r\n\r\nHello, world!";
|
||||
uv_write_t* write = tf_malloc(sizeof(uv_write_t) + strlen(payload));
|
||||
*write = (uv_write_t) { 0 };
|
||||
memcpy(write + 1, payload, strlen(payload));
|
||||
int r = uv_write(write, stream, &(uv_buf_t) { .base = (char*)(write + 1), .len = strlen(payload) }, 1, _http_on_write);
|
||||
if (r)
|
||||
{
|
||||
tf_printf("uv_write: %s\n", uv_strerror(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -231,3 +222,56 @@ void tf_http_destroy(tf_http_t* http)
|
||||
{
|
||||
tf_free(http);
|
||||
}
|
||||
|
||||
static const char* _http_status_text(int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case 200: return "OK";
|
||||
case 404: return "File not found";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void _http_on_shutdown(uv_shutdown_t* request, int status)
|
||||
{
|
||||
tf_free(request);
|
||||
}
|
||||
|
||||
void tf_http_respond(tf_http_request_t* request, int status, const char** headers, int headers_count, void* body, size_t content_length)
|
||||
{
|
||||
const char* status_text = _http_status_text(status);
|
||||
/* HTTP/1.x 200 OK\r\n */
|
||||
int headers_length = 8 + 1 + 3 + 1 + strlen(status_text) + 2;
|
||||
for (int i = 0; i < headers_count; i += 2)
|
||||
{
|
||||
/* Key: Value\r\n */
|
||||
headers_length += strlen(headers[i]) + 2 + strlen(headers[i + 1]) + 2;
|
||||
}
|
||||
/* \r\n */
|
||||
headers_length += 2;
|
||||
|
||||
uv_write_t* write = tf_malloc(sizeof(uv_write_t) + headers_length + content_length + 1);
|
||||
*write = (uv_write_t) { .data = request->connection };
|
||||
char* buffer = (char*)(write + 1);
|
||||
int offset = snprintf(buffer, headers_length + 1, "HTTP/1.0 %03d %s\r\n", status, status_text);
|
||||
for (int i = 0; i < headers_count; i += 2)
|
||||
{
|
||||
offset += snprintf(buffer + offset, headers_length + 1 - offset, "%s: %s\r\n", headers[i], headers[i + 1]);
|
||||
}
|
||||
offset += snprintf(buffer + offset, headers_length + 1 - offset, "\r\n");
|
||||
assert(offset == headers_length);
|
||||
if (content_length)
|
||||
{
|
||||
memcpy(buffer + offset, body, content_length);
|
||||
}
|
||||
int r = uv_write(write, (uv_stream_t*)&request->connection->tcp, &(uv_buf_t) { .base = buffer, .len = headers_length + content_length }, 1, _http_on_write);
|
||||
if (r)
|
||||
{
|
||||
tf_printf("uv_write: %s\n", uv_strerror(r));
|
||||
}
|
||||
|
||||
uv_shutdown_t* shutdown_request = tf_malloc(sizeof(uv_shutdown_t));
|
||||
*shutdown_request = (uv_shutdown_t) { .data = request };
|
||||
uv_shutdown(shutdown_request, (uv_stream_t*)&request->connection->tcp, _http_on_shutdown);
|
||||
}
|
||||
|
Reference in New Issue
Block a user