From 9b4161bd259134a70a8021a441ef902cbbaa61f6 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 10 Jul 2018 09:55:38 +0200 Subject: [PATCH] Excluded Network Library --- src/network/Address.cpp | 68 --- src/network/Address.h | 31 -- src/network/Socket.cpp | 642 ---------------------------- src/network/Socket.h | 167 -------- src/network/http/HttpConnection.cpp | 193 --------- src/network/http/HttpConnection.h | 54 --- src/network/http/HttpHeader.cpp | 123 ------ src/network/http/HttpHeader.h | 53 --- src/network/http/HttpRequest.cpp | 107 ----- src/network/http/HttpRequest.h | 52 --- src/network/http/HttpResponse.cpp | 70 --- src/network/http/HttpResponse.h | 50 --- src/network/http/HttpStatusCode.cpp | 65 --- src/network/http/HttpStatusCode.h | 15 - 14 files changed, 1690 deletions(-) delete mode 100644 src/network/Address.cpp delete mode 100644 src/network/Address.h delete mode 100644 src/network/Socket.cpp delete mode 100644 src/network/Socket.h delete mode 100644 src/network/http/HttpConnection.cpp delete mode 100644 src/network/http/HttpConnection.h delete mode 100644 src/network/http/HttpHeader.cpp delete mode 100644 src/network/http/HttpHeader.h delete mode 100644 src/network/http/HttpRequest.cpp delete mode 100644 src/network/http/HttpRequest.h delete mode 100644 src/network/http/HttpResponse.cpp delete mode 100644 src/network/http/HttpResponse.h delete mode 100644 src/network/http/HttpStatusCode.cpp delete mode 100644 src/network/http/HttpStatusCode.h diff --git a/src/network/Address.cpp b/src/network/Address.cpp deleted file mode 100644 index d283ea1..0000000 --- a/src/network/Address.cpp +++ /dev/null @@ -1,68 +0,0 @@ - - -#include -#include -#include -#include -#include "Address.h" - -using namespace std; - - -Address::Address() { - -} - -Address::Address(string addr) { - // TODO -} - -Address::Address(struct sockaddr_in *addr) { - address = ntohl(addr->sin_addr.s_addr); -} - - -struct sockaddr_in Address::toStruct(unsigned short port)const { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(address); - addr.sin_port = htons(port); - return addr; -} - - - -string Address::toString() const { - struct sockaddr_in addr = toStruct(0); - struct in_addr ipAddr = addr.sin_addr; - return inet_ntoa(ipAddr); -} - -bool Address::isLocal() { - string a = toString(); - return a.find("127.0.0.") == 0; -} - - -ostream& operator<<(ostream &str, const Address &addr) { - return str << addr.toString(); -} - -string operator+(string &str, const Address &addr) { - return str + addr.toString(); -} - -string operator+(string &str, const Address *addr) { - return str + addr->toString(); -} - -string operator+(const Address &addr, string &str) { - return addr.toString() + str; -} - -string operator+(const Address *addr, string &str) { - return addr->toString() + str; -} - - - diff --git a/src/network/Address.h b/src/network/Address.h deleted file mode 100644 index 4583b5c..0000000 --- a/src/network/Address.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Necronda Web Server 3.0 - * HttpHeader.h - HttpHeader Class definition - * Lorenz Stechauner, 2018-05-09 - */ - -#ifndef NECRONDA_ADDRESS -#define NECRONDA_ADDRESS - -using namespace std; - -class Address { -private: - unsigned int address; - -public: - Address(); - - explicit Address(string address); - - explicit Address(struct sockaddr_in *address); - - struct sockaddr_in toStruct(unsigned short port) const; - - string toString() const; - - bool isLocal(); - -}; - -#endif diff --git a/src/network/Socket.cpp b/src/network/Socket.cpp deleted file mode 100644 index daa99a2..0000000 --- a/src/network/Socket.cpp +++ /dev/null @@ -1,642 +0,0 @@ -/** - * Necronda Web Server 3.0 - * Socket.cpp - Socket Class methods - * Lorenz Stechauner, 2018-05-09 - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Address.h" -#include "Socket.h" -#include "../necronda-server.h" - - -using namespace std; - - -static void multi_ssl_init() { - SSL_load_error_strings(); - SSL_library_init(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); -} - - -char *multi_ssl_get_error(SSL *ssl, int ret) { - if (ret > 0) { - return NULL; - } - - unsigned long ret2 = ERR_get_error(); - const char *err2 = strerror(errno); - const char *err1 = ERR_reason_error_string(ret2); - - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_NONE: - return (char *) "none"; - case SSL_ERROR_ZERO_RETURN: - return (char *) "closed"; - case SSL_ERROR_WANT_READ: - return (char *) "want_read"; - case SSL_ERROR_WANT_WRITE: - return (char *) "want_write"; - case SSL_ERROR_WANT_CONNECT: - return (char *) "want_connect"; - case SSL_ERROR_WANT_ACCEPT: - return (char *) "want_accept"; - case SSL_ERROR_WANT_X509_LOOKUP: - return (char *) "want_x509_lookup"; - case SSL_ERROR_SYSCALL: - return (char *) ((ret2 == 0) ? (ret == 0) ? "protocol violation" : err2 : err1); - case SSL_ERROR_SSL: - return (char *) err1; - default: - return (char *) "unknown error"; - } -} - -char *strerror_socket(int nr) { - if (nr == EAGAIN || nr == EWOULDBLOCK) { - return (char *) "timeout"; - } else if (nr == ECONNRESET) { - return (char *) "closed"; - } else { - return strerror(nr); - } -} - - -Socket::Socket(int fd) { - this->fd = fd; - microsStart = getMicros(); - microsLast = microsStart; - bytesSent = 0; - bytesReceived = 0; - enc = false; - ssl = nullptr; - ctx = nullptr; - clients = false; - servers = false; -} - -Socket::Socket() { - fd = ::socket(AF_INET, SOCK_STREAM, 0); - if (fd == 0) { - throw strerror(errno); - } - enc = false; - microsStart = getMicros(); - microsLast = microsStart; - bytesSent = 0; - bytesReceived = 0; - ssl = nullptr; - ctx = nullptr; - clients = false; - servers = false; -} - -void Socket::setSocketOption(int option, bool value = true) { - int val = value ? 1 : 0; - - if (::setsockopt(fd, SOL_SOCKET, option, &val, sizeof(val)) != 0) { - throw strerror(errno); - } -} - -void Socket::bind(Address *address, unsigned short port) { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; // address. - addr.sin_port = htons(port); - - if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { - throw strerror(errno); - } -} - -void Socket::bind(unsigned short port) { - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(port); - - if (::bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { - throw strerror(errno); - } -} - -void Socket::listen(int num) { - if (::listen(fd, num) != 0) { - throw strerror(errno); - } -} - -void Socket::connect(Address, unsigned short) { - -} - -Socket* Socket::accept() { - int newfd = ::accept(fd, nullptr, nullptr); - if (newfd < 0) { - throw strerror(errno); - } - Socket *socket = new Socket(newfd); - socket->servers = true; - return socket; -} - -void Socket::close() { - if (isSecured()) { - //SSL_shutdown(ssl); - SSL_free(ssl); - SSL_CTX_free(ctx); - } - - if (::close(fd) != 0) { - throw strerror(errno); - } -} - -Address *Socket::getPeerAddress() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getpeername(fd, (struct sockaddr *) &addr, &len); - struct sockaddr_in *s = (struct sockaddr_in *) &addr; - return new Address(s); -} - -unsigned short Socket::getPeerPort() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getpeername(fd, (struct sockaddr *) &addr, &len); - return ntohs(((struct sockaddr_in *) &addr)->sin_port); -} - -Address *Socket::getSocketAddress() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getsockname(fd, (struct sockaddr *) &addr, &len); - struct sockaddr_in *s = (struct sockaddr_in *) &addr; - return new Address(s); -} - -unsigned short Socket::getSocketPort() const { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - getsockname(fd, (struct sockaddr *) &addr, &len); - return ntohs(((struct sockaddr_in *) &addr)->sin_port); -} - - -void Socket::setReuseAddress(bool value) { - setSocketOption(SO_REUSEADDR, value); -} - -void Socket::setReusePort(bool value) { - setSocketOption(SO_REUSEPORT, value); -} - - -string Socket::toString() const { - return "{[Socket]" + getSocketAddress()->toString() + ":" + to_string(getSocketPort()) + "<->" + - getPeerAddress()->toString() + ":" + to_string(getPeerPort()) + "}"; -} - -long Socket::send(string *str) { - return send(str->c_str(), str->length()); -} - -long Socket::send(string str) { - return send(str.c_str(), str.length()); -} - -long Socket::send(const char *str, long length) { - return send((void*) str, length); -} - -long Socket::send(const char *str) { - return send(str, strlen(str)); -} - -Socket::~Socket() { - -} - -long Socket::receive(void *buffer, int size) { - long len; - if (isSecured()) { - len = SSL_read(ssl, buffer, size); - if (len < 0) { - throw multi_ssl_get_error(ssl, (int) len); - } - } else { - len = recv(fd, buffer, (size_t) size, 0); - if (len < 0) { - throw strerror_socket(errno); - } - } - bytesReceived += len; - return len; -} - -long Socket::peek(void *buffer, int size) { - long len; - if (isSecured()) { - len = SSL_peek(ssl, buffer, size); - if (len < 0) { - throw multi_ssl_get_error(ssl, (int) len); - } - } else { - len = recv(fd, buffer, (size_t) size, MSG_PEEK); - if (len < 0) { - throw strerror_socket(errno); - } - } - return len; -} - -long Socket::send(void *buffer, int size) { - long len; - if (isSecured()) { - if (size != 0) { - len = SSL_write(ssl, buffer, size); - if (len <= 0) { - throw multi_ssl_get_error(ssl, (int) len); - } - } else { - len = 0; - } - } else { - len = ::send(fd, buffer, (size_t) size, 0); - if (len < 0) { - throw strerror_socket(errno); - } - } - bytesSent += len; - return len; -} - - -string Socket::receive() { - string *str = new string(); - - char buffer[CHUNK]; - long len = 0; - do { - len = receive((void*) buffer, CHUNK); - str->append(buffer, (unsigned) len); - } while (len > 0 && len == CHUNK); - - return *str; -} - -string Socket::receive(long length) { - string *str = new string(); - - char buffer[CHUNK]; - long len = 0; - long reclen = 0; - do { - len = receive((void*) buffer, CHUNK); - reclen += len; - str->append(buffer, (unsigned) len); - } while (reclen < length); - - return *str; -} - -string Socket::receive(string until) { - string *str = new string(); - - struct pollfd ufds[1]; - ufds[0].fd = fd; - ufds[0].events = POLLIN | POLLOUT; - - char buffer[CHUNK]; - long len = 0; - do { - len = peek((void*) buffer, CHUNK); - if (len != 0) { - string s = string(buffer, (size_t) len); - size_t found = s.find(until); - long l = (found != string::npos) ? found + 1 : len; - long l2 = (found != string::npos) ? found : len; - str->append(buffer, (unsigned) l2); - receive((void *) buffer, (int) l); - if (found != string::npos) { - break; - } - } - if (poll(ufds, 1, 0) < 0) { - throw strerror_socket(errno); - } else if ((ufds[0].revents & POLLIN) == 0) { - if ((ufds[0].revents & POLLOUT) != 0) { - throw (char *) "error"; - } else { - throw (char *) "want_write"; - } - } else if ((ufds[0].revents & POLLERR) != 0) { - throw (char *) "error"; - } else if (ufds[0].revents & (POLLRDHUP | POLLHUP | POLLNVAL) != 0) { - throw (char *) "closed"; - } - } while (true); - - return *str; -} - -string Socket::receive(const char *until) { - return receive(until, (int) (strlen(until))); -} - -string Socket::receive(const char *until, unsigned long strlen) { - return receive(string(until, strlen)); -} - -void Socket::receive(FILE *file) { - char buffer[CHUNK]; - long len = 0; - do { - len = receive((void*) buffer, CHUNK); - fwrite(buffer, 1, CHUNK, file); - } while (len > 0 && len == CHUNK); -} - -void Socket::receive(FILE *file, long size) { - char buffer[CHUNK]; - long len = 0; - long rec = 0; - do { - if (size - rec == 0) { - break; - } - len = receive((void*) buffer, (CHUNK > (size - rec) && size >= 0)?(size - rec):CHUNK); - fwrite(buffer, 1, CHUNK, file); - rec += len; - } while (len > 0); -} - -string Socket::receiveLine() { - string str = receive("\n"); - if (str.length() > 0 && str.at(str.length() - 1) == '\r') { - str = str.substr(0, str.length() - 1); - } - return str; -} - - -long Socket::getDuration() { - return getMicros() - microsStart; -} - - -void Socket::setReceiveTimeout(unsigned long ms) { - struct timeval timeout; - if (ms == 0) { - timeout.tv_sec = 0; - timeout.tv_usec = 1; - } else { - timeout.tv_sec = ms / 1000; - timeout.tv_usec = (ms % 1000) * 1000; - } - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout)) < 0) { - throw strerror(errno); - } -} - -void Socket::setSendTimeout(unsigned long ms) { - struct timeval timeout; - if (ms == 0) { - timeout.tv_sec = 0; - timeout.tv_usec = 1; - } else { - timeout.tv_sec = ms / 1000; - timeout.tv_usec = (ms % 1000) * 1000; - } - if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout)) < 0) { - throw strerror(errno); - } -} - -bool Socket::isServerSide() { - return servers; -} - -bool Socket::isSecured() { - return enc; -} - -bool Socket::isClientSide() { - return clients; -} - -void Socket::sslHandshake(map sni) { - /*if (isSecured()) { - throw (char *) "Socket already secured"; - } - - const SSL_METHOD *method; - if (isServerSide()) { - method = TLSv1_2_server_method(); - } else if (isClientSide()) { - method = TLSv1_2_client_method(); - } else { - method = TLSv1_2_method(); - } - - SSL_CTX *ctx = SSL_CTX_new(method); - SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); - SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"); - SSL_CTX_set_ecdh_auto(ctx, 1); - - const char *certfile = keypair.fullchain.c_str(); - const char *keyfile = keypair.privkey.c_str(); - - if (isServerSide()) { - if (SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } - - if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } - } - - SSL_CTX_set_tlsext_servername_callback - - this->ctx = ctx; - this->ssl = SSL_new(ctx); - SSL_set_fd(ssl, fd); - enc = true; - - while (true) { - int ret = 0; - if (isServerSide()) { - ret = SSL_accept(ssl); - } else if (isClientSide()) { - ret = SSL_connect(ssl); - } else { - ret = SSL_do_handshake(ssl); - } - - if (ret <= 0 && ((isServerSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_READ) || - (isClientSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_WRITE))) { - throw multi_ssl_get_error(ssl, ret); - } else if (ret == 1) { - break; - } - }*/ - -} - -void Socket::sslHandshake() { - sslHandshake(KeyPair{"", ""}); -} - -void Socket::sslHandshake(KeyPair keypair) { - if (isSecured()) { - throw (char *) "Socket already secured"; - } - - const SSL_METHOD *method; - if (isServerSide()) { - method = TLSv1_2_server_method(); - } else if (isClientSide()) { - method = TLSv1_2_client_method(); - } else { - method = TLSv1_2_method(); - } - - SSL_CTX *ctx = SSL_CTX_new(method); - SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); - SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"); - SSL_CTX_set_ecdh_auto(ctx, 1); - - const char *certfile = keypair.fullchain.c_str(); - const char *keyfile = keypair.privkey.c_str(); - - if (isServerSide()) { - if (SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } - - if (SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM) != 1) { - throw (char *) ERR_reason_error_string(ERR_get_error()); - } - } - - this->ctx = ctx; - this->ssl = SSL_new(ctx); - SSL_set_fd(ssl, fd); - enc = true; - - while (true) { - int ret = 0; - if (isServerSide()) { - ret = SSL_accept(ssl); - } else if (isClientSide()) { - ret = SSL_connect(ssl); - } else { - ret = SSL_do_handshake(ssl); - } - - if (ret <= 0 && ((isServerSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_READ) || - (isClientSide() && SSL_get_error(ssl, ret) != SSL_ERROR_WANT_WRITE))) { - throw multi_ssl_get_error(ssl, ret); - } else if (ret == 1) { - break; - } - } - -} - -void Socket::sslHandshake(string privkey, string fullchain) { - sslHandshake(KeyPair{std::move(privkey), std::move(fullchain)}); -} - -long Socket::select(list read, list write, long millis) { - fd_set readfd, writefd; - int maxfd = 0; - FD_ZERO(&readfd); - FD_ZERO(&writefd); - - for (Socket s : read) { - if (s.fd > maxfd) { - maxfd = s.fd; - } - FD_SET(s.fd, &readfd); - } - - for (Socket s : write) { - if (s.fd > maxfd) { - maxfd = s.fd; - } - FD_SET(s.fd, &writefd); - } - - struct timeval *tv = new struct timeval; - if (millis < 0) { - tv = nullptr; - } else if (millis == 0) { - tv->tv_sec = 0; - tv->tv_usec = 1; - } else { - tv->tv_sec = millis / 1000; - tv->tv_usec = (millis % 1000) * 1000; - } - - int ret = ::select(maxfd + 1, &readfd, &writefd, nullptr, tv); - if (ret < 0) { - throw (char *) strerror(errno); - } - return ret; -} - -long Socket::select(list read, list write) { - Socket::select(std::move(read), std::move(write), -1); -} - -unsigned long Socket::getBytesSent() { - return bytesSent; -} - -unsigned long Socket::getBytesReceived() { - return bytesReceived; -} - - -ostream &operator<<(ostream &str, const Socket &socket) { - return str << socket.toString(); -} - -ostream &operator<<(ostream &str, const Socket *socket) { - return str << socket->toString(); -} - -string operator+(string &str, const Socket &socket) { - return str + socket.toString(); -} - -string operator+(const Socket &socket, string &str) { - return socket.toString() + str; -} - - - - diff --git a/src/network/Socket.h b/src/network/Socket.h deleted file mode 100644 index 1521479..0000000 --- a/src/network/Socket.h +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Necronda Web Server 3.0 - * Socket.h - Socket Class definition - * Lorenz Stechauner, 2018-05-09 - */ - -#ifndef NECRONDA_SOCKET -#define NECRONDA_SOCKET - -#include - -typedef struct { - string privkey; - string fullchain; -} KeyPair; - -using namespace std; - -class Socket { -private: - int fd; - SSL *ssl; - SSL_CTX *ctx; - bool enc; - bool servers; - bool clients; - unsigned long bytesSent; - unsigned long bytesReceived; - long microsStart; - long microsLast; - - void setSocketOption(int, bool); - - long send(void *buffer, int size); - - long receive(void *buffer, int size); - - long peek(void *buffer, int size); - -public: - Socket(); - - explicit Socket(int filedescriptor); - - ~Socket(); - - void bind(Address *address, unsigned short port); - - void bind(unsigned short port); - - void listen(int count = 1); - - void connect(Address address, unsigned short port); - - Socket* accept(); - - void sslHandshake(); - - void sslHandshake(map sni); - - void sslHandshake(KeyPair keypair); - - void sslHandshake(string privkey, string fullchain); - - long send(string *str); - - long send(string str); - - long send(const char *str); - - long send(const char *str, long length); - - string receive(); - - string receive(long length); - - string receive(string until); - - string receive(const char *until, unsigned long strlen); - - string receive(const char *until); - - void receive(FILE *file); - - string receiveLine(); - - void shutdown(); - - void close(); - - long getDuration(); - - Address *getSocketAddress() const; - - unsigned short getSocketPort() const; - - Address *getPeerAddress() const; - - unsigned short getPeerPort() const; - - string toString() const; - - - bool isServerSide(); - - bool isClientSide(); - - bool isSecured(); - - - void setReuseAddress(bool value = true); - - void setReusePort(bool value = true); - - void setSendBufferSize(int value); - - void setReceiveBufferSize(int value); - - void setMinReceiveBytes(int value); - - void setMinSendBytes(int value); - - void setSendTimeout(unsigned long ms); - - void setReceiveTimeout(unsigned long ms); - - - bool getReuseAddress(); - - bool getReusePort(); - - int getSendBufferSize(); - - int getReceiveBufferSize(); - - int getMinReceiveBytes(); - - int getMinSendBytes(); - - long getSendTimeout(); - - long getReceiveTimeout(); - - unsigned long getBytesSent(); - - unsigned long getBytesReceived(); - - static long select(list read, list write, long millis); - - static long select(list read, list write); - - void receive(FILE *file, long size); -}; - -Socket operator<<(Socket sock, const char *str); - -Socket operator<<(Socket sock, string str); - -ostream &operator<<(ostream &str, const Socket &socket); - -ostream &operator<<(ostream &str, const Socket *socket); - -string operator+(string &str, const Socket &socket); - -string operator+(const Socket &socket, string &str); - -#endif diff --git a/src/network/http/HttpConnection.cpp b/src/network/http/HttpConnection.cpp deleted file mode 100644 index a58ac59..0000000 --- a/src/network/http/HttpConnection.cpp +++ /dev/null @@ -1,193 +0,0 @@ - - -#include -#include -#include -#include -#include "HttpConnection.h" -#include "../../necronda-server.h" -#include "HttpStatusCode.h" - -HttpConnection::HttpConnection(Socket *socket) { - this->socket = socket; - this->request = new HttpRequest(socket); - this->response = new HttpResponse(); - microsStart = getMicros(); - response->setVersion("1.1"); - response->setField("Server", "Necronda/3.0"); -} - -void HttpConnection::respond(int statuscode) { - if (statuscode >= 400 && statuscode < 600) { - respond(statuscode, - "" + to_string(statuscode) + " " + - ::getStatusCode(statuscode).message + - "

