diff --git a/.gitignore b/.gitignore index 2f0c79a3..899e495e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ *.swp *.o WebServer.exe + +.exe +Debug + +*.opendb \ No newline at end of file diff --git a/.vs/cpp-webserver/v14/.suo b/.vs/cpp-webserver/v14/.suo new file mode 100644 index 00000000..eed6ae7d Binary files /dev/null and b/.vs/cpp-webserver/v14/.suo differ diff --git a/README.md b/README.md index 1bb13789..0e086b72 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ # cpp-webserver A simple webserver for Windows +## 此版本特性 +加入vs2015工程 + +服务器输出支持中文,进行utf-8编码转换 + +增加config.ini文件,服务器端口和crsf跨越参数加入配置文件 + +部分warning忽略 + ## Getting the sources from Github git clone https://github.com/ReneNyffenegger/cpp-webserver webserver diff --git a/base64 b/base64 deleted file mode 160000 index 26a73f38..00000000 --- a/base64 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 26a73f38176434075d1f056bf5d207ee20918c26 diff --git a/cpp-webserver.VC.db b/cpp-webserver.VC.db new file mode 100644 index 00000000..fe3b9729 Binary files /dev/null and b/cpp-webserver.VC.db differ diff --git a/cpp-webserver.sln b/cpp-webserver.sln new file mode 100644 index 00000000..434f9ded --- /dev/null +++ b/cpp-webserver.sln @@ -0,0 +1,28 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpp-webserver", "cpp-webserver\cpp-webserver.vcxproj", "{36A1603B-A705-4F3A-902A-3F354FD31564}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36A1603B-A705-4F3A-902A-3F354FD31564}.Debug|x64.ActiveCfg = Debug|x64 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Debug|x64.Build.0 = Debug|x64 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Debug|x86.ActiveCfg = Debug|Win32 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Debug|x86.Build.0 = Debug|Win32 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Release|x64.ActiveCfg = Release|x64 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Release|x64.Build.0 = Release|x64 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Release|x86.ActiveCfg = Release|Win32 + {36A1603B-A705-4F3A-902A-3F354FD31564}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/cpp-webserver/EncodingConverter.h b/cpp-webserver/EncodingConverter.h new file mode 100644 index 00000000..6f082ea6 --- /dev/null +++ b/cpp-webserver/EncodingConverter.h @@ -0,0 +1,242 @@ +锘/** + * 婧愮爜鎰熻阿yaocoder + * 鎷疯礉宸ョ▼https://github.com/yaocoder/utility +*/ +#pragma once +#include +#include + +#ifdef tstring +#error "\"tstring\" Macro has been defined." +#else +#ifdef _UNICODE +#define tstring wstring +#else +#define tstring string +#endif +#endif + +class EncodingConverter +{ +public: + static int AnsiStrToWideStr(std::string& strSrc, std::wstring& strDest) + { + int nLen = strSrc.length() + 1; + int nRet = 0; + + nLen *= sizeof(wchar_t); + + wchar_t* pszW = new wchar_t[nLen]; + memset(pszW, 0, nLen); + + nRet = MultiByteToWideChar(CP_ACP, 0, strSrc.c_str(), -1, pszW, nLen); + + strDest = pszW; + delete[] pszW; + + return nRet; + }; + + static int WideStrToAnsiStr(std::wstring& strSrc, std::string& strDest) + { + int nLen = strSrc.length() + 1; + int nRet = 0; + + nLen *= sizeof(wchar_t); + + char* pszA = new char[nLen]; + memset(pszA, 0, nLen); + + + nRet = WideCharToMultiByte(CP_ACP, 0, strSrc.c_str(), -1, pszA, nLen, NULL, NULL); + + strDest = pszA; + delete[] pszA; + + return nRet; + }; + + static int AnsiStrToTStr(std::string& strSrc, std::tstring& strDest) + { + int nRet = 0; + +#ifdef _UNICODE + nRet = AnsiStrToWideStr(strSrc, strDest); +#else + strDest = strSrc; + nRet = strDest.length(); +#endif + + return nRet; + }; + + static int TStrToAnsiStr(std::tstring& strSrc, std::string& strDest) + { + int nRet = 0; + +#ifdef _UNICODE + nRet = WideStrToAnsiStr(strSrc, strDest); +#else + strDest = strSrc; + nRet = strDest.length(); +#endif + + return nRet; + }; + + static int WideStrToTStr(std::wstring& strSrc, std::tstring& strDest) + { + int nRet = 0; + +#ifdef _UNICODE + strDest = strSrc; + nRet = strDest.length(); +#else + nRet = WideStrToAnsiStr(strSrc, strDest); +#endif + + return nRet; + }; + + static int TStrToWideStr(std::tstring& strSrc, std::wstring& strDest) + { + int nRet = 0; + +#ifdef _UNICODE + strDest = strSrc; + nRet = strDest.length(); +#else + nRet = AnsiStrToWideStr(strSrc, strDest); +#endif + + return nRet; + }; + + static std::string ToAnsiString(const wchar_t* lpStr) + { + std::wstring wide_string = lpStr; + std::string ansi_string; + + WideStrToAnsiStr(wide_string, ansi_string); + return ansi_string; + }; + + static std::string ToAnsiString(const char* lpStr) + { + return std::string(lpStr); + }; + + static std::wstring ToWideString(const wchar_t* lpStr) + { + return std::wstring(lpStr); + }; + + static std::wstring ToWideString(const char* lpStr) + { + std::string ansi_string = lpStr; + std::wstring wide_string; + + AnsiStrToWideStr(ansi_string, wide_string); + return wide_string; + }; + + static std::tstring ToTString(const char* lpStr) + { +#ifdef _UNICODE + return ToWideString(lpStr); +#else + return ToAnsiString(lpStr); +#endif + }; + + static std::tstring ToTString(const wchar_t* lpStr) + { +#ifdef _UNICODE + return ToWideString(lpStr); +#else + return ToAnsiString(lpStr); +#endif + }; + + static int WideStrToUtf8Str(std::wstring& strSrc, std::string& strDest) + { + int nRet = 0; + int nLen = 0; + + nLen = WideCharToMultiByte(CP_UTF8, 0, strSrc.c_str(), -1, NULL, 0, NULL, NULL); + + char * lpUtf8Str = new char[nLen + 1]; + memset(lpUtf8Str, 0, nLen); + nRet = WideCharToMultiByte(CP_UTF8, 0, strSrc.c_str(), -1, lpUtf8Str, nLen, NULL, NULL); + strDest = lpUtf8Str; + delete[] lpUtf8Str; + + return nRet; + }; + + static int AnsiStrToUtf8Str(std::string& strSrc, std::string& strDest) + { + int nRet = 0; + std::wstring wide_string; + + nRet = AnsiStrToWideStr(strSrc, wide_string); + nRet = WideStrToUtf8Str(wide_string, strDest); + + return nRet; + }; + + static int Utf8StrToWideStr(const std::string& strSrc, std::wstring& strDest) + { + int nRet = 0; + int nLen = 0; + + nLen = MultiByteToWideChar(CP_UTF8, 0, strSrc.c_str(), -1, NULL, 0); + + wchar_t* lpWideStr = new wchar_t[nLen]; + memset(lpWideStr, 0, nLen * sizeof(lpWideStr[0])); + nRet = MultiByteToWideChar(CP_UTF8, 0, strSrc.c_str(), -1, lpWideStr, nLen); + strDest = lpWideStr; + delete[] lpWideStr; + + return nRet; + }; + + static int Utf8StrToAnsiStr(const std::string& strSrc, std::string& strDest) + { + int nRet = 0; + std::wstring wide_string; + + nRet = Utf8StrToWideStr(strSrc, wide_string); + nRet = WideStrToAnsiStr(wide_string, strDest); + + return nRet; + }; + + static int Utf8StrToTStr(const std::string& strSrc, std::tstring& strDest) + { +#ifdef UNICODE + return Utf8StrToWideStr(strSrc, strDest); +#else + return Utf8StrToAnsiStr(strSrc, strDest); +#endif + }; + + static std::string ToUtf8String(const std::string& str) + { + std::string ansi_string = str; + std::string utf8_string; + + AnsiStrToUtf8Str(ansi_string, utf8_string); + return utf8_string; + }; + + static std::string ToUtf8String(const std::wstring& str) + { + std::wstring wide_string = str; + std::string utf8_string; + + WideStrToUtf8Str(wide_string, utf8_string); + return utf8_string; + }; + +}; \ No newline at end of file diff --git a/cpp-webserver/ReadMe.txt b/cpp-webserver/ReadMe.txt new file mode 100644 index 00000000..956d0bae --- /dev/null +++ b/cpp-webserver/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + CONSOLE APPLICATION : cpp-webserver Project Overview +======================================================================== + +AppWizard has created this cpp-webserver application for you. + +This file contains a summary of what you will find in each of the files that +make up your cpp-webserver application. + + +cpp-webserver.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +cpp-webserver.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +cpp-webserver.cpp + This is the main application source file. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named cpp-webserver.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/Tracer.h b/cpp-webserver/Tracer.h similarity index 100% rename from Tracer.h rename to cpp-webserver/Tracer.h diff --git a/UrlHelper.cpp b/cpp-webserver/UrlHelper.cpp similarity index 99% rename from UrlHelper.cpp rename to cpp-webserver/UrlHelper.cpp index 8c467cb0..79d6bb55 100644 --- a/UrlHelper.cpp +++ b/cpp-webserver/UrlHelper.cpp @@ -24,7 +24,7 @@ Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch */ - +#include "stdafx.h" #include "UrlHelper.h" #include "Tracer.h" #include "stdHelpers.h" diff --git a/UrlHelper.h b/cpp-webserver/UrlHelper.h similarity index 100% rename from UrlHelper.h rename to cpp-webserver/UrlHelper.h diff --git a/cpp-webserver/base64/.gitignore b/cpp-webserver/base64/.gitignore new file mode 100644 index 00000000..089d9a5c --- /dev/null +++ b/cpp-webserver/base64/.gitignore @@ -0,0 +1,2 @@ +*.swp +test-base64 diff --git a/cpp-webserver/base64/LICENSE b/cpp-webserver/base64/LICENSE new file mode 100644 index 00000000..b20a2379 --- /dev/null +++ b/cpp-webserver/base64/LICENSE @@ -0,0 +1,19 @@ +Copyright 漏 2004-2017 by Ren茅 Nyffenegger + +This source code is provided 'as-is', without any express or implied +warranty. In no event will the author be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + +3. This notice may not be removed or altered from any source distribution. diff --git a/cpp-webserver/base64/README.md b/cpp-webserver/base64/README.md new file mode 100644 index 00000000..cb7b5f7e --- /dev/null +++ b/cpp-webserver/base64/README.md @@ -0,0 +1,2 @@ +# cpp-base64 +base64 encoding and decoding with c++ diff --git a/cpp-webserver/base64/base64.cpp b/cpp-webserver/base64/base64.cpp new file mode 100644 index 00000000..a2340839 --- /dev/null +++ b/cpp-webserver/base64/base64.cpp @@ -0,0 +1,122 @@ +/* + base64.cpp and base64.h + + base64 encoding and decoding with C++. + + Version: 1.01.00 + + Copyright (C) 2004-2017 Ren茅 Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ +#include "stdafx.h" +#include "base64.h" +#include + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = 0; j < i; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} diff --git a/cpp-webserver/base64/base64.h b/cpp-webserver/base64/base64.h new file mode 100644 index 00000000..dd1134c3 --- /dev/null +++ b/cpp-webserver/base64/base64.h @@ -0,0 +1,14 @@ +// +// base64 encoding and decoding with C++. +// Version: 1.01.00 +// + +#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A +#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A + +#include + +std::string base64_encode(unsigned char const* , unsigned int len); +std::string base64_decode(std::string const& s); + +#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */ diff --git a/cpp-webserver/base64/compile-and-run-test b/cpp-webserver/base64/compile-and-run-test new file mode 100644 index 00000000..1ab59854 --- /dev/null +++ b/cpp-webserver/base64/compile-and-run-test @@ -0,0 +1,2 @@ +g++ test.cpp base64.cpp -o test-base64 +./test-base64 diff --git a/cpp-webserver/base64/test.cpp b/cpp-webserver/base64/test.cpp new file mode 100644 index 00000000..d04abc3e --- /dev/null +++ b/cpp-webserver/base64/test.cpp @@ -0,0 +1,56 @@ +#include "base64.h" +#include + +int main() { + const std::string s = + "Ren茅 Nyffenegger\n" + "http://www.renenyffenegger.ch\n" + "passion for data\n"; + + std::string encoded = base64_encode(reinterpret_cast(s.c_str()), s.length()); + std::string decoded = base64_decode(encoded); + + std::cout << "encoded: " << std::endl << encoded << std::endl << std::endl; + std::cout << "decoded: " << std::endl << decoded << std::endl; + + + // Test all possibilites of fill bytes (none, one =, two ==) + // References calculated with: https://www.base64encode.org/ + + std::string rest0_original = "abc"; + std::string rest0_reference = "YWJj"; + + std::string rest0_encoded = base64_encode(reinterpret_cast(rest0_original.c_str()), + rest0_original.length()); + std::string rest0_decoded = base64_decode(rest0_encoded); + + std::cout << "encoded: " << rest0_encoded << std::endl; + std::cout << "reference: " << rest0_reference << std::endl; + std::cout << "decoded: " << rest0_decoded << std::endl << std::endl; + + + std::string rest1_original = "abcd"; + std::string rest1_reference = "YWJjZA=="; + + std::string rest1_encoded = base64_encode(reinterpret_cast(rest1_original.c_str()), + rest1_original.length()); + std::string rest1_decoded = base64_decode(rest1_encoded); + + std::cout << "encoded: " << rest1_encoded << std::endl; + std::cout << "reference: " << rest1_reference << std::endl; + std::cout << "decoded: " << rest1_decoded << std::endl << std::endl; + + + std::string rest2_original = "abcde"; + std::string rest2_reference = "YWJjZGU="; + + std::string rest2_encoded = base64_encode(reinterpret_cast(rest2_original.c_str()), + rest2_original.length()); + std::string rest2_decoded = base64_decode(rest2_encoded); + + std::cout << "encoded: " << rest2_encoded << std::endl; + std::cout << "reference: " << rest2_reference << std::endl; + std::cout << "decoded: " << rest2_decoded << std::endl << std::endl; + + return 0; +} diff --git a/compile.mingw.bat b/cpp-webserver/compile.mingw.bat similarity index 100% rename from compile.mingw.bat rename to cpp-webserver/compile.mingw.bat diff --git a/cpp-webserver/config.ini b/cpp-webserver/config.ini new file mode 100644 index 00000000..0b2051dd --- /dev/null +++ b/cpp-webserver/config.ini @@ -0,0 +1,4 @@ +## +#配置参数里面不要包含特殊符号# +crsf_url=http://localhost:3000 +server_port=9020 \ No newline at end of file diff --git a/cpp-webserver/config/FileReader.cpp b/cpp-webserver/config/FileReader.cpp new file mode 100644 index 00000000..93645904 --- /dev/null +++ b/cpp-webserver/config/FileReader.cpp @@ -0,0 +1,42 @@ + +#include "stdafx.h" + +#include +#include +#include +#include "FileReader.h" +std::map FileReader::configIni; + +string FileReader::getvalue(string &key) { + std::string value; + string filepath = "config.ini"; + std::map map = FileReader::loadFile(filepath); + std::map::const_iterator pos = map.find(key); + if (pos == map.end()) { + std::cout << key+"-------cant find value of the key-------\n"; + } + else { + value= pos->second; + std::cout << value + "-------find the key and value-------\n"; + } + return value; +} + +unsigned int FileReader::getServerPort() { + //crsf_url=http://localhost:3000 + //server_port = 9020 + string key = "server_port"; + string port = getvalue(key); + unsigned int need_port = atoi(port.c_str()); + std::cout << "-------配置服务器端口-------" << need_port <<"\n"; + return need_port; +} +string FileReader::Access_Control_Allow_Origin() { + string key = "crsf_url"; + string crsf_allow= getvalue(key); + std::cout << "-------配置跨域参数可以多个-------" << crsf_allow << "\n"; + return crsf_allow; + +} + + diff --git a/cpp-webserver/config/FileReader.h b/cpp-webserver/config/FileReader.h new file mode 100644 index 00000000..a1baee6b --- /dev/null +++ b/cpp-webserver/config/FileReader.h @@ -0,0 +1,57 @@ +锘#pragma once +#include +#include +#include +#include + + +using namespace std; +class FileReader { + + +public: + + static string getvalue(string &key); + static unsigned int getServerPort(); + static string Access_Control_Allow_Origin(); + static std::map configIni; +private: + + + static std::map loadFile(string &filepath) { + if (!configIni.empty()) { + return configIni;//宸茬粡鍒濆鍖 + } + + std::ifstream input(filepath); + std::string line; + + int number_of_line = 0; + while (std::getline(input, line)) + { + //鍒嗗壊瀛楃涓= + + std::size_t found = line.find_first_of("#"); + if(found != std::string::npos) { + //娉ㄩ噴绗﹀彿锛屽拷鐣ユ琛岀被瀹 + continue; + } + string key; + string value; + std::size_t pos = line.find_first_of("="); + if (pos == std::string::npos) { + continue; + } + key = line.substr(0, pos); + value = line.substr(pos + 1); + std::cout << "-------substring-------" << key + " and " + value + "\r\n"; + number_of_line++; + configIni.insert(std::map::value_type(key, value)); + } + + input.close(); + + return configIni; + + }; +}; diff --git a/cpp-webserver/cpp-webserver.cpp b/cpp-webserver/cpp-webserver.cpp new file mode 100644 index 00000000..5f12613b --- /dev/null +++ b/cpp-webserver/cpp-webserver.cpp @@ -0,0 +1,106 @@ +锘// cpp-webserver.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "webserver.h" +#include "socket/src/Socket.h" +#include +#include "config/FileReader.h" +using namespace std; + +void Request_Handler(webserver::http_request* r) { + Socket s = *(r->s_); + + std::string title; + std::string body; + std::string bgcolor = "#ffffff"; + std::string links = + "

