|
9 | 9 | /* Todo: use onWritable and tryEnd instead of end */ |
10 | 10 | int main() { |
11 | 11 |
|
12 | | - /* Read video file to memory */ |
13 | | - std::ifstream file("video.mp4", std::ios::binary | std::ios::ate); |
14 | | - std::streamsize size = file.tellg(); |
15 | | - file.seekg(0, std::ios::beg); |
| 12 | + /* Read video file to memory */ |
| 13 | + std::ifstream file("video.mp4", std::ios::binary | std::ios::ate); |
| 14 | + std::streamsize size = file.tellg(); |
| 15 | + file.seekg(0, std::ios::beg); |
16 | 16 |
|
17 | | - std::vector<char> buffer(size); |
18 | | - if (!file.read(buffer.data(), size)) { |
19 | | - std::cout << "Failed to load video.mp4" << std::endl; |
20 | | - return 0; |
21 | | - } |
| 17 | + std::vector<char> buffer(size); |
| 18 | + if (!file.read(buffer.data(), size)) { |
| 19 | + std::cout << "Failed to load video.mp4" << std::endl; |
| 20 | + return 0; |
| 21 | + } |
22 | 22 |
|
23 | | - /* We need a bootstrapping server that instructs |
24 | | - * the web browser to use HTTP3 */ |
25 | | - (*new uWS::SSLApp({ |
26 | | - .key_file_name = "misc/key.pem", |
27 | | - .cert_file_name = "misc/cert.pem", |
28 | | - .passphrase = "1234" |
29 | | - })).get("/*", [&buffer](auto *res, auto *req) { |
30 | | - res->writeHeader("Alt-Svc", "h3=\":9004\""); |
31 | | - res->writeHeader("Alternative-Protocol", "quic:9004"); |
32 | | - res->end("<html><h1>This is not HTTP3! Try refreshing (works in Firefox!)</h1></html>"); |
33 | | - }).listen(9004, [](auto *listen_socket) { |
34 | | - if (listen_socket) { |
35 | | - std::cout << "Bootstrapping server Listening on port " << 9004 << std::endl; |
36 | | - } |
37 | | - }); |
| 23 | + /* We need a bootstrapping server that instructs |
| 24 | + * the web browser to use HTTP3 */ |
| 25 | + (*new uWS::SSLApp({ |
| 26 | + .key_file_name = "misc/key.pem", |
| 27 | + .cert_file_name = "misc/cert.pem", |
| 28 | + .passphrase = "1234" |
| 29 | + })).get("/*", [&buffer](auto *res, auto *req) { |
| 30 | + res->writeHeader("Alt-Svc", "h3=\":9004\""); |
| 31 | + res->writeHeader("Alternative-Protocol", "quic:9004"); |
| 32 | + res->end("<html><h1>This is not HTTP3! Try refreshing (works in Firefox!)</h1></html>"); |
| 33 | + }).listen(9004, [](auto *listen_socket) { |
| 34 | + if (listen_socket) { |
| 35 | + std::cout << "Bootstrapping server Listening on port " << 9004 << std::endl; |
| 36 | + } |
| 37 | + }); |
38 | 38 |
|
39 | | - /* And we serve the video over HTTP3 */ |
40 | | - uWS::H3App({ |
41 | | - .key_file_name = "misc/key.pem", |
42 | | - .cert_file_name = "misc/cert.pem", |
43 | | - .passphrase = "1234" |
44 | | - }).get("/*", [&buffer](auto *res, auto *req) { |
45 | | - res->end("<html><h1>Welcome to HTTP3! <a href=\"video.mp4\">Go see a movie</a></html></h1>"); |
46 | | - }).get("/video.mp4", [&buffer](auto *res, auto *req) { |
47 | | - /* Send back a video */ |
48 | | - res->end({&buffer[0], buffer.size()}); |
49 | | - }).post("/*", [](auto *res, auto *req) { |
| 39 | + /* And we serve the video over HTTP3 */ |
| 40 | + uWS::H3App({ |
| 41 | + .key_file_name = "misc/key.pem", |
| 42 | + .cert_file_name = "misc/cert.pem", |
| 43 | + .passphrase = "1234" |
| 44 | + }).get("/*", [&buffer](auto *res, auto *req) { |
| 45 | + res->end("<html><h1>Welcome to HTTP3! <a href=\"video.mp4\">Go see a movie</a></html></h1>"); |
| 46 | + }).get("/video.mp4", [&buffer](auto *res, auto *req) { |
| 47 | + /* Send back a video */ |
| 48 | + res->end({&buffer[0], buffer.size()}); |
| 49 | + }).post("/*", [](auto *res, auto *req) { |
50 | 50 |
|
51 | | - std::cout << "Got POST request at " << req->getHeader(":path") << std::endl; |
| 51 | + std::cout << "Got POST request at " << req->getHeader(":path") << std::endl; |
52 | 52 |
|
53 | | - /* You also need to set onAborted if receiving data */ |
54 | | - res->onData([res, bodyBuffer = (std::string *)nullptr](std::string_view chunk, bool isLast) mutable { |
55 | | - if (isLast) { |
56 | | - std::cout << "Sending back posted body now" << std::endl; |
57 | | - if (bodyBuffer) { |
58 | | - /* Send back the (chunked) body we got, as response */ |
59 | | - bodyBuffer->append(chunk); |
60 | | - res->end(*bodyBuffer); |
61 | | - delete bodyBuffer; |
62 | | - } else { |
63 | | - /* Send back the body we got, as response (fast path) */ |
64 | | - res->end(chunk); |
65 | | - } |
66 | | - } else { |
67 | | - /* Slow path */ |
68 | | - if (!bodyBuffer) { |
69 | | - bodyBuffer = new std::string; |
70 | | - } |
71 | | - /* If we got the body in a chunk, buffer it up until whole */ |
72 | | - bodyBuffer->append(chunk); |
73 | | - } |
| 53 | + /* You also need to set onAborted if receiving data */ |
| 54 | + res->onData([res, bodyBuffer = (std::string *)nullptr](std::string_view chunk, bool isLast) mutable { |
| 55 | + if (isLast) { |
| 56 | + std::cout << "Sending back posted body now" << std::endl; |
| 57 | + if (bodyBuffer) { |
| 58 | + /* Send back the (chunked) body we got, as response */ |
| 59 | + bodyBuffer->append(chunk); |
| 60 | + res->end(*bodyBuffer); |
| 61 | + delete bodyBuffer; |
| 62 | + } else { |
| 63 | + /* Send back the body we got, as response (fast path) */ |
| 64 | + res->end(chunk); |
| 65 | + } |
| 66 | + } else { |
| 67 | + /* Slow path */ |
| 68 | + if (!bodyBuffer) { |
| 69 | + bodyBuffer = new std::string; |
| 70 | + } |
| 71 | + /* If we got the body in a chunk, buffer it up until whole */ |
| 72 | + bodyBuffer->append(chunk); |
| 73 | + } |
74 | 74 |
|
75 | | - }); |
| 75 | + }); |
76 | 76 |
|
77 | | - /* If you have pending, asynch work, you should abort such work in this callback */ |
78 | | - res->onAborted([]() { |
79 | | - /* Again, just printing is not enough, you need to abort any pending work here |
80 | | - * so that nothing will call res->end, since the request was aborted and deleted */ |
81 | | - printf("Stream was aborted!\n"); |
82 | | - }); |
83 | | - }).listen(9004, [](auto *listen_socket) { |
84 | | - if (listen_socket) { |
85 | | - std::cout << "HTTP/3 server Listening on port " << 9004 << std::endl; |
86 | | - } |
87 | | - }).run(); |
| 77 | + /* If you have pending, asynch work, you should abort such work in this callback */ |
| 78 | + res->onAborted([]() { |
| 79 | + /* Again, just printing is not enough, you need to abort any pending work here |
| 80 | + * so that nothing will call res->end, since the request was aborted and deleted */ |
| 81 | + printf("Stream was aborted!\n"); |
| 82 | + }); |
| 83 | + }).listen(9004, [](auto *listen_socket) { |
| 84 | + if (listen_socket) { |
| 85 | + std::cout << "HTTP/3 server Listening on port " << 9004 << std::endl; |
| 86 | + } |
| 87 | + }).run(); |
88 | 88 |
|
89 | | - std::cout << "Failed to listen on port 9004" << std::endl; |
| 89 | + std::cout << "Failed to listen on port 9004" << std::endl; |
90 | 90 | } |
91 | 91 |
|
92 | 92 | #else |
|
0 commit comments