├── .gitattributes ├── .gitconfig ├── .gitignore ├── .travis.yml ├── AUTHORS ├── CMakeLists.txt ├── Jamfile ├── LICENSE ├── README.md ├── example ├── async_http_stream.cpp ├── form.cpp ├── imagebin.cpp ├── ip138.cpp ├── multi_download.cpp ├── sync_http_stream.cpp └── sync_imagebin.cpp ├── include ├── avhttp.hpp └── avhttp │ ├── async_read_body.hpp │ ├── bencode.hpp │ ├── bitfield.hpp │ ├── completion_condition.hpp │ ├── cookie.hpp │ ├── default_storage.hpp │ ├── detail │ ├── abi_prefix.hpp │ ├── abi_suffix.hpp │ ├── error_codec.hpp │ ├── escape_string.hpp │ ├── handler_type_requirements.hpp │ ├── io.hpp │ ├── parsers.hpp │ ├── socket_type.hpp │ ├── ssl_stream.hpp │ └── utf8.hpp │ ├── entry.hpp │ ├── file.hpp │ ├── file_upload.hpp │ ├── http_stream.hpp │ ├── impl │ ├── file.ipp │ ├── file_upload.ipp │ ├── http_stream.ipp │ ├── multi_download.ipp │ └── src.hpp │ ├── logging.hpp │ ├── multi_download.hpp │ ├── post_form.hpp │ ├── rangefield.hpp │ ├── read_body.hpp │ ├── settings.hpp │ ├── storage_interface.hpp │ ├── url.hpp │ └── version.hpp ├── project-root.jam ├── test ├── async_proxy_test.cpp ├── avhttp_include.cpp ├── cookie_test.cpp ├── multi_avhttp_test.cpp ├── multi_download_test.cpp ├── percent_encoding_test.cpp └── sync_proxy_test.cpp └── vcprojects ├── async_http_stream-vc2005.sln ├── async_http_stream-vc2005.vcproj ├── async_http_stream-vc2012.sln ├── async_http_stream-vc2012.vcxproj ├── async_http_stream-vc2012.vcxproj.filters ├── async_proxy_test-vc2005.sln ├── async_proxy_test-vc2005.vcproj ├── async_proxy_test-vc2008.sln ├── async_proxy_test-vc2008.vcproj ├── async_proxy_test-vc2012.sln ├── async_proxy_test-vc2012.vcxproj ├── async_proxy_test-vc2012.vcxproj.filters ├── cookie_test-vc2013.sln ├── cookie_test-vc2013.vcxproj ├── cookie_test-vc2013.vcxproj.filters ├── mini_http_server-vc2012.sln ├── mini_http_server-vc2012.vcxproj ├── mini_http_server-vc2012.vcxproj.filters ├── multi_avhttp_test-vc2012.sln ├── multi_avhttp_test-vc2012.vcxproj ├── multi_download-vc2005.sln ├── multi_download-vc2005.vcproj ├── multi_download-vc2012.sln ├── multi_download-vc2012.vcxproj ├── multi_download-vc2012.vcxproj.filters ├── percent_encoding_test-vc2012.sln ├── percent_encoding_test-vc2012.vcxproj ├── percent_encoding_test-vc2012.vcxproj.filters ├── sync_http_stream-2005.sln ├── sync_http_stream-2005.vcproj ├── sync_http_stream-vc2012.sln ├── sync_http_stream-vc2012.vcxproj ├── sync_http_stream-vc2012.vcxproj.filters ├── sync_proxy_test-vc2005.sln ├── sync_proxy_test-vc2005.vcproj ├── sync_proxy_test-vc2008.sln ├── sync_proxy_test-vc2008.vcproj ├── sync_proxy_test-vc2012.sln ├── sync_proxy_test-vc2012.vcxproj └── sync_proxy_test-vc2012.vcxproj.filters /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | #* text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [core] 2 | autocrlf = true 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | 15 | .kdev4/ 16 | *.kdev4 17 | build/ 18 | Debug/ 19 | Release/ 20 | 21 | #Visual Studio files 22 | *.[Oo]bj 23 | *.user 24 | *.aps 25 | *.pch 26 | *.vspscc 27 | *.vssscc 28 | *_i.c 29 | *_p.c 30 | *.ncb 31 | *.suo 32 | *.tlb 33 | *.tlh 34 | *.bak 35 | *.[Cc]ache 36 | *.ilk 37 | *.log 38 | *.lib 39 | *.sbr 40 | *.sdf 41 | *.sdf 42 | *.opensdf 43 | *.pdb 44 | *.idb 45 | *.res 46 | *.unsuccessfulbuild 47 | *.lastbuildstate 48 | *.tlog 49 | *.intermediate 50 | *.dll 51 | *.exp 52 | *.exe 53 | *.manifest 54 | *.rc 55 | ipch/ 56 | obj/ 57 | *.resfiles 58 | [Bb]in 59 | Binaries/ 60 | VS11.winrt/ 61 | !*.vcxproj.* 62 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | dist: trusty 3 | sudo: false 4 | os: 5 | - linux 6 | 7 | compiler: 8 | - gcc 9 | - clang 10 | 11 | before_install: 12 | - sudo apt-get update 13 | - sudo apt-get install zlib1g-dev 14 | - wget https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.bz2 15 | - sudo apt-get install ninja 16 | - tar -xf boost_1_65_1.tar.bz2 17 | - ( cd boost_1_65_1 && ./bootstrap.sh --prefix=/usr --with-libraries=date_time,filesystem,exception,log,locale,random,regex,program_options,system,thread && sudo ./b2 -j2 link=static install ) > /dev/null 18 | 19 | before_script: 20 | cmake . -DDEBUG=1 21 | 22 | script: 23 | - make 24 | - ./avhttp http://www.boost.org/LICENSE_1_0.txt 25 | - ./avhttp https://github.com/blog 26 | - cat ./multi_download.log 27 | 28 | branches: 29 | only: 30 | - master 31 | - C++11 32 | notifications: 33 | recipients: 34 | - microcaicai@gmail.com 35 | - jack.wgm@gmail.com 36 | email: 37 | on_success: change 38 | on_failure: always 39 | 40 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Author: Jack 2 | Author: coleman 3 | Author: eahydra 4 | Author: kiki 5 | Author: microcai -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | project(avhttp) 3 | #SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 4 | 5 | set(CMAKE_CXX_STANDARD 11) 6 | 7 | OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON) 8 | 9 | find_package(Boost 1.55 REQUIRED COMPONENTS locale date_time thread filesystem system program_options regex) 10 | find_package(Threads) 11 | 12 | find_package(ZLIB REQUIRED) 13 | 14 | add_definitions(-DAVHTTP_ENABLE_ZLIB) 15 | 16 | if (ENABLE_OPENSSL) 17 | find_package(OpenSSL) 18 | add_definitions(-DAVHTTP_ENABLE_OPENSSL) 19 | endif() 20 | 21 | if (UNIX AND NOT APPLE AND DEBUG) 22 | add_definitions(-DDEBUG) 23 | endif() 24 | 25 | if (MINGW) 26 | include(CheckCXXSourceCompiles) 27 | 28 | set(CHECK_FILE_ALLOCATED_RANGE_BUFFER_STRUCT_DEFINED 29 | " 30 | #define WIN32_LEAN_AND_MEAN 31 | #include 32 | #include 33 | 34 | int main() 35 | { 36 | _FILE_ALLOCATED_RANGE_BUFFER alloc_buf; 37 | return 0; 38 | }") 39 | 40 | check_cxx_source_compiles("${CHECK_FILE_ALLOCATED_RANGE_BUFFER_STRUCT_DEFINED}" 41 | HAVE_FILE_ALLOCATED_RANGE_BUFFER) 42 | 43 | if (HAVE_FILE_ALLOCATED_RANGE_BUFFER) 44 | add_definitions(-DHAVE_FILE_ALLOCATED_RANGE_BUFFER) 45 | endif() 46 | endif() 47 | 48 | include_directories(${Boost_INCLUDE_DIRS}) 49 | include_directories(include) 50 | 51 | add_library(libavhttp test/avhttp_include.cpp) 52 | 53 | set_target_properties(libavhttp 54 | PROPERTIES 55 | OUTPUT_NAME avhttp 56 | PREFIX "lib" 57 | CLEAN_DIRECT_OUTPUT 1) 58 | 59 | add_executable(avhttp example/multi_download.cpp) 60 | add_executable(form example/form.cpp) 61 | 62 | target_link_libraries(libavhttp ${ZLIB_LIBRARIES}) 63 | 64 | target_link_libraries(libavhttp ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES} ${CMAKE_DL_LIBS}) 65 | 66 | if (WIN32) 67 | add_definitions(-D_WIN32_WINNT=0x0501 -DWIN32_LEAN_AND_MEAN -DBOOST_THREAD_USE_LIB) 68 | target_link_libraries(libavhttp ws2_32) 69 | endif() 70 | 71 | if (UNIX AND NOT APPLE) 72 | target_link_libraries(libavhttp rt) 73 | endif() 74 | 75 | target_link_libraries(avhttp libavhttp) 76 | target_link_libraries(form libavhttp) 77 | 78 | install(DIRECTORY include/ DESTINATION include) 79 | install(DIRECTORY example/ DESTINATION share/avhttp/examples) 80 | -------------------------------------------------------------------------------- /Jamfile: -------------------------------------------------------------------------------- 1 | import stage ; 2 | import os ; 3 | import modules ; 4 | import errors ; 5 | import feature : feature ; 6 | import package ; 7 | import virtual-target ; 8 | 9 | BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ; 10 | OS = [ os.name ] ; 11 | 12 | #使用bjam编译, 必须设置BOOST_ROOT和BOOST_BUILD_PATH这两个环境变量. 13 | #BOOST_ROOT是boost的所在目录, 比如d:\boost_1_54这样子. 14 | #BOOST_BUILD_PATH指向比如d:\boost_1_54\tools\build\v2这个路径. 15 | 16 | BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ; 17 | CXXFLAGS = [ modules.peek : CXXFLAGS ] ; 18 | LDFLAGS = [ modules.peek : LDFLAGS ] ; 19 | 20 | ECHO "BOOST_ROOT =" $(BOOST_ROOT) ; 21 | ECHO "CXXFLAGS =" $(CXXFLAGS) ; 22 | ECHO "LDFLAGS =" $(LDFLAGS) ; 23 | ECHO "OS =" [ os.name ] ; 24 | 25 | local boost-library-search-path = 26 | /opt/local/lib 27 | /usr/lib 28 | /usr/local/lib 29 | $(BOOST_ROOT:T)/stage/lib 30 | ; 31 | 32 | 33 | lib boost_thread_mgw : : boost_thread-mgw46-mt-1_54 static ; 34 | lib boost_thread : : boost_thread $(boost-library-search-path) ; 35 | lib boost_system_mgw : : boost_system-mgw46-mt-1_54 static ; 36 | lib boost_system : : boost_system $(boost-library-search-path) ; 37 | lib boost_filesystem_mgw : : boost_filesystem-mgw46-mt-1_54 static ; 38 | lib boost_filesystem : : boost_filesystem $(boost-library-search-path) ; 39 | lib boost_regex_mgw : : boost_regex-mgw46-mt-1_54 static ; 40 | lib boost_regex : : boost_regex $(boost-library-search-path) ; 41 | lib boost_date_mgw : : boost_date_time-mgw46-mt-1_54 static ; 42 | lib boost_date : : boost_date_time $(boost-library-search-path) ; 43 | lib pthread : : pthread $(boost-library-search-path) ; 44 | lib ws2_32 : : ws2_32 static ; 45 | 46 | rule linking ( properties * ) 47 | { 48 | local result ; 49 | 50 | #输出所有配置信息, 主要用于参考. 51 | for local x in $(properties) 52 | { 53 | ECHO $(x) ; 54 | } 55 | 56 | # windows下编译. 57 | if $(OS) = "NT" 58 | { 59 | # mingw下编译. 60 | if gcc in $(properties) 61 | { 62 | result += $(BOOST_ROOT:T)/stage/lib ; 63 | result += 64 | boost_thread_mgw 65 | boost_system_mgw 66 | boost_filesystem_mgw 67 | boost_regex_mgw 68 | boost_date_mgw 69 | ws2_32 70 | ; 71 | } 72 | 73 | # vc下编译. 74 | if msvc in $(properties) 75 | { 76 | result += $(BOOST_ROOT:T)/stage/lib ; 77 | result += "user32.lib gdi32.lib kernel32.lib winspool.lib comdlg32.lib advapi32.lib" ; 78 | result += WIN32 ; 79 | result += _WIN32_WINNT=0x0501 ; 80 | result += _CONSOLE ; 81 | result += _CRT_SECURE_NO_WARNINGS ; 82 | result += _SCL_SECURE_NO_WARNINGS ; 83 | } 84 | } 85 | 86 | if $(OS) = "LINUX" 87 | { 88 | result += 89 | boost_thread 90 | boost_system 91 | boost_filesystem 92 | boost_regex 93 | ; 94 | } 95 | return $(result) ; 96 | } 97 | 98 | local usage-requirements = 99 | @linking 100 | ; 101 | 102 | project avhttp : requirements 103 | ./include 104 | $(BOOST_ROOT:T) 105 | off 106 | : build-dir bin 107 | ; 108 | 109 | project ip138 : requirements 110 | ./include 111 | $(BOOST_ROOT:T) 112 | off 113 | : build-dir bin 114 | ; 115 | 116 | project async_http : requirements 117 | ./include 118 | $(BOOST_ROOT:T) 119 | off 120 | : build-dir bin 121 | ; 122 | 123 | 124 | MULTI_SOURCES = 125 | example/multi_download.cpp 126 | ; 127 | 128 | exe avhttp 129 | : $(MULTI_SOURCES) 130 | : $(usage-requirements) 131 | : 132 | static 133 | static 134 | multi 135 | ; 136 | 137 | IP138_SOURCES = 138 | example/ip138.cpp 139 | ; 140 | 141 | exe ip138 142 | : $(IP138_SOURCES) 143 | : $(usage-requirements) 144 | : 145 | static 146 | static 147 | multi 148 | ; 149 | 150 | ASYNC_SOURCE = 151 | example/async_http_stream.cpp 152 | ; 153 | 154 | exe async_http 155 | : $(ASYNC_SOURCE) 156 | : $(usage-requirements) 157 | : 158 | static 159 | static 160 | multi 161 | ; 162 | 163 | IMAGEBIN_SOURCE = 164 | example/imagebin.cpp 165 | ; 166 | 167 | exe imagebin 168 | : $(IMAGEBIN_SOURCE) 169 | : $(usage-requirements) 170 | : 171 | static 172 | static 173 | multi 174 | ; 175 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | avhttp [![Build Status](https://travis-ci.org/avplayer/avhttp.png?branch=master)](https://travis-ci.org/avplayer/avhttp) 2 | ====== 3 | 4 | avhttp是一个基于Boost.Asio实现的HTTP客户端开发工具库. 5 | 6 | - 7 | ##### 简介 8 | 9 | 10 | 它支持HTTP(1.0/1.1)、HTTPS,断点续传,多线程并发下载,异步,HTTP/SOCKS4/SOCKS5代理支持等特性,开发者可以轻松的基于这个库开发其他相关应用。 11 | 12 | - 13 | ##### 快速上手 14 | ``` c++ 15 | #include 16 | #include "avhttp.hpp" 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | try 21 | { 22 | boost::asio::io_service io; 23 | avhttp::http_stream h(io); 24 | 25 | h.open("http://www.boost.org/LICENSE_1_0.txt"); 26 | std::cout << &h; 27 | } 28 | catch (std::exception& e) 29 | { 30 | std::cerr << "Error:" << e.what() << std::endl; 31 | } 32 | 33 | return 0; 34 | } 35 | ``` 36 | 37 | OK,以上示例将http流通过标准std::cout输出,非常简单明确,这对熟悉使用c++标准流的朋友来说,是一件不可多得的好事!比如下载数据需要通过std::fstream保存,将std::fstream对象替换掉示例中的std::cout即可! 38 | 39 | ``` c++ 40 | #include 41 | #include 42 | #include "avhttp.hpp" 43 | 44 | int main() 45 | { 46 | boost::asio::io_service io; 47 | avhttp::http_stream h(io); 48 | boost::system::error_code ec; 49 | 50 | // 打开url. 51 | h.open("http://www.boost.org/LICENSE_1_0.txt", ec); 52 | if (ec) { // 打开失败处理... 53 | std::cout << "Error: " << ec.message() << std::endl; 54 | return -1; 55 | } 56 | 57 | boost::array buf; 58 | 59 | // 循环读取数据. 60 | while (!ec) { 61 | std::size_t bytes_transferred = h.read_some(boost::asio::buffer(buf), ec); 62 | // 将下载的数据打印到屏幕. 63 | std::cout.write(buf.data(), bytes_transferred); 64 | } 65 | 66 | std::cout.flush(); 67 | h.close(ec); // 关闭. 68 | io.run(); 69 | 70 | return 0; 71 | } 72 | ``` 73 | 74 | OK,上面已经展示了一个简单却功能完善的示例用于同步方式HTTP下载,下面我来介绍异步并发下载多个URL的示范。 75 | 76 | ``` c++ 77 | #include 78 | 79 | #include 80 | #include 81 | #include 82 | #include "avhttp.hpp" 83 | 84 | class downloader : public boost::enable_shared_from_this 85 | { 86 | public: 87 | downloader(boost::asio::io_service &io) 88 | : m_io_service(io) 89 | , m_stream(io) 90 | {} 91 | ~downloader() 92 | {} 93 | 94 | public: 95 | void start(const std::string &url) 96 | { 97 | // 异步打开链接, 完成操作时将调用handle_open. 98 | m_stream.async_open(url, 99 | boost::bind(&downloader::handle_open, shared_from_this(), boost::asio::placeholders::error)); 100 | } 101 | 102 | void handle_open(const boost::system::error_code &ec) 103 | { 104 | if (!ec) 105 | { 106 | // 异步发起从http读取数据操作. 107 | m_stream.async_read_some(boost::asio::buffer(m_buffer, 1024), 108 | boost::bind(&downloader::handle_read, shared_from_this(), 109 | boost::asio::placeholders::bytes_transferred, 110 | boost::asio::placeholders::error 111 | ) 112 | ); 113 | } 114 | } 115 | 116 | void handle_read(int bytes_transferred, const boost::system::error_code &ec) 117 | { 118 | if (!ec) 119 | { 120 | // 输出到屏幕. 121 | std::cout.write(m_buffer.data(), bytes_transferred); 122 | // 继续读取http数据. 123 | m_stream.async_read_some(boost::asio::buffer(m_buffer), 124 | boost::bind(&downloader::handle_read, shared_from_this(), 125 | boost::asio::placeholders::bytes_transferred, 126 | boost::asio::placeholders::error 127 | ) 128 | ); 129 | } 130 | else if (ec == boost::asio::error::eof) 131 | { 132 | std::cout.write(m_buffer.data(), bytes_transferred); 133 | } 134 | std::cout.flush(); 135 | } 136 | 137 | private: 138 | boost::asio::io_service &m_io_service; 139 | avhttp::http_stream m_stream; 140 | boost::array m_buffer; 141 | }; 142 | 143 | int main(int argc, char* argv[]) 144 | { 145 | if (argc < 2) 146 | { 147 | std::cerr << "usage: " << argv[0] << " [url2] ...\n"; 148 | return -1; 149 | } 150 | 151 | try 152 | { 153 | boost::asio::io_service io; 154 | // 循环遍历url, 并创建下载. 155 | for (int i = 1; i < argc; i++) 156 | { 157 | std::string url = argv[i]; 158 | if (url.empty()) 159 | break; 160 | boost::shared_ptr d(new downloader(io)); 161 | d->start(url); 162 | } 163 | 164 | io.run(); 165 | } 166 | catch (std::exception &e) 167 | { 168 | std::cerr << "Exception: " << e.what() << std::endl; 169 | return -1; 170 | } 171 | 172 | return 0; 173 | } 174 | ``` 175 | 176 | 到现在为止,您已经了解了AVHTTP的同步和异步的基本用法,但事实上有时您还需要定制自己的HTTP请求,请继续往下看,下面介绍HTTP参数相关的设置。 177 | 178 | 179 | - 180 | 181 | ##### 使用request_opts定制HTTP请求 182 | 183 | ``` c++ 184 | boost::asio::io_service io; 185 | avhttp::http_stream h(io); 186 | 187 | avhttp::request_opts opt; 188 | // 可以insert多个选项. 189 | opt.insert("Connection", "Keep-Alive"); 190 | 191 | // 在这里设置到request_options. 192 | h.request_options(opt); 193 | 194 | // 然后再发起其它相关操作. 195 | h.open("http://www.boost.org/LICENSE_1_0.txt"); 196 | // ... 197 | ``` 198 | 199 | avhttp::request_opts 在发起HTTP请求之前的设定HTTP选项,它可以实现让您定制自己的http header。 200 | 201 | - 202 | 203 | 204 | ##### 使用proxy_settings设置代理 205 | 206 | ``` c++ 207 | boost::asio::io_service io; 208 | avhttp::http_stream h(io); 209 | 210 | avhttp::proxy_settings p; 211 | // 这里可以设置3种代理, socks4/socks5/http, 具体可以查看avhttp::proxy_settings的声明. 212 | p.type = avhttp::proxy_settings::http; 213 | p.hostname = "127.0.0.1"; 214 | p.port = 8080; 215 | h.proxy(p); // 设置代理. 216 | 217 | // 然后再发起其它相关操作. 218 | h.open("http://www.boost.org/LICENSE_1_0.txt"); 219 | // ... 220 | ``` 221 | 222 | 想了解更多的关于avhttp的使用(断点续传并发下载等),请参考avhttp的example代码。 223 | 224 | - 225 | 226 | 227 | ##### 常用问题 228 | 229 | * 如果需要支持https,它依赖openssl,请自行编译openssl或到 http://sourceforge.net/projects/avplayer/files/develop/OpenSSL-dev/ 下载已经编译好的ssl开发包,并在项目中设置,启用AVHTTP_ENABLE_OPENSSL。 230 | * 如果需要支持gzip,它依赖zlib,需要在项目中启用AVHTTP_ENABLE_ZLIB,当然您还需要使用avhttp::request_opts指定相应Accept-Encoding。 231 | * 如果您只有一个线程运行io_service,那么定义AVHTTP_DISABLE_THREAD可以避免锁来提高工作效率。 232 | * 如果您还有其它任何问题,请加[telegram群组](https://telegram.me/joinchat/C3WytT4RMvLgPZ92_Txq8g)或IRC #avplayer @ irc.freenode.net,或直接mailto:jack.wgm@gmail.com。 233 | -------------------------------------------------------------------------------- /example/async_http_stream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "avhttp.hpp" 9 | 10 | class downloader : public boost::enable_shared_from_this 11 | { 12 | public: 13 | downloader(boost::asio::io_service &io) 14 | : m_io_service(io) 15 | , m_stream(io) 16 | {} 17 | ~downloader() 18 | {} 19 | 20 | public: 21 | void start(const std::string &url) 22 | { 23 | avhttp::proxy_settings p; 24 | p.type = avhttp::proxy_settings::http; 25 | p.hostname = "218.188.13.237"; 26 | p.port = 8888; 27 | 28 | // 设置代理服务器. 29 | // m_stream.proxy(p); 30 | 31 | // 设置处理https不进行认证. 32 | m_stream.check_certificate(false); 33 | 34 | avhttp::request_opts opt; 35 | opt.insert(avhttp::http_options::accept_encoding, "gzip"); 36 | // 设置接受gzip格式, 需要启用AVHTTP_ENABLE_ZLIB. 37 | // m_stream.request_options(opt); 38 | 39 | m_stream.async_open(url, 40 | boost::bind(&downloader::handle_open, shared_from_this(), boost::asio::placeholders::error)); 41 | } 42 | 43 | void handle_open(const boost::system::error_code &ec) 44 | { 45 | if (!ec) 46 | { 47 | m_stream.async_read_some(boost::asio::buffer(m_buffer, 1024), 48 | boost::bind(&downloader::handle_read, shared_from_this(), 49 | boost::asio::placeholders::bytes_transferred, 50 | boost::asio::placeholders::error 51 | ) 52 | ); 53 | // 也可以: 54 | // boost::asio::async_read(m_stream, boost::asio::buffer(m_buffer, 597), 55 | // boost::bind(&downloader::handle_read, shared_from_this(), 56 | // boost::asio::placeholders::bytes_transferred, 57 | // boost::asio::placeholders::error)); 58 | } 59 | } 60 | 61 | void handle_read(int bytes_transferred, const boost::system::error_code &ec) 62 | { 63 | if (!ec) 64 | { 65 | std::cout.write(m_buffer.data(), bytes_transferred); 66 | m_stream.async_read_some(boost::asio::buffer(m_buffer), 67 | boost::bind(&downloader::handle_read, shared_from_this(), 68 | boost::asio::placeholders::bytes_transferred, 69 | boost::asio::placeholders::error 70 | ) 71 | ); 72 | } 73 | else if (ec == boost::asio::error::eof) 74 | { 75 | std::cout.write(m_buffer.data(), bytes_transferred); 76 | } 77 | std::cout.flush(); 78 | } 79 | 80 | private: 81 | boost::asio::io_service &m_io_service; 82 | avhttp::http_stream m_stream; 83 | boost::array m_buffer; 84 | }; 85 | 86 | int main(int argc, char* argv[]) 87 | { 88 | if (argc != 2) 89 | { 90 | std::cerr << "usage: " << argv[0] << " \n"; 91 | std::cerr << "usage: " << argv[0] << " \n"; 92 | return -1; 93 | } 94 | 95 | boost::asio::io_service io; 96 | std::fstream file; 97 | std::string filename = argv[1]; 98 | bool urllist = false; 99 | 100 | // 如果是存在的文件, 则查看是否是txt文件, 允许.txt文件中多个url. 101 | // 在一个txt文件中可以保存多行url, 比如文件urls.txt中可以是: 102 | // http://www.boost.org/LICENSE_1_0.txt 103 | // http://www.microsoft.com/en-us/default.aspx 104 | // 本程序将同时下载这两个链接, 并且是单线程的哦!!! 105 | if (boost::filesystem::exists(filename)) 106 | { 107 | if (boost::filesystem::extension(filename) == ".txt") 108 | { 109 | urllist = true; 110 | file.open(filename.c_str()); 111 | } 112 | } 113 | 114 | for (;;) 115 | { 116 | if (!urllist) // 单个文件下载. 117 | { 118 | boost::shared_ptr d(new downloader(io)); 119 | d->start(filename); 120 | break; 121 | } 122 | else // 从url列表中下载, txt文件中的每一行是一个url. 123 | { 124 | std::string url; 125 | std::getline(file, url); 126 | if (url.empty()) 127 | break; 128 | boost::shared_ptr d(new downloader(io)); 129 | d->start(url); 130 | } 131 | } 132 | 133 | io.run(); 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /example/form.cpp: -------------------------------------------------------------------------------- 1 | #include "avhttp.hpp" 2 | #include 3 | #include 4 | namespace asio = boost::asio; 5 | 6 | int main() 7 | { 8 | asio::io_service io; 9 | avhttp::http_stream stream(io); 10 | std::map key_values; 11 | key_values["name"] = "hyq"; 12 | key_values["age"] = "25"; 13 | avhttp::post_form(stream, key_values); 14 | stream.open("http://localhost/"); 15 | std::cout << &stream; 16 | } 17 | -------------------------------------------------------------------------------- /example/imagebin.cpp: -------------------------------------------------------------------------------- 1 | // 通过avhttp提供的file_upload将图片上传到imagebin.org 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "avhttp.hpp" 9 | 10 | class image_bin : public boost::noncopyable 11 | { 12 | public: 13 | image_bin(boost::asio::io_service& io, const std::string& filename, const std::string& nickname) 14 | : m_io(io) 15 | , m_file_upload(io) 16 | , m_filename(filename) 17 | { 18 | avhttp::file_upload::form_args args; 19 | boost::system::error_code ec; 20 | avhttp::request_opts opts; 21 | 22 | opts.insert("Referer", "http://imagebin.org/index.php?page=add"); 23 | opts.insert(avhttp::http_options::user_agent, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"); 24 | opts.insert("Origin", "http://imagebin.org"); 25 | opts.insert("Cache-Control", "max-age=0"); 26 | opts.insert("Accept-Language", "zh-CN,zh;q=0.8"); 27 | 28 | m_file_upload.request_option(opts); 29 | 30 | // disable auto redirect. 31 | avhttp::http_stream& http = m_file_upload.get_http_stream(); 32 | http.max_redirects(0); 33 | 34 | args["nickname"] = nickname; 35 | args["remember_nickname"] = "Y"; 36 | args["title"] = boost::filesystem::path(m_filename).leaf().string(); 37 | args["description"] = "Upload by avhttp"; 38 | args["disclaimer_agree"] = "Y"; 39 | args["Submit"] = "Submit"; 40 | args["mode"] = "add"; 41 | 42 | m_file_upload.async_open("http://imagebin.org/index.php", 43 | m_filename, "image", args, 44 | boost::bind(&image_bin::open_handle, this, boost::asio::placeholders::error)); 45 | } 46 | 47 | void open_handle(boost::system::error_code ec) 48 | { 49 | if (!ec) 50 | { 51 | m_file.open(m_filename, ec); 52 | if (ec) 53 | { 54 | std::cerr << "Error: " << ec.message() << std::endl; 55 | return; 56 | } 57 | std::streamsize readed = m_file.read(m_buffer.data(), 1024); 58 | boost::asio::async_write(m_file_upload, boost::asio::buffer(m_buffer, readed), 59 | boost::bind(&image_bin::write_handle, this, 60 | boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 61 | } 62 | } 63 | 64 | void write_handle(boost::system::error_code ec, std::size_t bytes_transfered) 65 | { 66 | if (!ec) 67 | { 68 | if (m_file.eof()) 69 | { 70 | m_file_upload.async_write_tail(boost::bind( 71 | &image_bin::tail_handle, this, boost::asio::placeholders::error)); 72 | } 73 | else 74 | { 75 | std::streamsize readed = m_file.read(m_buffer.data(), 1024); 76 | boost::asio::async_write(m_file_upload, boost::asio::buffer(m_buffer, readed), 77 | boost::bind(&image_bin::write_handle, this, 78 | boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 79 | } 80 | } 81 | } 82 | 83 | void tail_handle(boost::system::error_code ec) 84 | { 85 | if (!ec || ec == avhttp::errc::found) 86 | { 87 | avhttp::http_stream& http = m_file_upload.get_http_stream(); 88 | std::string path = http.location(); 89 | std::cout << path << std::endl; 90 | } 91 | } 92 | 93 | private: 94 | boost::asio::io_service& m_io; 95 | avhttp::file_upload m_file_upload; 96 | avhttp::default_storge m_file; 97 | boost::array m_buffer; 98 | std::string m_filename; 99 | }; 100 | 101 | int main(int argc, char* argv[]) 102 | { 103 | if (argc < 2) 104 | { 105 | std::cerr << "usage: " << argv[0] << " [nickname]\n"; 106 | return -1; 107 | } 108 | 109 | std::string extension = boost::filesystem::path(argv[1]).extension().string(); 110 | boost::to_lower(extension); 111 | if (extension != ".png" && 112 | extension != ".jpg" && 113 | extension != ".jpeg" && 114 | extension != ".gif" && 115 | extension != ".jpe") 116 | { 117 | std::cerr << "You must provide a image!\n"; 118 | return -1; 119 | } 120 | 121 | std::string nickname = "Jackarain"; 122 | if (argc >= 3) 123 | { 124 | nickname = argv[2]; 125 | } 126 | 127 | boost::asio::io_service io; 128 | image_bin img(io, argv[1], nickname); 129 | io.run(); 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /example/ip138.cpp: -------------------------------------------------------------------------------- 1 | ///这个示例是用于从IP138.COM网站获得IP或域名所对应的地理位置. 2 | #include 3 | #include 4 | #include 5 | #include "avhttp.hpp" 6 | 7 | int main(int argc, char* argv[]) 8 | { 9 | if (argc != 2) 10 | { 11 | std::cerr << "usage: " << argv[0] << " \n"; 12 | return -1; 13 | } 14 | 15 | boost::asio::io_service io; 16 | boost::system::error_code ec; 17 | 18 | std::string ip = argv[1]; 19 | boost::trim(ip); 20 | // 构造查询IP的URL. 21 | std::string query_url = "http://ip138.com/ips138.asp?ip=" + ip; 22 | 23 | avhttp::http_stream h(io); 24 | h.open(query_url, ec); 25 | if (ec) 26 | return -1; 27 | 28 | std::string result; 29 | boost::asio::streambuf response; 30 | std::istream is(&h); 31 | 32 | try 33 | { 34 | while (is.good()) 35 | { 36 | std::getline(is, result); 37 | std::size_t pos = result.find("
  • "); 38 | if (pos == std::string::npos) 39 | continue; 40 | // 匹配出地址信息. 41 | boost::cmatch what; 42 | boost::regex ex("
    • (.*)?<\\/li>
    • "); 43 | if(boost::regex_search(result.c_str(), what, ex)) 44 | { 45 | result = std::string(what[1]); 46 | std::string gbk_ex; 47 | gbk_ex.push_back('\xA3'); 48 | gbk_ex.push_back('\xBA'); 49 | gbk_ex += "(.*)"; 50 | ex.assign(gbk_ex); 51 | if(boost::regex_search(result.c_str(), what, ex)) 52 | { 53 | result = std::string(what[1]); 54 | // 输出地址信息. 55 | if (!result.empty()) 56 | std::cout << result << std::endl; 57 | } 58 | break; 59 | } 60 | } 61 | } 62 | catch (std::exception& e) 63 | { 64 | std::cerr << e.what() << std::endl; 65 | return -1; 66 | } 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /example/multi_download.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "avhttp.hpp" 6 | 7 | std::string to_string(int v, int width) 8 | { 9 | std::stringstream s; 10 | s.flags(std::ios_base::right); 11 | s.width(width); 12 | s.fill(' '); 13 | s << v; 14 | return s.str(); 15 | } 16 | 17 | std::string& to_string(float v, int width, int precision = 3) 18 | { 19 | // this is a silly optimization 20 | // to avoid copying of strings 21 | enum { num_strings = 20 }; 22 | static std::string buf[num_strings]; 23 | static int round_robin = 0; 24 | std::string& ret = buf[round_robin]; 25 | ++round_robin; 26 | if (round_robin >= num_strings) round_robin = 0; 27 | ret.resize(20); 28 | int size = sprintf(&ret[0], "%*.*f", width, precision, v); 29 | ret.resize((std::min)(size, width)); 30 | return ret; 31 | } 32 | 33 | std::string add_suffix(float val, char const* suffix = 0) 34 | { 35 | std::string ret; 36 | if (val == 0) 37 | { 38 | ret.resize(4 + 2, ' '); 39 | if (suffix) ret.resize(4 + 2 + strlen(suffix), ' '); 40 | return ret; 41 | } 42 | 43 | const char* prefix[] = {"kB", "MB", "GB", "TB"}; 44 | const int num_prefix = sizeof(prefix) / sizeof(const char*); 45 | for (int i = 0; i < num_prefix; ++i) 46 | { 47 | val /= 1024.f; 48 | if (std::fabs(val) < 1024.f) 49 | { 50 | ret = to_string(val, 4); 51 | ret += prefix[i]; 52 | if (suffix) ret += suffix; 53 | return ret; 54 | } 55 | } 56 | ret = to_string(val, 4); 57 | ret += "PB"; 58 | if (suffix) ret += suffix; 59 | return ret; 60 | } 61 | 62 | int main(int argc, char* argv[]) 63 | { 64 | if (argc != 2) 65 | { 66 | std::cerr << "usage: " << argv[0] << " \n"; 67 | return -1; 68 | } 69 | 70 | #if WIN32 71 | std::locale::global(std::locale("")); 72 | #endif 73 | 74 | AVHTTP_INIT_LOGGER("multi_download.log"); 75 | 76 | try { 77 | boost::asio::io_service io; 78 | avhttp::multi_download d(io); 79 | 80 | avhttp::settings s; 81 | s.check_certificate = false; 82 | // s.m_download_rate_limit = 102400; 83 | 84 | d.start(argv[1], s); 85 | 86 | if (d.file_size() != -1) 87 | std::cout << "file \'" << d.file_name().c_str() << 88 | "\' size is: " << "(" << d.file_size() << " bytes) " << add_suffix((float)d.file_size()).c_str() << std::endl; 89 | 90 | boost::thread t(boost::bind(&boost::asio::io_service::run, &io)); 91 | 92 | if (d.file_size() != -1) 93 | { 94 | printf("\n"); 95 | int percent = 0; 96 | boost::int64_t bytes_download = 0; 97 | while (percent != 100 && !d.stopped()) 98 | { 99 | boost::int64_t file_size = d.file_size(); 100 | bytes_download = d.bytes_download(); 101 | percent = (int)(((double)bytes_download / (double)file_size) * 100.0f); 102 | boost::this_thread::sleep(boost::posix_time::millisec(200)); 103 | printf("\r"); 104 | printf("%3d%% [", percent); 105 | int progress = percent / 2; 106 | for (int i = 0; i < progress; i++) 107 | printf("="); 108 | if (progress != 50) 109 | printf(">"); 110 | for (int i = 0; i < 49 - progress; i++) 111 | printf(" "); 112 | printf("] %s %s/s", add_suffix((float)bytes_download).c_str(), add_suffix((float)d.download_rate()).c_str()); 113 | } 114 | printf("\n"); 115 | } 116 | 117 | t.join(); 118 | 119 | std::cout << "\n*** download completed! ***\n"; 120 | } 121 | catch (std::exception& e) 122 | { 123 | std::cerr << e.what() << std::endl; 124 | return -1; 125 | } 126 | 127 | return 0; 128 | } 129 | -------------------------------------------------------------------------------- /example/sync_http_stream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "avhttp.hpp" 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | if (argc != 2) 8 | { 9 | std::cerr << "usage: " << argv[0] << " \n"; 10 | return -1; 11 | } 12 | 13 | try { 14 | boost::asio::io_service io; 15 | avhttp::http_stream h(io); 16 | 17 | // 可以设置请求选项. 18 | // avhttp::request_opts opt; 19 | // opt.insert("Connection", "Keep-Alive"); 20 | // h.request_options(opt); 21 | 22 | h.open(argv[1]); 23 | 24 | boost::array buf; 25 | boost::system::error_code ec; 26 | std::size_t file_size = 0; 27 | while (!ec) 28 | { 29 | std::size_t bytes_transferred = 0; 30 | // 也可以: bytes_transferred = boost::asio::read(h, boost::asio::buffer(buf), ec); 31 | bytes_transferred = h.read_some(boost::asio::buffer(buf), ec); 32 | file_size += bytes_transferred; 33 | std::cout.write(buf.data(), bytes_transferred); 34 | } 35 | std::cout.flush(); 36 | 37 | h.close(ec); 38 | 39 | io.run(); 40 | } 41 | catch (boost::system::system_error &e) 42 | { 43 | std::cerr << e.what() << std::endl; 44 | return -1; 45 | } 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /example/sync_imagebin.cpp: -------------------------------------------------------------------------------- 1 | // upload image to imagebin.org 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "avhttp.hpp" 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | if (argc < 2) 13 | { 14 | std::cerr << "usage: " << argv[0] << " [nickname]\n"; 15 | return -1; 16 | } 17 | 18 | std::string filename = std::string(argv[1]); 19 | std::string extension = boost::filesystem::path(filename).extension().string(); 20 | boost::to_lower(extension); 21 | if (extension != ".png" && 22 | extension != ".jpg" && 23 | extension != ".jpeg" && 24 | extension != ".gif" && 25 | extension != ".jpe") 26 | { 27 | std::cerr << "You must provide a image!\n"; 28 | return -1; 29 | } 30 | 31 | boost::asio::io_service io; 32 | avhttp::file_upload upload(io); 33 | 34 | avhttp::request_opts opts; 35 | opts.insert("Referer", "http://imagebin.org/index.php?page=add"); 36 | opts.insert(avhttp::http_options::user_agent, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36"); 37 | opts.insert("Origin", "http://imagebin.org"); 38 | opts.insert("Cache-Control", "max-age=0"); 39 | opts.insert("Accept-Language", "zh-CN,zh;q=0.8"); 40 | 41 | upload.request_option(opts); 42 | 43 | avhttp::file_upload::form_args args; 44 | args["nickname"] = "Cai"; 45 | args["remember_nickname"] = "Y"; 46 | args["title"] = boost::filesystem::path(filename).leaf().string(); 47 | args["description"] = "Upload by avhttp"; 48 | args["disclaimer_agree"] = "Y"; 49 | args["Submit"] = "Submit"; 50 | args["mode"] = "add"; 51 | avhttp::http_stream& http = upload.get_http_stream(); 52 | http.max_redirects(0); 53 | boost::system::error_code ec; 54 | upload.open("http://imagebin.org/index.php", filename, "image", args, ec); 55 | if (ec) 56 | { 57 | return -1; 58 | } 59 | // start upload image. 60 | avhttp::default_storge file; 61 | file.open(filename, ec); 62 | if (ec) 63 | { 64 | return -1; 65 | } 66 | 67 | boost::array buffer; 68 | while (!file.eof()) 69 | { 70 | int readed = file.read(buffer.data(), 1024); 71 | boost::asio::write(upload, boost::asio::buffer(buffer, readed), ec); 72 | if (ec) 73 | { 74 | return -1; 75 | } 76 | } 77 | upload.write_tail(ec); 78 | if (ec) 79 | { 80 | return -1; 81 | } 82 | 83 | // output image url. 84 | std::string path = http.location(); 85 | std::cout << path << std::endl; 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /include/avhttp.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // avhttp.hpp 3 | // ~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_HPP 12 | #define AVHTTP_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include "avhttp/detail/abi_prefix.hpp" 19 | 20 | #include 21 | #include 22 | 23 | namespace 24 | { 25 | // 由于avhttp使用了boost.locale, 必须使用boost版本1.48或以上版本!!! 26 | // 原因是boost.locale是在boost-1.48加入boost的. 27 | BOOST_STATIC_ASSERT_MSG(BOOST_VERSION >= 104800, "You must use boost-1.48 or later!!!"); 28 | } 29 | 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | 39 | // Default to a header-only implementation. 40 | #if !defined(AVHTTP_HEADER_ONLY) 41 | # if !defined(AVHTTP_SEPARATE_COMPILATION) 42 | # define AVHTTP_HEADER_ONLY 1 43 | # endif // !defined(AVHTTP_SEPARATE_COMPILATION) 44 | #endif // !defined(AVHTTP_HEADER_ONLY) 45 | 46 | #if defined(AVHTTP_HEADER_ONLY) 47 | # define AVHTTP_DECL inline 48 | # else 49 | # define AVHTTP_DECL 50 | #endif // defined(AVHTTP_HEADER_ONLY) 51 | 52 | // If AVHTTP_DECL isn't defined yet define it now. 53 | #if !defined(AVHTTP_DECL) 54 | # define AVHTTP_DECL 55 | #endif // !defined(AVHTTP_DECL) 56 | 57 | #include "avhttp/version.hpp" 58 | #include "avhttp/logging.hpp" 59 | #include "avhttp/detail/error_codec.hpp" 60 | #include "avhttp/url.hpp" 61 | #include "avhttp/http_stream.hpp" 62 | #ifndef AVHTTP_DISABLE_FILE_UPLOAD 63 | # if (BOOST_VERSION >= 105400) 64 | # include "avhttp/file_upload.hpp" 65 | # endif 66 | #endif 67 | #ifndef AVHTTP_DISABLE_MULTI_DOWNLOAD 68 | # include "avhttp/entry.hpp" 69 | # include "avhttp/bencode.hpp" 70 | # include "avhttp/rangefield.hpp" 71 | # include "avhttp/bitfield.hpp" 72 | # include "avhttp/multi_download.hpp" 73 | #endif 74 | #if (BOOST_VERSION >= 105400) 75 | # include "avhttp/async_read_body.hpp" 76 | #endif 77 | 78 | #include "avhttp/read_body.hpp" 79 | 80 | #include "avhttp/post_form.hpp" 81 | 82 | #include "avhttp/detail/abi_suffix.hpp" 83 | 84 | 85 | #endif // AVHTTP_HPP 86 | -------------------------------------------------------------------------------- /include/avhttp/async_read_body.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // async_read_body.hpp 3 | // ~~~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // Copyright (C) 2012 - 2013 微蔡 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_MISC_HTTP_ASYNC_READBODY_HPP 13 | #define AVHTTP_MISC_HTTP_ASYNC_READBODY_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | BOOST_STATIC_ASSERT_MSG(BOOST_VERSION >= 105400, "You must use boost-1.54 or later!!!"); 20 | 21 | #include "avhttp/http_stream.hpp" 22 | #include "avhttp/completion_condition.hpp" 23 | 24 | #include 25 | 26 | namespace avhttp { 27 | namespace detail { 28 | 29 | template 30 | class read_body_op : boost::asio::coroutine 31 | { 32 | public: 33 | read_body_op(AsyncReadStream& stream, const avhttp::url& url, 34 | MutableBufferSequence& buffers, Handler handler) 35 | : m_stream(stream) 36 | , m_buffers(buffers) 37 | , m_handler(BOOST_ASIO_MOVE_CAST(Handler)(handler)) 38 | { 39 | m_stream.async_open(url, *this); 40 | } 41 | 42 | void operator()(const boost::system::error_code& ec, std::size_t bytes_transferred = 0) 43 | { 44 | reenter(this) 45 | { 46 | if(!ec || ec == avhttp::errc::accepted) 47 | { 48 | BOOST_ASIO_CORO_YIELD boost::asio::async_read( 49 | m_stream, m_buffers, transfer_response_body(m_stream.content_length()), *this); 50 | } 51 | else 52 | { 53 | m_handler(ec, bytes_transferred); 54 | return; 55 | } 56 | 57 | if(ec == boost::asio::error::eof && m_stream.content_length() == -1) 58 | { 59 | m_handler(boost::system::error_code(), bytes_transferred); 60 | } 61 | else 62 | { 63 | m_handler(ec, bytes_transferred); 64 | } 65 | } 66 | } 67 | 68 | // private: 69 | AsyncReadStream& m_stream; 70 | MutableBufferSequence& m_buffers; 71 | Handler m_handler; 72 | }; 73 | 74 | template 75 | read_body_op 76 | make_read_body_op(AsyncReadStream& stream, 77 | const avhttp::url& url, MutableBufferSequence& buffers, Handler handler) 78 | { 79 | return read_body_op( 80 | stream, url, buffers, handler); 81 | } 82 | 83 | } // namespace detail 84 | 85 | 86 | ///用于http_stream异步访问url. 87 | // 这个函数用于http_stream异步访问指定的url, 并通过handler回调通知用户, 数据将 88 | // 保存在用户事先提供的buffers中. 89 | // @注意: 90 | // 1. 该函数回调条件为直到读取完整的body或eof或其它错误, 错误信息通过error_code传回. 91 | // 2. 在完成整个过程中, 应该保持 stream 和 buffers的生命期. 92 | // @param stream 一个http_stream对象. 93 | // @param url 指定的url. 94 | // @param buffers 一个或多个用于读取数据的缓冲区 95 | // 这个类型必须满足MutableBufferSequence, MutableBufferSequence的定义. 96 | // 具体可参考boost.asio文档中相应的描述. 97 | // @param handler在读取操作完成或出现错误时, 将被回调, 它满足以下条件: 98 | // @begin code 99 | // void handler( 100 | // const boost::system::error_code& ec, // 用于返回操作状态. 101 | // std::size_t bytes_transferred // 返回读取的数据字节数. 102 | // ); 103 | // @end code 104 | // @begin example 105 | // void handler(const boost::system::error_code& ec, std::size_t bytes_transferred) 106 | // { 107 | // // 处理异步回调. 108 | // } 109 | // ... 110 | // avhttp::http_stream h(io); 111 | // async_read_body(h, "http://www.boost.org/LICENSE_1_0.txt", 112 | // boost::asio::buffer(data, 1024), handler); 113 | // io.run(); 114 | // ... 115 | // @end example 116 | template 117 | AVHTTP_DECL void async_read_body(AsyncReadStream& stream, 118 | const avhttp::url& url, MutableBufferSequence& buffers, Handler handler) 119 | { 120 | detail::make_read_body_op(stream, url, buffers, handler); 121 | } 122 | 123 | } // namespace avhttp 124 | 125 | #include 126 | 127 | #endif // AVHTTP_MISC_HTTP_ASYNC_READBODY_HPP 128 | -------------------------------------------------------------------------------- /include/avhttp/bencode.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // bencode.hpp 3 | // ~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2003, Arvid Norberg All rights reserved. 6 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_BENCODE_HPP 13 | #define AVHTTP_BENCODE_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "avhttp/entry.hpp" 24 | #include "avhttp/detail/escape_string.hpp" 25 | 26 | namespace avhttp { 27 | 28 | namespace detail { 29 | 30 | template 31 | int write_string(OutIt& out, const std::string& val) 32 | { 33 | for (std::string::const_iterator i = val.begin() 34 | , end(val.end()); i != end; ++i) 35 | *out++ = *i; 36 | return val.length(); 37 | } 38 | 39 | inline char const* integer_to_str(char* buf, int size, entry::integer_type val) 40 | { 41 | int sign = 0; 42 | if (val < 0) 43 | { 44 | sign = 1; 45 | val = -val; 46 | } 47 | buf[--size] = '\0'; 48 | if (val == 0) buf[--size] = '0'; 49 | for (; size > sign && val != 0;) 50 | { 51 | buf[--size] = '0' + char(val % 10); 52 | val /= 10; 53 | } 54 | if (sign) buf[--size] = '-'; 55 | return buf + size; 56 | } 57 | 58 | template 59 | int write_integer(OutIt& out, entry::integer_type val) 60 | { 61 | // the stack allocated buffer for keeping the 62 | // decimal representation of the number can 63 | // not hold number bigger than this: 64 | BOOST_STATIC_ASSERT(sizeof(entry::integer_type) <= 8); 65 | char buf[21]; 66 | int ret = 0; 67 | for (char const* str = integer_to_str(buf, 21, val); 68 | *str != 0; ++str) 69 | { 70 | *out = *str; 71 | ++out; 72 | ++ret; 73 | } 74 | return ret; 75 | } 76 | 77 | template 78 | void write_char(OutIt& out, char c) 79 | { 80 | *out = c; 81 | ++out; 82 | } 83 | 84 | template 85 | std::string read_until(InIt& in, InIt end, char end_token, bool& err) 86 | { 87 | std::string ret; 88 | if (in == end) 89 | { 90 | err = true; 91 | return ret; 92 | } 93 | while (*in != end_token) 94 | { 95 | ret += *in; 96 | ++in; 97 | if (in == end) 98 | { 99 | err = true; 100 | return ret; 101 | } 102 | } 103 | return ret; 104 | } 105 | 106 | template 107 | void read_string(InIt& in, InIt end, int len, std::string& str, bool& err) 108 | { 109 | BOOST_ASSERT(len >= 0); 110 | for (int i = 0; i < len; ++i) 111 | { 112 | if (in == end) 113 | { 114 | err = true; 115 | return; 116 | } 117 | str += *in; 118 | ++in; 119 | } 120 | } 121 | 122 | // returns the number of bytes written 123 | template 124 | int bencode_recursive(OutIt& out, const entry& e) 125 | { 126 | int ret = 0; 127 | switch(e.type()) 128 | { 129 | case entry::int_t: 130 | write_char(out, 'i'); 131 | ret += write_integer(out, e.integer()); 132 | write_char(out, 'e'); 133 | ret += 2; 134 | break; 135 | case entry::string_t: 136 | ret += write_integer(out, e.string().length()); 137 | write_char(out, ':'); 138 | ret += write_string(out, e.string()); 139 | ret += 1; 140 | break; 141 | case entry::list_t: 142 | write_char(out, 'l'); 143 | for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) 144 | ret += bencode_recursive(out, *i); 145 | write_char(out, 'e'); 146 | ret += 2; 147 | break; 148 | case entry::dictionary_t: 149 | write_char(out, 'd'); 150 | for (entry::dictionary_type::const_iterator i = e.dict().begin(); 151 | i != e.dict().end(); ++i) 152 | { 153 | // write key 154 | ret += write_integer(out, i->first.length()); 155 | write_char(out, ':'); 156 | ret += write_string(out, i->first); 157 | // write value 158 | ret += bencode_recursive(out, i->second); 159 | ret += 1; 160 | } 161 | write_char(out, 'e'); 162 | ret += 2; 163 | break; 164 | default: 165 | // do nothing 166 | break; 167 | } 168 | return ret; 169 | } 170 | 171 | template 172 | void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) 173 | { 174 | if (depth >= 100) 175 | { 176 | err = true; 177 | return; 178 | } 179 | 180 | if (in == end) 181 | { 182 | err = true; 183 | return; 184 | } 185 | switch (*in) 186 | { 187 | 188 | // ---------------------------------------------- 189 | // integer 190 | case 'i': 191 | { 192 | ++in; // 'i' 193 | std::string val = read_until(in, end, 'e', err); 194 | if (err) return; 195 | BOOST_ASSERT(*in == 'e'); 196 | ++in; // 'e' 197 | ret = entry(entry::int_t); 198 | char* end_pointer; 199 | #if defined WIN32 && !defined __MINGW_H 200 | ret.integer() = _strtoi64(val.c_str(), &end_pointer, 10); 201 | #else 202 | ret.integer() = strtoll(val.c_str(), &end_pointer, 10); 203 | #endif 204 | if (end_pointer == val.c_str()) 205 | { 206 | err = true; 207 | return; 208 | } 209 | } break; 210 | 211 | // ---------------------------------------------- 212 | // list 213 | case 'l': 214 | { 215 | ret = entry(entry::list_t); 216 | ++in; // 'l' 217 | while (*in != 'e') 218 | { 219 | ret.list().push_back(entry()); 220 | entry& e = ret.list().back(); 221 | bdecode_recursive(in, end, e, err, depth + 1); 222 | if (err) 223 | { 224 | return; 225 | } 226 | if (in == end) 227 | { 228 | err = true; 229 | return; 230 | } 231 | } 232 | BOOST_ASSERT(*in == 'e'); 233 | ++in; // 'e' 234 | } break; 235 | 236 | // ---------------------------------------------- 237 | // dictionary 238 | case 'd': 239 | { 240 | ret = entry(entry::dictionary_t); 241 | ++in; // 'd' 242 | while (*in != 'e') 243 | { 244 | entry key; 245 | bdecode_recursive(in, end, key, err, depth + 1); 246 | if (err || key.type() != entry::string_t) 247 | { 248 | return; 249 | } 250 | entry& e = ret[key.string()]; 251 | bdecode_recursive(in, end, e, err, depth + 1); 252 | if (err) 253 | { 254 | return; 255 | } 256 | if (in == end) 257 | { 258 | err = true; 259 | return; 260 | } 261 | } 262 | BOOST_ASSERT(*in == 'e'); 263 | ++in; // 'e' 264 | } break; 265 | 266 | // ---------------------------------------------- 267 | // string 268 | default: 269 | if (is_digit((unsigned char)*in)) 270 | { 271 | std::string len_s = read_until(in, end, ':', err); 272 | if (err) 273 | { 274 | return; 275 | } 276 | BOOST_ASSERT(*in == ':'); 277 | ++in; // ':' 278 | int len = std::atoi(len_s.c_str()); 279 | ret = entry(entry::string_t); 280 | read_string(in, end, len, ret.string(), err); 281 | if (err) 282 | { 283 | return; 284 | } 285 | } 286 | else 287 | { 288 | err = true; 289 | return; 290 | } 291 | } 292 | } 293 | } // namespace detail 294 | 295 | template 296 | int bencode(OutIt out, const entry& e) 297 | { 298 | return detail::bencode_recursive(out, e); 299 | } 300 | 301 | template 302 | entry bdecode(InIt start, InIt end) 303 | { 304 | entry e; 305 | bool err = false; 306 | detail::bdecode_recursive(start, end, e, err, 0); 307 | if (err) return entry(); 308 | return e; 309 | } 310 | 311 | template 312 | entry bdecode(InIt start, InIt end, int& len) 313 | { 314 | entry e; 315 | bool err = false; 316 | InIt s = start; 317 | detail::bdecode_recursive(start, end, e, err, 0); 318 | len = std::distance(s, start); 319 | BOOST_ASSERT(len >= 0); 320 | if (err) return entry(); 321 | return e; 322 | } 323 | 324 | } 325 | 326 | #endif // AVHTTP_BENCODE_HPP 327 | -------------------------------------------------------------------------------- /include/avhttp/bitfield.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 3 | // Copyright (c) 2008 Arvid Norberg All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions 7 | // are met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above copyright 12 | // notice, this list of conditions and the following disclaimer in 13 | // the documentation and/or other materials provided with the distribution. 14 | // * Neither the name of the author nor the names of its 15 | // contributors may be used to endorse or promote products derived 16 | // from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | // POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | 31 | #ifndef AVHTTP_BITFIELD_HPP 32 | #define AVHTTP_BITFIELD_HPP 33 | 34 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 35 | # pragma once 36 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 37 | 38 | #include 39 | 40 | namespace avhttp { 41 | 42 | // 一个位图的类实现. 43 | // 44 | 45 | struct bitfield 46 | { 47 | public: 48 | bitfield(void) : m_bytes(0), m_size(0), m_own(false) {} 49 | bitfield(int bits): m_bytes(0), m_size(0) 50 | { resize(bits); } 51 | bitfield(int bits, bool val): m_bytes(0), m_size(0) 52 | { resize(bits, val); } 53 | bitfield(char const* b, int bits): m_bytes(0), m_size(0) 54 | { assign(b, bits); } 55 | bitfield(bitfield const& rhs): m_bytes(0), m_size(0), m_own(false) 56 | { assign(rhs.bytes(), rhs.size()); } 57 | 58 | void borrow_bytes(char* b, int bits) 59 | { 60 | dealloc(); 61 | m_bytes = (unsigned char*)b; 62 | m_size = bits; 63 | m_own = false; 64 | } 65 | 66 | ~bitfield() { dealloc(); } 67 | void assign(char const* b, int bits) 68 | { resize(bits); std::memcpy(m_bytes, b, (bits + 7) / 8); clear_trailing_bits(); } 69 | 70 | bool operator[](int index) const 71 | { return get_bit(index); } 72 | 73 | bool get_bit(int index) const 74 | { 75 | BOOST_ASSERT(index >= 0); 76 | BOOST_ASSERT(index < m_size); 77 | return (m_bytes[index / 8] & (0x80 >> (index & 7))) != 0; 78 | } 79 | 80 | void clear_bit(int index) 81 | { 82 | BOOST_ASSERT(index >= 0); 83 | BOOST_ASSERT(index < m_size); 84 | m_bytes[index / 8] &= ~(0x80 >> (index & 7)); 85 | } 86 | 87 | void set_bit(int index) 88 | { 89 | BOOST_ASSERT(index >= 0); 90 | BOOST_ASSERT(index < m_size); 91 | m_bytes[index / 8] |= (0x80 >> (index & 7)); 92 | } 93 | 94 | std::size_t bytes_size() const { return m_size / 8 + (m_size % 8 == 0 ? 0 : 1); } 95 | std::size_t size() const { return m_size; } 96 | bool empty() const { return m_size == 0; } 97 | 98 | char const* bytes() const { return (char*)m_bytes; } 99 | 100 | bitfield& operator=(bitfield const& rhs) 101 | { 102 | assign(rhs.bytes(), rhs.size()); 103 | return *this; 104 | } 105 | 106 | int count() const 107 | { 108 | // 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, 109 | // 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111 110 | const static char num_bits[] = 111 | { 112 | 0, 1, 1, 2, 1, 2, 2, 3, 113 | 1, 2, 2, 3, 2, 3, 3, 4 114 | }; 115 | 116 | int ret = 0; 117 | const int num_bytes = m_size / 8; 118 | for (int i = 0; i < num_bytes; ++i) 119 | { 120 | ret += num_bits[m_bytes[i] & 0xf] + num_bits[m_bytes[i] >> 4]; 121 | } 122 | 123 | int rest = m_size - num_bytes * 8; 124 | for (int i = 0; i < rest; ++i) 125 | { 126 | ret += (m_bytes[num_bytes] >> (7-i)) & 1; 127 | } 128 | BOOST_ASSERT(ret <= m_size); 129 | BOOST_ASSERT(ret >= 0); 130 | return ret; 131 | } 132 | 133 | struct const_iterator 134 | { 135 | friend struct bitfield; 136 | 137 | typedef bool value_type; 138 | typedef ptrdiff_t difference_type; 139 | typedef bool const* pointer; 140 | typedef bool& reference; 141 | typedef std::forward_iterator_tag iterator_category; 142 | 143 | bool operator*() { return (*byte & bit) != 0; } 144 | const_iterator& operator++() { inc(); return *this; } 145 | const_iterator operator++(int) 146 | { const_iterator ret(*this); inc(); return ret; } 147 | const_iterator& operator--() { dec(); return *this; } 148 | const_iterator operator--(int) 149 | { const_iterator ret(*this); dec(); return ret; } 150 | 151 | const_iterator(): byte(0), bit(0x80) {} 152 | bool operator==(const_iterator const& rhs) const 153 | { return byte == rhs.byte && bit == rhs.bit; } 154 | 155 | bool operator!=(const_iterator const& rhs) const 156 | { return byte != rhs.byte || bit != rhs.bit; } 157 | 158 | const_iterator& operator+(boost::uint64_t rhs) 159 | { for (uint64_t i = 0; i < rhs; i++)inc(); return *this; } 160 | 161 | private: 162 | void inc() 163 | { 164 | BOOST_ASSERT(byte); 165 | if (bit == 0x01) 166 | { 167 | bit = 0x80; 168 | ++byte; 169 | } 170 | else 171 | { 172 | bit >>= 1; 173 | } 174 | } 175 | void dec() 176 | { 177 | BOOST_ASSERT(byte); 178 | if (bit == 0x80) 179 | { 180 | bit = 0x01; 181 | --byte; 182 | } 183 | else 184 | { 185 | bit <<= 1; 186 | } 187 | } 188 | const_iterator(unsigned char const* ptr, int offset) 189 | : byte(ptr), bit(0x80 >> offset) {} 190 | unsigned char const* byte; 191 | int bit; 192 | }; 193 | 194 | const_iterator begin() const { return const_iterator(m_bytes, 0); } 195 | const_iterator end() const { return const_iterator(m_bytes + m_size / 8, m_size & 7); } 196 | 197 | void resize(int bits, bool val) 198 | { 199 | int s = m_size; 200 | int b = m_size & 7; 201 | resize(bits); 202 | if (s >= m_size) return; 203 | int old_size_bytes = (s + 7) / 8; 204 | int new_size_bytes = (m_size + 7) / 8; 205 | if (val) 206 | { 207 | if (old_size_bytes && b) m_bytes[old_size_bytes - 1] |= (0xff >> b); 208 | if (old_size_bytes < new_size_bytes) 209 | std::memset(m_bytes + old_size_bytes, 0xff, new_size_bytes - old_size_bytes); 210 | clear_trailing_bits(); 211 | } 212 | else 213 | { 214 | if (old_size_bytes < new_size_bytes) 215 | std::memset(m_bytes + old_size_bytes, 0x00, new_size_bytes - old_size_bytes); 216 | } 217 | } 218 | 219 | void set_all() 220 | { 221 | std::memset(m_bytes, 0xff, (m_size + 7) / 8); 222 | clear_trailing_bits(); 223 | } 224 | 225 | void clear_all() 226 | { 227 | std::memset(m_bytes, 0x00, (m_size + 7) / 8); 228 | } 229 | 230 | void resize(int bits) 231 | { 232 | const int b = (bits + 7) / 8; 233 | if (m_bytes) 234 | { 235 | if (m_own) 236 | { 237 | m_bytes = (unsigned char*)std::realloc(m_bytes, b); 238 | m_own = true; 239 | } 240 | else if (bits > m_size) 241 | { 242 | unsigned char* tmp = (unsigned char*)std::malloc(b); 243 | std::memcpy(tmp, m_bytes, (std::min)(int(m_size + 7)/ 8, b)); 244 | m_bytes = tmp; 245 | m_own = true; 246 | } 247 | } 248 | else 249 | { 250 | m_bytes = (unsigned char*)std::malloc(b); 251 | m_own = true; 252 | } 253 | m_size = bits; 254 | clear_trailing_bits(); 255 | } 256 | 257 | void free() { dealloc(); m_size = 0; } 258 | 259 | private: 260 | 261 | void clear_trailing_bits() 262 | { 263 | // clear the tail bits in the last byte. 264 | if (m_size & 7) m_bytes[(m_size + 7) / 8 - 1] &= 0xff << (8 - (m_size & 7)); 265 | } 266 | 267 | void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; } 268 | unsigned char* m_bytes; 269 | int m_size:31; // in bits. 270 | bool m_own:1; 271 | }; 272 | 273 | } // namespace avhttp 274 | 275 | #endif // AVHTTP_BITFIELD_HPP 276 | 277 | -------------------------------------------------------------------------------- /include/avhttp/completion_condition.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // async_read_body.hpp 3 | // ~~~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (C) 2012 - 2013 微蔡 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_COMPLETION_CONDITION_HPP 12 | #define AVHTTP_COMPLETION_CONDITION_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | namespace avhttp { 25 | 26 | namespace detail { 27 | // match condition! 28 | struct transfer_response_body_t 29 | { 30 | transfer_response_body_t(boost::int64_t content_length) 31 | : m_content_length(content_length) 32 | { 33 | } 34 | 35 | template 36 | std::size_t operator()(const Error& err, std::size_t bytes_transferred) 37 | { 38 | using boost::asio::detail::default_max_transfer_size; 39 | 40 | if(m_content_length > 0 ) 41 | { 42 | // just the same boost::asio::transfer_exactly 43 | return (!!err || static_cast(bytes_transferred) >= m_content_length) ? 0 : 44 | (m_content_length - bytes_transferred < default_max_transfer_size 45 | ? m_content_length - bytes_transferred : std::size_t(default_max_transfer_size)); 46 | } 47 | else 48 | { 49 | // just the same as boost::asio::transfer_all 50 | return !!err ? 0 : default_max_transfer_size; 51 | } 52 | } 53 | 54 | boost::int64_t m_content_length; 55 | }; 56 | 57 | } 58 | 59 | ///Return a completion condition function object that indicates that a read or 60 | // write operation should continue until all http respons body have been 61 | // transferred, or until an error occurs. 62 | // 63 | // This function is used to create an object, of unspecified type, that meets 64 | // CompletionCondition requirements. 65 | // 66 | // @begin example 67 | // Reading until a buffer is full or contains all respons body: 68 | // @code 69 | // boost::array buf; 70 | // boost::system::error_code ec; 71 | // std::size_t n = boost::asio::read( 72 | // avhttp_stream, boost::asio::buffer(buf), 73 | // boost::asio::transfer_response_body(avhttp_stream.content_length()), ec); 74 | // if (ec) 75 | // { 76 | // // An error occurred. 77 | // } 78 | // else 79 | // { 80 | // // n == 64 81 | // } 82 | // @end example 83 | # if defined(GENERATING_DOCUMENTATION) 84 | unspecified transfer_response_body(boost::int64_t content_length) 85 | #else 86 | inline detail::transfer_response_body_t transfer_response_body(boost::int64_t content_length) 87 | { 88 | return detail::transfer_response_body_t(content_length); 89 | } 90 | #endif 91 | 92 | } 93 | 94 | 95 | #include 96 | 97 | #endif // AVHTTP_COMPLETION_CONDITION_HPP 98 | -------------------------------------------------------------------------------- /include/avhttp/default_storage.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // default_storage.hpp 3 | // ~~~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_DEFAULT_STORAGE_HPP 12 | #define AVHTTP_DEFAULT_STORAGE_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include "avhttp/file.hpp" 19 | #include "avhttp/storage_interface.hpp" 20 | 21 | namespace avhttp { 22 | 23 | class default_storge : public storage_interface 24 | { 25 | public: 26 | default_storge() 27 | {} 28 | 29 | virtual ~default_storge() 30 | {} 31 | 32 | // 存储组件初始化. 33 | // @param file_path指定了文件名路径信息. 34 | // @param ec在出错时保存了详细的错误信息. 35 | virtual void open(const fs::path& file_path, boost::system::error_code& ec) 36 | { 37 | m_file.open(file_path, file::read_write, ec); 38 | } 39 | 40 | // 关闭存储组件. 41 | virtual void close() 42 | { 43 | m_file.close(); 44 | } 45 | 46 | // 写入数据到文件. 47 | // @param buf是需要写入的数据缓冲. 48 | // @param size指定了写入的数据缓冲大小. 49 | // @返回值为实际写入的字节数, 返回-1表示写入失败. 50 | // 备注: 在文件指针当前位置写入, 写入完成将自动移动文件指针到完成位置, 保证和fwrite行为一至. 51 | virtual std::streamsize write(const char* buf, int size) 52 | { 53 | return m_file.write(buf, size); 54 | } 55 | 56 | // 写入数据. 57 | // @param buf是需要写入的数据缓冲. 58 | // @param offset是写入的偏移位置. 59 | // @param size指定了写入的数据缓冲大小. 60 | // @返回值为实际写入的字节数, 返回-1表示写入失败. 61 | virtual std::streamsize write(const char* buf, boost::int64_t offset, int size) 62 | { 63 | return m_file.write(offset, buf, size); 64 | } 65 | 66 | // 从文件读取数据. 67 | // @param buf是需要读取的数据缓冲. 68 | // @param size指定了读取的数据缓冲大小. 69 | // @返回值为实际读取的字节数, 返回-1表示读取失败. 70 | // 备注: 在文件指针当前位置开始读取, 读取完成将自动移动文件指针到完成位置, 保证和fread行为一至. 71 | virtual std::streamsize read(char* buf, int size) 72 | { 73 | return m_file.read(buf, size); 74 | } 75 | 76 | // 读取数据. 77 | // @param buf是需要读取的数据缓冲. 78 | // @param offset是读取的偏移位置. 79 | // @param size指定了读取的数据缓冲大小. 80 | // @返回值为实际读取的字节数, 返回-1表示读取失败. 81 | virtual std::streamsize read(char* buf, boost::int64_t offset, int size) 82 | { 83 | return m_file.read(offset, buf, size); 84 | } 85 | 86 | // 判断是否文件结束. 87 | // 返回值true表示文件结束. 88 | virtual bool eof() 89 | { 90 | char tmp; 91 | boost::system::error_code ec; 92 | boost::int64_t offset = m_file.offset(ec); 93 | BOOST_ASSERT(!ec); 94 | int ret = m_file.read(&tmp, 1); 95 | m_file.offset(offset, ec); 96 | BOOST_ASSERT(!ec); 97 | return ret == 0 ? true : false; 98 | } 99 | 100 | protected: 101 | file m_file; 102 | }; 103 | 104 | // 默认存储对象. 105 | static storage_interface* default_storage_constructor() 106 | { 107 | return new default_storge(); 108 | } 109 | 110 | } // namespace avhttp 111 | 112 | #endif // AVHTTP_DEFAULT_STORAGE_HPP 113 | -------------------------------------------------------------------------------- /include/avhttp/detail/abi_prefix.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // abi_prefix.hpp 3 | // ~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2009 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | // No include guard. 12 | 13 | // Disable some pesky MSVC warnings. 14 | #if defined(_MSC_VER) 15 | # pragma warning (push) 16 | # pragma warning (disable:4127) 17 | # pragma warning (disable:4251) 18 | # pragma warning (disable:4355) 19 | # pragma warning (disable:4512) 20 | # pragma warning (disable:4996) 21 | # pragma warning (disable:4267) 22 | # pragma warning (disable:4819) 23 | # pragma warning (disable:4244) 24 | # pragma warning (disable:4250) 25 | # pragma warning (disable:4996) 26 | #endif // defined(_MSC_VER) 27 | 28 | // Force external visibility of all types. 29 | #if defined(__GNUC__) 30 | # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) 31 | # pragma GCC visibility push (default) 32 | # endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) 33 | #endif // defined(__GNUC__) 34 | -------------------------------------------------------------------------------- /include/avhttp/detail/abi_suffix.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // abi_suffix.hpp 3 | // ~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2009 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #if defined(_MSC_VER) 12 | # pragma warning (pop) 13 | #endif // defined(_MSC_VER) 14 | 15 | // No include guard. 16 | 17 | #if defined(__GNUC__) 18 | # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) 19 | # pragma GCC visibility pop 20 | # endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) 21 | #endif // defined(__GNUC__) 22 | -------------------------------------------------------------------------------- /include/avhttp/detail/escape_string.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // escape_string.hpp 3 | // ~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2009 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_ESCAPE_STRING_HPP 13 | #define AVHTTP_ESCAPE_STRING_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "avhttp/detail/utf8.hpp" 30 | 31 | namespace avhttp { 32 | namespace detail { 33 | 34 | static const char hex_chars[] = "0123456789abcdef"; 35 | 36 | inline bool is_char(int c) 37 | { 38 | return c >= 0 && c <= 127; 39 | } 40 | 41 | inline bool is_digit(char c) 42 | { 43 | return c >= '0' && c <= '9'; 44 | } 45 | 46 | inline bool is_ctl(int c) 47 | { 48 | return (c >= 0 && c <= 31) || c == 127; 49 | } 50 | 51 | // Check if character is unreserved. List of unreserved characters is here: http://en.wikipedia.org/wiki/Percent-encoding 52 | inline bool is_unreserved_char(const char c) 53 | { 54 | return (c >= 'A' && c<= 'Z') || (c >= 'a' && c<= 'z') || (c >= '0' && c <= '9') || ('-' == c) || ('_' == c) || ('.' == c) || ('~' == c); 55 | } 56 | 57 | inline bool is_tspecial(int c) 58 | { 59 | switch (c) 60 | { 61 | case ' ': case '`': case '{': case '}': case '^': case '|': 62 | return true; 63 | default: 64 | return false; 65 | } 66 | } 67 | 68 | inline std::string to_hex(std::string const& s) 69 | { 70 | std::string ret; 71 | for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) 72 | { 73 | ret += hex_chars[((unsigned char)*i) >> 4]; 74 | ret += hex_chars[((unsigned char)*i) & 0xf]; 75 | } 76 | return ret; 77 | } 78 | 79 | inline void to_hex(char const* in, int len, char* out) 80 | { 81 | for (char const* end = in + len; in < end; ++in) 82 | { 83 | *out++ = hex_chars[((unsigned char)*in) >> 4]; 84 | *out++ = hex_chars[((unsigned char)*in) & 0xf]; 85 | } 86 | *out = '\0'; 87 | } 88 | 89 | inline bool is_print(char c) 90 | { 91 | return c >= 32 && c < 127; 92 | } 93 | 94 | inline bool tolower_compare(char a, char b) 95 | { 96 | return std::tolower(a) == std::tolower(b); 97 | } 98 | 99 | // convert path string to percent-encoded string. 100 | // ATTENTION: Only some "reserved characters" are transformed to percent-encoded form. Some characters like 0x02 are not transformed too. 101 | inline std::string escape_path(const std::string& s) 102 | { 103 | std::string ret; 104 | std::string h; 105 | 106 | for (std::string::const_iterator i = s.begin(); i != s.end(); i++) 107 | { 108 | h = *i; 109 | if (!is_char(*i) || is_tspecial(*i)) 110 | h = "%" + to_hex(h); 111 | ret += h; 112 | } 113 | 114 | return ret; 115 | } 116 | 117 | // convert any string to percent-encoded string. All characters except Unreserved onces are percent encoded. 118 | // List of reserved and unreserved characters is taken from http://en.wikipedia.org/wiki/Percent-encoding 119 | inline std::string escape_string(const std::string& s) 120 | { 121 | std::string ret; 122 | std::string h; 123 | 124 | for (std::string::const_iterator i = s.begin(); i != s.end(); i++) 125 | { 126 | h = *i; 127 | if (!is_unreserved_char(*i)) 128 | h = "%" + to_hex(h); 129 | ret += h; 130 | } 131 | 132 | return ret; 133 | } 134 | 135 | inline bool unescape_path(const std::string& in, std::string& out) 136 | { 137 | out.clear(); 138 | out.reserve(in.size()); 139 | for (std::size_t i = 0; i < in.size(); ++i) 140 | { 141 | switch (in[i]) 142 | { 143 | case '%': 144 | if (i + 3 <= in.size()) 145 | { 146 | unsigned int value = 0; 147 | for (std::size_t j = i + 1; j < i + 3; ++j) 148 | { 149 | value <<= 4; 150 | 151 | switch (in[j]) 152 | { 153 | case '0': case '1': case '2': case '3': case '4': 154 | case '5': case '6': case '7': case '8': case '9': 155 | value += in[j] - '0'; 156 | break; 157 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 158 | value += in[j] - 'a' + 10; 159 | break; 160 | case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 161 | value += in[j] - 'A' + 10; 162 | break; 163 | default: 164 | return false; 165 | } 166 | } 167 | out += static_cast(value); 168 | i += 2; 169 | } 170 | else 171 | return false; 172 | break; 173 | case '-': case '_': case '.': case '~': // unreserved characters. Do not encode them at any case 174 | // Reserved characters. In some special cases this characters might stay escaped. 175 | case '!': case '*': case '\'': case '(': case ')': case ';': case ':': case '@': case '&': 176 | case '=': case '+': case '$': case ',': case '/': case '?': case '#': case '[': case ']': 177 | out += in[i]; 178 | break; 179 | default: 180 | if (!std::isalnum((unsigned char)in[i])) 181 | return false; 182 | out += in[i]; 183 | break; 184 | } 185 | } 186 | return true; 187 | } 188 | 189 | template 190 | std::string encode_base64(const Source& s) 191 | { 192 | using namespace boost::archive::iterators; 193 | typedef typename Source::const_iterator source_const_iterator; 194 | typedef base64_from_binary< 195 | transform_width< 196 | source_const_iterator, 197 | 6, 198 | 8 199 | > 200 | > base64_text; 201 | std::stringstream ss; 202 | std::copy(base64_text(s.begin()), base64_text(s.end()), 203 | boost::archive::iterators::ostream_iterator(ss)); 204 | std::string result = ss.str(); 205 | int padding = result.size() % 4 ? 4 - result.size() % 4 : 0; 206 | for (int i = 0; i < padding; i++) 207 | result += "="; 208 | return result; 209 | } 210 | 211 | } 212 | } 213 | 214 | #endif // AVHTTP_ESCAPE_STRING_HPP 215 | -------------------------------------------------------------------------------- /include/avhttp/detail/handler_type_requirements.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // detail/handler_type_requirements.hpp 3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // Copyright (c) 2003, Arvid Norberg 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_HANDLER_TYPE_REQUIREMENTS_HPP 13 | #define AVHTTP_HANDLER_TYPE_REQUIREMENTS_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | #include 20 | #include 21 | 22 | namespace boost { 23 | namespace asio { 24 | namespace detail { 25 | 26 | #if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) 27 | 28 | #define AVHTTP_READ_HANDLER_CHECK( \ 29 | handler_type, handler) \ 30 | \ 31 | BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ 32 | sizeof(boost::asio::detail::two_arg_handler_test( \ 33 | handler, \ 34 | static_cast(0), \ 35 | static_cast(0))) == 1, \ 36 | "ReadHandler type requirements not met") \ 37 | \ 38 | typedef boost::asio::detail::handler_type_requirements< \ 39 | sizeof( \ 40 | boost::asio::detail::argbyv( \ 41 | boost::asio::detail::clvref(handler))) + \ 42 | sizeof( \ 43 | boost::asio::detail::lvref(handler)( \ 44 | boost::asio::detail::lvref(), \ 45 | boost::asio::detail::lvref()), \ 46 | char(0))> 47 | 48 | #define AVHTTP_WRITE_HANDLER_CHECK( \ 49 | handler_type, handler) \ 50 | \ 51 | BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ 52 | sizeof(boost::asio::detail::two_arg_handler_test( \ 53 | handler, \ 54 | static_cast(0), \ 55 | static_cast(0))) == 1, \ 56 | "WriteHandler type requirements not met") \ 57 | \ 58 | typedef boost::asio::detail::handler_type_requirements< \ 59 | sizeof( \ 60 | boost::asio::detail::argbyv( \ 61 | boost::asio::detail::clvref(handler))) + \ 62 | sizeof( \ 63 | boost::asio::detail::lvref(handler)( \ 64 | boost::asio::detail::lvref(), \ 65 | boost::asio::detail::lvref()), \ 66 | char(0))> 67 | 68 | #define AVHTTP_OPEN_HANDLER_CHECK( \ 69 | handler_type, handler) \ 70 | \ 71 | BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ 72 | sizeof(boost::asio::detail::one_arg_handler_test( \ 73 | handler, \ 74 | static_cast(0))) == 1, \ 75 | "OpenHandler type requirements not met") \ 76 | \ 77 | typedef boost::asio::detail::handler_type_requirements< \ 78 | sizeof( \ 79 | boost::asio::detail::argbyv( \ 80 | boost::asio::detail::clvref(handler))) + \ 81 | sizeof( \ 82 | boost::asio::detail::lvref(handler)( \ 83 | boost::asio::detail::lvref()), \ 84 | char(0))> 85 | 86 | #define AVHTTP_REQUEST_HANDLER_CHECK( \ 87 | handler_type, handler) \ 88 | \ 89 | BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ 90 | sizeof(boost::asio::detail::one_arg_handler_test( \ 91 | handler, \ 92 | static_cast(0))) == 1, \ 93 | "RequestHandler type requirements not met") \ 94 | \ 95 | typedef boost::asio::detail::handler_type_requirements< \ 96 | sizeof( \ 97 | boost::asio::detail::argbyv( \ 98 | boost::asio::detail::clvref(handler))) + \ 99 | sizeof( \ 100 | boost::asio::detail::lvref(handler)( \ 101 | boost::asio::detail::lvref()), \ 102 | char(0))> 103 | 104 | #define AVHTTP_RECEIVE_HEADER_CHECK( \ 105 | handler_type, handler) \ 106 | \ 107 | BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ 108 | sizeof(boost::asio::detail::one_arg_handler_test( \ 109 | handler, \ 110 | static_cast(0))) == 1, \ 111 | "ReceiveHandler type requirements not met") \ 112 | \ 113 | typedef boost::asio::detail::handler_type_requirements< \ 114 | sizeof( \ 115 | boost::asio::detail::argbyv( \ 116 | boost::asio::detail::clvref(handler))) + \ 117 | sizeof( \ 118 | boost::asio::detail::lvref(handler)( \ 119 | boost::asio::detail::lvref()), \ 120 | char(0))> 121 | 122 | #else 123 | 124 | #define AVHTTP_READ_HANDLER_CHECK( \ 125 | handler_type, handler) \ 126 | typedef int 127 | 128 | #define AVHTTP_WRITE_HANDLER_CHECK( \ 129 | handler_type, handler) \ 130 | typedef int 131 | 132 | #define AVHTTP_OPEN_HANDLER_CHECK( \ 133 | handler_type, handler) \ 134 | typedef int 135 | 136 | #define AVHTTP_REQUEST_HANDLER_CHECK( \ 137 | handler_type, handler) \ 138 | typedef int 139 | 140 | #define AVHTTP_RECEIVE_HEADER_CHECK( \ 141 | handler_type, handler) \ 142 | typedef int 143 | 144 | #endif 145 | 146 | } // namespace detail 147 | } // namespace asio 148 | } // namespace boost 149 | 150 | #endif // AVHTTP_HANDLER_TYPE_REQUIREMENTS_HPP 151 | -------------------------------------------------------------------------------- /include/avhttp/detail/io.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // socket_type.hpp 3 | // ~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // Copyright (c) 2003, Arvid Norberg 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_IO_HPP 13 | #define AVHTTP_IO_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | namespace avhttp { 20 | namespace detail { 21 | 22 | template struct type {}; 23 | 24 | // reads an integer from a byte stream in big endian byte order and converts 25 | // it to native endianess 26 | template 27 | inline T read_impl(InIt& start, type) 28 | { 29 | T ret = 0; 30 | for (int i = 0; i < (int)sizeof(T); ++i) 31 | { 32 | ret <<= 8; 33 | ret |= static_cast(*start); 34 | ++start; 35 | } 36 | return ret; 37 | } 38 | 39 | template 40 | boost::uint8_t read_impl(InIt& start, type) 41 | { 42 | return static_cast(*start++); 43 | } 44 | 45 | template 46 | boost::int8_t read_impl(InIt& start, type) 47 | { 48 | return static_cast(*start++); 49 | } 50 | 51 | template 52 | inline void write_impl(T val, OutIt& start) 53 | { 54 | for (int i = (int)sizeof(T)-1; i >= 0; --i) 55 | { 56 | *start = static_cast((val >> (i * 8)) & 0xff); 57 | ++start; 58 | } 59 | } 60 | 61 | // -- adaptors 62 | 63 | template 64 | boost::int64_t read_int64(InIt& start) 65 | { return read_impl(start, type()); } 66 | 67 | template 68 | boost::uint64_t read_uint64(InIt& start) 69 | { return read_impl(start, type()); } 70 | 71 | template 72 | boost::uint32_t read_uint32(InIt& start) 73 | { return read_impl(start, type()); } 74 | 75 | template 76 | boost::int32_t read_int32(InIt& start) 77 | { return read_impl(start, type()); } 78 | 79 | template 80 | boost::int16_t read_int16(InIt& start) 81 | { return read_impl(start, type()); } 82 | 83 | template 84 | boost::uint16_t read_uint16(InIt& start) 85 | { return read_impl(start, type()); } 86 | 87 | template 88 | boost::int8_t read_int8(InIt& start) 89 | { return read_impl(start, type()); } 90 | 91 | template 92 | boost::uint8_t read_uint8(InIt& start) 93 | { return read_impl(start, type()); } 94 | 95 | 96 | template 97 | void write_uint64(boost::uint64_t val, OutIt& start) 98 | { write_impl(val, start); } 99 | 100 | template 101 | void write_int64(boost::int64_t val, OutIt& start) 102 | { write_impl(val, start); } 103 | 104 | template 105 | void write_uint32(boost::uint32_t val, OutIt& start) 106 | { write_impl(val, start); } 107 | 108 | template 109 | void write_int32(boost::int32_t val, OutIt& start) 110 | { write_impl(val, start); } 111 | 112 | template 113 | void write_uint16(boost::uint16_t val, OutIt& start) 114 | { write_impl(val, start); } 115 | 116 | template 117 | void write_int16(boost::int16_t val, OutIt& start) 118 | { write_impl(val, start); } 119 | 120 | template 121 | void write_uint8(boost::uint8_t val, OutIt& start) 122 | { write_impl(val, start); } 123 | 124 | template 125 | void write_int8(boost::int8_t val, OutIt& start) 126 | { write_impl(val, start); } 127 | 128 | inline void write_string(std::string const& str, char *&start) 129 | { 130 | std::memcpy((void*)start, str.c_str(), str.size()); 131 | start += str.size(); 132 | } 133 | 134 | template 135 | void write_string(std::string const& str, OutIt& start) 136 | { 137 | std::copy(str.begin(), str.end(), start); 138 | } 139 | 140 | } // namespace detail 141 | } // namespace avhttp 142 | 143 | #endif // AVHTTP_IO_HPP 144 | -------------------------------------------------------------------------------- /include/avhttp/detail/ssl_stream.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ssl_stream.hpp 3 | // ~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // Copyright (c) 2003, Arvid Norberg 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_SSL_STREAM_HPP 13 | #define AVHTTP_SSL_STREAM_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | #include 20 | #include 21 | 22 | // openssl seems to believe it owns this name in every single scope. 23 | #undef set_key 24 | 25 | namespace avhttp { 26 | namespace detail { 27 | 28 | template 29 | class ssl_stream 30 | { 31 | public: 32 | 33 | explicit ssl_stream(boost::asio::io_context& io_service) 34 | : m_context(boost::asio::ssl::context::sslv23_client) 35 | , m_sock(io_service, m_context) 36 | { 37 | boost::system::error_code ec; 38 | m_context.set_default_verify_paths(ec); 39 | m_context.set_verify_mode(boost::asio::ssl::context::verify_none, ec); 40 | } 41 | 42 | template 43 | explicit ssl_stream(Arg& arg, boost::asio::io_context& io_service) 44 | : m_context(boost::asio::ssl::context::sslv23_client) 45 | , m_sock(arg, m_context) 46 | { 47 | boost::system::error_code ec; 48 | m_context.set_default_verify_paths(ec); 49 | m_context.set_verify_mode(boost::asio::ssl::context::verify_none, ec); 50 | } 51 | 52 | ~ssl_stream() {} 53 | 54 | typedef typename boost::remove_reference::type next_layer_type; 55 | typedef typename next_layer_type::lowest_layer_type lowest_layer_type; 56 | typedef typename lowest_layer_type::endpoint_type endpoint_type; 57 | typedef typename lowest_layer_type::protocol_type protocol_type; 58 | typedef typename boost::asio::ssl::stream sock_type; 59 | 60 | typedef boost::function handler_type; 61 | 62 | void add_verify_path(const std::string& path, boost::system::error_code& ec) 63 | { 64 | m_context.add_verify_path(path, ec); 65 | } 66 | 67 | void load_verify_file(const std::string& filename, boost::system::error_code& ec) 68 | { 69 | m_context.load_verify_file(filename, ec); 70 | } 71 | 72 | template 73 | void set_verify_callback(VerifyCallback callback, boost::system::error_code& ec) 74 | { 75 | m_sock.set_verify_callback(callback, ec); 76 | } 77 | 78 | 79 | template 80 | void set_verify_mode(VerifyMode m) 81 | { 82 | m_sock.set_verify_mode(m); 83 | } 84 | 85 | template 86 | void set_verify_mode(VerifyMode m, boost::system::error_code& ec) 87 | { 88 | m_sock.set_verify_mode(m, ec); 89 | } 90 | 91 | typename boost::asio::ssl::stream::native_handle_type native_handle() 92 | { 93 | return m_sock.native_handle(); 94 | } 95 | 96 | #ifndef BOOST_NO_EXCEPTIONS 97 | void connect(endpoint_type const& endpoint) 98 | { 99 | // 1. connect to peer 100 | // 2. perform SSL client handshake 101 | 102 | m_sock.next_layer().connect(endpoint); 103 | m_sock.handshake(boost::asio::ssl::stream_base::client); 104 | } 105 | #endif 106 | 107 | void connect(endpoint_type const& endpoint, boost::system::error_code& ec) 108 | { 109 | // 1. connect to peer 110 | // 2. perform SSL client handshake 111 | 112 | m_sock.next_layer().connect(endpoint, ec); 113 | if (ec) 114 | return; 115 | m_sock.handshake(boost::asio::ssl::stream_base::client, ec); 116 | } 117 | 118 | template 119 | void async_connect(endpoint_type& endpoint, Handler handler) 120 | { 121 | // the connect is split up in the following steps: 122 | // 1. connect to peer 123 | // 2. perform SSL client handshake 124 | 125 | // to avoid unnecessary copying of the handler, 126 | // store it in a shared_ptr 127 | boost::shared_ptr h(new handler_type(handler)); 128 | 129 | m_sock.next_layer().async_connect(endpoint 130 | , boost::bind(&ssl_stream::connected, this, _1, h)); 131 | } 132 | 133 | #ifndef BOOST_NO_EXCEPTIONS 134 | void handshake() 135 | { 136 | m_sock.handshake(boost::asio::ssl::stream_base::client); 137 | } 138 | #endif 139 | 140 | void handshake(boost::system::error_code& ec) 141 | { 142 | m_sock.handshake(boost::asio::ssl::stream_base::client, ec); 143 | } 144 | 145 | template 146 | void async_handshake(Handler handler) 147 | { 148 | boost::shared_ptr h(new handler_type(handler)); 149 | m_sock.async_handshake(boost::asio::ssl::stream_base::client 150 | , boost::bind(&ssl_stream::handle_handshake, this, _1, h)); 151 | } 152 | 153 | template 154 | void async_read_some(Mutable_Buffers const& buffers, Handler handler) 155 | { 156 | m_sock.async_read_some(buffers, handler); 157 | } 158 | 159 | template 160 | std::size_t read_some(Mutable_Buffers const& buffers, boost::system::error_code& ec) 161 | { 162 | return m_sock.read_some(buffers, ec); 163 | } 164 | 165 | #ifndef BOOST_NO_EXCEPTIONS 166 | template 167 | std::size_t read_some(Mutable_Buffers const& buffers) 168 | { 169 | return m_sock.read_some(buffers); 170 | } 171 | 172 | template 173 | void io_control(IO_Control_Command& ioc) 174 | { 175 | m_sock.next_layer().io_control(ioc); 176 | } 177 | #endif 178 | 179 | template 180 | void io_control(IO_Control_Command& ioc, boost::system::error_code& ec) 181 | { 182 | m_sock.next_layer().io_control(ioc, ec); 183 | } 184 | 185 | template 186 | void async_write_some(Const_Buffers const& buffers, Handler handler) 187 | { 188 | m_sock.async_write_some(buffers, handler); 189 | } 190 | 191 | template 192 | std::size_t write_some(Const_Buffers const& buffers, boost::system::error_code& ec) 193 | { 194 | return m_sock.write_some(buffers, ec); 195 | } 196 | 197 | #ifndef BOOST_NO_EXCEPTIONS 198 | template 199 | std::size_t write_some(Const_Buffers const& buffers) 200 | { 201 | return m_sock.write_some(buffers); 202 | } 203 | 204 | void bind(endpoint_type const& endpoint) 205 | { 206 | m_sock.next_layer().bind(endpoint); 207 | } 208 | #endif 209 | 210 | void bind(endpoint_type const& endpoint, boost::system::error_code& ec) 211 | { 212 | m_sock.next_layer().bind(endpoint, ec); 213 | } 214 | 215 | #ifndef BOOST_NO_EXCEPTIONS 216 | void open(protocol_type const& p) 217 | { 218 | m_sock.next_layer().open(p); 219 | } 220 | #endif 221 | 222 | void open(protocol_type const& p, boost::system::error_code& ec) 223 | { 224 | m_sock.next_layer().open(p, ec); 225 | } 226 | 227 | bool is_open() const 228 | { 229 | return const_cast(m_sock).next_layer().is_open(); 230 | } 231 | 232 | #ifndef BOOST_NO_EXCEPTIONS 233 | void close() 234 | { 235 | m_sock.next_layer().close(); 236 | } 237 | #endif 238 | 239 | void close(boost::system::error_code& ec) 240 | { 241 | m_sock.next_layer().close(ec); 242 | } 243 | 244 | #ifndef BOOST_NO_EXCEPTIONS 245 | endpoint_type remote_endpoint() const 246 | { 247 | return const_cast(m_sock).next_layer().remote_endpoint(); 248 | } 249 | #endif 250 | 251 | endpoint_type remote_endpoint(boost::system::error_code& ec) const 252 | { 253 | return const_cast(m_sock).next_layer().remote_endpoint(ec); 254 | } 255 | 256 | #ifndef BOOST_NO_EXCEPTIONS 257 | endpoint_type local_endpoint() const 258 | { 259 | return const_cast(m_sock).next_layer().local_endpoint(); 260 | } 261 | #endif 262 | 263 | endpoint_type local_endpoint(boost::system::error_code& ec) const 264 | { 265 | return const_cast(m_sock).next_layer().local_endpoint(ec); 266 | } 267 | 268 | boost::asio::io_context& get_io_service() 269 | { 270 | return m_sock.get_io_service(); 271 | } 272 | 273 | lowest_layer_type& lowest_layer() 274 | { 275 | return m_sock.lowest_layer(); 276 | } 277 | 278 | next_layer_type& next_layer() 279 | { 280 | return m_sock.next_layer(); 281 | } 282 | 283 | // impl_type impl() 284 | // { 285 | // return m_sock.impl(); 286 | // } 287 | 288 | template 289 | boost::system::error_code set_option(const SettableSocketOption& option, 290 | boost::system::error_code& ec) 291 | { 292 | return m_sock.next_layer().set_option(option, ec); 293 | } 294 | 295 | #ifndef BOOST_NO_EXCEPTIONS 296 | template 297 | void set_option(const SettableSerialPortOption& option) 298 | { 299 | m_sock.next_layer().set_option(option); 300 | } 301 | #endif 302 | 303 | private: 304 | 305 | void connected(boost::system::error_code const& e, boost::shared_ptr h) 306 | { 307 | if (e) 308 | { 309 | (*h)(e); 310 | return; 311 | } 312 | 313 | m_sock.async_handshake(boost::asio::ssl::stream_base::client 314 | , boost::bind(&ssl_stream::handle_handshake, this, _1, h)); 315 | } 316 | 317 | void handle_handshake(boost::system::error_code const& e, boost::shared_ptr h) 318 | { 319 | (*h)(e); 320 | } 321 | 322 | boost::asio::ssl::context m_context; 323 | boost::asio::ssl::stream m_sock; 324 | }; 325 | 326 | } 327 | } 328 | 329 | #endif // AVHTTP_SSL_STREAM_HPP 330 | -------------------------------------------------------------------------------- /include/avhttp/detail/utf8.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // utf8.hpp 3 | // ~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_UTF8_HPP 12 | #define AVHTTP_UTF8_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include // for mbtowc, wctomb. 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | namespace avhttp { 25 | namespace detail { 26 | 27 | // 字符集编码转换接口声明. 28 | 29 | // wide string to utf8 string. 30 | inline std::string wide_utf8(const std::wstring& source); 31 | 32 | // utf8 string to wide string. 33 | inline std::wstring utf8_wide(std::string const& source); 34 | 35 | // ansi string to utf8 string. 36 | inline std::string ansi_utf8(std::string const& source); 37 | inline std::string ansi_utf8( 38 | std::string const& source, const std::string& characters); 39 | 40 | // utf8 string to ansi string. 41 | inline std::string utf8_ansi(std::string const& source); 42 | inline std::string utf8_ansi( 43 | std::string const& source, const std::string& characters); 44 | 45 | // wide string to ansi string. 46 | inline std::string wide_ansi(const std::wstring& source); 47 | inline std::string wide_ansi( 48 | std::wstring const& source, const std::string& characters); 49 | 50 | // ansi string to wide string. 51 | inline std::wstring ansi_wide(const std::string& source); 52 | inline std::wstring ansi_wide( 53 | const std::string& source, const std::string& characters); 54 | 55 | // 字符集编码转换接口实现, 使用boost实现. 56 | inline std::wstring ansi_wide( 57 | const std::string& source, const std::string& characters) 58 | { 59 | return boost::locale::conv::utf_to_utf(ansi_utf8(source, characters)); 60 | } 61 | 62 | inline std::wstring ansi_wide(const std::string& source) 63 | { 64 | std::wstring wide; 65 | wchar_t dest; 66 | std::size_t max = source.size(); 67 | 68 | // reset mbtowc. 69 | mbtowc(NULL, NULL, 0); 70 | 71 | // convert source to wide. 72 | for (std::string::const_iterator i = source.begin(); 73 | i != source.end(); ) 74 | { 75 | int length = mbtowc(&dest, &(*i), max); 76 | if (length < 1) 77 | break; 78 | max -= length; 79 | while (length--) i++; 80 | wide.push_back(dest); 81 | } 82 | 83 | return wide; 84 | } 85 | 86 | inline std::string ansi_utf8( 87 | std::string const& source, const std::string& characters) 88 | { 89 | return boost::locale::conv::between(source, "UTF-8", characters); 90 | } 91 | 92 | inline std::string ansi_utf8(std::string const& source) 93 | { 94 | std::wstring wide = ansi_wide(source); 95 | return wide_utf8(wide); 96 | } 97 | 98 | inline std::string wide_utf8(const std::wstring& source) 99 | { 100 | return boost::locale::conv::utf_to_utf(source); 101 | } 102 | 103 | inline std::wstring utf8_wide(std::string const& source) 104 | { 105 | return boost::locale::conv::utf_to_utf(source); 106 | } 107 | 108 | inline std::string utf8_ansi( 109 | std::string const& source, const std::string& characters) 110 | { 111 | return boost::locale::conv::between(source, characters, "UTF-8"); 112 | } 113 | 114 | inline std::string utf8_ansi(std::string const& source) 115 | { 116 | return wide_ansi(utf8_wide(source)); 117 | } 118 | 119 | inline std::string wide_ansi( 120 | std::wstring const& source, const std::string& characters) 121 | { 122 | return utf8_ansi(wide_utf8(source), characters); 123 | } 124 | 125 | inline std::string wide_ansi(const std::wstring& source) 126 | { 127 | std::size_t buffer_size = MB_CUR_MAX; 128 | std::vector buffer(buffer_size, 0); 129 | std::string ansi; 130 | 131 | // reset wctomb. 132 | wctomb(NULL, 0); 133 | 134 | // convert source to wide. 135 | for (std::wstring::const_iterator i = source.begin(); 136 | i != source.end(); i++) 137 | { 138 | int length = wctomb(&(*buffer.begin()), *i); 139 | if (length < 1) 140 | break; 141 | for (int j = 0; j < length; j++) 142 | ansi.push_back(buffer[j]); 143 | } 144 | 145 | return ansi; 146 | } 147 | 148 | } // namespace detail 149 | } // namespace avhttp 150 | 151 | #endif // AVHTTP_UTF8_HPP 152 | -------------------------------------------------------------------------------- /include/avhttp/file.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // file.hpp 3 | // ~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_FILE_HPP 12 | #define AVHTTP_FILE_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include 19 | #include 20 | 21 | namespace avhttp { 22 | 23 | class file : public boost::noncopyable 24 | { 25 | public: 26 | enum 27 | { 28 | // when a file is opened with no_buffer 29 | // file offsets have to be aligned to 30 | // pos_alignment() and buffer addresses 31 | // to buf_alignment() and read/write sizes 32 | // to size_alignment() 33 | read_only = 0, 34 | write_only = 1, 35 | read_write = 2, 36 | rw_mask = read_only | write_only | read_write, 37 | no_buffer = 4, 38 | mode_mask = rw_mask | no_buffer, 39 | sparse = 8, 40 | 41 | attribute_hidden = 0x1000, 42 | attribute_executable = 0x2000, 43 | attribute_mask = attribute_hidden | attribute_executable 44 | }; 45 | 46 | #ifdef WIN32 47 | struct iovec_t 48 | { 49 | void* iov_base; 50 | size_t iov_len; 51 | }; 52 | #else 53 | typedef iovec iovec_t; 54 | #endif 55 | 56 | // use a typedef for the type of iovec_t::iov_base 57 | // since it may differ 58 | #ifdef __sparc__ 59 | typedef char* iovec_base_t; 60 | #else 61 | typedef void* iovec_base_t; 62 | #endif 63 | 64 | typedef boost::int64_t size_type; 65 | typedef boost::uint64_t unsigned_size_type; 66 | 67 | public: 68 | AVHTTP_DECL explicit file(); 69 | AVHTTP_DECL explicit file(fs::path const& p, int m, boost::system::error_code& ec); 70 | AVHTTP_DECL ~file(void); 71 | 72 | AVHTTP_DECL void open(fs::path const& p, int m); 73 | AVHTTP_DECL void open(fs::path const& p, int m, boost::system::error_code& ec); 74 | AVHTTP_DECL bool is_open() const; 75 | AVHTTP_DECL void close(); 76 | AVHTTP_DECL bool set_size(size_type size, boost::system::error_code& ec); 77 | 78 | AVHTTP_DECL int open_mode() const { return m_open_mode; } 79 | 80 | // when opened in unbuffered mode, this is the 81 | // required alignment of file_offsets. i.e. 82 | // any (file_offset & (pos_alignment()-1)) == 0 83 | // is a precondition to read and write operations 84 | AVHTTP_DECL int pos_alignment() const; 85 | 86 | // when opened in unbuffered mode, this is the 87 | // required alignment of buffer addresses 88 | AVHTTP_DECL int buf_alignment() const; 89 | 90 | // read/write buffer sizes needs to be aligned to 91 | // this when in unbuffered mode 92 | AVHTTP_DECL int size_alignment() const; 93 | 94 | AVHTTP_DECL size_type write(const char* buf, int size); 95 | AVHTTP_DECL size_type read(char* buf, int size); 96 | 97 | AVHTTP_DECL size_type write(size_type offset, const char* buf, int size); 98 | AVHTTP_DECL size_type read(size_type offset, char* buf, int size); 99 | 100 | AVHTTP_DECL size_type writev(size_type file_offset, iovec_t const* bufs, int num_bufs, boost::system::error_code& ec); 101 | AVHTTP_DECL size_type readv(size_type file_offset, iovec_t const* bufs, int num_bufs, boost::system::error_code& ec); 102 | 103 | AVHTTP_DECL bool flush(); 104 | 105 | AVHTTP_DECL size_type offset(boost::system::error_code& ec); 106 | AVHTTP_DECL file::size_type offset(size_type offset, boost::system::error_code& ec); 107 | 108 | AVHTTP_DECL size_type get_size(boost::system::error_code& ec) const; 109 | 110 | // return the offset of the first byte that 111 | // belongs to a data-region 112 | AVHTTP_DECL size_type sparse_end(size_type start) const; 113 | 114 | AVHTTP_DECL size_type phys_offset(size_type offset); 115 | 116 | #ifdef WIN32 117 | AVHTTP_DECL HANDLE native_handle() const { return m_file_handle; } 118 | #else 119 | AVHTTP_DECL int native_handle() const { return m_fd; } 120 | #endif 121 | 122 | private: 123 | 124 | #ifdef WIN32 125 | HANDLE m_file_handle; 126 | std::string m_path; 127 | #else 128 | int m_fd; 129 | #endif 130 | #if defined WIN32 || defined __linux__ || defined DEBUG 131 | AVHTTP_DECL void init_file() const; 132 | mutable int m_page_size; 133 | #endif 134 | int m_open_mode; 135 | #if defined WIN32 || defined __linux__ 136 | mutable int m_sector_size; 137 | #endif 138 | #if defined WIN32 139 | mutable int m_cluster_size; 140 | #endif 141 | }; 142 | 143 | } // namespace avhttp 144 | 145 | #if defined(AVHTTP_HEADER_ONLY) 146 | # include "avhttp/impl/file.ipp" 147 | #endif 148 | 149 | #endif // AVHTTP_FILE_HPP 150 | -------------------------------------------------------------------------------- /include/avhttp/file_upload.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // upload.hpp 3 | // ~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2003, Arvid Norberg All rights reserved. 6 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_UPLOAD_HPP 13 | #define AVHTTP_UPLOAD_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | #include 20 | #include "avhttp/http_stream.hpp" 21 | 22 | BOOST_STATIC_ASSERT_MSG(BOOST_VERSION >= 105400, "You must use boost-1.54 or later!!!"); 23 | 24 | namespace avhttp { 25 | 26 | // WebForm文件上传组件. 27 | // 根据RFC1867(http://www.servlets.com/rfcs/rfc1867.txt)实现. 28 | // @begin example 29 | // boost::asio::io_context io; 30 | // avhttp::file_upload upload(io); 31 | // avhttp::file_upload::form_agrs fields; 32 | // fields["username"] = "Cai"; 33 | // boost::system::error_code ec; 34 | // upload.open("http://example.upload/upload", "cppStudy.tar.bz2", 35 | // "file", fields, ec); 36 | // if (ec) 37 | // { 38 | // // 处理错误. 39 | // } 40 | // // 开始上传文件数据. 41 | // avhttp::default_storge file; 42 | // file.open("\\root\\cppStudy.tar.bz2", ec); 43 | // if (ec) 44 | // { 45 | // // 处理错误. 46 | // } 47 | // 48 | // boost::array buffer; 49 | // while (!file.eof()) 50 | // { 51 | // int readed = file.read(buffer.data(), 1024); 52 | // boost::asio::write(upload, boost::asio::buffer(buffer, readed), ec); 53 | // if (ec) 54 | // { 55 | // // 处理错误. 56 | // } 57 | // } 58 | // upload.write_tail(ec); 59 | // if (ec) 60 | // { 61 | // // 处理错误. 62 | // } 63 | // ... 64 | // @end example 65 | class file_upload : public boost::noncopyable 66 | { 67 | public: 68 | typedef std::map form_args; 69 | 70 | ///Constructor. 71 | // @param io用户指定的io_service对象. 72 | // @param fake_continue指定启用fake-continue消息. 73 | // fake continue消息用于在http服务器不支持100的时候, 74 | // 在async_open/open打开时, 返回一个fake continue. 75 | AVHTTP_DECL explicit file_upload(boost::asio::io_context& io, bool fake_continue = false); 76 | 77 | /// Destructor. 78 | AVHTTP_DECL virtual ~file_upload(); 79 | 80 | ///异步打开文件上传. 81 | template 82 | void async_open(const std::string& url, const std::string& filename, 83 | const std::string& file_of_form, const form_args& args, BOOST_ASIO_MOVE_ARG(Handler) handler); 84 | 85 | ///打开文件上传. 86 | // @param url指定上传文件的url. 87 | // @param filename指定的上传文件名. 88 | // @param file_of_form在web form中的上传文件名字段. 89 | // @param args其它各上传文件字段. 90 | // @param ec错误信息. 91 | // @begin example 92 | // avhttp::file_upload f(io_service); 93 | // file_upload::form_agrs fields; 94 | // fields["username"] = "Cai"; 95 | // boost::system::error_code ec; 96 | // f.open("http://example.upload/upload.cgi", "cppStudy.tar.bz2", 97 | // "file", fields, ec); 98 | // @end example 99 | AVHTTP_DECL void open(const std::string& url, const std::string& filename, 100 | const std::string& file_of_form, const form_args& args, boost::system::error_code& ec); 101 | 102 | ///打开文件上传. 103 | // @param url指定上传文件的url. 104 | // @param filename指定的上传文件名. 105 | // @param file_of_form在web form中的上传文件名字段. 106 | // @param args其它各上传文件字段. 107 | // 失败将抛出一个boost::system::system_error异常. 108 | // @begin example 109 | // avhttp::file_upload f(io_service); 110 | // file_upload::form_agrs fields; 111 | // fields["username"] = "Cai"; 112 | // boost::system::error_code ec; 113 | // f.open("http://example.upload/upload.cgi", "cppStudy.tar.bz2", 114 | // "file", fields, ec); 115 | // @end example 116 | AVHTTP_DECL void open(const std::string& url, const std::string& filename, 117 | const std::string& file_of_form, const form_args& agrs); 118 | 119 | ///发送一些上传的文件数据. 120 | // @param buffers是一个或多个用于发送数据缓冲. 这个类型必须满足ConstBufferSequence, 参考文档: 121 | // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConstBufferSequence.html 122 | // @返回实现发送的数据大小. 123 | // @备注: 该函数将会阻塞到一直等待数据被发送或发生错误时才返回. 124 | // write_some不保证发送完所有数据, 用户需要根据返回值来确定已经发送的数据大小. 125 | // @begin example 126 | // try 127 | // { 128 | // std::size bytes_transferred = f.write_some(boost::asio::buffer(data, size)); 129 | // } 130 | // catch (boost::asio::system_error& e) 131 | // { 132 | // std::cerr << e.what() << std::endl; 133 | // } 134 | // ... 135 | // @end example 136 | // 关于示例中的boost::asio::buffer用法可以参考boost中的文档. 它可以接受一个 137 | // boost.array或std.vector作为数据容器. 138 | template 139 | std::size_t write_some(const ConstBufferSequence& buffers); 140 | 141 | ///发送一些上传的文件数据. 142 | // @param buffers是一个或多个用于发送数据缓冲. 这个类型必须满足ConstBufferSequence, 参考文档: 143 | // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConstBufferSequence.html 144 | // @返回实现发送的数据大小. 145 | // @备注: 该函数将会阻塞到一直等待数据被发送或发生错误时才返回. 146 | // write_some不保证发送完所有数据, 用户需要根据返回值来确定已经发送的数据大小. 147 | // @begin example 148 | // boost::system::error_code ec; 149 | // std::size bytes_transferred = f.write_some(boost::asio::buffer(data, size), ec); 150 | // ... 151 | // @end example 152 | // 关于示例中的boost::asio::buffer用法可以参考boost中的文档. 它可以接受一个 153 | // boost.array或std.vector作为数据容器. 154 | template 155 | std::size_t write_some(const ConstBufferSequence& buffers, 156 | boost::system::error_code& ec); 157 | 158 | ///异步上传一些文件数据. 159 | // @param buffers一个或多个用于读取数据的缓冲区, 这个类型必须满足ConstBufferSequence, 160 | // ConstBufferSequence的定义在boost.asio文档中. 161 | // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConstBufferSequence.html 162 | // @param handler在发送操作完成或出现错误时, 将被回调, 它满足以下条件: 163 | // @begin code 164 | // void handler( 165 | // int bytes_transferred, // 返回发送的数据字节数. 166 | // const boost::system::error_code& ec // 用于返回操作状态. 167 | // ); 168 | // @end code 169 | // @begin example 170 | // void handler(int bytes_transferred, const boost::system::error_code& ec) 171 | // { 172 | // // 处理异步回调. 173 | // } 174 | // file_upload f(io_service); 175 | // ... 176 | // f.async_write_some(boost::asio::buffer(data, size), handler); 177 | // ... 178 | // @end example 179 | // 关于示例中的boost::asio::buffer用法可以参考boost中的文档. 它可以接受一个 180 | // boost.array或std.vector作为数据容器. 181 | template 182 | void async_write_some(const ConstBufferSequence& buffers, BOOST_ASIO_MOVE_ARG(Handler) handler); 183 | 184 | ///发送结尾行. 185 | // @param ec错误信息. 186 | AVHTTP_DECL void write_tail(boost::system::error_code& ec); 187 | 188 | ///发送结尾行. 189 | // 失败将抛出一个boost::system::system_error异常. 190 | AVHTTP_DECL void write_tail(); 191 | 192 | ///异步发送结尾行. 193 | // @param handler在发送操作完成或出现错误时, 将被回调, 它满足以下条件: 194 | // @begin code 195 | // void handler( 196 | // const boost::system::error_code& ec // 用于返回操作状态. 197 | // ); 198 | // @end code 199 | // @begin example 200 | // void tail_handler(const boost::system::error_code& ec) 201 | // { 202 | // if (!ec) 203 | // { 204 | // // 发送成功! 205 | // } 206 | // } 207 | // ... 208 | // avhttp::file_upload f(io_service); 209 | // ... 210 | // f.async_write_tail(handler); 211 | // @end example 212 | // @备注: handler也可以使用boost.bind来绑定一个符合规定的函数作 213 | // 为async_open的参数handler. 214 | template 215 | void async_write_tail(BOOST_ASIO_MOVE_ARG(Handler) handler); 216 | 217 | ///设置http header选项. 218 | AVHTTP_DECL void request_option(request_opts& opts); 219 | 220 | ///返回http_stream对象的引用. 221 | AVHTTP_DECL http_stream& get_http_stream(); 222 | 223 | ///反回当前file_upload所使用的io_service的引用. 224 | AVHTTP_DECL boost::asio::io_context& get_io_service(); 225 | 226 | private: 227 | 228 | template 229 | struct open_coro; 230 | 231 | template 232 | struct tail_coro; 233 | 234 | ///辅助函数,用于创建协程并进行 Templet type deduction. 235 | template 236 | open_coro make_open_coro(const std::string& url, const std::string& filename, 237 | const std::string& file_of_form, const form_args& args, BOOST_ASIO_MOVE_ARG(Handler) handler); 238 | 239 | ///辅助函数,用于创建协程并进行 Templet type deduction. 240 | template 241 | tail_coro make_tail_coro(BOOST_ASIO_MOVE_ARG(Handler) handler); 242 | 243 | private: 244 | 245 | // io_service引用. 246 | boost::asio::io_context& m_io_service; 247 | 248 | // http_stream对象. 249 | http_stream m_http_stream; 250 | 251 | // 边界符. 252 | std::string m_boundary; 253 | std::string m_base_boundary; 254 | 255 | // 表单参数. 256 | form_args m_form_args; 257 | 258 | // 是否启用fake-continue消息. 259 | // fake continue消息用于在http服 260 | // 务器不支持100的时候, 在 261 | // async_open/open打开时, 返回一个 262 | // fake continue. 263 | bool m_fake_continue; 264 | }; 265 | 266 | } // namespace avhttp 267 | 268 | #if defined(AVHTTP_HEADER_ONLY) 269 | # include "avhttp/impl/file_upload.ipp" 270 | #endif 271 | 272 | #endif // AVHTTP_UPLOAD_HPP 273 | -------------------------------------------------------------------------------- /include/avhttp/impl/src.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // impl/src.hpp 3 | // ~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_IMPL_SRC_HPP 12 | #define AVHTTP_IMPL_SRC_HPP 13 | 14 | #if defined(AVHTTP_HEADER_ONLY) 15 | # error Do not compile avhttp library source with AVHTTP_HEADER_ONLY defined 16 | #endif 17 | 18 | #include "avhttp/impl/file.ipp" 19 | #include "avhttp/impl/file_upload.ipp" 20 | #include "avhttp/impl/http_stream.ipp" 21 | #include "avhttp/impl/multi_download.ipp" 22 | 23 | #endif // AVHTTP_IMPL_SRC_HPP 24 | -------------------------------------------------------------------------------- /include/avhttp/post_form.hpp: -------------------------------------------------------------------------------- 1 | #ifndef AVHTTP_POST_FORM_HPP 2 | #define AVHTTP_POST_FORM_HPP 3 | #include "avhttp/http_stream.hpp" 4 | #include 5 | #include 6 | 7 | namespace avhttp { 8 | 9 | typedef std::map KeyValues; 10 | 11 | AVHTTP_DECL std::string map_to_query(const KeyValues& key_values) 12 | { 13 | if(key_values.size() == 0) 14 | { 15 | return std::string(); 16 | } 17 | 18 | std::stringstream ss; 19 | for(KeyValues::const_iterator iter = key_values.begin(); 20 | iter != key_values.end(); 21 | ++iter) 22 | { 23 | ss << iter->first << "=" << iter->second << "&"; 24 | } 25 | 26 | const std::string& temp = ss.str(); 27 | return std::string(temp.begin(), temp.begin() + temp.size() - 1); 28 | } 29 | 30 | AVHTTP_DECL void post_form(http_stream& stream, const KeyValues& key_values) 31 | { 32 | const std::string& body = map_to_query(key_values); 33 | request_opts opts = stream.request_options(); 34 | opts.remove(http_options::request_method); 35 | opts.remove(http_options::request_body); 36 | opts.remove(http_options::content_type); 37 | opts.remove(http_options::content_length); 38 | opts.insert(http_options::content_length, (boost::format("%1%") % body.size()).str()); 39 | opts.insert(http_options::content_type, "application/x-www-form-urlencoded"); 40 | opts.insert(http_options::request_body, body); 41 | opts.insert(http_options::request_method, "POST"); 42 | stream.request_options(opts); 43 | } 44 | } 45 | 46 | #endif // AVHTTP_POST_FORM_HPP 47 | -------------------------------------------------------------------------------- /include/avhttp/read_body.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // async_read_body.hpp 3 | // ~~~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2014 Jack (jack dot wgm at gmail dot com) 6 | // Copyright (C) 2012 - 2014 微蔡 7 | // 8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | 12 | #ifndef AVHTTP_MISC_HTTP_READBODY_HPP 13 | #define AVHTTP_MISC_HTTP_READBODY_HPP 14 | 15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 | # pragma once 17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 | 19 | #include "avhttp/http_stream.hpp" 20 | #include "avhttp/completion_condition.hpp" 21 | 22 | 23 | namespace avhttp { 24 | ///用于http_stream访问url. 25 | // 这个函数用于http_stream访问指定的url, 数据将保存在用户事先提供的buffers中. 26 | // @注意: 27 | // 1. 该函数返回条件为直到读取完整的body或eof或其它错误, 错误信息通过error_code传回. 28 | // @param stream 一个http_stream对象. 29 | // @param url 指定的url. 30 | // @param buffers 一个或多个用于读取数据的缓冲区 31 | // 这个类型必须满足MutableBufferSequence, MutableBufferSequence的定义. 32 | // 具体可参考boost.asio文档中相应的描述. 33 | template 34 | AVHTTP_DECL std::size_t read_body(AsyncReadStream& stream, 35 | const avhttp::url& url, MutableBufferSequence& buffers, boost::system::error_code &ec) 36 | { 37 | std::size_t readed = 0; 38 | stream.open(url, ec); 39 | if (ec) 40 | return -1; 41 | readed = boost::asio::read(stream, buffers, transfer_response_body(stream.content_length()), ec); 42 | 43 | if(ec == boost::asio::error::eof && stream.content_length() == -1) 44 | ec = boost::system::error_code(); 45 | return readed; 46 | } 47 | 48 | } // namespace avhttp 49 | 50 | #endif // AVHTTP_MISC_HTTP_READBODY_HPP 51 | 52 | -------------------------------------------------------------------------------- /include/avhttp/settings.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // settings.hpp 3 | // ~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_SETTINGS_HPP 12 | #define AVHTTP_SETTINGS_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "avhttp/storage_interface.hpp" 26 | 27 | namespace avhttp { 28 | 29 | // 如果没有定义最大重定向次数, 则默认为5次最大重定向. 30 | #ifndef AVHTTP_MAX_REDIRECTS 31 | #define AVHTTP_MAX_REDIRECTS 5 32 | #endif 33 | 34 | // 常用有以下http选项. 35 | namespace http_options { 36 | 37 | // 下面为avhttp内定的一些选项. 38 | static const std::string request_method("_request_method"); // 请求方式(GET/POST) 39 | static const std::string http_version("_http_version"); // HTTP/1.0|HTTP/1.1 40 | static const std::string request_body("_request_body"); // 一般用于POST一些数据如表单之类时使用. 41 | static const std::string status_code("_status_code"); // HTTP状态码. 42 | static const std::string path("_path"); // 请求的path, 如http://abc.ed/v2/cma.txt中的/v2/cma.txt. 43 | static const std::string url("_url"); // 在启用keep-alive的时候, 请求host上不同的url时使用. 44 | // 以下是常用的标准http head选项. 45 | static const std::string host("Host"); 46 | static const std::string accept("Accept"); 47 | static const std::string range("Range"); 48 | static const std::string cookie("Cookie"); 49 | static const std::string referer("Referer"); 50 | static const std::string user_agent("User-Agent"); 51 | static const std::string content_type("Content-Type"); 52 | static const std::string content_length("Content-Length"); 53 | static const std::string content_range("Content-Range"); 54 | static const std::string connection("Connection"); 55 | static const std::string proxy_connection("Proxy-Connection"); 56 | static const std::string accept_encoding("Accept-Encoding"); 57 | static const std::string transfer_encoding("Transfer-Encoding"); 58 | static const std::string content_encoding("Content-Encoding"); 59 | 60 | } // namespace http_options 61 | 62 | 63 | // 具体的http的option选项实现. 64 | 65 | class option 66 | { 67 | public: 68 | // 定义option_item类型. 69 | typedef std::pair option_item; 70 | // 定义option_item_list类型. 71 | typedef std::vector option_item_list; 72 | // for boost::assign::insert 73 | typedef option_item value_type; 74 | // 定义选项回调. 75 | typedef boost::function body_callback_func; 76 | 77 | public: 78 | 79 | option() 80 | : m_fake_continue(false) 81 | {} 82 | 83 | ~option() 84 | {} 85 | 86 | public: 87 | 88 | // 这样就允许这样的应用: 89 | // http_stream s; 90 | // s.request_options(request_opts()("cookie", "XXXXXX")); 91 | option& operator()(const std::string& key, const std::string& val) 92 | { 93 | insert(key, val); 94 | return *this; 95 | } 96 | 97 | // 添加选项, 由key/value形式添加. 98 | void insert(const std::string& key, const std::string& val) 99 | { 100 | m_opts.push_back(option_item(key, val)); 101 | } 102 | 103 | // 添加选项,由 std::part 形式. 104 | void insert(value_type& item) 105 | { 106 | m_opts.push_back(item); 107 | } 108 | 109 | // 删除选项. 110 | option& remove(const std::string& key) 111 | { 112 | for (option_item_list::iterator i = m_opts.begin(); i != m_opts.end(); i++) 113 | { 114 | if (i->first == key) 115 | { 116 | m_opts.erase(i); 117 | return *this; 118 | } 119 | } 120 | return *this; 121 | } 122 | 123 | // 查找指定key的value. 124 | bool find(const std::string& key, std::string& val) const 125 | { 126 | std::string s = key; 127 | boost::to_lower(s); 128 | for (option_item_list::const_iterator f = m_opts.begin(); f != m_opts.end(); f++) 129 | { 130 | std::string temp = f->first; 131 | boost::to_lower(temp); 132 | if (temp == s) 133 | { 134 | val = f->second; 135 | return true; 136 | } 137 | } 138 | return false; 139 | } 140 | 141 | // 查找指定的 key 的 value. 没找到返回 "", 这是个偷懒的帮助. 142 | std::string find(const std::string& key) const 143 | { 144 | std::string v; 145 | find(key, v); 146 | return v; 147 | } 148 | 149 | // 得到Header字符串. 150 | std::string header_string() const 151 | { 152 | std::string str; 153 | for (option_item_list::const_iterator f = m_opts.begin(); f != m_opts.end(); f++) 154 | { 155 | if (f->first != http_options::status_code) 156 | str += (f->first + ": " + f->second + "\r\n"); 157 | } 158 | return str; 159 | } 160 | 161 | // 清空. 162 | void clear() 163 | { 164 | m_opts.clear(); 165 | } 166 | 167 | // 返回所有option. 168 | option_item_list& option_all() 169 | { 170 | return m_opts; 171 | } 172 | 173 | // 返回当前option个数. 174 | int size() const 175 | { 176 | return m_opts.size(); 177 | } 178 | 179 | // 返回fake_continue. 180 | bool fake_continue() const 181 | { 182 | return m_fake_continue; 183 | } 184 | 185 | // 设置fake_continue. 186 | void fake_continue(bool b) 187 | { 188 | m_fake_continue = b; 189 | } 190 | 191 | protected: 192 | // 选项列表. 193 | option_item_list m_opts; 194 | 195 | // 是否启用假100 continue消息, 如果启用, 则在发送完成http request head 196 | // 之后, 返回一个fake continue消息. 197 | bool m_fake_continue; 198 | }; 199 | 200 | // 请求时的http选项. 201 | // _http_version, 取值 "HTTP/1.0" / "HTTP/1.1", 默认为"HTTP/1.1". 202 | // _request_method, 取值 "GET/POST/HEAD", 默认为"GET". 203 | // _request_body, 请求中的body内容, 取值任意, 默认为空. 204 | // Host, 取值为http服务器, 默认为http服务器. 205 | // Accept, 取值任意, 默认为"*/*". 206 | // 这些比较常用的选项被定义在http_options中. 207 | typedef option request_opts; 208 | 209 | // http服务器返回的http选项. 210 | // 一般会包括以下几个选项: 211 | // _status_code, http返回状态. 212 | // Server, 服务器名称. 213 | // Content-Length, 数据内容长度. 214 | // Connection, 连接状态标识. 215 | typedef option response_opts; 216 | 217 | 218 | 219 | // Http请求的代理设置. 220 | 221 | struct proxy_settings 222 | { 223 | proxy_settings() 224 | : type (none) 225 | {} 226 | 227 | std::string hostname; 228 | int port; 229 | 230 | std::string username; 231 | std::string password; 232 | 233 | enum proxy_type 234 | { 235 | // 没有设置代理. 236 | none, 237 | // socks4代理, 需要username. 238 | socks4, 239 | // 不需要用户密码的socks5代理. 240 | socks5, 241 | // 需要用户密码认证的socks5代理. 242 | socks5_pw, 243 | // http代理, 不需要认证. 244 | http, 245 | // http代理, 需要认证. 246 | http_pw, 247 | }; 248 | 249 | proxy_type type; 250 | }; 251 | 252 | 253 | // 一些默认的值. 254 | static const int default_request_piece_num = 10; 255 | static const int default_time_out = 11; 256 | static const int default_connections_limit = 5; 257 | static const int default_buffer_size = 1024; 258 | 259 | // multi_download下载设置. 260 | 261 | struct settings 262 | { 263 | settings () 264 | : download_rate_limit(-1) 265 | , connections_limit(default_connections_limit) 266 | , piece_size(-1) 267 | , time_out(default_time_out) 268 | , request_piece_num(default_request_piece_num) 269 | , allow_use_meta_url(true) 270 | , disable_multi_download(false) 271 | , check_certificate(true) 272 | , storage(NULL) 273 | {} 274 | 275 | // 下载速率限制, -1为无限制, 单位为: byte/s. 276 | int download_rate_limit; 277 | 278 | // 连接数限制, -1为默认. 279 | int connections_limit; 280 | 281 | // 分块大小, 默认根据文件大小自动计算. 282 | int piece_size; 283 | 284 | // 超时断开, 默认为11秒. 285 | int time_out; 286 | 287 | // 每次请求的分片数, 默认为10. 288 | int request_piece_num; 289 | 290 | // meta_file路径, 默认为当前路径下同文件名的.meta文件. 291 | fs::path meta_file; 292 | 293 | // 允许使用meta中保存的url, 默认为允许. 针对一些变动的url, 我们应该禁用. 294 | bool allow_use_meta_url; 295 | 296 | // 禁止使用并发下载. 297 | // NOTE: 比如用于动态页面下载, 因为动态页面不能使用并发下载, 如果还想继续使用 298 | // multi_download进行下载, 则需要设置这个参数, 否则并发下载动态数据的行为, 是 299 | // 未定义的, 其结果可能因为数据长度不一至导致断言, 也可能数据错误. 300 | // NOTE: 不推荐使用multi_download进行下载, 而应该使用http_stream进行下载, 301 | // multi_download主要应用在大文件, 静态页面下载! 302 | bool disable_multi_download; 303 | 304 | // 下载文件路径, 默认为当前目录. 305 | fs::path save_path; 306 | 307 | // 设置是否检查证书, 默认检查证书. 308 | bool check_certificate; 309 | 310 | // 存储接口创建函数指针, 默认为multi_download提供的file.hpp实现. 311 | storage_constructor_type storage; 312 | 313 | // 请求选项. 314 | request_opts opts; 315 | 316 | // 代理设置. 317 | proxy_settings proxy; 318 | }; 319 | 320 | } // namespace avhttp 321 | 322 | #endif // AVHTTP_SETTINGS_HPP 323 | -------------------------------------------------------------------------------- /include/avhttp/storage_interface.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // storage_interface.hpp 3 | // ~~~~~~~~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef AVHTTP_STORAGE_INTERFACE_HPP 12 | #define AVHTTP_STORAGE_INTERFACE_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace avhttp { 23 | 24 | namespace fs = boost::filesystem; 25 | 26 | // 数据存储接口. 27 | struct storage_interface 28 | { 29 | storage_interface() {} 30 | virtual ~storage_interface() {} 31 | 32 | // 存储组件初始化. 33 | // @param file_path指定了文件名路径信息. 34 | // @param ec在出错时保存了详细的错误信息. 35 | virtual void open(const fs::path& file_path, boost::system::error_code& ec) = 0; 36 | 37 | // 关闭存储组件. 38 | virtual void close() = 0; 39 | 40 | // 写入数据到文件. 41 | // @param buf是需要写入的数据缓冲. 42 | // @param size指定了写入的数据缓冲大小. 43 | // @返回值为实际写入的字节数, 返回-1表示写入失败. 44 | // 备注: 在文件指针当前位置写入, 写入完成将自动移动文件指针到完成位置, 保证和fwrite行为一至. 45 | virtual std::streamsize write(const char* buf, int size) = 0; 46 | 47 | // 写入数据. 48 | // @param buf是需要写入的数据缓冲. 49 | // @param offset是写入的偏移位置. 50 | // @param size指定了写入的数据缓冲大小. 51 | // @返回值为实际写入的字节数, 返回-1表示写入失败. 52 | virtual std::streamsize write(const char* buf, boost::int64_t offset, int size) = 0; 53 | 54 | // 从文件读取数据. 55 | // @param buf是需要读取的数据缓冲. 56 | // @param size指定了读取的数据缓冲大小. 57 | // @返回值为实际读取的字节数, 返回-1表示读取失败. 58 | // 备注: 在文件指针当前位置开始读取, 读取完成将自动移动文件指针到完成位置, 保证和fread行为一至. 59 | virtual std::streamsize read(char* buf, int size) = 0; 60 | 61 | // 读取数据. 62 | // @param buf是需要读取的数据缓冲. 63 | // @param offset是读取的偏移位置. 64 | // @param size指定了读取的数据缓冲大小. 65 | // @返回值为实际读取的字节数, 返回-1表示读取失败. 66 | virtual std::streamsize read(char* buf, boost::int64_t offset, int size) = 0; 67 | 68 | // 判断是否文件结束. 69 | // 返回值true表示文件结束. 70 | virtual bool eof() = 0; 71 | }; 72 | 73 | // 重定义storage_interface创建函数指针, 在multi_download内部通过调用它来完成创建storage_interface. 74 | typedef storage_interface* (*storage_constructor_type)(); 75 | 76 | } 77 | 78 | #endif // AVHTTP_STORAGE_INTERFACE_HPP 79 | -------------------------------------------------------------------------------- /include/avhttp/version.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2013 Jack (jack dot wgm at gmail dot com) 3 | // 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 | // path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | 8 | #ifndef AVHTTP_VERSION_HPP 9 | #define AVHTTP_VERSION_HPP 10 | 11 | #define AVHTTP_VERSION_MAJOR 2 12 | #define AVHTTP_VERSION_MINOR 9 13 | #define AVHTTP_VERSION_TINY 9 14 | 15 | // the format of this version is: MMmmtt 16 | // M = Major version, m = minor version, t = tiny version 17 | #define AVHTTP_VERSION_NUM ((AVHTTP_VERSION_MAJOR * 10000) + (AVHTTP_VERSION_MINOR * 100) + AVHTTP_VERSION_TINY) 18 | #define AVHTTP_VERSION "2.9.9" 19 | #define AVHTTP_VERSION_MIME "avhttp/" AVHTTP_VERSION 20 | // #define AVHTTP_REVISION "$Git-Rev$" 21 | 22 | 23 | #endif // AVHTTP_VERSION_HPP 24 | -------------------------------------------------------------------------------- /project-root.jam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/project-root.jam -------------------------------------------------------------------------------- /test/async_proxy_test.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/test/async_proxy_test.cpp -------------------------------------------------------------------------------- /test/avhttp_include.cpp: -------------------------------------------------------------------------------- 1 |  2 | #include -------------------------------------------------------------------------------- /test/cookie_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "avhttp.hpp" 4 | 5 | 6 | int main(int argc, char** argv) 7 | { 8 | avhttp::cookies cookie; 9 | cookie("sf_mirror_attempt=avplayer:optimate|softlayer-ams:/avplayer/exe/release-2013-03-13.7z; expires=Tue, 3-Dec-2013 14:52:55 GMT; Path=/"); 10 | BOOST_ASSERT(cookie["sf_mirror_attempt"] == std::string("avplayer:optimate|softlayer-ams:/avplayer/exe/release-2013-03-13.7z")); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test/multi_avhttp_test.cpp: -------------------------------------------------------------------------------- 1 | #include "avhttp.hpp" 2 | 3 | int main(int argc, char** argv) 4 | { 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /test/multi_download_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "avhttp.hpp" 6 | 7 | std::string to_string(int v, int width) 8 | { 9 | std::stringstream s; 10 | s.flags(std::ios_base::right); 11 | s.width(width); 12 | s.fill(' '); 13 | s << v; 14 | return s.str(); 15 | } 16 | 17 | std::string& to_string(float v, int width, int precision = 3) 18 | { 19 | // this is a silly optimization 20 | // to avoid copying of strings 21 | enum { num_strings = 20 }; 22 | static std::string buf[num_strings]; 23 | static int round_robin = 0; 24 | std::string& ret = buf[round_robin]; 25 | ++round_robin; 26 | if (round_robin >= num_strings) round_robin = 0; 27 | ret.resize(20); 28 | int size = sprintf(&ret[0], "%*.*f", width, precision, v); 29 | ret.resize((std::min)(size, width)); 30 | return ret; 31 | } 32 | 33 | std::string add_suffix(float val, char const* suffix = 0) 34 | { 35 | std::string ret; 36 | if (val == 0) 37 | { 38 | ret.resize(4 + 2, ' '); 39 | if (suffix) ret.resize(4 + 2 + strlen(suffix), ' '); 40 | return ret; 41 | } 42 | 43 | const char* prefix[] = {"kB", "MB", "GB", "TB"}; 44 | const int num_prefix = sizeof(prefix) / sizeof(const char*); 45 | for (int i = 0; i < num_prefix; ++i) 46 | { 47 | val /= 1024.f; 48 | if (std::fabs(val) < 1024.f) 49 | { 50 | ret = to_string(val, 4); 51 | ret += prefix[i]; 52 | if (suffix) ret += suffix; 53 | return ret; 54 | } 55 | } 56 | ret = to_string(val, 4); 57 | ret += "PB"; 58 | if (suffix) ret += suffix; 59 | return ret; 60 | } 61 | 62 | int main(int argc, char* argv[]) 63 | { 64 | if (argc != 2) 65 | { 66 | std::cerr << "usage: " << argv[0] << " \n"; 67 | return -1; 68 | } 69 | try { 70 | boost::asio::io_service io; 71 | avhttp::multi_download d(io); 72 | 73 | avhttp::settings s; 74 | // s.m_download_rate_limit = 102400; 75 | 76 | d.start(argv[1], s); 77 | 78 | if (d.file_size() != -1) 79 | std::cout << "file \'" << d.file_name().c_str() << 80 | "\' size is: " << "(" << d.file_size() << " bytes) " << add_suffix(d.file_size()).c_str() << std::endl; 81 | 82 | boost::thread t(boost::bind(&boost::asio::io_service::run, &io)); 83 | 84 | if (d.file_size() != -1) 85 | { 86 | printf("\n"); 87 | int percent = 0; 88 | boost::int64_t file_size = d.file_size(); 89 | boost::int64_t bytes_download = 0; 90 | while (percent != 100) 91 | { 92 | bytes_download = d.bytes_download(); 93 | percent = ((double)bytes_download / (double)file_size) * 100.0f; 94 | boost::this_thread::sleep(boost::posix_time::millisec(200)); 95 | printf("\r"); 96 | printf("%3d%% [", percent); 97 | int progress = percent / 2; 98 | for (int i = 0; i < progress; i++) 99 | printf("="); 100 | if (progress != 50) 101 | printf(">"); 102 | for (int i = 0; i < 49 - progress; i++) 103 | printf(" "); 104 | printf("] %s %s/s", add_suffix(bytes_download).c_str(), add_suffix(d.download_rate()).c_str()); 105 | } 106 | printf("\n"); 107 | } 108 | 109 | t.join(); 110 | 111 | std::cout << "\n*** download completed! ***\n"; 112 | } 113 | catch (std::exception &e) 114 | { 115 | std::cerr << e.what() << std::endl; 116 | return -1; 117 | } 118 | 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /test/percent_encoding_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "avhttp.hpp" 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | std::vector unreserved_chars; 7 | for(char i = 'a'; i <= 'z'; ++i) 8 | { 9 | unreserved_chars.push_back(i); 10 | } 11 | for(char i = 'A'; i <= 'Z'; ++i) 12 | { 13 | unreserved_chars.push_back(i); 14 | } 15 | for(char i = '0'; i <= '9'; ++i) 16 | { 17 | unreserved_chars.push_back(i); 18 | } 19 | unreserved_chars.push_back('-'); 20 | unreserved_chars.push_back('_'); 21 | unreserved_chars.push_back('.'); 22 | unreserved_chars.push_back('~'); 23 | 24 | std::set unescaped_chars_set(unreserved_chars.begin(), unreserved_chars.end()); 25 | 26 | std::vector all_asci_vector; 27 | for(size_t i = 0; i <= 0xff; ++i) 28 | { 29 | all_asci_vector.push_back(static_cast(i)); 30 | } 31 | 32 | std::string str(&all_asci_vector[0], all_asci_vector.size()); 33 | auto encoded = avhttp::detail::escape_string(str); 34 | 35 | assert(encoded.size() == (all_asci_vector.size() - unreserved_chars.size()) * 3 + unreserved_chars.size()); 36 | 37 | int position = 0; 38 | for(size_t i = 0; i < all_asci_vector.size(); ++i) 39 | { 40 | char ch = all_asci_vector[i]; 41 | if (unescaped_chars_set.end() != unescaped_chars_set.find(ch)) 42 | { 43 | assert(encoded[position] == ch); 44 | position += 1; 45 | } 46 | else 47 | { 48 | char out_str[3]; 49 | avhttp::detail::to_hex(&ch, 1, out_str); 50 | 51 | assert(encoded[position] == '%'); 52 | assert(encoded[position+1] == out_str[0]); 53 | assert(encoded[position+2] == out_str[1]); 54 | 55 | position += 3; 56 | } 57 | } 58 | 59 | std::string decoded; 60 | bool res = avhttp::detail::unescape_path(encoded, decoded); 61 | assert(res); 62 | assert(decoded == str); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /test/sync_proxy_test.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/test/sync_proxy_test.cpp -------------------------------------------------------------------------------- /vcprojects/async_http_stream-vc2005.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual Studio 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "async_http_stream", "async_http_stream-vc2005.vcproj", "{B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.Build.0 = Debug|Win32 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.ActiveCfg = Release|Win32 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/async_http_stream-vc2005.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/async_http_stream-vc2005.vcproj -------------------------------------------------------------------------------- /vcprojects/async_http_stream-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "async_http_stream-vc2012", "async_http_stream-vc2012.vcxproj", "{B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.Build.0 = Debug|Win32 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.ActiveCfg = Release|Win32 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/async_http_stream-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2} 15 | async_http_stream 16 | Win32Proj 17 | 18 | 19 | 20 | Application 21 | v110 22 | Unicode 23 | true 24 | 25 | 26 | Application 27 | v110 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | <_ProjectFileVersion>11.0.51106.1 42 | 43 | 44 | $(SolutionDir)$(Configuration)\ 45 | $(Configuration)\ 46 | true 47 | 48 | 49 | $(SolutionDir)$(Configuration)\ 50 | $(Configuration)\ 51 | false 52 | 53 | 54 | 55 | Disabled 56 | ../include;%(AdditionalIncludeDirectories) 57 | WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;AVHTTP_ENABLE_OPENSSL;%(PreprocessorDefinitions) 58 | true 59 | EnableFastChecks 60 | MultiThreadedDebug 61 | 62 | Level3 63 | EditAndContinue 64 | 65 | 66 | true 67 | Console 68 | MachineX86 69 | ..\include\libs;%(AdditionalLibraryDirectories) 70 | libeay32.lib;ssleay32.lib;%(AdditionalDependencies) 71 | /SAFESEH:NO %(AdditionalOptions) 72 | 73 | 74 | 75 | 76 | ../include;%(AdditionalIncludeDirectories) 77 | WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 78 | MultiThreaded 79 | 80 | Level3 81 | ProgramDatabase 82 | 83 | 84 | true 85 | Console 86 | true 87 | true 88 | MachineX86 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /vcprojects/async_http_stream-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2005.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual Studio 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aync_proxy_test", "async_proxy_test-vc2005.vcproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2005.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/async_proxy_test-vc2005.vcproj -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2008.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aync_proxy_test", "async_proxy_test-vc2008.vcproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2008.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/async_proxy_test-vc2008.vcproj -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "async_proxy_test", "async_proxy_test-vc2012.vcxproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | async_proxy_test 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2} 16 | avhttp 17 | Win32Proj 18 | 19 | 20 | 21 | Application 22 | v110 23 | Unicode 24 | true 25 | 26 | 27 | Application 28 | v110 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <_ProjectFileVersion>11.0.51106.1 43 | 44 | 45 | $(SolutionDir)$(Configuration)\ 46 | $(Configuration)\ 47 | true 48 | 49 | 50 | $(SolutionDir)$(Configuration)\ 51 | $(Configuration)\ 52 | false 53 | 54 | 55 | 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;AVHTTP_ENABLE_OPENSSL;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 58 | true 59 | EnableFastChecks 60 | MultiThreadedDebug 61 | 62 | Level3 63 | EditAndContinue 64 | ../include;%(AdditionalIncludeDirectories) 65 | 66 | 67 | true 68 | Console 69 | MachineX86 70 | /SAFESEH:NO %(AdditionalOptions) 71 | ..\include\libs;%(AdditionalLibraryDirectories) 72 | ssleay32.lib;libeay32.lib;%(AdditionalDependencies) 73 | 74 | 75 | 76 | 77 | WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 78 | MultiThreadedDebug 79 | 80 | Level3 81 | ProgramDatabase 82 | ../include 83 | 84 | 85 | true 86 | Console 87 | true 88 | true 89 | MachineX86 90 | /SAFESEH:NO %(AdditionalOptions) 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /vcprojects/async_proxy_test-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | {1508c6bd-50ea-431b-9ec1-49ad436c1ff0} 18 | 19 | 20 | {42627b62-82ed-4c48-8a1a-0c23c989ad21} 21 | 22 | 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件\avhttp 29 | 30 | 31 | 头文件\avhttp 32 | 33 | 34 | 头文件\avhttp\detail 35 | 36 | 37 | 头文件\avhttp\detail 38 | 39 | 40 | 头文件\avhttp\detail 41 | 42 | 43 | 头文件\avhttp\detail 44 | 45 | 46 | 头文件\avhttp\detail 47 | 48 | 49 | 头文件\avhttp\detail 50 | 51 | 52 | 头文件\avhttp 53 | 54 | 55 | 头文件\avhttp 56 | 57 | 58 | 头文件\avhttp 59 | 60 | 61 | 头文件\avhttp 62 | 63 | 64 | 头文件\avhttp 65 | 66 | 67 | 头文件\avhttp\detail 68 | 69 | 70 | 头文件\avhttp 71 | 72 | 73 | 头文件\avhttp\detail 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 源文件 82 | 83 | 84 | -------------------------------------------------------------------------------- /vcprojects/cookie_test-vc2013.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cookie_test-vc2013", "cookie_test-vc2013.vcxproj", "{640BB22C-B1C2-4061-B73C-C0A994B44EA0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {640BB22C-B1C2-4061-B73C-C0A994B44EA0}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {640BB22C-B1C2-4061-B73C-C0A994B44EA0}.Debug|Win32.Build.0 = Debug|Win32 16 | {640BB22C-B1C2-4061-B73C-C0A994B44EA0}.Release|Win32.ActiveCfg = Release|Win32 17 | {640BB22C-B1C2-4061-B73C-C0A994B44EA0}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /vcprojects/cookie_test-vc2013.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {640BB22C-B1C2-4061-B73C-C0A994B44EA0} 15 | Win32Proj 16 | cookie_testvc2013 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | Level3 51 | Disabled 52 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 53 | ..\include 54 | MultiThreadedDebug 55 | 4996 56 | 57 | 58 | Console 59 | true 60 | 61 | 62 | 63 | 64 | Level3 65 | MaxSpeed 66 | true 67 | true 68 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 69 | ..\include 70 | MultiThreaded 71 | 72 | 73 | Console 74 | true 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /vcprojects/cookie_test-vc2013.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /vcprojects/mini_http_server-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mini_http_server-vc2012", "mini_http_server-vc2012.vcxproj", "{66A9D457-92BB-4C85-BF2A-F1F382814A65}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {66A9D457-92BB-4C85-BF2A-F1F382814A65}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {66A9D457-92BB-4C85-BF2A-F1F382814A65}.Debug|Win32.Build.0 = Debug|Win32 14 | {66A9D457-92BB-4C85-BF2A-F1F382814A65}.Release|Win32.ActiveCfg = Release|Win32 15 | {66A9D457-92BB-4C85-BF2A-F1F382814A65}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/mini_http_server-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {66A9D457-92BB-4C85-BF2A-F1F382814A65} 15 | Win32Proj 16 | mini_http_servervc2012 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | WIN32;_DEBUG;_CONSOLE;AVHTTP_DISABLE_MULTI_DOWNLOAD;%(PreprocessorDefinitions) 55 | MultiThreadedDebug 56 | ../include 57 | 58 | 59 | Console 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | 67 | 68 | MaxSpeed 69 | true 70 | true 71 | WIN32;NDEBUG;_CONSOLE;AVHTTP_DISABLE_MULTI_DOWNLOAD;%(PreprocessorDefinitions) 72 | MultiThreaded 73 | ../include 74 | 75 | 76 | Console 77 | true 78 | true 79 | true 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /vcprojects/mini_http_server-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /vcprojects/multi_avhttp_test-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_avhttp_test", "multi_avhttp_test-vc2012.vcxproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/multi_avhttp_test-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | multi_avhttp_test 55 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2} 56 | avhttp 57 | Win32Proj 58 | 59 | 60 | 61 | Application 62 | v110 63 | Unicode 64 | true 65 | 66 | 67 | Application 68 | v110 69 | Unicode 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | <_ProjectFileVersion>11.0.51106.1 83 | 84 | 85 | $(SolutionDir)$(Configuration)\ 86 | $(Configuration)\ 87 | true 88 | 89 | 90 | $(SolutionDir)$(Configuration)\ 91 | $(Configuration)\ 92 | false 93 | 94 | 95 | 96 | Disabled 97 | WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 98 | true 99 | EnableFastChecks 100 | MultiThreadedDebug 101 | 102 | Level3 103 | EditAndContinue 104 | ../include;%(AdditionalIncludeDirectories) 105 | 106 | 107 | true 108 | Console 109 | MachineX86 110 | /SAFESEH:NO %(AdditionalOptions) 111 | ..\include\libs;%(AdditionalLibraryDirectories) 112 | ssleay32.lib;libeay32.lib;%(AdditionalDependencies) 113 | 114 | 115 | 116 | 117 | WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 118 | MultiThreadedDebug 119 | 120 | Level3 121 | ProgramDatabase 122 | ../include 123 | 124 | 125 | true 126 | Console 127 | true 128 | true 129 | MachineX86 130 | /SAFESEH:NO %(AdditionalOptions) 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /vcprojects/multi_download-vc2005.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual Studio 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_download", "multi_download-vc2005.vcproj", "{B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.Build.0 = Debug|Win32 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.ActiveCfg = Release|Win32 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/multi_download-vc2005.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/multi_download-vc2005.vcproj -------------------------------------------------------------------------------- /vcprojects/multi_download-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_download", "multi_download-vc2012.vcxproj", "{B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.Build.0 = Debug|Win32 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.ActiveCfg = Release|Win32 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/multi_download-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | multi_download 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2} 16 | async_http_stream 17 | Win32Proj 18 | 19 | 20 | 21 | Application 22 | v110 23 | Unicode 24 | true 25 | 26 | 27 | Application 28 | v110 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <_ProjectFileVersion>11.0.51106.1 43 | 44 | 45 | $(SolutionDir)$(Configuration)\ 46 | $(Configuration)\ 47 | true 48 | 49 | 50 | $(SolutionDir)$(Configuration)\ 51 | $(Configuration)\ 52 | false 53 | 54 | 55 | 56 | Disabled 57 | ../include;%(AdditionalIncludeDirectories) 58 | WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 59 | true 60 | EnableFastChecks 61 | MultiThreadedDebug 62 | Level3 63 | EditAndContinue 64 | 65 | 66 | 67 | 4819 68 | 69 | 70 | libeay32.lib;ssleay32.lib;%(AdditionalDependencies) 71 | ..\include\libs;%(AdditionalLibraryDirectories) 72 | true 73 | Console 74 | MachineX86 75 | 76 | 77 | 78 | 79 | ../include;%(AdditionalIncludeDirectories) 80 | WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 81 | MultiThreaded 82 | 83 | Level3 84 | ProgramDatabase 85 | 86 | 87 | 4819 88 | 89 | 90 | true 91 | Console 92 | true 93 | true 94 | MachineX86 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /vcprojects/multi_download-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {5f043797-1ab7-47c0-b215-2d0c8f56ec41} 14 | 15 | 16 | {8be65954-4cad-423f-8e11-96122048ed0d} 17 | 18 | 19 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 20 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 21 | 22 | 23 | {47f1d63e-e248-44ee-96ed-8cc26b97292b} 24 | 25 | 26 | 27 | 28 | 源文件 29 | 30 | 31 | 32 | 33 | 头文件 34 | 35 | 36 | 头文件\avhttp 37 | 38 | 39 | 头文件\avhttp 40 | 41 | 42 | 头文件\avhttp 43 | 44 | 45 | 头文件\avhttp 46 | 47 | 48 | 头文件\avhttp 49 | 50 | 51 | 头文件\avhttp 52 | 53 | 54 | 头文件\avhttp 55 | 56 | 57 | 头文件\avhttp 58 | 59 | 60 | 头文件\avhttp 61 | 62 | 63 | 头文件\avhttp 64 | 65 | 66 | 头文件\avhttp\detail 67 | 68 | 69 | 头文件\avhttp\detail 70 | 71 | 72 | 头文件\avhttp\detail 73 | 74 | 75 | 头文件\avhttp\detail 76 | 77 | 78 | 头文件\avhttp\detail 79 | 80 | 81 | 头文件\avhttp\detail 82 | 83 | 84 | 头文件\avhttp\detail 85 | 86 | 87 | 头文件\avhttp\detail 88 | 89 | 90 | 头文件\avhttp\detail 91 | 92 | 93 | 头文件\avhttp\detail 94 | 95 | 96 | 头文件\avhttp 97 | 98 | 99 | 头文件\avhttp 100 | 101 | 102 | 头文件\avhttp 103 | 104 | 105 | 头文件\avhttp 106 | 107 | 108 | 头文件\avhttp 109 | 110 | 111 | 头文件\avhttp 112 | 113 | 114 | 头文件\avhttp 115 | 116 | 117 | 118 | 119 | 头文件\avhttp\impl 120 | 121 | 122 | 头文件\avhttp\impl 123 | 124 | 125 | 头文件\avhttp\impl 126 | 127 | 128 | 头文件\avhttp\impl 129 | 130 | 131 | -------------------------------------------------------------------------------- /vcprojects/percent_encoding_test-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "percent_encoding_test-vc2012", "percent_encoding_test-vc2012.vcxproj", "{56E59C88-07BB-4DC5-962A-795BA0530EAE}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {56E59C88-07BB-4DC5-962A-795BA0530EAE}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {56E59C88-07BB-4DC5-962A-795BA0530EAE}.Debug|Win32.Build.0 = Debug|Win32 14 | {56E59C88-07BB-4DC5-962A-795BA0530EAE}.Release|Win32.ActiveCfg = Release|Win32 15 | {56E59C88-07BB-4DC5-962A-795BA0530EAE}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/percent_encoding_test-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {56E59C88-07BB-4DC5-962A-795BA0530EAE} 15 | Win32Proj 16 | percent_encoding_testvc2012 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 55 | ../include 56 | 57 | 58 | Console 59 | true 60 | 61 | 62 | 63 | 64 | 65 | 66 | Level3 67 | 68 | 69 | MaxSpeed 70 | true 71 | true 72 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 73 | ../include 74 | 75 | 76 | Console 77 | true 78 | true 79 | true 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /vcprojects/percent_encoding_test-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /vcprojects/sync_http_stream-2005.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual Studio 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync_http_stream", "sync_http_stream-2005.vcproj", "{B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.Build.0 = Debug|Win32 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.ActiveCfg = Release|Win32 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/sync_http_stream-2005.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/sync_http_stream-2005.vcproj -------------------------------------------------------------------------------- /vcprojects/sync_http_stream-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync_http_stream", "sync_http_stream-vc2012.vcxproj", "{B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Debug|Win32.Build.0 = Debug|Win32 14 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.ActiveCfg = Release|Win32 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/sync_http_stream-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | sync_http_stream 15 | {B082E8C6-633B-4EC8-BA28-DE2942B9F4C2} 16 | async_http_stream 17 | Win32Proj 18 | 19 | 20 | 21 | Application 22 | v110 23 | Unicode 24 | true 25 | 26 | 27 | Application 28 | v110 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <_ProjectFileVersion>11.0.51106.1 43 | 44 | 45 | $(SolutionDir)$(Configuration)\ 46 | $(Configuration)\ 47 | true 48 | 49 | 50 | $(SolutionDir)$(Configuration)\ 51 | $(Configuration)\ 52 | false 53 | 54 | 55 | 56 | Disabled 57 | ../include;%(AdditionalIncludeDirectories) 58 | WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 59 | true 60 | EnableFastChecks 61 | MultiThreadedDebug 62 | 63 | Level3 64 | EditAndContinue 65 | 66 | 67 | true 68 | Console 69 | MachineX86 70 | 71 | 72 | 73 | 74 | ../include;%(AdditionalIncludeDirectories) 75 | WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 76 | MultiThreaded 77 | 78 | Level3 79 | ProgramDatabase 80 | 81 | 82 | true 83 | Console 84 | true 85 | true 86 | MachineX86 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /vcprojects/sync_http_stream-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2005.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual Studio 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync_proxy_test", "sync_proxy_test-vc2005.vcproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2005.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/sync_proxy_test-vc2005.vcproj -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2008.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync_proxy_test", "sync_proxy_test-vc2008.vcproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2008.vcproj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avplayer/avhttp/575bfe529a69f432cc365362f58af937639791ef/vcprojects/sync_proxy_test-vc2008.vcproj -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2012.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sync_proxy_test", "sync_proxy_test-vc2012.vcxproj", "{4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.ActiveCfg = Release|Win32 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2012.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | sync_proxy_test 15 | {4BD66C1E-20F7-4CDF-AE9A-05C8273077F2} 16 | avhttp 17 | Win32Proj 18 | 19 | 20 | 21 | Application 22 | v110 23 | Unicode 24 | true 25 | 26 | 27 | Application 28 | v110 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <_ProjectFileVersion>11.0.51106.1 43 | 44 | 45 | $(SolutionDir)$(Configuration)\ 46 | $(Configuration)\ 47 | true 48 | 49 | 50 | $(SolutionDir)$(Configuration)\ 51 | $(Configuration)\ 52 | false 53 | 54 | 55 | 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;AVHTTP_ENABLE_OPENSSL;%(PreprocessorDefinitions) 58 | true 59 | EnableFastChecks 60 | MultiThreadedDebug 61 | 62 | Level3 63 | EditAndContinue 64 | ../include;%(AdditionalIncludeDirectories) 65 | 66 | 67 | true 68 | Console 69 | MachineX86 70 | /SAFESEH:NO %(AdditionalOptions) 71 | ..\include\libs;%(AdditionalLibraryDirectories) 72 | ssleay32.lib;libeay32.lib;%(AdditionalDependencies) 73 | 74 | 75 | 76 | 77 | WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;%(PreprocessorDefinitions) 78 | MultiThreadedDebug 79 | 80 | Level3 81 | ProgramDatabase 82 | ../include 83 | 84 | 85 | true 86 | Console 87 | true 88 | true 89 | MachineX86 90 | /SAFESEH:NO %(AdditionalOptions) 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /vcprojects/sync_proxy_test-vc2012.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | {1508c6bd-50ea-431b-9ec1-49ad436c1ff0} 18 | 19 | 20 | {42627b62-82ed-4c48-8a1a-0c23c989ad21} 21 | 22 | 23 | 24 | 25 | 头文件 26 | 27 | 28 | 头文件\avhttp 29 | 30 | 31 | 头文件\avhttp 32 | 33 | 34 | 头文件\avhttp\detail 35 | 36 | 37 | 头文件\avhttp\detail 38 | 39 | 40 | 头文件\avhttp\detail 41 | 42 | 43 | 头文件\avhttp\detail 44 | 45 | 46 | 头文件\avhttp\detail 47 | 48 | 49 | 头文件\avhttp\detail 50 | 51 | 52 | 头文件\avhttp 53 | 54 | 55 | 头文件\avhttp 56 | 57 | 58 | 头文件\avhttp 59 | 60 | 61 | 头文件\avhttp 62 | 63 | 64 | 头文件\avhttp 65 | 66 | 67 | 头文件\avhttp\detail 68 | 69 | 70 | 头文件\avhttp 71 | 72 | 73 | 头文件\avhttp\detail 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 源文件 82 | 83 | 84 | --------------------------------------------------------------------------------