GithubHelp home page GithubHelp logo

meltwater / served Goto Github PK

View Code? Open in Web Editor NEW
710.0 70.0 175.0 811 KB

A C++11 RESTful web server library

License: MIT License

CMake 6.30% C++ 91.92% Shell 0.01% Ragel 1.17% Python 0.61%
datasift data-platform

served's Introduction

Served

Served Logo

Build Status

Overview

Served is a C++ library for building high performance RESTful web servers.

Served builds upon Boost.ASIO to provide a simple API for developers to create HTTP services in C++.

Features:

  • HTTP 1.1 compatible request parser
  • Middleware / plug-ins
  • Flexible handler API
  • Cross-platform compatible

Installation

Requirements

Building

$ git clone [email protected]:meltwater/served.git
$ mkdir served.build && cd served.build
$ cmake ../served && make

Or, using bazel:

$ git clone [email protected]:meltwater/served.git
$ cd served
$ bazel build :served
$ bazel test :served-test

Getting Started

The most basic example of creating a server and handling a HTTP GET for the path /hello:

#include <served/served.hpp>

int main(int argc, char const* argv[]) {
	// Create a multiplexer for handling requests
	served::multiplexer mux;

	// GET /hello
	mux.handle("/hello")
		.get([](served::response & res, const served::request & req) {
			res << "Hello world!";
		});

	// Create the server and run with 10 handler threads.
	served::net::server server("127.0.0.1", "8080", mux);
	server.run(10);

	return (EXIT_SUCCESS);
}

To test the above example, you could run the following command from a terminal:

$ curl http://localhost:8080/hello -ivh

You can also use named path variables for REST parameters:

mux.handle("/users/{id}")
	.get([](served::response & res, const served::request & req) {
		res << "User: " << req.params["id"];
	});

To test the above example, you could run the following command from a terminal:

$ curl http://localhost:8080/users/dave -ivh

If you need to be more specific, you can specify a pattern to use to validate the parameter:

mux.handle("/users/{id:\\d+}")
	.get([](served::response & res, const served::request & req) {
		res << "id: " << req.params["id"];
	});

To test the above example, you could run the following command from a terminal:

$ curl http://localhost:8080/users/1 -ivh

Method handlers can have arbitrary complexity:

mux.handle("/users/{id:\\d+}/{property}/{value:[a-zA-Z]+")
	.get([](served::response & res, const served::request & req) {
		// handler logic
	});

If you want to automatically log requests, you could use a plugin (or make your own):

#include <served/plugins.hpp>
// ...
mux.use_after(served::plugin::access_log);

You can also access the other elements of the request, including headers and components of the URI:

mux.handle("/posts/{id:\\d+}")
	.post([](served::response & res, const served::request & req) {
		if (req.header("Content-Type") != "application/json") {
			served::response::stock_reply(400, res);
			return;
		}
		res << req.url().fragment();
	});

Compile Options

Option Purpose
SERVED_BUILD_SHARED Build shared library
SERVED_BUILD_STATIC Build static library
SERVED_BUILD_TESTS Build unit test suite
SERVED_BUILD_EXAMPLES Build bundled examples
SERVED_BUILD_DEB Build DEB package (note: you must also have dpkg installed)
SERVED_BUILD_RPM Build RPM package (note: you must also have rpmbuild installed)

System Compatibility

OS Compiler Status
Linux GCC 4.8 Working
OSX Clang 3.5 Working

TODO

  • Chunked encoding support

Contributing

Pull requests are welcome.

Authors

Copyright

See LICENSE.md document

served's People

Contributors

adevress avatar adriandc avatar benjamg avatar bryant1410 avatar cjgdev avatar claudiouzelac avatar jeffail avatar jpihl avatar krzysztofwos avatar luismartingil avatar manashmandal avatar plule-ansys avatar r3mus-n0x avatar rhubbarb avatar stevensona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

served's Issues

PSA: Plan to move to new organisation

Served is going to be migrating to a new organisation at https://github.com/meltwater. I have never done this before but as I understand it the current github URL github.com/datasift/served will automatically forward to the new one at github.com/meltwater/served once the move has happened. I am hoping this means no broken builds for anyone.

If you experience any issues from this move, or have any thoughts to contribute please post them here.

HTTPS support

Is HTTPS support planned? Boost::asio supports SSL, so it seems to me HTTPS is not really out of reach.

Handle same path for POST and get throws Error

Describe the bug

My REST server is using get for getting Informations and POST to update. But if I am using GET and POST for /settings then it will throw a served::request_error when I try to GET Request for Settings
the REST Client says Method not allowed.

Steps to reproduce