" + to_string(statuscode) + " " + - ::getStatusCode(statuscode).message + - "

" + - ((request->isExistingField("Host")) ? - (request->isExistingField("Referer") && - request->getField("Referer").find(request->getField("Host")) != string::npos) ? - "

Go back to the last page you visited: getField("Referer") + "\">" + - request->getField("Referer") + "

" : - "

Go back to the home page of getField("Host") + "/\">" + - request->getField("Host") + - "

" : "") + "
\r\n" - ); - } else { - respond(statuscode, ""); - } -} - -void HttpConnection::respond(int statuscode, string payload) { - response->setStatusCode(statuscode); - response->setField("Date", getHttpDate()); - response->setField("Content-Length", to_string(payload.length())); - response->sendHeader(socket); - socket->send(std::move(payload)); -} - -void HttpConnection::respond(int statuscode, FILE *file, bool compress, long start, long end) { - response->setStatusCode(statuscode); - response->setField("Transfer-Encoding", "chunked"); - response->setField("Date", getHttpDate()); - - long shouldTransfer; - long transfered = 0; - - fseek(file, 0, SEEK_END); - long len = ftell(file); - - if (start != -1 && end != -1) { - fseek(file, start, SEEK_SET); - response->setField("Content-Length", to_string(end - start + 1)); - shouldTransfer = end - start + 1; - compress = false; - } else { - fseek(file, 0, SEEK_SET); - shouldTransfer = len; - if (len >= 0) { - response->setField("Content-Length", to_string(len)); - } - } - - if (compress) { - response->setField("Content-Encoding", "deflate"); - } - - response->sendHeader(socket); - - if (compress) { - int level = 1; - int ret, flush; - unsigned have; - z_stream strm; - unsigned char in[CHUNK]; - unsigned char out[CHUNK]; - - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - ret = deflateInit(&strm, level); - if (ret != Z_OK) { - throw (char *) "Unable to open file"; - } - - do { - strm.avail_in = (uInt) fread(in, 1, CHUNK, file); - - if (ferror(file)) { - (void) deflateEnd(&strm); - throw (char *) strerror(errno); - } - flush = feof(file) ? Z_FINISH : Z_NO_FLUSH; - strm.next_in = in; - do { - strm.avail_out = CHUNK; - strm.next_out = out; - ret = deflate(&strm, flush); - assert(ret != Z_STREAM_ERROR); - have = CHUNK - strm.avail_out; - - if (have != 0) { - char buffer[64]; - sprintf(buffer, "%X\r\n", have); - socket->send(buffer); - socket->send((const char *) out, have); - socket->send("\r\n"); - } - } while (strm.avail_out == 0); - assert(strm.avail_in == 0); - } while (flush != Z_FINISH); - assert(ret == Z_STREAM_END); - socket->send("0\r\n\r\n"); - deflateEnd(&strm); - } else { - char buffer[CHUNK]; - char buff[64]; - while (true) { - unsigned long size = fread(buffer, 1, (size_t) ((CHUNK > (shouldTransfer - transfered) && shouldTransfer > 0) ? (shouldTransfer - transfered) : CHUNK), file); - transfered += size; - sprintf(buff, "%lX\r\n", size); - socket->send(buff); - socket->send((const char *) buffer, size); - socket->send("\r\n"); - if (size == 0) { - break; - } - } - } -} - -string HttpConnection::getField(string index) { - return request->getField(std::move(index)); -} - -string HttpConnection::getPath() { - return request->getPath(); -} - -void HttpConnection::setField(string index, string data) { - response->setField(std::move(index), std::move(data)); -} - -bool HttpConnection::isExistingField(string index) { - return request->isExistingField(std::move(index)); -} - -string HttpConnection::getMethod() { - return request->getMethod(); -} - -long HttpConnection::getDuration() { - return getMicros() - microsStart; -} - -HttpStatusCode HttpConnection::getStatusCode() { - return response->getStatusCode(); -} - -void HttpConnection::redirect(int statuscode, string location) { - setField("Location", std::move(location)); - respond(statuscode, ""); -} - -string HttpConnection::getResponseField(string index) { - return response->getField(std::move(index)); -} - -bool HttpConnection::isExistingResponseField(string index) { - return response->isExistingField(std::move(index)); -} - -string HttpConnection::cgiExport() { - return request->cgiExport(); -} - -void HttpConnection::removeField(string index) { - response->removeField(std::move(index)); -} - - - diff --git a/src/network/http/HttpConnection.h b/src/network/http/HttpConnection.h deleted file mode 100644 index 464ea98..0000000 --- a/src/network/http/HttpConnection.h +++ /dev/null @@ -1,54 +0,0 @@ - - -#ifndef NECRONDA_HTTP_CONNECTION -#define NECRONDA_HTTP_CONNECTION - - -#include "../Socket.h" -#include "HttpResponse.h" -#include "HttpRequest.h" -#include "../../necronda-server.h" - - -class HttpConnection { -private: - Socket *socket; - HttpRequest *request; - HttpResponse *response; - long microsStart; - -public: - explicit HttpConnection(Socket *socket); - - void respond(int statuscode); - - void respond(int statuscode, string payload); - - void respond(int statuscode, FILE *file, bool compress = false, long start = -1, long end = -1); - - void redirect(int statuscode, string location); - - bool isExistingField(string index); - - bool isExistingResponseField(string index); - - string getField(string index); - - string getResponseField(string index); - - string getPath(); - - string getMethod(); - - void setField(string index, string data); - - long getDuration(); - - HttpStatusCode getStatusCode(); - - string cgiExport(); - - void removeField(string index); -}; - -#endif diff --git a/src/network/http/HttpHeader.cpp b/src/network/http/HttpHeader.cpp deleted file mode 100644 index 5a864a4..0000000 --- a/src/network/http/HttpHeader.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Necronda Web Server 3.0 - * HttpHeader.cpp - HttpHeader Class methods - * Lorenz Stechauner, 2018-05-09 - */ - - -#include -#include -#include "../Socket.h" - -#include "HttpHeader.h" -#include "../../necronda-server.h" - - -using namespace std; - -string to_cgi(string text) { - for (auto & c: text) c = (char) toupper(c); - long pos = 0; - while ((pos = text.find('-', pos + 1)) != string::npos) { - text.replace(pos, 1, 1, '_'); - } - return text; -} - - -/** - * Default Constructor - */ -HttpHeader::HttpHeader() { - fields = fields; -} - -HttpHeader::HttpHeader(Socket *socket) : HttpHeader::HttpHeader() { - parse(socket); -} - - -void HttpHeader::parse(Socket *socket) { - while (true) { - string line = socket->receiveLine(); - if (line.length() == 0) { - break; - } else { - unsigned long pos = line.find(':'); - if (pos == string::npos) { - throw (char *) "Malformed header"; - } - string index = line.substr(0, pos); - string data = line.substr(pos + 1, line.length() - pos); - while (index[0] == ' ') index.erase(index.begin() + 0); - while (index[index.length() - 1] == ' ') index.erase(index.end() - 1); - while (data[0] == ' ') data.erase(data.begin() + 0); - while (data[data.length() - 1] == ' ') data.erase(data.end() - 1); - setField(index, data); - } - } -} - - -/** - * Default Destructor - */ -HttpHeader::~HttpHeader() { - fields.clear(); -} - - -/** - * Sets a field in the HTTP header - * e.g. Content-Length: 42 - * @param index The field index - * @param data The field data - */ -void HttpHeader::setField(string index, string data) { - removeField(index); - fields.insert(make_pair(index, data)); -} - -void HttpHeader::removeField(string index) { - fields.erase(index); -} - -/** - * Gets a field from the HTTP header - * e.g. Content-Length: 42 - * @param index The field index - * @return The field data - */ -string HttpHeader::getField(string index) { - auto i = fields.find(index); - if (i != fields.end()) { - return fields.at(index); - } else { - return ""; - } -} - - -bool HttpHeader::isExistingField(string index) { - auto i = fields.find(index); - return i != fields.end(); -} - -string HttpHeader::toString() { - string header = ""; - for (auto it = fields.begin(); it != fields.end(); it++ ) { - header += it->first + ": " + it->second + "\r\n"; - } - return header; -} - -string HttpHeader::cgiExport() { - string header = ""; - for (auto it = fields.begin(); it != fields.end(); it++ ) { - header += "HTTP_" + to_cgi(it->first) + "=" + cli_encode(it->second) + " "; - } - return header; -} - - - diff --git a/src/network/http/HttpHeader.h b/src/network/http/HttpHeader.h deleted file mode 100644 index 291f434..0000000 --- a/src/network/http/HttpHeader.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Necronda Web Server 3.0 - * HttpHeader.h - HttpHeader Class definition - * Lorenz Stechauner, 2018-05-09 - */ - -#ifndef NECRONDA_HTTP_HEADER -#define NECRONDA_HTTP_HEADER - -#include - -using namespace std; - -struct comp { - bool operator()(const std::string& lhs, const std::string& rhs) const { - return strcasecmp(lhs.c_str(), rhs.c_str()) < 0; - } -}; - -/** - * Stores Key-Value Pairs for a HTTP header - * e.g. - * Content-Length: 64 - * Host: example.org - */ -class HttpHeader { -private: - map fields; - -public: - HttpHeader(); - - explicit HttpHeader(Socket *socket); - - ~HttpHeader(); - - void setField(string index, string data); - - string getField(string index); - - void removeField(string index); - - bool isExistingField(string index); - - void parse(Socket *socket); - - string toString(); - - string cgiExport(); - -}; - -#endif diff --git a/src/network/http/HttpRequest.cpp b/src/network/http/HttpRequest.cpp deleted file mode 100644 index c323a01..0000000 --- a/src/network/http/HttpRequest.cpp +++ /dev/null @@ -1,107 +0,0 @@ - - -#include -#include -#include -#include "../Socket.h" -#include "HttpHeader.h" -#include "HttpRequest.h" - - -HttpRequest::HttpRequest() { - this->header = HttpHeader(); -} - -HttpRequest::HttpRequest(Socket *socket) : HttpRequest::HttpRequest() { - parseHeader(socket); -} - -HttpRequest::HttpRequest(string method, string path, string version) : HttpRequest::HttpRequest() { - this->method = std::move(method); - this->path = std::move(path); - this->version = std::move(version); -} - -void HttpRequest::parseHeader(Socket *socket) { - string line = socket->receiveLine(); - - unsigned long pos1 = line.find(' '); - unsigned long pos2; - - bool invalid = false; - - if (pos1 != string::npos) { - pos2 = line.find(' ', pos1 + 1); - if (pos2 != string::npos) { - method = line.substr(0, pos1); - for (auto &c: method) c = (char) toupper(c); - path = line.substr(pos1 + 1, pos2 - pos1 - 1); - version = line.substr(pos2 + 6, 3); - } else { - invalid = true; - } - } else { - pos2 = string::npos; - invalid = true; - } - - - if (!invalid && (line.substr(pos2 + 1, 5) != "HTTP/" || version[1] != '.' || path[0] != '/' || !(version[0] >= '0' && version[0] <= '9') || !(version[2] >= '0' && version[2] <= '9'))) { - invalid = true; - } - - if (invalid) { - method = ""; - path = ""; - version = ""; - throw (char *) "Malformed header"; - } - - header.parse(socket); -} - -string HttpRequest::getMethod() { - return method; -} - -string HttpRequest::getPath() { - return path; -} - -string HttpRequest::getVersion() { - return version; -} - -void HttpRequest::setMethod(string method) { - this->method = std::move(method); -} - -void HttpRequest::setPath(string path) { - this->path = std::move(path); -} - -void HttpRequest::setVersion(string version) { - this->version = std::move(version); -} - -string HttpRequest::getField(string index) { - return header.getField(std::move(index)); -} - -void HttpRequest::setField(string index, string data) { - header.setField(std::move(index), std::move(data)); -} - -bool HttpRequest::isExistingField(string index) { - return header.isExistingField(std::move(index)); -} - -string HttpRequest::cgiExport() { - return header.cgiExport(); -} - - - - - - diff --git a/src/network/http/HttpRequest.h b/src/network/http/HttpRequest.h deleted file mode 100644 index 1432719..0000000 --- a/src/network/http/HttpRequest.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Necronda Web Server 3.0 - * HttpHeader.h - HttpHeader Class definition - * Lorenz Stechauner, 2018-05-09 - */ - -#ifndef NECRONDA_HTTP_REQUEST -#define NECRONDA_HTTP_REQUEST - -using namespace std; - -class HttpRequest { -private: - HttpHeader header; - string method; - string path; - string version; - -public: - HttpRequest(); - - explicit HttpRequest(Socket *socket); - - HttpRequest(string method, string path, string version = "1.1"); - - void parseHeader(Socket *socket); - - void sendHeader(Socket *socket); - - string getField(string index); - - void setField(string index, string data); - - bool isExistingField(string index); - - string getMethod(); - - string getPath(); - - string getVersion(); - - void setMethod(string method); - - void setPath(string path); - - void setVersion(string version); - - string cgiExport(); - -}; - -#endif diff --git a/src/network/http/HttpResponse.cpp b/src/network/http/HttpResponse.cpp deleted file mode 100644 index 83df59e..0000000 --- a/src/network/http/HttpResponse.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// Created by lorenz on 5/17/18. -// - -#include "HttpResponse.h" -#include -#include -#include "HttpStatusCode.h" - - -HttpResponse::HttpResponse() { - this->header = HttpHeader(); -} - -HttpResponse::HttpResponse(Socket *socket) : HttpResponse::HttpResponse() { - this->parseHeader(socket); -} - -HttpResponse::HttpResponse(int statuscode, string version) : HttpResponse::HttpResponse(::getStatusCode(statuscode), std::move(version)) { -} - -HttpResponse::HttpResponse(HttpStatusCode statuscode, string version) : HttpResponse::HttpResponse() { - this->statuscode = statuscode; - this->version = std::move(version); -} - -void HttpResponse::sendHeader(Socket *socket) { - socket->send("HTTP/" + version + " " + to_string(statuscode.code) + " " + statuscode.message + "\r\n" + - header.toString() + "\r\n"); -} - -string HttpResponse::getField(string index) { - return header.getField(std::move(index)); -} - -void HttpResponse::setField(string index, string data) { - header.setField(std::move(index), std::move(data)); -} - -bool HttpResponse::isExistingField(string index) { - return header.isExistingField(std::move(index)); -} - -HttpStatusCode HttpResponse::getStatusCode() { - return statuscode; -} - -string HttpResponse::getVersion() { - return version; -} - -void HttpResponse::setStatusCode(HttpStatusCode statuscode) { - this->statuscode = statuscode; -} - -void HttpResponse::setStatusCode(int statuscode) { - this->statuscode = ::getStatusCode(statuscode); -} - -void HttpResponse::setVersion(string version) { - this->version = std::move(version); -} - -void HttpResponse::parseHeader(Socket *socket) { - -} - -void HttpResponse::removeField(string index) { - header.removeField(std::move(index)); -} diff --git a/src/network/http/HttpResponse.h b/src/network/http/HttpResponse.h deleted file mode 100644 index f664e71..0000000 --- a/src/network/http/HttpResponse.h +++ /dev/null @@ -1,50 +0,0 @@ - - -#ifndef NECRONDA_HTTP_RESPONSE -#define NECRONDA_HTTP_RESPONSE - - -#include -#include "HttpHeader.h" -#include "HttpStatusCode.h" -#include "../Socket.h" - -class HttpResponse { -private: - HttpHeader header; - HttpStatusCode statuscode; - string version; - -public: - HttpResponse(); - - explicit HttpResponse(Socket *socket); - - explicit HttpResponse(int statuscode, string version = "1.1"); - - explicit HttpResponse(HttpStatusCode statuscode, string version = "1.1"); - - void parseHeader(Socket *socket); - - void sendHeader(Socket *socket); - - string getField(string index); - - void setField(string index, string data); - - bool isExistingField(string index); - - HttpStatusCode getStatusCode(); - - string getVersion(); - - void setStatusCode(HttpStatusCode statuscode); - - void setStatusCode(int statuscode); - - void setVersion(string version); - - void removeField(string index); -}; - -#endif diff --git a/src/network/http/HttpStatusCode.cpp b/src/network/http/HttpStatusCode.cpp deleted file mode 100644 index bffeafb..0000000 --- a/src/network/http/HttpStatusCode.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "HttpStatusCode.h" - -/** - * Necronda Web Server 3.0 - * HttpStatusCode.cpp - HTTP Status Code definition - * Lorenz Stechauner, 2018-05-16 - * Reference: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html - */ - - -HttpStatusCode httpStatusCodes[] = { - HttpStatusCode{100, "Informational", "Continue", ""}, - HttpStatusCode{101, "Informational", "Switching Protocols", ""}, - - HttpStatusCode{200, "Success", "OK", ""}, - HttpStatusCode{201, "Success", "Created", ""}, - HttpStatusCode{202, "Success", "Accepted", ""}, - HttpStatusCode{203, "Success", "Non-Authoritative Information", ""}, - HttpStatusCode{204, "Success", "No Centent", ""}, - HttpStatusCode{205, "Success", "Reset Content", ""}, - HttpStatusCode{206, "Success", "Partial Content", ""}, - - HttpStatusCode{300, "Redirection", "Multiple Choices", ""}, - HttpStatusCode{301, "Redirection", "Moved Permanently", ""}, - HttpStatusCode{302, "Redirection", "Found", ""}, - HttpStatusCode{303, "Redirection", "See Other", ""}, - HttpStatusCode{304, "Redirection", "Not Modified", ""}, - HttpStatusCode{305, "Redirection", "Use Proxy", ""}, - HttpStatusCode{307, "Redirection", "Temporary Redirect", ""}, - - HttpStatusCode{400, "Client Error", "Bad Request", ""}, - HttpStatusCode{401, "Client Error", "Unauthorized", ""}, - HttpStatusCode{402, "Client Error", "Payment Required", ""}, - HttpStatusCode{403, "Client Error", "Forbidden", ""}, - HttpStatusCode{404, "Client Error", "Not Found", ""}, - HttpStatusCode{405, "Client Error", "Method Not Allowed", ""}, - HttpStatusCode{406, "Client Error", "Not Acceptable", ""}, - HttpStatusCode{407, "Client Error", "Proxy Authentication Required", ""}, - HttpStatusCode{408, "Client Error", "Request Timeout", ""}, - HttpStatusCode{409, "Client Error", "Conflict", ""}, - HttpStatusCode{410, "Client Error", "Gone", ""}, - HttpStatusCode{411, "Client Error", "Length Required", ""}, - HttpStatusCode{412, "Client Error", "Precondition Failed", ""}, - HttpStatusCode{413, "Client Error", "Request Entity Too Large", ""}, - HttpStatusCode{414, "Client Error", "Request-URI Too Long", ""}, - HttpStatusCode{415, "Client Error", "Unsupported Media Type", ""}, - HttpStatusCode{416, "Client Error", "Requested Range Not Satisfiable", ""}, - HttpStatusCode{417, "Client Error", "Expectation Failed", ""}, - - HttpStatusCode{500, "Server Error", "Internal Server Error", ""}, - HttpStatusCode{501, "Server Error", "Not Implemented", ""}, - HttpStatusCode{502, "Server Error", "Bad Gateway", ""}, - HttpStatusCode{503, "Server Error", "Service Unavailable", ""}, - HttpStatusCode{504, "Server Error", "Gateway Timeout", ""}, - HttpStatusCode{505, "Server Error", "HTTP Version Not Supported", ""}, -}; - -HttpStatusCode getStatusCode(int statuscode) { - for (HttpStatusCode sc : httpStatusCodes) { - if (sc.code == statuscode) { - return sc; - } - } - throw (char *) "Invalid status code"; -} diff --git a/src/network/http/HttpStatusCode.h b/src/network/http/HttpStatusCode.h deleted file mode 100644 index 7773af9..0000000 --- a/src/network/http/HttpStatusCode.h +++ /dev/null @@ -1,15 +0,0 @@ - - -#ifndef NECRONDA_HTTP_STATUSCODE -#define NECRONDA_HTTP_STATUSCODE - -typedef struct { - short code; // The status code (e.g. 200) - const char *type; // The status type type (e.g Success) - const char *message; // The status code message (e.g. OK) - const char *description; // The status code description (currently not used) -} HttpStatusCode; - -HttpStatusCode getStatusCode(int statuscode); - -#endif \ No newline at end of file