red " + "
blue " + "
form " + "
authentication example [use rene as username and secretGarden as password" + "
show some HTTP header details " + ; + + if (r->path_ == "/") { + title = "Web Server Example"; + body = "

Welcome to Rene's Web Server.娆㈣繋璁块棶Rene鐨剋eb鏈嶅姟鍣紒

" + "I wonder what you're going to click" + links; + } + else if (r->path_ == "/red") { + bgcolor = "#ff4444"; + title = "You chose red"; + body = "

Red

" + links; + } + else if (r->path_ == "/blue") { + bgcolor = "#4444ff"; + title = "You chose blue"; + body = "

Blue

" + links; + } + else if (r->path_ == "/form") { + title = "Fill a form"; + + body = "

Fill a form

"; + body += "
" + "" + "" + "" + "" + "
Field 1
Field 2
Field 3
" + "
"; + + + for (std::map::const_iterator i = r->params_.begin(); + i != r->params_.end(); + i++) { + + body += "
" + i->first + " = " + i->second; + } + + + body += "
" + links; + + } + else if (r->path_ == "/auth") { + if (r->authentication_given_) { + if (r->username_ == "rene" && r->password_ == "secretGarden") { + body = "

Successfully authenticated

" + links; + } + else { + body = "

Wrong username or password

" + links; + r->auth_realm_ = "Private Stuff"; + } + } + else { + r->auth_realm_ = "Private Stuff"; + } + } + else if (r->path_ == "/header") { + title = "some HTTP header details"; + body = std::string("") + + "" + + "" + + "" + + "" + + "
Accept:" + r->accept_ + "
Accept-Encoding:" + r->accept_encoding_ + "
Accept-Language:" + r->accept_language_ + "
User-Agent:" + r->user_agent_ + "
" + + links; + } + else { + r->status_ = "404 Not Found"; + title = "Wrong URL"; + body = "

Wrong URL

"; + body += "Path is : >" + r->path_ + "<"; + } + + r->answer_ = ""; + r->answer_ += title; + r->answer_ += ""; + r->answer_ += body; + r->answer_ += ""; +} + +int main() { + unsigned int port=FileReader::getServerPort(); + std::cout << "================鍚姩鏈嶅姟鍣⊿TARTED SERVER===================" << port << "\n"; + webserver(port, Request_Handler); +} diff --git a/cpp-webserver/cpp-webserver.vcxproj b/cpp-webserver/cpp-webserver.vcxproj new file mode 100644 index 00000000..83fecd9c --- /dev/null +++ b/cpp-webserver/cpp-webserver.vcxproj @@ -0,0 +1,175 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {36A1603B-A705-4F3A-902A-3F354FD31564} + Win32Proj + cppwebserver + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + _WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + ws2_32.lib;%(AdditionalDependencies) + + + + + Use + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + \ No newline at end of file diff --git a/cpp-webserver/cpp-webserver.vcxproj.filters b/cpp-webserver/cpp-webserver.vcxproj.filters new file mode 100644 index 00000000..d2758b34 --- /dev/null +++ b/cpp-webserver/cpp-webserver.vcxproj.filters @@ -0,0 +1,69 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/main.cpp b/cpp-webserver/main.cpp similarity index 98% rename from main.cpp rename to cpp-webserver/main.cpp index 873a6b17..1e891c9c 100644 --- a/main.cpp +++ b/cpp-webserver/main.cpp @@ -1,5 +1,6 @@ +#include "stdafx.h" #include "webserver.h" -#include "Socket.h" +#include "socket/src/Socket.h" void Request_Handler(webserver::http_request* r) { Socket s = *(r->s_); diff --git a/cpp-webserver/socket/.gitignore b/cpp-webserver/socket/.gitignore new file mode 100644 index 00000000..1377554e --- /dev/null +++ b/cpp-webserver/socket/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/cpp-webserver/socket/README.md b/cpp-webserver/socket/README.md new file mode 100644 index 00000000..d73762c5 --- /dev/null +++ b/cpp-webserver/socket/README.md @@ -0,0 +1,4 @@ +# Socket.cpp +C++ Socket Class for Windows + +http://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/Socket_cpp/index diff --git a/cpp-webserver/socket/examples/.gitignore b/cpp-webserver/socket/examples/.gitignore new file mode 100644 index 00000000..774f0087 --- /dev/null +++ b/cpp-webserver/socket/examples/.gitignore @@ -0,0 +1,2 @@ +*.exe +*.o diff --git a/cpp-webserver/socket/examples/compile.ming.bat b/cpp-webserver/socket/examples/compile.ming.bat new file mode 100644 index 00000000..8d2bfbe2 --- /dev/null +++ b/cpp-webserver/socket/examples/compile.ming.bat @@ -0,0 +1,5 @@ +g++ -c ../src/Socket.cpp -o Socket.o +g++ -I../src simple-client.cpp Socket.o -lwsock32 -o simple-client.exe +g++ -I../src echo-server.cpp Socket.o -lwsock32 -o echo-server.exe +g++ -I../src proxy.cpp Socket.o -lwsock32 -o proxy.exe +g++ -I../src msg-distributor.cpp Socket.o -lwsock32 -o msg-distributor.exe diff --git a/cpp-webserver/socket/examples/echo-server.cpp b/cpp-webserver/socket/examples/echo-server.cpp new file mode 100644 index 00000000..48033e40 --- /dev/null +++ b/cpp-webserver/socket/examples/echo-server.cpp @@ -0,0 +1,57 @@ +/* + echo-server.cpp + + Copyright (C) 2002-2017 Ren茅 Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + + +#include "Socket.h" +#include +#include + +unsigned __stdcall Answer(void* a) { + Socket* s = (Socket*) a; + + while (1) { + std::string r = s->ReceiveLine(); + if (r.empty()) break; + s->SendLine(r); + } + + delete s; + + return 0; +} + +int main(int argc, char* argv[]) { + SocketServer in(2000,5); + + while (1) { + Socket* s=in.Accept(); + + unsigned ret; + _beginthreadex(0,0,Answer,(void*) s,0,&ret); + } + + return 0; +} diff --git a/cpp-webserver/socket/examples/msg-distributor.cpp b/cpp-webserver/socket/examples/msg-distributor.cpp new file mode 100644 index 00000000..fcf4b998 --- /dev/null +++ b/cpp-webserver/socket/examples/msg-distributor.cpp @@ -0,0 +1,72 @@ +/* + msg-distributor.cpp + + Copyright (C) 2002-2017 Ren茅 Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +#include "Socket.h" +#include +#include +#include + +typedef std::list socket_list; + +socket_list g_connections; + +unsigned __stdcall Connection(void* a) { + Socket* s = (Socket*) a; + + g_connections.push_back(s); + + s->SendLine("Welcome to the Message Distributor"); + + while (1) { + std::string r = s->ReceiveLine(); + if (r.empty()) break; + + for (socket_list::iterator os =g_connections.begin(); + os!=g_connections.end(); + os++) { + if (*os != s) (*os)->SendLine(r); + } + } + + g_connections.remove(s); + + delete s; + + return 0; +} + +int main() { + SocketServer in(2000,5); + + while (1) { + Socket* s=in.Accept(); + + unsigned ret; + _beginthreadex(0,0,Connection,(void*) s,0,&ret); + } + + return 0; +} diff --git a/cpp-webserver/socket/examples/proxy.cpp b/cpp-webserver/socket/examples/proxy.cpp new file mode 100644 index 00000000..27657252 --- /dev/null +++ b/cpp-webserver/socket/examples/proxy.cpp @@ -0,0 +1,98 @@ +/* + proxy.cpp + + Copyright (C) 2002-2017 Ren茅 Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +#include "Socket.h" + +#include +#include +#include + +int portProxy; +std::string addrServer; +int portServer; + +unsigned __stdcall RunProxyThread (void* a) { + Socket* s = (Socket*) a; + SocketClient c(addrServer, portServer); + + while (1) { + SocketSelect sel(s, &c); + + bool still_connected = true; + + if (sel.Readable(s)) { + std::string bytes = s->ReceiveBytes(); + c.SendBytes(bytes); + std::cout << "Server: " << bytes << std::endl; + if (bytes.empty()) still_connected=false; + } + if (sel.Readable(&c)) { + std::string bytes = c.ReceiveBytes(); + s->SendBytes(bytes); + std::cout << "Client: " << bytes << std::endl; + if (bytes.empty()) still_connected=false; + } + if (! still_connected) { + break; + } + } + + delete s; + + return 0; +} + +int main(int argc, char* argv[]) { + if (argc < 4) { + std::cout << "Usage:" << std::endl; + std::cout << " proxy " << std::endl; + std::cout << std::endl; + std::cout << " This proxy will then listen on and whenever it receives" << std::endl; + std::cout << " a connection, relays the traffic to the of ." << std::endl; + std::cout << " This makes it ideal to see what an SMTP Client exchanges with a SMTP Server," << std::endl; + std::cout << " or equally what a NNTP client exchanges with an NNTP Server." << std::endl << std::endl; + return -1; + } + + std::stringstream s; + + s<>portProxy; s.clear(); + + addrServer=argv[2]; + + s<>portServer; + + SocketServer in(portProxy,5); + + while (1) { + Socket* s=in.Accept(); + + unsigned ret; + _beginthreadex(0, 0, RunProxyThread,(void*) s,0,&ret); + } + + return 0; +} diff --git a/cpp-webserver/socket/examples/simple-client.cpp b/cpp-webserver/socket/examples/simple-client.cpp new file mode 100644 index 00000000..b6db3063 --- /dev/null +++ b/cpp-webserver/socket/examples/simple-client.cpp @@ -0,0 +1,35 @@ +#include "Socket.h" + +#include + +using namespace std; + +int main() { + + try { + SocketClient s("www.renenyffenegger.ch", 80); + + s.SendLine("GET / HTTP/1.0"); + s.SendLine("Host: www.renenyffenegger.ch"); + s.SendLine(""); + + while (1) { + string l = s.ReceiveLine(); + if (l.empty()) break; + cout << l; + cout.flush(); + } + + } + catch (const char* s) { + cerr << s << endl; + } + catch (std::string s) { + cerr << s << endl; + } + catch (...) { + cerr << "unhandled exception\n"; + } + + return 0; +} diff --git a/cpp-webserver/socket/src/Socket.cpp b/cpp-webserver/socket/src/Socket.cpp new file mode 100644 index 00000000..00d7a90f --- /dev/null +++ b/cpp-webserver/socket/src/Socket.cpp @@ -0,0 +1,249 @@ +/* + Socket.cpp + + Copyright (C) 2002-2004 Ren茅 Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +#include "stdafx.h" +#include "Socket.h" +#include + +using namespace std; + +int Socket::nofSockets_= 0; + +void Socket::Start() { + if (!nofSockets_) { + WSADATA info; + if (WSAStartup(MAKEWORD(2,0), &info)) { + throw "Could not start WSA"; + } + } + ++nofSockets_; +} + +void Socket::End() { + WSACleanup(); +} + +Socket::Socket() : s_(0) { + Start(); + // UDP: use SOCK_DGRAM instead of SOCK_STREAM + s_ = socket(AF_INET,SOCK_STREAM,0); + + if (s_ == INVALID_SOCKET) { + throw "INVALID_SOCKET"; + } + + refCounter_ = new int(1); +} + +Socket::Socket(SOCKET s) : s_(s) { + Start(); + refCounter_ = new int(1); +}; + +Socket::~Socket() { + if (! --(*refCounter_)) { + Close(); + delete refCounter_; + } + + --nofSockets_; + if (!nofSockets_) End(); +} + +Socket::Socket(const Socket& o) { + refCounter_=o.refCounter_; + (*refCounter_)++; + s_ =o.s_; + + nofSockets_++; +} + +Socket& Socket::operator=(Socket& o) { + (*o.refCounter_)++; + + refCounter_=o.refCounter_; + s_ =o.s_; + + nofSockets_++; + + return *this; +} + +void Socket::Close() { + closesocket(s_); +} + +std::string Socket::ReceiveBytes() { + std::string ret; + char buf[1024]; + + while (1) { + u_long arg = 0; + if (ioctlsocket(s_, FIONREAD, &arg) != 0) + break; + + if (arg == 0) + break; + + if (arg > 1024) arg = 1024; + + int rv = recv (s_, buf, arg, 0); + if (rv <= 0) break; + + std::string t; + + t.assign (buf, rv); + ret += t; + } + + return ret; +} + +std::string Socket::ReceiveLine() { + std::string ret; + while (1) { + char r; + + switch(recv(s_, &r, 1, 0)) { + case 0: // not connected anymore; + // ... but last line sent + // might not end in \n, + // so return ret anyway. + return ret; + case -1: + return ""; +// if (errno == EAGAIN) { +// return ret; +// } else { +// // not connected anymore +// return ""; +// } + } + + ret += r; + if (r == '\n') return ret; + } +} + +void Socket::SendLine(std::string s) { + s += '\n'; + send(s_,s.c_str(),s.length(),0); +} + +void Socket::SendBytes(const std::string& s) { + send(s_,s.c_str(),s.length(),0); +} + +SocketServer::SocketServer(int port, int connections, TypeSocket type) { + sockaddr_in sa; + + memset(&sa, 0, sizeof(sa)); + + sa.sin_family = PF_INET; + sa.sin_port = htons(port); + s_ = socket(AF_INET, SOCK_STREAM, 0); + if (s_ == INVALID_SOCKET) { + throw "INVALID_SOCKET"; + } + + if(type==NonBlockingSocket) { + u_long arg = 1; + ioctlsocket(s_, FIONBIO, &arg); + } + + /* bind the socket to the internet address */ + if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) { + closesocket(s_); + throw "INVALID_SOCKET"; + } + + listen(s_, connections); +} + +Socket* SocketServer::Accept() { + SOCKET new_sock = accept(s_, 0, 0); + if (new_sock == INVALID_SOCKET) { + int rc = WSAGetLastError(); + if(rc==WSAEWOULDBLOCK) { + return 0; // non-blocking call, no request pending + } + else { + throw "Invalid Socket"; + } + } + + Socket* r = new Socket(new_sock); + return r; +} + +SocketClient::SocketClient(const std::string& host, int port) : Socket() { + std::string error; + + hostent *he; + if ((he = gethostbyname(host.c_str())) == 0) { + error = strerror(errno); + throw error; + } + + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr = *((in_addr *)he->h_addr); + memset(&(addr.sin_zero), 0, 8); + + if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr))) { + error = strerror(WSAGetLastError()); + throw error; + } +} + +SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) { + FD_ZERO(&fds_); + FD_SET(const_cast(s1)->s_,&fds_); + if(s2) { + FD_SET(const_cast(s2)->s_,&fds_); + } + + TIMEVAL tval; + tval.tv_sec = 0; + tval.tv_usec = 1; + + TIMEVAL *ptval; + if(type==NonBlockingSocket) { + ptval = &tval; + } + else { + ptval = 0; + } + + if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, ptval) == SOCKET_ERROR) + throw "Error in select"; +} + +bool SocketSelect::Readable(Socket const* const s) { + if (FD_ISSET(s->s_,&fds_)) return true; + return false; +} diff --git a/cpp-webserver/socket/src/Socket.h b/cpp-webserver/socket/src/Socket.h new file mode 100644 index 00000000..afde4808 --- /dev/null +++ b/cpp-webserver/socket/src/Socket.h @@ -0,0 +1,99 @@ +/* + Socket.h + + Copyright (C) 2002-2017 Ren茅 Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +#ifndef SOCKET_H +#define SOCKET_H + +#include + +#include + +enum TypeSocket {BlockingSocket, NonBlockingSocket}; + +class Socket { +public: + + virtual ~Socket(); + Socket(const Socket&); + Socket& operator=(Socket&); + + std::string ReceiveLine(); + std::string ReceiveBytes(); + + void Close(); + + // The parameter of SendLine is not a const reference + // because SendLine modifes the std::string passed. + void SendLine (std::string); + + // The parameter of SendBytes is a const reference + // because SendBytes does not modify the std::string passed + // (in contrast to SendLine). + void SendBytes(const std::string&); + +protected: + friend class SocketServer; + friend class SocketSelect; + + Socket(SOCKET s); + Socket(); + + SOCKET s_; + + int* refCounter_; + +private: + static void Start(); + static void End(); + static int nofSockets_; +}; + +class SocketClient : public Socket { +public: + SocketClient(const std::string& host, int port); +}; + +class SocketServer : public Socket { +public: + SocketServer(int port, int connections, TypeSocket type=BlockingSocket); + + Socket* Accept(); +}; + +class SocketSelect { +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/wsapiref_2tiq.asp + public: + SocketSelect(Socket const * const s1, Socket const * const s2=NULL, TypeSocket type=BlockingSocket); + + bool Readable(Socket const * const s); + + private: + fd_set fds_; +}; + + + +#endif diff --git a/stdHelpers.cpp b/cpp-webserver/stdHelpers.cpp similarity index 98% rename from stdHelpers.cpp rename to cpp-webserver/stdHelpers.cpp index 6f4521c7..4324eda5 100644 --- a/stdHelpers.cpp +++ b/cpp-webserver/stdHelpers.cpp @@ -23,7 +23,7 @@ Ren茅 Nyffenegger rene.nyffenegger@adp-gmbh.ch */ - +#include "stdafx.h" #include "stdHelpers.h" #include #include diff --git a/stdHelpers.h b/cpp-webserver/stdHelpers.h similarity index 100% rename from stdHelpers.h rename to cpp-webserver/stdHelpers.h diff --git a/cpp-webserver/stdafx.cpp b/cpp-webserver/stdafx.cpp new file mode 100644 index 00000000..e2319b5b --- /dev/null +++ b/cpp-webserver/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// cpp-webserver.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/cpp-webserver/stdafx.h b/cpp-webserver/stdafx.h new file mode 100644 index 00000000..d893a2bf --- /dev/null +++ b/cpp-webserver/stdafx.h @@ -0,0 +1,15 @@ +锘// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + +//鏀寔涓枃 + +// TODO: reference additional headers your program requires here diff --git a/cpp-webserver/targetver.h b/cpp-webserver/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/cpp-webserver/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/webserver.cpp b/cpp-webserver/webserver.cpp similarity index 89% rename from webserver.cpp rename to cpp-webserver/webserver.cpp index 3d192586..9a0491c9 100644 --- a/webserver.cpp +++ b/cpp-webserver/webserver.cpp @@ -1,4 +1,4 @@ -/* +锘/* WebServer.cpp Copyright (C) 2003-2004 Ren茅 Nyffenegger @@ -25,7 +25,7 @@ Thanks to Tom Lynn who pointed out an error in this source code. */ - +#include "stdafx.h" #include #include #include @@ -36,9 +36,10 @@ #include "webserver.h" -#include "socket.h" +#include "socket/src/Socket.h" #include "UrlHelper.h" -#include "base64.h" +#include "base64/base64.h" +#include "EncodingConverter.h" webserver::request_func webserver::request_func_=0; @@ -66,7 +67,7 @@ unsigned webserver::Request(void* ptr_s) { SplitGetReq(line.substr(posStartPath), path, params); - req.status_ = "202 OK"; + req.status_ = "200 OK"; req.s_ = &s; req.path_ = path; req.params_ = params; @@ -114,7 +115,7 @@ unsigned webserver::Request(void* ptr_s) { request_func_(&req); std::stringstream str_str; - str_str << req.answer_.size(); + str_str << req.answer_.size();//Using chinese with utf-8,the content length is not correct. time_t ltime; time(<ime); @@ -139,10 +140,12 @@ unsigned webserver::Request(void* ptr_s) { s.SendLine(std::string("Date: ") + asctime_remove_nl + " GMT"); s.SendLine(std::string("Server: ") +serverName); s.SendLine("Connection: close"); - s.SendLine("Content-Type: text/html; charset=ISO-8859-1"); - s.SendLine("Content-Length: " + str_str.str()); + s.SendLine("Content-Type: text/html; charset=utf-8"); + //Using chinese with utf-8,the content length is not correct. + //s.SendLine("Content-Length: " + str_str.str()); s.SendLine(""); - s.SendLine(req.answer_); + std::string content=EncodingConverter::ToUtf8String(req.answer_); + s.SendLine(content); s.Close(); diff --git a/webserver.h b/cpp-webserver/webserver.h similarity index 100% rename from webserver.h rename to cpp-webserver/webserver.h diff --git a/ipch/CPP-WEBSERVER-ab209096/CPP-WEBSERVER-8391ee31.ipch b/ipch/CPP-WEBSERVER-ab209096/CPP-WEBSERVER-8391ee31.ipch new file mode 100644 index 00000000..c746b1c8 Binary files /dev/null and b/ipch/CPP-WEBSERVER-ab209096/CPP-WEBSERVER-8391ee31.ipch differ diff --git a/socket b/socket deleted file mode 160000 index 713768b9..00000000 --- a/socket +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 713768b97514363aede0b77a96fa8af59e952b5f