hunting/external/httpserver.h-master/test/functional/main.c
2024-06-15 08:30:24 +08:00

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);
}