Actually put headers, content-length and status in response

This commit is contained in:
Alex Hultman
2018-06-24 01:27:40 +02:00
parent a2fe871e63
commit 0cbccaf08e
5 changed files with 77 additions and 50 deletions
+17 -15
View File
@@ -1,31 +1,33 @@
// this is roughly the interfaces I plan for (with changes and additional helpers added with time) #include "uWS.h"
// much speaks for a header-only or header-mostly implementation now that uSockets is properly isolating its internal headers
#include "App.h" std::string buffer;
#include "HttpRouter.h"
//#define USE_SSL
int main() { int main() {
std::cout << "HttpSocket size: " << sizeof(HttpSocket<true>::Data) << std::endl; buffer = "Why hello there!";
char *buffer = new char[512];
uWS::SSLApp c(uWS::SSLOptions() //uWS::init();
//uWS::Loop loop();
#ifdef USE_SSL
uWS::SSLApp app(uWS::SSLOptions()
.keyFileName("/home/alexhultman/uWebSockets/misc/ssl/key.pem") .keyFileName("/home/alexhultman/uWebSockets/misc/ssl/key.pem")
.certFileName("/home/alexhultman/uWebSockets/misc/ssl/cert.pem") .certFileName("/home/alexhultman/uWebSockets/misc/ssl/cert.pem")
.passphrase("1234")); .passphrase("1234"));
//uWS::App c; #else
uWS::App app;
#endif
c.onGet("/", [buffer](auto *s, HttpRequest *req, auto *args) { app.onGet("/", [](auto *s, auto *req, auto *args) {
s->writeStatus(200)->writeHeader("Hello", "World")->end(buffer, 512); s->writeStatus("200 OK")->writeHeader("Hello", "World")->end(buffer);
}).onGet("/wrong", [buffer](auto *s, HttpRequest *req, auto *args) { }).onWebSocket("/wsApi", []() {
std::cout << "Wrong way!" << std::endl;
}).onWebSocket([]() {
}).listen("localhost", 3000, 0); }).listen("localhost", 3000, 0);
uWS::run(); uWS::run();
// loop.run();
} }
+1 -1
View File
@@ -125,7 +125,7 @@ public:
} }
// for client and server // for client and server
AppBase &onWebSocket(std::function<void()> handler) { AppBase &onWebSocket(std::string pattern, std::function<void()> handler) {
return *this; return *this;
} }
+54 -28
View File
@@ -2,6 +2,7 @@
#define HTTP_H #define HTTP_H
#include "libusockets.h" #include "libusockets.h"
#include "Loop.h"
#include <functional> #include <functional>
#include <cstring> #include <cstring>
@@ -88,50 +89,75 @@ struct HttpSocket {
std::function<std::pair<const char *, int>(int)> outStream; std::function<std::pair<const char *, int>(int)> outStream;
}; };
// cork is stored in hub // only this one should be used!
char *getCorkBuffer() { void writeToCorkBuffer(const char *src, int length) {
// context -> hub -> cork buffer uWS::Loop::Data *loopData = (uWS::Loop::Data *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
us_socket *s = (us_socket *) this; memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
loopData->corkOffset += length;
// get the loop from the context!
//return us_socket_context_loop(us_socket_get_context(s));
return corkBuffer;
} }
HttpSocket *writeStatus(int status) { // sprintf is super slow, this one is a lot faster
char *corkBuffer = getCorkBuffer(); int u32toa_naive(uint32_t value, char *dst) {
char temp[10];
char *p = temp;
do {
*p++ = char(value % 10) + '0';
value /= 10;
} while (value > 0);
char largeBuf[] = "HTTP/1.1 200 OK\r\nContent-Length: 512\r\n\r\n"; int ret = p - temp;
memcpy(corkBuffer + corkOffset, largeBuf, sizeof(largeBuf) - 1); do {
corkOffset += sizeof(largeBuf) - 1; *dst++ = *--p;
} while (p != temp);
return this; return ret;
} }
HttpSocket *writeHeader(char *key, char *value) { // never rely on this one!
return this; void writeToCorkBufferAndReset(const char *src, int length) {
} uWS::Loop::Data *loopData = (uWS::Loop::Data *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
// this depends on SSL! memcpy(loopData->corkBuffer + loopData->corkOffset, "Content-Length: ", 16);
void end(char *data, int length) { loopData->corkOffset += 16;
//us_ssl_socket *s = (us_ssl_socket *) this;
char *corkBuffer = getCorkBuffer(); loopData->corkOffset += u32toa_naive(length, loopData->corkBuffer + loopData->corkOffset);
memcpy(corkBuffer + corkOffset, data, length);
corkOffset += length;
memcpy(loopData->corkBuffer + loopData->corkOffset, "\r\n\r\n", 4);
loopData->corkOffset += 4;
memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
loopData->corkOffset += length;
if constexpr(SSL) { if constexpr(SSL) {
us_ssl_socket_write((us_ssl_socket *) this, corkBuffer, corkOffset); us_ssl_socket_write((us_ssl_socket *) this, loopData->corkBuffer, loopData->corkOffset);
} else { } else {
us_socket_write((us_socket *) this, corkBuffer, corkOffset, 0); us_socket_write((us_socket *) this, loopData->corkBuffer, loopData->corkOffset, 0);
} }
corkOffset = 0; loopData->corkOffset = 0;
}
HttpSocket *writeStatus(std::string_view status) {
writeToCorkBuffer("HTTP/1.1 ", 9);
writeToCorkBuffer(status.data(), status.length());
writeToCorkBuffer("\r\n", 2);
return this;
}
HttpSocket *writeHeader(std::string_view key, std::string_view value) {
writeToCorkBuffer(key.data(), key.length());
writeToCorkBuffer(": ", 2);
writeToCorkBuffer(value.data(), value.length());
writeToCorkBuffer("\r\n", 2);
return this;
}
void end(std::string_view data) {
// end should not explicitly flush the cork buffer! delay to when done with all http data!
writeToCorkBufferAndReset(data.data(), data.length());
} }
// can't create this! // can't create this!
+4 -5
View File
@@ -1,7 +1,3 @@
// should lie in hub and be connected with pre/post callbacks
char *corkBuffer = new char[1024];
int corkOffset = 0;
#ifndef HUB_H #ifndef HUB_H
#define HUB_H #define HUB_H
@@ -16,8 +12,11 @@ struct Loop {
us_loop *loop; us_loop *loop;
struct Data { struct Data {
Data() {
char *corkBuffer = new char[1024];
int corkOffset = 0;
Data() {
} }
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef UWS_H #ifndef UWS_H
#define UWS_H #define UWS_H
#include "Loop.h" #include "App.h"
#endif // UWS_H #endif // UWS_H