How to write simple HTTP proxy with Boost.Asio
How to write simple HTTP proxy with Boost.Asio
Меню:
In this article I describe process of writing of simple cross-platform HTTP proxy.
What we need
To develop this example (source code) I used Boost version 1.35. To build example, you can use cmake (but you can also build sources manually). To configure and build you need to run following commands (on Unix-like OSes)1:
> cmake .
> makeand after compilation you'll get
proxy-asio-asyncexecutable, that you can run from command line. This program accepts only one argument — number of threads, that will perform request processing (by default, this value is equal 2). Port number on which requests will accepted is hardcoded in source code and equal to100012.Architecture
As in previous examples, our program consists from three parts:
- the
mainfunction, that parses command line, creates separate threads for asio services together withserverobject, and then enters into request processing loop;serverclass, that accepts requests, and createsconnectionobject, that implements all logic of connection handling;connectionclass, that implements all logic, and pass data between client & web-server.The data processing is performed in asynchronous mode, and to distribute load between processors, we can use several independent asio services, that perform dispatching of calls (
asio::io_service).Note: Most hard part of the development of asynchronous code is proper design of data flow. I usually draw a state diagram and then transform each state to separate function. Presence of such diagram is very helpful for understanding of code by other developers.
Implementation
The
mainfunction is pretty simple, so we'll not analyze it — you can just look to its source code and understand, what it does (all common definitions are in file common.h.Implementation of server (the
serverclass — proxy-server.hpp & proxy-server.cpp) also not so much different from previous examples — changes were made only for method, that is used to select service, that will implement dispatching. In our example new service is selected from circular list of services, that allow us to get some load balancing for requests.All data processing logic is implemented in
connectionclass (proxy-conn.hpp & proxy-conn.cpp. I want to say, that parsing of headers was done without any optimisation3.Data processing is started from call to
startfunction fromserverclass, that accepts connection and creates new object ofconnectionclass. This function initiates asynchronous reading of request headers from browser.Reading of request headers is performed in the
handle_browser_read_headersfunction, that is called when we get some part of data from browser. I need to mention, that if we get incomplete headers (there is no empty string (\r\n\r\n)), then this function initiates new reading of headers, trying to get them all.After we get all headers, this function parses them and extracts version of HTTP protocol, used method and address of web-server (some of these data will be required to detect persistent connections).
After parsing of headers, this function calls
start_connect, that parses address of web-server, and if we don't have opened connection to this server, then it initiates process of name resolution. If we have opened connection, then we simply start data transfer withstart_write_to_serverfunction.The
handle_resolvefunction is called after name resolution, and if we get address of server, then it initiates process of connection establishing. Result of this process is handled byhandle_connectfunction, that initiates process of data transfer to the server withstart_write_to_serverfunction, that forms correct headers, and pass these data to the server.After transferring data to server, in function
handle_server_writewe initiate reading of response (only headers first) from server. Processing of headers is handled byhandle_server_read_headersfunction, that is similar to thehandle_browser_read_headers, but it also tries to understand — should we close connection after data transfer, or not. After processing of headers, this function initiates process of sending data to browser.After sending of headers, we create a loop, that transfer body of response from server to browser. In this loop we use two functions —
handle_server_read_bodyandhandle_browser_write, each of them calls another function until we don't finish reading of data from server (either number of bytes, specified in headers) or don't get end of file.If we'll get end of file, then we'll pass rest of data to the browser and close connection. Or if we use persistent connection, then we'll pass control to the
startfunction, that initiates reading of new headers from browser.That's all. As I already mentioned above, main problem — building of right data flow sequence.
1. If cmake can't find required libraries, you can specify their location with two <em>cmake's variables —
CMAKE_INCLUDE_PATHиCMAKE_LIBRARY_PATH, by running cmake following way:> cmake . -DCMAKE_INCLUDE_PATH=~/exp/include -DCMAKE_LIBRARY_PATH=~/exp/lib2. I could also implement code, that allow to specify port number in command line, but I was lazy, as this example was just a prototype to check some of my ideas.
3. There is also cpp-netlib project, that has (development in progress) parsers for basic protocols — HTTP, SMTP и т.п.
How to write simple HTTP proxy with Boost.Asio的更多相关文章
- 使用Boost.Asio编写通信程序
摘要:本文通过形像而活泼的语言简单地介绍了Boost::asio库的使用,作为asio的一个入门介绍是非常合适的,可以给人一种新鲜的感觉,同时也能让体验到asio的主要内容. Boost.Asio是一 ...
- boost.asio包装类st_asio_wrapper开发教程(2013.12.8更新)(二)
如果你是偶然浏览到这里,请先看 源代码及例程下载地址:命令行:svn checkout http://st-asio-wrapper.googlecode.com/svn/trunk/ st-asio ...
- c++ boost asio库初学习
前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...
- 如何在多线程leader-follower模式下正确的使用boost::asio。
#include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...
- BOOST.Asio——Tutorial
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- BOOST.Asio——Overview
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- boost asio sync
Service: #include<boost/asio.hpp> #include<boost/thread.hpp> #include<iostream> #i ...
- 网络库crash以及boost asio strand dispath分析
最近在做服务器的稳定性的相关测试,服务器的网络底层使用的是boost asio,然后自己做的二次封装以更好的满足需求. 服务器昨天晚上发现crash了一次,之前测试了将近半个多月,有一次是莫名的退出了 ...
- boost asio tcp server 拆分
从官方给出的示例中对于 boost::asio::ip::tcp::acceptor 类的使用,是直接使用构造函数进行构造对象,这一种方法用来学习是一个不错的方式. 但是要用它来做项目却是不能够满足我 ...
随机推荐
- windows安装Apache,注册服务出现“(OS 5)拒绝访问。 : AH00369: Failed to open the WinNT service manager..."错误
原文:http://blog.csdn.net/jaray/article/details/9950211 在安装Apache的时候,我下载的是zip格式,不是msi安装版,需要自己注册服务,才能在桌 ...
- ZXing工具类v1.0
package com.jadyer.util; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import jav ...
- LoadRunner监控数据库服务器
使用LoadRunner的数据库服务器资源监控器,可以在场景或会话步骤运行期间监控DB2.Oracle.SQL Server或Sybase数据库的资源使用率.在场景或会话步骤运行期间,使用这些监控器可 ...
- python算法之二分查找
说明:大部分代码是在网上找到的,好几个代码思路总结出来的 通常写算法,习惯用C语言写,显得思路清晰.可是假设一旦把思路确定下来,并且又不想打草稿.想高速写下来看看效果,还是python写的比較快.也看 ...
- 跟我一起写 Makefile(一)
跟我一起写 Makefile 陈皓 概述—— 什么是makefile?也许非常多Winodws的程序猿都不知道这个东西,由于那些Windows的IDE都为你做了这个工作,但我认为要作一个好的和pro ...
- eclipse不能自己主动弹出提示的解决的方法
曾经碰到过好几次eclipse不能自己主动弹出提示的情况,每次总是弄好之后就不再管它,结果下次遇到同样的问题,又到网上去搜索一大堆答案非常多都不能解决实际问题,费了时间还没有效果,如今这里记录下来下面 ...
- EasyUI - Combo组件
-自定义下拉组件,有别于ComboBox下拉组件. 效果: html代码: <input id ="box" /> <div id ="fruits&q ...
- Appium 命令行启动配置
Appium 安装过后,会有图形界面,同样也支持命令行参数的启动和配置 Windws: 在windows 安装配置Appium有三种方式: Node install -g appium .exe文件安 ...
- Windows通过远程桌面访问Ubuntu
关于Windows通过远程桌面访问Ubuntu 问题及目标 Window环境通过远程桌面访问Ubuntu Ubuntu机器端 1. 安装所需软件包 sudoapt-get install x ...
- GDI GDI+ 的区别
GDI+是GDI的下一个版本,它进行了很好的改进,并且易用性更好.GDI的一个好处就是你不必知道任何关于数据怎样在设备上渲染的细节,GDI+更好的实现了这个优点,也就是说,GDI是一个中低层API,你 ...