void KSecureDesktopServer::initREST() {
   //General Settings
    served::multiplexer& mux = this->multiplexer;
    auto* sender = this;
    mux.handle("/settings").get([this](served::response& res, const served::request& req) {
       this->getSettings(res, req);  //throws an exception
        });
    mux.handle("/settings").post([this](served::response& res, const served::request& req) {
        this->postSettings(res, req); }); // works
    //Get User Info
    mux.handle("/user").get([this](served::response& res, const served::request& req) {
       // this->getUser(res, req); 
        int i = 0;
        res << "SUCCESS"; //works
        }
    );
  // mux.handle("/user").post([this](served::response& res, const served::request& req) {this->postUser(res, req); });
   // mux.handle("/user").put([this](served::response& res, const served::request& req) {this->putUser(res, req); });
    //mux.handle("/user").del([this](served::response& res, const served::request& req) {this->deleteUser(res, req); });
    //Channels
    //mux.handle("/channel").get([this](served::response& res, const served::request& req) {this->getChannel(res, req); });
    //mux.handle("/channel").post([this](served::response& res, const served::request& req) {this->postChannel(res, req); });
    //mux.handle("/channel").put([this](served::response& res, const served::request& req) {this->putChannel(res, req); });
    //mux.handle("/channel").del([this](served::response& res, const served::request& req) {this->deleteChannel(res, req); });

    this->restServer = std::make_unique<served::net::server>("127.0.0.1", "8080", mux);
   
    this->restServer->run(10,false);
}

Multiplexer is a Class member and net::server is a smart pointer.

Expected behavior

can handle both requests

Environment (anything that would help us investigate the bug)

Windows 10 x64
Visual Studio 2019 Community Edition

how to add header Access-Control-Allow-Origin ?

Hi,
I have the following error:
"...has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."

so i need to add the Access-Control-Allow-Origin header, actually I am using the json_data example

How to do that?

Thanks and Regards

I wrote a simple http server using served. Found two issues.

Hello !

I wrote a simple http server using served. Found two issues.

1、Visual studio mode debugging, chrome open url http://localhost:8123/
The program will crash
Crash location: asio\include\asio\buffer.hpp

   ~buffer_debug_check()
   {
#if defined(ASIO_MSVC) && (ASIO_MSVC == 1400)
     // MSVC 8's string iterator checking may crash in a std::string::iterator
     // object's destructor when the iterator points to an already-destroyed
     // std::string object, unless the iterator is cleared first.
     Iter_ = Iterator();
#endif //defined(ASIO_MSVC) && (ASIO_MSVC == 1400)
   }

   Void operator()()
   {
     (void)*iter_;
   }

2、Use release to run normally, but opening the page is very slow, sometimes loading resources fails

Sample code is as follows:

`
#include <served/served.hpp>
#include <served/plugins.hpp>
#include <io.h>
#include <stdio.h>
#include <direct.h>
#include
#include

inline const char * mime_type(const std::string & path)
{
std::string ext;
size_t pos = path.rfind(".");
if (pos != std::string::npos) {
ext = path.substr(pos, path.size() - pos);
}

if (ext == ".txt") {
	return "text/plain";
}
else if (ext == ".html" || ext == ".htm") {
	return "text/html";
}
else if (ext == ".css") {
	return "text/css";
}
else if (ext == ".jpeg" || ext == ".jpg") {
	return "image/jpg";
}
else if (ext == ".png") {
	return "image/png";
}
else if (ext == ".bmp") {
	return "image/bmp";
}
else if (ext == ".gif") {
	return "image/gif";
}
else if (ext == ".svg" || ext == ".svgz") {
	return "image/svg+xml";
}
else if (ext == ".ico") {
	return "image/x-icon";
}
else if (ext == ".json") {
	return "application/json";
}
else if (ext == ".pdf") {
	return "application/pdf";
}
else if (ext == ".js") {
	return "application/javascript";
}
else if (ext == ".xml") {
	return "application/xml";
}
else if (ext == ".xhtml") {
	return "application/xhtml+xml";
}
else if (ext == ".ttf") {
	return "application/x-font-truetype";
}
return nullptr;

}

int main(int argc, char *argv[])
{
served::multiplexer mux;
mux.use_after(served::plugin::access_log);
std::string htdocs = argv[1];

if ((_access(htdocs.c_str(), 0)) == -1) {
	printf("args: tinyhttpd c:\wwwroot");
	return 0;
}

mux.handle("/").get([&](served::response & res, const served::request & req) {
	std::string path = htdocs + req.url().path();
	if (!path.empty() && path.back() == '/') { path += "index.html"; }

	bool is_exist = false;
	if ((_access(path.c_str(), 0)) != -1) {
		std::string out;
		std::ifstream fs(path, std::ios_base::binary);
		fs.seekg(0, std::ios_base::end);
		auto size = fs.tellg();
		fs.seekg(0);
		out.resize(static_cast<size_t>(size));
		fs.read(&out[0], size);
		res.set_body(out);

		is_exist = true;
	}
	
	const char *type = mime_type(path);
	if (type) {
		res.set_header("content-type", type);
	}

	if (is_exist) {
		res.set_status(200);
	} else {
		res.set_status(404);
	}
});

std::cout << "Try this example by opening http://localhost:8123 in a browser" << std::endl;

served::net::server server("0.0.0.0", "8123", mux);
server.run(1);

return (EXIT_SUCCESS);

}
`

