Sfoglia il codice sorgente

删除一些不用代码

tanghai 14 anni fa
parent
commit
c667d7f0a1

+ 0 - 187
Src/Experimental/chat/chat_message.cc

@@ -1,187 +0,0 @@
-//
-// chat_client.cc
-// ~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <cstdlib>
-#include <deque>
-#include <iostream>
-#include <boost/bind.hpp>
-#include <boost/asio.hpp>
-#include <boost/thread.hpp>
-#include "Experimental/chat/chat_message.h"
-
-using boost::asio::ip::tcp;
-
-typedef std::deque<chat_message> chat_message_queue;
-
-class chat_client
-{
-public:
-	chat_client(boost::asio::io_service& io_service,
-			tcp::resolver::iterator endpoint_iterator) :
-		io_service_(io_service), socket_(io_service)
-	{
-		tcp::endpoint endpoint = *endpoint_iterator;
-		socket_.async_connect(endpoint, boost::bind(
-				&chat_client::handle_connect, this,
-				boost::asio::placeholders::error, ++endpoint_iterator));
-	}
-
-	void write(const chat_message& msg)
-	{
-		io_service_.post(boost::bind(&chat_client::do_write, this, msg));
-	}
-
-	void close()
-	{
-		io_service_.post(boost::bind(&chat_client::do_close, this));
-	}
-
-private:
-
-	void handle_connect(const boost::system::error_code& error,
-			tcp::resolver::iterator endpoint_iterator)
-	{
-		if (!error)
-		{
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.data(), chat_message::header_length),
-					boost::bind(&chat_client::handle_read_header, this,
-							boost::asio::placeholders::error));
-		}
-		else if (endpoint_iterator != tcp::resolver::iterator())
-		{
-			socket_.close();
-			tcp::endpoint endpoint = *endpoint_iterator;
-			socket_.async_connect(endpoint, boost::bind(
-					&chat_client::handle_connect, this,
-					boost::asio::placeholders::error, ++endpoint_iterator));
-		}
-	}
-
-	void handle_read_header(const boost::system::error_code& error)
-	{
-		if (!error && read_msg_.decode_header())
-		{
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.body(), read_msg_.body_length()), boost::bind(
-					&chat_client::handle_read_body, this,
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			do_close();
-		}
-	}
-
-	void handle_read_body(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			std::cout.write(read_msg_.body(), read_msg_.body_length());
-			std::cout << "\n";
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.data(), chat_message::header_length),
-					boost::bind(&chat_client::handle_read_header, this,
-							boost::asio::placeholders::error));
-		}
-		else
-		{
-			do_close();
-		}
-	}
-
-	void do_write(chat_message msg)
-	{
-		bool write_in_progress = !write_msgs_.empty();
-		write_msgs_.push_back(msg);
-		if (!write_in_progress)
-		{
-			boost::asio::async_write(socket_, boost::asio::buffer(
-					write_msgs_.front().data(), write_msgs_.front().length()),
-					boost::bind(&chat_client::handle_write, this,
-							boost::asio::placeholders::error));
-		}
-	}
-
-	void handle_write(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			write_msgs_.pop_front();
-			if (!write_msgs_.empty())
-			{
-				boost::asio::async_write(socket_, boost::asio::buffer(
-						write_msgs_.front().data(),
-						write_msgs_.front().length()), boost::bind(
-						&chat_client::handle_write, this,
-						boost::asio::placeholders::error));
-			}
-		}
-		else
-		{
-			do_close();
-		}
-	}
-
-	void do_close()
-	{
-		socket_.close();
-	}
-
-private:
-	boost::asio::io_service& io_service_;
-	tcp::socket socket_;
-	chat_message read_msg_;
-	chat_message_queue write_msgs_;
-};
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 3)
-		{
-			std::cerr << "Usage: chat_client <host> <port>\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		tcp::resolver resolver(io_service);
-		tcp::resolver::query query(argv[1], argv[2]);
-		tcp::resolver::iterator iterator = resolver.resolve(query);
-
-		chat_client c(io_service, iterator);
-
-		boost::thread
-				t(boost::bind(&boost::asio::io_service::run, &io_service));
-
-		char line[chat_message::max_body_length + 1];
-		while (std::cin.getline(line, chat_message::max_body_length + 1))
-		{
-			using namespace std;
-			// For strlen and memcpy.
-			chat_message msg;
-			msg.body_length(strlen(line));
-			memcpy(msg.body(), line, msg.body_length());
-			msg.encode_header();
-			c.write(msg);
-		}
-
-		c.close();
-		t.join();
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 101
Src/Experimental/chat/chat_message.h

@@ -1,101 +0,0 @@
-//
-// chat_message.hpp
-// ~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_CHAT_MESSAGE_H
-#define EXPERIMENTAL_CHAT_MESSAGE_H
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-class chat_message
-{
-public:
-	enum
-	{
-		header_length = 4
-	};
-	enum
-	{
-		max_body_length = 512
-	};
-
-	chat_message() :
-		body_length_(0)
-	{
-	}
-
-	const char* data() const
-	{
-		return data_;
-	}
-
-	char* data()
-	{
-		return data_;
-	}
-
-	size_t length() const
-	{
-		return header_length + body_length_;
-	}
-
-	const char* body() const
-	{
-		return data_ + header_length;
-	}
-
-	char* body()
-	{
-		return data_ + header_length;
-	}
-
-	size_t body_length() const
-	{
-		return body_length_;
-	}
-
-	void body_length(size_t length)
-	{
-		body_length_ = length;
-		if (body_length_ > max_body_length)
-			body_length_ = max_body_length;
-	}
-
-	bool decode_header()
-	{
-		using namespace std;
-		// For strncat and atoi.
-		char header[header_length + 1] = "";
-		strncat(header, data_, header_length);
-		body_length_ = atoi(header);
-		if (body_length_ > max_body_length)
-		{
-			body_length_ = 0;
-			return false;
-		}
-		return true;
-	}
-
-	void encode_header()
-	{
-		using namespace std;
-		// For sprintf and memcpy.
-		char header[header_length + 1] = "";
-		sprintf(header, "%4d", body_length_);
-		memcpy(data_, header, header_length);
-	}
-
-private:
-	char data_[header_length + max_body_length];
-	size_t body_length_;
-};
-
-#endif // EXPERIMENTAL_CHAT_MESSAGE_H

+ 0 - 247
Src/Experimental/chat/chat_server.cc

@@ -1,247 +0,0 @@
-//
-// chat_server.cpp
-// ~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <algorithm>
-#include <cstdlib>
-#include <deque>
-#include <iostream>
-#include <list>
-#include <set>
-#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/asio.hpp>
-#include "Experimental/chat/chat_message.h"
-
-using boost::asio::ip::tcp;
-
-//----------------------------------------------------------------------
-
-typedef std::deque<chat_message> chat_message_queue;
-
-//----------------------------------------------------------------------
-
-class chat_participant
-{
-public:
-	virtual ~chat_participant()
-	{
-	}
-	virtual void deliver(const chat_message& msg) = 0;
-};
-
-typedef boost::shared_ptr<chat_participant> chat_participant_ptr;
-
-//----------------------------------------------------------------------
-
-class chat_room
-{
-public:
-	void join(chat_participant_ptr participant)
-	{
-		participants_.insert(participant);
-		std::for_each(recent_msgs_.begin(), recent_msgs_.end(), boost::bind(
-				&chat_participant::deliver, participant, _1));
-	}
-
-	void leave(chat_participant_ptr participant)
-	{
-		participants_.erase(participant);
-	}
-
-	void deliver(const chat_message& msg)
-	{
-		recent_msgs_.push_back(msg);
-		while (recent_msgs_.size() > max_recent_msgs)
-			recent_msgs_.pop_front();
-
-		std::for_each(participants_.begin(), participants_.end(), boost::bind(
-				&chat_participant::deliver, _1, boost::ref(msg)));
-	}
-
-private:
-	std::set<chat_participant_ptr> participants_;
-	enum
-	{
-		max_recent_msgs = 100
-	};
-	chat_message_queue recent_msgs_;
-};
-
-//----------------------------------------------------------------------
-
-class chat_session: public chat_participant,
-		public boost::enable_shared_from_this<chat_session>
-{
-public:
-	chat_session(boost::asio::io_service& io_service, chat_room& room) :
-		socket_(io_service), room_(room)
-	{
-	}
-
-	tcp::socket& socket()
-	{
-		return socket_;
-	}
-
-	void start()
-	{
-		room_.join(shared_from_this());
-		boost::asio::async_read(socket_, boost::asio::buffer(read_msg_.data(),
-				chat_message::header_length), boost::bind(
-				&chat_session::handle_read_header, shared_from_this(),
-				boost::asio::placeholders::error));
-	}
-
-	void deliver(const chat_message& msg)
-	{
-		bool write_in_progress = !write_msgs_.empty();
-		write_msgs_.push_back(msg);
-		if (!write_in_progress)
-		{
-			boost::asio::async_write(socket_, boost::asio::buffer(
-					write_msgs_.front().data(), write_msgs_.front().length()),
-					boost::bind(&chat_session::handle_write,
-							shared_from_this(),
-							boost::asio::placeholders::error));
-		}
-	}
-
-	void handle_read_header(const boost::system::error_code& error)
-	{
-		if (!error && read_msg_.decode_header())
-		{
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.body(), read_msg_.body_length()), boost::bind(
-					&chat_session::handle_read_body, shared_from_this(),
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			room_.leave(shared_from_this());
-		}
-	}
-
-	void handle_read_body(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			room_.deliver(read_msg_);
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.data(), chat_message::header_length),
-					boost::bind(&chat_session::handle_read_header,
-							shared_from_this(),
-							boost::asio::placeholders::error));
-		}
-		else
-		{
-			room_.leave(shared_from_this());
-		}
-	}
-
-	void handle_write(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			write_msgs_.pop_front();
-			if (!write_msgs_.empty())
-			{
-				boost::asio::async_write(socket_, boost::asio::buffer(
-						write_msgs_.front().data(),
-						write_msgs_.front().length()), boost::bind(
-						&chat_session::handle_write, shared_from_this(),
-						boost::asio::placeholders::error));
-			}
-		}
-		else
-		{
-			room_.leave(shared_from_this());
-		}
-	}
-
-private:
-	tcp::socket socket_;
-	chat_room& room_;
-	chat_message read_msg_;
-	chat_message_queue write_msgs_;
-};
-
-typedef boost::shared_ptr<chat_session> chat_session_ptr;
-
-//----------------------------------------------------------------------
-
-class chat_server
-{
-public:
-	chat_server(boost::asio::io_service& io_service,
-			const tcp::endpoint& endpoint) :
-		io_service_(io_service), acceptor_(io_service, endpoint)
-	{
-		chat_session_ptr new_session(new chat_session(io_service_, room_));
-		acceptor_.async_accept(new_session->socket(), boost::bind(
-				&chat_server::handle_accept, this, new_session,
-				boost::asio::placeholders::error));
-	}
-
-	void handle_accept(chat_session_ptr session,
-			const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			session->start();
-			chat_session_ptr new_session(new chat_session(io_service_, room_));
-			acceptor_.async_accept(new_session->socket(), boost::bind(
-					&chat_server::handle_accept, this, new_session,
-					boost::asio::placeholders::error));
-		}
-	}
-
-private:
-	boost::asio::io_service& io_service_;
-	tcp::acceptor acceptor_;
-	chat_room room_;
-};
-
-typedef boost::shared_ptr<chat_server> chat_server_ptr;
-typedef std::list<chat_server_ptr> chat_server_list;
-
-//----------------------------------------------------------------------
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc < 2)
-		{
-			std::cerr << "Usage: chat_server <port> [<port> ...]\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		chat_server_list servers;
-		for (int i = 1; i < argc; ++i)
-		{
-			using namespace std;
-			// For atoi.
-			tcp::endpoint endpoint(tcp::v4(), atoi(argv[i]));
-			chat_server_ptr server(new chat_server(io_service, endpoint));
-			servers.push_back(server);
-		}
-
-		io_service.run();
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 220
Src/Experimental/chat/posix_chat_client.cc

@@ -1,220 +0,0 @@
-//
-// posix_chat_client.cpp
-// ~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <boost/array.hpp>
-#include <boost/bind.hpp>
-#include <boost/asio.hpp>
-#include "Experimental/chat/chat_message.h"
-
-#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
-
-using boost::asio::ip::tcp;
-namespace posix = boost::asio::posix;
-
-class posix_chat_client
-{
-public:
-	posix_chat_client(boost::asio::io_service& io_service,
-			tcp::resolver::iterator endpoint_iterator) :
-		socket_(io_service), input_(io_service, ::dup(STDIN_FILENO)), output_(
-				io_service, ::dup(STDOUT_FILENO)), input_buffer_(
-				chat_message::max_body_length)
-	{
-		// Try connecting to the first endpoint.
-		tcp::endpoint endpoint = *endpoint_iterator;
-		socket_.async_connect(endpoint, boost::bind(
-				&posix_chat_client::handle_connect, this,
-				boost::asio::placeholders::error, ++endpoint_iterator));
-	}
-
-private:
-
-	void handle_connect(const boost::system::error_code& error,
-			tcp::resolver::iterator endpoint_iterator)
-	{
-		if (!error)
-		{
-			// Read the fixed-length header of the next message from the server.
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.data(), chat_message::header_length),
-					boost::bind(&posix_chat_client::handle_read_header, this,
-							boost::asio::placeholders::error));
-
-
-			// Read a line of input entered by the user.
-			boost::asio::async_read_until(input_, input_buffer_, '\n',
-					boost::bind(&posix_chat_client::handle_read_input, this,
-							boost::asio::placeholders::error,
-							boost::asio::placeholders::bytes_transferred));
-		}
-		else if (endpoint_iterator != tcp::resolver::iterator())
-		{
-			// That endpoint didn't work, try the next one.
-			socket_.close();
-			tcp::endpoint endpoint = *endpoint_iterator;
-			socket_.async_connect(endpoint, boost::bind(
-					&posix_chat_client::handle_connect, this,
-					boost::asio::placeholders::error, ++endpoint_iterator));
-		}
-	}
-
-	void handle_read_header(const boost::system::error_code& error)
-	{
-		if (!error && read_msg_.decode_header())
-		{
-			// Read the variable-length body of the message from the server.
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.body(), read_msg_.body_length()), boost::bind(
-					&posix_chat_client::handle_read_body, this,
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			close();
-		}
-	}
-
-	void handle_read_body(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			// Write out the message we just received, terminated by a newline.
-			static char eol[] =
-			{'\n'};
-			boost::array<boost::asio::const_buffer, 2> buffers =
-			{
-			{boost::asio::buffer(read_msg_.body(), read_msg_.body_length()),
-					boost::asio::buffer(eol)}};
-			boost::asio::async_write(output_, buffers, boost::bind(
-					&posix_chat_client::handle_write_output, this,
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			close();
-		}
-	}
-
-	void handle_write_output(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			// Read the fixed-length header of the next message from the server.
-			boost::asio::async_read(socket_, boost::asio::buffer(
-					read_msg_.data(), chat_message::header_length),
-					boost::bind(&posix_chat_client::handle_read_header, this,
-							boost::asio::placeholders::error));
-		}
-		else
-		{
-			close();
-		}
-	}
-
-	void handle_read_input(const boost::system::error_code& error,
-			std::size_t length)
-	{
-		if (!error)
-		{
-			// Write the message (minus the newline) to the server.
-			write_msg_.body_length(length - 1);
-			input_buffer_.sgetn(write_msg_.body(), length - 1);
-			input_buffer_.consume(1); // Remove newline from input.
-			write_msg_.encode_header();
-			boost::asio::async_write(socket_, boost::asio::buffer(
-					write_msg_.data(), write_msg_.length()), boost::bind(
-					&posix_chat_client::handle_write, this,
-					boost::asio::placeholders::error));
-		}
-		else if (error == boost::asio::error::not_found)
-		{
-			// Didn't get a newline. Send whatever we have.
-			write_msg_.body_length(input_buffer_.size());
-			input_buffer_.sgetn(write_msg_.body(), input_buffer_.size());
-			write_msg_.encode_header();
-			boost::asio::async_write(socket_, boost::asio::buffer(
-					write_msg_.data(), write_msg_.length()), boost::bind(
-					&posix_chat_client::handle_write, this,
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			close();
-		}
-	}
-
-	void handle_write(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			// Read a line of input entered by the user.
-			boost::asio::async_read_until(input_, input_buffer_, '\n',
-					boost::bind(&posix_chat_client::handle_read_input, this,
-							boost::asio::placeholders::error,
-							boost::asio::placeholders::bytes_transferred));
-		}
-		else
-		{
-			close();
-		}
-	}
-
-	void close()
-	{
-		// Cancel all outstanding asynchronous operations.
-		socket_.close();
-		input_.close();
-		output_.close();
-	}
-
-private:
-	tcp::socket socket_;
-	posix::stream_descriptor input_;
-	posix::stream_descriptor output_;
-	chat_message read_msg_;
-	chat_message write_msg_;
-	boost::asio::streambuf input_buffer_;
-};
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 3)
-		{
-			std::cerr << "Usage: posix_chat_client <host> <port>\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		tcp::resolver resolver(io_service);
-		tcp::resolver::query query(argv[1], argv[2]);
-		tcp::resolver::iterator iterator = resolver.resolve(query);
-
-		posix_chat_client c(io_service, iterator);
-
-		io_service.run();
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}
-
-#else // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
-int main()
-{}
-#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)

