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)
// much speaks for a header-only or header-mostly implementation now that uSockets is properly isolating its internal headers
#include "uWS.h"
#include "App.h"
#include "HttpRouter.h"
std::string buffer;
//#define USE_SSL
int main() {
std::cout << "HttpSocket size: " << sizeof(HttpSocket<true>::Data) << std::endl;
char *buffer = new char[512];
buffer = "Why hello there!";
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")
.certFileName("/home/alexhultman/uWebSockets/misc/ssl/cert.pem")
.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) {
std::cout << "Wrong way!" << std::endl;
}).onWebSocket([]() {
}).onWebSocket("/wsApi", []() {
}).listen("localhost", 3000, 0);
uWS::run();
// loop.run();
}
+1 -1
View File
@@ -125,7 +125,7 @@ public:
}
// for client and server
AppBase &onWebSocket(std::function<void()> handler) {
AppBase &onWebSocket(std::string pattern, std::function<void()> handler) {
return *this;
}
+54 -28
View File
@@ -2,6 +2,7 @@
#define HTTP_H
#include "libusockets.h"
#include "Loop.h"
#include <functional>
#include <cstring>
@@ -88,50 +89,75 @@ struct HttpSocket {
std::function<std::pair<const char *, int>(int)> outStream;
};
// cork is stored in hub
char *getCorkBuffer() {
// context -> hub -> cork buffer
// only this one should be used!
void writeToCorkBuffer(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)));
us_socket *s = (us_socket *) this;
// get the loop from the context!
//return us_socket_context_loop(us_socket_get_context(s));
return corkBuffer;
memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
loopData->corkOffset += length;
}
HttpSocket *writeStatus(int status) {
char *corkBuffer = getCorkBuffer();
// sprintf is super slow, this one is a lot faster
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);
corkOffset += sizeof(largeBuf) - 1;
do {
*dst++ = *--p;
} while (p != temp);
return this;
return ret;
}
HttpSocket *writeHeader(char *key, char *value) {
return this;
}
// never rely on this one!
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!
void end(char *data, int length) {
//us_ssl_socket *s = (us_ssl_socket *) this;
memcpy(loopData->corkBuffer + loopData->corkOffset, "Content-Length: ", 16);
loopData->corkOffset += 16;
char *corkBuffer = getCorkBuffer();
memcpy(corkBuffer + corkOffset, data, length);
corkOffset += length;
loopData->corkOffset += u32toa_naive(length, loopData->corkBuffer + loopData->corkOffset);
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) {
us_ssl_socket_write((us_ssl_socket *) this, corkBuffer, corkOffset);
us_ssl_socket_write((us_ssl_socket *) this, loopData->corkBuffer, loopData->corkOffset);
} 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!
+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
#define HUB_H
@@ -16,8 +12,11 @@ struct Loop {
us_loop *loop;
struct Data {
Data() {
char *corkBuffer = new char[1024];
int corkOffset = 0;
Data() {
}
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef UWS_H
#define UWS_H
#include "Loop.h"
#include "App.h"
#endif // UWS_H