Http3 POST/GET example working
This commit is contained in:
@@ -4,19 +4,52 @@
|
|||||||
#include "Http3App.h"
|
#include "Http3App.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
/* Tentative example of simple Http3 server */
|
/* Example of simple Http3 server handling both GET with headers and POST with body.
|
||||||
|
* You might be surprised to find out you can replace uWS::H3App with uWS::SSLApp and
|
||||||
|
* serve TCP/TLS-based HTTP instead of QUIC-based HTTP, using the same very code ;) */
|
||||||
int main() {
|
int main() {
|
||||||
uWS::H3App({
|
uWS::SSLApp({
|
||||||
.key_file_name = "misc/key.pem",
|
.key_file_name = "misc/key.pem",
|
||||||
.cert_file_name = "misc/cert.pem",
|
.cert_file_name = "misc/cert.pem",
|
||||||
.passphrase = "1234"
|
.passphrase = "1234"
|
||||||
}).get("/*", [](auto *res, auto *req) {
|
}).get("/*", [](auto *res, auto *req) {
|
||||||
|
|
||||||
/* Printing these should obviously be disabled if doing benchmarking */
|
/* Printing these should obviously be disabled if doing benchmarking */
|
||||||
//std::cout << req->getHeader(":path") << std::endl;
|
std::cout << req->getHeader(":path") << std::endl;
|
||||||
//std::cout << req->getHeader(":method") << std::endl;
|
std::cout << req->getHeader(":method") << std::endl;
|
||||||
|
|
||||||
res->end("Hello H3 from uWS!");
|
res->end("Hello H3 from uWS!");
|
||||||
|
}).post("/*", [](auto *res, auto */*req*/) {
|
||||||
|
|
||||||
|
/* You also need to set onAborted if receiving data */
|
||||||
|
res->onData([res, bodyBuffer = (std::string *)nullptr](std::string_view chunk, bool isLast) mutable {
|
||||||
|
if (isLast) {
|
||||||
|
if (bodyBuffer) {
|
||||||
|
/* Send back the (chunked) body we got, as response */
|
||||||
|
bodyBuffer->append(chunk);
|
||||||
|
res->end(*bodyBuffer);
|
||||||
|
delete bodyBuffer;
|
||||||
|
} else {
|
||||||
|
/* Send back the body we got, as response (fast path) */
|
||||||
|
res->end(chunk);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Slow path */
|
||||||
|
if (!bodyBuffer) {
|
||||||
|
bodyBuffer = new std::string;
|
||||||
|
}
|
||||||
|
/* If we got the body in a chunk, buffer it up until whole */
|
||||||
|
bodyBuffer->append(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/* If you have pending, asynch work, you should abort such work in this callback */
|
||||||
|
res->onAborted([]() {
|
||||||
|
/* Again, just printing is not enough, you need to abort any pending work here
|
||||||
|
* so that nothing will call res->end, since the request was aborted and deleted */
|
||||||
|
printf("Stream was aborted!\n");
|
||||||
|
});
|
||||||
}).listen(9004, [](auto *listen_socket) {
|
}).listen(9004, [](auto *listen_socket) {
|
||||||
if (listen_socket) {
|
if (listen_socket) {
|
||||||
std::cout << "Listening on port " << 9004 << std::endl;
|
std::cout << "Listening on port " << 9004 << std::endl;
|
||||||
|
|||||||
+7
-3
@@ -19,10 +19,14 @@ namespace uWS {
|
|||||||
/* Specify application callbacks */
|
/* Specify application callbacks */
|
||||||
us_quic_socket_context_on_stream_data(context, [](us_quic_stream_t *s, char *data, int length) {
|
us_quic_socket_context_on_stream_data(context, [](us_quic_stream_t *s, char *data, int length) {
|
||||||
|
|
||||||
// Http3ResponseData *responseData = us_quic_stream_ext(s);
|
// we don't have a way to know EOF?
|
||||||
// responseData->onData(data, length);
|
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext(s);
|
||||||
|
|
||||||
printf("Body length is: %d\n", length);
|
if (responseData) {
|
||||||
|
responseData->onData({data, length}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("Body length is: %d\n", length);
|
||||||
});
|
});
|
||||||
us_quic_socket_context_on_stream_open(context, [](us_quic_stream_t *s, int is_client) {
|
us_quic_socket_context_on_stream_open(context, [](us_quic_stream_t *s, int is_client) {
|
||||||
//printf("Stream opened!\n");
|
//printf("Stream opened!\n");
|
||||||
|
|||||||
+18
-2
@@ -29,8 +29,8 @@ namespace uWS {
|
|||||||
|
|
||||||
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext((us_quic_stream_t *) this);
|
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext((us_quic_stream_t *) this);
|
||||||
|
|
||||||
printf("Wrapper responseData is %p\n", responseData);
|
//printf("Wrapper responseData is %p\n", responseData);
|
||||||
printf("%s\n", responseData);
|
//printf("%s\n", responseData);
|
||||||
|
|
||||||
// if not already written status then write status
|
// if not already written status then write status
|
||||||
|
|
||||||
@@ -46,6 +46,22 @@ namespace uWS {
|
|||||||
/* Every request has its own stream, so we conceptually serve requests like in HTTP 1.0 */
|
/* Every request has its own stream, so we conceptually serve requests like in HTTP 1.0 */
|
||||||
us_quic_stream_shutdown((us_quic_stream_t *) this);
|
us_quic_stream_shutdown((us_quic_stream_t *) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Attach handler for aborted HTTP request */
|
||||||
|
Http3Response *onAborted(MoveOnlyFunction<void()> &&handler) {
|
||||||
|
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext((us_quic_stream_t *) this);
|
||||||
|
|
||||||
|
responseData->onAborted = std::move(handler);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach a read handler for data sent. Will be called with FIN set true if last segment. */
|
||||||
|
void onData(MoveOnlyFunction<void(std::string_view, bool)> &&handler) {
|
||||||
|
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext((us_quic_stream_t *) this);
|
||||||
|
|
||||||
|
responseData->onData = std::move(handler);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
#ifndef UWS_H3RESPONSEDATA_H
|
#ifndef UWS_H3RESPONSEDATA_H
|
||||||
#define UWS_H3RESPONSEDATA_H
|
#define UWS_H3RESPONSEDATA_H
|
||||||
|
|
||||||
|
#include "MoveOnlyFunction.h"
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace uWS {
|
namespace uWS {
|
||||||
struct Http3ResponseData {
|
struct Http3ResponseData {
|
||||||
|
|
||||||
|
MoveOnlyFunction<void()> onAborted;
|
||||||
// will need onWritable
|
MoveOnlyFunction<void(std::string_view, bool)> onData;
|
||||||
// onData
|
|
||||||
|
|
||||||
// hasWrittenStatus
|
// hasWrittenStatus
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user