Stub code for http server
This commit is contained in:
parent
43deaba547
commit
44f37a4140
56
ixwebsocket/IXHttp.cpp
Normal file
56
ixwebsocket/IXHttp.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* IXHttp.cpp
|
||||||
|
* Author: Benjamin Sergeant
|
||||||
|
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IXHttp.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ix
|
||||||
|
{
|
||||||
|
std::string Http::trim(const std::string& str)
|
||||||
|
{
|
||||||
|
std::string out(str);
|
||||||
|
out.erase(std::remove(out.begin(), out.end(), ' '), out.end());
|
||||||
|
out.erase(std::remove(out.begin(), out.end(), '\r'), out.end());
|
||||||
|
out.erase(std::remove(out.begin(), out.end(), '\n'), out.end());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<std::string, std::string, std::string> Http::parseRequestLine(const std::string& line)
|
||||||
|
{
|
||||||
|
// Request-Line = Method SP Request-URI SP HTTP-Version CRLF
|
||||||
|
std::string token;
|
||||||
|
std::stringstream tokenStream(line);
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
|
||||||
|
// Split by ' '
|
||||||
|
while (std::getline(tokenStream, token, ' '))
|
||||||
|
{
|
||||||
|
tokens.push_back(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string method;
|
||||||
|
if (tokens.size() >= 1)
|
||||||
|
{
|
||||||
|
method = trim(tokens[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string requestUri;
|
||||||
|
if (tokens.size() >= 2)
|
||||||
|
{
|
||||||
|
requestUri = trim(tokens[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string httpVersion;
|
||||||
|
if (tokens.size() >= 3)
|
||||||
|
{
|
||||||
|
httpVersion = trim(tokens[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(method, requestUri, httpVersion);
|
||||||
|
}
|
||||||
|
}
|
93
ixwebsocket/IXHttp.h
Normal file
93
ixwebsocket/IXHttp.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* IXHttp.h
|
||||||
|
* Author: Benjamin Sergeant
|
||||||
|
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IXWebSocketHttpHeaders.h"
|
||||||
|
#include "IXProgressCallback.h"
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace ix
|
||||||
|
{
|
||||||
|
enum class HttpErrorCode : int
|
||||||
|
{
|
||||||
|
Ok = 0,
|
||||||
|
CannotConnect = 1,
|
||||||
|
Timeout = 2,
|
||||||
|
Gzip = 3,
|
||||||
|
UrlMalformed = 4,
|
||||||
|
CannotCreateSocket = 5,
|
||||||
|
SendError = 6,
|
||||||
|
ReadError = 7,
|
||||||
|
CannotReadStatusLine = 8,
|
||||||
|
MissingStatus = 9,
|
||||||
|
HeaderParsingError = 10,
|
||||||
|
MissingLocation = 11,
|
||||||
|
TooManyRedirects = 12,
|
||||||
|
ChunkReadError = 13,
|
||||||
|
CannotReadBody = 14,
|
||||||
|
Invalid = 100
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HttpResponse
|
||||||
|
{
|
||||||
|
int statusCode;
|
||||||
|
HttpErrorCode errorCode;
|
||||||
|
WebSocketHttpHeaders headers;
|
||||||
|
std::string payload;
|
||||||
|
std::string errorMsg;
|
||||||
|
uint64_t uploadSize;
|
||||||
|
uint64_t downloadSize;
|
||||||
|
|
||||||
|
HttpResponse(int s = 0,
|
||||||
|
const HttpErrorCode& c = HttpErrorCode::Ok,
|
||||||
|
const WebSocketHttpHeaders& h = WebSocketHttpHeaders(),
|
||||||
|
const std::string& p = std::string(),
|
||||||
|
const std::string& e = std::string(),
|
||||||
|
uint64_t u = 0,
|
||||||
|
uint64_t d = 0)
|
||||||
|
: statusCode(s)
|
||||||
|
, errorCode(c)
|
||||||
|
, headers(h)
|
||||||
|
, payload(p)
|
||||||
|
, errorMsg(e)
|
||||||
|
, uploadSize(u)
|
||||||
|
, downloadSize(d)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using HttpResponsePtr = std::shared_ptr<HttpResponse>;
|
||||||
|
using HttpParameters = std::map<std::string, std::string>;
|
||||||
|
using Logger = std::function<void(const std::string&)>;
|
||||||
|
using OnResponseCallback = std::function<void(const HttpResponsePtr&)>;
|
||||||
|
|
||||||
|
struct HttpRequestArgs
|
||||||
|
{
|
||||||
|
std::string url;
|
||||||
|
std::string verb;
|
||||||
|
WebSocketHttpHeaders extraHeaders;
|
||||||
|
std::string body;
|
||||||
|
int connectTimeout;
|
||||||
|
int transferTimeout;
|
||||||
|
bool followRedirects;
|
||||||
|
int maxRedirects;
|
||||||
|
bool verbose;
|
||||||
|
bool compress;
|
||||||
|
Logger logger;
|
||||||
|
OnProgressCallback onProgressCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
using HttpRequestArgsPtr = std::shared_ptr<HttpRequestArgs>;
|
||||||
|
|
||||||
|
class Http
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::tuple<std::string, std::string, std::string> parseRequestLine(const std::string& line);
|
||||||
|
static std::string trim(const std::string& str);
|
||||||
|
};
|
||||||
|
}
|
86
ixwebsocket/IXHttpServer.cpp
Normal file
86
ixwebsocket/IXHttpServer.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* IXHttpServer.cpp
|
||||||
|
* Author: Benjamin Sergeant
|
||||||
|
* Copyright (c) 2019 Machine Zone, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IXHttpServer.h"
|
||||||
|
#include "IXSocketConnect.h"
|
||||||
|
#include "IXSocketFactory.h"
|
||||||
|
#include "IXNetSystem.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <future>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace ix
|
||||||
|
{
|
||||||
|
const int HttpServer::kDefaultHandShakeTimeoutSecs(3); // 3 seconds
|
||||||
|
|
||||||
|
HttpServer::HttpServer(int port,
|
||||||
|
const std::string& host,
|
||||||
|
int backlog,
|
||||||
|
size_t maxConnections,
|
||||||
|
int handshakeTimeoutSecs) : SocketServer(port, host, backlog, maxConnections),
|
||||||
|
_handshakeTimeoutSecs(handshakeTimeoutSecs),
|
||||||
|
_connectedClientsCount(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServer::~HttpServer()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpServer::stop()
|
||||||
|
{
|
||||||
|
stopAcceptingConnections();
|
||||||
|
|
||||||
|
// FIXME: cancelling / closing active clients ...
|
||||||
|
|
||||||
|
SocketServer::stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpServer::setOnConnectionCallback(const OnConnectionCallback& callback)
|
||||||
|
{
|
||||||
|
_onConnectionCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HttpServer::handleConnection(
|
||||||
|
int fd,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState)
|
||||||
|
{
|
||||||
|
_connectedClientsCount++;
|
||||||
|
|
||||||
|
std::string errorMsg;
|
||||||
|
auto socket = createSocket(fd, errorMsg);
|
||||||
|
|
||||||
|
std::cout << "I was here" << std::endl;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Parse request
|
||||||
|
auto httpRequest = std::make_shared<HttpRequestArgs>();
|
||||||
|
|
||||||
|
// Execute callback which should produce a response
|
||||||
|
auto response = _onConnectionCallback(httpRequest, connectionState);
|
||||||
|
|
||||||
|
// Write the response to the socket
|
||||||
|
if (!socket->writeBytes(response, nullptr))
|
||||||
|
{
|
||||||
|
std::string errorMsg("Cannot send request");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
logInfo("HttpServer::handleConnection() done");
|
||||||
|
connectionState->setTerminated();
|
||||||
|
|
||||||
|
_connectedClientsCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t HttpServer::getConnectedClientsCount()
|
||||||
|
{
|
||||||
|
return _connectedClientsCount;
|
||||||
|
}
|
||||||
|
}
|
50
ixwebsocket/IXHttpServer.h
Normal file
50
ixwebsocket/IXHttpServer.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* IXHttpServer.h
|
||||||
|
* Author: Benjamin Sergeant
|
||||||
|
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IXSocketServer.h"
|
||||||
|
#include "IXWebSocket.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <utility> // pair
|
||||||
|
|
||||||
|
namespace ix
|
||||||
|
{
|
||||||
|
using OnConnectionCallback =
|
||||||
|
std::function<void(std::shared_ptr<WebSocket>, std::shared_ptr<ConnectionState>)>;
|
||||||
|
|
||||||
|
class HttpServer final : public SocketServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HttpServer(int port = SocketServer::kDefaultPort,
|
||||||
|
const std::string& host = SocketServer::kDefaultHost,
|
||||||
|
int backlog = SocketServer::kDefaultTcpBacklog,
|
||||||
|
size_t maxConnections = SocketServer::kDefaultMaxConnections,
|
||||||
|
int handshakeTimeoutSecs = HttpServer::kDefaultHandShakeTimeoutSecs);
|
||||||
|
virtual ~HttpServer();
|
||||||
|
virtual void stop() final;
|
||||||
|
|
||||||
|
void setOnConnectionCallback(const OnConnectionCallback& callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Member variables
|
||||||
|
int _handshakeTimeoutSecs;
|
||||||
|
OnConnectionCallback _onConnectionCallback;
|
||||||
|
const static int kDefaultHandShakeTimeoutSecs;
|
||||||
|
std::atomic<int> _connectedClientsCount;
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
virtual void handleConnection(int fd,
|
||||||
|
std::shared_ptr<ConnectionState> connectionState) final;
|
||||||
|
virtual size_t getConnectedClientsCount() final;
|
||||||
|
};
|
||||||
|
} // namespace ix
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user