129 lines
4.4 KiB
C
129 lines
4.4 KiB
C
#define HTTPSERVER_IMPL
|
|
#include "../../build/src/httpserver.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
|
|
#define RESPONSE "Hello, World!"
|
|
|
|
ssize_t hs_test_write(int fd, char const *data, size_t size) {
|
|
return write(fd, data, size);
|
|
}
|
|
|
|
int request_target_is(struct http_request_s* request, char const * target) {
|
|
http_string_t url = http_request_target(request);
|
|
int len = strlen(target);
|
|
return len == url.len && memcmp(url.buf, target, url.len) == 0;
|
|
}
|
|
|
|
int chunk_count = 0;
|
|
|
|
void chunk_cb(struct http_request_s* request) {
|
|
chunk_count++;
|
|
struct http_response_s* response = http_response_init();
|
|
http_response_body(response, RESPONSE, sizeof(RESPONSE) - 1);
|
|
if (chunk_count < 3) {
|
|
http_respond_chunk(request, response, chunk_cb);
|
|
} else {
|
|
http_response_header(response, "Foo-Header", "bar");
|
|
http_respond_chunk_end(request, response);
|
|
}
|
|
}
|
|
|
|
typedef struct {
|
|
char* buf;
|
|
struct http_response_s* response;
|
|
int index;
|
|
} chunk_buf_t;
|
|
|
|
void chunk_req_cb(struct http_request_s* request) {
|
|
http_string_t str = http_request_chunk(request);
|
|
chunk_buf_t* chunk_buffer = (chunk_buf_t*)http_request_userdata(request);
|
|
if (str.len > 0) {
|
|
memcpy(chunk_buffer->buf + chunk_buffer->index, str.buf, str.len);
|
|
chunk_buffer->index += str.len;
|
|
http_request_read_chunk(request, chunk_req_cb);
|
|
} else {
|
|
http_response_body(chunk_buffer->response, chunk_buffer->buf, chunk_buffer->index);
|
|
http_respond(request, chunk_buffer->response);
|
|
free(chunk_buffer->buf);
|
|
free(chunk_buffer);
|
|
}
|
|
}
|
|
|
|
struct http_server_s* poll_server;
|
|
|
|
void handle_request(struct http_request_s* request) {
|
|
chunk_count = 0;
|
|
http_request_connection(request, HTTP_AUTOMATIC);
|
|
struct http_response_s* response = http_response_init();
|
|
http_response_status(response, 200);
|
|
if (request_target_is(request, "/echo")) {
|
|
http_string_t body = http_request_body(request);
|
|
http_response_header(response, "Content-Type", "text/plain");
|
|
http_response_body(response, body.buf, body.len);
|
|
} else if (request_target_is(request, "/host")) {
|
|
http_string_t ua = http_request_header(request, "Host");
|
|
http_response_header(response, "Content-Type", "text/plain");
|
|
http_response_body(response, ua.buf, ua.len);
|
|
} else if (request_target_is(request, "/poll")) {
|
|
while (http_server_poll(poll_server) > 0);
|
|
http_response_header(response, "Content-Type", "text/plain");
|
|
http_response_body(response, RESPONSE, sizeof(RESPONSE) - 1);
|
|
} else if (request_target_is(request, "/empty")) {
|
|
// No Body
|
|
} else if (request_target_is(request, "/chunked")) {
|
|
http_response_header(response, "Content-Type", "text/plain");
|
|
http_response_body(response, RESPONSE, sizeof(RESPONSE) - 1);
|
|
http_respond_chunk(request, response, chunk_cb);
|
|
return;
|
|
} else if (request_target_is(request, "/chunked-req")) {
|
|
chunk_buf_t* chunk_buffer = (chunk_buf_t*)calloc(1, sizeof(chunk_buf_t));
|
|
chunk_buffer->buf = (char*)malloc(512 * 1024);
|
|
chunk_buffer->response = response;
|
|
http_request_set_userdata(request, chunk_buffer);
|
|
http_request_read_chunk(request, chunk_req_cb);
|
|
return;
|
|
} else if (request_target_is(request, "/large")) {
|
|
chunk_buf_t* chunk_buffer = (chunk_buf_t*)calloc(1, sizeof(chunk_buf_t));
|
|
chunk_buffer->buf = (char*)malloc(25165824);
|
|
chunk_buffer->response = response;
|
|
http_request_set_userdata(request, chunk_buffer);
|
|
http_request_read_chunk(request, chunk_req_cb);
|
|
return;
|
|
} else if (request_target_is(request, "/headers")) {
|
|
int iter = 0, i = 0;
|
|
http_string_t key, val;
|
|
char buf[512];
|
|
while (http_request_iterate_headers(request, &key, &val, &iter)) {
|
|
i += snprintf(buf + i, 512 - i, "%.*s: %.*s\n", key.len, key.buf, val.len, val.buf);
|
|
}
|
|
http_response_header(response, "Content-Type", "text/plain");
|
|
http_response_body(response, buf, i);
|
|
return http_respond(request, response);
|
|
} else {
|
|
http_response_header(response, "Content-Type", "text/plain");
|
|
http_response_body(response, RESPONSE, sizeof(RESPONSE) - 1);
|
|
}
|
|
http_respond(request, response);
|
|
}
|
|
|
|
struct http_server_s* server;
|
|
|
|
void handle_sigterm(int signum) {
|
|
(void)signum;
|
|
free(server);
|
|
free(poll_server);
|
|
exit(0);
|
|
}
|
|
|
|
int main() {
|
|
signal(SIGTERM, handle_sigterm);
|
|
server = http_server_init(8080, handle_request);
|
|
poll_server = http_server_init(8081, handle_request);
|
|
http_server_listen_poll(poll_server);
|
|
http_server_listen(server);
|
|
}
|