├── .gitattributes ├── .gitignore ├── HTTPClient.sln └── HTTPClient ├── HTTPClient.vcxproj ├── HTTPClient.vcxproj.filters ├── HTTPClient.vcxproj.user ├── HTTPSession.cpp ├── HTTPSession.h ├── HttpClient.cpp ├── HttpClient.h └── main.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /HTTPClient.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HTTPClient", "HTTPClient\HTTPClient.vcxproj", "{9A85771E-1D84-4403-8642-14F9DC5990B0}" 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 | {9A85771E-1D84-4403-8642-14F9DC5990B0}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {9A85771E-1D84-4403-8642-14F9DC5990B0}.Debug|Win32.Build.0 = Debug|Win32 14 | {9A85771E-1D84-4403-8642-14F9DC5990B0}.Release|Win32.ActiveCfg = Release|Win32 15 | {9A85771E-1D84-4403-8642-14F9DC5990B0}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /HTTPClient/HTTPClient.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {9A85771E-1D84-4403-8642-14F9DC5990B0} 15 | Win32Proj 16 | HTTPClient 17 | 18 | 19 | 20 | Application 21 | true 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | true 28 | MultiByte 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | 43 | 44 | false 45 | 46 | 47 | 48 | 49 | 50 | Level3 51 | Disabled 52 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 53 | 54 | 55 | Console 56 | true 57 | 58 | 59 | 60 | 61 | Level3 62 | 63 | 64 | MaxSpeed 65 | true 66 | true 67 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 68 | 69 | 70 | Console 71 | true 72 | true 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /HTTPClient/HTTPClient.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 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /HTTPClient/HTTPClient.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /HTTPClient/HTTPSession.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunflover/HTTPClient/ff62bdc58120180b5bdb76cf853f0e6d62a5427c/HTTPClient/HTTPSession.cpp -------------------------------------------------------------------------------- /HTTPClient/HTTPSession.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef _WIN32 7 | #define WIN32_LEAN_AND_MEAN 8 | #include 9 | #include 10 | #pragma comment(lib,"ws2_32.lib") 11 | 12 | #ifndef uint8_t 13 | typedef unsigned char uint8_t; 14 | #endif 15 | 16 | #ifndef uint16_t 17 | typedef unsigned short uint16_t; 18 | #endif 19 | 20 | #ifndef uint32_t 21 | typedef unsigned int uint32_t; 22 | #endif 23 | 24 | #ifndef uint64_t 25 | typedef unsigned __int64 uint64_t; 26 | #endif 27 | #else // unix or linux 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #ifndef SOCKET 42 | #define SOCKET int 43 | #endif 44 | 45 | #ifndef INVALID_SOCKET 46 | #define INVALID_SOCKET (-1) 47 | #endif 48 | 49 | #endif 50 | 51 | class HTTPSession 52 | { 53 | public: 54 | HTTPSession(void); 55 | ~HTTPSession(void); 56 | 57 | public: 58 | bool connect(uint32_t ip, uint16_t port); 59 | void closeSession(); 60 | int send(const char* data, const int len); 61 | int read(char* data, const int len); 62 | int readLine(std::string& line, const int len = 0); 63 | int readLimit(std::string& limit, const int len); 64 | 65 | private: 66 | bool initSocket(); 67 | 68 | private: 69 | SOCKET m_sock; 70 | }; 71 | -------------------------------------------------------------------------------- /HTTPClient/HttpClient.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunflover/HTTPClient/ff62bdc58120180b5bdb76cf853f0e6d62a5427c/HTTPClient/HttpClient.cpp -------------------------------------------------------------------------------- /HTTPClient/HttpClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "HTTPSession.h" 3 | 4 | 5 | enum HTTPRESPONSE_CODE 6 | { 7 | HTTPRESPONSE_000 = 0, 8 | HTTPRESPONSE_200 = 200, 9 | HTTPRESPONSE_204 = 204, 10 | HTTPRESPONSE_206 = 206, 11 | HTTPRESPONSE_301 = 301, 12 | HTTPRESPONSE_302 = 302, 13 | HTTPRESPONSE_400 = 400, 14 | HTTPRESPONSE_403 = 403, 15 | HTTPRESPONSE_404 = 404, 16 | HTTPRESPONSE_413 = 413, 17 | HTTPRESPONSE_500 = 500, 18 | }; 19 | 20 | enum HTTP_REQ_TYPE { 21 | HTTP_DEFAULT, 22 | HTTP_GET, 23 | HTTP_POST, 24 | HTTP_PUT, 25 | HTTP_DELETE 26 | }; 27 | 28 | enum HTTP_STATUS 29 | { 30 | HTTP_STATUS_DEFAULT, 31 | HTTP_STATUS_CONNECT_FAILED, 32 | HTTP_STATUS_CONNECT_SUCCESS, 33 | HTTP_STATUS_CONNECT_STOP, 34 | HTTP_STATUS_CONNECT_CLOSE, 35 | HTTP_STATUS_IO_ERROR, 36 | HTTP_STATUS_PARSE_URL_FAILED 37 | }; 38 | 39 | ////////////////////////////////////////////////////////////////////////// 40 | #define HTTP_REQUEST_GET "GET" 41 | #define HTTP_REQUEST_POST "POST" 42 | #define HTTP_REQUEST_PUT "PUT" 43 | #define HTTP_REQUEST_DELETE "DELETE" 44 | ////////////////////////////////////////////////////////////////////////// 45 | #define HTTP_VERSION_1_1 "HTTP/1.1" 46 | ////////////////////////////////////////////////////////////////////////// 47 | #define HTTP_HEAD_HOST "Host" 48 | #define HTTP_HEAD_ACCEPT "Accept" 49 | #define HTTP_HEAD_REFERER "Referer" 50 | #define HTTP_HEAD_ACCEPT_LANGUAGE "Accept-Language" 51 | #define HTTP_HEAD_ACCEPT_ENCODING "Accept-Encoding" 52 | #define HTTP_HEAD_ACCEPT_CHARSET "Accept-Charset" 53 | #define HTTP_HEAD_ACCEPT_RANGES "Accept-Ranges" 54 | #define HTTP_HEAD_USER_AGENT "User-Agent" 55 | #define HTTP_HEAD_COOKIE "Cookie" 56 | #define HTTP_HEAD_CONTENT_TYPE "Content-Type" 57 | #define HTTP_HEAD_DATE "Date" 58 | #define HTTP_HEAD_CHARSET "utf-8" 59 | #define HTTP_HEAD_CONTENT_LENGTH "Content-Length" 60 | #define HTTP_HEAD_DATE "Date" 61 | #define HTTP_HEAD_KEEP_ALIVE "Keep-Alive" 62 | #define HTTP_HEAD_CONNECTION "Connection" 63 | #define HTTP_HEAD_SERVER "Server" 64 | #define HTTP_HEAD_LOCATION "Location" 65 | #define HTTP_HEAD_SET_COOKIE "Set-Cookie" 66 | #define HTTP_HEAD_CONTENT_ENCODING "Content-Encoding" 67 | #define HTTP_HEAD_TRANSFER_ENCODING "Transfer-Encoding" 68 | 69 | #define HTTP_HEAD_CONTENT_DISPOSITION "Content-Disposition" 70 | #define HTTP_HEAD_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding" 71 | 72 | struct MultiPart 73 | { 74 | std::map m_headMap; 75 | std::string data; 76 | 77 | void setHead(const std::string& key, const std::string& value) 78 | { 79 | m_headMap[key] = value; 80 | } 81 | 82 | std::string makeHeader() 83 | { 84 | std::ostringstream oss; 85 | for (std::map::iterator st = m_headMap.begin(); st != m_headMap.end(); ++ st) 86 | { 87 | oss << st->first << ": " << st->second << "\r\n"; 88 | } 89 | oss << "\r\n"; 90 | return oss.str(); 91 | } 92 | }; 93 | 94 | struct HTTPMultipart 95 | { 96 | std::string strBoundary; 97 | std::map m_multiPartMap; 98 | 99 | void makeMultiPart(std::string& strBody) 100 | { 101 | std::ostringstream oss; 102 | for (std::map::iterator it = m_multiPartMap.begin(); it != m_multiPartMap.end(); ++ it) 103 | { 104 | if (it == m_multiPartMap.begin()) 105 | { 106 | oss << "--" << strBoundary << "\r\n";//first boundary 107 | } 108 | else 109 | { 110 | oss << "\r\n--" << strBoundary << "\r\n"; 111 | } 112 | MultiPart& part = it->second; 113 | oss << part.makeHeader(); 114 | oss << part.data; 115 | } 116 | oss << "\r\n--" << strBoundary << "--" << "\r\n";//last boundary 117 | strBody.append(oss.str()); 118 | } 119 | }; 120 | 121 | struct HTTPRequest 122 | { 123 | std::string version; 124 | std::string url; 125 | std::string host; 126 | uint16_t port; 127 | std::string strRelative; 128 | std::map m_headMap; 129 | 130 | HTTPRequest() 131 | : version(HTTP_VERSION_1_1) 132 | , port(80) 133 | , strRelative("/") 134 | { 135 | m_headMap[HTTP_HEAD_ACCEPT] = "*/*"; 136 | m_headMap[HTTP_HEAD_ACCEPT_LANGUAGE] = "zh-CN"; 137 | m_headMap[HTTP_HEAD_USER_AGENT] = "SDK C++ http client"; 138 | m_headMap[HTTP_HEAD_CONNECTION] = "Keep-Alive"; 139 | } 140 | 141 | void setHead(const std::string& key, const std::string& value) 142 | { 143 | m_headMap[key] = value; 144 | } 145 | }; 146 | 147 | struct HTTPResponse 148 | { 149 | HTTPRESPONSE_CODE code; 150 | bool bChunked; 151 | bool bChunkedEnd; 152 | uint32_t uContentLength; 153 | uint32_t uReadLength; 154 | uint32_t uChunkLength; 155 | std::map m_headMap; 156 | 157 | HTTPResponse() 158 | { 159 | bChunked = false; 160 | bChunkedEnd = false; 161 | uContentLength = 0; 162 | uReadLength = 0; 163 | uChunkLength = 0; 164 | code = HTTPRESPONSE_000; 165 | } 166 | 167 | void setHead(const std::string& key, std::string& value) 168 | { 169 | m_headMap[key] = value; 170 | } 171 | }; 172 | 173 | class HTTPClient 174 | { 175 | public: 176 | HTTPClient(void); 177 | ~HTTPClient(void); 178 | 179 | public: 180 | bool get(HTTPRequest& req, HTTPResponse& rep, std::string& strData); 181 | bool post(HTTPRequest& req, HTTPResponse& rep, const std::string& strData, std::string& strResult); 182 | bool startPost(HTTPSession& session, HTTPRequest& req); 183 | bool postData(HTTPSession& session, const std::string& data); 184 | void stopPost(HTTPSession& session, HTTPResponse& rep, std::string& strResult); 185 | bool startGet(HTTPSession& session, HTTPResponse& rep, HTTPRequest& req); 186 | bool getData(HTTPSession& session, HTTPResponse& rep, std::string& data); 187 | void stopGet(HTTPSession& session); 188 | 189 | public: 190 | void makeMultipartBody(HTTPMultipart& multipart, std::string& strBody); 191 | 192 | private: 193 | bool parseUrl(HTTPRequest& req); 194 | void makeHeader(HTTP_REQ_TYPE& type, HTTPRequest& req, std::string &strHead); 195 | bool sendHeader(HTTP_REQ_TYPE& type, HTTPSession& session, HTTPRequest& req); 196 | bool readHeader(HTTPSession& session, HTTPResponse& rep); 197 | bool sendBody(HTTPSession& session, const std::string& strData); 198 | bool readBody(HTTPSession& session, HTTPResponse& rep, std::string& strData); 199 | void parseLine(const std::string& line, std::string& key, std::string& value); 200 | uint32_t hostToLong(std::string host); 201 | 202 | }; 203 | -------------------------------------------------------------------------------- /HTTPClient/main.cpp: -------------------------------------------------------------------------------- 1 | #include "HttpClient.h" 2 | #include 3 | 4 | void main() 5 | { 6 | #if defined(_WIN32) 7 | WORD version = MAKEWORD(2, 2); 8 | WSADATA data; 9 | if (WSAStartup(version, &data) != 0) 10 | return;//failed init network 11 | #endif // _WIN32 12 | 13 | 14 | HTTPClient http; 15 | HTTPRequest req; 16 | HTTPResponse rep; 17 | std::string strData; 18 | req.url = "http://www.qq.com/"; 19 | req.setHead(HTTP_HEAD_REFERER, "http://www.qq.com/"); 20 | if (http.get(req, rep, strData)) 21 | { 22 | std::cout << rep.code << std::endl; 23 | } 24 | 25 | #if defined(_WIN32) 26 | WSACleanup(); 27 | #endif // _WIN32 28 | 29 | return; 30 | } --------------------------------------------------------------------------------