+ 0 - 137
Src/Experimental/echo/async_tcp_echo_server.cc

@@ -1,137 +0,0 @@
-//
-// async_tcp_echo_server.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <cstdlib>
-#include <iostream>
-#include <boost/bind.hpp>
-#include <boost/asio.hpp>
-
-using boost::asio::ip::tcp;
-
-class session
-{
-public:
-	session(boost::asio::io_service& io_service) :
-		socket_(io_service)
-	{
-	}
-
-	tcp::socket& socket()
-	{
-		return socket_;
-	}
-
-	void start()
-	{
-		socket_.async_read_some(boost::asio::buffer(data_, max_length),
-				boost::bind(&session::handle_read, this,
-						boost::asio::placeholders::error,
-						boost::asio::placeholders::bytes_transferred));
-	}
-
-	void handle_read(const boost::system::error_code& error,
-			size_t bytes_transferred)
-	{
-		if (!error)
-		{
-			boost::asio::async_write(socket_, boost::asio::buffer(data_,
-					bytes_transferred), boost::bind(&session::handle_write,
-					this, boost::asio::placeholders::error));
-		}
-		else
-		{
-			delete this;
-		}
-	}
-
-	void handle_write(const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			socket_.async_read_some(boost::asio::buffer(data_, max_length),
-					boost::bind(&session::handle_read, this,
-							boost::asio::placeholders::error,
-							boost::asio::placeholders::bytes_transferred));
-		}
-		else
-		{
-			delete this;
-		}
-	}
-
-private:
-	tcp::socket socket_;
-	enum
-	{
-		max_length = 1024
-	};
-	char data_[max_length];
-};
-
-class server
-{
-public:
-	server(boost::asio::io_service& io_service, short port) :
-		io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(),
-				port))
-	{
-		session* new_session = new session(io_service_);
-		acceptor_.async_accept(new_session->socket(), boost::bind(
-				&server::handle_accept, this, new_session,
-				boost::asio::placeholders::error));
-	}
-
-	void handle_accept(session* new_session,
-			const boost::system::error_code& error)
-	{
-		if (!error)
-		{
-			new_session->start();
-			new_session = new session(io_service_);
-			acceptor_.async_accept(new_session->socket(), boost::bind(
-					&server::handle_accept, this, new_session,
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			delete new_session;
-		}
-	}
-
-private:
-	boost::asio::io_service& io_service_;
-	tcp::acceptor acceptor_;
-};
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 2)
-		{
-			std::cerr << "Usage: async_tcp_echo_server <port>\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		using namespace std;
-		// For atoi.
-		server s(io_service, atoi(argv[1]));
-
-		io_service.run();
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 93
Src/Experimental/echo/async_udp_echo_server.cc

@@ -1,93 +0,0 @@
-//
-// async_udp_echo_server.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <cstdlib>
-#include <iostream>
-#include <boost/bind.hpp>
-#include <boost/asio.hpp>
-
-using boost::asio::ip::udp;
-
-class server
-{
-public:
-	server(boost::asio::io_service& io_service, short port) :
-		io_service_(io_service), socket_(io_service, udp::endpoint(udp::v4(),
-				port))
-	{
-		socket_.async_receive_from(boost::asio::buffer(data_, max_length),
-				sender_endpoint_, boost::bind(&server::handle_receive_from,
-						this, boost::asio::placeholders::error,
-						boost::asio::placeholders::bytes_transferred));
-	}
-
-	void handle_receive_from(const boost::system::error_code& error,
-			size_t bytes_recvd)
-	{
-		if (!error && bytes_recvd > 0)
-		{
-			socket_.async_send_to(boost::asio::buffer(data_, bytes_recvd),
-					sender_endpoint_, boost::bind(&server::handle_send_to,
-							this, boost::asio::placeholders::error,
-							boost::asio::placeholders::bytes_transferred));
-		}
-		else
-		{
-			socket_.async_receive_from(boost::asio::buffer(data_, max_length),
-					sender_endpoint_, boost::bind(&server::handle_receive_from,
-							this, boost::asio::placeholders::error,
-							boost::asio::placeholders::bytes_transferred));
-		}
-	}
-
-	void handle_send_to(const boost::system::error_code& /*error*/, size_t /*bytes_sent*/)
-	{
-		socket_.async_receive_from(boost::asio::buffer(data_, max_length),
-				sender_endpoint_, boost::bind(&server::handle_receive_from,
-						this, boost::asio::placeholders::error,
-						boost::asio::placeholders::bytes_transferred));
-	}
-
-private:
-	boost::asio::io_service& io_service_;
-	udp::socket socket_;
-	udp::endpoint sender_endpoint_;
-	enum
-	{
-		max_length = 1024
-	};
-	char data_[max_length];
-};
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 2)
-		{
-			std::cerr << "Usage: async_udp_echo_server <port>\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		using namespace std;
-		// For atoi.
-		server s(io_service, atoi(argv[1]));
-
-		io_service.run();
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 63
Src/Experimental/echo/blocking_tcp_echo_client.cc

@@ -1,63 +0,0 @@
-//
-// blocking_tcp_echo_client.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <boost/asio.hpp>
-
-using boost::asio::ip::tcp;
-
-enum
-{
-	max_length = 1024
-};
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 3)
-		{
-			std::cerr << "Usage: blocking_tcp_echo_client <host> <port>\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		tcp::resolver resolver(io_service);
-		tcp::resolver::query query(tcp::v4(), argv[1], argv[2]);
-		tcp::resolver::iterator iterator = resolver.resolve(query);
-
-		tcp::socket s(io_service);
-		s.connect(*iterator);
-
-		using namespace std;
-		// For strlen.
-		std::cout << "Enter message: ";
-		char request[max_length];
-		std::cin.getline(request, max_length);
-		size_t request_length = strlen(request);
-		boost::asio::write(s, boost::asio::buffer(request, request_length));
-
-		char reply[max_length];
-		size_t reply_length = boost::asio::read(s, boost::asio::buffer(reply,
-				request_length));
-		std::cout << "Reply is: ";
-		std::cout.write(reply, reply_length);
-		std::cout << "\n";
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 81
Src/Experimental/echo/blocking_tcp_echo_server.cc

@@ -1,81 +0,0 @@
-//
-// blocking_tcp_echo_server.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <cstdlib>
-#include <iostream>
-#include <boost/bind.hpp>
-#include <boost/smart_ptr.hpp>
-#include <boost/asio.hpp>
-#include <boost/thread.hpp>
-
-using boost::asio::ip::tcp;
-
-const int max_length = 1024;
-
-typedef boost::shared_ptr<tcp::socket> socket_ptr;
-
-void session(socket_ptr sock)
-{
-	try
-	{
-		for (;;)
-		{
-			char data[max_length];
-
-			boost::system::error_code error;
-			size_t length = sock->read_some(boost::asio::buffer(data), error);
-			if (error == boost::asio::error::eof)
-				break; // Connection closed cleanly by peer.
-			else if (error)
-				throw boost::system::system_error(error); // Some other error.
-
-			boost::asio::write(*sock, boost::asio::buffer(data, length));
-		}
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception in thread: " << e.what() << "\n";
-	}
-}
-
-void server(boost::asio::io_service& io_service, short port)
-{
-	tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
-	for (;;)
-	{
-		socket_ptr sock(new tcp::socket(io_service));
-		a.accept(*sock);
-		boost::thread t(boost::bind(session, sock));
-	}
-}
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 2)
-		{
-			std::cerr << "Usage: blocking_tcp_echo_server <port>\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-		using namespace std;
-		// For atoi.
-		server(io_service, atoi(argv[1]));
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 217
Src/Experimental/http_client/async_client.cc

@@ -1,217 +0,0 @@
-//
-// async_client.cpp
-// ~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <iostream>
-#include <istream>
-#include <ostream>
-#include <string>
-#include <boost/asio.hpp>
-#include <boost/bind.hpp>
-
-using boost::asio::ip::tcp;
-
-class client
-{
-public:
-	client(boost::asio::io_service& io_service, const std::string& server,
-			const std::string& path) :
-		resolver_(io_service), socket_(io_service)
-	{
-		// Form the request. We specify the "Connection: close" header so that the
-		// server will close the socket after transmitting the response. This will
-		// allow us to treat all data up until the EOF as the content.
-		std::ostream request_stream(&request_);
-		request_stream << "GET " << path << " HTTP/1.0\r\n";
-		request_stream << "Host: " << server << "\r\n";
-		request_stream << "Accept: */*\r\n";
-		request_stream << "Connection: close\r\n\r\n";
-
-
-		// Start an asynchronous resolve to translate the server and service names
-		// into a list of endpoints.
-		tcp::resolver::query query(server, "http");
-		resolver_.async_resolve(query, boost::bind(&client::handle_resolve,
-				this, boost::asio::placeholders::error,
-				boost::asio::placeholders::iterator));
-	}
-
-private:
-	void handle_resolve(const boost::system::error_code& err,
-			tcp::resolver::iterator endpoint_iterator)
-	{
-		if (!err)
-		{
-			// Attempt a connection to the first endpoint in the list. Each endpoint
-			// will be tried until we successfully establish a connection.
-			tcp::endpoint endpoint = *endpoint_iterator;
-			socket_.async_connect(endpoint, boost::bind(
-					&client::handle_connect, this,
-					boost::asio::placeholders::error, ++endpoint_iterator));
-		}
-		else
-		{
-			std::cout << "Error: " << err.message() << "\n";
-		}
-	}
-
-	void handle_connect(const boost::system::error_code& err,
-			tcp::resolver::iterator endpoint_iterator)
-	{
-		if (!err)
-		{
-			// The connection was successful. Send the request.
-			boost::asio::async_write(socket_, request_, boost::bind(
-					&client::handle_write_request, this,
-					boost::asio::placeholders::error));
-		}
-		else if (endpoint_iterator != tcp::resolver::iterator())
-		{
-			// The connection failed. Try the next endpoint in the list.
-			socket_.close();
-			tcp::endpoint endpoint = *endpoint_iterator;
-			socket_.async_connect(endpoint, boost::bind(
-					&client::handle_connect, this,
-					boost::asio::placeholders::error, ++endpoint_iterator));
-		}
-		else
-		{
-			std::cout << "Error: " << err.message() << "\n";
-		}
-	}
-
-	void handle_write_request(const boost::system::error_code& err)
-	{
-		if (!err)
-		{
-			// Read the response status line.
-			boost::asio::async_read_until(socket_, response_, "\r\n",
-					boost::bind(&client::handle_read_status_line, this,
-							boost::asio::placeholders::error));
-		}
-		else
-		{
-			std::cout << "Error: " << err.message() << "\n";
-		}
-	}
-
-	void handle_read_status_line(const boost::system::error_code& err)
-	{
-		if (!err)
-		{
-			// Check that response is OK.
-			std::istream response_stream(&response_);
-			std::string http_version;
-			response_stream >> http_version;
-			unsigned int status_code;
-			response_stream >> status_code;
-			std::string status_message;
-			std::getline(response_stream, status_message);
-			if (!response_stream || http_version.substr(0, 5) != "HTTP/")
-			{
-				std::cout << "Invalid response\n";
-				return;
-			}
-			if (status_code != 200)
-			{
-				std::cout << "Response returned with status code ";
-				std::cout << status_code << "\n";
-				return;
-			}
-
-
-			// Read the response headers, which are terminated by a blank line.
-			boost::asio::async_read_until(socket_, response_, "\r\n\r\n",
-					boost::bind(&client::handle_read_headers, this,
-							boost::asio::placeholders::error));
-		}
-		else
-		{
-			std::cout << "Error: " << err << "\n";
-		}
-	}
-
-	void handle_read_headers(const boost::system::error_code& err)
-	{
-		if (!err)
-		{
-			// Process the response headers.
-			std::istream response_stream(&response_);
-			std::string header;
-			while (std::getline(response_stream, header) && header != "\r")
-				std::cout << header << "\n";
-			std::cout << "\n";
-
-
-			// Write whatever content we already have to output.
-			if (response_.size() > 0)
-				std::cout << &response_;
-
-
-			// Start reading remaining data until EOF.
-			boost::asio::async_read(socket_, response_,
-					boost::asio::transfer_at_least(1), boost::bind(
-							&client::handle_read_content, this,
-							boost::asio::placeholders::error));
-		}
-		else
-		{
-			std::cout << "Error: " << err << "\n";
-		}
-	}
-
-	void handle_read_content(const boost::system::error_code& err)
-	{
-		if (!err)
-		{
-			// Write all of the data that has been read so far.
-			std::cout << &response_;
-
-
-			// Continue reading remaining data until EOF.
-			boost::asio::async_read(socket_, response_,
-					boost::asio::transfer_at_least(1), boost::bind(
-							&client::handle_read_content, this,
-							boost::asio::placeholders::error));
-		}
-		else if (err != boost::asio::error::eof)
-		{
-			std::cout << "Error: " << err << "\n";
-		}
-	}
-
-	tcp::resolver resolver_;
-	tcp::socket socket_;
-	boost::asio::streambuf request_;
-	boost::asio::streambuf response_;
-};
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 3)
-		{
-			std::cout << "Usage: async_client <server> <path>\n";
-			std::cout << "Example:\n";
-			std::cout << "  async_client www.boost.org /LICENSE_1_0.txt\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-		client c(io_service, argv[1], argv[2]);
-		io_service.run();
-	}
-	catch (std::exception& e)
-	{
-		std::cout << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 122
Src/Experimental/http_client/sync_client.cc

@@ -1,122 +0,0 @@
-//
-// sync_client.cpp
-// ~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <iostream>
-#include <istream>
-#include <ostream>
-#include <string>
-#include <boost/asio.hpp>
-
-using boost::asio::ip::tcp;
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		if (argc != 3)
-		{
-			std::cout << "Usage: sync_client <server> <path>\n";
-			std::cout << "Example:\n";
-			std::cout << "  sync_client www.boost.org /LICENSE_1_0.txt\n";
-			return 1;
-		}
-
-		boost::asio::io_service io_service;
-
-
-		// Get a list of endpoints corresponding to the server name.
-		tcp::resolver resolver(io_service);
-		tcp::resolver::query query(argv[1], "http");
-		tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
-		tcp::resolver::iterator end;
-
-
-		// Try each endpoint until we successfully establish a connection.
-		tcp::socket socket(io_service);
-		boost::system::error_code error = boost::asio::error::host_not_found;
-		while (error && endpoint_iterator != end)
-		{
-			socket.close();
-			socket.connect(*endpoint_iterator++, error);
-		}
-		if (error)
-			throw boost::system::system_error(error);
-
-
-		// Form the request. We specify the "Connection: close" header so that the
-		// server will close the socket after transmitting the response. This will
-		// allow us to treat all data up until the EOF as the content.
-		boost::asio::streambuf request;
-		std::ostream request_stream(&request);
-		request_stream << "GET " << argv[2] << " HTTP/1.0\r\n";
-		request_stream << "Host: " << argv[1] << "\r\n";
-		request_stream << "Accept: */*\r\n";
-		request_stream << "Connection: close\r\n\r\n";
-
-
-		// Send the request.
-		boost::asio::write(socket, request);
-
-
-		// Read the response status line.
-		boost::asio::streambuf response;
-		boost::asio::read_until(socket, response, "\r\n");
-
-
-		// Check that response is OK.
-		std::istream response_stream(&response);
-		std::string http_version;
-		response_stream >> http_version;
-		unsigned int status_code;
-		response_stream >> status_code;
-		std::string status_message;
-		std::getline(response_stream, status_message);
-		if (!response_stream || http_version.substr(0, 5) != "HTTP/")
-		{
-			std::cout << "Invalid response\n";
-			return 1;
-		}
-		if (status_code != 200)
-		{
-			std::cout << "Response returned with status code " << status_code
-					<< "\n";
-			return 1;
-		}
-
-		// Read the response headers, which are terminated by a blank line.
-		boost::asio::read_until(socket, response, "\r\n\r\n");
-
-
-		// Process the response headers.
-		std::string header;
-		while (std::getline(response_stream, header) && header != "\r")
-			std::cout << header << "\n";
-		std::cout << "\n";
-
-
-		// Write whatever content we already have to output.
-		if (response.size() > 0)
-			std::cout << &response;
-
-
-		// Read until EOF, writing data to output as we go.
-		while (boost::asio::read(socket, response,
-				boost::asio::transfer_at_least(1), error))
-			std::cout << &response;
-		if (error != boost::asio::error::eof)
-			throw boost::system::system_error(error);
-	}
-	catch (std::exception& e)
-	{
-		std::cout << "Exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}

+ 0 - 97
Src/Experimental/http_server/connection.cc

@@ -1,97 +0,0 @@
-//
-// connection.cpp
-// ~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <vector>
-#include <boost/bind.hpp>
-#include "Experimental/http_server/connection.h"
-#include "Experimental/http_server/connection_manager.h"
-#include "Experimental/http_server/request_handler.h"
-
-namespace http_server {
-
-connection::connection(boost::asio::io_service& io_service,
-		connection_manager& manager, request_handler& handler) :
-	socket_(io_service), connection_manager_(manager),
-			request_handler_(handler)
-{
-}
-
-boost::asio::ip::tcp::socket& connection::socket()
-{
-	return socket_;
-}
-
-void connection::start()
-{
-	socket_.async_read_some(boost::asio::buffer(buffer_), boost::bind(
-			&connection::handle_read, shared_from_this(),
-			boost::asio::placeholders::error,
-			boost::asio::placeholders::bytes_transferred));
-}
-
-void connection::stop()
-{
-	socket_.close();
-}
-
-void connection::handle_read(const boost::system::error_code& e,
-		std::size_t bytes_transferred)
-{
-	if (!e)
-	{
-		boost::tribool result;
-		boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
-				request_, buffer_.data(), buffer_.data() + bytes_transferred);
-
-		if (result)
-		{
-			request_handler_.handle_request(request_, reply_);
-			boost::asio::async_write(socket_, reply_.to_buffers(), boost::bind(
-					&connection::handle_write, shared_from_this(),
-					boost::asio::placeholders::error));
-		}
-		else if (!result)
-		{
-			reply_ = reply::stock_reply(reply::bad_request);
-			boost::asio::async_write(socket_, reply_.to_buffers(), boost::bind(
-					&connection::handle_write, shared_from_this(),
-					boost::asio::placeholders::error));
-		}
-		else
-		{
-			socket_.async_read_some(boost::asio::buffer(buffer_), boost::bind(
-					&connection::handle_read, shared_from_this(),
-					boost::asio::placeholders::error,
-					boost::asio::placeholders::bytes_transferred));
-		}
-	}
-	else if (e != boost::asio::error::operation_aborted)
-	{
-		connection_manager_.stop(shared_from_this());
-	}
-}
-
-void connection::handle_write(const boost::system::error_code& e)
-{
-	if (!e)
-	{
-		// Initiate graceful connection closure.
-		boost::system::error_code ignored_ec;
-		socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both,
-				ignored_ec);
-	}
-
-	if (e != boost::asio::error::operation_aborted)
-	{
-		connection_manager_.stop(shared_from_this());
-	}
-}
-
-} // namespace http_server

