diff --git a/examples/Http3Server.cpp b/examples/Http3Server.cpp index fc424de..8a1ecec 100644 --- a/examples/Http3Server.cpp +++ b/examples/Http3Server.cpp @@ -10,7 +10,10 @@ int main() { .key_file_name = "../misc/key.pem", .cert_file_name = "../misc/cert.pem", .passphrase = "1234" - }).get("/*", [](auto *res, auto */*req*/) { + }).get("/*", [](auto *res, auto *req) { + + std::cout << req->getHeader(":path") << std::endl; + res->end("Hello quic!"); }).listen(3000, [](auto *listen_socket) { if (listen_socket) { diff --git a/src/Http3Context.h b/src/Http3Context.h index 1137cb1..db572f8 100644 --- a/src/Http3Context.h +++ b/src/Http3Context.h @@ -3,52 +3,44 @@ extern "C" { #include "quic.h" } +#include "Http3ContextData.h" +#include "Http3ResponseData.h" /* Let's just have this one here for now */ us_quic_socket_context_t *context; -void print_current_headers() { - /* Iterate the headers and print them */ - for (int i = 0, more = 1; more; i++) { - char *name, *value; - int name_length, value_length; - if (more = us_quic_socket_context_get_header(context, i, &name, &name_length, &value, &value_length)) { - printf("header %.*s = %.*s\n", name_length, name, value_length, value); - } - } -} - /* This would be a request */ void on_stream_headers(us_quic_stream_t *s) { - printf("==== HTTP/3 request ====\n"); + Http3ContextData *contextData = (Http3ContextData *) us_quic_socket_context_ext(us_quic_socket_context(us_quic_stream_socket(s))); - print_current_headers(); + contextData->router.route(); - /* Write headers */ - us_quic_socket_context_set_header(context, 0, ":status", 7, "200", 3); - //us_quic_socket_context_set_header(context, 1, "content-length", 14, "11", 2); - //us_quic_socket_context_set_header(context, 2, "content-type", 12, "text/html", 9); - us_quic_socket_context_send_headers(context, s, 1, 1); - /* Write body and shutdown (unknown if content-length must be present?) */ - us_quic_stream_write(s, "Hello quic!", 11); - - /* Every request has its own stream, so we conceptually serve requests like in HTTP 1.0 */ - us_quic_stream_shutdown(s); } /* And this would be the body of the request */ void on_stream_data(us_quic_stream_t *s, char *data, int length) { + + // Http3ResponseData *responseData = us_quic_stream_ext(s); + // responseData->onData(data, length); + printf("Body length is: %d\n", length); } void on_stream_writable(us_quic_stream_t *s) { - + // Http3ResponseData *responseData = us_quic_stream_ext(s); + // responseData->onWritable(); } void on_stream_close(us_quic_stream_t *s) { - printf("Stream closed\n"); + + // Http3ResponseData *responseData = us_quic_stream_ext(s); + // responseData->onAborted(); + + //printf("Stream closed\n"); + + // inplace destruct Http3ResponseData here } /* On new connection */ @@ -58,7 +50,9 @@ void on_open(us_quic_socket_t *s, int is_client) { /* On new stream */ void on_stream_open(us_quic_stream_t *s, int is_client) { - printf("Stream opened!\n"); + //printf("Stream opened!\n"); + + // inplace initialize Http3ResponseData here } void on_close(us_quic_socket_t *s) { @@ -73,7 +67,7 @@ namespace uWS { printf("Creating context now\n"); /* Create quic socket context (assumes h3 for now) */ - context = us_create_quic_socket_context(loop, options); + context = us_create_quic_socket_context(loop, options); // sizeof(Http3ContextData) /* Specify application callbacks */ us_quic_socket_context_on_stream_data(context, on_stream_data); @@ -85,7 +79,7 @@ namespace uWS { us_quic_socket_context_on_close(context, on_close); /* The listening socket is the actual UDP socket used */ - us_quic_listen_socket_t *listen_socket = us_quic_socket_context_listen(context, "::1", 9004); + us_quic_listen_socket_t *listen_socket = us_quic_socket_context_listen(context, "::1", 9004); // sizeof(Http3ResponseData) return nullptr; diff --git a/src/Http3ContextData.h b/src/Http3ContextData.h index e69de29..20ad5f0 100644 --- a/src/Http3ContextData.h +++ b/src/Http3ContextData.h @@ -0,0 +1,9 @@ +#include "HttpRouter.h" + +namespace uWS { + + struct Http3ContextData { + HttpRouter router; + }; + +} \ No newline at end of file diff --git a/src/Http3Request.h b/src/Http3Request.h index 9139931..299d888 100644 --- a/src/Http3Request.h +++ b/src/Http3Request.h @@ -1,6 +1,22 @@ +extern "C" { +#include "quic.h" +} + namespace uWS { struct Http3Request { - // really the same thing as HttpRequest with same rules + + std::string_view getHeader(std::string_view key) { + for (int i = 0, more = 1; more; i++) { + char *name, *value; + int name_length, value_length; + if (more = us_quic_socket_context_get_header(nullptr, i, &name, &name_length, &value, &value_length)) { + if (name_length == key.length() && !memcmp(name, key.data(), key.length())) { + return {value, value_length}; + } + } + return {nullptr, 0}; + } + } }; } \ No newline at end of file diff --git a/src/Http3Response.h b/src/Http3Response.h index 50f9463..50422cb 100644 --- a/src/Http3Response.h +++ b/src/Http3Response.h @@ -1,10 +1,29 @@ namespace uWS { + /* Is a quic stream */ struct Http3Response { - // has a quic stream + + void writeStatus() { + + } void end(std::string_view data) { - + + // Http3ResponseData *responseData = us_quic_stream_ext(this); + + // if not already written status then write status + + /* Write headers */ + us_quic_socket_context_set_header(context, 0, ":status", 7, "200", 3); + //us_quic_socket_context_set_header(context, 1, "content-length", 14, "11", 2); + //us_quic_socket_context_set_header(context, 2, "content-type", 12, "text/html", 9); + us_quic_socket_context_send_headers(context, this, 1, 1); + + /* Write body and shutdown (unknown if content-length must be present?) */ + us_quic_stream_write(this, "Hello quic!", 11); + + /* Every request has its own stream, so we conceptually serve requests like in HTTP 1.0 */ + us_quic_stream_shutdown(this); } }; diff --git a/src/Http3ResponseData.h b/src/Http3ResponseData.h new file mode 100644 index 0000000..e69de29