Need some help

Hello,
How can I return a json response to a client with served::response & res object. ?

Thank you for helping me.

Long polling

Hi!
I want to process request as long polling service. Already this feature implemets on web-server through
sending first byte of response and wait on server-side of changing some state for finalize response. This hack provide long polling connection of most clients. I was tested this behaviour and receive nothing (against one byte of response) and client (curl, chromium and firefox) was disconnected after 60 seconds (default time of HTTP-connection).
What I do (compile, coding or using) libserved for using long polling?
And if this not supported can you add long polling feature to next release?

Expose server?

Hi,
awesome lib, i'm trying to use ti to expose a json from outside my local network but i can't figure out how to make the server listen to 0.0.0.0, that's what i tried so far:

served::net::server server("192.168.1.193", "8123", mux);

served::net::server server("0.0.0.0", "8123", mux);

but stil I cannot connect from outside localhost

compile example cpp got #include <served/served.hpp> file not found

Have followed the instruction:

  1. installed Boost
  2. Ran command below
    $ git clone [email protected]:meltwater/served.git
    $ mkdir served.build && cd served.build
    $ cmake ../served && make
  3. create a file name a.cpp, whose content is

#include <served/served.hpp>

int main(int argc, char const* argv[]) {
// Create a multiplexer for handling requests
served::multiplexer mux;

// GET /hello
mux.handle("/hello")
	.get([](served::response & res, const served::request & req) {
		res << "Hello world!";
	});

// Create the server and run with 10 handler threads.
served::net::server server("127.0.0.1", "8080", mux);
server.run(10);

return (EXIT_SUCCESS);

}

  1. g++ a.cpp, got

a.cpp:1:10: fatal error: 'served/served.hpp' file not found
#include <served/served.hpp>
^~~~~~~~~~~~~~~~~~~
1 error generated.

Where should I put a.cpp? Maybe it's because of the wrong file location..

Unable to send query parameters

Hi, I am not able to send query parameters. I tried this:

