eidheim / Simple-Web-Server

A very simple, fast, multithreaded, platform independent HTTP and HTTPS server and client library implemented using C++11 and Boost.Asio. Created to be an easy way to make REST resources available from C++ applications.
MIT License
2.62k stars 758 forks source link

Richer API #99

Open aaalgo opened 7 years ago

aaalgo commented 7 years ago

I appreciate the author's philosophy on keeping things simple, but it seems this project is becoming the most promising open-source embedded C++ web server on the web and it is inevitable that people will ask for more. Datasift's served has failed me on serving very large files and is becoming less actively maintained, this is now my only choice and I have to post my request here. I think it will be much better if the author could extend the API to allow:

I need these so badly that I implemented my own wrappers at https://github.com/aaalgo/Simple-Web-Extra . But other than being partially functional and meeting my immediate needs, my solution is rather ugly. I would very much like to see native APIs for the above.

eidheim commented 7 years ago

Regarding registering handlers once to run both HTTP and HTTPS: I think maybe you can write a resource function and copy it to both a HTTP resource and HTTPS resource as long as you use (auto response, auto request) in the lambda parameters.

My initial thought is that authentication, caching, upload handling, and compression is dependent on the solution at hand, and there is no approach that is best for every possible solution. Though, we could maybe add request parsing as a util function (like the crypto class), but some work would be needed to make this a good general method. We could maybe work this out in a separate pull request/issue concerning request parsing alone.

Nevertheless, I'm thankful for your insight and discussion is welcome.

SethHamilton commented 7 years ago

@aaalgo I have a template function in a handler class I made called HttpServe, please forgive my horrible regex.

template<typename T>
void HttpServe::mapEndpoints(T& server)
{
    /* match:
     *   query/<some_table_name>
     *   query/<some_table_name>/
     *   query/<some_table_name>#
     *   query/<some_table_name>?
     *   query/<some_table_name>/anything_else/
     */   
    server.resource[R"(^/query/([a-zA-Z0-9_]+)(\/|\?|\#|)+(?:.*))"]["GET"] = [](std::shared_ptr<T::Response> response, std::shared_ptr<T::Request> request) {
        std::string text = "{\"status\":\"" + std::string(request->path_match[1]) + "\"";
        response->write(text);
    };

    // default
    server.resource["^/status$"]["GET"] = [](std::shared_ptr<T::Response> response, std::shared_ptr<T::Request> request) {
        response->write("{\"status\":\"OK\"");
    };
}

Right after you make your server object (regular or ssl) you can call the function like this:

mapEndpoints(server);