Stub code for http server
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user