mux.handle("api/moveby/{x}")
	.post([](served::response & res, const served::request & req) {
            std::string x = req.params["x"]; // gets x from path
            std::string y = req.query["y"]; // gets nothing
        }

I am using curl:
curl -d y=2 localhost:8080/api/moveby/1

No matter what I do I can't retrieve it. And I don't really want to use path params.

Served: Stability issues upon Boost ASIO classes destructors

Served server generates random segmentation faults (SIGSEGV) upon cleanups,
due to race conditions throughout the Boost ASIO io_service destructors.

The issue can be proven with the new "stability" example sources (PR #53),
iterating through 1000 creations of served::net::server with explicit stop() calls
and through 1000 creations of served::net::server without calling stop().

The issue can be easily reproduced in CentOS 7.6.1810 or Debian 10 Stable Docker images :

docker run --rm -i --cap-add=SYS_PTRACE -v "${PWD}/..:${PWD}/.." -w "${PWD}" debian:stable bash <<EOF
rm -rf ../served.debian
mkdir -p ../served.debian/
cd ../served.debian/
apt update
apt install -y cmake g++ gdb libboost-dev libboost-system-dev ragel
cmake -DCMAKE_BUILD_TYPE=Debug -DSERVED_BUILD_SHARED=ON -DSERVED_BUILD_STATIC=ON -DSERVED_BUILD_EXAMPLES=ON ../served/
make -j8
gdb -q --batch -ex 'set print thread-events off' -ex 'run' -ex 'bt' ../served/bin/eg_stability
EOF
docker run --rm -i --cap-add=SYS_PTRACE -v "${PWD}/..:${PWD}/.." -w "${PWD}" centos:7.6.1810 bash <<EOF
rm -rf ../served.centos
mkdir -p ../served.centos/
cd ../served.centos/
yum install -y epel-release
yum install -y boost-devel cmake gcc-c++ gdb make ragel
cmake -DCMAKE_BUILD_TYPE=Debug -DSERVED_BUILD_SHARED=ON -DSERVED_BUILD_STATIC=ON -DSERVED_BUILD_EXAMPLES=ON ../served/
make -j8
gdb -q --batch -ex 'set print thread-events off' -ex 'run' -ex 'bt' ../served/bin/eg_stability
EOF

The random segmentation fault's backtrace are :

Thread 1 "eg_stability" received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
#0  0x0000000000000000 in ?? ()
#1  0x00007efebee6c392 in boost::asio::detail::scheduler_operation::destroy (this=0x5601ebed3520) at /usr/include/boost/asio/detail/scheduler_operation.hpp:45
#2  0x00007efebee748b1 in boost::asio::detail::op_queue_access::destroy<boost::asio::detail::scheduler_operation> (o=0x5601ebed3520) at /usr/include/boost/asio/detail/op_queue.hpp:47
#3  0x00007efebee727bc in boost::asio::detail::op_queue<boost::asio::detail::scheduler_operation>::~op_queue (this=0x5601ebed3548, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/op_queue.hpp:81
#4  0x00007efebee72d20 in boost::asio::detail::scheduler::~scheduler (this=0x5601ebed3470, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/scheduler.hpp:38
#5  0x00007efebee72d7a in boost::asio::detail::scheduler::~scheduler (this=0x5601ebed3470, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/scheduler.hpp:38
#6  0x00005601eaa18226 in boost::asio::detail::service_registry::destroy (service=0x5601ebed3470) at /usr/include/boost/asio/detail/impl/service_registry.ipp:110
#7  0x00005601eaa181eb in boost::asio::detail::service_registry::destroy_services (this=0x5601ebed3420) at /usr/include/boost/asio/detail/impl/service_registry.ipp:54
#8  0x00005601eaa182b9 in boost::asio::execution_context::destroy (this=0x7ffd8d1317c0) at /usr/include/boost/asio/impl/execution_context.ipp:46
#9  0x00005601eaa1824f in boost::asio::execution_context::~execution_context (this=0x7ffd8d1317c0, __in_chrg=<optimized out>) at /usr/include/boost/asio/impl/execution_context.ipp:35
#10 0x00007efebee8108c in boost::asio::io_context::~io_context (this=0x7ffd8d1317c0, __in_chrg=<optimized out>) at /usr/include/boost/asio/impl/io_context.ipp:55
#11 0x00007efebee7d5ee in served::net::server::~server (this=0x7ffd8d1317c0, __in_chrg=<optimized out>) at /.../served/src/served/net/server.cpp:73
#12 0x00005601eaa166b8 in test () at /.../served/src/examples/stability/main.cpp:42
#13 0x00005601eaa16844 in main () at /.../served/src/examples/stability/main.cpp:55
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
#0  0x0000000000000000 in ?? ()
#1  0x00007ffb3149c7f0 in boost::asio::detail::task_io_service_operation::destroy (this=0xdc5960) at /usr/include/boost/asio/detail/task_io_service_operation.hpp:42
#2  0x00007ffb314a4dd4 in boost::asio::detail::op_queue_access::destroy<boost::asio::detail::task_io_service_operation> (o=0xdc5960) at /usr/include/boost/asio/detail/op_queue.hpp:47
#3  0x00007ffb314a2eac in boost::asio::detail::op_queue<boost::asio::detail::task_io_service_operation>::~op_queue (this=0xdc5988, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/op_queue.hpp:81
#4  0x00007ffb314aa588 in boost::asio::detail::task_io_service::~task_io_service (this=0xdc5900, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/task_io_service.hpp:38
#5  0x00007ffb314aa5e4 in boost::asio::detail::task_io_service::~task_io_service (this=0xdc5900, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/task_io_service.hpp:38
#6  0x00007ffb3149c5c4 in boost::asio::detail::service_registry::destroy (service=0xdc5900) at /usr/include/boost/asio/detail/impl/service_registry.ipp:101
#7  0x00007ffb3149c4d8 in boost::asio::detail::service_registry::~service_registry (this=0xdc5260, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/impl/service_registry.ipp:45
#8  0x00007ffb3149f583 in boost::asio::io_service::~io_service (this=0x7ffd69c1c610, __in_chrg=<optimized out>) at /usr/include/boost/asio/impl/io_service.ipp:53
#9  0x00007ffb31498fe6 in served::net::server::~server (this=0x7ffd69c1c610, __in_chrg=<optimized out>) at /.../served/src/served/net/server.cpp:73
#10 0x00000000004097e2 in test (stop=true) at /.../served/src/examples/stability/main.cpp:42
#11 0x0000000000409934 in main () at /.../served/src/examples/stability/main.cpp:57
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f86b6600700 (LWP 1571)]
0x00007f86ba92ccc9 in boost::asio::detail::epoll_reactor::run (this=0x0, block=true, ops=...) at /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:382
382       if (timer_fd_ != -1)
#0  0x00007f86ba92ccc9 in boost::asio::detail::epoll_reactor::run (this=0x0, block=true, ops=...) at /usr/include/boost/asio/detail/impl/epoll_reactor.ipp:382
#1  0x00007f86ba92e19d in boost::asio::detail::task_io_service::do_run_one (this=0x9dc8b0, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:396
#2  0x00007f86ba92dc1b in boost::asio::detail::task_io_service::run (this=0x9dc8b0, ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:153
#3  0x00007f86ba92e5cd in boost::asio::io_service::run (this=0x7fff23ccb5a0) at /usr/include/boost/asio/impl/io_service.ipp:59
#4  0x00007f86ba928003 in served::net::server::__lambda0::operator() (__closure=0x9dd370) at /.../served/src/served/net/server.cpp:108
#5  0x00007f86ba92a020 in std::_Bind_simple<served::net::server::run(int, bool)::__lambda0()>::_M_invoke<>(std::_Index_tuple<>) (this=0x9dd370) at /usr/include/c++/4.8.2/functional:1732
#6  0x00007f86ba929f77 in std::_Bind_simple<served::net::server::run(int, bool)::__lambda0()>::operator()(void) (this=0x9dd370) at /usr/include/c++/4.8.2/functional:1720
#7  0x00007f86ba929f10 in std::thread::_Impl<std::_Bind_simple<served::net::server::run(int, bool)::__lambda0()> >::_M_run(void) (this=0x9dd358) at /usr/include/c++/4.8.2/thread:115
#8  0x00007f86ba1a9070 in ?? () from /lib64/libstdc++.so.6
#9  0x00007f86ba402dd5 in start_thread () from /lib64/libpthread.so.0
#10 0x00007f86b990d02d in clone () from /lib64/libc.so.6

Trivial app segfaults when there are more than two routes

This trivial served app below segfaults immediately when there are more than two routes. It works fine as long as only /route1 and /route2 are present, but as soon as I add /route3, it segfaults.

This does not happen if served is built with build type set to Debug. I have also tried building served with build type set to RelWithDebInfo and running the app in a debugger. The debugger pointed out multiplexer.cpp:139 as the culprit, which I find hard to believe since it's just std::vector::push_back:

_handler_candidates.push_back(
	path_handler_candidate(get_segments(path), served::methods_handler(_base_path + path, info), path));

The app:

#include <served/plugins.hpp>
#include <served/served.hpp>

int main(int, char **) {
    served::multiplexer mux;
    mux.use_after(served::plugin::access_log);
    mux.handle("/route1").get([](served::response &response, const served::request &) {
        response.set_body("1");
    });
    mux.handle("/route2").get([](served::response &response, const served::request &) {
        response.set_body("version2");
    });
    mux.handle("/route3").get([](served::response &response, const served::request &) {
        response.set_body("3");
    });
    served::net::server server("127.0.0.1", "8080", mux);
    server.run();
    return 0;
}

If I comment out

    mux.handle("/route3").get([](served::response &response, const served::request &) {
        response.set_body("3");
    });

it works fine, but with three or more routes, boom!

Example segfaults after returning "hello world"

As I was just looking for web server libraries, and found this one, I got the example working, but it immediately segfaults after returning the first request. I am not sure whether this has to do with your library, or the fact I am using later boost, so I'll pass along what CMake spits out.

Here's the messages I get when running CMAKE (accordingly to example)

-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is Clang 8.0.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/local/bin/clang++
-- Check for working CXX compiler: /usr/local/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning at /usr/share/cmake-3.10/Modules/FindBoost.cmake:801 (message):
  New Boost version may have incorrect or missing dependencies and imported
  targets
Call Stack (most recent call first):
  /usr/share/cmake-3.10/Modules/FindBoost.cmake:907 (_Boost_COMPONENT_DEPENDENCIES)
  /usr/share/cmake-3.10/Modules/FindBoost.cmake:1558 (_Boost_MISSING_DEPENDENCIES)
  CMakeLists.txt:71 (FIND_PACKAGE)

-- Boost version: 1.67.0
-- Found the following Boost libraries:
--   system
-- Could NOT find RAGEL (missing: RAGEL_EXECUTABLE) 
-- Could NOT find RAGEL (missing: RAGEL_EXECUTABLE) 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success
-- Configuring done
-- Generating done
-- Build files have been written to: /home/cx/dev/workspace/cpp/nhlanalys/dependencies/servedbuild

It can't be a major error, as it is able to actually return 1 request, using curl. But maybe it is because I am using the wrong Boost version, later clang, or what could it be?

Unable to use same endpoint for different HTTP methods

Hello. I'm using served library and I really like it. However, I've encountered with an issue. It is not possible to use same endpoint for different HTTP methods. It seems like the latter registered method replaces the previous one and I get the following error.

Method not allowed

A simple code to reproduce the issue

// Standard C++ includes 
#include <stdlib.h>
#include <iostream>

// REST
#include <served/served.hpp>
#include <served/plugins.hpp>

int main(int argc, char const* argv[])
{
    try 
    {
        // Create a multiplexer for handling requests
        served::multiplexer mux;

        // GET
        mux.handle("/hello")
            .get([&](served::response& res, const served::request& req) {
                res << "Hello from GET\n";
        });

        // POST
        mux.handle("/hello")
            .post([&](served::response& res, const served::request& req) {
                res << "Hello from POST\n";
        });

        // Register served::plugins::access_log plugin to run after a handler
        mux.use_after(served::plugin::access_log);

        // Create the server and run with 10 handler threads.
        served::net::server server("0.0.0.0", "8080", mux);
        server.run(10);
    } 
    catch (const std::exception& e)
    {
        std::cout << e.what();
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
```
`

Remove RE2 dependency or make it optional

Hi,

I would like to use std::regex instead of RE2, to remove the dependency. Is this something you would be interested in?
I found this issue and it seems std::regex is a bit slower than RE2, is this the reason why you are using RE2?

Alternatively I could make RE2 an optional dependency like Ragel. I just don't want to put in the effort if you don't like the idea.

What do you think?

not work when transfer 1G file

it is working well when I request a file of 100M. But I get 500 error code when I request a file of 1G. It stop at the setbody function

Syntax errors in `request_parser.hpp` when including `served/served.hpp`

I added this as a submodule to another program I'm designing to be a rest api so I don't have to futz with building dependencies separately. The following I added to my cmakelists

include_directories(served/src)

And when I include served/served.hpp and do nothing else - I have just an empty main, I get a ton of syntax errors from request_parser.hpp

served\src\served/request_parser.hpp(59,39): error C2143:  syntax error: missing '}' before 'constant'
served\src\served/request_parser.hpp(59,39): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(59,45): error C2143:  syntax error: missing ';' before '}'
served\src\served/request_parser.hpp(59,45): error C2238:  unexpected token(s) preceding ';'
served\src\served/request_parser.hpp(61,1): error C2059:  syntax error: 'private'
served\src\served/request_parser.hpp(84,1): error C2059:  syntax error: 'protected'
served\src\served/request_parser.hpp(95,36): error C2575:  'http_field': only member functions and bases can be virtual
served\src\served/request_parser.hpp(95,38): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(105,19): error C2575:  'request_method': only member functions and bases can be virtual
served\src\served/request_parser.hpp(105,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(115,19): error C2575:  'request_uri': only member functions and bases can be virtual
served\src\served/request_parser.hpp(115,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(125,19): error C2575:  'fragment': only member functions and bases can be virtual
served\src\served/request_parser.hpp(125,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(135,19): error C2575:  'request_path': only member functions and bases can be virtual
served\src\served/request_parser.hpp(135,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(145,19): error C2575:  'query_string': only member functions and bases can be virtual
served\src\served/request_parser.hpp(145,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(155,19): error C2575:  'http_version': only member functions and bases can be virtual
served\src\served/request_parser.hpp(155,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(165,19): error C2575:  'header_done': only member functions and bases can be virtual
served\src\served/request_parser.hpp(165,21): error C2059:  syntax error: 'constant'
served\src\served/request_parser.hpp(171,17): error C2059:  syntax error: ')'
served\src\served/request_parser.hpp(176,25): error C2588:  '::~request_parser': illegal global destructor
served\src\served/request_parser.hpp(176,27): error C2575:  'request_parser': only member functions and bases can be virtual
served\src\served/request_parser.hpp(176,27): error C4430:  missing type specifier - int assumed. Note: C++ does not support default-int
served\src\served/request_parser.hpp(198,19): error C4430:  missing type specifier - int assumed. Note: C++ does not support default-int
served\src\served/request_parser.hpp(198,19): error C2365:  'served::status': redefinition; previous definition was 'namespace'
served\src\served/status.hpp(112): message :  see declaration of 'served::status'
served\src\served/request_parser.hpp(198,9): error C2146:  syntax error: missing ';' before identifier 'get_status'
served\src\served/request_parser.hpp(201,1): error C2059:  syntax error: '}'
served\src\served/request_parser.hpp(201,1): error C2143:  syntax error: missing ';' before '}'
served\src\served/request_parser_impl.hpp(31,18): error C2143:  syntax error: missing ';' before '{'
served\src\served/request_parser_impl.hpp(31,18): error C2447:  '{': missing function header (old-style formal list?)
served\src\served/net/connection.hpp(62,46): error C3646:  '_request_parser': unknown override specifier
served\src\served/net/connection.hpp(62,46): error C4430:  missing type specifier - int assumed. Note: C++ does not support default-int

I'm building this in Visual Studio 2019. Is Served compatible with on Windows, or it is only Linux and Mac? I assumed since it's using Boost, I could compile it on Windows.

how can I iterate over the available request headers?

As far as I can see the only way to access headers is via request::headers(std::string key).
It would be nice to have a list of available keys.

It would sufficient to expose the const-iterators of request::header_list.
Shall I make a PR ?

How build it?

I really try build it manually. But it is so hard. Firstly i start with cmake (i usually use it). And catch some dependency's errors. Ok, let's go bazel. And again catch errors.
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:97:1: First argument of 'load' must be a label and start with either '//', ':', or '@'. Use --incompatible_load_argument_is_label=false to temporarily disable this check.
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:99:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:101:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:103:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:105:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:107:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:109:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:111:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:113:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:115:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:117:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:119:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:121:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:123:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:125:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:127:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:132:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:137:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:142:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:147:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:152:1: name 're2_test' is not defined (did you mean 'sh_test'?)
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/bitmap256.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/bitstate.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/compile.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/dfa.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/filtered_re2.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/mimics_pcre.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/nfa.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/onepass.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/parse.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/perl_groups.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/prefilter.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/prefilter.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/prefilter_tree.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/prefilter_tree.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/prog.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/prog.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/re2.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/regexp.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/regexp.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/set.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/simplify.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/stringpiece.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/tostring.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/unicode_casefold.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/unicode_casefold.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/unicode_groups.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/unicode_groups.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/walker-inl.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/flags.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/logging.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/mix.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/mutex.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/rune.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/sparse_array.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/sparse_set.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/strutil.cc' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/strutil.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/utf.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:util/util.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/filtered_re2.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/re2.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/set.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/.cache/bazel/_bazel_mrsmith/8a19c473225d56b32acf37c8766fcddb/external/com_googlesource_code_re2/BUILD:11:1: Target '@com_googlesource_code_re2//:re2/stringpiece.h' contains an error and its package is in error and referenced by '@com_googlesource_code_re2//:re2'
ERROR: /home/mrsmith/CLionProjects/test_task/served/BUILD:5:1: Target '@com_googlesource_code_re2//:re2' contains an error and its package is in error and referenced by '//:served'
ERROR: Analysis of target '//:served' failed; build aborted: Loading failed
INFO: Elapsed time: 0.391s
FAILED: Build did NOT complete successfully (0 packages loaded)
How it is build. How resolve dependency's hell.
P.S. I use ubuntu

Configure blocking nature for server run

Hi @Jeffail

All the examples are implemented using a blocking run call.

served::multiplexer mux;
...
served::net::server server("127.0.0.1", "8123", mux);
server.run(10);

I was wondering if you have any suggestion on how to bind and start serving without a blocking call. Similar to:

served::multiplexer mux;
...
served::net::server server("127.0.0.1", "8123", mux);
server.start(10); // maybe do_accept?
// Do other stuff
server.stop();

May I just focus on running this in another thread?

I can maybe look deeper to boost io_service but wanted to have your thoughts first.

Congrats for such a great lib!
Luis

minimal served example fails to pass apache bench test

The server src/examples/hello_world/main.cpp fails to accept any request sent by ApacheBench.
It seems like served does perform the handshake correctly.
Curl and webbrowsers are less fuzzy and report no issue.

 ab -v2 http://localhost:8123/ 
This is ApacheBench, Version 2.3 <$Revision: 1796539 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)...INFO: GET header == 
---
GET /hello HTTP/1.0
Host: localhost:8123
User-Agent: ApacheBench/2.3
Accept: */*


---
apr_socket_recv: Connection refused (111)

Furthermore I also tested with https://github.com/tarekziade/boom
It reports that roughly 10% of requests are answered with errorcode 413.
If I enable -O3 the errorrate increases to above 90%

random chrashes/keep alive

Using msvc 14 and win10 i get some random crashes/heap corruptions. boost version is 1.6.0.
To get it to work in msvc i had to rewrite url::decode and fix some char[dynamicalloc] things in multiplexer. Those rewrites are probably not causing the issue.
If you are interested i can send you the code.
i have done quite the same implementation as you did (boost asio example) in another project with keep alive and dropping the connection when currently active caused kind of the same corruptions (i cannot access this code anymore due to i left this company).

the exception appears here:

server.exe!boost::asio::detail::buffer_cast_helper(const boost::asio::const_buffer & b) Line 276 C++
server.exe!boost::asio::buffer_cast<void const * __ptr64>(const boost::asio::const_buffer & b) Line 435 C++
server.exe!boost::asio::detail::buffer_sequence_adapterboost::asio::const_buffer,boost::asio::const_buffers_1::validate(const boost::asio::const_buffers_1 & buffer_sequence) Line 255 C++
server.exe!boost::asio::detail::win_iocp_socket_send_opboost::asio::const_buffers_1,boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp >,boost::asio::const_buffers_1,boost::asio::detail::transfer_all_t,void (boost::system::error_code, unsigned __int64) > >::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, const boost::system::error_code & result_ec, unsigned __int64 bytes_transferred) Line 74 C++
server.exe!boost::asio::detail::win_iocp_operation::complete(boost::asio::detail::win_iocp_io_service & owner, const boost::system::error_code & ec, unsigned __int64 bytes_transferred) Line 47 C++
server.exe!boost::asio::detail::win_iocp_io_service::do_one(bool block, boost::system::error_code & ec) Line 406 C++
server.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec) Line 164 C++
server.exe!boost::asio::io_service::run() Line 59 C++
server.exe!served::net::server::run::__l7::() Line 86 C++

In addition to that i dont see any implementation for http keep alive. Please correct me if iam wrong.

crash/kill/restart will complain "bind: Address already in use"

After killing, I restart the server and get the following error.

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
  what():  bind: Address already in use
Aborted (core dumped)
make: *** [run] Error 134

Looks like socket opt is not set correctly to allow reuse.

Issues compiling hello world

After running the install steps with cmake from the README's building steps, i am met with the below errors:

/usr/bin/ld: /tmp/ccb5Bytw.o: in function `main::{lambda(served::response&, served::request const&)#1}::operator()(served::response&, served::request const&) const':
main.cpp:(.text+0x76): undefined reference to `served::response::operator<<(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: /tmp/ccb5Bytw.o: in function `main':
main.cpp:(.text+0x11a): undefined reference to `served::multiplexer::multiplexer()'
/usr/bin/ld: main.cpp:(.text+0x192): undefined reference to `served::multiplexer::handle(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: main.cpp:(.text+0x1b6): undefined reference to `served::methods_handler::get(std::function<void (served::response&, served::request const&)>)'
/usr/bin/ld: main.cpp:(.text+0x2d3): undefined reference to `served::net::server::server(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, served::multiplexer&, bool)'
/usr/bin/ld: main.cpp:(.text+0x328): undefined reference to `served::net::server::run(int, bool)'
/usr/bin/ld: /tmp/ccb5Bytw.o: in function `served::net::server::~server()':
main.cpp:(.text._ZN6served3net6serverD2Ev[_ZN6served3net6serverD5Ev]+0x2e): undefined reference to `served::net::connection_manager::~connection_manager()'
collect2: error: ld returned 1 exit status

seems like it is a linker error? i am compiling with g++ -std=c++11 main.cpp -Iinclude -Iserved/src/served -lboost_system -lpthread from the directory i cloned the served project into.

i will try building with blaze tomorrow to see if this resolves it

Conan package

Hello,
Do you know about Conan?
Conan is modern dependency manager for C++. And will be great if your library will be available via package manager for other developers.

Here you can find example, how you can create package for the library.

If you have any questions, just ask :-)

Would you or anybody else be interested in helping out with Restbed?

Tagline: The Restbed framework brings asynchronous RESTful functionality to C++11 applications.

It's a little bit further down the development road than Served and quite feature rich. Our aim is to bring HTTP 2 functionality with the ability to introduce additional HTTP protocols via dependency injection. e.g

Service service;
service.add_protocol( "HTTP/2", instance );
service.add_protocol( "SPDY", instance );

Get IP Address of Request

Hello,

Is there a way at the moment to get the IP address of the request WITHOUT using ::header(const std::string&)

If not, could this be added in?

Cannot set multiple cookies because set-header overwrites set-cookie

Hi,

The Set-Cookie HTTP response header is used to send cookies from the server to the user agent, so the user agent can send them back to the server later.

The only way to set headers in served is to use the function set_header() from the request object, like so

res.set_header("Set-Cookie","foo=1");

this way, when the client get the response from the request, it gets the Cookie "foo" with a value of 1

The problem is that, in a specific request, the server may set two or more cookies, like foo=1 and bar=2,

but running

res.set_header("Set-Cookie","foo=1");
res.set_header("Set-Cookie","bar=2");

actually only sends the last key-value pair bar=2, because the request class is using a std::unordered_map<std::string, std::string> header_list

so the last value overwrites the first

also it seems that passing two cookies into one Set-Cookie is not supported on Chrome, so

res.set_header("Set-Cookie","foo=1; bar=2");
or
res.set_header("Set-Cookie","foo=1, bar=2");

does not work

Building Served Throws Error

I think the rename of LICENSE --> LICENSE.md a couple days ago messed up the cmake build a bit. Compiling gives the following error:

CMake Error at /usr/share/cmake-2.8/Modules/CPack.cmake:395 (message):
CPack license resource file: "/home/jswenski/served/LICENSE" could
not be found.
Call Stack (most recent call first):
/usr/share/cmake-2.8/Modules/CPack.cmake:400 (cpack_check_file_exists)
CMakeLists.txt:127 (INCLUDE)

Renaming LICENSE.md back to LICENSE fixes the problem

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.