126 lines
3.9 KiB
C++
126 lines
3.9 KiB
C++
#ifndef ASYNCSOCKET_H
|
|
#define ASYNCSOCKET_H
|
|
|
|
#include "StaticDispatch.h"
|
|
#include "LoopData.h"
|
|
|
|
// todo: this is where the magic happens
|
|
|
|
namespace uWS {
|
|
|
|
template <bool SSL>
|
|
struct AsyncSocket : StaticDispatch<SSL> {
|
|
|
|
using SOCKET_TYPE = typename StaticDispatch<SSL>::SOCKET_TYPE;
|
|
using StaticDispatch<SSL>::static_dispatch;
|
|
|
|
// control everything with write, cork, uncork, close
|
|
// have HttpResponseData derive from AsyncSocketData?
|
|
|
|
// HttpResponse will only need one buffer for outgoing - the corked up
|
|
|
|
// maybe better name would be CorkableSocket?
|
|
|
|
// this does not belong here!
|
|
int u32toa(uint32_t value, char *dst) {
|
|
char temp[10];
|
|
char *p = temp;
|
|
do {
|
|
*p++ = (char) (value % 10) + '0';
|
|
value /= 10;
|
|
} while (value > 0);
|
|
|
|
int ret = p - temp;
|
|
|
|
do {
|
|
*dst++ = *--p;
|
|
} while (p != temp);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void cork() {
|
|
LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
|
|
|
|
loopData->corked = true;
|
|
|
|
}
|
|
|
|
void uncork() {
|
|
LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
|
|
|
|
loopData->corked = false;
|
|
|
|
// send it off now!
|
|
|
|
int written = static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, loopData->corkBuffer, loopData->corkOffset, false);
|
|
|
|
loopData->corkOffset = 0;
|
|
|
|
// buffer the rest up in the outbuffer of this asynsocket!
|
|
}
|
|
|
|
void writeUnsigned(unsigned int value) {
|
|
LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
|
|
|
|
loopData->corkOffset += u32toa(value, loopData->corkBuffer + loopData->corkOffset);
|
|
}
|
|
|
|
void write(const char *src, int length) {
|
|
LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(us_socket_get_context((us_socket *) this)));
|
|
|
|
memcpy(loopData->corkBuffer + loopData->corkOffset, src, length);
|
|
loopData->corkOffset += length;
|
|
}
|
|
|
|
int writeOptionally(const char *src, int length) {
|
|
|
|
// not optional for now
|
|
AsyncSocket<SSL>::write(src, length);
|
|
|
|
return length;
|
|
|
|
/*
|
|
// kopiera upp till (SSL eller icke-ssl) max copy distance
|
|
|
|
// om mer än detta, fortsätt skicka
|
|
|
|
// this entire strategy should be made entirely in AsyncSocket!
|
|
|
|
// this strategy can be simplified to one, we can even have MAX_COPY_DISTANCE_SSL and MAX_COPY_DISTANCE
|
|
if (length < LoopData::MAX_COPY_DISTANCE) {
|
|
AsyncSocket<SSL>::write("Content-Length: ", 16);
|
|
AsyncSocket<SSL>::writeUnsigned(chunk.length());
|
|
AsyncSocket<SSL>::write("\r\n\r\n", 4);
|
|
AsyncSocket<SSL>::write(chunk.data(), chunk.length());
|
|
} else {
|
|
// copying some data with the headers is a good idea for SSL but probably not for non-SSL
|
|
//writeToCorkBufferAndReset(chunk.data(), LoopData::MAX_COPY_DISTANCE, length, true);
|
|
|
|
// just assume this went fine
|
|
HttpResponseData<SSL> *httpData = (HttpResponseData<SSL> *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
|
|
|
// write that off! (should never happen here!)
|
|
//static_dispatch(us_ssl_socket_write, us_socket_write)((SOCKET_TYPE *) this, chunk.data() + LoopData::MAX_COPY_DISTANCE, chunk.length() - LoopData::MAX_COPY_DISTANCE, 0);
|
|
|
|
// if offset is at the end, we are done
|
|
if (httpData->offset < length) {
|
|
httpData->outStream = cb;
|
|
}
|
|
}*/
|
|
|
|
}
|
|
|
|
void *getExt() {
|
|
return static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this);
|
|
}
|
|
|
|
void close() {
|
|
static_dispatch(us_ssl_socket_close, us_socket_close)((SOCKET_TYPE *) this);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif // ASYNCSOCKET_H
|