Files @ 8f1f90064cf0
Branch filter:

Location: libtransport.git/3rdparty/cpprestsdk/include/cpprest/details/http_server_asio.h - annotation

Jan Kaluza
Remove O2, add cpprestsdk
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
8f1f90064cf0
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#endif
#include <boost/asio.hpp>
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#include <boost/bind.hpp>
#include <set>
#include "pplx/threadpool.h"
#include "cpprest/details/http_server.h"

namespace web
{
namespace http
{
namespace experimental
{
namespace listener
{

class http_linux_server;

namespace details
{

struct linux_request_context : web::http::details::_http_server_context
{
    linux_request_context(){}

    pplx::task_completion_event<void> m_response_completed;

private:
    linux_request_context(const linux_request_context&);
    linux_request_context& operator=(const linux_request_context&);
};

class hostport_listener;

class connection
{
private:
    std::unique_ptr<boost::asio::ip::tcp::socket> m_socket;
    boost::asio::streambuf m_request_buf;
    boost::asio::streambuf m_response_buf;
    http_linux_server* m_p_server;
    hostport_listener* m_p_parent;
    http_request m_request;
    size_t m_read, m_write;
    size_t m_read_size, m_write_size;
    bool m_close;
    bool m_chunked;
    std::atomic<int> m_refs; // track how many threads are still referring to this
    
public:
    connection(std::unique_ptr<boost::asio::ip::tcp::socket> socket, http_linux_server* server, hostport_listener* parent)
    : m_socket(std::move(socket))
    , m_request_buf()
    , m_response_buf()
    , m_p_server(server)
    , m_p_parent(parent)
    , m_refs(1)
    {
        start_request_response();
    }

    connection(const connection&) = delete;
    connection& operator=(const connection&) = delete;

    void close();

private:
    void start_request_response();
    void handle_http_line(const boost::system::error_code& ec);
    void handle_headers();
    void handle_body(const boost::system::error_code& ec);
    void handle_chunked_header(const boost::system::error_code& ec);
    void handle_chunked_body(const boost::system::error_code& ec, int toWrite);
    void dispatch_request_to_listener();
    void do_response(bool bad_request);
    template <typename ReadHandler>
    void async_read_until_buffersize(size_t size, const ReadHandler &handler);
    void async_process_response(http_response response);
    void cancel_sending_response_with_error(const http_response &response, const std::exception_ptr &);
    void handle_headers_written(const http_response &response, const boost::system::error_code& ec);
    void handle_write_large_response(const http_response &response, const boost::system::error_code& ec);
    void handle_write_chunked_response(const http_response &response, const boost::system::error_code& ec);
    void handle_response_written(const http_response &response, const boost::system::error_code& ec);
    void finish_request_response();
};

class hostport_listener
{
private:
    friend class connection;

    std::unique_ptr<boost::asio::ip::tcp::acceptor> m_acceptor;
    std::map<std::string, web::http::experimental::listener::details::http_listener_impl* > m_listeners;
    pplx::extensibility::reader_writer_lock_t m_listeners_lock;

    pplx::extensibility::recursive_lock_t m_connections_lock;
    pplx::extensibility::event_t m_all_connections_complete;
    std::set<connection*> m_connections;

    http_linux_server* m_p_server;

    std::string m_host;
    std::string m_port;

public:
     hostport_listener(http_linux_server* server, const std::string& hostport)
    : m_acceptor()
    , m_listeners()
    , m_listeners_lock()
    , m_connections_lock()
    , m_connections()
    , m_p_server(server)
    {
        m_all_connections_complete.set();

        std::istringstream hostport_in(hostport);
        hostport_in.imbue(std::locale::classic());

        std::getline(hostport_in, m_host, ':');
        std::getline(hostport_in, m_port);
    }

    ~hostport_listener()
    {
        stop();
    }

    void start();
    void stop();

    void add_listener(const std::string& path, web::http::experimental::listener::details::http_listener_impl* listener);
    void remove_listener(const std::string& path, web::http::experimental::listener::details::http_listener_impl* listener);

private:
    void on_accept(boost::asio::ip::tcp::socket* socket, const boost::system::error_code& ec);

};

}

struct iequal_to
{
    bool operator()(const std::string& left, const std::string& right) const
    {
        return boost::ilexicographical_compare(left, right);
    }
};

class http_linux_server : public web::http::experimental::details::http_server
{
private:
    friend class http::experimental::listener::details::connection;

    pplx::extensibility::reader_writer_lock_t m_listeners_lock;
    std::map<std::string, std::unique_ptr<details::hostport_listener>, iequal_to> m_listeners;
    std::unordered_map<details::http_listener_impl *, std::unique_ptr<pplx::extensibility::reader_writer_lock_t>> m_registered_listeners;
    bool m_started;

public:
    http_linux_server()
    : m_listeners_lock()
    , m_listeners()
    , m_started(false)
    {}

    ~http_linux_server()
    {
        stop();
    }

    virtual pplx::task<void> start();
    virtual pplx::task<void> stop();

    virtual pplx::task<void> register_listener(web::http::experimental::listener::details::http_listener_impl* listener);
    virtual pplx::task<void> unregister_listener(web::http::experimental::listener::details::http_listener_impl* listener);

    pplx::task<void> respond(http::http_response response);
};

}}}}