Introduce HttpSocket::stream, make it benchmarkable

This commit is contained in:
Alex Hultman
2018-05-06 22:03:28 +02:00
parent 9cf5042a57
commit 10ce6df701
6 changed files with 101 additions and 33 deletions
+2 -2
View File
@@ -18,5 +18,5 @@ HEADERS += \
src/Http.h
INCLUDEPATH += uSockets/src src
QMAKE_CXXFLAGS += -fsanitize=address
LIBS += -lasan
#QMAKE_CXXFLAGS += -fsanitize=address
#LIBS += -lasan
+30 -6
View File
@@ -1,21 +1,45 @@
// uWS.h
#include "Hub.h"
#include <iostream>
#include <string.h>
//char largeBuf[] = "HTTP/1.1 200 OK\r\nContent-Length: 512\r\n\r\n";
//int largeHttpBufSize = sizeof(largeBuf) + 512 - 1;
char largeBuf[] = "HTTP/1.1 200 OK\r\nContent-Length: 52428800\r\n\r\n";
int largeHttpBufSize = sizeof(largeBuf) + 52428800 - 1;
char *largeHttpBuf;
int main() {
std::cout << "HttpSocket size: " << sizeof(HttpSocket) << std::endl;
largeHttpBuf = (char *) malloc(largeHttpBufSize);
memcpy(largeHttpBuf, largeBuf, sizeof(largeBuf) - 1);
Hub h;
h.onHttpConnection([](HttpSocket *s) {
//std::cout << "HTTP connection" << std::endl;
});
// req = ?, res = HttpSocket
h.onHttpRequest([](auto req, auto res, char *data, unsigned int length) {
h.onHttpRequest([](HttpSocket *s, auto req, char *data, unsigned int length) {
std::cout << "Got data: " << std::string(data, length) << std::endl;
//std::cout << "Got data: " << std::string(data, length) << std::endl;
// res.writeStatus();
// res.writeHeader();
// res.write();
// s->writeStatus();
// s->writeHeader();
res->write();
// if url == / then stream index.htm
s->stream(largeHttpBufSize, [](int offset) {
return std::make_pair(largeHttpBuf + offset, largeHttpBufSize - offset);
});
});
h.onHttpDisconnection([](HttpSocket *s) {
//std::cout << "HTTP disconnection" << std::endl;
});
h.listen(nullptr, 3000, 0);
+39 -14
View File
@@ -4,30 +4,55 @@
#include <iostream>
void HttpContext::httpBegin(us_socket *s) {
// yep
std::cout << "Accepted a connection" << std::endl;
Hub::Data *hubData = (Hub::Data *) us_loop_userdata(s->context->loop);
//std::cout << "BeginHTTP: " << s << std::endl;
// should not touch the socket?
new (s) HttpSocket();
// tester
((HttpSocket *) s)->outStream = nullptr;
hubData->onHttpConnection((HttpSocket *) s);
}
void HttpContext::httpEnd(us_socket *s) {
Hub::Data *hubData = (Hub::Data *) us_loop_userdata(s->context->loop);
hubData->onHttpDisconnection((HttpSocket *) s);
}
void HttpContext::httpData(us_socket *s, void *data, int size) {
Hub::Data *hubData = (Hub::Data *) us_loop_userdata(s->context->loop);
hubData->onHttpRequest(nullptr, nullptr, (char *) data, size);
hubData->onHttpRequest((HttpSocket *) s, nullptr, (char *) data, size);
}
void HttpContext::httpEnd(us_socket *s) {
// yep
std::cout << "Disconnection of a connection" << std::endl;
void HttpContext::httpOut(us_socket *s) {
HttpSocket *httpSocket = (HttpSocket *) s;
std::pair<const char *, int> chunk = httpSocket->outStream(httpSocket->offset);
httpSocket->offset += us_socket_write(s, chunk.first, chunk.second);
}
HttpContext::HttpContext(us_loop *loop) {
context = us_create_socket_context(loop, sizeof(us_socket_context));
context->on_accepted = httpBegin;
context->on_data = httpData;
context->on_end = httpEnd;
HttpContext::HttpContext() {
context.on_accepted = httpBegin;
context.on_data = httpData;
context.on_end = httpEnd;
context.on_writable = httpOut;
}
void HttpContext::listen(const char *host, int port, int options) {
us_socket_context_listen(context, host, port, options, sizeof(us_socket));
us_socket_context_listen(&context, host, port, options, sizeof(HttpSocket));
}
// HttpSocket
void HttpSocket::stream(int length, decltype(outStream) stream) {
outStream = stream;
offset = 0;
// try stream
std::pair<const char *, int> chunk = outStream(offset);
offset = us_socket_write(&s, chunk.first, chunk.second);
}
+13 -6
View File
@@ -2,31 +2,38 @@
#define HTTP_H
#include "libusockets.h"
#include <functional>
struct HttpRequest {
};
struct HttpResponse {
struct HttpSocket {
us_socket s;
int offset = 0;
void write() {
HttpSocket() {
}
std::function<std::pair<const char *, int>(int)> outStream;
void stream(int length, decltype(outStream) stream);
};
// basically a HttpServer
struct HttpContext {
us_socket_context *context;
struct Data {
us_socket_context context;
/*struct Data {
} *data;
} *data;*/
static void httpBegin(us_socket *s);
// httpIn
static void httpData(us_socket *s, void *data, int size);
static void httpOut(us_socket *s);
static void httpEnd(us_socket *s);
HttpContext(us_loop *loop);
HttpContext();
void listen(const char *host, int port, int options);
};
+6 -2
View File
@@ -7,11 +7,15 @@ void Hub::wakeupCb(us_loop *loop) {
Hub::Hub() {
loop = us_create_loop(wakeupCb, sizeof(Data));
new (data = (Data *) us_loop_userdata(loop)) Data(loop);
new (data = (Data *) us_loop_userdata(loop)) Data();
// this could lie in Data constructor
data->httpContext = (HttpContext *) us_create_socket_context(loop, sizeof(HttpContext));
new (data->httpContext) HttpContext();
}
void Hub::listen(const char *host, int port, int options) {
data->httpContext.listen(host, port, options);
data->httpContext->listen(host, port, options);
}
void Hub::run() {
+11 -3
View File
@@ -10,15 +10,23 @@
struct Hub {
us_loop *loop;
struct Data {
Data(us_loop *loop) : httpContext(loop) {
Data() {
}
HttpContext httpContext;
std::function<void(HttpRequest *, HttpResponse *, char *data, unsigned int length)> onHttpRequest;
HttpContext *httpContext;
std::function<void(HttpSocket *)> onHttpConnection;
std::function<void(HttpSocket *)> onHttpDisconnection;
std::function<void(HttpSocket *, HttpRequest *, char *data, unsigned int length)> onHttpRequest;
} *data;
static void wakeupCb(us_loop *loop);
void onHttpConnection(decltype(Data::onHttpConnection) handler) {
data->onHttpConnection = handler;
}
void onHttpDisconnection(decltype(Data::onHttpDisconnection) handler) {
data->onHttpDisconnection = handler;
}
void onHttpRequest(decltype(Data::onHttpRequest) handler) {
data->onHttpRequest = handler;
}