+ 0 - 80
Src/Experimental/http_server/connection.h

@@ -1,80 +0,0 @@
-//
-// connection.hpp
-// ~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_CONNECTION_H
-#define EXPERIMENTAL_HTTP_SERVER_CONNECTION_H
-
-#include <boost/asio.hpp>
-#include <boost/array.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include "Experimental/http_server/reply.h"
-#include "Experimental/http_server/request.h"
-#include "Experimental/http_server/request_handler.h"
-#include "Experimental/http_server/request_parser.h"
-
-namespace http_server {
-
-class connection_manager;
-
-/// Represents a single connection from a client.
-class connection: public boost::enable_shared_from_this<connection>,
-        private boost::noncopyable
-{
-public:
-	/// Construct a connection with the given io_service.
-	explicit connection(boost::asio::io_service& io_service,
-	        connection_manager& manager, request_handler& handler);
-
-	/// Get the socket associated with the connection.
-	boost::asio::ip::tcp::socket& socket();
-
-	/// Start the first asynchronous operation for the connection.
-	void start();
-
-	/// Stop all asynchronous operations associated with the connection.
-	void stop();
-
-private:
-	/// Handle completion of a read operation.
-	void handle_read(const boost::system::error_code& e,
-	        std::size_t bytes_transferred);
-
-	/// Handle completion of a write operation.
-	void handle_write(const boost::system::error_code& e);
-
-	/// Socket for the connection.
-	boost::asio::ip::tcp::socket socket_;
-
-	/// The manager for this connection.
-	connection_manager& connection_manager_;
-
-	/// The handler used to process the incoming request.
-	request_handler& request_handler_;
-
-	/// Buffer for incoming data.
-	boost::array<char, 8192> buffer_;
-
-	/// The incoming request.
-	request request_;
-
-	/// The parser for the incoming request.
-	request_parser request_parser_;
-
-	/// The reply to be sent back to the client.
-	reply reply_;
-};
-
-typedef boost::shared_ptr<connection> connection_ptr;
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_CONNECTION_H

+ 0 - 36
Src/Experimental/http_server/connection_manager.cc

@@ -1,36 +0,0 @@
-//
-// connection_manager.cpp
-// ~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <algorithm>
-#include <boost/bind.hpp>
-#include "Experimental/http_server/connection_manager.h"
-
-namespace http_server {
-
-void connection_manager::start(connection_ptr c)
-{
-	connections_.insert(c);
-	c->start();
-}
-
-void connection_manager::stop(connection_ptr c)
-{
-	connections_.erase(c);
-	c->stop();
-}
-
-void connection_manager::stop_all()
-{
-	std::for_each(connections_.begin(), connections_.end(), boost::bind(
-			&connection::stop, _1));
-	connections_.clear();
-}
-
-} // namespace http_server

+ 0 - 41
Src/Experimental/http_server/connection_manager.h

@@ -1,41 +0,0 @@
-//
-// connection_manager.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_CONNECTION_MANAGER_H
-#define EXPERIMENTAL_HTTP_SERVER_CONNECTION_MANAGER_H
-
-#include <set>
-#include <boost/noncopyable.hpp>
-#include "Experimental/http_server/connection.h"
-
-namespace http_server {
-
-/// Manages open connections so that they may be cleanly stopped when the server
-/// needs to shut down.
-class connection_manager: private boost::noncopyable
-{
-public:
-	/// Add the specified connection to the manager and start it.
-	void start(connection_ptr c);
-
-	/// Stop the specified connection.
-	void stop(connection_ptr c);
-
-	/// Stop all connections.
-	void stop_all();
-
-private:
-	/// The managed connections.
-	std::set<connection_ptr> connections_;
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_CONNECTION_MANAGER_H

+ 0 - 26
Src/Experimental/http_server/header.h

@@ -1,26 +0,0 @@
-//
-// header.hpp
-// ~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HEADER_H
-#define EXPERIMENTAL_HTTP_SERVER_HEADER_H
-
-#include <string>
-
-namespace http_server {
-
-struct header
-{
-	std::string name;
-	std::string value;
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HEADER_H

+ 0 - 44
Src/Experimental/http_server/mime_types.cc

@@ -1,44 +0,0 @@
-//
-// mime_types.cpp
-// ~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include "Experimental/http_server/mime_types.h"
-
-namespace http_server {
-namespace mime_types {
-
-struct mapping
-{
-	const char* extension;
-	const char* mime_type;
-} mappings[] =
-{
-	{"gif", "image/gif"},
-	{"htm", "text/html"},
-	{"html", "text/html"},
-	{"jpg", "image/jpeg"},
-	{"png", "image/png"},
-	{0, 0} // Marks end of list.
-};
-
-std::string extension_to_type(const std::string& extension)
-{
-	for (mapping* m = mappings; m->extension; ++m)
-	{
-		if (m->extension == extension)
-		{
-			return m->mime_type;
-		}
-	}
-
-	return "text/plain";
-}
-
-} // namespace mime_types
-} // namespace http_server

+ 0 - 25
Src/Experimental/http_server/mime_types.h

@@ -1,25 +0,0 @@
-//
-// mime_types.hpp
-// ~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HTTP_MIME_TYPES_H
-#define EXPERIMENTAL_HTTP_SERVER_HTTP_MIME_TYPES_H
-
-#include <string>
-
-namespace http_server {
-namespace mime_types {
-
-/// Convert a file extension into a MIME type.
-std::string extension_to_type(const std::string& extension);
-
-} // namespace mime_types
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HTTP_MIME_TYPES_H

+ 0 - 74
Src/Experimental/http_server/posix_main.cc

@@ -1,74 +0,0 @@
-//
-// posix_main.cc
-// ~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <iostream>
-#include <string>
-#include <boost/asio.hpp>
-#include <boost/thread.hpp>
-#include <boost/bind.hpp>
-#include "Experimental/http_server/server.h"
-
-#include <pthread.h>
-#include <signal.h>
-
-int main(int argc, char* argv[])
-{
-	try
-	{
-		// Check command line arguments.
-		if (argc != 4)
-		{
-			std::cerr << "Usage: http_server <address> <port> <doc_root>\n";
-			std::cerr << "  For IPv4, try:\n";
-			std::cerr << "    receiver 0.0.0.0 80 .\n";
-			std::cerr << "  For IPv6, try:\n";
-			std::cerr << "    receiver 0::0 80 .\n";
-			return 1;
-		}
-
-		// Block all signals for background thread.
-		sigset_t new_mask;
-		sigfillset(&new_mask);
-		sigset_t old_mask;
-		pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
-
-
-		// Run server in background thread.
-		http_server::server s(argv[1], argv[2], argv[3]);
-		boost::thread t(boost::bind(&http_server::server::run, &s));
-
-
-		// Restore previous signals.
-		pthread_sigmask(SIG_SETMASK, &old_mask, 0);
-
-
-		// Wait for signal indicating time to shut down.
-		sigset_t wait_mask;
-		sigemptyset(&wait_mask);
-		sigaddset(&wait_mask, SIGINT);
-		sigaddset(&wait_mask, SIGQUIT);
-		sigaddset(&wait_mask, SIGTERM);
-		pthread_sigmask(SIG_BLOCK, &wait_mask, 0);
-		int sig = 0;
-		sigwait(&wait_mask, &sig);
-
-
-		// Stop the server.
-		s.stop();
-		t.join();
-	}
-	catch (std::exception& e)
-	{
-		std::cerr << "exception: " << e.what() << "\n";
-	}
-
-	return 0;
-}
-

+ 0 - 227
Src/Experimental/http_server/reply.cc

@@ -1,227 +0,0 @@
-//
-// reply.cpp
-// ~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <string>
-#include <boost/lexical_cast.hpp>
-#include "Experimental/http_server/reply.h"
-
-namespace http_server {
-
-namespace status_strings {
-
-const std::string ok = "HTTP/1.0 200 OK\r\n";
-const std::string created = "HTTP/1.0 201 Created\r\n";
-const std::string accepted = "HTTP/1.0 202 Accepted\r\n";
-const std::string no_content = "HTTP/1.0 204 No Content\r\n";
-const std::string multiple_choices = "HTTP/1.0 300 Multiple Choices\r\n";
-const std::string moved_permanently = "HTTP/1.0 301 Moved Permanently\r\n";
-const std::string moved_temporarily = "HTTP/1.0 302 Moved Temporarily\r\n";
-const std::string not_modified = "HTTP/1.0 304 Not Modified\r\n";
-const std::string bad_request = "HTTP/1.0 400 Bad Request\r\n";
-const std::string unauthorized = "HTTP/1.0 401 Unauthorized\r\n";
-const std::string forbidden = "HTTP/1.0 403 Forbidden\r\n";
-const std::string not_found = "HTTP/1.0 404 Not Found\r\n";
-const std::string internal_server_error =
-		"HTTP/1.0 500 Internal Server Error\r\n";
-const std::string not_implemented = "HTTP/1.0 501 Not Implemented\r\n";
-const std::string bad_gateway = "HTTP/1.0 502 Bad Gateway\r\n";
-const std::string service_unavailable = "HTTP/1.0 503 Service Unavailable\r\n";
-
-boost::asio::const_buffer to_buffer(reply::status_type status)
-{
-	switch (status)
-	{
-		case reply::ok:
-			return boost::asio::buffer(ok);
-		case reply::created:
-			return boost::asio::buffer(created);
-		case reply::accepted:
-			return boost::asio::buffer(accepted);
-		case reply::no_content:
-			return boost::asio::buffer(no_content);
-		case reply::multiple_choices:
-			return boost::asio::buffer(multiple_choices);
-		case reply::moved_permanently:
-			return boost::asio::buffer(moved_permanently);
-		case reply::moved_temporarily:
-			return boost::asio::buffer(moved_temporarily);
-		case reply::not_modified:
-			return boost::asio::buffer(not_modified);
-		case reply::bad_request:
-			return boost::asio::buffer(bad_request);
-		case reply::unauthorized:
-			return boost::asio::buffer(unauthorized);
-		case reply::forbidden:
-			return boost::asio::buffer(forbidden);
-		case reply::not_found:
-			return boost::asio::buffer(not_found);
-		case reply::internal_server_error:
-			return boost::asio::buffer(internal_server_error);
-		case reply::not_implemented:
-			return boost::asio::buffer(not_implemented);
-		case reply::bad_gateway:
-			return boost::asio::buffer(bad_gateway);
-		case reply::service_unavailable:
-			return boost::asio::buffer(service_unavailable);
-		default:
-			return boost::asio::buffer(internal_server_error);
-	}
-}
-
-} // namespace status_strings
-
-namespace misc_strings {
-
-const char name_value_separator[] =
-{':', ' '};
-const char crlf[] =
-{'\r', '\n'};
-
-} // namespace misc_strings
-
-std::vector<boost::asio::const_buffer> reply::to_buffers()
-{
-	std::vector<boost::asio::const_buffer> buffers;
-	buffers.push_back(status_strings::to_buffer(status));
-	for (std::size_t i = 0; i < headers.size(); ++i)
-	{
-		header& h = headers[i];
-		buffers.push_back(boost::asio::buffer(h.name));
-		buffers.push_back(boost::asio::buffer(
-				misc_strings::name_value_separator));
-		buffers.push_back(boost::asio::buffer(h.value));
-		buffers.push_back(boost::asio::buffer(misc_strings::crlf));
-	}
-	buffers.push_back(boost::asio::buffer(misc_strings::crlf));
-	buffers.push_back(boost::asio::buffer(content));
-	return buffers;
-}
-
-namespace stock_replies {
-
-const char ok[] = "";
-const char created[] = "<html>"
-	"<head><title>Created</title></head>"
-	"<body><h1>201 Created</h1></body>"
-	"</html>";
-const char accepted[] = "<html>"
-	"<head><title>Accepted</title></head>"
-	"<body><h1>202 Accepted</h1></body>"
-	"</html>";
-const char no_content[] = "<html>"
-	"<head><title>No Content</title></head>"
-	"<body><h1>204 Content</h1></body>"
-	"</html>";
-const char multiple_choices[] = "<html>"
-	"<head><title>Multiple Choices</title></head>"
-	"<body><h1>300 Multiple Choices</h1></body>"
-	"</html>";
-const char moved_permanently[] = "<html>"
-	"<head><title>Moved Permanently</title></head>"
-	"<body><h1>301 Moved Permanently</h1></body>"
-	"</html>";
-const char moved_temporarily[] = "<html>"
-	"<head><title>Moved Temporarily</title></head>"
-	"<body><h1>302 Moved Temporarily</h1></body>"
-	"</html>";
-const char not_modified[] = "<html>"
-	"<head><title>Not Modified</title></head>"
-	"<body><h1>304 Not Modified</h1></body>"
-	"</html>";
-const char bad_request[] = "<html>"
-	"<head><title>Bad Request</title></head>"
-	"<body><h1>400 Bad Request</h1></body>"
-	"</html>";
-const char unauthorized[] = "<html>"
-	"<head><title>Unauthorized</title></head>"
-	"<body><h1>401 Unauthorized</h1></body>"
-	"</html>";
-const char forbidden[] = "<html>"
-	"<head><title>Forbidden</title></head>"
-	"<body><h1>403 Forbidden</h1></body>"
-	"</html>";
-const char not_found[] = "<html>"
-	"<head><title>Not Found</title></head>"
-	"<body><h1>404 Not Found</h1></body>"
-	"</html>";
-const char internal_server_error[] = "<html>"
-	"<head><title>Internal Server Error</title></head>"
-	"<body><h1>500 Internal Server Error</h1></body>"
-	"</html>";
-const char not_implemented[] = "<html>"
-	"<head><title>Not Implemented</title></head>"
-	"<body><h1>501 Not Implemented</h1></body>"
-	"</html>";
-const char bad_gateway[] = "<html>"
-	"<head><title>Bad Gateway</title></head>"
-	"<body><h1>502 Bad Gateway</h1></body>"
-	"</html>";
-const char service_unavailable[] = "<html>"
-	"<head><title>Service Unavailable</title></head>"
-	"<body><h1>503 Service Unavailable</h1></body>"
-	"</html>";
-
-std::string to_string(reply::status_type status)
-{
-	switch (status)
-	{
-		case reply::ok:
-			return ok;
-		case reply::created:
-			return created;
-		case reply::accepted:
-			return accepted;
-		case reply::no_content:
-			return no_content;
-		case reply::multiple_choices:
-			return multiple_choices;
-		case reply::moved_permanently:
-			return moved_permanently;
-		case reply::moved_temporarily:
-			return moved_temporarily;
-		case reply::not_modified:
-			return not_modified;
-		case reply::bad_request:
-			return bad_request;
-		case reply::unauthorized:
-			return unauthorized;
-		case reply::forbidden:
-			return forbidden;
-		case reply::not_found:
-			return not_found;
-		case reply::internal_server_error:
-			return internal_server_error;
-		case reply::not_implemented:
-			return not_implemented;
-		case reply::bad_gateway:
-			return bad_gateway;
-		case reply::service_unavailable:
-			return service_unavailable;
-		default:
-			return internal_server_error;
-	}
-}
-
-} // namespace stock_replies
-
-reply reply::stock_reply(reply::status_type status)
-{
-	reply rep;
-	rep.status = status;
-	rep.content = stock_replies::to_string(status);
-	rep.headers.resize(2);
-	rep.headers[0].name = "Content-Length";
-	rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
-	rep.headers[1].name = "Content-Type";
-	rep.headers[1].value = "text/html";
-	return rep;
-}
-
-} // namespace http_server

+ 0 - 62
Src/Experimental/http_server/reply.h

@@ -1,62 +0,0 @@
-//
-// reply.hpp
-// ~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HTTP_REPLY_H
-#define EXPERIMENTAL_HTTP_SERVER_HTTP_REPLY_H
-
-#include <string>
-#include <vector>
-#include <boost/asio.hpp>
-#include "Experimental/http_server/header.h"
-
-namespace http_server {
-
-/// A reply to be sent to a client.
-struct reply
-{
-	/// The status of the reply.
-	enum status_type
-	{
-		ok = 200,
-		created = 201,
-		accepted = 202,
-		no_content = 204,
-		multiple_choices = 300,
-		moved_permanently = 301,
-		moved_temporarily = 302,
-		not_modified = 304,
-		bad_request = 400,
-		unauthorized = 401,
-		forbidden = 403,
-		not_found = 404,
-		internal_server_error = 500,
-		not_implemented = 501,
-		bad_gateway = 502,
-		service_unavailable = 503
-	} status;
-
-	/// The headers to be included in the reply.
-	std::vector<header> headers;
-
-	/// The content to be sent in the reply.
-	std::string content;
-
-	/// Convert the reply into a vector of buffers. The buffers do not own the
-	/// underlying memory blocks, therefore the reply object must remain valid and
-	/// not be changed until the write operation has completed.
-	std::vector<boost::asio::const_buffer> to_buffers();
-
-	/// Get a stock reply.
-	static reply stock_reply(status_type status);
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HTTP_REPLY_H

+ 0 - 32
Src/Experimental/http_server/request.h

@@ -1,32 +0,0 @@
-//
-// request.hpp
-// ~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_H
-#define EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_H
-
-#include <string>
-#include <vector>
-#include "Experimental/http_server/header.h"
-
-namespace http_server {
-
-/// A request received from a client.
-struct request
-{
-	std::string method;
-	std::string uri;
-	int http_version_major;
-	int http_version_minor;
-	std::vector<header> headers;
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_H

+ 0 - 120
Src/Experimental/http_server/request_handler.cc

@@ -1,120 +0,0 @@
-//
-// request_handler.cpp
-// ~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <fstream>
-#include <sstream>
-#include <string>
-#include <boost/lexical_cast.hpp>
-#include "Experimental/http_server/request_handler.h"
-#include "Experimental/http_server/mime_types.h"
-#include "Experimental/http_server/reply.h"
-#include "Experimental/http_server/request.h"
-
-namespace http_server {
-
-request_handler::request_handler(const std::string& doc_root) :
-	doc_root_(doc_root)
-{
-}
-
-void request_handler::handle_request(const request& req, reply& rep)
-{
-	// Decode url to path.
-	std::string request_path;
-	if (!url_decode(req.uri, request_path))
-	{
-		rep = reply::stock_reply(reply::bad_request);
-		return;
-	}
-
-	// Request path must be absolute and not contain "..".
-	if (request_path.empty() || request_path[0] != '/' || request_path.find(
-			"..") != std::string::npos)
-	{
-		rep = reply::stock_reply(reply::bad_request);
-		return;
-	}
-
-	// If path ends in slash (i.e. is a directory) then add "index.html".
-	if (request_path[request_path.size() - 1] == '/')
-	{
-		request_path += "index.html";
-	}
-
-	// Determine the file extension.
-	std::size_t last_slash_pos = request_path.find_last_of("/");
-	std::size_t last_dot_pos = request_path.find_last_of(".");
-	std::string extension;
-	if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
-	{
-		extension = request_path.substr(last_dot_pos + 1);
-	}
-
-	// Open the file to send back.
-	std::string full_path = doc_root_ + request_path;
-	std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
-	if (!is)
-	{
-		rep = reply::stock_reply(reply::not_found);
-		return;
-	}
-
-	// Fill out the reply to be sent to the client.
-	rep.status = reply::ok;
-	char buf[512];
-	while (is.read(buf, sizeof(buf)).gcount() > 0)
-		rep.content.append(buf, is.gcount());
-	rep.headers.resize(2);
-	rep.headers[0].name = "Content-Length";
-	rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size());
-	rep.headers[1].name = "Content-Type";
-	rep.headers[1].value = mime_types::extension_to_type(extension);
-}
-
-bool request_handler::url_decode(const std::string& in, std::string& out)
-{
-	out.clear();
-	out.reserve(in.size());
-	for (std::size_t i = 0; i < in.size(); ++i)
-	{
-		if (in[i] == '%')
-		{
-			if (i + 3 <= in.size())
-			{
-				int value = 0;
-				std::istringstream is(in.substr(i + 1, 2));
-				if (is >> std::hex >> value)
-				{
-					out += static_cast<char> (value);
-					i += 2;
-				}
-				else
-				{
-					return false;
-				}
-			}
-			else
-			{
-				return false;
-			}
-		}
-		else if (in[i] == '+')
-		{
-			out += ' ';
-		}
-		else
-		{
-			out += in[i];
-		}
-	}
-	return true;
-}
-
-} // namespace http_server

+ 0 - 43
Src/Experimental/http_server/request_handler.h

@@ -1,43 +0,0 @@
-//
-// request_handler.hpp
-// ~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_HANDLER_H
-#define EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_HANDLER_H
-
-#include <string>
-#include <boost/noncopyable.hpp>
-
-namespace http_server {
-
-struct reply;
-struct request;
-
-/// The common handler for all incoming requests.
-class request_handler: private boost::noncopyable
-{
-public:
-	/// Construct with a directory containing files to be served.
-	explicit request_handler(const std::string& doc_root);
-
-	/// Handle a request and produce a reply.
-	void handle_request(const request& req, reply& rep);
-
-private:
-	/// The directory containing the files to be served.
-	std::string doc_root_;
-
-	/// Perform URL-decoding on a string. Returns false if the encoding was
-	/// invalid.
-	static bool url_decode(const std::string& in, std::string& out);
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_HANDLER_H

+ 0 - 343
Src/Experimental/http_server/request_parser.cc

@@ -1,343 +0,0 @@
-//
-// request_parser.cpp
-// ~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include "Experimental/http_server/request_parser.h"
-#include "Experimental/http_server/request.h"
-
-namespace http_server {
-
-request_parser::request_parser() :
-	state_(method_start)
-{
-}
-
-void request_parser::reset()
-{
-	state_ = method_start;
-}
-
-boost::tribool request_parser::consume(request& req, char input)
-{
-	switch (state_)
-	{
-		case method_start:
-			if (!is_char(input) || is_ctl(input) || is_tspecial(input))
-			{
-				return false;
-			}
-			else
-			{
-				state_ = method;
-				req.method.push_back(input);
-				return boost::indeterminate;
-			}
-		case method:
-			if (input == ' ')
-			{
-				state_ = uri;
-				return boost::indeterminate;
-			}
-			else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
-			{
-				return false;
-			}
-			else
-			{
-				req.method.push_back(input);
-				return boost::indeterminate;
-			}
-		case uri_start:
-			if (is_ctl(input))
-			{
-				return false;
-			}
-			else
-			{
-				state_ = uri;
-				req.uri.push_back(input);
-				return boost::indeterminate;
-			}
-		case uri:
-			if (input == ' ')
-			{
-				state_ = http_version_h;
-				return boost::indeterminate;
-			}
-			else if (is_ctl(input))
-			{
-				return false;
-			}
-			else
-			{
-				req.uri.push_back(input);
-				return boost::indeterminate;
-			}
-		case http_version_h:
-			if (input == 'H')
-			{
-				state_ = http_version_t_1;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_t_1:
-			if (input == 'T')
-			{
-				state_ = http_version_t_2;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_t_2:
-			if (input == 'T')
-			{
-				state_ = http_version_p;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_p:
-			if (input == 'P')
-			{
-				state_ = http_version_slash;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_slash:
-			if (input == '/')
-			{
-				req.http_version_major = 0;
-				req.http_version_minor = 0;
-				state_ = http_version_major_start;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_major_start:
-			if (is_digit(input))
-			{
-				req.http_version_major = req.http_version_major * 10 + input
-						- '0';
-				state_ = http_version_major;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_major:
-			if (input == '.')
-			{
-				state_ = http_version_minor_start;
-				return boost::indeterminate;
-			}
-			else if (is_digit(input))
-			{
-				req.http_version_major = req.http_version_major * 10 + input
-						- '0';
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_minor_start:
-			if (is_digit(input))
-			{
-				req.http_version_minor = req.http_version_minor * 10 + input
-						- '0';
-				state_ = http_version_minor;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case http_version_minor:
-			if (input == '\r')
-			{
-				state_ = expecting_newline_1;
-				return boost::indeterminate;
-			}
-			else if (is_digit(input))
-			{
-				req.http_version_minor = req.http_version_minor * 10 + input
-						- '0';
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case expecting_newline_1:
-			if (input == '\n')
-			{
-				state_ = header_line_start;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case header_line_start:
-			if (input == '\r')
-			{
-				state_ = expecting_newline_3;
-				return boost::indeterminate;
-			}
-			else if (!req.headers.empty() && (input == ' ' || input == '\t'))
-			{
-				state_ = header_lws;
-				return boost::indeterminate;
-			}
-			else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
-			{
-				return false;
-			}
-			else
-			{
-				req.headers.push_back(header());
-				req.headers.back().name.push_back(input);
-				state_ = header_name;
-				return boost::indeterminate;
-			}
-		case header_lws:
-			if (input == '\r')
-			{
-				state_ = expecting_newline_2;
-				return boost::indeterminate;
-			}
-			else if (input == ' ' || input == '\t')
-			{
-				return boost::indeterminate;
-			}
-			else if (is_ctl(input))
-			{
-				return false;
-			}
-			else
-			{
-				state_ = header_value;
-				req.headers.back().value.push_back(input);
-				return boost::indeterminate;
-			}
-		case header_name:
-			if (input == ':')
-			{
-				state_ = space_before_header_value;
-				return boost::indeterminate;
-			}
-			else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
-			{
-				return false;
-			}
-			else
-			{
-				req.headers.back().name.push_back(input);
-				return boost::indeterminate;
-			}
-		case space_before_header_value:
-			if (input == ' ')
-			{
-				state_ = header_value;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case header_value:
-			if (input == '\r')
-			{
-				state_ = expecting_newline_2;
-				return boost::indeterminate;
-			}
-			else if (is_ctl(input))
-			{
-				return false;
-			}
-			else
-			{
-				req.headers.back().value.push_back(input);
-				return boost::indeterminate;
-			}
-		case expecting_newline_2:
-			if (input == '\n')
-			{
-				state_ = header_line_start;
-				return boost::indeterminate;
-			}
-			else
-			{
-				return false;
-			}
-		case expecting_newline_3:
-			return (input == '\n');
-		default:
-			return false;
-	}
-}
-
-bool request_parser::is_char(int c)
-{
-	return c >= 0 && c <= 127;
-}
-
-bool request_parser::is_ctl(int c)
-{
-	return (c >= 0 && c <= 31) || (c == 127);
-}
-
-bool request_parser::is_tspecial(int c)
-{
-	switch (c)
-	{
-		case '(':
-		case ')':
-		case '<':
-		case '>':
-		case '@':
-		case ',':
-		case ';':
-		case ':':
-		case '\\':
-		case '"':
-		case '/':
-		case '[':
-		case ']':
-		case '?':
-		case '=':
-		case '{':
-		case '}':
-		case ' ':
-		case '\t':
-			return true;
-		default:
-			return false;
-	}
-}
-
-bool request_parser::is_digit(int c)
-{
-	return c >= '0' && c <= '9';
-}
-
-} // namespace http_server

+ 0 - 94
Src/Experimental/http_server/request_parser.h

@@ -1,94 +0,0 @@
-//
-// request_parser.hpp
-// ~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_PARSER_H
-#define EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_PARSER_H
-
-#include <boost/logic/tribool.hpp>
-#include <boost/tuple/tuple.hpp>
-
-namespace http_server {
-
-struct request;
-
-/// Parser for incoming requests.
-class request_parser
-{
-public:
-	/// Construct ready to parse the request method.
-	request_parser();
-
-	/// Reset to initial parser state.
-	void reset();
-
-	/// Parse some data. The tribool return value is true when a complete request
-	/// has been parsed, false if the data is invalid, indeterminate when more
-	/// data is required. The InputIterator return value indicates how much of the
-	/// input has been consumed.
-	template<typename InputIterator>
-	boost::tuple<boost::tribool, InputIterator> parse(request& req,
-	        InputIterator begin, InputIterator end)
-	{
-		while(begin != end)
-		{
-			boost::tribool result = consume(req, *begin++);
-			if(result || !result)
-				return boost::make_tuple(result, begin);
-		}
-		boost::tribool result = boost::indeterminate;
-		return boost::make_tuple(result, begin);
-	}
-
-private:
-	/// Handle the next character of input.
-	boost::tribool consume(request& req, char input);
-
-	/// Check if a byte is an HTTP character.
-	static bool is_char(int c);
-
-	/// Check if a byte is an HTTP control character.
-	static bool is_ctl(int c);
-
-	/// Check if a byte is defined as an HTTP tspecial character.
-	static bool is_tspecial(int c);
-
-	/// Check if a byte is a digit.
-	static bool is_digit(int c);
-
-	/// The current state of the parser.
-	enum state
-	{
-		method_start,
-		method,
-		uri_start,
-		uri,
-		http_version_h,
-		http_version_t_1,
-		http_version_t_2,
-		http_version_p,
-		http_version_slash,
-		http_version_major_start,
-		http_version_major,
-		http_version_minor_start,
-		http_version_minor,
-		expecting_newline_1,
-		header_line_start,
-		header_lws,
-		header_name,
-		space_before_header_value,
-		header_value,
-		expecting_newline_2,
-		expecting_newline_3
-	} state_;
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HTTP_REQUEST_PARSER_H

+ 0 - 71
Src/Experimental/http_server/server.cc

@@ -1,71 +0,0 @@
-//
-// server.cc
-// ~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#include <boost/bind.hpp>
-#include "Experimental/http_server/server.h"
-
-namespace http_server {
-
-server::server(const std::string& address, const std::string& port,
-		const std::string& doc_root) :
-	io_service_(), acceptor_(io_service_), connection_manager_(),
-			new_connection_(new connection(io_service_, connection_manager_,
-					request_handler_)), request_handler_(doc_root)
-{
-	// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
-	boost::asio::ip::tcp::resolver resolver(io_service_);
-	boost::asio::ip::tcp::resolver::query query(address, port);
-	boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
-	acceptor_.open(endpoint.protocol());
-	acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
-	acceptor_.bind(endpoint);
-	acceptor_.listen();
-	acceptor_.async_accept(new_connection_->socket(), boost::bind(
-			&server::handle_accept, this, boost::asio::placeholders::error));
-}
-
-void server::run()
-{
-	// The io_service::run() call will block until all asynchronous operations
-	// have finished. While the server is running, there is always at least one
-	// asynchronous operation outstanding: the asynchronous accept call waiting
-	// for new incoming connections.
-	io_service_.run();
-}
-
-void server::stop()
-{
-	// Post a call to the stop function so that server::stop() is safe to call
-	// from any thread.
-	io_service_.post(boost::bind(&server::handle_stop, this));
-}
-
-void server::handle_accept(const boost::system::error_code& e)
-{
-	if (!e)
-	{
-		connection_manager_.start(new_connection_);
-		new_connection_.reset(new connection(io_service_, connection_manager_,
-				request_handler_));
-		acceptor_.async_accept(new_connection_->socket(), boost::bind(
-				&server::handle_accept, this, boost::asio::placeholders::error));
-	}
-}
-
-void server::handle_stop()
-{
-	// The server is stopped by cancelling all outstanding asynchronous
-	// operations. Once all operations have finished the io_service::run() call
-	// will exit.
-	acceptor_.close();
-	connection_manager_.stop_all();
-}
-
-} // namespace http_server

+ 0 - 63
Src/Experimental/http_server/server.h

@@ -1,63 +0,0 @@
-//
-// server.hpp
-// ~~~~~~~~~~
-//
-// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-
-#ifndef EXPERIMENTAL_HTTP_SERVER_HTTP_SERVER_H
-#define EXPERIMENTAL_HTTP_SERVER_HTTP_SERVER_H
-
-#include <boost/asio.hpp>
-#include <string>
-#include <boost/noncopyable.hpp>
-#include "Experimental/http_server/connection.h"
-#include "Experimental/http_server/connection_manager.h"
-#include "Experimental/http_server/request_handler.h"
-
-namespace http_server {
-
-/// The top-level class of the HTTP server.
-class server: private boost::noncopyable
-{
-public:
-	/// Construct the server to listen on the specified TCP address and port, and
-	/// serve up files from the given directory.
-	explicit server(const std::string& address, const std::string& port,
-	        const std::string& doc_root);
-
-	/// Run the server's io_service loop.
-	void run();
-
-	/// Stop the server.
-	void stop();
-
-private:
-	/// Handle completion of an asynchronous accept operation.
-	void handle_accept(const boost::system::error_code& e);
-
-	/// Handle a request to stop the server.
-	void handle_stop();
-
-	/// The io_service used to perform asynchronous operations.
-	boost::asio::io_service io_service_;
-
-	/// Acceptor used to listen for incoming connections.
-	boost::asio::ip::tcp::acceptor acceptor_;
-
-	/// The connection manager which owns all live connections.
-	connection_manager connection_manager_;
-
-	/// The next connection to be accepted.
-	connection_ptr new_connection_;
-
-	/// The handler for all incoming requests.
-	request_handler request_handler_;
-};
-
-} // namespace http_server
-
-#endif // EXPERIMENTAL_HTTP_SERVER_HTTP_SERVER_H