pion-5.0.7+dfsg.orig/0000755000372000001440000000000012420270445013740 5ustar robertouserspion-5.0.7+dfsg.orig/PionNetServices.vcxproj0000644000372000001440000002526012420270445020442 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F} PionNetServices Utility v120 Utility v120 Utility v120 Utility v120 Utility v120 Utility v120 Utility v120 Utility v120 <_ProjectFileVersion>10.0.40219.1 Remove all files from services\.libs if exist services\.libs del /Q services\.libs\*.* Copy the plugin DLLs for the current configuration into services\.libs if not exist services\.libs md services\.libs copy services\$(Configuration)_$(Platform)\*.dll services\.libs del $(LastBuildState) Remove all files from services\.libs if exist services\.libs del /Q services\.libs\*.* X64 Copy the plugin DLLs for the current configuration into services\.libs if not exist services\.libs md services\.libs copy services\$(Configuration)_$(Platform)\*.dll services\.libs del $(LastBuildState) Remove all files from services\.libs if exist services\.libs del /Q services\.libs\*.* Copy the plugin DLLs for the current configuration into services\.libs if not exist services\.libs md services\.libs copy services\$(Configuration)_$(Platform)\*.dll services\.libs del $(LastBuildState) Remove all files from services\.libs if exist services\.libs del /Q services\.libs\*.* X64 Copy the plugin DLLs for the current configuration into services\.libs if not exist services\.libs md services\.libs copy services\$(Configuration)_$(Platform)\*.dll services\.libs del $(LastBuildState) X64 X64 {8c8a8e46-4588-4ce1-b624-89c36ea5209e} false {1cf012d8-a47c-4d2b-952d-d90d19795a07} false {09c3d3d7-7ce0-48d1-994f-eb534c07cf8b} false {70ca1fa9-ba9a-4ea4-9b7b-c747238991c1} false {9ee2433a-b460-45e0-8968-ec5ce8ef9875} false {12f95fe7-ace1-4281-86bf-4117ae2d633e} false pion-5.0.7+dfsg.orig/COPYING0000644000372000001440000000247212420270445015000 0ustar robertousersBoost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pion-5.0.7+dfsg.orig/pion.sln0000644000372000001440000005337712420270445015442 0ustar robertousers Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.30723.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pion", "src\pion.vcxproj", "{61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "piond", "utils\piond.vcxproj", "{2CF6432F-56EA-43AD-BCCB-C31A4DB75853}" ProjectSection(ProjectDependencies) = postProject {99D0C0C7-793B-49B1-A42E-CB563E5BB81F} = {99D0C0C7-793B-49B1-A42E-CB563E5BB81F} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "piontests", "tests\piontests.vcxproj", "{5AD25B42-E2C0-4D08-985B-E8F115D19D56}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PionNetServices", "PionNetServices.vcxproj", "{99D0C0C7-793B-49B1-A42E-CB563E5BB81F}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AllowNothingService", "services\AllowNothingService.vcxproj", "{8C8A8E46-4588-4CE1-B624-89C36EA5209E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CookieService", "services\CookieService.vcxproj", "{1CF012D8-A47C-4D2B-952D-D90D19795A07}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EchoService", "services\EchoService.vcxproj", "{09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileService", "services\FileService.vcxproj", "{70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloService", "services\HelloService.vcxproj", "{9EE2433A-B460-45E0-8968-EC5CE8EF9875}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LogService", "services\LogService.vcxproj", "{12F95FE7-ACE1-4281-86BF-4117AE2D633E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hasCreateAndDestroy", "tests\plugins\hasCreateAndDestroy.vcxproj", "{CD11B3D6-1296-45F4-B924-034CC103D626}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hasCreateButNoDestroy", "tests\plugins\hasCreateButNoDestroy.vcxproj", "{2DEAB99F-2617-4235-8EF7-653F36EFAC83}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hasNoCreate", "tests\plugins\hasNoCreate.vcxproj", "{33DEAB53-40E1-42FF-9C17-7A9956102052}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestPlugins", "tests\TestPlugins.vcxproj", "{7080E9F1-318F-4152-9E36-9F427F5CE9B7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_DLL_full|Win32 = Debug_DLL_full|Win32 Debug_DLL_full|x64 = Debug_DLL_full|x64 Debug_static|Win32 = Debug_static|Win32 Debug_static|x64 = Debug_static|x64 Release_DLL_full|Win32 = Release_DLL_full|Win32 Release_DLL_full|x64 = Release_DLL_full|x64 Release_static|Win32 = Release_static|Win32 Release_static|x64 = Release_static|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_static|Win32.Build.0 = Debug_static|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_static|x64.ActiveCfg = Debug_static|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Debug_static|x64.Build.0 = Debug_static|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_static|Win32.ActiveCfg = Release_static|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_static|Win32.Build.0 = Release_static|Win32 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_static|x64.ActiveCfg = Release_static|x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62}.Release_static|x64.Build.0 = Release_static|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_static|Win32.Build.0 = Debug_static|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_static|x64.ActiveCfg = Debug_static|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Debug_static|x64.Build.0 = Debug_static|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_static|Win32.ActiveCfg = Release_static|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_static|Win32.Build.0 = Release_static|Win32 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_static|x64.ActiveCfg = Release_static|x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853}.Release_static|x64.Build.0 = Release_static|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_static|Win32.Build.0 = Debug_static|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_static|x64.ActiveCfg = Debug_static|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Debug_static|x64.Build.0 = Debug_static|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_static|Win32.ActiveCfg = Release_static|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_static|Win32.Build.0 = Release_static|Win32 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_static|x64.ActiveCfg = Release_static|x64 {5AD25B42-E2C0-4D08-985B-E8F115D19D56}.Release_static|x64.Build.0 = Release_static|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_static|Win32.Build.0 = Debug_static|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_static|x64.ActiveCfg = Debug_static|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Debug_static|x64.Build.0 = Debug_static|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_static|Win32.ActiveCfg = Release_static|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_static|Win32.Build.0 = Release_static|Win32 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_static|x64.ActiveCfg = Release_static|x64 {99D0C0C7-793B-49B1-A42E-CB563E5BB81F}.Release_static|x64.Build.0 = Release_static|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_static|Win32.Build.0 = Debug_static|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_static|x64.ActiveCfg = Debug_static|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Debug_static|x64.Build.0 = Debug_static|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_static|Win32.ActiveCfg = Release_static|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_static|Win32.Build.0 = Release_static|Win32 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_static|x64.ActiveCfg = Release_static|x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E}.Release_static|x64.Build.0 = Release_static|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_static|Win32.Build.0 = Debug_static|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_static|x64.ActiveCfg = Debug_static|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Debug_static|x64.Build.0 = Debug_static|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_static|Win32.ActiveCfg = Release_static|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_static|Win32.Build.0 = Release_static|Win32 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_static|x64.ActiveCfg = Release_static|x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07}.Release_static|x64.Build.0 = Release_static|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_static|Win32.Build.0 = Debug_static|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_static|x64.ActiveCfg = Debug_static|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Debug_static|x64.Build.0 = Debug_static|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_static|Win32.ActiveCfg = Release_static|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_static|Win32.Build.0 = Release_static|Win32 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_static|x64.ActiveCfg = Release_static|x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B}.Release_static|x64.Build.0 = Release_static|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_static|Win32.Build.0 = Debug_static|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_static|x64.ActiveCfg = Debug_static|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Debug_static|x64.Build.0 = Debug_static|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_static|Win32.ActiveCfg = Release_static|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_static|Win32.Build.0 = Release_static|Win32 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_static|x64.ActiveCfg = Release_static|x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1}.Release_static|x64.Build.0 = Release_static|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_static|Win32.Build.0 = Debug_static|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_static|x64.ActiveCfg = Debug_static|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Debug_static|x64.Build.0 = Debug_static|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_static|Win32.ActiveCfg = Release_static|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_static|Win32.Build.0 = Release_static|Win32 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_static|x64.ActiveCfg = Release_static|x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875}.Release_static|x64.Build.0 = Release_static|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_static|Win32.Build.0 = Debug_static|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_static|x64.ActiveCfg = Debug_static|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Debug_static|x64.Build.0 = Debug_static|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_static|Win32.ActiveCfg = Release_static|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_static|Win32.Build.0 = Release_static|Win32 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_static|x64.ActiveCfg = Release_static|x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E}.Release_static|x64.Build.0 = Release_static|x64 {CD11B3D6-1296-45F4-B924-034CC103D626}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {CD11B3D6-1296-45F4-B924-034CC103D626}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {CD11B3D6-1296-45F4-B924-034CC103D626}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {CD11B3D6-1296-45F4-B924-034CC103D626}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {CD11B3D6-1296-45F4-B924-034CC103D626}.Debug_static|Win32.ActiveCfg = Release_Static|Win32 {CD11B3D6-1296-45F4-B924-034CC103D626}.Debug_static|x64.ActiveCfg = Release_Static|x64 {CD11B3D6-1296-45F4-B924-034CC103D626}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_Full|Win32 {CD11B3D6-1296-45F4-B924-034CC103D626}.Release_DLL_full|Win32.Build.0 = Release_DLL_Full|Win32 {CD11B3D6-1296-45F4-B924-034CC103D626}.Release_DLL_full|x64.ActiveCfg = Release_DLL_Full|x64 {CD11B3D6-1296-45F4-B924-034CC103D626}.Release_DLL_full|x64.Build.0 = Release_DLL_Full|x64 {CD11B3D6-1296-45F4-B924-034CC103D626}.Release_static|Win32.ActiveCfg = Release_Static|Win32 {CD11B3D6-1296-45F4-B924-034CC103D626}.Release_static|x64.ActiveCfg = Release_Static|x64 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Debug_static|Win32.ActiveCfg = Release_Static|Win32 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Debug_static|x64.ActiveCfg = Release_Static|x64 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Release_static|Win32.ActiveCfg = Release_Static|Win32 {2DEAB99F-2617-4235-8EF7-653F36EFAC83}.Release_static|x64.ActiveCfg = Release_Static|x64 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Debug_static|Win32.ActiveCfg = Release_Static|Win32 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Debug_static|x64.ActiveCfg = Release_Static|x64 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Release_static|Win32.ActiveCfg = Release_Static|Win32 {33DEAB53-40E1-42FF-9C17-7A9956102052}.Release_static|x64.ActiveCfg = Release_Static|x64 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Debug_DLL_full|Win32.ActiveCfg = Debug_DLL_full|Win32 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Debug_DLL_full|Win32.Build.0 = Debug_DLL_full|Win32 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Debug_DLL_full|x64.ActiveCfg = Debug_DLL_full|x64 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Debug_DLL_full|x64.Build.0 = Debug_DLL_full|x64 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Debug_static|Win32.ActiveCfg = Debug_static|Win32 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Debug_static|x64.ActiveCfg = Debug_static|x64 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Release_DLL_full|Win32.ActiveCfg = Release_DLL_full|Win32 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Release_DLL_full|Win32.Build.0 = Release_DLL_full|Win32 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Release_DLL_full|x64.ActiveCfg = Release_DLL_full|x64 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Release_DLL_full|x64.Build.0 = Release_DLL_full|x64 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Release_static|Win32.ActiveCfg = Release_static|Win32 {7080E9F1-318F-4152-9E36-9F427F5CE9B7}.Release_static|x64.ActiveCfg = Release_static|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal pion-5.0.7+dfsg.orig/configure.ac0000644000372000001440000000256112420270445016232 0ustar robertousers# ------------------------------------------------ # Pion Network Library autoconf configuration file # ------------------------------------------------ # Set pion version information AC_INIT([pion], [5.0.7], [pion-users@lists.sourceforge.net]) # Initialize some other things AC_PREREQ([2.59]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([m4]) AC_CONFIG_SRCDIR(src/algorithm.cpp) # package and version args are now taken from AC_INIT() AM_INIT_AUTOMAKE([foreign]) # Use "silent mode" for less verbose build commands in automake 1.11+ m4_ifdef( [AM_SILENT_RULES], [AM_SILENT_RULES([yes])] ) # Needed to set per-target compilation flags AM_PROG_CC_C_O # Setup libtool AC_LIBTOOL_WIN32_DLL AC_LIBTOOL_DLOPEN AC_PROG_LIBTOOL # Setup doxygen support DX_DOXYGEN_FEATURE(ON) DX_HTML_FEATURE(ON) DX_INIT_DOXYGEN(pion, doc/Doxyfile, doc) # Define CXXFLAGS before AC_PROG_CXX to suppress the default autoconf # compiler options CFLAGS="$CFLAGS -DPION" CXXFLAGS="$CXXFLAGS -DPION" # Include pion-config.inc m4_include([build/pion-setup.inc]) m4_include([build/pion-boost.inc]) m4_include([build/pion-config.inc]) # Output Makefiles AC_OUTPUT(pion.pc Makefile include/Makefile include/pion/Makefile include/pion/tcp/Makefile include/pion/http/Makefile include/pion/test/Makefile include/pion/spdy/Makefile src/Makefile services/Makefile utils/Makefile tests/Makefile tests/plugins/Makefile) pion-5.0.7+dfsg.orig/TODO0000644000372000001440000000004712420270445014431 0ustar robertousersSee https://github.com/cloudmeter/pion pion-5.0.7+dfsg.orig/services/0000755000372000001440000000000012420270445015563 5ustar robertouserspion-5.0.7+dfsg.orig/services/EchoService.vcxproj0000644000372000001440000003272412420270445021407 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {09C3D3D7-7CE0-48D1-994F-EB534C07CF8B} EchoService Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset X64 ProgramDatabase X64 MultiThreadedDLL ECHOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 ECHOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 ECHOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 ECHOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false MachineX64 MultiThreadedDLL {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/services/CookieService.cpp0000644000372000001440000001177012420270445021027 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include "CookieService.hpp" #include #include using namespace pion; namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins // CookieService member functions /// handles requests for CookieService void CookieService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string HEADER_HTML = "\n\nCookie Service\n" "\n\n\n

Cookie Service

\n"; static const std::string FOOTER_HTML = "\n\n\n"; // Set Content-type for HTML and write the header http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_content_type(http::types::CONTENT_TYPE_HTML); writer->write_no_copy(HEADER_HTML); // Check if we have an action to perform if (http_request_ptr->has_query("action")) { if (http_request_ptr->get_query("action") == "Add Cookie") { // add a new cookie const std::string cookie_name(http_request_ptr->get_query("cookie_name")); const std::string cookie_value(http_request_ptr->get_query("cookie_value")); if (cookie_name.empty() || cookie_value.empty()) { writer << "\n

[Error: You must specify a name and value to add a cookie]

\n\n"; } else { writer->get_response().set_cookie(cookie_name, cookie_value); writer << "\n

[Added cookie " << cookie_name << '=' << cookie_value << "]

\n\n"; } } else if (http_request_ptr->get_query("action") == "delete") { const std::string cookie_name(http_request_ptr->get_query("cookie_name")); if (cookie_name.empty()) { writer << "\n

[Error: You must specify a name to delete a cookie]

\n\n"; } else { writer->get_response().delete_cookie(cookie_name); writer << "\n

[Deleted cookie " << cookie_name << "]

\n\n"; } } else { writer << "\n

[Error: Unrecognized action]

\n\n"; } } // display cookie headers in request if (http_request_ptr->has_header(http::types::HEADER_COOKIE)) { writer << "\n

Cookie Headers

\n\n\n"; } else { writer << "\n

No Cookie Headers

\n\n"; } // display existing cookies ihash_multimap& cookie_params = http_request_ptr->get_cookies(); if (! cookie_params.empty()) { writer << "\n

Cookie Variables

\n\n\n"; } else { writer << "\n

No Cookie Variables

\n\n"; } // display form to add a cookie writer << "\n

Add Cookie

\n" "

get_resource() << "\" method=\"POST\">\n" "Name:
\n" "Value:
\n" "

\n" "
\n\n"; // write the footer writer->write_no_copy(FOOTER_HTML); // send the writer writer->send(); } } // end namespace plugins } // end namespace pion /// creates new CookieService objects extern "C" PION_PLUGIN pion::plugins::CookieService *pion_create_CookieService(void) { return new pion::plugins::CookieService(); } /// destroys CookieService objects extern "C" PION_PLUGIN void pion_destroy_CookieService(pion::plugins::CookieService *service_ptr) { delete service_ptr; } pion-5.0.7+dfsg.orig/services/HelloService.hpp0000644000372000001440000000200012420270445020650 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HELLOSERVICE_HEADER__ #define __PION_HELLOSERVICE_HEADER__ #include namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// /// HelloService: web service that responds with "Hello World" /// class HelloService : public pion::http::plugin_service { public: HelloService(void) {} virtual ~HelloService() {} virtual void operator()(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); }; } // end namespace plugins } // end namespace pion #endif pion-5.0.7+dfsg.orig/services/LogService.vcxproj.filters0000644000372000001440000000203012420270445022704 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Header Files pion-5.0.7+dfsg.orig/services/FileService.cpp0000644000372000001440000012700712420270445020476 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include #include #include "FileService.hpp" #include #include #include #include using namespace pion; namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins // static members of FileService const std::string FileService::DEFAULT_MIME_TYPE("application/octet-stream"); const unsigned int FileService::DEFAULT_CACHE_SETTING = 1; const unsigned int FileService::DEFAULT_SCAN_SETTING = 0; const unsigned long FileService::DEFAULT_MAX_CACHE_SIZE = 0; /* 0=disabled */ const unsigned long FileService::DEFAULT_MAX_CHUNK_SIZE = 0; /* 0=disabled */ boost::once_flag FileService::m_mime_types_init_flag = BOOST_ONCE_INIT; FileService::MIMETypeMap *FileService::m_mime_types_ptr = NULL; // FileService member functions FileService::FileService(void) : m_logger(PION_GET_LOGGER("pion.FileService")), m_cache_setting(DEFAULT_CACHE_SETTING), m_scan_setting(DEFAULT_SCAN_SETTING), m_max_cache_size(DEFAULT_MAX_CACHE_SIZE), m_max_chunk_size(DEFAULT_MAX_CHUNK_SIZE), m_writable(false) {} void FileService::set_option(const std::string& name, const std::string& value) { if (name == "directory") { m_directory = value; m_directory.normalize(); plugin::check_cygwin_path(m_directory, value); // make sure that the directory exists if (! boost::filesystem::exists(m_directory) || ! boost::filesystem::is_directory(m_directory)) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 const std::string dir_name = m_directory.string(); #else const std::string dir_name = m_directory.directory_string(); #endif BOOST_THROW_EXCEPTION( error::directory_not_found() << error::errinfo_dir_name(dir_name) ); } } else if (name == "file") { m_file = value; plugin::check_cygwin_path(m_file, value); // make sure that the directory exists if (! boost::filesystem::exists(m_file) || boost::filesystem::is_directory(m_file)) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 const std::string file_name = m_file.string(); #else const std::string file_name = m_file.file_string(); #endif BOOST_THROW_EXCEPTION( error::file_not_found() << error::errinfo_file_name(file_name) ); } } else if (name == "cache") { if (value == "0") { m_cache_setting = 0; } else if (value == "1") { m_cache_setting = 1; } else if (value == "2") { m_cache_setting = 2; } else { BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } } else if (name == "scan") { if (value == "0") { m_scan_setting = 0; } else if (value == "1") { m_scan_setting = 1; } else if (value == "2") { m_scan_setting = 2; } else if (value == "3") { m_scan_setting = 3; } else { BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } } else if (name == "max_chunk_size") { m_max_chunk_size = boost::lexical_cast(value); } else if (name == "writable") { if (value == "true") { m_writable = true; } else if (value == "false") { m_writable = false; } else { BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } } else { BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } } void FileService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // get the relative resource path for the request const std::string relative_path(get_relative_resource(http_request_ptr->get_resource())); // determine the path of the file being requested boost::filesystem::path file_path; if (relative_path.empty()) { // request matches resource exactly if (m_file.empty()) { // no file is specified, either in the request or in the options PION_LOG_WARN(m_logger, "No file option defined (" << get_resource() << ")"); sendNotFoundResponse(http_request_ptr, tcp_conn); return; } else { file_path = m_file; } } else { // request does not match resource if (m_directory.empty()) { // no directory is specified for the relative file PION_LOG_WARN(m_logger, "No directory option defined (" << get_resource() << "): " << relative_path); sendNotFoundResponse(http_request_ptr, tcp_conn); return; } else { file_path = m_directory / relative_path; } } // make sure that the requested file is within the configured directory file_path.normalize(); # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 std::string file_string = file_path.string(); if (file_string.find(m_directory.string()) != 0) { #else std::string file_string = file_path.file_string(); if (file_string.find(m_directory.directory_string()) != 0) { #endif PION_LOG_WARN(m_logger, "Request for file outside of directory (" << get_resource() << "): " << relative_path); static const std::string FORBIDDEN_HTML_START = "\n" "403 Forbidden\n" "\n" "

Forbidden

\n" "

The requested URL "; static const std::string FORBIDDEN_HTML_FINISH = " is not in the configured directory.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_FORBIDDEN); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_FORBIDDEN); if (http_request_ptr->get_method() != http::types::REQUEST_METHOD_HEAD) { writer->write_no_copy(FORBIDDEN_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(FORBIDDEN_HTML_FINISH); } writer->send(); return; } // requests specifying directories are not allowed if (boost::filesystem::is_directory(file_path)) { PION_LOG_WARN(m_logger, "Request for directory (" << get_resource() << "): " << relative_path); static const std::string FORBIDDEN_HTML_START = "\n" "403 Forbidden\n" "\n" "

Forbidden

\n" "

The requested URL "; static const std::string FORBIDDEN_HTML_FINISH = " is a directory.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_FORBIDDEN); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_FORBIDDEN); if (http_request_ptr->get_method() != http::types::REQUEST_METHOD_HEAD) { writer->write_no_copy(FORBIDDEN_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(FORBIDDEN_HTML_FINISH); } writer->send(); return; } if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_GET || http_request_ptr->get_method() == http::types::REQUEST_METHOD_HEAD) { // the type of response we will send enum ResponseType { RESPONSE_UNDEFINED, // initial state until we know how to respond RESPONSE_OK, // normal response that includes the file's content RESPONSE_HEAD_OK, // response to HEAD request (would send file's content) RESPONSE_NOT_FOUND, // Not Found (404) RESPONSE_NOT_MODIFIED // Not Modified (304) response to If-Modified-Since } response_type = RESPONSE_UNDEFINED; // used to hold our response information DiskFile response_file; // get the If-Modified-Since request header const std::string if_modified_since(http_request_ptr->get_header(http::types::HEADER_IF_MODIFIED_SINCE)); // check the cache for a corresponding entry (if enabled) // note that m_cache_setting may equal 0 if m_scan_setting == 1 if (m_cache_setting > 0 || m_scan_setting > 0) { // search for a matching cache entry boost::mutex::scoped_lock cache_lock(m_cache_mutex); CacheMap::iterator cache_itr = m_cache_map.find(relative_path); if (cache_itr == m_cache_map.end()) { // no existing cache entries found if (m_scan_setting == 1 || m_scan_setting == 3) { // do not allow files to be added; // all requests must correspond with existing cache entries // since no match was found, just return file not found PION_LOG_WARN(m_logger, "Request for unknown file (" << get_resource() << "): " << relative_path); response_type = RESPONSE_NOT_FOUND; } else { PION_LOG_DEBUG(m_logger, "No cache entry for request (" << get_resource() << "): " << relative_path); } } else { // found an existing cache entry PION_LOG_DEBUG(m_logger, "Found cache entry for request (" << get_resource() << "): " << relative_path); if (m_cache_setting == 0) { // cache is disabled // copy & re-use file_path and mime_type response_file.setFilePath(cache_itr->second.getFilePath()); response_file.setMimeType(cache_itr->second.getMimeType()); // get the file_size and last_modified timestamp response_file.update(); // just compare strings for simplicity (parsing this date format sucks!) if (response_file.getLastModifiedString() == if_modified_since) { // no need to read the file; the modified times match! response_type = RESPONSE_NOT_MODIFIED; } else { if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_HEAD) { response_type = RESPONSE_HEAD_OK; } else { response_type = RESPONSE_OK; PION_LOG_DEBUG(m_logger, "Cache disabled, reading file (" << get_resource() << "): " << relative_path); } } } else { // cache is enabled // true if the entry was updated (used for log message) bool cache_was_updated = false; if (cache_itr->second.getLastModified() == 0) { // cache file for the first time cache_was_updated = true; cache_itr->second.update(); if (m_max_cache_size==0 || cache_itr->second.getFileSize() <= m_max_cache_size) { // read the file (may throw exception) cache_itr->second.read(); } else { cache_itr->second.resetFileContent(); } } else if (m_cache_setting == 1) { // check if file has been updated (may throw exception) cache_was_updated = cache_itr->second.checkUpdated(); } // else cache_setting == 2 (use existing values) // get the response type if (cache_itr->second.getLastModifiedString() == if_modified_since) { response_type = RESPONSE_NOT_MODIFIED; } else if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_HEAD) { response_type = RESPONSE_HEAD_OK; } else { response_type = RESPONSE_OK; } // copy cache contents so that we can release the mutex response_file = cache_itr->second; // check if max size has been exceeded if (cache_was_updated && m_max_cache_size > 0 && cache_itr->second.getFileSize() > m_max_cache_size) { cache_itr->second.resetFileContent(); } PION_LOG_DEBUG(m_logger, (cache_was_updated ? "Updated" : "Using") << " cache entry for request (" << get_resource() << "): " << relative_path); } } } if (response_type == RESPONSE_UNDEFINED) { // make sure that the file exists if (! boost::filesystem::exists(file_path)) { PION_LOG_WARN(m_logger, "File not found (" << get_resource() << "): " << relative_path); sendNotFoundResponse(http_request_ptr, tcp_conn); return; } response_file.setFilePath(file_path); PION_LOG_DEBUG(m_logger, "Found file for request (" << get_resource() << "): " << relative_path); // determine the MIME type # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 response_file.setMimeType(findMIMEType( response_file.getFilePath().filename().string())); #else response_file.setMimeType(findMIMEType( response_file.getFilePath().leaf() )); #endif // get the file_size and last_modified timestamp response_file.update(); // just compare strings for simplicity (parsing this date format sucks!) if (response_file.getLastModifiedString() == if_modified_since) { // no need to read the file; the modified times match! response_type = RESPONSE_NOT_MODIFIED; } else if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_HEAD) { response_type = RESPONSE_HEAD_OK; } else { response_type = RESPONSE_OK; if (m_cache_setting != 0) { if (m_max_cache_size==0 || response_file.getFileSize() <= m_max_cache_size) { // read the file (may throw exception) response_file.read(); } // add new entry to the cache PION_LOG_DEBUG(m_logger, "Adding cache entry for request (" << get_resource() << "): " << relative_path); boost::mutex::scoped_lock cache_lock(m_cache_mutex); m_cache_map.insert( std::make_pair(relative_path, response_file) ); } } } if (response_type == RESPONSE_OK) { // use DiskFileSender to send a file DiskFileSenderPtr sender_ptr(DiskFileSender::create(response_file, http_request_ptr, tcp_conn, m_max_chunk_size)); sender_ptr->send(); } else if (response_type == RESPONSE_NOT_FOUND) { sendNotFoundResponse(http_request_ptr, tcp_conn); } else { // sending headers only -> use our own response object // prepare a response and set the Content-Type http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_content_type(response_file.getMimeType()); // set Last-Modified header to enable client-side caching writer->get_response().add_header(http::types::HEADER_LAST_MODIFIED, response_file.getLastModifiedString()); switch(response_type) { case RESPONSE_UNDEFINED: case RESPONSE_NOT_FOUND: case RESPONSE_OK: // this should never happen BOOST_ASSERT(false); break; case RESPONSE_NOT_MODIFIED: // set "Not Modified" response writer->get_response().set_status_code(http::types::RESPONSE_CODE_NOT_MODIFIED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_MODIFIED); break; case RESPONSE_HEAD_OK: // set "OK" response (not really necessary since this is the default) writer->get_response().set_status_code(http::types::RESPONSE_CODE_OK); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_OK); break; } // send the response writer->send(); } } else if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_POST || http_request_ptr->get_method() == http::types::REQUEST_METHOD_PUT || http_request_ptr->get_method() == http::types::REQUEST_METHOD_DELETE) { // If not writable, then send 405 (Method Not Allowed) response for POST, PUT or DELETE requests. if (!m_writable) { static const std::string NOT_ALLOWED_HTML_START = "\n" "405 Method Not Allowed\n" "\n" "

Not Allowed

\n" "

The requested method "; static const std::string NOT_ALLOWED_HTML_FINISH = " is not allowed on this server.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_METHOD_NOT_ALLOWED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED); writer->write_no_copy(NOT_ALLOWED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_method()); writer->write_no_copy(NOT_ALLOWED_HTML_FINISH); writer->get_response().add_header("Allow", "GET, HEAD"); writer->send(); } else { http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_POST || http_request_ptr->get_method() == http::types::REQUEST_METHOD_PUT) { if (boost::filesystem::exists(file_path)) { writer->get_response().set_status_code(http::types::RESPONSE_CODE_NO_CONTENT); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NO_CONTENT); } else { // The file doesn't exist yet, so it will be created below, unless the // directory of the requested file also doesn't exist. if (!boost::filesystem::exists(file_path.branch_path())) { static const std::string NOT_FOUND_HTML_START = "\n" "404 Not Found\n" "\n" "

Not Found

\n" "

The directory of the requested URL "; static const std::string NOT_FOUND_HTML_FINISH = " was not found on this server.

\n" "\n"; writer->get_response().set_status_code(http::types::RESPONSE_CODE_NOT_FOUND); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND); writer->write_no_copy(NOT_FOUND_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(NOT_FOUND_HTML_FINISH); writer->send(); return; } static const std::string CREATED_HTML_START = "\n" "201 Created\n" "\n" "

Created

\n" "

"; static const std::string CREATED_HTML_FINISH = "

\n" "\n"; writer->get_response().set_status_code(http::types::RESPONSE_CODE_CREATED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_CREATED); writer->get_response().add_header(http::types::HEADER_LOCATION, http_request_ptr->get_resource()); writer->write_no_copy(CREATED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(CREATED_HTML_FINISH); } std::ios_base::openmode mode = http_request_ptr->get_method() == http::types::REQUEST_METHOD_POST? std::ios::app : std::ios::out; boost::filesystem::ofstream file_stream(file_path, mode); file_stream.write(http_request_ptr->get_content(), http_request_ptr->get_content_length()); file_stream.close(); if (!boost::filesystem::exists(file_path)) { static const std::string PUT_FAILED_HTML_START = "\n" "500 Server Error\n" "\n" "

Server Error

\n" "

Error writing to "; static const std::string PUT_FAILED_HTML_FINISH = ".

\n" "\n"; writer->get_response().set_status_code(http::types::RESPONSE_CODE_SERVER_ERROR); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_SERVER_ERROR); writer->write_no_copy(PUT_FAILED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(PUT_FAILED_HTML_FINISH); } writer->send(); } else if (http_request_ptr->get_method() == http::types::REQUEST_METHOD_DELETE) { if (!boost::filesystem::exists(file_path)) { sendNotFoundResponse(http_request_ptr, tcp_conn); } else { try { boost::filesystem::remove(file_path); writer->get_response().set_status_code(http::types::RESPONSE_CODE_NO_CONTENT); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NO_CONTENT); writer->send(); } catch (std::exception& e) { static const std::string DELETE_FAILED_HTML_START = "\n" "500 Server Error\n" "\n" "

Server Error

\n" "

Could not delete "; static const std::string DELETE_FAILED_HTML_FINISH = ".

\n" "\n"; writer->get_response().set_status_code(http::types::RESPONSE_CODE_SERVER_ERROR); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_SERVER_ERROR); writer->write_no_copy(DELETE_FAILED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()) << ".

" << boost::diagnostic_information(e); writer->write_no_copy(DELETE_FAILED_HTML_FINISH); writer->send(); } } } else { // This should never be reached. writer->get_response().set_status_code(http::types::RESPONSE_CODE_SERVER_ERROR); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_SERVER_ERROR); writer->send(); } } } // Any method not handled above is unimplemented. else { static const std::string NOT_IMPLEMENTED_HTML_START = "\n" "501 Not Implemented\n" "\n" "

Not Implemented

\n" "

The requested method "; static const std::string NOT_IMPLEMENTED_HTML_FINISH = " is not implemented on this server.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_NOT_IMPLEMENTED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_IMPLEMENTED); writer->write_no_copy(NOT_IMPLEMENTED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_method()); writer->write_no_copy(NOT_IMPLEMENTED_HTML_FINISH); writer->send(); } } void FileService::sendNotFoundResponse(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string NOT_FOUND_HTML_START = "\n" "404 Not Found\n" "\n" "

Not Found

\n" "

The requested URL "; static const std::string NOT_FOUND_HTML_FINISH = " was not found on this server.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_NOT_FOUND); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND); if (http_request_ptr->get_method() != http::types::REQUEST_METHOD_HEAD) { writer->write_no_copy(NOT_FOUND_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(NOT_FOUND_HTML_FINISH); } writer->send(); } void FileService::start(void) { PION_LOG_DEBUG(m_logger, "Starting up resource (" << get_resource() << ')'); // scan directory/file if scan setting != 0 if (m_scan_setting != 0) { // force caching if scan == (2 | 3) if (m_cache_setting == 0 && m_scan_setting > 1) m_cache_setting = 1; boost::mutex::scoped_lock cache_lock(m_cache_mutex); // add entry for file if one is defined if (! m_file.empty()) { // use empty relative_path for file option // use placeholder entry (do not pre-populate) if scan == 1 addCacheEntry("", m_file, m_scan_setting == 1); } // scan directory if one is defined if (! m_directory.empty()) scanDirectory(m_directory); } } void FileService::stop(void) { PION_LOG_DEBUG(m_logger, "Shutting down resource (" << get_resource() << ')'); // clear cached files (if started again, it will re-scan) boost::mutex::scoped_lock cache_lock(m_cache_mutex); m_cache_map.clear(); } void FileService::scanDirectory(const boost::filesystem::path& dir_path) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_DEBUG(m_logger, "Scanning directory (" << get_resource() << "): " << dir_path.string()); #else PION_LOG_DEBUG(m_logger, "Scanning directory (" << get_resource() << "): " << dir_path.directory_string()); #endif // iterate through items in the directory boost::filesystem::directory_iterator end_itr; for ( boost::filesystem::directory_iterator itr( dir_path ); itr != end_itr; ++itr ) { if ( boost::filesystem::is_directory(*itr) ) { // item is a sub-directory // recursively call scanDirectory() scanDirectory(*itr); } else { // item is a regular file // figure out relative path to the file # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 std::string file_path_string( itr->path().string() ); std::string relative_path( file_path_string.substr(m_directory.string().size() + 1) ); #else std::string file_path_string( itr->path().file_string() ); std::string relative_path( file_path_string.substr(m_directory.directory_string().size() + 1) ); #endif // add item to cache (use placeholder if scan == 1) addCacheEntry(relative_path, *itr, m_scan_setting == 1); } } } std::pair FileService::addCacheEntry(const std::string& relative_path, const boost::filesystem::path& file_path, const bool placeholder) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 DiskFile cache_entry(file_path, NULL, 0, 0, findMIMEType(file_path.filename().string())); #else DiskFile cache_entry(file_path, NULL, 0, 0, findMIMEType(file_path.leaf())); #endif if (! placeholder) { cache_entry.update(); // only read the file if its size is <= max_cache_size if (m_max_cache_size==0 || cache_entry.getFileSize() <= m_max_cache_size) { try { cache_entry.read(); } catch (std::exception&) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_ERROR(m_logger, "Unable to add file to cache: " << file_path.string()); #else PION_LOG_ERROR(m_logger, "Unable to add file to cache: " << file_path.file_string()); #endif return std::make_pair(m_cache_map.end(), false); } } } std::pair add_entry_result = m_cache_map.insert( std::make_pair(relative_path, cache_entry) ); if (add_entry_result.second) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_DEBUG(m_logger, "Added file to cache: " << file_path.string()); #else PION_LOG_DEBUG(m_logger, "Added file to cache: " << file_path.file_string()); #endif } else { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_ERROR(m_logger, "Unable to insert cache entry for file: " << file_path.string()); #else PION_LOG_ERROR(m_logger, "Unable to insert cache entry for file: " << file_path.file_string()); #endif } return add_entry_result; } std::string FileService::findMIMEType(const std::string& file_name) { // initialize m_mime_types if it hasn't been done already boost::call_once(FileService::createMIMETypes, m_mime_types_init_flag); // determine the file's extension std::string extension(file_name.substr(file_name.find_last_of('.') + 1)); boost::algorithm::to_lower(extension); // search for the matching mime type and return the result MIMETypeMap::iterator i = m_mime_types_ptr->find(extension); return (i == m_mime_types_ptr->end() ? DEFAULT_MIME_TYPE : i->second); } void FileService::createMIMETypes(void) { // create the map static MIMETypeMap mime_types; // populate mime types mime_types["js"] = "text/javascript"; mime_types["txt"] = "text/plain"; mime_types["xml"] = "text/xml"; mime_types["css"] = "text/css"; mime_types["htm"] = "text/html"; mime_types["html"] = "text/html"; mime_types["xhtml"] = "text/html"; mime_types["gif"] = "image/gif"; mime_types["png"] = "image/png"; mime_types["jpg"] = "image/jpeg"; mime_types["jpeg"] = "image/jpeg"; mime_types["svg"] = "image/svg+xml"; mime_types["eof"] = "application/vnd.ms-fontobject"; mime_types["otf"] = "application/x-font-opentype"; mime_types["ttf"] = "application/x-font-ttf"; mime_types["woff"] = "application/font-woff"; // ... // set the static pointer m_mime_types_ptr = &mime_types; } // DiskFile member functions void DiskFile::update(void) { // set file_size and last_modified m_file_size = boost::numeric_cast(boost::filesystem::file_size( m_file_path )); m_last_modified = boost::filesystem::last_write_time( m_file_path ); m_last_modified_string = http::types::get_date_string( m_last_modified ); } void DiskFile::read(void) { // re-allocate storage buffer for the file's content m_file_content.reset(new char[m_file_size]); // open the file for reading boost::filesystem::ifstream file_stream; file_stream.open(m_file_path, std::ios::in | std::ios::binary); // read the file into memory if (!file_stream.is_open() || !file_stream.read(m_file_content.get(), m_file_size)) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 const std::string file_name = m_file_path.string(); #else const std::string file_name = m_file_path.file_string(); #endif BOOST_THROW_EXCEPTION( error::read_file() << error::errinfo_file_name(file_name) ); } } bool DiskFile::checkUpdated(void) { // get current values std::streamsize cur_size = boost::numeric_cast(boost::filesystem::file_size( m_file_path )); time_t cur_modified = boost::filesystem::last_write_time( m_file_path ); // check if file has not been updated if (cur_modified == m_last_modified && cur_size == m_file_size) return false; // file has been updated // update file_size and last_modified timestamp m_file_size = cur_size; m_last_modified = cur_modified; m_last_modified_string = http::types::get_date_string( m_last_modified ); // read new contents read(); return true; } // DiskFileSender member functions DiskFileSender::DiskFileSender(DiskFile& file, pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn, unsigned long max_chunk_size) : m_logger(PION_GET_LOGGER("pion.FileService.DiskFileSender")), m_disk_file(file), m_writer(pion::http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))), m_max_chunk_size(max_chunk_size), m_file_bytes_to_send(0), m_bytes_sent(0) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_DEBUG(m_logger, "Preparing to send file" << (m_disk_file.hasFileContent() ? " (cached): " : ": ") << m_disk_file.getFilePath().string()); #else PION_LOG_DEBUG(m_logger, "Preparing to send file" << (m_disk_file.hasFileContent() ? " (cached): " : ": ") << m_disk_file.getFilePath().file_string()); #endif // set the Content-Type HTTP header using the file's MIME type m_writer->get_response().set_content_type(m_disk_file.getMimeType()); // set Last-Modified header to enable client-side caching m_writer->get_response().add_header(http::types::HEADER_LAST_MODIFIED, m_disk_file.getLastModifiedString()); // use "200 OK" HTTP response m_writer->get_response().set_status_code(http::types::RESPONSE_CODE_OK); m_writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_OK); } void DiskFileSender::send(void) { // check if we have nothing to send (send 0 byte response content) if (m_disk_file.getFileSize() <= m_bytes_sent) { m_writer->send(); return; } // calculate the number of bytes to send (m_file_bytes_to_send) m_file_bytes_to_send = m_disk_file.getFileSize() - m_bytes_sent; if (m_max_chunk_size > 0 && m_file_bytes_to_send > m_max_chunk_size) m_file_bytes_to_send = m_max_chunk_size; // get the content to send (file_content_ptr) char *file_content_ptr; if (m_disk_file.hasFileContent()) { // the entire file IS cached in memory (m_disk_file.file_content) file_content_ptr = m_disk_file.getFileContent() + m_bytes_sent; } else { // the file is not cached in memory // check if the file has been opened yet if (! m_file_stream.is_open()) { // open the file for reading m_file_stream.open(m_disk_file.getFilePath(), std::ios::in | std::ios::binary); if (! m_file_stream.is_open()) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_ERROR(m_logger, "Unable to open file: " << m_disk_file.getFilePath().string()); #else PION_LOG_ERROR(m_logger, "Unable to open file: " << m_disk_file.getFilePath().file_string()); #endif return; } } // check if the content buffer was initialized yet if (! m_content_buf) { // allocate memory for the new content buffer m_content_buf.reset(new char[m_file_bytes_to_send]); } file_content_ptr = m_content_buf.get(); // read a block of data from the file into the content buffer if (! m_file_stream.read(m_content_buf.get(), m_file_bytes_to_send)) { if (m_file_stream.gcount() > 0) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_ERROR(m_logger, "File size inconsistency: " << m_disk_file.getFilePath().string()); #else PION_LOG_ERROR(m_logger, "File size inconsistency: " << m_disk_file.getFilePath().file_string()); #endif } else { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 PION_LOG_ERROR(m_logger, "Unable to read file: " << m_disk_file.getFilePath().string()); #else PION_LOG_ERROR(m_logger, "Unable to read file: " << m_disk_file.getFilePath().file_string()); #endif } return; } } // send the content m_writer->write_no_copy(file_content_ptr, m_file_bytes_to_send); if (m_bytes_sent + m_file_bytes_to_send >= m_disk_file.getFileSize()) { // this is the last piece of data to send if (m_bytes_sent > 0) { // send last chunk in a series m_writer->send_final_chunk(boost::bind(&DiskFileSender::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { // sending entire file at once m_writer->send(boost::bind(&DiskFileSender::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } } else { // there will be more data -> send a chunk m_writer->send_chunk(boost::bind(&DiskFileSender::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } } void DiskFileSender::handle_write(const boost::system::error_code& write_error, std::size_t bytes_written) { bool finished_sending = true; if (write_error) { // encountered error sending response data m_writer->get_connection()->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // make sure it will get closed PION_LOG_WARN(m_logger, "Error sending file (" << write_error.message() << ')'); } else { // response data sent OK // use m_file_bytes_to_send instead of bytes_written; bytes_written // includes bytes for HTTP headers and chunking headers m_bytes_sent += m_file_bytes_to_send; if (m_bytes_sent >= m_disk_file.getFileSize()) { // finished sending PION_LOG_DEBUG(m_logger, "Sent " << (m_file_bytes_to_send < m_disk_file.getFileSize() ? "file chunk" : "complete file") << " of " << m_file_bytes_to_send << " bytes (finished" << (m_writer->get_connection()->get_keep_alive() ? ", keeping alive)" : ", closing)") ); } else { // NOT finished sending PION_LOG_DEBUG(m_logger, "Sent file chunk of " << m_file_bytes_to_send << " bytes"); finished_sending = false; m_writer->clear(); } } if (finished_sending) { // connection::finish() calls tcp::server::finish_connection, which will either: // a) call http::server::handle_connection again if keep-alive is true; or, // b) close the socket and remove it from the server's connection pool m_writer->get_connection()->finish(); } else { send(); } } } // end namespace plugins } // end namespace pion /// creates new FileService objects extern "C" PION_PLUGIN pion::plugins::FileService *pion_create_FileService(void) { return new pion::plugins::FileService(); } /// destroys FileService objects extern "C" PION_PLUGIN void pion_destroy_FileService(pion::plugins::FileService *service_ptr) { delete service_ptr; } pion-5.0.7+dfsg.orig/services/LogService.cpp0000644000372000001440000001317512420270445020340 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include "LogService.hpp" #if defined(PION_USE_LOG4CXX) #include #include #elif defined(PION_USE_LOG4CPLUS) #include #include #elif defined(PION_USE_LOG4CPP) #include #endif #include using namespace pion; namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins // static members of LogServiceAppender const unsigned int LogServiceAppender::DEFAULT_MAX_EVENTS = 25; // LogServiceAppender member functions #if defined(PION_USE_LOG4CPP) LogServiceAppender::LogServiceAppender(void) : log4cpp::AppenderSkeleton("LogServiceAppender"), m_max_events(DEFAULT_MAX_EVENTS), m_num_events(0), m_layout_ptr(new log4cpp::BasicLayout()) {} #else LogServiceAppender::LogServiceAppender(void) : m_max_events(DEFAULT_MAX_EVENTS), m_num_events(0) {} #endif LogServiceAppender::~LogServiceAppender() { #if defined(PION_USE_LOG4CPLUS) destructorImpl(); #endif } #if defined(PION_USE_LOG4CXX) void LogServiceAppender::append(const log4cxx::spi::LoggingEventPtr& event) { // custom layouts is not supported for log4cxx library std::string formatted_string(boost::lexical_cast(event->getTimeStamp())); formatted_string += ' '; formatted_string += event->getLevel()->toString(); formatted_string += ' '; formatted_string += event->getLoggerName(); formatted_string += " - "; formatted_string += event->getRenderedMessage(); formatted_string += '\n'; addLogString(formatted_string); } #elif defined(PION_USE_LOG4CPLUS) void LogServiceAppender::append(const log4cplus::spi::InternalLoggingEvent& event) { // custom layouts is not supported for log4cplus library std::string formatted_string(boost::lexical_cast(event.getTimestamp().sec())); formatted_string += ' '; formatted_string += m_log_level_manager.toString(event.getLogLevel()); formatted_string += ' '; formatted_string += event.getLoggerName(); formatted_string += " - "; formatted_string += event.getMessage(); formatted_string += '\n'; addLogString(formatted_string); } #elif defined(PION_USE_LOG4CPP) void LogServiceAppender::_append(const log4cpp::LoggingEvent& event) { std::string formatted_string(m_layout_ptr->format(event)); addLogString(formatted_string); } #endif void LogServiceAppender::addLogString(const std::string& log_string) { boost::mutex::scoped_lock log_lock(m_log_mutex); m_log_events.push_back(log_string); ++m_num_events; while (m_num_events > m_max_events) { m_log_events.erase(m_log_events.begin()); --m_num_events; } } void LogServiceAppender::writeLogEvents(pion::http::response_writer_ptr& writer) { #if defined(PION_USE_LOG4CXX) || defined(PION_USE_LOG4CPLUS) || defined(PION_USE_LOG4CPP) boost::mutex::scoped_lock log_lock(m_log_mutex); for (std::list::const_iterator i = m_log_events.begin(); i != m_log_events.end(); ++i) { writer << *i; } #elif defined(PION_DISABLE_LOGGING) writer << "Logging is disabled." << http::types::STRING_CRLF; #else writer << "Using ostream logging." << http::types::STRING_CRLF; #endif } // LogService member functions LogService::LogService(void) : m_log_appender_ptr(new LogServiceAppender()) { #if defined(PION_USE_LOG4CXX) m_log_appender_ptr->setName("LogServiceAppender"); log4cxx::Logger::getRootLogger()->addAppender(m_log_appender_ptr); #elif defined(PION_USE_LOG4CPLUS) m_log_appender_ptr->setName("LogServiceAppender"); log4cplus::Logger::getRoot().addAppender(m_log_appender_ptr); #elif defined(PION_USE_LOG4CPP) log4cpp::Category::getRoot().addAppender(m_log_appender_ptr); #endif } LogService::~LogService() { #if defined(PION_USE_LOG4CXX) // removeAppender() also deletes the object log4cxx::Logger::getRootLogger()->removeAppender(m_log_appender_ptr); #elif defined(PION_USE_LOG4CPLUS) // removeAppender() also deletes the object log4cplus::Logger::getRoot().removeAppender("LogServiceAppender"); #elif defined(PION_USE_LOG4CPP) // removeAppender() also deletes the object log4cpp::Category::getRoot().removeAppender(m_log_appender_ptr); #else delete m_log_appender_ptr; #endif } /// handles requests for LogService void LogService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // Set Content-type to "text/plain" (plain ascii text) http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_content_type(http::types::CONTENT_TYPE_TEXT); getLogAppender().writeLogEvents(writer); writer->send(); } } // end namespace plugins } // end namespace pion /// creates new LogService objects extern "C" PION_PLUGIN pion::plugins::LogService *pion_create_LogService(void) { return new pion::plugins::LogService(); } /// destroys LogService objects extern "C" PION_PLUGIN void pion_destroy_LogService(pion::plugins::LogService *service_ptr) { delete service_ptr; } pion-5.0.7+dfsg.orig/services/EchoService.cpp0000644000372000001440000001271212420270445020471 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include "EchoService.hpp" #include #include #include #include using namespace pion; namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// used by handle_request to write dictionary terms void writeDictionaryTerm(http::response_writer_ptr& writer, const ihash_multimap::value_type& val) { // text is copied into writer text cache writer << val.first << http::types::HEADER_NAME_VALUE_DELIMITER << val.second << http::types::STRING_CRLF; } // EchoService member functions /// handles requests for EchoService void EchoService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // this web service uses static text to test the mixture of "copied" with // "static" (no-copy) text static const std::string REQUEST_ECHO_TEXT("[Request Echo]"); static const std::string REQUEST_HEADERS_TEXT("[Request Headers]"); static const std::string QUERY_PARAMS_TEXT("[Query Parameters]"); static const std::string COOKIE_PARAMS_TEXT("[Cookie Parameters]"); static const std::string POST_CONTENT_TEXT("[POST Content]"); static const std::string USER_INFO_TEXT("[USER Info]"); // Set Content-type to "text/plain" (plain ascii text) http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_content_type(http::types::CONTENT_TYPE_TEXT); // write request information writer->write_no_copy(REQUEST_ECHO_TEXT); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); writer << "Request method: " << http_request_ptr->get_method() << http::types::STRING_CRLF << "Resource originally requested: " << http_request_ptr->get_original_resource() << http::types::STRING_CRLF << "Resource delivered: " << http_request_ptr->get_resource() << http::types::STRING_CRLF << "Query string: " << http_request_ptr->get_query_string() << http::types::STRING_CRLF << "HTTP version: " << http_request_ptr->get_version_major() << '.' << http_request_ptr->get_version_minor() << http::types::STRING_CRLF << "Content length: " << (unsigned long)http_request_ptr->get_content_length() << http::types::STRING_CRLF << http::types::STRING_CRLF; // write request headers writer->write_no_copy(REQUEST_HEADERS_TEXT); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); std::for_each(http_request_ptr->get_headers().begin(), http_request_ptr->get_headers().end(), boost::bind(&writeDictionaryTerm, writer, _1)); writer->write_no_copy(http::types::STRING_CRLF); // write query parameters writer->write_no_copy(QUERY_PARAMS_TEXT); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); std::for_each(http_request_ptr->get_queries().begin(), http_request_ptr->get_queries().end(), boost::bind(&writeDictionaryTerm, writer, _1)); writer->write_no_copy(http::types::STRING_CRLF); // write cookie parameters writer->write_no_copy(COOKIE_PARAMS_TEXT); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); std::for_each(http_request_ptr->get_cookies().begin(), http_request_ptr->get_cookies().end(), boost::bind(&writeDictionaryTerm, writer, _1)); writer->write_no_copy(http::types::STRING_CRLF); // write POST content writer->write_no_copy(POST_CONTENT_TEXT); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); if (http_request_ptr->get_content_length() != 0) { writer->write(http_request_ptr->get_content(), http_request_ptr->get_content_length()); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); } // if authenticated, write user info user_ptr user = http_request_ptr->get_user(); if (user) { writer->write_no_copy(USER_INFO_TEXT); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); writer << "User authenticated, username: " << user->get_username(); writer->write_no_copy(http::types::STRING_CRLF); } // send the writer writer->send(); } } // end namespace plugins } // end namespace pion /// creates new EchoService objects extern "C" PION_PLUGIN pion::plugins::EchoService *pion_create_EchoService(void) { return new pion::plugins::EchoService(); } /// destroys EchoService objects extern "C" PION_PLUGIN void pion_destroy_EchoService(pion::plugins::EchoService *service_ptr) { delete service_ptr; } pion-5.0.7+dfsg.orig/services/HelloService.cpp0000644000372000001440000000312512420270445020654 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include "HelloService.hpp" #include using namespace pion; namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins // HelloService member functions /// handles requests for HelloService void HelloService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string HELLO_HTML = "Hello World!"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->write_no_copy(HELLO_HTML); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); writer->send(); } } // end namespace plugins } // end namespace pion /// creates new HelloService objects extern "C" PION_PLUGIN pion::plugins::HelloService *pion_create_HelloService(void) { return new pion::plugins::HelloService(); } /// destroys HelloService objects extern "C" PION_PLUGIN void pion_destroy_HelloService(pion::plugins::HelloService *service_ptr) { delete service_ptr; } pion-5.0.7+dfsg.orig/services/FileService.vcxproj.filters0000644000372000001440000000203212420270445023044 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Header Files pion-5.0.7+dfsg.orig/services/CookieService.vcxproj.filters0000644000372000001440000000203612420270445023402 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Header Files pion-5.0.7+dfsg.orig/services/HelloService.vcxproj.filters0000644000372000001440000000203412420270445023232 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Header Files pion-5.0.7+dfsg.orig/services/AllowNothingService.vcxproj0000644000372000001440000003301412420270445023127 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {8C8A8E46-4588-4CE1-B624-89C36EA5209E} AllowNothingService Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset X64 ProgramDatabase X64 MultiThreadedDLL ALLOWNOTHINGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 ALLOWNOTHINGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 ALLOWNOTHINGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 ALLOWNOTHINGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false MachineX64 MultiThreadedDLL {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/services/CookieService.vcxproj0000644000372000001440000003274212420270445021742 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {1CF012D8-A47C-4D2B-952D-D90D19795A07} CookieService Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset X64 ProgramDatabase X64 MultiThreadedDLL COOKIESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 COOKIESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 COOKIESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 COOKIESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false MachineX64 MultiThreadedDLL {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/services/FileService.hpp0000644000372000001440000003214312420270445020477 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_FILESERVICE_HEADER__ #define __PION_FILESERVICE_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// /// DiskFile: class used to represent files stored on disk /// class DiskFile { public: /// default constructor DiskFile(void) : m_file_size(0), m_last_modified(0) {} /// used to construct new disk file objects DiskFile(const boost::filesystem::path& path, char *content, unsigned long size, std::time_t modified, const std::string& mime) : m_file_path(path), m_file_content(content), m_file_size(size), m_last_modified(modified), m_mime_type(mime) {} /// copy constructor DiskFile(const DiskFile& f) : m_file_path(f.m_file_path), m_file_content(f.m_file_content), m_file_size(f.m_file_size), m_last_modified(f.m_last_modified), m_last_modified_string(f.m_last_modified_string), m_mime_type(f.m_mime_type) {} /// updates the file_size and last_modified timestamp to disk void update(void); /// reads content from disk into file_content buffer (may throw) void read(void); /** * checks if the file has been updated and updates vars if it has (may throw) * * @return true if the file was updated */ bool checkUpdated(void); /// return path to the cached file inline const boost::filesystem::path& getFilePath(void) const { return m_file_path; } /// returns content of the cached file inline char *getFileContent(void) { return m_file_content.get(); } /// returns true if there is cached file content inline bool hasFileContent(void) const { return static_cast(m_file_content); } /// returns size of the file's content inline unsigned long getFileSize(void) const { return m_file_size; } /// returns timestamp that the cached file was last modified (0 = cache disabled) inline std::time_t getLastModified(void) const { return m_last_modified; } /// returns timestamp that the cached file was last modified (string format) inline const std::string& getLastModifiedString(void) const { return m_last_modified_string; } /// returns mime type for the cached file inline const std::string& getMimeType(void) const { return m_mime_type; } /// sets the path to the cached file inline void setFilePath(const boost::filesystem::path& p) { m_file_path = p; } /// appends to the path of the cached file inline void appendFilePath(const std::string& p) { m_file_path /= p; } /// sets the mime type for the cached file inline void setMimeType(const std::string& t) { m_mime_type = t; } /// resets the size of the file content buffer inline void resetFileContent(unsigned long n = 0) { if (n == 0) m_file_content.reset(); else m_file_content.reset(new char[n]); } protected: /// path to the cached file boost::filesystem::path m_file_path; /// content of the cached file boost::shared_array m_file_content; /// size of the file's content std::streamsize m_file_size; /// timestamp that the cached file was last modified (0 = cache disabled) std::time_t m_last_modified; /// timestamp that the cached file was last modified (string format) std::string m_last_modified_string; /// mime type for the cached file std::string m_mime_type; }; /// /// DiskFileSender: class used to send files to clients using HTTP responses /// class DiskFileSender : public boost::enable_shared_from_this, private boost::noncopyable { public: /** * creates new DiskFileSender objects * * @param file disk file object that should be sent * @param http_request_ptr HTTP request that we are responding to * @param tcp_conn TCP connection used to send the file * @param max_chunk_size sets the maximum chunk size (default=0, unlimited) */ static inline boost::shared_ptr create(DiskFile& file, pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn, unsigned long max_chunk_size = 0) { return boost::shared_ptr(new DiskFileSender(file, http_request_ptr, tcp_conn, max_chunk_size)); } /// default virtual destructor virtual ~DiskFileSender() {} /// Begins sending the file to the client. Following a call to this /// function, it is not thread safe to use your reference to the /// DiskFileSender object. void send(void); /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// returns the logger currently in use inline logger get_logger(void) { return m_logger; } protected: /** * protected constructor restricts creation of objects (use create()) * * @param file disk file object that should be sent * @param http_request_ptr HTTP request that we are responding to * @param tcp_conn TCP connection used to send the file * @param max_chunk_size sets the maximum chunk size */ DiskFileSender(DiskFile& file, pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn, unsigned long max_chunk_size); /** * handler called after a send operation has completed * * @param write_error error status from the last write operation * @param bytes_written number of bytes sent by the last write operation */ void handle_write(const boost::system::error_code& write_error, std::size_t bytes_written); /// primary logging interface used by this class logger m_logger; private: /// the disk file we are sending DiskFile m_disk_file; /// the HTTP response we are sending pion::http::response_writer_ptr m_writer; /// used to read the file from disk if it is not already cached in memory boost::filesystem::ifstream m_file_stream; /// buffer used to send file content boost::shared_array m_content_buf; /** * maximum chunk size (in bytes): files larger than this size will be * delivered to clients using HTTP chunked responses. A value of * zero means that the size is unlimited (chunking is disabled). */ unsigned long m_max_chunk_size; /// the number of file bytes send in the last operation unsigned long m_file_bytes_to_send; /// the number of bytes we have sent so far unsigned long m_bytes_sent; }; /// data type for a DiskFileSender pointer typedef boost::shared_ptr DiskFileSenderPtr; /// /// FileService: web service that serves regular files /// class FileService : public pion::http::plugin_service { public: // default constructor and destructor FileService(void); virtual ~FileService() {} /** * configuration options supported by FileService: * * directory: all files within the directory will be made available * file: * cache: * scan: * max_chunk_size: * writable: */ virtual void set_option(const std::string& name, const std::string& value); /// handles requests for FileService virtual void operator()(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); /// called when the web service's server is starting virtual void start(void); /// called when the web service's server is stopping virtual void stop(void); /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// returns the logger currently in use inline logger get_logger(void) { return m_logger; } protected: /// data type for map of file names to cache entries typedef PION_HASH_MAP CacheMap; /// data type for map of file extensions to MIME types typedef PION_HASH_MAP MIMETypeMap; /** * adds all files within a directory to the cache * * @param dir_path the directory to scan (sub-directories are included) */ void scanDirectory(const boost::filesystem::path& dir_path); /** * adds a single file to the cache * * @param relative_path path for the file relative to the root directory * @param file_path actual path to the file on disk * @param placeholder if true, the file's contents are not cached * * @return std::pair if an entry is added to the * cache, second will be true and first will point to the new entry */ std::pair addCacheEntry(const std::string& relative_path, const boost::filesystem::path& file_path, const bool placeholder); /** * searches for a MIME type that matches a file * * @param file_name name of the file to search for * @return MIME type corresponding with the file, or DEFAULT_MIME_TYPE if none found */ static std::string findMIMEType(const std::string& file_name); void sendNotFoundResponse(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); /// primary logging interface used by this class logger m_logger; private: /// function called once to initialize the map of MIME types static void createMIMETypes(void); /// mime type used if no others are found for the file's extension static const std::string DEFAULT_MIME_TYPE; /// default setting for cache configuration option static const unsigned int DEFAULT_CACHE_SETTING; /// default setting for scan configuration option static const unsigned int DEFAULT_SCAN_SETTING; /// default setting for the maximum cache size option static const unsigned long DEFAULT_MAX_CACHE_SIZE; /// default setting for the maximum chunk size option static const unsigned long DEFAULT_MAX_CHUNK_SIZE; /// flag used to make sure that createMIMETypes() is called only once static boost::once_flag m_mime_types_init_flag; /// map of file extensions to MIME types static MIMETypeMap * m_mime_types_ptr; /// directory containing files that will be made available boost::filesystem::path m_directory; /// single file served by the web service boost::filesystem::path m_file; /// used to cache file contents and metadata in memory CacheMap m_cache_map; /// mutex used to make the file cache thread-safe boost::mutex m_cache_mutex; /** * cache configuration setting: * 0 = do not cache files in memory * 1 = cache files in memory when requested, check for any updates * 2 = cache files in memory when requested, ignore any updates */ unsigned int m_cache_setting; /** * scan configuration setting (only applies to directories): * 0 = do not scan the directory; allow files to be added at any time * 1 = scan directory when started, and do not allow files to be added * 2 = scan directory and pre-populate cache; allow new files * 3 = scan directory and pre-populate cache; ignore new files */ unsigned int m_scan_setting; /** * maximum cache size (in bytes): files larger than this size will never be * cached in memory. A value of zero means that the size is unlimited. */ unsigned long m_max_cache_size; /** * maximum chunk size (in bytes): files larger than this size will be * delivered to clients using HTTP chunked responses. A value of * zero means that the size is unlimited (chunking is disabled). */ unsigned long m_max_chunk_size; /** * Whether the file and/or directory served are writable. */ bool m_writable; }; } // end namespace plugins } // end namespace pion #endif pion-5.0.7+dfsg.orig/services/AllowNothingService.vcxproj.filters0000644000372000001440000000205212420270445024574 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Header Files pion-5.0.7+dfsg.orig/services/CMakeLists.txt0000644000372000001440000000232112420270445020321 0ustar robertousers# --------------------------------------------------------------------- # pion: a Boost C++ framework for building lightweight HTTP interfaces # --------------------------------------------------------------------- # Copyright (C) 2013 Splunk Inc. (https://github.com/splunk/pion) # # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt # --------------------------------------------------------------------- cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR) set(PROJECT_NAME services) project(${PROJECT_NAME} CXX) # get all *.cpp files from src to build target file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp) # build targets from each file foreach(_file ${SRC_FILES}) get_filename_component(_prj_name ${_file} NAME_WE) string(TOUPPER ${_prj_name} _prj_name_upper) message("BUILD_${_prj_name_upper} = ${BUILD_${_prj_name_upper}}") if (BUILD_${_prj_name_upper}) add_library(${_prj_name} MODULE ${_file}) target_link_libraries(${_prj_name} pion) install(TARGETS ${_prj_name} RUNTIME DESTINATION services LIBRARY DESTINATION services ARCHIVE DESTINATION services ) endif() endforeach() pion-5.0.7+dfsg.orig/services/FileService.vcxproj0000644000372000001440000003272412420270445021410 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {70CA1FA9-BA9A-4EA4-9B7B-C747238991C1} FileService Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset X64 ProgramDatabase X64 MultiThreadedDLL FILESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 FILESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 FILESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 FILESERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false MachineX64 MultiThreadedDLL {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/services/EchoService.hpp0000644000372000001440000000201412420270445020470 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_ECHOSERVICE_HEADER__ #define __PION_ECHOSERVICE_HEADER__ #include namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// /// EchoService: web service that echos back requests (to test request parsing) /// class EchoService : public pion::http::plugin_service { public: EchoService(void) {} virtual ~EchoService() {} virtual void operator()(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); }; } // end namespace plugins } // end namespace pion #endif pion-5.0.7+dfsg.orig/services/AllowNothingService.cpp0000644000372000001440000000407312420270445022221 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include "AllowNothingService.hpp" #include #include using namespace pion; namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins void AllowNothingService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string DENY_HTML = "No, you can't."; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_METHOD_NOT_ALLOWED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED); // This is a legitimate header, but it crashes when it's sent. //writer->get_response().add_header("Allow", ""); // Use this line to demonstrate that it's the empty header value that's causing the problem. writer->get_response().add_header("Allow", "GET"); writer->write_no_copy(DENY_HTML); writer->write_no_copy(http::types::STRING_CRLF); writer->write_no_copy(http::types::STRING_CRLF); writer->send(); } } // end namespace plugins } // end namespace pion /// creates new AllowNothingService objects extern "C" PION_PLUGIN pion::plugins::AllowNothingService *pion_create_AllowNothingService(void) { return new pion::plugins::AllowNothingService(); } /// destroys AllowNothingService objects extern "C" PION_PLUGIN void pion_destroy_AllowNothingService(pion::plugins::AllowNothingService *service_ptr) { delete service_ptr; } pion-5.0.7+dfsg.orig/services/HelloService.vcxproj0000644000372000001440000003273312420270445021574 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {9EE2433A-B460-45E0-8968-EC5CE8EF9875} HelloService Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset X64 ProgramDatabase X64 MultiThreadedDLL HELLOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 HELLOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 HELLOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 HELLOSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false MachineX64 MultiThreadedDLL {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/services/Makefile.am0000644000372000001440000000415412420270445017623 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- AM_CPPFLAGS = -I../include pion_pluginsdir = @PION_PLUGINS_DIRECTORY@ pion_plugins_LTLIBRARIES = HelloService.la EchoService.la \ CookieService.la LogService.la FileService.la AllowNothingService.la HelloService_la_CXXFLAGS = -shared $(AM_CXXFLAGS) HelloService_la_SOURCES = HelloService.hpp HelloService.cpp HelloService_la_LDFLAGS = -no-undefined -module -avoid-version HelloService_la_LIBADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ HelloService_la_DEPENDENCIES = ../src/libpion.la EchoService_la_CXXFLAGS = -shared $(AM_CXXFLAGS) EchoService_la_SOURCES = EchoService.hpp EchoService.cpp EchoService_la_LDFLAGS = -no-undefined -module -avoid-version EchoService_la_LIBADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ EchoService_la_DEPENDENCIES = ../src/libpion.la CookieService_la_CXXFLAGS = -shared $(AM_CXXFLAGS) CookieService_la_SOURCES = CookieService.hpp CookieService.cpp CookieService_la_LDFLAGS = -no-undefined -module -avoid-version CookieService_la_LIBADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ CookieService_la_DEPENDENCIES = ../src/libpion.la LogService_la_CXXFLAGS = -shared $(AM_CXXFLAGS) LogService_la_SOURCES = LogService.hpp LogService.cpp LogService_la_LDFLAGS = -no-undefined -module -avoid-version LogService_la_LIBADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ LogService_la_DEPENDENCIES = ../src/libpion.la # Build both dynamic and static library for FileService #FileService_la_CXXFLAGS = -shared $(AM_CXXFLAGS) FileService_la_SOURCES = FileService.hpp FileService.cpp FileService_la_LDFLAGS = -no-undefined -module -avoid-version FileService_la_LIBADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ FileService_la_DEPENDENCIES = ../src/libpion.la AllowNothingService_la_CXXFLAGS = -shared $(AM_CXXFLAGS) AllowNothingService_la_SOURCES = AllowNothingService.hpp AllowNothingService.cpp AllowNothingService_la_LDFLAGS = -no-undefined -module -avoid-version AllowNothingService_la_LIBADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ AllowNothingService_la_DEPENDENCIES = ../src/libpion.la EXTRA_DIST = *.vcxproj *.vcxproj.filters pion-5.0.7+dfsg.orig/services/LogService.vcxproj0000644000372000001440000003271512420270445021252 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {12F95FE7-ACE1-4281-86BF-4117AE2D633E} LogService Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset X64 ProgramDatabase X64 MultiThreadedDLL LOGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 LOGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 LOGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false X64 LOGSERVICE_EXPORTS;PION_FULL;%(PreprocessorDefinitions) false MachineX64 MultiThreadedDLL {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/services/AllowNothingService.hpp0000644000372000001440000000223112420270445022220 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_ALLOW_NOTHING_SERVICE_HEADER__ #define __PION_ALLOW_NOTHING_SERVICE_HEADER__ #include namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// /// This class has a corresponding create function (pion_create_AllowNothingService) and /// destroy function (pion_destroy_AllowNothingService), as required for use by plugin. /// class AllowNothingService : public pion::http::plugin_service { public: AllowNothingService(void) {} ~AllowNothingService() {} virtual void operator()(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); }; } // end namespace plugins } // end namespace pion #endif pion-5.0.7+dfsg.orig/services/CookieService.hpp0000644000372000001440000000201312420270445021022 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_COOKIESERVICE_HEADER__ #define __PION_COOKIESERVICE_HEADER__ #include namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// /// CookieService: web service that displays and updates cookies /// class CookieService : public pion::http::plugin_service { public: CookieService(void) {} virtual ~CookieService() {} virtual void operator()(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); }; } // end namespace plugins } // end namespace pion #endif pion-5.0.7+dfsg.orig/services/EchoService.vcxproj.filters0000644000372000001440000000203212420270445023043 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Header Files pion-5.0.7+dfsg.orig/services/LogService.hpp0000644000372000001440000001152212420270445020337 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_LOGSERVICE_HEADER__ #define __PION_LOGSERVICE_HEADER__ #include #include #include #include #include #include #include #if defined(PION_USE_LOG4CXX) #include // version 0.10.x introduces a new data type that is declared in a // pool.h header file. If we're using 0.9.x, just declare the type // as an int since it is not being used at all #ifndef _LOG4CXX_HELPERS_POOL_H namespace log4cxx { namespace helpers { typedef int Pool; } } #endif #endif namespace pion { // begin namespace pion namespace plugins { // begin namespace plugins /// /// LogServiceAppender: caches log events in memory for use by LogService /// class LogServiceAppender #ifdef PION_HAS_LOG_APPENDER : public log_appender #endif { public: // default constructor and destructor LogServiceAppender(void); virtual ~LogServiceAppender(); /// sets the maximum number of log events cached in memory inline void setMaxEvents(unsigned int n) { m_max_events = n; } /// adds a formatted log message to the memory cache void addLogString(const std::string& log_string); /// writes the events cached in memory to a response stream void writeLogEvents(pion::http::response_writer_ptr& writer); private: /// default maximum number of events cached in memory static const unsigned int DEFAULT_MAX_EVENTS; /// maxiumum number of events cached in memory unsigned int m_max_events; /// number of events currently cached in memory unsigned int m_num_events; /// memory cache of pre-formatted log events std::list m_log_events; /// mutex to make class thread-safe boost::mutex m_log_mutex; #if defined(PION_USE_LOG4CXX) public: // member functions inherited from the Appender interface class virtual void close() {} virtual bool requiresLayout() const { return false; } protected: /// adds log event to the memory cache virtual void append(const log4cxx::spi::LoggingEventPtr& event); // version 0.10.x adds a second "pool" argument -> just ignore it virtual void append(const log4cxx::spi::LoggingEventPtr& event, log4cxx::helpers::Pool& pool) { append(event); } #elif defined(PION_USE_LOG4CPLUS) public: // member functions inherited from the Appender interface class virtual void close() {} protected: virtual void append(const log4cplus::spi::InternalLoggingEvent& event); private: /// this is used to convert numeric log levels into strings log4cplus::LogLevelManager m_log_level_manager; #elif defined(PION_USE_LOG4CPP) public: // member functions inherited from the AppenderSkeleton class virtual void close() {} virtual bool requiresLayout() const { return true; } virtual void setLayout(log4cpp::Layout* layout) { m_layout_ptr.reset(layout); } protected: /// adds log event to the memory cache virtual void _append(const log4cpp::LoggingEvent& event); private: /// the logging layout used to format events boost::scoped_ptr m_layout_ptr; #endif }; /// /// LogService: web service that displays log messages /// class LogService : public pion::http::plugin_service { public: // default constructor and destructor LogService(void); virtual ~LogService(); /// handles a new HTTP request virtual void operator()(pion::http::request_ptr& http_request_ptr, pion::tcp::connection_ptr& tcp_conn); /// returns the log appender used by LogService inline LogServiceAppender& getLogAppender(void) { #ifdef PION_HAS_LOG_APPENDER return dynamic_cast(*m_log_appender_ptr); #else return *m_log_appender_ptr; #endif } private: /// this is used to keep track of log messages #ifdef PION_HAS_LOG_APPENDER log_appender_ptr m_log_appender_ptr; #else LogServiceAppender * m_log_appender_ptr; #endif }; } // end namespace plugins } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/0000755000372000001440000000000012420270445015363 5ustar robertouserspion-5.0.7+dfsg.orig/include/pion/0000755000372000001440000000000012420270445016330 5ustar robertouserspion-5.0.7+dfsg.orig/include/pion/admin_rights.hpp0000644000372000001440000000517412420270445021520 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_ADMIN_RIGHTS_HEADER__ #define __PION_ADMIN_RIGHTS_HEADER__ #include #include #include #include namespace pion { // begin namespace pion /// /// admin_rights: obtains administrative rights for the process /// class PION_API admin_rights { public: /** * constructs object, obtaining administrative rights; will block * if another thread has already obtained rights * * @param use_log if false, then no logging will be performed */ admin_rights(bool use_log = true); /// destructor releases administrative rights virtual ~admin_rights() { release(); } /// releases administrative rights void release(void); /// calculates the user id based upon the user configuration parameter static long run_as_user(const std::string& user_name); /// calculates the group id based upon the group configuration parameter static long run_as_group(const std::string& group_name); private: /** * finds an identifier within a system credentials file (users or groups) * * @param name descriptive name to lookup (user or group name, may be id) * @param file system credentials file to look within * * @return boost::int32_t identifier found, or -1 if none found */ static long find_system_id(const std::string& name, const std::string& file); /// adminisitrator or root user identifier static const boost::int16_t ADMIN_USER_ID; /// mutex used to prevent multiple threads from corrupting user id static boost::mutex m_mutex; /// primary logging interface used by this class logger m_logger; /// lock used to prevent multiple threads from corrupting user id boost::unique_lock m_lock; /// saved user identifier before upgrading to administrator boost::int16_t m_user_id; /// true if the class currently holds administrative rights bool m_has_rights; /// if false, then no logging will be performed bool m_use_log; }; } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/config.hpp.xcode0000644000372000001440000000505612420270445021415 0ustar robertousers/* common/include/pion/PionConfig.hpp. Generated from PionConfig.hpp.in by configure. */ // --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PIONCONFIG_HEADER__ #define __PION_PIONCONFIG_HEADER__ // DO NOT USE autoheader ; this file is not automanaged!!! /* Define to the version number of pion. */ #define PION_VERSION "5.0.7" /* Define to the directory where Pion plug-ins are installed. */ #define PION_PLUGINS_DIRECTORY "/usr/local/lib/pion/plugins" /* Define to the directory where cygwin is installed. */ #define PION_CYGWIN_DIRECTORY "" /* Define to 1 if C library supports malloc_trim() */ #undef PION_HAVE_MALLOC_TRIM // ----------------------------------------------------------------------- // hash_map support // // At least one of the following options should be defined. /* Define to 1 if you have the header file. */ /* #undef PION_HAVE_EXT_HASH_MAP 1 */ /* Define to 1 if you have the header file. */ /* #undef PION_HAVE_HASH_MAP */ /* Define to 1 if you have the header file. */ #define PION_HAVE_TR1_UNORDERED_MAP /* Define to 1 if you have the header file. */ /* #undef PION_HAVE_UNORDERED_MAP */ // ----------------------------------------------------------------------- // Logging Options // // At most one of the logging options below should be defined. If none of // them are defined, std::cout and std::cerr will be used for logging. /* Define to 1 to use the `log4cplus' library (-llog4cplus) for logging. */ #define PION_USE_LOG4CPLUS 1 /* Define to 1 to use the `log4cxx' library (-llog4cxx) for logging. */ /* #undef PION_USE_LOG4CXX */ /* Define to 1 to use the `log4cpp' library (-llog4cpp) for logging. */ /* #undef PION_USE_LOG4CPP */ /* Define to 1 to disable logging. */ /* #undef PION_DISABLE_LOGGING */ // ----------------------------------------------------------------------- /* Define to 1 if you have the `zlib' library. */ #define PION_HAVE_ZLIB 1 /* Define to 1 if you have the `bzlib' library. */ #define PION_HAVE_BZLIB 1 /* Define to 1 if you have the `OpenSSL' library. */ #define PION_HAVE_SSL 1 /* This is used by Windows projects to flag exported symbols */ #define PION_API #define PION_PLUGIN #endif pion-5.0.7+dfsg.orig/include/pion/logger.hpp0000644000372000001440000002756712420270445020341 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_LOGGER_HEADER__ #define __PION_LOGGER_HEADER__ #include #if defined(PION_USE_LOG4CXX) // unfortunately, the current version of log4cxx has many problems that // produce very annoying warnings // log4cxx headers #include #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation #endif #include #include #ifdef _MSC_VER #pragma warning(pop) #endif #if defined _MSC_VER #if defined _DEBUG #pragma comment(lib, "log4cxxd") #else #pragma comment(lib, "log4cxx") #endif #pragma comment(lib, "odbc32") #endif namespace pion { typedef log4cxx::LoggerPtr logger; typedef log4cxx::AppenderSkeleton log_appender; typedef log_appender * log_appender_ptr; } #define PION_HAS_LOG_APPENDER 1 #define PION_LOG_CONFIG_BASIC log4cxx::BasicConfigurator::configure(); #define PION_LOG_CONFIG(FILE) log4cxx::PropertyConfigurator::configure(FILE); #define PION_GET_LOGGER(NAME) log4cxx::Logger::get_logger(NAME) #define PION_SHUTDOWN_LOGGER log4cxx::LogManager::shutdown(); #define PION_LOG_SETLEVEL_DEBUG(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::DEBUG_INT)); #define PION_LOG_SETLEVEL_INFO(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::INFO_INT)); #define PION_LOG_SETLEVEL_WARN(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::WARN_INT)); #define PION_LOG_SETLEVEL_ERROR(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::ERROR_INT)); #define PION_LOG_SETLEVEL_FATAL(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::FATAL_INT)); #define PION_LOG_SETLEVEL_UP(LOG) LOG->setLevel(LOG->getLevel()->toInt()+1); #define PION_LOG_SETLEVEL_DOWN(LOG) LOG->setLevel(LOG->getLevel()->toInt()-1); #define PION_LOG_DEBUG LOG4CXX_DEBUG #define PION_LOG_INFO LOG4CXX_INFO #define PION_LOG_WARN LOG4CXX_WARN #define PION_LOG_ERROR LOG4CXX_ERROR #define PION_LOG_FATAL LOG4CXX_FATAL #elif defined(PION_USE_LOG4CPLUS) // log4cplus headers #include #include #include #include #include #include #include #include #if defined(_MSC_VER) && !defined(PION_CMAKE_BUILD) #if defined _DEBUG #if defined PION_STATIC_LINKING #pragma comment(lib, "log4cplusSD") #else #pragma comment(lib, "log4cplusD") #endif #else #if defined PION_STATIC_LINKING #pragma comment(lib, "log4cplusS") #else #pragma comment(lib, "log4cplus") #endif #endif #endif namespace pion { typedef log4cplus::Logger logger; typedef log4cplus::Appender log_appender; typedef log4cplus::SharedAppenderPtr log_appender_ptr; /// /// circular_buffer_appender: caches log events in a circular buffer /// class circular_buffer_appender : public log4cplus::Appender { public: typedef boost::circular_buffer LogEventBuffer; // default constructor and destructor circular_buffer_appender(void) : m_log_events(1000) {}; virtual ~circular_buffer_appender() { destructorImpl(); } /// returns an iterator to the log events in the buffer const LogEventBuffer& getLogIterator() const { return m_log_events; } public: // member functions inherited from the Appender interface class virtual void close() {} protected: virtual void append(const log4cplus::spi::InternalLoggingEvent& event) { boost::mutex::scoped_lock log_lock(m_log_mutex); m_log_events.push_back(*event.clone()); } private: /// circular buffer for log events LogEventBuffer m_log_events; /// mutex to make class thread-safe boost::mutex m_log_mutex; }; } #define PION_HAS_LOG_APPENDER 1 #define PION_LOG_CONFIG_BASIC log4cplus::BasicConfigurator::doConfigure(); #define PION_LOG_CONFIG(FILE) log4cplus::PropertyConfigurator::doConfigure(FILE); #define PION_GET_LOGGER(NAME) log4cplus::Logger::getInstance(NAME) #define PION_SHUTDOWN_LOGGER log4cplus::Logger::shutdown(); #define PION_LOG_SETLEVEL_DEBUG(LOG) LOG.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); #define PION_LOG_SETLEVEL_INFO(LOG) LOG.setLogLevel(log4cplus::INFO_LOG_LEVEL); #define PION_LOG_SETLEVEL_WARN(LOG) LOG.setLogLevel(log4cplus::WARN_LOG_LEVEL); #define PION_LOG_SETLEVEL_ERROR(LOG) LOG.setLogLevel(log4cplus::ERROR_LOG_LEVEL); #define PION_LOG_SETLEVEL_FATAL(LOG) LOG.setLogLevel(log4cplus::FATAL_LOG_LEVEL); #define PION_LOG_SETLEVEL_UP(LOG) LOG.setLogLevel(LOG.getLogLevel()+1); #define PION_LOG_SETLEVEL_DOWN(LOG) LOG.setLogLevel(LOG.getLogLevel()-1); #define PION_LOG_DEBUG LOG4CPLUS_DEBUG #define PION_LOG_INFO LOG4CPLUS_INFO #define PION_LOG_WARN LOG4CPLUS_WARN #define PION_LOG_ERROR LOG4CPLUS_ERROR #define PION_LOG_FATAL LOG4CPLUS_FATAL #elif defined(PION_USE_LOG4CPP) // log4cpp headers #include #include #include #include namespace pion { typedef log4cpp::Category* logger; typedef log4cpp::AppenderSkeleton log_appender; typedef log_appender * log_appender_ptr; } #define PION_HAS_LOG_APPENDER 1 #define PION_LOG_CONFIG_BASIC { log4cpp::OstreamAppender *app = new log4cpp::OstreamAppender("cout", &std::cout); app->setLayout(new log4cpp::BasicLayout()); log4cpp::Category::getRoot().setAppender(app); } #define PION_LOG_CONFIG(FILE) { log4cpp::PropertyConfigurator::configure(FILE); } #define PION_GET_LOGGER(NAME) (&log4cpp::Category::getInstance(NAME)) #define PION_SHUTDOWN_LOGGER log4cpp::Category::shutdown(); #define PION_LOG_SETLEVEL_DEBUG(LOG) { LOG->setPriority(log4cpp::Priority::DEBUG); } #define PION_LOG_SETLEVEL_INFO(LOG) { LOG->setPriority(log4cpp::Priority::INFO); } #define PION_LOG_SETLEVEL_WARN(LOG) { LOG->setPriority(log4cpp::Priority::WARN); } #define PION_LOG_SETLEVEL_ERROR(LOG) { LOG->setPriority(log4cpp::Priority::ERROR); } #define PION_LOG_SETLEVEL_FATAL(LOG) { LOG->setPriority(log4cpp::Priority::FATAL); } #define PION_LOG_SETLEVEL_UP(LOG) { LOG->setPriority(LOG.getPriority()+1); } #define PION_LOG_SETLEVEL_DOWN(LOG) { LOG->setPriority(LOG.getPriority()-1); } #define PION_LOG_DEBUG(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::DEBUG) { LOG->debugStream() << MSG; } #define PION_LOG_INFO(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::INFO) { LOG->infoStream() << MSG; } #define PION_LOG_WARN(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::WARN) { LOG->warnStream() << MSG; } #define PION_LOG_ERROR(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::ERROR) { LOG->errorStream() << MSG; } #define PION_LOG_FATAL(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::FATAL) { LOG->fatalStream() << MSG; } #elif defined(PION_DISABLE_LOGGING) // Logging is disabled -> add do-nothing stubs for logging namespace pion { struct PION_API logger { logger(int /* glog */) {} operator bool() const { return false; } static void shutdown() {} }; typedef int log_appender; typedef log_appender * log_appender_ptr; } #undef PION_HAS_LOG_APPENDER #define PION_LOG_CONFIG_BASIC {} #define PION_LOG_CONFIG(FILE) {} #define PION_GET_LOGGER(NAME) 0 #define PION_SHUTDOWN_LOGGER 0 // use LOG to avoid warnings about LOG not being used #define PION_LOG_SETLEVEL_DEBUG(LOG) { if (LOG) {} } #define PION_LOG_SETLEVEL_INFO(LOG) { if (LOG) {} } #define PION_LOG_SETLEVEL_WARN(LOG) { if (LOG) {} } #define PION_LOG_SETLEVEL_ERROR(LOG) { if (LOG) {} } #define PION_LOG_SETLEVEL_FATAL(LOG) { if (LOG) {} } #define PION_LOG_SETLEVEL_UP(LOG) { if (LOG) {} } #define PION_LOG_SETLEVEL_DOWN(LOG) { if (LOG) {} } #define PION_LOG_DEBUG(LOG, MSG) { if (LOG) {} } #define PION_LOG_INFO(LOG, MSG) { if (LOG) {} } #define PION_LOG_WARN(LOG, MSG) { if (LOG) {} } #define PION_LOG_ERROR(LOG, MSG) { if (LOG) {} } #define PION_LOG_FATAL(LOG, MSG) { if (LOG) {} } #else #define PION_USE_OSTREAM_LOGGING // Logging uses std::cout and std::cerr #include #include #include namespace pion { struct PION_API logger { enum log_priority_type { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARN, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL }; ~logger() {} logger(void) : m_name("pion") {} logger(const std::string& name) : m_name(name) {} logger(const logger& p) : m_name(p.m_name) {} static void shutdown() {} std::string m_name; static log_priority_type m_priority; }; typedef int log_appender; typedef log_appender * log_appender_ptr; } #undef PION_HAS_LOG_APPENDER #define PION_LOG_CONFIG_BASIC {} #define PION_LOG_CONFIG(FILE) {} #define PION_GET_LOGGER(NAME) pion::logger(NAME) #define PION_SHUTDOWN_LOGGER {} #define PION_LOG_SETLEVEL_DEBUG(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_DEBUG; } #define PION_LOG_SETLEVEL_INFO(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_INFO; } #define PION_LOG_SETLEVEL_WARN(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_WARN; } #define PION_LOG_SETLEVEL_ERROR(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_ERROR; } #define PION_LOG_SETLEVEL_FATAL(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_FATAL; } #define PION_LOG_SETLEVEL_UP(LOG) { ++LOG.m_priority; } #define PION_LOG_SETLEVEL_DOWN(LOG) { --LOG.m_priority; } #define PION_LOG_DEBUG(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_DEBUG) { std::cout << time(NULL) << " DEBUG " << LOG.m_name << ' ' << MSG << std::endl; } #define PION_LOG_INFO(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_INFO) { std::cout << time(NULL) << " INFO " << LOG.m_name << ' ' << MSG << std::endl; } #define PION_LOG_WARN(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_WARN) { std::cerr << time(NULL) << " WARN " << LOG.m_name << ' ' << MSG << std::endl; } #define PION_LOG_ERROR(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_ERROR) { std::cerr << time(NULL) << " ERROR " << LOG.m_name << ' ' << MSG << std::endl; } #define PION_LOG_FATAL(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_FATAL) { std::cerr << time(NULL) << " FATAL " << LOG.m_name << ' ' << MSG << std::endl; } #endif #endif pion-5.0.7+dfsg.orig/include/pion/config.hpp.in0000644000372000001440000000456412420270445020724 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PIONCONFIG_HEADER__ #define __PION_PIONCONFIG_HEADER__ // DO NOT USE autoheader ; this file is not automanaged!!! /* Define to the version number of pion. */ #undef PION_VERSION /* Define to the directory where Pion plug-ins are installed. */ #undef PION_PLUGINS_DIRECTORY /* Define to the directory where cygwin is installed. */ #undef PION_CYGWIN_DIRECTORY /* Define to 1 if C library supports malloc_trim() */ #undef PION_HAVE_MALLOC_TRIM // ----------------------------------------------------------------------- // hash_map support // // At least one of the following options should be defined. /* Define to 1 if you have the header file. */ #undef PION_HAVE_EXT_HASH_MAP /* Define to 1 if you have the header file. */ #undef PION_HAVE_HASH_MAP /* Define to 1 if you have the header file. */ #undef PION_HAVE_TR1_UNORDERED_MAP /* Define to 1 if you have the header file. */ #undef PION_HAVE_UNORDERED_MAP // ----------------------------------------------------------------------- // Logging Options // // At most one of the logging options below should be defined. If none of // them are defined, std::cout and std::cerr will be used for logging. /* Define to 1 to use the `log4cplus' library (-llog4cplus) for logging. */ #undef PION_USE_LOG4CPLUS /* Define to 1 to use the `log4cxx' library (-llog4cxx) for logging. */ #undef PION_USE_LOG4CXX /* Define to 1 to use the `log4cpp' library (-llog4cpp) for logging. */ #undef PION_USE_LOG4CPP /* Define to 1 to disable logging. */ #undef PION_DISABLE_LOGGING // ----------------------------------------------------------------------- /* Define to 1 if you have the `zlib' library. */ #undef PION_HAVE_ZLIB /* Define to 1 if you have the `bzlib' library. */ #undef PION_HAVE_BZLIB /* Define to 1 if you have the `OpenSSL' library. */ #undef PION_HAVE_SSL /* This is used by Windows projects to flag exported symbols */ #define PION_API #define PION_PLUGIN #endif pion-5.0.7+dfsg.orig/include/pion/http/0000755000372000001440000000000012420270445017307 5ustar robertouserspion-5.0.7+dfsg.orig/include/pion/http/message.hpp0000644000372000001440000006477112420270445021463 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_MESSAGE_HEADER__ #define __PION_HTTP_MESSAGE_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #ifndef BOOST_SYSTEM_NOEXCEPT // if 'BOOST_NOEXCEPT' is not defined, as with some older versions of // boost, setting it to nothing should be harmless. #ifndef BOOST_NOEXCEPT #define BOOST_SYSTEM_NOEXCEPT #else #define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT #endif #endif namespace pion { // begin namespace pion namespace tcp { // forward declaration for class used by send() and receive() class connection; } namespace http { // begin namespace http // forward declaration of parser class class parser; /// /// message: base container for HTTP messages /// class PION_API message : public http::types { public: /// data type for I/O write buffers (these wrap existing data to be sent) typedef std::vector write_buffers_t; /// used to cache chunked data typedef std::vector chunk_cache_t; /// data type for library errors returned during receive() operations struct receive_error_t : public boost::system::error_category { virtual ~receive_error_t() {} virtual inline const char *name() const BOOST_SYSTEM_NOEXCEPT { return "receive_error_t"; } virtual inline std::string message(int ev) const { std::string result; switch(ev) { case 1: result = "HTTP message parsing error"; break; default: result = "Unknown receive error"; break; } return result; } }; /// defines message data integrity status codes enum data_status_t { STATUS_NONE, // no data received (i.e. all lost) STATUS_TRUNCATED, // one or more missing packets at the end STATUS_PARTIAL, // one or more missing packets but NOT at the end STATUS_OK // no missing packets }; /// constructs a new HTTP message object message(void) : m_is_valid(false), m_is_chunked(false), m_chunks_supported(false), m_do_not_send_content_length(false), m_version_major(1), m_version_minor(1), m_content_length(0), m_content_buf(), m_status(STATUS_NONE), m_has_missing_packets(false), m_has_data_after_missing(false) {} /// copy constructor message(const message& http_msg) : m_first_line(http_msg.m_first_line), m_is_valid(http_msg.m_is_valid), m_is_chunked(http_msg.m_is_chunked), m_chunks_supported(http_msg.m_chunks_supported), m_do_not_send_content_length(http_msg.m_do_not_send_content_length), m_remote_ip(http_msg.m_remote_ip), m_version_major(http_msg.m_version_major), m_version_minor(http_msg.m_version_minor), m_content_length(http_msg.m_content_length), m_content_buf(http_msg.m_content_buf), m_chunk_cache(http_msg.m_chunk_cache), m_headers(http_msg.m_headers), m_status(http_msg.m_status), m_has_missing_packets(http_msg.m_has_missing_packets), m_has_data_after_missing(http_msg.m_has_data_after_missing) {} /// assignment operator inline message& operator=(const message& http_msg) { m_first_line = http_msg.m_first_line; m_is_valid = http_msg.m_is_valid; m_is_chunked = http_msg.m_is_chunked; m_chunks_supported = http_msg.m_chunks_supported; m_do_not_send_content_length = http_msg.m_do_not_send_content_length; m_remote_ip = http_msg.m_remote_ip; m_version_major = http_msg.m_version_major; m_version_minor = http_msg.m_version_minor; m_content_length = http_msg.m_content_length; m_content_buf = http_msg.m_content_buf; m_chunk_cache = http_msg.m_chunk_cache; m_headers = http_msg.m_headers; m_status = http_msg.m_status; m_has_missing_packets = http_msg.m_has_missing_packets; m_has_data_after_missing = http_msg.m_has_data_after_missing; return *this; } /// virtual destructor virtual ~message() {} /// clears all message data virtual void clear(void) { clear_first_line(); m_is_valid = m_is_chunked = m_chunks_supported = m_do_not_send_content_length = false; m_remote_ip = boost::asio::ip::address_v4(0); m_version_major = m_version_minor = 1; m_content_length = 0; m_content_buf.clear(); m_chunk_cache.clear(); m_headers.clear(); m_cookie_params.clear(); m_status = STATUS_NONE; m_has_missing_packets = false; m_has_data_after_missing = false; } /// should return true if the content length can be implied without headers virtual bool is_content_length_implied(void) const = 0; /// returns true if the message is valid inline bool is_valid(void) const { return m_is_valid; } /// returns true if chunked transfer encodings are supported inline bool get_chunks_supported(void) const { return m_chunks_supported; } /// returns IP address of the remote endpoint inline boost::asio::ip::address& get_remote_ip(void) { return m_remote_ip; } /// returns the major HTTP version number inline boost::uint16_t get_version_major(void) const { return m_version_major; } /// returns the minor HTTP version number inline boost::uint16_t get_version_minor(void) const { return m_version_minor; } /// returns a string representation of the HTTP version (i.e. "HTTP/1.1") inline std::string get_version_string(void) const { std::string http_version(STRING_HTTP_VERSION); http_version += boost::lexical_cast(get_version_major()); http_version += '.'; http_version += boost::lexical_cast(get_version_minor()); return http_version; } /// returns the length of the payload content (in bytes) inline size_t get_content_length(void) const { return m_content_length; } /// returns true if the message content is chunked inline bool is_chunked(void) const { return m_is_chunked; } /// returns true if buffer for content is allocated bool is_content_buffer_allocated() const { return !m_content_buf.is_empty(); } /// returns size of allocated buffer inline std::size_t get_content_buffer_size() const { return m_content_buf.size(); } /// returns a pointer to the payload content, or empty string if there is none inline char *get_content(void) { return m_content_buf.get(); } /// returns a const pointer to the payload content, or empty string if there is none inline const char *get_content(void) const { return m_content_buf.get(); } /// returns a reference to the chunk cache inline chunk_cache_t& get_chunk_cache(void) { return m_chunk_cache; } /// returns a value for the header if any are defined; otherwise, an empty string inline const std::string& get_header(const std::string& key) const { return get_value(m_headers, key); } /// returns a reference to the HTTP headers inline ihash_multimap& get_headers(void) { return m_headers; } /// returns true if at least one value for the header is defined inline bool has_header(const std::string& key) const { return(m_headers.find(key) != m_headers.end()); } /// returns a value for the cookie if any are defined; otherwise, an empty string /// since cookie names are insensitive, key should use lowercase alpha chars inline const std::string& get_cookie(const std::string& key) const { return get_value(m_cookie_params, key); } /// returns the cookie parameters inline ihash_multimap& get_cookies(void) { return m_cookie_params; } /// returns true if at least one value for the cookie is defined /// since cookie names are insensitive, key should use lowercase alpha chars inline bool has_cookie(const std::string& key) const { return(m_cookie_params.find(key) != m_cookie_params.end()); } /// adds a value for the cookie /// since cookie names are insensitive, key should use lowercase alpha chars inline void add_cookie(const std::string& key, const std::string& value) { m_cookie_params.insert(std::make_pair(key, value)); } /// changes the value of a cookie /// since cookie names are insensitive, key should use lowercase alpha chars inline void change_cookie(const std::string& key, const std::string& value) { change_value(m_cookie_params, key, value); } /// removes all values for a cookie /// since cookie names are insensitive, key should use lowercase alpha chars inline void delete_cookie(const std::string& key) { delete_value(m_cookie_params, key); } /// returns a string containing the first line for the HTTP message inline const std::string& get_first_line(void) const { if (m_first_line.empty()) update_first_line(); return m_first_line; } /// true if there were missing packets inline bool has_missing_packets() const { return m_has_missing_packets; } /// set to true when missing packets detected inline void set_missing_packets(bool newVal) { m_has_missing_packets = newVal; } /// true if more data seen after the missing packets inline bool has_data_after_missing_packets() const { return m_has_data_after_missing; } inline void set_data_after_missing_packet(bool newVal) { m_has_data_after_missing = newVal; } /// sets whether or not the message is valid inline void set_is_valid(bool b = true) { m_is_valid = b; } /// set to true if chunked transfer encodings are supported inline void set_chunks_supported(bool b) { m_chunks_supported = b; } /// sets IP address of the remote endpoint inline void set_remote_ip(const boost::asio::ip::address& ip) { m_remote_ip = ip; } /// sets the major HTTP version number inline void set_version_major(const boost::uint16_t n) { m_version_major = n; clear_first_line(); } /// sets the minor HTTP version number inline void set_version_minor(const boost::uint16_t n) { m_version_minor = n; clear_first_line(); } /// sets the length of the payload content (in bytes) inline void set_content_length(size_t n) { m_content_length = n; } /// if called, the content-length will not be sent in the HTTP headers inline void set_do_not_send_content_length(void) { m_do_not_send_content_length = true; } /// return the data receival status inline data_status_t get_status() const { return m_status; } /// inline void set_status(data_status_t newVal) { m_status = newVal; } /// sets the length of the payload content using the Content-Length header inline void update_content_length_using_header(void) { ihash_multimap::const_iterator i = m_headers.find(HEADER_CONTENT_LENGTH); if (i == m_headers.end()) { m_content_length = 0; } else { std::string trimmed_length(i->second); boost::algorithm::trim(trimmed_length); m_content_length = boost::lexical_cast(trimmed_length); } } /// sets the transfer coding using the Transfer-Encoding header inline void update_transfer_encoding_using_header(void) { m_is_chunked = false; ihash_multimap::const_iterator i = m_headers.find(HEADER_TRANSFER_ENCODING); if (i != m_headers.end()) { // From RFC 2616, sec 3.6: All transfer-coding values are case-insensitive. m_is_chunked = boost::regex_match(i->second, REGEX_ICASE_CHUNKED); // ignoring other possible values for now } } ///creates a payload content buffer of size m_content_length and returns /// a pointer to the new buffer (memory is managed by message class) inline char *create_content_buffer(void) { m_content_buf.resize(m_content_length); return m_content_buf.get(); } /// resets payload content to match the value of a string inline void set_content(const std::string& content) { set_content_length(content.size()); create_content_buffer(); memcpy(m_content_buf.get(), content.c_str(), content.size()); } /// clears payload content buffer inline void clear_content(void) { set_content_length(0); create_content_buffer(); delete_value(m_headers, HEADER_CONTENT_TYPE); } /// sets the content type for the message payload inline void set_content_type(const std::string& type) { change_value(m_headers, HEADER_CONTENT_TYPE, type); } /// adds a value for the HTTP header named key inline void add_header(const std::string& key, const std::string& value) { m_headers.insert(std::make_pair(key, value)); } /// changes the value for the HTTP header named key inline void change_header(const std::string& key, const std::string& value) { change_value(m_headers, key, value); } /// removes all values for the HTTP header named key inline void delete_header(const std::string& key) { delete_value(m_headers, key); } /// returns true if the HTTP connection may be kept alive inline bool check_keep_alive(void) const { return (get_header(HEADER_CONNECTION) != "close" && (get_version_major() > 1 || (get_version_major() >= 1 && get_version_minor() >= 1)) ); } /** * initializes a vector of write buffers with the HTTP message information * * @param write_buffers vector of write buffers to initialize * @param keep_alive true if the connection should be kept alive * @param using_chunks true if the payload content will be sent in chunks */ inline void prepare_buffers_for_send(write_buffers_t& write_buffers, const bool keep_alive, const bool using_chunks) { // update message headers prepare_headers_for_send(keep_alive, using_chunks); // add first message line write_buffers.push_back(boost::asio::buffer(get_first_line())); write_buffers.push_back(boost::asio::buffer(STRING_CRLF)); // append cookie headers (if any) append_cookie_headers(); // append HTTP headers append_headers(write_buffers); } /** * sends the message over a TCP connection (blocks until finished) * * @param tcp_conn TCP connection to use * @param ec contains error code if the send fails * @param headers_only if true then only HTTP headers are sent * * @return std::size_t number of bytes written to the connection */ std::size_t send(tcp::connection& tcp_conn, boost::system::error_code& ec, bool headers_only = false); /** * receives a new message from a TCP connection (blocks until finished) * * @param tcp_conn TCP connection to use * @param ec contains error code if the receive fails * @param http_parser http parser object to use * * @return std::size_t number of bytes read from the connection */ std::size_t receive(tcp::connection& tcp_conn, boost::system::error_code& ec, parser& http_parser); /** * receives a new message from a TCP connection (blocks until finished) * * @param tcp_conn TCP connection to use * @param ec contains error code if the receive fails * @param headers_only if true then only HTTP headers are received * @param max_content_length maximum number of content bytes received * * @return std::size_t number of bytes read from the connection */ std::size_t receive(tcp::connection& tcp_conn, boost::system::error_code& ec, bool headers_only = false, std::size_t max_content_length = static_cast(-1)); /** * writes the message to a std::ostream (blocks until finished) * * @param out std::ostream to use * @param ec contains error code if the write fails * @param headers_only if true then only HTTP headers are written * * @return std::size_t number of bytes written to the connection */ std::size_t write(std::ostream& out, boost::system::error_code& ec, bool headers_only = false); /** * reads a new message from a std::istream (blocks until finished) * * @param in std::istream to use * @param ec contains error code if the read fails * @param http_parser http parser object to use * * @return std::size_t number of bytes read from the connection */ std::size_t read(std::istream& in, boost::system::error_code& ec, parser& http_parser); /** * reads a new message from a std::istream (blocks until finished) * * @param in std::istream to use * @param ec contains error code if the read fails * @param headers_only if true then only HTTP headers are read * @param max_content_length maximum number of content bytes received * * @return std::size_t number of bytes read from the connection */ std::size_t read(std::istream& in, boost::system::error_code& ec, bool headers_only = false, std::size_t max_content_length = static_cast(-1)); /** * pieces together all the received chunks */ void concatenate_chunks(void); protected: /// a simple helper class used to manage a fixed-size payload content buffer class content_buffer_t { public: /// simple destructor ~content_buffer_t() {} /// default constructor content_buffer_t() : m_buf(), m_len(0), m_empty(0), m_ptr(&m_empty) {} /// copy constructor content_buffer_t(const content_buffer_t& buf) : m_buf(), m_len(0), m_empty(0), m_ptr(&m_empty) { if (buf.size()) { resize(buf.size()); memcpy(get(), buf.get(), buf.size()); } } /// assignment operator content_buffer_t& operator=(const content_buffer_t& buf) { if (buf.size()) { resize(buf.size()); memcpy(get(), buf.get(), buf.size()); } else { clear(); } return *this; } /// returns true if buffer is empty inline bool is_empty() const { return m_len == 0; } /// returns size in bytes inline std::size_t size() const { return m_len; } /// returns const pointer to data inline const char *get() const { return m_ptr; } /// returns mutable pointer to data inline char *get() { return m_ptr; } /// changes the size of the content buffer inline void resize(std::size_t len) { m_len = len; if (len == 0) { m_buf.reset(); m_ptr = &m_empty; } else { m_buf.reset(new char[len+1]); m_buf[len] = '\0'; m_ptr = m_buf.get(); } } /// clears the content buffer inline void clear() { resize(0); } private: boost::scoped_array m_buf; std::size_t m_len; char m_empty; char *m_ptr; }; /** * prepares HTTP headers for a send operation * * @param keep_alive true if the connection should be kept alive * @param using_chunks true if the payload content will be sent in chunks */ inline void prepare_headers_for_send(const bool keep_alive, const bool using_chunks) { change_header(HEADER_CONNECTION, (keep_alive ? "Keep-Alive" : "close") ); if (using_chunks) { if (get_chunks_supported()) change_header(HEADER_TRANSFER_ENCODING, "chunked"); } else if (! m_do_not_send_content_length) { change_header(HEADER_CONTENT_LENGTH, boost::lexical_cast(get_content_length())); } } /** * appends the message's HTTP headers to a vector of write buffers * * @param write_buffers the buffers to append HTTP headers into */ inline void append_headers(write_buffers_t& write_buffers) { // add HTTP headers for (ihash_multimap::const_iterator i = m_headers.begin(); i != m_headers.end(); ++i) { write_buffers.push_back(boost::asio::buffer(i->first)); write_buffers.push_back(boost::asio::buffer(HEADER_NAME_VALUE_DELIMITER)); write_buffers.push_back(boost::asio::buffer(i->second)); write_buffers.push_back(boost::asio::buffer(STRING_CRLF)); } // add an extra CRLF to end HTTP headers write_buffers.push_back(boost::asio::buffer(STRING_CRLF)); } /// appends HTTP headers for any cookies defined by the http::message virtual void append_cookie_headers(void) {} /** * Returns the first value in a dictionary if key is found; or an empty * string if no values are found * * @param dict the dictionary to search for key * @param key the key to search for * @return value if found; empty string if not */ template inline static const std::string& get_value(const DictionaryType& dict, const std::string& key) { typename DictionaryType::const_iterator i = dict.find(key); return ( (i==dict.end()) ? STRING_EMPTY : i->second ); } /** * Changes the value for a dictionary key. Adds the key if it does not * already exist. If multiple values exist for the key, they will be * removed and only the new value will remain. * * @param dict the dictionary object to update * @param key the key to change the value for * @param value the value to assign to the key */ template inline static void change_value(DictionaryType& dict, const std::string& key, const std::string& value) { // retrieve all current values for key std::pair result_pair = dict.equal_range(key); if (result_pair.first == dict.end()) { // no values exist -> add a new key dict.insert(std::make_pair(key, value)); } else { // set the first value found for the key to the new one result_pair.first->second = value; // remove any remaining values typename DictionaryType::iterator i; ++(result_pair.first); while (result_pair.first != result_pair.second) { i = result_pair.first; ++(result_pair.first); dict.erase(i); } } } /** * Deletes all values for a key * * @param dict the dictionary object to update * @param key the key to delete */ template inline static void delete_value(DictionaryType& dict, const std::string& key) { std::pair result_pair = dict.equal_range(key); if (result_pair.first != dict.end()) dict.erase(result_pair.first, result_pair.second); } /// erases the string containing the first line for the HTTP message /// (it will be updated the next time get_first_line() is called) inline void clear_first_line(void) const { if (! m_first_line.empty()) m_first_line.clear(); } /// updates the string containing the first line for the HTTP message virtual void update_first_line(void) const = 0; /// first line sent in an HTTP message /// (i.e. "GET / HTTP/1.1" for request, or "HTTP/1.1 200 OK" for response) mutable std::string m_first_line; private: /// Regex used to check for the "chunked" transfer encoding header static const boost::regex REGEX_ICASE_CHUNKED; /// True if the HTTP message is valid bool m_is_valid; /// whether the message body is chunked bool m_is_chunked; /// true if chunked transfer encodings are supported bool m_chunks_supported; /// if true, the content length will not be sent in the HTTP headers bool m_do_not_send_content_length; /// IP address of the remote endpoint boost::asio::ip::address m_remote_ip; /// HTTP major version number boost::uint16_t m_version_major; /// HTTP major version number boost::uint16_t m_version_minor; /// the length of the payload content (in bytes) size_t m_content_length; /// the payload content, if any was sent with the message content_buffer_t m_content_buf; /// buffers for holding chunked data chunk_cache_t m_chunk_cache; /// HTTP message headers ihash_multimap m_headers; /// HTTP cookie parameters parsed from the headers ihash_multimap m_cookie_params; /// message data integrity status data_status_t m_status; /// missing packet indicator bool m_has_missing_packets; /// indicates missing packets in the middle of the data stream bool m_has_data_after_missing; }; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/request_reader.hpp0000644000372000001440000001022512420270445023032 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_REQUEST_READER_HEADER__ #define __PION_HTTP_REQUEST_READER_HEADER__ #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// request_reader: asynchronously reads and parses HTTP requests /// class request_reader : public http::reader, public boost::enable_shared_from_this { public: /// function called after the HTTP message has been parsed typedef boost::function3 finished_handler_t; // default destructor virtual ~request_reader() {} /** * creates new request_reader objects * * @param tcp_conn TCP connection containing a new message to parse * @param handler function called after the message has been parsed */ static inline boost::shared_ptr create(tcp::connection_ptr& tcp_conn, finished_handler_t handler) { return boost::shared_ptr (new request_reader(tcp_conn, handler)); } /// sets a function to be called after HTTP headers have been parsed inline void set_headers_parsed_callback(finished_handler_t& h) { m_parsed_headers = h; } protected: /** * protected constructor restricts creation of objects (use create()) * * @param tcp_conn TCP connection containing a new message to parse * @param handler function called after the message has been parsed */ request_reader(tcp::connection_ptr& tcp_conn, finished_handler_t handler) : http::reader(true, tcp_conn), m_http_msg(new http::request), m_finished(handler) { m_http_msg->set_remote_ip(tcp_conn->get_remote_ip()); set_logger(PION_GET_LOGGER("pion.http.request_reader")); } /// Reads more bytes from the TCP connection virtual void read_bytes(void) { get_connection()->async_read_some(boost::bind(&request_reader::consume_bytes, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } /// Called after we have finished parsing the HTTP message headers virtual void finished_parsing_headers(const boost::system::error_code& ec) { // call the finished headers handler with the HTTP message if (m_parsed_headers) m_parsed_headers(m_http_msg, get_connection(), ec); } /// Called after we have finished reading/parsing the HTTP message virtual void finished_reading(const boost::system::error_code& ec) { // call the finished handler with the finished HTTP message if (m_finished) m_finished(m_http_msg, get_connection(), ec); } /// Returns a reference to the HTTP message being parsed virtual http::message& get_message(void) { return *m_http_msg; } /// The new HTTP message container being created http::request_ptr m_http_msg; /// function called after the HTTP message has been parsed finished_handler_t m_finished; /// function called after the HTTP message headers have been parsed finished_handler_t m_parsed_headers; }; /// data type for a request_reader pointer typedef boost::shared_ptr request_reader_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/basic_auth.hpp0000644000372000001440000000654312420270445022132 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_BASIC_AUTH_HEADER__ #define __PION_HTTP_BASIC_AUTH_HEADER__ #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// basic_auth: a base class for handling HTTP Authentication and session management /// in accordance with RFC 2617 http://tools.ietf.org/html/rfc2617 /// class PION_API basic_auth : public http::auth { public: /// default constructor basic_auth(user_manager_ptr userManager, const std::string& realm="PION"); /// virtual destructor virtual ~basic_auth() {} /** * attempts to validate authentication of a new HTTP request. * If request valid, pointer to user identity object (if any) will be preserved in * the request and return "true". * If request not authenticated, appropriate response is sent over tcp_conn * and return "false"; * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * * @return true if request valid and user identity inserted into request */ virtual bool handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * sets a configuration option * Valid options: * - "domain" - name of authentication domain * * @param name the name of the option to change * @param value the value of the option */ virtual void set_option(const std::string& name, const std::string& value); protected: /** * used to send responses when access to resource is not authorized * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ void handle_unauthorized(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * extracts base64 user credentials from authorization string * * @param authorization value of the HEADER_AUTHORIZATION */ static bool parse_authorization(std::string const &authorization, std::string &credentials); /** * parse base64 credentials and extract username/password */ static bool parse_credentials(std::string const &credentials, std::string &username, std::string &password); private: /// number of seconds after which entires in the user cache will be expired static const unsigned int CACHE_EXPIRATION; /// authentication realm ( "PION" by default) std::string m_realm; /// time of the last cache clean up boost::posix_time::ptime m_cache_cleanup_time; /// cache of users that are currently active user_cache_type m_user_cache; /// mutex used to protect access to the user cache mutable boost::mutex m_cache_mutex; }; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/response.hpp0000644000372000001440000002102612420270445021657 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_RESPONSE_HEADER__ #define __PION_HTTP_RESPONSE_HEADER__ #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// response: container for HTTP response information /// class response : public http::message { public: /** * constructs a new response object for a particular request * * @param http_request_ptr the request that this is responding to */ response(const http::request& http_request_ptr) : m_status_code(RESPONSE_CODE_OK), m_status_message(RESPONSE_MESSAGE_OK) { update_request_info(http_request_ptr); } /** * constructs a new response object for a particular request method * * @param request_method the method used by the HTTP request we are responding to */ response(const std::string& request_method) : m_status_code(RESPONSE_CODE_OK), m_status_message(RESPONSE_MESSAGE_OK), m_request_method(request_method) {} /// copy constructor response(const response& http_response) : message(http_response), m_status_code(http_response.m_status_code), m_status_message(http_response.m_status_message), m_request_method(http_response.m_request_method) {} /// default constructor: you are strongly encouraged to use one of the other /// constructors, since response parsing is influenced by the request method response(void) : m_status_code(RESPONSE_CODE_OK), m_status_message(RESPONSE_MESSAGE_OK) {} /// virtual destructor virtual ~response() {} /// clears all response data virtual void clear(void) { http::message::clear(); m_status_code = RESPONSE_CODE_OK; m_status_message = RESPONSE_MESSAGE_OK; m_request_method.clear(); } /// the content length may be implied for certain types of responses virtual bool is_content_length_implied(void) const { return (m_request_method == REQUEST_METHOD_HEAD // HEAD responses have no content || (m_status_code >= 100 && m_status_code <= 199) // 1xx responses have no content || m_status_code == 204 || m_status_code == 205 // no content & reset content responses || m_status_code == 304 // not modified responses have no content ); } /** * Updates HTTP request information for the response object (use * this if the response cannot be constructed using the request) * * @param http_request the request that this is responding to */ inline void update_request_info(const http::request& http_request) { m_request_method = http_request.get_method(); if (http_request.get_version_major() == 1 && http_request.get_version_minor() >= 1) { set_chunks_supported(true); } else if (http_request.get_version_major() == 0) { // the request is likely HTTP 0.9 "simple-request", so expect the response to contain no header and no version info set_status_code(0U); set_status_message(""); set_version_major(0); set_version_minor(0); } } /// sets the HTTP response status code inline void set_status_code(unsigned int n) { m_status_code = n; clear_first_line(); } /// sets the HTTP response status message inline void set_status_message(const std::string& msg) { m_status_message = msg; clear_first_line(); } /// returns the HTTP response status code inline unsigned int get_status_code(void) const { return m_status_code; } /// returns the HTTP response status message inline const std::string& get_status_message(void) const { return m_status_message; } /** * sets a cookie by adding a Set-Cookie header (see RFC 2109) * the cookie will be discarded by the user-agent when it closes * * @param name the name of the cookie * @param value the value of the cookie */ inline void set_cookie(const std::string& name, const std::string& value) { std::string set_cookie_header(make_set_cookie_header(name, value, "/")); add_header(HEADER_SET_COOKIE, set_cookie_header); } /** * sets a cookie by adding a Set-Cookie header (see RFC 2109) * the cookie will be discarded by the user-agent when it closes * * @param name the name of the cookie * @param value the value of the cookie * @param path the path of the cookie */ inline void set_cookie(const std::string& name, const std::string& value, const std::string& path) { std::string set_cookie_header(make_set_cookie_header(name, value, path)); add_header(HEADER_SET_COOKIE, set_cookie_header); } /** * sets a cookie by adding a Set-Cookie header (see RFC 2109) * * @param name the name of the cookie * @param value the value of the cookie * @param path the path of the cookie * @param max_age the life of the cookie, in seconds (0 = discard) */ inline void set_cookie(const std::string& name, const std::string& value, const std::string& path, const unsigned long max_age) { std::string set_cookie_header(make_set_cookie_header(name, value, path, true, max_age)); add_header(HEADER_SET_COOKIE, set_cookie_header); } /** * sets a cookie by adding a Set-Cookie header (see RFC 2109) * * @param name the name of the cookie * @param value the value of the cookie * @param max_age the life of the cookie, in seconds (0 = discard) */ inline void set_cookie(const std::string& name, const std::string& value, const unsigned long max_age) { std::string set_cookie_header(make_set_cookie_header(name, value, "/", true, max_age)); add_header(HEADER_SET_COOKIE, set_cookie_header); } /// deletes cookie called name by adding a Set-Cookie header (cookie has no path) inline void delete_cookie(const std::string& name) { std::string set_cookie_header(make_set_cookie_header(name, "", "/", true, 0)); add_header(HEADER_SET_COOKIE, set_cookie_header); } /// deletes cookie called name by adding a Set-Cookie header (cookie has a path) inline void delete_cookie(const std::string& name, const std::string& path) { std::string set_cookie_header(make_set_cookie_header(name, "", path, true, 0)); add_header(HEADER_SET_COOKIE, set_cookie_header); } /// sets the time that the response was last modified (Last-Modified) inline void set_last_modified(const unsigned long t) { change_header(HEADER_LAST_MODIFIED, get_date_string(t)); } protected: /// updates the string containing the first line for the HTTP message virtual void update_first_line(void) const { // start out with the HTTP version m_first_line = get_version_string(); m_first_line += ' '; // append the response status code m_first_line += boost::lexical_cast(m_status_code); m_first_line += ' '; // append the response status message m_first_line += m_status_message; } /// appends HTTP headers for any cookies defined by the http::message virtual void append_cookie_headers(void) { for (ihash_multimap::const_iterator i = get_cookies().begin(); i != get_cookies().end(); ++i) { set_cookie(i->first, i->second); } } private: /// The HTTP response status code unsigned int m_status_code; /// The HTTP response status message std::string m_status_message; /// HTTP method used by the request std::string m_request_method; }; /// data type for a HTTP response pointer typedef boost::shared_ptr response_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/plugin_service.hpp0000644000372000001440000000755412420270445023051 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PLUGIN_SERVICE_HEADER__ #define __PION_PLUGIN_SERVICE_HEADER__ #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// plugin_service: interface class for web services /// class plugin_service : private boost::noncopyable { public: /// default constructor plugin_service(void) {} /// virtual destructor virtual ~plugin_service() {} /** * attempts to handle a new HTTP request * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ virtual void operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) = 0; /** * sets a configuration option * * @param name the name of the option to change * @param value the value of the option */ virtual void set_option(const std::string& name, const std::string& value) { BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } /// called when the web service's server is starting virtual void start(void) {} /// called when the web service's server is stopping virtual void stop(void) {} /// sets the URI stem or resource that is bound to the web service inline void set_resource(const std::string& str) { m_resource = str; } /// returns the URI stem or resource that is bound to the web service inline const std::string& get_resource(void) const { return m_resource; } /// returns the path to the resource requested, relative to the web service's location inline std::string get_relative_resource(const std::string& resource_requested) const { if (resource_requested.size() <= get_resource().size()) { // either the request matches the web service's resource path (a directory) // or the request does not match (should never happen) return std::string(); } // strip the web service's resource path plus the slash after it return algorithm::url_decode(resource_requested.substr(get_resource().size() + 1)); } private: /// the URI stem or resource that is bound to the web service std::string m_resource; }; // // The following symbols must be defined for any web service that you would // like to be able to load dynamically using the http::server::load_service() // function. These are not required for any services that you only want to link // directly into your programs. // // Make sure that you replace "MyPluginName" with the name of your derived class. // This name must also match the name of the object file (excluding the // extension). These symbols must be linked into your service's object file, // not included in any headers that it may use (declarations are OK in headers // but not the definitions). // // The "pion_create" function is used to create new instances of your service. // The "pion_destroy" function is used to destroy instances of your service. // // extern "C" MyPluginName *pion_create_MyPluginName(void) { // return new MyPluginName; // } // // extern "C" void pion_destroy_MyPluginName(MyPluginName *service_ptr) { // delete service_ptr; // } // } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/response_writer.hpp0000644000372000001440000001644512420270445023264 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_RESPONSE_WRITER_HEADER__ #define __PION_HTTP_RESPONSE_WRITER_HEADER__ #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// response_writer: used to asynchronously send HTTP responses /// class PION_API response_writer : public http::writer, public boost::enable_shared_from_this { public: /// default destructor virtual ~response_writer() {} /** * creates new response_writer objects * * @param tcp_conn TCP connection used to send the response * @param http_response pointer to the response that will be sent * @param handler function called after the response has been sent * * @return boost::shared_ptr shared pointer to * the new writer object that was created */ static inline boost::shared_ptr create(tcp::connection_ptr& tcp_conn, http::response_ptr& http_response_ptr, finished_handler_t handler = finished_handler_t()) { return boost::shared_ptr(new response_writer(tcp_conn, http_response_ptr, handler)); } /** * creates new response_writer objects * * @param tcp_conn TCP connection used to send the response * @param http_request the request we are responding to * @param handler function called after the request has been sent * * @return boost::shared_ptr shared pointer to * the new writer object that was created */ static inline boost::shared_ptr create(tcp::connection_ptr& tcp_conn, const http::request& http_request, finished_handler_t handler = finished_handler_t()) { return boost::shared_ptr(new response_writer(tcp_conn, http_request, handler)); } /// returns a non-const reference to the response that will be sent inline http::response& get_response(void) { return *m_http_response; } protected: /** * protected constructor restricts creation of objects (use create()) * * @param tcp_conn TCP connection used to send the response * @param http_response pointer to the response that will be sent * @param handler function called after the request has been sent */ response_writer(tcp::connection_ptr& tcp_conn, http::response_ptr& http_response_ptr, finished_handler_t handler) : http::writer(tcp_conn, handler), m_http_response(http_response_ptr) { set_logger(PION_GET_LOGGER("pion.http.response_writer")); // tell the http::writer base class whether or not the client supports chunks supports_chunked_messages(m_http_response->get_chunks_supported()); // check if we should initialize the payload content using // the response's content buffer if (m_http_response->get_content_length() > 0 && m_http_response->get_content() != NULL && m_http_response->get_content()[0] != '\0') { write_no_copy(m_http_response->get_content(), m_http_response->get_content_length()); } } /** * protected constructor restricts creation of objects (use create()) * * @param tcp_conn TCP connection used to send the response * @param http_request the request we are responding to * @param handler function called after the request has been sent */ response_writer(tcp::connection_ptr& tcp_conn, const http::request& http_request, finished_handler_t handler) : http::writer(tcp_conn, handler), m_http_response(new http::response(http_request)) { set_logger(PION_GET_LOGGER("pion.http.response_writer")); // tell the http::writer base class whether or not the client supports chunks supports_chunked_messages(m_http_response->get_chunks_supported()); } /** * initializes a vector of write buffers with the HTTP message information * * @param write_buffers vector of write buffers to initialize */ virtual void prepare_buffers_for_send(http::message::write_buffers_t& write_buffers) { if (get_content_length() > 0) m_http_response->set_content_length(get_content_length()); m_http_response->prepare_buffers_for_send(write_buffers, get_connection()->get_keep_alive(), sending_chunked_message()); } /// returns a function bound to http::writer::handle_write() virtual write_handler_t bind_to_write_handler(void) { return boost::bind(&response_writer::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred); } /** * called after the response is sent * * @param write_error error status from the last write operation * @param bytes_written number of bytes sent by the last write operation */ virtual void handle_write(const boost::system::error_code& write_error, std::size_t bytes_written) { logger log_ptr(get_logger()); if (!write_error) { // response sent OK if (sending_chunked_message()) { PION_LOG_DEBUG(log_ptr, "Sent HTTP response chunk of " << bytes_written << " bytes"); } else { PION_LOG_DEBUG(log_ptr, "Sent HTTP response of " << bytes_written << " bytes (" << (get_connection()->get_keep_alive() ? "keeping alive)" : "closing)")); } } finished_writing(write_error); } private: /// the response that will be sent http::response_ptr m_http_response; /// the initial HTTP response header line std::string m_response_line; }; /// data type for a response_writer pointer typedef boost::shared_ptr response_writer_ptr; /// override operator<< for convenience template const response_writer_ptr& operator<<(const response_writer_ptr& writer, const T& data) { writer->write(data); return writer; } inline response_writer_ptr& operator<<(response_writer_ptr& writer, std::ostream& (*iomanip)(std::ostream&)) { writer->write(iomanip); return writer; } } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/reader.hpp0000644000372000001440000000667312420270445021276 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_READER_HEADER__ #define __PION_HTTP_READER_HEADER__ #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// reader: asynchronously reads and parses HTTP messages /// class PION_API reader : public http::parser { public: // default destructor virtual ~reader() {} /// Incrementally reads & parses the HTTP message void receive(void); /// returns a shared pointer to the TCP connection inline tcp::connection_ptr& get_connection(void) { return m_tcp_conn; } /// sets the maximum number of seconds for read operations inline void set_timeout(boost::uint32_t seconds) { m_read_timeout = seconds; } protected: /** * protected constructor: only derived classes may create objects * * @param is_request if true, the message is parsed as an HTTP request; * if false, the message is parsed as an HTTP response * @param tcp_conn TCP connection containing a new message to parse */ reader(const bool is_request, tcp::connection_ptr& tcp_conn) : http::parser(is_request), m_tcp_conn(tcp_conn), m_read_timeout(DEFAULT_READ_TIMEOUT) {} /** * Consumes bytes that have been read using an HTTP parser * * @param read_error error status from the last read operation * @param bytes_read number of bytes consumed by the last read operation */ void consume_bytes(const boost::system::error_code& read_error, std::size_t bytes_read); /// Consumes bytes that have been read using an HTTP parser void consume_bytes(void); /// Reads more bytes from the TCP connection virtual void read_bytes(void) = 0; /// Called after we have finished reading/parsing the HTTP message virtual void finished_reading(const boost::system::error_code& ec) = 0; /// Returns a reference to the HTTP message being parsed virtual http::message& get_message(void) = 0; private: /// reads more bytes for parsing, with timeout support void read_bytes_with_timeout(void); /** * Handles errors that occur during read operations * * @param read_error error status from the last read operation */ void handle_read_error(const boost::system::error_code& read_error); /// default maximum number of seconds for read operations static const boost::uint32_t DEFAULT_READ_TIMEOUT; /// The HTTP connection that has a new HTTP message to parse tcp::connection_ptr m_tcp_conn; /// pointer to a tcp::timer object if read timeouts are enabled tcp::timer_ptr m_timer_ptr; /// maximum number of seconds for read operations boost::uint32_t m_read_timeout; }; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/cookie_auth.hpp0000644000372000001440000001454612420270445022324 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_COOKIE_AUTH_HEADER__ #define __PION_HTTP_COOKIE_AUTH_HEADER__ #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// cookie_auth: handles HTTP authentication and session management in /// accordance with RFC 2617 (http://tools.ietf.org/html/rfc2617 ) using cookies. /// class PION_API cookie_auth : public http::auth { public: /** * default constructor * * @param userManager * @param login - URL resource for login request. Typical login request has format: * http://website/login?user="username"&pass="password"&url="redirection_url" * @param logout - URL resource for logout request. Typical logout request has format: * http://website/logout?url="redirection_url" * @param redirect - if not empty, URL for redirection in case of authentication failure * if empty - send code 401 on authentication failure */ cookie_auth(user_manager_ptr userManager, const std::string& login="/login", const std::string& logout="/logout", const std::string& redirect=""); /// virtual destructor virtual ~cookie_auth() {} /** * attempts to validate authentication of a new HTTP request. * If request valid, pointer to user identity object (if any) will be preserved in * the request and return "true". * If request not authenticated, appropriate response is sent over tcp_conn * and return "false"; * * Note: if request matches "login" resource, then login sequences attempted. * If "name" and "pass" attributes match user definition, a random cookie is created * and associated with given user session. If request contains "url" attribute, * then page redirection response returned. Otherwise - empty 204 response. * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * * @return true if request valid and user identity inserted into request */ virtual bool handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * sets a configuration option * Valid options: * - "login" - URL resource for login request. Typical login request has format: * http://website/login?user="username"&pass="password"&url="redirection_url" * - "logout" - URL resource for logout request. Typical logout request has format: * http://website/logout?url="redirection_url" * - "redirect" - if not empty, URL for redirection in case of authentication failure * if empty - send code 401 on authentication failure * * @param name the name of the option to change * @param value the value of the option */ virtual void set_option(const std::string& name, const std::string& value); protected: /** * check if given request is a login/logout and process it * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * * @return true if it was a login/logout request and no future processing required. */ bool process_login(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * used to send responses when access to resource is not authorized * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ void handle_unauthorized(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * used to send redirection responses * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ void handle_redirection(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string &redirection_url, const std::string &new_cookie="", bool delete_cookie=false); /** * used to send OK responses with new cookie * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ void handle_ok(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string &new_cookie="", bool delete_cookie=false); /** * Cache expiration cleanup. (Call it periodically) */ void expire_cache(const boost::posix_time::ptime &time_now); private: /// number of seconds after which entries in the user cache will be expired static const unsigned int CACHE_EXPIRATION; /// number of random bytes to use for cookie generation static const unsigned int RANDOM_COOKIE_BYTES; /// name of cookie used for authentication static const std::string AUTH_COOKIE_NAME; /// value of "login" resource std::string m_login; /// value of "logout" resource std::string m_logout; /// value of "redirection" resource std::string m_redirect; /// random number generator used for cookie generation boost::mt19937 m_random_gen; /// random number range used for cookie generation boost::uniform_int<> m_random_range; /// random dice that uses m_random_gen to produce ints within m_random_range boost::variate_generator > m_random_die; /// time of the last cache clean up boost::posix_time::ptime m_cache_cleanup_time; /// cache of users that are currently active user_cache_type m_user_cache; /// mutex used to protect access to the user cache mutable boost::mutex m_cache_mutex; }; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/writer.hpp0000644000372000001440000003356412420270445021347 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_WRITER_HEADER__ #define __PION_HTTP_WRITER_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// writer: used to asynchronously send HTTP messages /// class PION_API writer : private boost::noncopyable { protected: /// function called after the HTTP message has been sent typedef boost::function1 finished_handler_t; /// data type for a function that handles write operations typedef boost::function2 write_handler_t; /** * protected constructor: only derived classes may create objects * * @param tcp_conn TCP connection used to send the message * @param handler function called after the request has been sent */ writer(tcp::connection_ptr& tcp_conn, finished_handler_t handler) : m_logger(PION_GET_LOGGER("pion.http.writer")), m_tcp_conn(tcp_conn), m_content_length(0), m_stream_is_empty(true), m_client_supports_chunks(true), m_sending_chunks(false), m_sent_headers(false), m_finished(handler) {} /** * called after the message is sent * * @param write_error error status from the last write operation * @param bytes_written number of bytes sent by the last write operation */ virtual void handle_write(const boost::system::error_code& write_error, std::size_t bytes_written) = 0; /** * initializes a vector of write buffers with the HTTP message information * * @param write_buffers vector of write buffers to initialize */ virtual void prepare_buffers_for_send(http::message::write_buffers_t& write_buffers) = 0; /// returns a function bound to writer::handle_write() virtual write_handler_t bind_to_write_handler(void) = 0; /// called after we have finished sending the HTTP message inline void finished_writing(const boost::system::error_code& ec) { if (m_finished) m_finished(ec); } public: /// default destructor virtual ~writer() {} /// clears out all of the memory buffers used to cache payload content data inline void clear(void) { m_content_buffers.clear(); m_binary_cache.clear(); m_text_cache.clear(); m_content_stream.str(""); m_stream_is_empty = true; m_content_length = 0; } /** * write text (non-binary) payload content * * @param data the data to append to the payload content */ template inline void write(const T& data) { m_content_stream << data; if (m_stream_is_empty) m_stream_is_empty = false; } inline void write(std::ostream& (*iomanip)(std::ostream&)) { m_content_stream << iomanip; if (m_stream_is_empty) m_stream_is_empty = false; } /** * write binary payload content * * @param data points to the binary data to append to the payload content * @param length the length, in bytes, of the binary data */ inline void write(const void *data, size_t length) { if (length != 0) { flush_content_stream(); m_content_buffers.push_back(m_binary_cache.add(data, length)); m_content_length += length; } } /** * write text (non-binary) payload content; the data written is not * copied, and therefore must persist until the message has finished * sending * * @param data the data to append to the payload content */ inline void write_no_copy(const std::string& data) { if (! data.empty()) { flush_content_stream(); m_content_buffers.push_back(boost::asio::buffer(data)); m_content_length += data.size(); } } /** * write binary payload content; the data written is not copied, and * therefore must persist until the message has finished sending * * @param data points to the binary data to append to the payload content * @param length the length, in bytes, of the binary data */ inline void write_no_copy(void *data, size_t length) { if (length > 0) { flush_content_stream(); m_content_buffers.push_back(boost::asio::buffer(data, length)); m_content_length += length; } } /** * Sends all data buffered as a single HTTP message (without chunking). * Following a call to this function, it is not thread safe to use your * reference to the writer object. */ inline void send(void) { send_more_data(false, bind_to_write_handler()); } /** * Sends all data buffered as a single HTTP message (without chunking). * Following a call to this function, it is not thread safe to use your * reference to the writer object until the send_handler has been called. * * @param send_handler function that is called after the message has been * sent to the client. Your callback function must end * the connection by calling connection::finish(). */ template inline void send(SendHandler send_handler) { send_more_data(false, send_handler); } /** * Sends all data buffered as a single HTTP chunk. Following a call to this * function, it is not thread safe to use your reference to the writer * object until the send_handler has been called. * * @param send_handler function that is called after the chunk has been sent * to the client. Your callback function must end by * calling one of send_chunk() or send_final_chunk(). Also, * be sure to clear() the writer before writing data to it. */ template inline void send_chunk(SendHandler send_handler) { m_sending_chunks = true; if (!supports_chunked_messages()) { // sending data in chunks, but the client does not support chunking; // make sure that the connection will be closed when we are all done m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); } // send more data send_more_data(false, send_handler); } /** * Sends all data buffered (if any) and also sends the final HTTP chunk. * This function (either overloaded version) must be called following any * calls to send_chunk(). * Following a call to this function, it is not thread safe to use your * reference to the writer object until the send_handler has been called. * * @param send_handler function that is called after the message has been * sent to the client. Your callback function must end * the connection by calling connection::finish(). */ template inline void send_final_chunk(SendHandler send_handler) { m_sending_chunks = true; send_more_data(true, send_handler); } /** * Sends all data buffered (if any) and also sends the final HTTP chunk. * This function (either overloaded version) must be called following any * calls to send_chunk(). * Following a call to this function, it is not thread safe to use your * reference to the writer object. */ inline void send_final_chunk(void) { m_sending_chunks = true; send_more_data(true, bind_to_write_handler()); } /// returns a shared pointer to the TCP connection inline tcp::connection_ptr& get_connection(void) { return m_tcp_conn; } /// returns the length of the payload content (in bytes) inline size_t get_content_length(void) const { return m_content_length; } /// sets whether or not the client supports chunked messages inline void supports_chunked_messages(bool b) { m_client_supports_chunks = b; } /// returns true if the client supports chunked messages inline bool supports_chunked_messages() const { return m_client_supports_chunks; } /// returns true if we are sending a chunked message to the client inline bool sending_chunked_message() const { return m_sending_chunks; } /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// returns the logger currently in use inline logger get_logger(void) { return m_logger; } private: /** * sends all of the buffered data to the client * * @param send_final_chunk true if the final 0-byte chunk should be included * @param send_handler function called after the data has been sent */ template inline void send_more_data(const bool send_final_chunk, SendHandler send_handler) { // make sure that we did not lose the TCP connection if (m_tcp_conn->is_open()) { // make sure that the content-length is up-to-date flush_content_stream(); // prepare the write buffers to be sent http::message::write_buffers_t write_buffers; prepare_write_buffers(write_buffers, send_final_chunk); // send data in the write buffers m_tcp_conn->async_write(write_buffers, send_handler); } else { finished_writing(boost::asio::error::connection_reset); } } /** * prepares write_buffers for next send operation * * @param write_buffers buffers to which data will be appended * @param send_final_chunk true if the final 0-byte chunk should be included */ void prepare_write_buffers(http::message::write_buffers_t &write_buffers, const bool send_final_chunk); /// flushes any text data in the content stream after caching it in the text_cache_t inline void flush_content_stream(void) { if (! m_stream_is_empty) { std::string string_to_add(m_content_stream.str()); if (! string_to_add.empty()) { m_content_stream.str(""); m_content_length += string_to_add.size(); m_text_cache.push_back(string_to_add); m_content_buffers.push_back(boost::asio::buffer(m_text_cache.back())); } m_stream_is_empty = true; } } /// used to cache binary data included within the payload content class binary_cache_t : public std::vector > { public: ~binary_cache_t() { for (iterator i=begin(); i!=end(); ++i) { delete[] i->first; } } inline boost::asio::const_buffer add(const void *ptr, const size_t size) { char *data_ptr = new char[size]; memcpy(data_ptr, ptr, size); push_back( std::make_pair(data_ptr, size) ); return boost::asio::buffer(data_ptr, size); } }; /// used to cache text (non-binary) data included within the payload content typedef std::list text_cache_t; /// primary logging interface used by this class logger m_logger; /// The HTTP connection that we are writing the message to tcp::connection_ptr m_tcp_conn; /// I/O write buffers that wrap the payload content to be written http::message::write_buffers_t m_content_buffers; /// caches binary data included within the payload content binary_cache_t m_binary_cache; /// caches text (non-binary) data included within the payload content text_cache_t m_text_cache; /// incrementally creates strings of text data for the text_cache_t std::ostringstream m_content_stream; /// The length (in bytes) of the response content to be sent (Content-Length) size_t m_content_length; /// true if the content_stream is empty (avoids unnecessary string copies) bool m_stream_is_empty; /// true if the HTTP client supports chunked transfer encodings bool m_client_supports_chunks; /// true if data is being sent to the client using multiple chunks bool m_sending_chunks; /// true if the HTTP message headers have already been sent bool m_sent_headers; /// function called after the HTTP message has been sent finished_handler_t m_finished; }; /// data type for a writer pointer typedef boost::shared_ptr writer_ptr; /// override operator<< for convenience template inline const writer_ptr& operator<<(const writer_ptr& writer, const T& data) { writer->write(data); return writer; } inline const writer_ptr& operator<<(const writer_ptr& writer, std::ostream& (*iomanip)(std::ostream&)) { writer->write(iomanip); return writer; } } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/parser.hpp0000644000372000001440000007045412420270445021326 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_PARSER_HEADER__ #define __PION_HTTP_PARSER_HEADER__ #include #include #include #include #include #include #include #include #include #ifndef BOOST_SYSTEM_NOEXCEPT #define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT #endif namespace pion { // begin namespace pion namespace http { // begin namespace http // forward declarations used for finishing HTTP messages class request; class response; /// /// parser: parses HTTP messages /// class PION_API parser : private boost::noncopyable { public: /// maximum length for HTTP payload content static const std::size_t DEFAULT_CONTENT_MAX; /// callback type used to consume payload content typedef boost::function2 payload_handler_t; /// class-specific error code values enum error_value_t { ERROR_METHOD_CHAR = 1, ERROR_METHOD_SIZE, ERROR_URI_CHAR, ERROR_URI_SIZE, ERROR_QUERY_CHAR, ERROR_QUERY_SIZE, ERROR_VERSION_EMPTY, ERROR_VERSION_CHAR, ERROR_STATUS_EMPTY, ERROR_STATUS_CHAR, ERROR_HEADER_CHAR, ERROR_HEADER_NAME_SIZE, ERROR_HEADER_VALUE_SIZE, ERROR_INVALID_CONTENT_LENGTH, ERROR_CHUNK_CHAR, ERROR_MISSING_CHUNK_DATA, ERROR_MISSING_HEADER_DATA, ERROR_MISSING_TOO_MUCH_CONTENT, }; /// class-specific error category class error_category_t : public boost::system::error_category { public: const char *name() const BOOST_SYSTEM_NOEXCEPT { return "parser"; } std::string message(int ev) const { switch (ev) { case ERROR_METHOD_CHAR: return "invalid method character"; case ERROR_METHOD_SIZE: return "method exceeds maximum size"; case ERROR_URI_CHAR: return "invalid URI character"; case ERROR_URI_SIZE: return "method exceeds maximum size"; case ERROR_QUERY_CHAR: return "invalid query string character"; case ERROR_QUERY_SIZE: return "query string exceeds maximum size"; case ERROR_VERSION_EMPTY: return "HTTP version undefined"; case ERROR_VERSION_CHAR: return "invalid version character"; case ERROR_STATUS_EMPTY: return "HTTP status undefined"; case ERROR_STATUS_CHAR: return "invalid status character"; case ERROR_HEADER_CHAR: return "invalid header character"; case ERROR_HEADER_NAME_SIZE: return "header name exceeds maximum size"; case ERROR_HEADER_VALUE_SIZE: return "header value exceeds maximum size"; case ERROR_INVALID_CONTENT_LENGTH: return "invalid Content-Length header"; case ERROR_CHUNK_CHAR: return "invalid chunk character"; case ERROR_MISSING_HEADER_DATA: return "missing header data"; case ERROR_MISSING_CHUNK_DATA: return "missing chunk data"; case ERROR_MISSING_TOO_MUCH_CONTENT: return "missing too much content"; } return "parser error"; } }; /** * creates new parser objects * * @param is_request if true, the message is parsed as an HTTP request; * if false, the message is parsed as an HTTP response * @param max_content_length maximum length for HTTP payload content */ parser(const bool is_request, std::size_t max_content_length = DEFAULT_CONTENT_MAX) : m_logger(PION_GET_LOGGER("pion.http.parser")), m_is_request(is_request), m_read_ptr(NULL), m_read_end_ptr(NULL), m_message_parse_state(PARSE_START), m_headers_parse_state(is_request ? PARSE_METHOD_START : PARSE_HTTP_VERSION_H), m_chunked_content_parse_state(PARSE_CHUNK_SIZE_START), m_status_code(0), m_bytes_content_remaining(0), m_bytes_content_read(0), m_bytes_last_read(0), m_bytes_total_read(0), m_max_content_length(max_content_length), m_parse_headers_only(false), m_save_raw_headers(false) {} /// default destructor virtual ~parser() {} /** * parses an HTTP message including all payload content it might contain * * @param http_msg the HTTP message object to populate from parsing * @param ec error_code contains additional information for parsing errors * * @return boost::tribool result of parsing: * false = message has an error, * true = finished parsing HTTP message, * indeterminate = not yet finished parsing HTTP message */ boost::tribool parse(http::message& http_msg, boost::system::error_code& ec); /** * attempts to continue parsing despite having missed data (length is known but content is not) * * @param http_msg the HTTP message object to populate from parsing * @param len the length in bytes of the missing data * @param ec error_code contains additional information for parsing errors * * @return boost::tribool result of parsing: * false = message has an error, * true = finished parsing HTTP message, * indeterminate = not yet finished parsing HTTP message */ boost::tribool parse_missing_data(http::message& http_msg, std::size_t len, boost::system::error_code& ec); /** * finishes parsing an HTTP response message * * @param http_msg the HTTP message object to finish */ void finish(http::message& http_msg) const; /** * resets the location and size of the read buffer * * @param ptr pointer to the first bytes available to be read * @param len number of bytes available to be read */ inline void set_read_buffer(const char *ptr, size_t len) { m_read_ptr = ptr; m_read_end_ptr = ptr + len; } /** * loads a read position bookmark * * @param read_ptr points to the next character to be consumed in the read_buffer * @param read_end_ptr points to the end of the read_buffer (last byte + 1) */ inline void load_read_pos(const char *&read_ptr, const char *&read_end_ptr) const { read_ptr = m_read_ptr; read_end_ptr = m_read_end_ptr; } /** * checks to see if a premature EOF was encountered while parsing. This * should be called if there is no more data to parse, and if the last * call to the parse() function returned boost::indeterminate * * @param http_msg the HTTP message object being parsed * @return true if premature EOF, false if message is OK & finished parsing */ inline bool check_premature_eof(http::message& http_msg) { if (m_message_parse_state != PARSE_CONTENT_NO_LENGTH) return true; m_message_parse_state = PARSE_END; http_msg.concatenate_chunks(); finish(http_msg); return false; } /** * controls headers-only parsing (default is disabled; content parsed also) * * @param b if true, then the parse() function returns true after headers */ inline void parse_headers_only(bool b = true) { m_parse_headers_only = b; } /** * skip parsing all headers and parse payload content only * * @param http_msg the HTTP message object being parsed */ inline void skip_header_parsing(http::message& http_msg) { boost::system::error_code ec; finish_header_parsing(http_msg, ec); } /// resets the parser to its initial state inline void reset(void) { m_message_parse_state = PARSE_START; m_headers_parse_state = (m_is_request ? PARSE_METHOD_START : PARSE_HTTP_VERSION_H); m_chunked_content_parse_state = PARSE_CHUNK_SIZE_START; m_status_code = 0; m_status_message.erase(); m_method.erase(); m_resource.erase(); m_query_string.erase(); m_raw_headers.erase(); m_bytes_content_read = m_bytes_last_read = m_bytes_total_read = 0; } /// returns true if there are no more bytes available in the read buffer inline bool eof(void) const { return m_read_ptr == NULL || m_read_ptr >= m_read_end_ptr; } /// returns the number of bytes available in the read buffer inline std::size_t bytes_available(void) const { return (eof() ? 0 : (std::size_t)(m_read_end_ptr - m_read_ptr)); } /// returns the number of bytes read during the last parse operation inline std::size_t gcount(void) const { return m_bytes_last_read; } /// returns the total number of bytes read while parsing the HTTP message inline std::size_t get_total_bytes_read(void) const { return m_bytes_total_read; } /// returns the total number of bytes read while parsing the payload content inline std::size_t get_content_bytes_read(void) const { return m_bytes_content_read; } /// returns the maximum length for HTTP payload content inline std::size_t get_max_content_length(void) const { return m_max_content_length; } /// returns the raw HTTP headers saved by the parser inline const std::string& get_raw_headers(void) const { return m_raw_headers; } /// returns true if the parser is saving raw HTTP header contents inline bool get_save_raw_headers(void) const { return m_save_raw_headers; } /// returns true if parsing headers only inline bool get_parse_headers_only(void) { return m_parse_headers_only; } /// returns true if the parser is being used to parse an HTTP request inline bool is_parsing_request(void) const { return m_is_request; } /// returns true if the parser is being used to parse an HTTP response inline bool is_parsing_response(void) const { return ! m_is_request; } /// defines a callback function to be used for consuming payload content inline void set_payload_handler(payload_handler_t& h) { m_payload_handler = h; } /// sets the maximum length for HTTP payload content inline void set_max_content_length(std::size_t n) { m_max_content_length = n; } /// resets the maximum length for HTTP payload content to the default value inline void reset_max_content_length(void) { m_max_content_length = DEFAULT_CONTENT_MAX; } /// sets parameter for saving raw HTTP header content inline void set_save_raw_headers(bool b) { m_save_raw_headers = b; } /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// returns the logger currently in use inline logger get_logger(void) { return m_logger; } /** * parses a URI string * * @param uri the string to parse * @param proto will be set to the protocol (i.e. "http") * @param host will be set to the hostname (i.e. "www.cloudmeter.com") * @param port host port number to use for connection (i.e. 80) * @param path uri stem or file path * @param query uri query string * * @return true if the URI was successfully parsed, false if there was an error */ static bool parse_uri(const std::string& uri, std::string& proto, std::string& host, boost::uint16_t& port, std::string& path, std::string& query); /** * parse key-value pairs out of a url-encoded string * (i.e. this=that&a=value) * * @param dict dictionary for key-values pairs * @param ptr points to the start of the encoded string * @param len length of the encoded string, in bytes * * @return bool true if successful */ static bool parse_url_encoded(ihash_multimap& dict, const char *ptr, const std::size_t len); /** * parse key-value pairs out of a multipart/form-data payload content * (http://www.ietf.org/rfc/rfc2388.txt) * * @param dict dictionary for key-values pairs * @param content_type value of the content-type HTTP header * @param ptr points to the start of the encoded data * @param len length of the encoded data, in bytes * * @return bool true if successful */ static bool parse_multipart_form_data(ihash_multimap& dict, const std::string& content_type, const char *ptr, const std::size_t len); /** * parse key-value pairs out of a "Cookie" request header * (i.e. this=that; a=value) * * @param dict dictionary for key-values pairs * @param ptr points to the start of the header string to be parsed * @param len length of the encoded string, in bytes * @param set_cookie_header set true if parsing Set-Cookie response header * * @return bool true if successful */ static bool parse_cookie_header(ihash_multimap& dict, const char *ptr, const std::size_t len, bool set_cookie_header); /** * parse key-value pairs out of a "Cookie" request header * (i.e. this=that; a=value) * * @param dict dictionary for key-values pairs * @param cookie_header header string to be parsed * @param set_cookie_header set true if parsing Set-Cookie response header * * @return bool true if successful */ static inline bool parse_cookie_header(ihash_multimap& dict, const std::string& cookie_header, bool set_cookie_header) { return parse_cookie_header(dict, cookie_header.c_str(), cookie_header.size(), set_cookie_header); } /** * parse key-value pairs out of a url-encoded string * (i.e. this=that&a=value) * * @param dict dictionary for key-values pairs * @param query the encoded query string to be parsed * * @return bool true if successful */ static inline bool parse_url_encoded(ihash_multimap& dict, const std::string& query) { return parse_url_encoded(dict, query.c_str(), query.size()); } /** * parse key-value pairs out of a multipart/form-data payload content * (http://www.ietf.org/rfc/rfc2388.txt) * * @param dict dictionary for key-values pairs * @param content_type value of the content-type HTTP header * @param form_data the encoded form data * * @return bool true if successful */ static inline bool parse_multipart_form_data(ihash_multimap& dict, const std::string& content_type, const std::string& form_data) { return parse_multipart_form_data(dict, content_type, form_data.c_str(), form_data.size()); } /** * should be called after parsing HTTP headers, to prepare for payload content parsing * available in the read buffer * * @param http_msg the HTTP message object to populate from parsing * @param ec error_code contains additional information for parsing errors * * @return boost::tribool result of parsing: * false = message has an error, * true = finished parsing HTTP message (no content), * indeterminate = payload content is available to be parsed */ boost::tribool finish_header_parsing(http::message& http_msg, boost::system::error_code& ec); /** * parses an X-Forwarded-For HTTP header, and extracts from it an IP * address that best matches the client's public IP address (if any are found) * * @param header the X-Forwarded-For HTTP header to parse * @param public_ip the extract IP address, if found * * @return bool true if a public IP address was found and extracted */ static bool parse_forwarded_for(const std::string& header, std::string& public_ip); /// returns an instance of parser::error_category_t static inline error_category_t& get_error_category(void) { boost::call_once(parser::create_error_category, m_instance_flag); return *m_error_category_ptr; } protected: /// Called after we have finished parsing the HTTP message headers virtual void finished_parsing_headers(const boost::system::error_code& ec) {} /** * parses an HTTP message up to the end of the headers using bytes * available in the read buffer * * @param http_msg the HTTP message object to populate from parsing * @param ec error_code contains additional information for parsing errors * * @return boost::tribool result of parsing: * false = message has an error, * true = finished parsing HTTP headers, * indeterminate = not yet finished parsing HTTP headers */ boost::tribool parse_headers(http::message& http_msg, boost::system::error_code& ec); /** * updates an http::message object with data obtained from parsing headers * * @param http_msg the HTTP message object to populate from parsing */ void update_message_with_header_data(http::message& http_msg) const; /** * parses a chunked HTTP message-body using bytes available in the read buffer * * @param chunk_buffers buffers to be populated from parsing chunked content * @param ec error_code contains additional information for parsing errors * * @return boost::tribool result of parsing: * false = message has an error, * true = finished parsing message, * indeterminate = message is not yet finished */ boost::tribool parse_chunks(http::message::chunk_cache_t& chunk_buffers, boost::system::error_code& ec); /** * consumes payload content in the parser's read buffer * * @param http_msg the HTTP message object to consume content for * @param ec error_code contains additional information for parsing errors * * @return boost::tribool result of parsing: * false = message has an error, * true = finished parsing message, * indeterminate = message is not yet finished */ boost::tribool consume_content(http::message& http_msg, boost::system::error_code& ec); /** * consume the bytes available in the read buffer, converting them into * the next chunk for the HTTP message * * @param chunk_buffers buffers to be populated from parsing chunked content * @return std::size_t number of content bytes consumed, if any */ std::size_t consume_content_as_next_chunk(http::message::chunk_cache_t& chunk_buffers); /** * compute and sets a HTTP Message data integrity status * @param http_msg target HTTP message * @param msg_parsed_ok message parsing result */ static void compute_msg_status(http::message& http_msg, bool msg_parsed_ok); /** * sets an error code * * @param ec error code variable to define * @param ev error value to raise */ static inline void set_error(boost::system::error_code& ec, error_value_t ev) { ec = boost::system::error_code(static_cast(ev), get_error_category()); } /// creates the unique parser error_category_t static void create_error_category(void); // misc functions used by the parsing functions inline static bool is_char(int c); inline static bool is_control(int c); inline static bool is_special(int c); inline static bool is_digit(int c); inline static bool is_hex_digit(int c); inline static bool is_cookie_attribute(const std::string& name, bool set_cookie_header); /// maximum length for response status message static const boost::uint32_t STATUS_MESSAGE_MAX; /// maximum length for the request method static const boost::uint32_t METHOD_MAX; /// maximum length for the resource requested static const boost::uint32_t RESOURCE_MAX; /// maximum length for the query string static const boost::uint32_t QUERY_STRING_MAX; /// maximum length for an HTTP header name static const boost::uint32_t HEADER_NAME_MAX; /// maximum length for an HTTP header value static const boost::uint32_t HEADER_VALUE_MAX; /// maximum length for the name of a query string variable static const boost::uint32_t QUERY_NAME_MAX; /// maximum length for the value of a query string variable static const boost::uint32_t QUERY_VALUE_MAX; /// maximum length for the name of a cookie name static const boost::uint32_t COOKIE_NAME_MAX; /// maximum length for the value of a cookie; also used for path and domain static const boost::uint32_t COOKIE_VALUE_MAX; /// primary logging interface used by this class mutable logger m_logger; /// true if the message is an HTTP request; false if it is an HTTP response const bool m_is_request; /// points to the next character to be consumed in the read_buffer const char * m_read_ptr; /// points to the end of the read_buffer (last byte + 1) const char * m_read_end_ptr; private: /// state used to keep track of where we are in parsing the HTTP message enum message_parse_state_t { PARSE_START, PARSE_HEADERS, PARSE_FOOTERS, PARSE_CONTENT, PARSE_CONTENT_NO_LENGTH, PARSE_CHUNKS, PARSE_END }; /// state used to keep track of where we are in parsing the HTTP headers /// (only used if message_parse_state_t == PARSE_HEADERS) enum header_parse_state_t { PARSE_METHOD_START, PARSE_METHOD, PARSE_URI_STEM, PARSE_URI_QUERY, PARSE_HTTP_VERSION_H, PARSE_HTTP_VERSION_T_1, PARSE_HTTP_VERSION_T_2, PARSE_HTTP_VERSION_P, PARSE_HTTP_VERSION_SLASH, PARSE_HTTP_VERSION_MAJOR_START, PARSE_HTTP_VERSION_MAJOR, PARSE_HTTP_VERSION_MINOR_START, PARSE_HTTP_VERSION_MINOR, PARSE_STATUS_CODE_START, PARSE_STATUS_CODE, PARSE_STATUS_MESSAGE, PARSE_EXPECTING_NEWLINE, PARSE_EXPECTING_CR, PARSE_HEADER_WHITESPACE, PARSE_HEADER_START, PARSE_HEADER_NAME, PARSE_SPACE_BEFORE_HEADER_VALUE, PARSE_HEADER_VALUE, PARSE_EXPECTING_FINAL_NEWLINE, PARSE_EXPECTING_FINAL_CR }; /// state used to keep track of where we are in parsing chunked content /// (only used if message_parse_state_t == PARSE_CHUNKS) enum chunk_parse_state_t { PARSE_CHUNK_SIZE_START, PARSE_CHUNK_SIZE, PARSE_EXPECTING_IGNORED_TEXT_AFTER_CHUNK_SIZE, PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE, PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE, PARSE_CHUNK, PARSE_EXPECTING_CR_AFTER_CHUNK, PARSE_EXPECTING_LF_AFTER_CHUNK, PARSE_EXPECTING_FINAL_CR_OR_FOOTERS_AFTER_LAST_CHUNK, PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK }; /// the current state of parsing HTTP headers message_parse_state_t m_message_parse_state; /// the current state of parsing HTTP headers header_parse_state_t m_headers_parse_state; /// the current state of parsing chunked content chunk_parse_state_t m_chunked_content_parse_state; /// if defined, this function is used to consume payload content payload_handler_t m_payload_handler; /// Used for parsing the HTTP response status code boost::uint16_t m_status_code; /// Used for parsing the HTTP response status message std::string m_status_message; /// Used for parsing the request method std::string m_method; /// Used for parsing the name of resource requested std::string m_resource; /// Used for parsing the query string portion of a URI std::string m_query_string; /// Used to store the raw contents of HTTP headers when m_save_raw_headers is true std::string m_raw_headers; /// Used for parsing the name of HTTP headers std::string m_header_name; /// Used for parsing the value of HTTP headers std::string m_header_value; /// Used for parsing the chunk size std::string m_chunk_size_str; /// number of bytes in the chunk currently being parsed std::size_t m_size_of_current_chunk; /// number of bytes read so far in the chunk currently being parsed std::size_t m_bytes_read_in_current_chunk; /// number of payload content bytes that have not yet been read std::size_t m_bytes_content_remaining; /// number of bytes read so far into the message's payload content std::size_t m_bytes_content_read; /// number of bytes read during last parse operation std::size_t m_bytes_last_read; /// total number of bytes read while parsing the HTTP message std::size_t m_bytes_total_read; /// maximum length for HTTP payload content std::size_t m_max_content_length; /// if true, then only HTTP headers will be parsed (no content parsing) bool m_parse_headers_only; /// if true, the raw contents of HTTP headers are stored into m_raw_headers bool m_save_raw_headers; /// points to a single and unique instance of the parser error_category_t static error_category_t * m_error_category_ptr; /// used to ensure thread safety of the parser error_category_t static boost::once_flag m_instance_flag; }; // inline functions for parser inline bool parser::is_char(int c) { return(c >= 0 && c <= 127); } inline bool parser::is_control(int c) { return( (c >= 0 && c <= 31) || c == 127); } inline bool parser::is_special(int c) { switch (c) { case '(': case ')': case '<': case '>': case '@': case ',': case ';': case ':': case '\\': case '"': case '/': case '[': case ']': case '?': case '=': case '{': case '}': case ' ': case '\t': return true; default: return false; } } inline bool parser::is_digit(int c) { return(c >= '0' && c <= '9'); } inline bool parser::is_hex_digit(int c) { return((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); } inline bool parser::is_cookie_attribute(const std::string& name, bool set_cookie_header) { return (name.empty() || name[0] == '$' || (set_cookie_header && ( // This is needed because of a very lenient determination in parse_cookie_header() of what // qualifies as a cookie-pair in a Set-Cookie header. // According to RFC 6265, everything after the first semicolon is a cookie attribute, but RFC 2109, // which is obsolete, allowed multiple comma separated cookies. // parse_cookie_header() is very conservatively assuming that any = pair in a // Set-Cookie header is a cookie-pair unless is a known cookie attribute. boost::algorithm::iequals(name, "Comment") || boost::algorithm::iequals(name, "Domain") || boost::algorithm::iequals(name, "Max-Age") || boost::algorithm::iequals(name, "Path") || boost::algorithm::iequals(name, "Secure") || boost::algorithm::iequals(name, "Version") || boost::algorithm::iequals(name, "Expires") || boost::algorithm::iequals(name, "HttpOnly") ) )); } } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/response_reader.hpp0000644000372000001440000001064612420270445023207 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_RESPONSE_READER_HEADER__ #define __PION_HTTP_RESPONSE_READER_HEADER__ #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// response_reader: asynchronously reads and parses HTTP responses /// class response_reader : public http::reader, public boost::enable_shared_from_this { public: /// function called after the HTTP message has been parsed typedef boost::function3 finished_handler_t; // default destructor virtual ~response_reader() {} /** * creates new response_reader objects * * @param tcp_conn TCP connection containing a new message to parse * @param http_request the request we are responding to * @param handler function called after the message has been parsed */ static inline boost::shared_ptr create(tcp::connection_ptr& tcp_conn, const http::request& http_request, finished_handler_t handler) { return boost::shared_ptr (new response_reader(tcp_conn, http_request, handler)); } /// sets a function to be called after HTTP headers have been parsed inline void set_headers_parsed_callback(finished_handler_t& h) { m_parsed_headers = h; } protected: /** * protected constructor restricts creation of objects (use create()) * * @param tcp_conn TCP connection containing a new message to parse * @param http_request the request we are responding to * @param handler function called after the message has been parsed */ response_reader(tcp::connection_ptr& tcp_conn, const http::request& http_request, finished_handler_t handler) : http::reader(false, tcp_conn), m_http_msg(new http::response(http_request)), m_finished(handler) { m_http_msg->set_remote_ip(tcp_conn->get_remote_ip()); set_logger(PION_GET_LOGGER("pion.http.response_reader")); } /// Reads more bytes from the TCP connection virtual void read_bytes(void) { get_connection()->async_read_some(boost::bind(&response_reader::consume_bytes, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } /// Called after we have finished parsing the HTTP message headers virtual void finished_parsing_headers(const boost::system::error_code& ec) { // call the finished headers handler with the HTTP message if (m_parsed_headers) m_parsed_headers(m_http_msg, get_connection(), ec); } /// Called after we have finished reading/parsing the HTTP message virtual void finished_reading(const boost::system::error_code& ec) { // call the finished handler with the finished HTTP message if (m_finished) m_finished(m_http_msg, get_connection(), ec); } /// Returns a reference to the HTTP message being parsed virtual http::message& get_message(void) { return *m_http_msg; } /// The new HTTP message container being created http::response_ptr m_http_msg; /// function called after the HTTP message has been parsed finished_handler_t m_finished; /// function called after the HTTP message headers have been parsed finished_handler_t m_parsed_headers; }; /// data type for a response_reader pointer typedef boost::shared_ptr response_reader_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/plugin_server.hpp0000644000372000001440000001254312420270445022711 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PLUGIN_SERVER_HEADER__ #define __PION_PLUGIN_SERVER_HEADER__ #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// plugin_server: a server that handles HTTP connections using http::plugin_service plug-ins /// class PION_API plugin_server : public http::server { public: /// default destructor virtual ~plugin_server() { clear(); } /** * creates a new plugin_server object * * @param tcp_port port number used to listen for new connections (IPv4) */ explicit plugin_server(const unsigned int tcp_port = 0) : http::server(tcp_port) { set_logger(PION_GET_LOGGER("pion.http.plugin_server")); } /** * creates a new plugin_server object * * @param endpoint TCP endpoint used to listen for new connections (see ASIO docs) */ explicit plugin_server(const boost::asio::ip::tcp::endpoint& endpoint) : http::server(endpoint) { set_logger(PION_GET_LOGGER("pion.http.plugin_server")); } /** * creates a new plugin_server object * * @param sched the scheduler that will be used to manage worker threads * @param tcp_port port number used to listen for new connections (IPv4) */ explicit plugin_server(scheduler& sched, const unsigned int tcp_port = 0) : http::server(sched, tcp_port) { set_logger(PION_GET_LOGGER("pion.http.plugin_server")); } /** * creates a new plugin_server object * * @param sched the scheduler that will be used to manage worker threads * @param endpoint TCP endpoint used to listen for new connections (see ASIO docs) */ plugin_server(scheduler& sched, const boost::asio::ip::tcp::endpoint& endpoint) : http::server(sched, endpoint) { set_logger(PION_GET_LOGGER("pion.http.plugin_server")); } /** * adds a new web service to the web server * * @param resource the resource name or uri-stem to bind to the web service * @param service_ptr a pointer to the web service */ void add_service(const std::string& resource, http::plugin_service *service_ptr); /** * loads a web service from a shared object file * * @param resource the resource name or uri-stem to bind to the web service * @param service_name the name of the web service to load (searches plug-in * directories and appends extensions) */ void load_service(const std::string& resource, const std::string& service_name); /** * sets a configuration option for the web service associated with resource * * @param resource the resource name or uri-stem that identifies the web service * @param name the name of the configuration option * @param value the value to set the option to */ void set_service_option(const std::string& resource, const std::string& name, const std::string& value); /** * Parses a simple web service configuration file. Each line in the file * starts with one of the following commands: * * path VALUE : adds a directory to the web service search path * service RESOURCE FILE : loads web service bound to RESOURCE from FILE * option RESOURCE NAME=VALUE : sets web service option NAME to VALUE * * Blank lines or lines that begin with # are ignored as comments. * * @param config_name the name of the config file to parse */ void load_service_config(const std::string& config_name); /// clears all the web services that are currently configured virtual void clear(void) { if (is_listening()) stop(); m_services.clear(); http::server::clear(); } protected: /// called before the TCP server starts listening for new connections virtual void before_starting(void) { // call the start() method for each web service associated with this server m_services.run(boost::bind(&http::plugin_service::start, _1)); } /// called after the TCP server has stopped listening for new connections virtual void after_stopping(void) { // call the stop() method for each web service associated with this server m_services.run(boost::bind(&http::plugin_service::stop, _1)); } private: /// data type for a collection of web services typedef plugin_manager service_manager_t; /// Web services associated with this server service_manager_t m_services; }; /// data type for a web server pointer typedef boost::shared_ptr plugin_server_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/types.hpp0000644000372000001440000001261012420270445021164 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_TYPES_HEADER__ #define __PION_HTTP_TYPES_HEADER__ #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// types: common data types used by HTTP /// struct PION_API types { /// virtual destructor virtual ~types() {} // generic strings used by HTTP static const std::string STRING_EMPTY; static const std::string STRING_CRLF; static const std::string STRING_HTTP_VERSION; static const std::string HEADER_NAME_VALUE_DELIMITER; static const std::string COOKIE_NAME_VALUE_DELIMITER; // common HTTP header names static const std::string HEADER_HOST; static const std::string HEADER_COOKIE; static const std::string HEADER_SET_COOKIE; static const std::string HEADER_CONNECTION; static const std::string HEADER_CONTENT_TYPE; static const std::string HEADER_CONTENT_LENGTH; static const std::string HEADER_CONTENT_LOCATION; static const std::string HEADER_CONTENT_ENCODING; static const std::string HEADER_CONTENT_DISPOSITION; static const std::string HEADER_LAST_MODIFIED; static const std::string HEADER_IF_MODIFIED_SINCE; static const std::string HEADER_TRANSFER_ENCODING; static const std::string HEADER_LOCATION; static const std::string HEADER_AUTHORIZATION; static const std::string HEADER_REFERER; static const std::string HEADER_USER_AGENT; static const std::string HEADER_X_FORWARDED_FOR; static const std::string HEADER_CLIENT_IP; // common HTTP content types static const std::string CONTENT_TYPE_HTML; static const std::string CONTENT_TYPE_TEXT; static const std::string CONTENT_TYPE_XML; static const std::string CONTENT_TYPE_URLENCODED; static const std::string CONTENT_TYPE_MULTIPART_FORM_DATA; // common HTTP request methods static const std::string REQUEST_METHOD_HEAD; static const std::string REQUEST_METHOD_GET; static const std::string REQUEST_METHOD_PUT; static const std::string REQUEST_METHOD_POST; static const std::string REQUEST_METHOD_DELETE; // common HTTP response messages static const std::string RESPONSE_MESSAGE_OK; static const std::string RESPONSE_MESSAGE_CREATED; static const std::string RESPONSE_MESSAGE_ACCEPTED; static const std::string RESPONSE_MESSAGE_NO_CONTENT; static const std::string RESPONSE_MESSAGE_FOUND; static const std::string RESPONSE_MESSAGE_UNAUTHORIZED; static const std::string RESPONSE_MESSAGE_FORBIDDEN; static const std::string RESPONSE_MESSAGE_NOT_FOUND; static const std::string RESPONSE_MESSAGE_METHOD_NOT_ALLOWED; static const std::string RESPONSE_MESSAGE_NOT_MODIFIED; static const std::string RESPONSE_MESSAGE_BAD_REQUEST; static const std::string RESPONSE_MESSAGE_SERVER_ERROR; static const std::string RESPONSE_MESSAGE_NOT_IMPLEMENTED; static const std::string RESPONSE_MESSAGE_CONTINUE; // common HTTP response codes static const unsigned int RESPONSE_CODE_OK; static const unsigned int RESPONSE_CODE_CREATED; static const unsigned int RESPONSE_CODE_ACCEPTED; static const unsigned int RESPONSE_CODE_NO_CONTENT; static const unsigned int RESPONSE_CODE_FOUND; static const unsigned int RESPONSE_CODE_UNAUTHORIZED; static const unsigned int RESPONSE_CODE_FORBIDDEN; static const unsigned int RESPONSE_CODE_NOT_FOUND; static const unsigned int RESPONSE_CODE_METHOD_NOT_ALLOWED; static const unsigned int RESPONSE_CODE_NOT_MODIFIED; static const unsigned int RESPONSE_CODE_BAD_REQUEST; static const unsigned int RESPONSE_CODE_SERVER_ERROR; static const unsigned int RESPONSE_CODE_NOT_IMPLEMENTED; static const unsigned int RESPONSE_CODE_CONTINUE; /// converts time_t format into an HTTP-date string static std::string get_date_string(const time_t t); /// builds an HTTP query string from a collection of query parameters static std::string make_query_string(const ihash_multimap& query_params); /** * creates a "Set-Cookie" header * * @param name the name of the cookie * @param value the value of the cookie * @param path the path of the cookie * @param has_max_age true if the max_age value should be set * @param max_age the life of the cookie, in seconds (0 = discard) * * @return the new "Set-Cookie" header */ static std::string make_set_cookie_header(const std::string& name, const std::string& value, const std::string& path, const bool has_max_age = false, const unsigned long max_age = 0); }; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/request_writer.hpp0000644000372000001440000001454512420270445023115 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_REQUEST_WRITER_HEADER__ #define __PION_HTTP_REQUEST_WRITER_HEADER__ #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// request_writer: used to asynchronously send HTTP requests /// class request_writer : public http::writer, public boost::enable_shared_from_this { public: /// default destructor virtual ~request_writer() {} /** * creates new request_writer objects * * @param tcp_conn TCP connection used to send the request * @param handler function called after the request has been sent * * @return boost::shared_ptr shared pointer to * the new writer object that was created */ static inline boost::shared_ptr create(tcp::connection_ptr& tcp_conn, finished_handler_t handler = finished_handler_t()) { return boost::shared_ptr(new request_writer(tcp_conn, handler)); } /** * creates new request_writer objects * * @param tcp_conn TCP connection used to send the request * @param http_request_ptr pointer to the request that will be sent * @param handler function called after the request has been sent * * @return boost::shared_ptr shared pointer to * the new writer object that was created */ static inline boost::shared_ptr create(tcp::connection_ptr& tcp_conn, http::request_ptr& http_request_ptr, finished_handler_t handler = finished_handler_t()) { return boost::shared_ptr(new request_writer(tcp_conn, http_request_ptr, handler)); } /// returns a non-const reference to the request that will be sent inline http::request& get_request(void) { return *m_http_request; } protected: /** * protected constructor restricts creation of objects (use create()) * * @param tcp_conn TCP connection used to send the request * @param handler function called after the request has been sent */ request_writer(tcp::connection_ptr& tcp_conn, finished_handler_t handler) : http::writer(tcp_conn, handler), m_http_request(new http::request) { set_logger(PION_GET_LOGGER("pion.http.request_writer")); } /** * protected constructor restricts creation of objects (use create()) * * @param tcp_conn TCP connection used to send the request * @param http_request_ptr pointer to the request that will be sent * @param handler function called after the request has been sent */ request_writer(tcp::connection_ptr& tcp_conn, http::request_ptr& http_request_ptr, finished_handler_t handler) : http::writer(tcp_conn, handler), m_http_request(http_request_ptr) { set_logger(PION_GET_LOGGER("pion.http.request_writer")); // check if we should initialize the payload content using // the request's content buffer if (m_http_request->get_content_length() > 0 && m_http_request->get_content() != NULL && m_http_request->get_content()[0] != '\0') { write_no_copy(m_http_request->get_content(), m_http_request->get_content_length()); } } /** * initializes a vector of write buffers with the HTTP message information * * @param write_buffers vector of write buffers to initialize */ virtual void prepare_buffers_for_send(http::message::write_buffers_t& write_buffers) { if (get_content_length() > 0) m_http_request->set_content_length(get_content_length()); m_http_request->prepare_buffers_for_send(write_buffers, get_connection()->get_keep_alive(), sending_chunked_message()); } /// returns a function bound to http::writer::handle_write() virtual write_handler_t bind_to_write_handler(void) { return boost::bind(&request_writer::handle_write, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred); } /** * called after the request is sent * * @param write_error error status from the last write operation * @param bytes_written number of bytes sent by the last write operation */ virtual void handle_write(const boost::system::error_code& write_error, std::size_t bytes_written) { logger log_ptr(get_logger()); if (! write_error) { // request sent OK if (sending_chunked_message()) { PION_LOG_DEBUG(log_ptr, "Sent HTTP request chunk of " << bytes_written << " bytes"); clear(); } else { PION_LOG_DEBUG(log_ptr, "Sent HTTP request of " << bytes_written << " bytes"); } } finished_writing(write_error); } private: /// the request that will be sent http::request_ptr m_http_request; /// the initial HTTP request header line std::string m_request_line; }; /// data type for a request_writer pointer typedef boost::shared_ptr request_writer_ptr; /// override operator<< for convenience template const request_writer_ptr& operator<<(const request_writer_ptr& writer, const T& data) { writer->write(data); return writer; } } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/auth.hpp0000644000372000001440000001243712420270445020770 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_AUTH_HEADER__ #define __PION_HTTP_AUTH_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #include // order important, otherwise compiling error under win32 namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// auth: a base class for handling HTTP Authentication and session management /// class PION_API auth : private boost::noncopyable { public: /// default constructor auth(user_manager_ptr userManager) : m_logger(PION_GET_LOGGER("pion.http.auth")), m_user_manager(userManager) {} /// virtual destructor virtual ~auth() {} /** * attempts to validate authentication of a new HTTP request. * If request valid, pointer to user identity object (if any) will be preserved in * the request and return "true". * If request not authenticated, appropriate response is sent over tcp_conn * and return "false"; * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * * @return true if request valid and user identity inserted into request */ virtual bool handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) = 0; /** * sets a configuration option * * @param name the name of the option to change * @param value the value of the option */ virtual void set_option(const std::string& name, const std::string& value) { BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } /** * adds a resource that requires authentication * * @param resource the resource name or uri-stem that requires authentication */ void add_restrict(const std::string& resource); /** * adds a resource that does NOT require authentication * * @param resource the resource name or uri-stem that does not require authentication */ void add_permit(const std::string& resource); /** * used to add a new user * * @ return false if user with such name already exists */ virtual bool add_user(std::string const &username, std::string const &password) { return m_user_manager->add_user(username, password); } /** * update password for given user * * @return false if user with such a name doesn't exist */ virtual bool update_user(std::string const &username, std::string const &password) { return m_user_manager->update_user(username, password); } /** * used to remove given user * * @return false if no user with such username */ virtual bool remove_user(std::string const &username) { return m_user_manager->remove_user(username); }; /** * Used to locate user object by username */ virtual user_ptr get_user(std::string const &username) { return m_user_manager->get_user(username); } protected: /// data type for a set of resources to be authenticated typedef std::set resource_set_type; /// data type used to map authentication credentials to user objects typedef std::map > user_cache_type; /** * check if given HTTP request requires authentication * * @param http_request_ptr the HTTP request to check */ bool need_authentication(http::request_ptr const& http_request_ptr) const; /** * tries to find a resource in a given collection * * @param resource_set the collection of resource to look in * @param resource the resource to look for * * @return true if the resource was found */ bool find_resource(const resource_set_type& resource_set, const std::string& resource) const; /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// primary logging interface used by this class mutable logger m_logger; /// container used to manager user objects user_manager_ptr m_user_manager; /// collection of resources that require authentication resource_set_type m_restrict_list; /// collection of resources that do NOT require authentication resource_set_type m_white_list; /// mutex used to protect access to the resources mutable boost::mutex m_resource_mutex; }; /// data type for a auth pointer typedef boost::shared_ptr auth_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/Makefile.am0000644000372000001440000000066712420270445021354 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- pion_http_includedir = $(includedir)/pion/http pion_http_include_HEADERS = \ auth.hpp basic_auth.hpp cookie_auth.hpp message.hpp parser.hpp \ plugin_server.hpp plugin_service.hpp reader.hpp request.hpp \ request_reader.hpp request_writer.hpp response.hpp response_reader.hpp \ response_writer.hpp server.hpp types.hpp writer.hpp pion-5.0.7+dfsg.orig/include/pion/http/server.hpp0000644000372000001440000002533212420270445021333 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_SERVER_HEADER__ #define __PION_HTTP_SERVER_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// server: a server that handles HTTP connections /// class PION_API server : public tcp::server { public: /// type of function that is used to handle requests typedef boost::function2 request_handler_t; /// handler for requests that result in "500 Server Error" typedef boost::function3 error_handler_t; /// default destructor virtual ~server() { if (is_listening()) stop(); } /** * creates a new server object * * @param tcp_port port number used to listen for new connections (IPv4) */ explicit server(const unsigned int tcp_port = 0) : tcp::server(tcp_port), m_bad_request_handler(server::handle_bad_request), m_not_found_handler(server::handle_not_found_request), m_server_error_handler(server::handle_server_error), m_max_content_length(http::parser::DEFAULT_CONTENT_MAX) { set_logger(PION_GET_LOGGER("pion.http.server")); } /** * creates a new server object * * @param endpoint TCP endpoint used to listen for new connections (see ASIO docs) */ explicit server(const boost::asio::ip::tcp::endpoint& endpoint) : tcp::server(endpoint), m_bad_request_handler(server::handle_bad_request), m_not_found_handler(server::handle_not_found_request), m_server_error_handler(server::handle_server_error), m_max_content_length(http::parser::DEFAULT_CONTENT_MAX) { set_logger(PION_GET_LOGGER("pion.http.server")); } /** * creates a new server object * * @param sched the scheduler that will be used to manage worker threads * @param tcp_port port number used to listen for new connections (IPv4) */ explicit server(scheduler& sched, const unsigned int tcp_port = 0) : tcp::server(sched, tcp_port), m_bad_request_handler(server::handle_bad_request), m_not_found_handler(server::handle_not_found_request), m_server_error_handler(server::handle_server_error), m_max_content_length(http::parser::DEFAULT_CONTENT_MAX) { set_logger(PION_GET_LOGGER("pion.http.server")); } /** * creates a new server object * * @param sched the scheduler that will be used to manage worker threads * @param endpoint TCP endpoint used to listen for new connections (see ASIO docs) */ server(scheduler& sched, const boost::asio::ip::tcp::endpoint& endpoint) : tcp::server(sched, endpoint), m_bad_request_handler(server::handle_bad_request), m_not_found_handler(server::handle_not_found_request), m_server_error_handler(server::handle_server_error), m_max_content_length(http::parser::DEFAULT_CONTENT_MAX) { set_logger(PION_GET_LOGGER("pion.http.server")); } /** * adds a new web service to the HTTP server * * @param resource the resource name or uri-stem to bind to the handler * @param request_handler function used to handle requests to the resource */ void add_resource(const std::string& resource, request_handler_t request_handler); /** * removes a web service from the HTTP server * * @param resource the resource name or uri-stem to remove */ void remove_resource(const std::string& resource); /** * adds a new resource redirection to the HTTP server * * @param requested_resource the resource name or uri-stem that will be redirected * @param new_resource the resource that requested_resource will be redirected to */ void add_redirect(const std::string& requested_resource, const std::string& new_resource); /// sets the function that handles bad HTTP requests inline void set_bad_request_handler(request_handler_t h) { m_bad_request_handler = h; } /// sets the function that handles requests which match no other web services inline void set_not_found_handler(request_handler_t h) { m_not_found_handler = h; } /// sets the function that handles requests which match no other web services inline void set_error_handler(error_handler_t h) { m_server_error_handler = h; } /// clears the collection of resources recognized by the HTTP server virtual void clear(void) { if (is_listening()) stop(); boost::mutex::scoped_lock resource_lock(m_resource_mutex); m_resources.clear(); } /** * strips trailing slash from a string, if one exists * * @param str the original string * @return the resulting string, after any trailing slash is removed */ static inline std::string strip_trailing_slash(const std::string& str) { std::string result(str); if (!result.empty() && result[result.size()-1]=='/') result.resize(result.size() - 1); return result; } /** * used to send responses when a bad HTTP request is made * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ static void handle_bad_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * used to send responses when no web services can handle the request * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request */ static void handle_not_found_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn); /** * used to send responses when a server error occurs * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * @param error_msg message that explains what went wrong */ static void handle_server_error(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& error_msg); /** * used to send responses when a request is forbidden * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * @param error_msg message that explains what went wrong */ static void handle_forbidden_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& error_msg); /** * used to send responses when a method is not allowed * * @param http_request_ptr the new HTTP request to handle * @param tcp_conn the TCP connection that has the new request * @param allowed_methods optional comma separated list of allowed methods */ static void handle_method_not_allowed(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& allowed_methods = ""); /** * sets the handler object for authentication verification processing */ inline void set_authentication(http::auth_ptr auth) { m_auth_ptr = auth; } /// sets the maximum length for HTTP request payload content inline void set_max_content_length(std::size_t n) { m_max_content_length = n; } protected: /** * handles a new TCP connection * * @param tcp_conn the new TCP connection to handle */ virtual void handle_connection(tcp::connection_ptr& tcp_conn); /** * handles a new HTTP request * * @param http_request_ptr the HTTP request to handle * @param tcp_conn TCP connection containing a new request * @param ec error_code contains additional information for parsing errors */ virtual void handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const boost::system::error_code& ec); /** * searches for the appropriate request handler to use for a given resource * * @param resource the name of the resource to search for * @param request_handler function that can handle requests for this resource */ virtual bool find_request_handler(const std::string& resource, request_handler_t& request_handler) const; private: /// maximum number of redirections static const unsigned int MAX_REDIRECTS; /// data type for a map of resources to request handlers typedef std::map resource_map_t; /// data type for a map of requested resources to other resources typedef std::map redirect_map_t; /// collection of resources that are recognized by this HTTP server resource_map_t m_resources; /// collection of redirections from a requested resource to another resource redirect_map_t m_redirects; /// points to a function that handles bad HTTP requests request_handler_t m_bad_request_handler; /// points to a function that handles requests which match no web services request_handler_t m_not_found_handler; /// points to the function that handles server errors error_handler_t m_server_error_handler; /// mutex used to protect access to the resources mutable boost::mutex m_resource_mutex; /// pointer to authentication handler object http::auth_ptr m_auth_ptr; /// maximum length for HTTP request payload content std::size_t m_max_content_length; }; /// data type for a HTTP server pointer typedef boost::shared_ptr server_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/http/request.hpp0000644000372000001440000001670312420270445021517 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HTTP_REQUEST_HEADER__ #define __PION_HTTP_REQUEST_HEADER__ #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http /// /// request: container for HTTP request information /// class request : public http::message { public: /** * constructs a new request object * * @param resource the HTTP resource to request */ request(const std::string& resource) : m_method(REQUEST_METHOD_GET), m_resource(resource) {} /// constructs a new request object (default constructor) request(void) : m_method(REQUEST_METHOD_GET) {} /// virtual destructor virtual ~request() {} /// clears all request data virtual void clear(void) { http::message::clear(); m_method.erase(); m_resource.erase(); m_original_resource.erase(); m_query_string.erase(); m_query_params.clear(); m_user_record.reset(); } /// the content length of the message can never be implied for requests virtual bool is_content_length_implied(void) const { return false; } /// returns the request method (i.e. GET, POST, PUT) inline const std::string& get_method(void) const { return m_method; } /// returns the resource uri-stem to be delivered (possibly the result of a redirect) inline const std::string& get_resource(void) const { return m_resource; } /// returns the resource uri-stem originally requested inline const std::string& get_original_resource(void) const { return m_original_resource; } /// returns the uri-query or query string requested inline const std::string& get_query_string(void) const { return m_query_string; } /// returns a value for the query key if any are defined; otherwise, an empty string inline const std::string& get_query(const std::string& key) const { return get_value(m_query_params, key); } /// returns the query parameters inline ihash_multimap& get_queries(void) { return m_query_params; } /// returns true if at least one value for the query key is defined inline bool has_query(const std::string& key) const { return(m_query_params.find(key) != m_query_params.end()); } /// sets the HTTP request method (i.e. GET, POST, PUT) inline void set_method(const std::string& str) { m_method = str; clear_first_line(); } /// sets the resource or uri-stem originally requested inline void set_resource(const std::string& str) { m_resource = m_original_resource = str; clear_first_line(); } /// changes the resource or uri-stem to be delivered (called as the result of a redirect) inline void change_resource(const std::string& str) { m_resource = str; } /// sets the uri-query or query string requested inline void set_query_string(const std::string& str) { m_query_string = str; clear_first_line(); } /// adds a value for the query key inline void add_query(const std::string& key, const std::string& value) { m_query_params.insert(std::make_pair(key, value)); } /// changes the value of a query key inline void change_query(const std::string& key, const std::string& value) { change_value(m_query_params, key, value); } /// removes all values for a query key inline void delete_query(const std::string& key) { delete_value(m_query_params, key); } /// use the query parameters to build a query string for the request inline void use_query_params_for_query_string(void) { set_query_string(make_query_string(m_query_params)); } /// use the query parameters to build POST content for the request inline void use_query_params_for_post_content(void) { std::string post_content(make_query_string(m_query_params)); set_content_length(post_content.size()); char *ptr = create_content_buffer(); // null-terminates buffer if (! post_content.empty()) memcpy(ptr, post_content.c_str(), post_content.size()); set_method(REQUEST_METHOD_POST); set_content_type(CONTENT_TYPE_URLENCODED); } /// add content (for POST) from string inline void set_content(const std::string &value) { set_content_length(value.size()); char *ptr = create_content_buffer(); if (! value.empty()) memcpy(ptr, value.c_str(), value.size()); } /// add content (for POST) from buffer of given size /// does nothing if the buffer is invalid or the buffer size is zero inline void set_content(const char* value, size_t size) { if ( NULL == value || 0 == size ) return; set_content_length(size); char *ptr = create_content_buffer(); memcpy(ptr, value, size); } /// sets the user record for HTTP request after authentication inline void set_user(user_ptr user) { m_user_record = user; } /// get the user record for HTTP request after authentication inline user_ptr get_user() const { return m_user_record; } protected: /// updates the string containing the first line for the HTTP message virtual void update_first_line(void) const { // start out with the request method m_first_line = m_method; m_first_line += ' '; // append the resource requested m_first_line += m_resource; if (! m_query_string.empty()) { // append query string if not empty m_first_line += '?'; m_first_line += m_query_string; } m_first_line += ' '; // append HTTP version m_first_line += get_version_string(); } /// appends HTTP headers for any cookies defined by the http::message virtual void append_cookie_headers(void) { for (ihash_multimap::const_iterator i = get_cookies().begin(); i != get_cookies().end(); ++i) { std::string cookie_header; cookie_header = i->first; cookie_header += COOKIE_NAME_VALUE_DELIMITER; cookie_header += i->second; add_header(HEADER_COOKIE, cookie_header); } } private: /// request method (GET, POST, PUT, etc.) std::string m_method; /// name of the resource or uri-stem to be delivered std::string m_resource; /// name of the resource or uri-stem originally requested std::string m_original_resource; /// query string portion of the URI std::string m_query_string; /// HTTP query parameters parsed from the request line and post content ihash_multimap m_query_params; /// pointer to user record if this request had been authenticated user_ptr m_user_record; }; /// data type for a HTTP request pointer typedef boost::shared_ptr request_ptr; } // end namespace http } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/spdy/0000755000372000001440000000000012420270445017307 5ustar robertouserspion-5.0.7+dfsg.orig/include/pion/spdy/decompressor.hpp0000644000372000001440000000502612420270445022530 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_SPDYDECOMPRESSOR_HEADER__ #define __PION_SPDYDECOMPRESSOR_HEADER__ #include #include #include #include #include namespace pion { // begin namespace pion namespace spdy { // begin namespace spdy /// /// SPDYDecompressor : Decompresses SPDY frames /// class PION_API decompressor { public: /// data size constants enum data_size_t { /// maximum size of an uncompressed spdy header MAX_UNCOMPRESSED_DATA_BUF_SIZE = 16384 }; /// constructs a new decompressor object (default constructor) decompressor(); /// destructor ~decompressor(); /** * decompresses the http content * * @return the uncompressed string, or null on failure */ char* decompress(const char *compressed_data_ptr, boost::uint32_t stream_id, const spdy_control_frame_info& frame, boost::uint32_t header_block_length); protected: /** * decompresses the spdy header * * @return true if successful */ bool spdy_decompress_header(const char *compressed_data_ptr, z_streamp decomp, boost::uint32_t length, boost::uint32_t& uncomp_length); private: /// zlib stream for decompression request packets z_streamp m_request_zstream; /// zlib stream for decompression response packets z_streamp m_response_zstream; /// dictionary identifier boost::uint32_t m_dictionary_id; /// Used for decompressing spdy headers boost::uint8_t m_uncompressed_header[MAX_UNCOMPRESSED_DATA_BUF_SIZE]; // SPDY Dictionary used for zlib decompression static const char SPDY_ZLIB_DICTIONARY[]; }; /// data type for a spdy reader pointer typedef boost::shared_ptr decompressor_ptr; } // end namespace spdy } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/spdy/parser.hpp0000644000372000001440000002050312420270445021314 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_SPDYPARSER_HEADER__ #define __PION_SPDYPARSER_HEADER__ #include #include #include #include #include #include #include #include #ifndef BOOST_SYSTEM_NOEXCEPT #define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT #endif namespace pion { // begin namespace pion namespace spdy { // begin namespace spdy /// /// parser : parsers and reads the SPDY frames /// class PION_API parser { public: /// class-specific error code values enum error_value_t { ERROR_INVALID_SPDY_FRAME = 1, ERROR_INVALID_SPDY_VERSION, ERROR_DECOMPRESSION, ERROR_PROTOCOL_ERROR, ERROR_INTERNAL_SPDY_ERROR, ERROR_MISSING_HEADER_DATA }; /// class-specific error category class error_category_t : public boost::system::error_category { public: const char *name() const BOOST_SYSTEM_NOEXCEPT { return "SPDYParser"; } std::string message(int ev) const { switch (ev) { case ERROR_INVALID_SPDY_FRAME: return "invalid spdy frame"; case ERROR_INVALID_SPDY_VERSION: return "invalid spdy version"; case ERROR_DECOMPRESSION: return "error in decompression"; case ERROR_MISSING_HEADER_DATA: return "missing header data"; } return "SPDYParser error"; } }; /// constructs a new parser object (default constructor) parser(); /// destructor ~parser() {} /** * parse a SPDY packet * * @return boost::tribool result of parsing: * false = SPDY frame has an error, * true = finished parsing SPDY frame, * indeterminate = not yet finished parsing SPDY frame */ boost::tribool parse(http_protocol_info& http_headers, boost::system::error_code& ec, decompressor_ptr& decompressor, const char *packet_ptr, boost::uint32_t& length_packet, boost::uint32_t current_stream_count); /// Get the pointer to the first character to the spdy data contect const char * get_spdy_data_content( ) { return m_last_data_chunk_ptr; } /// Get the pointer to the first character to the spdy data contect const char * get_spdy_read_pointer( ) { return m_read_ptr; } /** * checks if the frame is spdy frame or not * * @return true if it is a frame else returns false */ static spdy_frame_type get_spdy_frame_type(const char *ptr); /** * checks if the frame is spdy control frame or not * * @return true if it is a control frame else returns false */ static bool is_spdy_control_frame(const char *ptr); /** * get the stream id for the spdy control frame * * @return true if it is a control frame else returns false */ static boost::uint32_t get_control_frame_stream_id(const char *ptr); protected: /// resets the read pointer inline void set_read_ptr(const char *ptr) { m_read_ptr = m_current_data_chunk_ptr = ptr; } /// populates the frame for every spdy packet /// Returns false if there was an error else returns true bool populate_frame(boost::system::error_code& ec, spdy_control_frame_info& frame, boost::uint32_t& length_packet, boost::uint32_t& stream_id, http_protocol_info& http_headers); /// creates the unique parser error_category_t static void create_error_category(void); /// returns an instance of parser::error_category_t static inline error_category_t& get_error_category(void) { boost::call_once(parser::create_error_category, m_instance_flag); return *m_error_category_ptr; } /** * sets an error code * * @param ec error code variable to define * @param ev error value to raise */ static inline void set_error(boost::system::error_code& ec, error_value_t ev) { ec = boost::system::error_code(static_cast(ev), get_error_category()); } /** * parses an the header payload for SPDY * */ void parse_header_payload(boost::system::error_code& ec, decompressor_ptr& decompressor, const spdy_control_frame_info& frame, http_protocol_info& http_headers, boost::uint32_t current_stream_count); /** * parses the data for SPDY * */ void parse_spdy_data(boost::system::error_code& ec, const spdy_control_frame_info& frame, boost::uint32_t stream_id, http_protocol_info& http_info); /** * parses an the Settings Frame for SPDY * */ void parse_spdy_settings_frame(boost::system::error_code& ec, const spdy_control_frame_info& frame); /** * parses an the RST stream for SPDY * */ void parse_spdy_rst_stream(boost::system::error_code& ec, const spdy_control_frame_info& frame); /** * parses an the Ping Frame for SPDY * */ void parse_spdy_ping_frame(boost::system::error_code& ec, const spdy_control_frame_info& frame); /** * parses an the GoAway Frame for SPDY * */ void parse_spdy_goaway_frame(boost::system::error_code& ec, const spdy_control_frame_info& frame); /** * parses an the WindowUpdate Frame for SPDY * */ void parse_spdy_window_update_frame(boost::system::error_code& ec, const spdy_control_frame_info& frame); /** * parse a SPDY frame (protected implementation) * * @return boost::tribool result of parsing: * false = SPDY frame has an error, * true = finished parsing SPDY frame, * indeterminate = not yet finished parsing SPDY frame */ boost::tribool parse_spdy_frame(boost::system::error_code& ec, decompressor_ptr& decompressor, http_protocol_info& http_headers, boost::uint32_t& length_packet, boost::uint32_t current_stream_count); private: /// generic read pointer which parses the spdy data const char * m_read_ptr; /// points to the first character of the uncompressed http headers const char * m_uncompressed_ptr; /// SPDY has interleaved frames and this will point to start of the current chunk data const char * m_current_data_chunk_ptr; /// SPDY has interleaved frames and this will point to start of the the last chunk data const char * m_last_data_chunk_ptr; /// primary logging interface used by this class mutable logger m_logger; /// points to a single and unique instance of the HTTPParser ErrorCategory static error_category_t * m_error_category_ptr; /// used to ensure thread safety of the HTTPParser ErrorCategory static boost::once_flag m_instance_flag; }; /// data type for a spdy reader pointer typedef boost::shared_ptr parser_ptr; } // end namespace spdy } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/spdy/types.hpp0000644000372000001440000000532712420270445021173 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_SPDYTYPES_HEADER__ #define __PION_SPDYTYPES_HEADER__ #include #include namespace pion { // begin namespace pion namespace spdy { // begin namespace spdy #define MIN_SPDY_VERSION 3 // The types of SPDY frames #define SPDY_DATA 0 #define SPDY_SYN_STREAM 1 #define SPDY_SYN_REPLY 2 #define SPDY_RST_STREAM 3 #define SPDY_SETTINGS 4 #define SPDY_PING 6 #define SPDY_GOAWAY 7 #define SPDY_HEADERS 8 #define SPDY_WINDOW_UPDATE 9 #define SPDY_CREDENTIAL 10 #define SPDY_INVALID 11 #define SPDY_FLAG_FIN 0x01 #define SPDY_FLAG_UNIDIRECTIONAL 0x02 #define SIZE_OF_BYTE 8 #define NON_SPDY 0 #define HTTP_REQUEST 1 #define HTTP_RESPONSE 2 #define HTTP_DATA 3 #define SPDY_CONTROL 4 /// This structure will be tied to each SPDY frame typedef struct spdy_control_frame_info{ bool control_bit; boost::uint16_t version; boost::uint16_t type; boost::uint8_t flags; boost::uint32_t length; // Actually only 24 bits. } spdy_control_frame_info; /// This structure will be tied to each SPDY header frame. /// Only applies to frames containing headers: SYN_STREAM, SYN_REPLY, HEADERS /// Note that there may be multiple SPDY frames in one packet. typedef struct _spdy_header_info{ boost::uint32_t stream_id; boost::uint8_t *header_block; boost::uint8_t header_block_len; boost::uint16_t frame_type; } spdy_header_info; /// This structure contains the HTTP Protocol information typedef struct _http_protocol_info_t{ std::map http_headers; boost::uint32_t http_type; boost::uint32_t stream_id; boost::uint32_t data_offset; boost::uint32_t data_size; bool last_chunk; _http_protocol_info_t() : http_type(NON_SPDY), stream_id(0), data_offset(0), data_size(0), last_chunk(false){} } http_protocol_info; enum spdy_frame_type{ spdy_data_frame = 1, spdy_control_frame = 2, spdy_invalid_frame = 3 }; } // end namespace spdy } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/spdy/Makefile.am0000644000372000001440000000033612420270445021345 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- pion_spdy_includedir = $(includedir)/pion/spdy pion_spdy_include_HEADERS = \ decompressor.hpp parser.hpp types.hpp pion-5.0.7+dfsg.orig/include/pion/tcp/0000755000372000001440000000000012420270445017116 5ustar robertouserspion-5.0.7+dfsg.orig/include/pion/tcp/timer.hpp0000644000372000001440000000436212420270445020754 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_TCP_TIMER_HEADER__ #define __PION_TCP_TIMER_HEADER__ #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace tcp { // begin namespace tcp /// /// timer: helper class used to time-out TCP connections /// class PION_API timer : public boost::enable_shared_from_this { public: /** * creates a new TCP connection timer * * @param conn_ptr pointer to TCP connection to monitor */ timer(tcp::connection_ptr& conn_ptr); /** * starts a timer for closing a TCP connection * * @param seconds number of seconds before the timeout triggers */ void start(const boost::uint32_t seconds); /// cancel the timer (operation completed) void cancel(void); private: /** * Callback handler for the deadline timer * * @param ec deadline timer error status code */ void timer_callback(const boost::system::error_code& ec); /// pointer to the TCP connection that is being monitored tcp::connection_ptr m_conn_ptr; /// deadline timer used to timeout TCP operations boost::asio::deadline_timer m_timer; /// mutex used to synchronize the TCP connection timer boost::mutex m_mutex; /// true if the deadline timer is active bool m_timer_active; /// true if the timer was cancelled (operation completed) bool m_was_cancelled; }; /// shared pointer to a timer object typedef boost::shared_ptr timer_ptr; } // end namespace tcp } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/tcp/stream.hpp0000644000372000001440000004414412420270445021131 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_TCP_STREAM_HEADER__ #define __PION_TCP_STREAM_HEADER__ #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace tcp { // begin namespace tcp /// /// stream_buffer: std::basic_streambuf wrapper for TCP network connections. /// Based in part on section 13.13.3 of "The Standard C++ Library" /// by Nicolai M. Josuttis, published in 1999 by Addison-Wesley /// class stream_buffer : public std::basic_streambuf > { public: // data type definitions required for iostream compatability typedef char char_type; typedef std::char_traits::int_type int_type; typedef std::char_traits::off_type off_type; typedef std::char_traits::pos_type pos_type; typedef std::char_traits traits_type; // some integer constants used within stream_buffer enum { PUT_BACK_MAX = 10, //< number of bytes that can be put back into the read buffer WRITE_BUFFER_SIZE = 8192 //< size of the write buffer }; /** * constructs a TCP stream buffer object for an existing TCP connection * * @param conn_ptr pointer to the TCP connection to use for reading & writing */ explicit stream_buffer(tcp::connection_ptr& conn_ptr) : m_conn_ptr(conn_ptr), m_read_buf(m_conn_ptr->get_read_buffer().c_array()) { setup_buffers(); } /** * constructs a TCP stream buffer object for a new TCP connection * * @param io_service asio service associated with the connection * @param ssl_flag if true then the connection will be encrypted using SSL */ explicit stream_buffer(boost::asio::io_service& io_service, const bool ssl_flag = false) : m_conn_ptr(new connection(io_service, ssl_flag)), m_read_buf(m_conn_ptr->get_read_buffer().c_array()) { setup_buffers(); } /** * constructs a TCP stream buffer object for a new SSL/TCP connection * * @param io_service asio service associated with the connection * @param ssl_context asio ssl context associated with the connection */ stream_buffer(boost::asio::io_service& io_service, connection::ssl_context_type& ssl_context) : m_conn_ptr(new connection(io_service, ssl_context)), m_read_buf(m_conn_ptr->get_read_buffer().c_array()) { setup_buffers(); } /// virtual destructor flushes the write buffer virtual ~stream_buffer() { sync(); } /// returns a reference to the current TCP connection connection& get_connection(void) { return *m_conn_ptr; } /// returns a const reference to the current TCP connection const connection& get_connection(void) const { return *m_conn_ptr; } protected: /// sets up the read and write buffers for input and output inline void setup_buffers(void) { // use the TCP connection's read buffer and allow for bytes to be put back setg(m_read_buf+PUT_BACK_MAX, m_read_buf+PUT_BACK_MAX, m_read_buf+PUT_BACK_MAX); // set write buffer size-1 so that we have an extra char avail for overflow setp(m_write_buf, m_write_buf+(WRITE_BUFFER_SIZE-1)); } /** * writes data in the output buffer to the TCP connection * * @return int_type the number of bytes sent, or eof() if there was an error */ inline int_type flush_output(void) { const std::streamsize bytes_to_send = std::streamsize(pptr() - pbase()); int_type bytes_sent = 0; if (bytes_to_send > 0) { boost::mutex::scoped_lock async_lock(m_async_mutex); m_bytes_transferred = 0; m_conn_ptr->async_write(boost::asio::buffer(pbase(), bytes_to_send), boost::bind(&stream_buffer::operation_finished, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); m_async_done.wait(async_lock); bytes_sent = m_bytes_transferred; pbump(-bytes_sent); if (m_async_error) bytes_sent = traits_type::eof(); } return bytes_sent; } /** * this function is called when the read buffer has no more characters available * * @return int_type the next character available for reading, or eof() if there was an error */ virtual int_type underflow(void) { // first check if we still have bytes available in the read buffer if (gptr() < egptr()) return traits_type::to_int_type(*gptr()); // calculate the number of bytes we will allow to be put back std::streamsize put_back_num = std::streamsize(gptr() - eback()); if (put_back_num > PUT_BACK_MAX) put_back_num = PUT_BACK_MAX; // copy the last bytes read to the beginning of the buffer (for put back) if (put_back_num > 0) memmove(m_read_buf+(PUT_BACK_MAX-put_back_num), gptr()-put_back_num, put_back_num); // read data from the TCP connection // note that this has to be an ansynchronous call; otherwise, it cannot // be cancelled by other threads and will block forever (such as during shutdown) boost::mutex::scoped_lock async_lock(m_async_mutex); m_bytes_transferred = 0; m_conn_ptr->async_read_some(boost::asio::buffer(m_read_buf+PUT_BACK_MAX, connection::READ_BUFFER_SIZE-PUT_BACK_MAX), boost::bind(&stream_buffer::operation_finished, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); m_async_done.wait(async_lock); if (m_async_error) return traits_type::eof(); // reset buffer pointers now that data is available setg(m_read_buf+(PUT_BACK_MAX-put_back_num), //< beginning of putback bytes m_read_buf+PUT_BACK_MAX, //< read position m_read_buf+PUT_BACK_MAX+m_bytes_transferred); //< end of buffer // return next character available return traits_type::to_int_type(*gptr()); } /** * this function is called when the write buffer for the stream is full * * @param c character that has not been written yet, or eof() if we are flushing * @return int_type the last character written, or eof() if there was an error */ virtual int_type overflow(int_type c) { if (! traits_type::eq_int_type(c, traits_type::eof())) { // character is not eof -> add it to the end of the write buffer // we can push this to the back of the write buffer because we set // the size of the write buffer to 1 less than the actual size using setp() *pptr() = c; pbump(1); } // flush data in the write buffer by sending it to the TCP connection return ((flush_output() == traits_type::eof()) ? traits_type::eof() : traits_type::not_eof(c)); } /** * writes a sequence of characters * * @param s pointer to a sequence of characters * @param n number of characters in the sequence to write * * @return std::streamsize number of character written */ virtual std::streamsize xsputn(const char_type *s, std::streamsize n) { const std::streamsize bytes_available = std::streamsize(epptr() - pptr()); std::streamsize bytes_sent = 0; if (bytes_available >= n) { // there is enough room in the buffer -> just put it in there memcpy(pptr(), s, n); pbump(n); bytes_sent = n; } else { // there is not enough room left in the buffer if (bytes_available > 0) { // fill up the buffer memcpy(pptr(), s, bytes_available); pbump(bytes_available); } // flush data in the write buffer by sending it to the TCP connection if (flush_output() == traits_type::eof()) return 0; if ((n-bytes_available) >= (WRITE_BUFFER_SIZE-1)) { // the remaining data to send is larger than the buffer available // send it all now rather than buffering boost::mutex::scoped_lock async_lock(m_async_mutex); m_bytes_transferred = 0; m_conn_ptr->async_write(boost::asio::buffer(s+bytes_available, n-bytes_available), boost::bind(&stream_buffer::operation_finished, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); m_async_done.wait(async_lock); bytes_sent = bytes_available + m_bytes_transferred; } else { // the buffer is larger than the remaining data // put remaining data to the beginning of the output buffer memcpy(pbase(), s+bytes_available, n-bytes_available); pbump(n-bytes_available); bytes_sent = n; } } return bytes_sent; } /** * reads a sequence of characters * * @param s pointer to where the sequence of characters will be stored * @param n number of characters in the sequence to read * * @return std::streamsize number of character read */ virtual std::streamsize xsgetn(char_type *s, std::streamsize n) { std::streamsize bytes_remaining = n; while (bytes_remaining > 0) { const std::streamsize bytes_available = std::streamsize(egptr() - gptr()); const std::streamsize bytes_next_read = ((bytes_available >= bytes_remaining) ? bytes_remaining : bytes_available); // copy available input data from buffer if (bytes_next_read > 0) { memcpy(s, gptr(), bytes_next_read); gbump(bytes_next_read); bytes_remaining -= bytes_next_read; s += bytes_next_read; } if (bytes_remaining > 0) { // call underflow() to read more data if (traits_type::eq_int_type(underflow(), traits_type::eof())) break; } } return(n-bytes_remaining); } /** * synchronize buffers with the TCP connection * * @return 0 if successful, -1 if there was an error */ virtual int_type sync(void) { return ((flush_output() == traits_type::eof()) ? -1 : 0); } private: /// function called after an asynchronous operation has completed inline void operation_finished(const boost::system::error_code& error_code, std::size_t bytes_transferred) { boost::mutex::scoped_lock async_lock(m_async_mutex); m_async_error = error_code; m_bytes_transferred = bytes_transferred; m_async_done.notify_one(); } /// pointer to the underlying TCP connection used for reading & writing tcp::connection_ptr m_conn_ptr; /// condition signaled whenever an asynchronous operation has completed boost::mutex m_async_mutex; /// condition signaled whenever an asynchronous operation has completed boost::condition m_async_done; /// used to keep track of the result from the last asynchronous operation boost::system::error_code m_async_error; /// the number of bytes transferred by the last asynchronous operation std::size_t m_bytes_transferred; /// pointer to the start of the TCP connection's read buffer char_type * m_read_buf; /// buffer used to write output char_type m_write_buf[WRITE_BUFFER_SIZE]; }; /// /// stream: std::basic_iostream wrapper for TCP network connections /// class stream : public std::basic_iostream > { public: // data type definitions required for iostream compatability typedef char char_type; typedef std::char_traits::int_type int_type; typedef std::char_traits::off_type off_type; typedef std::char_traits::pos_type pos_type; typedef std::char_traits traits_type; /** * constructs a TCP stream object for an existing TCP connection * * @param conn_ptr pointer to the TCP connection to use for reading & writing */ explicit stream(tcp::connection_ptr& conn_ptr) : std::basic_iostream >(NULL), m_tcp_buf(conn_ptr) { // initialize basic_iostream with pointer to the stream buffer std::basic_ios >::init(&m_tcp_buf); } /** * constructs a TCP stream object for a new TCP connection * * @param io_service asio service associated with the connection * @param ssl_flag if true then the connection will be encrypted using SSL */ explicit stream(boost::asio::io_service& io_service, const bool ssl_flag = false) : std::basic_iostream >(NULL), m_tcp_buf(io_service, ssl_flag) { // initialize basic_iostream with pointer to the stream buffer std::basic_ios >::init(&m_tcp_buf); } /** * constructs a TCP stream object for a new SSL/TCP connection * * @param io_service asio service associated with the connection * @param ssl_context asio ssl context associated with the connection */ stream(boost::asio::io_service& io_service, connection::ssl_context_type& ssl_context) : std::basic_iostream >(NULL), m_tcp_buf(io_service, ssl_context) { // initialize basic_iostream with pointer to the stream buffer std::basic_ios >::init(&m_tcp_buf); } /** * accepts a new tcp connection and performs SSL handshake if necessary * * @param tcp_acceptor object used to accept new connections * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::accept() */ inline boost::system::error_code accept(boost::asio::ip::tcp::acceptor& tcp_acceptor) { boost::system::error_code ec = m_tcp_buf.get_connection().accept(tcp_acceptor); if (! ec && get_ssl_flag()) ec = m_tcp_buf.get_connection().handshake_server(); return ec; } /** * connects to a remote endpoint and performs SSL handshake if necessary * * @param tcp_endpoint remote endpoint to connect to * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::connect() */ inline boost::system::error_code connect(boost::asio::ip::tcp::endpoint& tcp_endpoint) { boost::system::error_code ec = m_tcp_buf.get_connection().connect(tcp_endpoint); if (! ec && get_ssl_flag()) ec = m_tcp_buf.get_connection().handshake_client(); return ec; } /** * connects to a (IPv4) remote endpoint and performs SSL handshake if necessary * * @param remote_addr remote IP address (v4) to connect to * @param remote_port remote port number to connect to * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::connect() */ inline boost::system::error_code connect(const boost::asio::ip::address& remote_addr, const unsigned int remote_port) { boost::asio::ip::tcp::endpoint tcp_endpoint(remote_addr, remote_port); boost::system::error_code ec = m_tcp_buf.get_connection().connect(tcp_endpoint); if (! ec && get_ssl_flag()) ec = m_tcp_buf.get_connection().handshake_client(); return ec; } /// closes the tcp connection inline void close(void) { m_tcp_buf.get_connection().close(); } /* Use close instead; basic_socket::cancel is deprecated for Windows XP. /// cancels any asynchronous operations pending on the tcp connection inline void cancel(void) { m_tcp_buf.get_connection().cancel(); } */ /// returns true if the connection is currently open inline bool is_open(void) const { return m_tcp_buf.get_connection().is_open(); } /// returns true if the connection is encrypted using SSL inline bool get_ssl_flag(void) const { return m_tcp_buf.get_connection().get_ssl_flag(); } /// returns the client's IP address inline boost::asio::ip::address get_remote_ip(void) const { return m_tcp_buf.get_connection().get_remote_ip(); } /// returns a pointer to the stream buffer in use stream_buffer *rdbuf(void) { return &m_tcp_buf; } private: /// the underlying TCP stream buffer used for reading & writing stream_buffer m_tcp_buf; }; } // end namespace tcp } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/tcp/connection.hpp0000644000372000001440000006564412420270445022005 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_TCP_CONNECTION_HEADER__ #define __PION_TCP_CONNECTION_HEADER__ #ifdef PION_HAVE_SSL #ifdef PION_XCODE // ignore openssl warnings if building with XCode #pragma GCC system_header #endif #include #endif #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace tcp { // begin namespace tcp /// /// connection: represents a single tcp connection /// class connection : public boost::enable_shared_from_this, private boost::noncopyable { public: /// data type for the connection's lifecycle state enum lifecycle_type { LIFECYCLE_CLOSE, LIFECYCLE_KEEPALIVE, LIFECYCLE_PIPELINED }; /// size of the read buffer enum { READ_BUFFER_SIZE = 8192 }; /// data type for a function that handles TCP connection objects typedef boost::function1 > connection_handler; /// data type for an I/O read buffer typedef boost::array read_buffer_type; /// data type for a socket connection typedef boost::asio::ip::tcp::socket socket_type; #ifdef PION_HAVE_SSL /// data type for an SSL socket connection typedef boost::asio::ssl::stream ssl_socket_type; /// data type for SSL configuration context typedef boost::asio::ssl::context ssl_context_type; #else class ssl_socket_type { public: ssl_socket_type(boost::asio::io_service& io_service) : m_socket(io_service) {} inline socket_type& next_layer(void) { return m_socket; } inline const socket_type& next_layer(void) const { return m_socket; } inline socket_type::lowest_layer_type& lowest_layer(void) { return m_socket.lowest_layer(); } inline const socket_type::lowest_layer_type& lowest_layer(void) const { return m_socket.lowest_layer(); } inline void shutdown(void) {} private: socket_type m_socket; }; typedef int ssl_context_type; #endif /** * creates new shared connection objects * * @param io_service asio service associated with the connection * @param ssl_context asio ssl context associated with the connection * @param ssl_flag if true then the connection will be encrypted using SSL * @param finished_handler function called when a server has finished * handling the connection */ static inline boost::shared_ptr create(boost::asio::io_service& io_service, ssl_context_type& ssl_context, const bool ssl_flag, connection_handler finished_handler) { return boost::shared_ptr(new connection(io_service, ssl_context, ssl_flag, finished_handler)); } /** * creates a new connection object * * @param io_service asio service associated with the connection * @param ssl_flag if true then the connection will be encrypted using SSL */ explicit connection(boost::asio::io_service& io_service, const bool ssl_flag = false) : #ifdef PION_HAVE_SSL m_ssl_context(io_service, boost::asio::ssl::context::sslv23), m_ssl_socket(io_service, m_ssl_context), m_ssl_flag(ssl_flag), #else m_ssl_context(0), m_ssl_socket(io_service), m_ssl_flag(false), #endif m_lifecycle(LIFECYCLE_CLOSE) { save_read_pos(NULL, NULL); } /** * creates a new connection object for SSL * * @param io_service asio service associated with the connection * @param ssl_context asio ssl context associated with the connection */ connection(boost::asio::io_service& io_service, ssl_context_type& ssl_context) : #ifdef PION_HAVE_SSL m_ssl_context(io_service, boost::asio::ssl::context::sslv23), m_ssl_socket(io_service, ssl_context), m_ssl_flag(true), #else m_ssl_context(0), m_ssl_socket(io_service), m_ssl_flag(false), #endif m_lifecycle(LIFECYCLE_CLOSE) { save_read_pos(NULL, NULL); } /// returns true if the connection is currently open inline bool is_open(void) const { return const_cast(m_ssl_socket).lowest_layer().is_open(); } /// closes the tcp socket and cancels any pending asynchronous operations inline void close(void) { if (is_open()) { try { // shutting down SSL will wait forever for a response from the remote end, // which causes it to hang indefinitely if the other end died unexpectedly // if (get_ssl_flag()) m_ssl_socket.shutdown(); // windows seems to require this otherwise it doesn't // recognize that connections have been closed m_ssl_socket.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both); } catch (...) {} // ignore exceptions // close the underlying socket (ignore errors) boost::system::error_code ec; m_ssl_socket.next_layer().close(ec); } } /// cancels any asynchronous operations pending on the socket. /// there is no good way to do this on windows until vista or later (0x0600) /// see http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/reference/basic_stream_socket/cancel/overload2.html /// note that the asio docs are misleading because close() is not thread-safe, /// and the suggested #define statements cause WAY too much trouble and heartache inline void cancel(void) { #if !defined(_MSC_VER) || (_WIN32_WINNT >= 0x0600) boost::system::error_code ec; m_ssl_socket.next_layer().cancel(ec); #endif } /// virtual destructor virtual ~connection() { close(); } /** * asynchronously accepts a new tcp connection * * @param tcp_acceptor object used to accept new connections * @param handler called after a new connection has been accepted * * @see boost::asio::basic_socket_acceptor::async_accept() */ template inline void async_accept(boost::asio::ip::tcp::acceptor& tcp_acceptor, AcceptHandler handler) { tcp_acceptor.async_accept(m_ssl_socket.lowest_layer(), handler); } /** * accepts a new tcp connection (blocks until established) * * @param tcp_acceptor object used to accept new connections * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::accept() */ inline boost::system::error_code accept(boost::asio::ip::tcp::acceptor& tcp_acceptor) { boost::system::error_code ec; tcp_acceptor.accept(m_ssl_socket.lowest_layer(), ec); return ec; } /** * asynchronously connects to a remote endpoint * * @param tcp_endpoint remote endpoint to connect to * @param handler called after a new connection has been established * * @see boost::asio::basic_socket_acceptor::async_connect() */ template inline void async_connect(const boost::asio::ip::tcp::endpoint& tcp_endpoint, ConnectHandler handler) { m_ssl_socket.lowest_layer().async_connect(tcp_endpoint, handler); } /** * asynchronously connects to a (IPv4) remote endpoint * * @param remote_addr remote IP address (v4) to connect to * @param remote_port remote port number to connect to * @param handler called after a new connection has been established * * @see boost::asio::basic_socket_acceptor::async_connect() */ template inline void async_connect(const boost::asio::ip::address& remote_addr, const unsigned int remote_port, ConnectHandler handler) { boost::asio::ip::tcp::endpoint tcp_endpoint(remote_addr, remote_port); async_connect(tcp_endpoint, handler); } /** * connects to a remote endpoint (blocks until established) * * @param tcp_endpoint remote endpoint to connect to * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::connect() */ inline boost::system::error_code connect(boost::asio::ip::tcp::endpoint& tcp_endpoint) { boost::system::error_code ec; m_ssl_socket.lowest_layer().connect(tcp_endpoint, ec); return ec; } /** * connects to a (IPv4) remote endpoint (blocks until established) * * @param remote_addr remote IP address (v4) to connect to * @param remote_port remote port number to connect to * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::connect() */ inline boost::system::error_code connect(const boost::asio::ip::address& remote_addr, const unsigned int remote_port) { boost::asio::ip::tcp::endpoint tcp_endpoint(remote_addr, remote_port); return connect(tcp_endpoint); } /** * connects to a remote endpoint with hostname lookup * * @param remote_server hostname of the remote server to connect to * @param remote_port remote port number to connect to * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::basic_socket_acceptor::connect() */ inline boost::system::error_code connect(const std::string& remote_server, const unsigned int remote_port) { // query a list of matching endpoints boost::system::error_code ec; boost::asio::ip::tcp::resolver resolver(m_ssl_socket.lowest_layer().get_io_service()); boost::asio::ip::tcp::resolver::query query(remote_server, boost::lexical_cast(remote_port), boost::asio::ip::tcp::resolver::query::numeric_service); boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, ec); if (ec) return ec; // try each one until we are successful ec = boost::asio::error::host_not_found; boost::asio::ip::tcp::resolver::iterator end; while (ec && endpoint_iterator != end) { boost::asio::ip::tcp::endpoint ep(endpoint_iterator->endpoint()); ++endpoint_iterator; ec = connect(ep); if (ec) close(); } return ec; } /** * asynchronously performs client-side SSL handshake for a new connection * * @param handler called after the ssl handshake has completed * * @see boost::asio::ssl::stream::async_handshake() */ template inline void async_handshake_client(SSLHandshakeHandler handler) { #ifdef PION_HAVE_SSL m_ssl_socket.async_handshake(boost::asio::ssl::stream_base::client, handler); m_ssl_flag = true; #endif } /** * asynchronously performs server-side SSL handshake for a new connection * * @param handler called after the ssl handshake has completed * * @see boost::asio::ssl::stream::async_handshake() */ template inline void async_handshake_server(SSLHandshakeHandler handler) { #ifdef PION_HAVE_SSL m_ssl_socket.async_handshake(boost::asio::ssl::stream_base::server, handler); m_ssl_flag = true; #endif } /** * performs client-side SSL handshake for a new connection (blocks until finished) * * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::ssl::stream::handshake() */ inline boost::system::error_code handshake_client(void) { boost::system::error_code ec; #ifdef PION_HAVE_SSL m_ssl_socket.handshake(boost::asio::ssl::stream_base::client, ec); m_ssl_flag = true; #endif return ec; } /** * performs server-side SSL handshake for a new connection (blocks until finished) * * @return boost::system::error_code contains error code if the connection fails * * @see boost::asio::ssl::stream::handshake() */ inline boost::system::error_code handshake_server(void) { boost::system::error_code ec; #ifdef PION_HAVE_SSL m_ssl_socket.handshake(boost::asio::ssl::stream_base::server, ec); m_ssl_flag = true; #endif return ec; } /** * asynchronously reads some data into the connection's read buffer * * @param handler called after the read operation has completed * * @see boost::asio::basic_stream_socket::async_read_some() */ template inline void async_read_some(ReadHandler handler) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) m_ssl_socket.async_read_some(boost::asio::buffer(m_read_buffer), handler); else #endif m_ssl_socket.next_layer().async_read_some(boost::asio::buffer(m_read_buffer), handler); } /** * asynchronously reads some data into the connection's read buffer * * @param read_buffer the buffer to read data into * @param handler called after the read operation has completed * * @see boost::asio::basic_stream_socket::async_read_some() */ template inline void async_read_some(ReadBufferType read_buffer, ReadHandler handler) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) m_ssl_socket.async_read_some(read_buffer, handler); else #endif m_ssl_socket.next_layer().async_read_some(read_buffer, handler); } /** * reads some data into the connection's read buffer (blocks until finished) * * @param ec contains error code if the read fails * @return std::size_t number of bytes read * * @see boost::asio::basic_stream_socket::read_some() */ inline std::size_t read_some(boost::system::error_code& ec) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) return m_ssl_socket.read_some(boost::asio::buffer(m_read_buffer), ec); else #endif return m_ssl_socket.next_layer().read_some(boost::asio::buffer(m_read_buffer), ec); } /** * reads some data into the connection's read buffer (blocks until finished) * * @param read_buffer the buffer to read data into * @param ec contains error code if the read fails * @return std::size_t number of bytes read * * @see boost::asio::basic_stream_socket::read_some() */ template inline std::size_t read_some(ReadBufferType read_buffer, boost::system::error_code& ec) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) return m_ssl_socket.read_some(read_buffer, ec); else #endif return m_ssl_socket.next_layer().read_some(read_buffer, ec); } /** * asynchronously reads data into the connection's read buffer until * completion_condition is met * * @param completion_condition determines if the read operation is complete * @param handler called after the read operation has completed * * @see boost::asio::async_read() */ template inline void async_read(CompletionCondition completion_condition, ReadHandler handler) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) boost::asio::async_read(m_ssl_socket, boost::asio::buffer(m_read_buffer), completion_condition, handler); else #endif boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(m_read_buffer), completion_condition, handler); } /** * asynchronously reads data from the connection until completion_condition * is met * * @param buffers one or more buffers into which the data will be read * @param completion_condition determines if the read operation is complete * @param handler called after the read operation has completed * * @see boost::asio::async_read() */ template inline void async_read(const MutableBufferSequence& buffers, CompletionCondition completion_condition, ReadHandler handler) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) boost::asio::async_read(m_ssl_socket, buffers, completion_condition, handler); else #endif boost::asio::async_read(m_ssl_socket.next_layer(), buffers, completion_condition, handler); } /** * reads data into the connection's read buffer until completion_condition * is met (blocks until finished) * * @param completion_condition determines if the read operation is complete * @param ec contains error code if the read fails * @return std::size_t number of bytes read * * @see boost::asio::read() */ template inline std::size_t read(CompletionCondition completion_condition, boost::system::error_code& ec) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) return boost::asio::async_read(m_ssl_socket, boost::asio::buffer(m_read_buffer), completion_condition, ec); else #endif return boost::asio::async_read(m_ssl_socket.next_layer(), boost::asio::buffer(m_read_buffer), completion_condition, ec); } /** * reads data from the connection until completion_condition is met * (blocks until finished) * * @param buffers one or more buffers into which the data will be read * @param completion_condition determines if the read operation is complete * @param ec contains error code if the read fails * @return std::size_t number of bytes read * * @see boost::asio::read() */ template inline std::size_t read(const MutableBufferSequence& buffers, CompletionCondition completion_condition, boost::system::error_code& ec) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) return boost::asio::read(m_ssl_socket, buffers, completion_condition, ec); else #endif return boost::asio::read(m_ssl_socket.next_layer(), buffers, completion_condition, ec); } /** * asynchronously writes data to the connection * * @param buffers one or more buffers containing the data to be written * @param handler called after the data has been written * * @see boost::asio::async_write() */ template inline void async_write(const ConstBufferSequence& buffers, write_handler_t handler) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) boost::asio::async_write(m_ssl_socket, buffers, handler); else #endif boost::asio::async_write(m_ssl_socket.next_layer(), buffers, handler); } /** * writes data to the connection (blocks until finished) * * @param buffers one or more buffers containing the data to be written * @param ec contains error code if the write fails * @return std::size_t number of bytes written * * @see boost::asio::write() */ template inline std::size_t write(const ConstBufferSequence& buffers, boost::system::error_code& ec) { #ifdef PION_HAVE_SSL if (get_ssl_flag()) return boost::asio::write(m_ssl_socket, buffers, boost::asio::transfer_all(), ec); else #endif return boost::asio::write(m_ssl_socket.next_layer(), buffers, boost::asio::transfer_all(), ec); } /// This function should be called when a server has finished handling /// the connection inline void finish(void) { if (m_finished_handler) m_finished_handler(shared_from_this()); } /// returns true if the connection is encrypted using SSL inline bool get_ssl_flag(void) const { return m_ssl_flag; } /// sets the lifecycle type for the connection inline void set_lifecycle(lifecycle_type t) { m_lifecycle = t; } /// returns the lifecycle type for the connection inline lifecycle_type get_lifecycle(void) const { return m_lifecycle; } /// returns true if the connection should be kept alive inline bool get_keep_alive(void) const { return m_lifecycle != LIFECYCLE_CLOSE; } /// returns true if the HTTP requests are pipelined inline bool get_pipelined(void) const { return m_lifecycle == LIFECYCLE_PIPELINED; } /// returns the buffer used for reading data from the TCP connection inline read_buffer_type& get_read_buffer(void) { return m_read_buffer; } /** * saves a read position bookmark * * @param read_ptr points to the next character to be consumed in the read_buffer * @param read_end_ptr points to the end of the read_buffer (last byte + 1) */ inline void save_read_pos(const char *read_ptr, const char *read_end_ptr) { m_read_position.first = read_ptr; m_read_position.second = read_end_ptr; } /** * loads a read position bookmark * * @param read_ptr points to the next character to be consumed in the read_buffer * @param read_end_ptr points to the end of the read_buffer (last byte + 1) */ inline void load_read_pos(const char *&read_ptr, const char *&read_end_ptr) const { read_ptr = m_read_position.first; read_end_ptr = m_read_position.second; } /// returns an ASIO endpoint for the client connection inline boost::asio::ip::tcp::endpoint get_remote_endpoint(void) const { boost::asio::ip::tcp::endpoint remote_endpoint; try { // const_cast is required since lowest_layer() is only defined non-const in asio remote_endpoint = const_cast(m_ssl_socket).lowest_layer().remote_endpoint(); } catch (boost::system::system_error& /* e */) { // do nothing } return remote_endpoint; } /// returns the client's IP address inline boost::asio::ip::address get_remote_ip(void) const { return get_remote_endpoint().address(); } /// returns the client's port number inline unsigned short get_remote_port(void) const { return get_remote_endpoint().port(); } /// returns reference to the io_service used for async operations inline boost::asio::io_service& get_io_service(void) { return m_ssl_socket.lowest_layer().get_io_service(); } /// returns non-const reference to underlying TCP socket object inline socket_type& get_socket(void) { return m_ssl_socket.next_layer(); } /// returns non-const reference to underlying SSL socket object inline ssl_socket_type& get_ssl_socket(void) { return m_ssl_socket; } /// returns const reference to underlying TCP socket object inline const socket_type& get_socket(void) const { return const_cast(m_ssl_socket).next_layer(); } /// returns const reference to underlying SSL socket object inline const ssl_socket_type& get_ssl_socket(void) const { return m_ssl_socket; } protected: /** * protected constructor restricts creation of objects (use create()) * * @param io_service asio service associated with the connection * @param ssl_context asio ssl context associated with the connection * @param ssl_flag if true then the connection will be encrypted using SSL * @param finished_handler function called when a server has finished * handling the connection */ connection(boost::asio::io_service& io_service, ssl_context_type& ssl_context, const bool ssl_flag, connection_handler finished_handler) : #ifdef PION_HAVE_SSL m_ssl_context(io_service, boost::asio::ssl::context::sslv23), m_ssl_socket(io_service, ssl_context), m_ssl_flag(ssl_flag), #else m_ssl_context(0), m_ssl_socket(io_service), m_ssl_flag(false), #endif m_lifecycle(LIFECYCLE_CLOSE), m_finished_handler(finished_handler) { save_read_pos(NULL, NULL); } private: /// data type for a read position bookmark typedef std::pair read_pos_type; /// context object for the SSL connection socket ssl_context_type m_ssl_context; /// SSL connection socket ssl_socket_type m_ssl_socket; /// true if the connection is encrypted using SSL bool m_ssl_flag; /// buffer used for reading data from the TCP connection read_buffer_type m_read_buffer; /// saved read position bookmark read_pos_type m_read_position; /// lifecycle state for the connection lifecycle_type m_lifecycle; /// function called when a server has finished handling the connection connection_handler m_finished_handler; }; /// data type for a connection pointer typedef boost::shared_ptr connection_ptr; } // end namespace tcp } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/tcp/Makefile.am0000644000372000001440000000034112420270445021150 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- pion_tcp_includedir = $(includedir)/pion/tcp pion_tcp_include_HEADERS = connection.hpp server.hpp stream.hpp timer.hpp pion-5.0.7+dfsg.orig/include/pion/tcp/server.hpp0000644000372000001440000002155212420270445021142 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_TCP_SERVER_HEADER__ #define __PION_TCP_SERVER_HEADER__ #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace tcp { // begin namespace tcp /// /// tcp::server: a multi-threaded, asynchronous TCP server /// class PION_API server : private boost::noncopyable { public: /// default destructor virtual ~server() { if (m_is_listening) stop(false); } /// starts listening for new connections void start(void); /** * stops listening for new connections * * @param wait_until_finished if true, blocks until all pending connections have closed */ void stop(bool wait_until_finished = false); /// the calling thread will sleep until the server has stopped listening for connections void join(void); /** * configures server for SSL using a PEM-encoded RSA private key file * * @param pem_key_file name of the file containing a PEM-encoded private key */ void set_ssl_key_file(const std::string& pem_key_file); /// returns the number of active tcp connections std::size_t get_connections(void) const; /// returns tcp port number that the server listens for connections on inline unsigned int get_port(void) const { return m_endpoint.port(); } /// sets tcp port number that the server listens for connections on inline void set_port(unsigned int p) { m_endpoint.port(p); } /// returns IP address that the server listens for connections on inline boost::asio::ip::address get_address(void) const { return m_endpoint.address(); } /// sets IP address that the server listens for connections on inline void set_address(const boost::asio::ip::address& addr) { m_endpoint.address(addr); } /// returns tcp endpoint that the server listens for connections on inline const boost::asio::ip::tcp::endpoint& get_endpoint(void) const { return m_endpoint; } /// sets tcp endpoint that the server listens for connections on inline void set_endpoint(const boost::asio::ip::tcp::endpoint& ep) { m_endpoint = ep; } /// returns true if the server uses SSL to encrypt connections inline bool get_ssl_flag(void) const { return m_ssl_flag; } /// sets value of SSL flag (true if the server uses SSL to encrypt connections) inline void set_ssl_flag(bool b = true) { m_ssl_flag = b; } /// returns the SSL context for configuration inline connection::ssl_context_type& get_ssl_context_type(void) { return m_ssl_context; } /// returns true if the server is listening for connections inline bool is_listening(void) const { return m_is_listening; } /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// returns the logger currently in use inline logger get_logger(void) { return m_logger; } /// returns mutable reference to the TCP connection acceptor inline boost::asio::ip::tcp::acceptor& get_acceptor(void) { return m_tcp_acceptor; } /// returns const reference to the TCP connection acceptor inline const boost::asio::ip::tcp::acceptor& get_acceptor(void) const { return m_tcp_acceptor; } protected: /** * protected constructor so that only derived objects may be created * * @param tcp_port port number used to listen for new connections (IPv4) */ explicit server(const unsigned int tcp_port); /** * protected constructor so that only derived objects may be created * * @param endpoint TCP endpoint used to listen for new connections (see ASIO docs) */ explicit server(const boost::asio::ip::tcp::endpoint& endpoint); /** * protected constructor so that only derived objects may be created * * @param sched the scheduler that will be used to manage worker threads * @param tcp_port port number used to listen for new connections (IPv4) */ explicit server(scheduler& sched, const unsigned int tcp_port = 0); /** * protected constructor so that only derived objects may be created * * @param sched the scheduler that will be used to manage worker threads * @param endpoint TCP endpoint used to listen for new connections (see ASIO docs) */ server(scheduler& sched, const boost::asio::ip::tcp::endpoint& endpoint); /** * handles a new TCP connection; derived classes SHOULD override this * since the default behavior does nothing * * @param tcp_conn the new TCP connection to handle */ virtual void handle_connection(tcp::connection_ptr& tcp_conn) { tcp_conn->set_lifecycle(connection::LIFECYCLE_CLOSE); // make sure it will get closed tcp_conn->finish(); } /// called before the TCP server starts listening for new connections virtual void before_starting(void) {} /// called after the TCP server has stopped listing for new connections virtual void after_stopping(void) {} /// returns an async I/O service used to schedule work inline boost::asio::io_service& get_io_service(void) { return m_active_scheduler.get_io_service(); } /// primary logging interface used by this class logger m_logger; private: /// handles a request to stop the server void handle_stop_request(void); /// listens for a new connection void listen(void); /** * handles new connections (checks if there was an accept error) * * @param tcp_conn the new TCP connection (if no error occurred) * @param accept_error true if an error occurred while accepting connections */ void handle_accept(tcp::connection_ptr& tcp_conn, const boost::system::error_code& accept_error); /** * handles new connections following an SSL handshake (checks for errors) * * @param tcp_conn the new TCP connection (if no error occurred) * @param handshake_error true if an error occurred during the SSL handshake */ void handle_ssl_handshake(tcp::connection_ptr& tcp_conn, const boost::system::error_code& handshake_error); /// This will be called by connection::finish() after a server has /// finished handling a connection. If the keep_alive flag is true, /// it will call handle_connection(); otherwise, it will close the /// connection and remove it from the server's management pool void finish_connection(tcp::connection_ptr& tcp_conn); /// prunes orphaned connections that did not close cleanly /// and returns the remaining number of connections in the pool std::size_t prune_connections(void); /// data type for a pool of TCP connections typedef std::set ConnectionPool; /// the default scheduler object used to manage worker threads single_service_scheduler m_default_scheduler; /// reference to the active scheduler object used to manage worker threads scheduler & m_active_scheduler; /// manages async TCP connections boost::asio::ip::tcp::acceptor m_tcp_acceptor; /// context used for SSL configuration connection::ssl_context_type m_ssl_context; /// condition triggered when the server has stopped listening for connections boost::condition m_server_has_stopped; /// condition triggered when the connection pool is empty boost::condition m_no_more_connections; /// pool of active connections associated with this server ConnectionPool m_conn_pool; /// tcp endpoint used to listen for new connections boost::asio::ip::tcp::endpoint m_endpoint; /// true if the server uses SSL to encrypt connections bool m_ssl_flag; /// set to true when the server is listening for new connections bool m_is_listening; /// mutex to make class thread-safe mutable boost::mutex m_mutex; }; /// data type for a server pointer typedef boost::shared_ptr server_ptr; } // end namespace tcp } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/error.hpp0000644000372000001440000002025212420270445020173 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_ERROR_HEADER__ #define __PION_ERROR_HEADER__ #include #include #include #include #include #include #include #include #include #if BOOST_VERSION >= 104700 #include #endif #include namespace pion { // begin namespace pion // // exception: simple exception class for pion errors that generates what() // strings with more descriptive messages and optionally arguments as well // class exception : public virtual std::exception, public virtual boost::exception { public: exception() {} exception(const std::string& msg) : m_what_msg(msg) {} exception(const char * const msg) : m_what_msg(msg) {} virtual ~exception() throw () {} virtual const char* what() const throw() { if (m_what_msg.empty()) update_what_msg(); return m_what_msg.c_str(); } protected: inline void set_what_msg(const char * const msg = NULL, const std::string * const arg1 = NULL, const std::string * const arg2 = NULL, const std::string * const arg3 = NULL) const { std::ostringstream tmp; #if BOOST_VERSION >= 104700 tmp << ( msg ? msg : boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(*this).type_->name()) ); #else tmp << ( msg ? msg : boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(*this).type_.name()) ); #endif if (arg1 || arg2 || arg3) tmp << ':'; if (arg1) tmp << ' ' << *arg1; if (arg2) tmp << ' ' << *arg2; if (arg3) tmp << ' ' << *arg3; m_what_msg = tmp.str(); } virtual void update_what_msg() const { set_what_msg(); } mutable std::string m_what_msg; }; /** * static method that generates a meaningful diagnostic message from exceptions * * @param e reference to an exception object * @return std::string descriptive error message */ template static inline std::string diagnostic_information( T const & e ) { boost::exception const * const be = dynamic_cast(&e); std::exception const * const se = dynamic_cast(&e); std::ostringstream tmp; if (se) { tmp << se->what(); } else { #if BOOST_VERSION >= 104700 tmp << boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(e).type_->name()); #else tmp << boost::units::detail::demangle(BOOST_EXCEPTION_DYNAMIC_TYPEID(e).type_.name()); #endif } if (be) { //char const * const * fn=boost::get_error_info(*be); //if (fn) tmp << " at " << *fn; char const * const * f=boost::get_error_info(*be); if (f) { tmp << " [" << *f; if (int const * l=boost::get_error_info(*be)) tmp << ':' << *l; tmp << "]"; } } return tmp.str(); } namespace error { // begin namespace error // // pion error info types // /// generic error message typedef boost::error_info errinfo_message; /// name of an unrecognized configuration argument or option typedef boost::error_info errinfo_arg_name; /// file name/path typedef boost::error_info errinfo_file_name; /// directory name/path typedef boost::error_info errinfo_dir_name; /// plugin identifier typedef boost::error_info errinfo_plugin_name; /// plugin symbol name typedef boost::error_info errinfo_symbol_name; // // pion exception types // /// exception thrown for an invalid configuration argument or option class bad_arg : public pion::exception { virtual void update_what_msg() const { set_what_msg("bad argument", boost::get_error_info(*this)); } }; /// exception thrown if there is an error parsing a configuration file class bad_config : public pion::exception { virtual void update_what_msg() const { set_what_msg("config parser error", boost::get_error_info(*this)); } }; /// exception thrown if we failed to open a file class open_file : public pion::exception { virtual void update_what_msg() const { set_what_msg("unable to open file", boost::get_error_info(*this)); } }; /// exception thrown if we are unable to open a plugin class open_plugin : public pion::exception { virtual void update_what_msg() const { set_what_msg("unable to open plugin", boost::get_error_info(*this)); } }; /// exception thrown if we failed to read data from a file class read_file : public pion::exception { virtual void update_what_msg() const { set_what_msg("unable to read file", boost::get_error_info(*this)); } }; /// exception thrown if a file is not found class file_not_found : public pion::exception { virtual void update_what_msg() const { set_what_msg("file not found", boost::get_error_info(*this)); } }; /// exception thrown if a required directory is not found class directory_not_found : public pion::exception { virtual void update_what_msg() const { set_what_msg("directory not found", boost::get_error_info(*this)); } }; /// exception thrown if a plugin cannot be found class plugin_not_found : public pion::exception { virtual void update_what_msg() const { set_what_msg("plugin not found", boost::get_error_info(*this)); } }; /// exception thrown if we try to add or load a duplicate plugin class duplicate_plugin : public pion::exception { virtual void update_what_msg() const { set_what_msg("duplicate plugin", boost::get_error_info(*this)); } }; /// exception thrown if a plugin is missing a required symbol class plugin_missing_symbol : public pion::exception { virtual void update_what_msg() const { set_what_msg("missing plugin symbol", boost::get_error_info(*this)); } }; /// exception thrown if a plugin has an undefined state class plugin_undefined : public pion::exception { virtual void update_what_msg() const { set_what_msg("plugin has undefined state"); } }; /// exception thrown if a bad password hash is provided class bad_password_hash : public pion::exception { virtual void update_what_msg() const { set_what_msg("bad password hash"); } }; } // end namespace error } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/config.hpp.win0000644000372000001440000001132412420270445021103 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PIONCONFIG_HEADER__ #define __PION_PIONCONFIG_HEADER__ // DO NOT USE autoheader ; this file is not automanaged!!! // Other libraries should be added here as they become part of the configuration // used for binary releases. #ifdef PION_FULL #define PION_USE_LOG4CPLUS #define PION_HAVE_SSL #define PION_HAVE_JSON #define PION_HAVE_PYTHON #endif /* Define to the version number of pion. */ #define PION_VERSION "5.0.7" /* Define to the directory where Pion plug-ins are installed. */ //#undef PION_PLUGINS_DIRECTORY #define PION_PLUGINS_DIRECTORY "." /* Define to the directory where cygwin is installed. */ #undef PION_CYGWIN_DIRECTORY /* Define to 1 if C library supports malloc_trim() */ #undef PION_HAVE_MALLOC_TRIM // ----------------------------------------------------------------------- // hash_map support // // At least one of the following options should be defined. /* Define to 1 if you have the header file. */ #undef PION_HAVE_EXT_HASH_MAP /* Define to 1 if you have the header file. */ //#undef PION_HAVE_HASH_MAP #define PION_HAVE_HASH_MAP 1 /* Define to 1 if you have the header file. */ #undef PION_HAVE_TR1_UNORDERED_MAP /* Define to 1 if you have the header file. */ #undef PION_HAVE_UNORDERED_MAP #if defined(_MSC_VER) && (_MSC_VER >= 1600) #define PION_HAVE_UNORDERED_MAP 1 #endif // ----------------------------------------------------------------------- // Logging Options // // At most one of the logging options below should be defined. If none of // them are defined, std::cout and std::cerr will be used for logging. /* To use the `log4cplus' library for logging, include PION_USE_LOG4CPLUS or PION_FULL in Preprocessor Definitions, or uncomment the following line. */ //#define PION_USE_LOG4CPLUS /* To use the `log4cxx' library for logging, include PION_USE_LOG4CXX in Preprocessor Definitions, or uncomment the following line. */ //#define PION_USE_LOG4CXX /* To use the `log4cpp' library for logging, include PION_USE_LOG4CPP in Preprocessor Definitions, or uncomment the following line. */ //#define PION_USE_LOG4CPP /* To disable logging, include PION_DISABLE_LOGGING in Preprocessor Definitions, or uncomment the following line. */ //#define PION_DISABLE_LOGGING // ----------------------------------------------------------------------- /* Define to 1 if you have the `zlib' library. */ #undef PION_HAVE_ZLIB /* Define to 1 if you have the `bzlib' library. */ #undef PION_HAVE_BZLIB /* If you have the `OpenSSL' library installed, include PION_HAVE_SSL or PION_FULL in Preprocessor Definitions, or uncomment the following line, to use SSL. */ //#define PION_HAVE_SSL #if defined(PION_HAVE_SSL) && !defined(PION_CMAKE_BUILD) #if defined _DEBUG #pragma comment(lib, "ssleay32d") #pragma comment(lib, "libeay32d") #else #pragma comment(lib, "ssleay32") #pragma comment(lib, "libeay32") #endif #endif /* If you have the `yajl' library installed, include PION_HAVE_JSON or PION_FULL in Preprocessor Definitions, or uncomment the following line, to use yajl. */ //#define PION_HAVE_JSON /* If you have the `python' library installed, include PION_HAVE_PYTHON or PION_FULL in Preprocessor Definitions, or uncomment the following line, to use python. */ //#define PION_HAVE_PYTHON #if defined(_WIN32) || defined(_WINDOWS) #define PION_WIN32 1 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif #else #error PionConfig.hpp.win is for Win32 only. #endif // _WIN32 #include #ifdef _MSC_VER #ifdef PION_EXPORTS #define PION_API __declspec(dllexport) #elif defined PION_STATIC_LINKING #define PION_API #else #define PION_API __declspec(dllimport) #endif #ifdef PION_STATIC_LINKING #define PION_PLUGIN #else #define PION_PLUGIN __declspec(dllexport) #endif /* Verify correctness of the PION_STATIC_LINKING setup */ #ifdef PION_STATIC_LINKING #ifdef _USRDLL #error Need to be compiled as a static library for PION_STATIC_LINKING #endif #endif #endif // _MSC_VER #endif //__PION_PIONCONFIG_HEADER__ pion-5.0.7+dfsg.orig/include/pion/plugin_manager.hpp0000644000372000001440000003546312420270445022044 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PLUGIN_MANAGER_HEADER__ #define __PION_PLUGIN_MANAGER_HEADER__ #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion /// /// plugin_manager: used to manage a collection of plug-in objects /// template class plugin_manager { public: /// data type for a function that may be called by the run() method typedef boost::function1 PluginRunFunction; /// data type for a function that may be called by the getStat() method typedef boost::function1 PluginStatFunction; /// default constructor plugin_manager(void) {} /// default destructor virtual ~plugin_manager() {} /// clears all the plug-in objects being managed inline void clear(void) { boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); m_plugin_map.clear(); } /// returns true if there are no plug-in objects being managed inline bool empty(void) const { boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); return m_plugin_map.empty(); } /** * adds a new plug-in object * * @param plugin_id unique identifier associated with the plug-in * @param plugin_object_ptr pointer to the plug-in object to add */ inline void add(const std::string& plugin_id, PluginType *plugin_object_ptr); /** * removes a plug-in object * * @param plugin_id unique identifier associated with the plug-in */ inline void remove(const std::string& plugin_id); /** * replaces an existing plug-in object with a new one * * @param plugin_id unique identifier associated with the plug-in * @param plugin_ptr pointer to the new plug-in object which will replace the old one */ inline void replace(const std::string& plugin_id, PluginType *plugin_ptr); /** * clones an existing plug-in object (creates a new one of the same type) * * @param plugin_id unique identifier associated with the plug-in * @return PluginType* pointer to the new plug-in object */ inline PluginType *clone(const std::string& plugin_id); /** * loads a new plug-in object * * @param plugin_id unique identifier associated with the plug-in * @param plugin_type the name or type of the plug-in to load (searches * plug-in directories and appends extensions) * @return PluginType* pointer to the new plug-in object */ inline PluginType *load(const std::string& plugin_id, const std::string& plugin_type); /** * gets the plug-in object associated with a particular plugin_id (exact match) * * @param plugin_id unique identifier associated with the plug-in * @return PluginType* pointer to the matching plug-in object or NULL if not found */ inline PluginType *get(const std::string& plugin_id); /** * gets the plug-in object associated with a particular plugin_id (exact match) * * @param plugin_id unique identifier associated with the plug-in * @return PluginType* pointer to the matching plug-in object or NULL if not found */ inline const PluginType *get(const std::string& plugin_id) const; /** * gets a smart pointer to the plugin shared library for a particular plugin_id (exact match) * * @param plugin_id unique identifier associated with the plug-in * @return plugin_ptr pointer to the plugin shared library if found */ inline plugin_ptr get_lib_ptr(const std::string& plugin_id) const; /** * finds the plug-in object associated with a particular resource (fuzzy match) * * @param resource resource identifier (uri-stem) to search for * @return PluginType* pointer to the matching plug-in object or NULL if not found */ inline PluginType *find(const std::string& resource); /** * runs a method for every plug-in being managed * * @param run_func the function to execute for each plug-in object */ inline void run(PluginRunFunction run_func); /** * runs a method for a particular plug-in * * @param plugin_id unique identifier associated with the plug-in * @param run_func the function to execute */ inline void run(const std::string& plugin_id, PluginRunFunction run_func); /** * returns a total statistic value summed for every plug-in being managed * * @param stat_func the statistic function to execute for each plug-in object */ inline boost::uint64_t get_statistic(PluginStatFunction stat_func) const; /** * returns a statistic value for a particular plug-in * * @param plugin_id unique identifier associated with the plug-in * @param stat_func the statistic function to execute */ inline boost::uint64_t get_statistic(const std::string& plugin_id, PluginStatFunction stat_func) const; protected: /// data type that maps identifiers to plug-in objects class map_type : public std::map > > { public: inline void clear(void); virtual ~map_type() { map_type::clear(); } map_type(void) {} }; /// collection of plug-in objects being managed map_type m_plugin_map; /// mutex to make class thread-safe mutable boost::mutex m_plugin_mutex; }; // plugin_manager member functions template inline void plugin_manager::add(const std::string& plugin_id, PluginType *plugin_object_ptr) { plugin_ptr plugin_ptr; boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); m_plugin_map.insert(std::make_pair(plugin_id, std::make_pair(plugin_object_ptr, plugin_ptr))); } template inline void plugin_manager::remove(const std::string& plugin_id) { boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); typename pion::plugin_manager::map_type::iterator i = m_plugin_map.find(plugin_id); if (i == m_plugin_map.end()) BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) ); if (i->second.second.is_open()) { i->second.second.destroy(i->second.first); } else { delete i->second.first; } m_plugin_map.erase(i); } template inline void plugin_manager::replace(const std::string& plugin_id, PluginType *plugin_ptr) { BOOST_ASSERT(plugin_ptr); boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); typename pion::plugin_manager::map_type::iterator i = m_plugin_map.find(plugin_id); if (i == m_plugin_map.end()) BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) ); if (i->second.second.is_open()) { i->second.second.destroy(i->second.first); } else { delete i->second.first; } i->second.first = plugin_ptr; } template inline PluginType *plugin_manager::clone(const std::string& plugin_id) { boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); typename pion::plugin_manager::map_type::iterator i = m_plugin_map.find(plugin_id); if (i == m_plugin_map.end()) BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) ); return i->second.second.create(); } template inline PluginType *plugin_manager::load(const std::string& plugin_id, const std::string& plugin_type) { // search for the plug-in file using the configured paths if (m_plugin_map.find(plugin_id) != m_plugin_map.end()) BOOST_THROW_EXCEPTION( error::duplicate_plugin() << error::errinfo_plugin_name(plugin_id) ); // open up the plug-in's shared object library plugin_ptr plugin_ptr; plugin_ptr.open(plugin_type); // may throw // create a new object using the plug-in library PluginType *plugin_object_ptr(plugin_ptr.create()); // add the new plug-in object to our map boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); m_plugin_map.insert(std::make_pair(plugin_id, std::make_pair(plugin_object_ptr, plugin_ptr))); return plugin_object_ptr; } template inline PluginType *plugin_manager::get(const std::string& plugin_id) { PluginType *plugin_object_ptr = NULL; boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); typename pion::plugin_manager::map_type::iterator i = m_plugin_map.find(plugin_id); if (i != m_plugin_map.end()) plugin_object_ptr = i->second.first; return plugin_object_ptr; } template inline const PluginType *plugin_manager::get(const std::string& plugin_id) const { const PluginType *plugin_object_ptr = NULL; boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); typename pion::plugin_manager::map_type::const_iterator i = m_plugin_map.find(plugin_id); if (i != m_plugin_map.end()) plugin_object_ptr = i->second.first; return plugin_object_ptr; } template inline plugin_ptr plugin_manager::get_lib_ptr(const std::string& plugin_id) const { plugin_ptr plugin_ptr; boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); typename pion::plugin_manager::map_type::const_iterator i = m_plugin_map.find(plugin_id); if (i != m_plugin_map.end()) plugin_ptr = i->second.second; return plugin_ptr; } template inline PluginType *plugin_manager::find(const std::string& resource) { // will point to the matching plug-in object, if found PluginType *plugin_object_ptr = NULL; // lock mutex for thread safety (this should probably use ref counters) boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); // check if no plug-ins are being managed if (m_plugin_map.empty()) return plugin_object_ptr; // iterate through each plug-in whose identifier may match the resource typename pion::plugin_manager::map_type::iterator i = m_plugin_map.upper_bound(resource); while (i != m_plugin_map.begin()) { --i; // keep checking while the first part of the strings match if (resource.compare(0, i->first.size(), i->first) != 0) { // the first part no longer matches if (i != m_plugin_map.begin()) { // continue to next plug-in in list if its size is < this one typename pion::plugin_manager::map_type::iterator j=i; --j; if (j->first.size() < i->first.size()) continue; } // otherwise we've reached the end; stop looking for a match break; } // only if the resource matches the plug-in's identifier // or if resource is followed first with a '/' character if (resource.size() == i->first.size() || resource[i->first.size()]=='/') { plugin_object_ptr = i->second.first; break; } } return plugin_object_ptr; } template inline void plugin_manager::run(PluginRunFunction run_func) { boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); for (typename pion::plugin_manager::map_type::iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) { run_func(i->second.first); } } template inline void plugin_manager::run(const std::string& plugin_id, PluginRunFunction run_func) { // no need to lock (handled by plugin_manager::get()) PluginType *plugin_object_ptr = get(plugin_id); if (plugin_object_ptr == NULL) BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) ); run_func(plugin_object_ptr); } template inline boost::uint64_t plugin_manager::get_statistic(PluginStatFunction stat_func) const { boost::uint64_t stat_value = 0; boost::mutex::scoped_lock plugins_lock(m_plugin_mutex); for (typename pion::plugin_manager::map_type::const_iterator i = m_plugin_map.begin(); i != m_plugin_map.end(); ++i) { stat_value += stat_func(i->second.first); } return stat_value; } template inline boost::uint64_t plugin_manager::get_statistic(const std::string& plugin_id, PluginStatFunction stat_func) const { // no need to lock (handled by plugin_manager::get()) const PluginType *plugin_object_ptr = const_cast*>(this)->get(plugin_id); if (plugin_object_ptr == NULL) BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) ); return stat_func(plugin_object_ptr); } // plugin_manager::map_type member functions template inline void plugin_manager::map_type::clear(void) { if (! std::map > >::empty()) { for (typename pion::plugin_manager::map_type::iterator i = std::map > >::begin(); i != std::map > >::end(); ++i) { if (i->second.second.is_open()) { i->second.second.destroy(i->second.first); } else { delete i->second.first; } } this->erase(std::map > >::begin(), std::map > >::end()); } } } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/test/0000755000372000001440000000000012420270445017307 5ustar robertouserspion-5.0.7+dfsg.orig/include/pion/test/unit_test.hpp0000644000372000001440000004231612420270445022044 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_TEST_UNIT_TEST_HEADER__ #define __PION_TEST_UNIT_TEST_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef _MSC_VER #include #define CHANGE_DIRECTORY _chdir #define GET_DIRECTORY(a,b) _getcwd(a,b) #else #include #define CHANGE_DIRECTORY chdir #define GET_DIRECTORY(a,b) getcwd(a,b) #endif #define DIRECTORY_MAX_SIZE 1000 namespace pion { // begin namespace pion namespace test { // begin namespace test /// thread-safe version of Boost.Test's xml_log_formatter class class safe_xml_log_formatter : public boost::unit_test::unit_test_log_formatter { public: /// default constructor safe_xml_log_formatter() : m_entry_in_progress(false) {} /// virtual destructor virtual ~safe_xml_log_formatter() {} /// wrapper to flush output for xml_log_formatter::log_start virtual void log_start(std::ostream& ostr, boost::unit_test::counter_t test_cases_amount ) { ostr << "" << std::endl; } /// wrapper to flush output for xml_log_formatter::log_finish virtual void log_finish(std::ostream& ostr) { ostr << "" << std::endl; } /// wrapper to flush output for xml_log_formatter::log_build_info virtual void log_build_info(std::ostream& ostr) { ostr << "" << std::endl; } /// wrapper to flush output for xml_log_formatter::test_unit_start virtual void test_unit_start(std::ostream& ostr, boost::unit_test::test_unit const& tu ) { ostr << "<" << tu_type_name( tu ) << " name" << attr_value() << tu.p_name.get() << ">" << std::endl; } /// wrapper to flush output for xml_log_formatter::test_unit_finish virtual void test_unit_finish(std::ostream& ostr, boost::unit_test::test_unit const& tu, unsigned long elapsed ) { if ( tu.p_type == boost::unit_test::tut_case ) ostr << "" << elapsed << ""; ostr << "" << std::endl; } /// wrapper to flush output for xml_log_formatter::test_unit_skipped virtual void test_unit_skipped(std::ostream& ostr, boost::unit_test::test_unit const& tu ) { ostr << "<" << tu_type_name( tu ) << " name" << attr_value() << tu.p_name.get() << " skipped" << attr_value() << "yes" << "/>" << std::endl; } /// wrapper to flush output for xml_log_formatter::log_exception virtual void log_exception(std::ostream& ostr, boost::unit_test::log_checkpoint_data const& checkpoint_data, boost::execution_exception const& ex ) { boost::execution_exception::location const& loc = ex.where(); ostr << "" << boost::unit_test::cdata() << ex.what(); if( !checkpoint_data.m_file_name.is_empty() ) { ostr << "" << boost::unit_test::cdata() << checkpoint_data.m_message << ""; } ostr << "" << std::endl; } /// thread-safe wrapper for xml_log_formatter::log_entry_start virtual void log_entry_start( std::ostream& ostr, boost::unit_test::log_entry_data const& entry_data, log_entry_types let ) { boost::mutex::scoped_lock entry_lock(m_mutex); while (m_entry_in_progress) { m_entry_complete.wait(entry_lock); } m_entry_in_progress = true; static boost::unit_test::literal_string xml_tags[] = { "Info", "Message", "Warning", "Error", "FatalError" }; m_curr_tag = xml_tags[let]; ostr << '<' << m_curr_tag << BOOST_TEST_L( " file" ) << attr_value() << entry_data.m_file_name << BOOST_TEST_L( " line" ) << attr_value() << entry_data.m_line_num << BOOST_TEST_L( ">" ) << std::endl; m_curr_tag.clear(); m_entry_in_progress = false; m_entry_complete.notify_all(); } } private: /// output appropriate xml element name static boost::unit_test::const_string tu_type_name( boost::unit_test::test_unit const& tu ) { return tu.p_type == boost::unit_test::tut_case ? "TestCase" : "TestSuite"; } /// re-use attr_value data type from xml_printer.hpp typedef boost::unit_test::attr_value attr_value; /// true if a log entry is in progress volatile bool m_entry_in_progress; /// condition used to signal the completion of a log entry boost::condition m_entry_complete; /// mutex used to prevent multiple threads from interleaving entries boost::mutex m_mutex; /// current xml tag boost::unit_test::const_string m_curr_tag; }; /// config is intended for use as a global fixture. By including the /// following line in one source code file of a unit test project, the constructor will /// run once before the first test and the destructor will run once after the last test: /// /// BOOST_GLOBAL_FIXTURE(pion::test::config); struct config { config() { std::cout << "global setup for all pion unit tests\n"; // argc and argv do not include parameters handled by the boost unit test framework, such as --log_level. int argc = boost::unit_test::framework::master_test_suite().argc; char** argv = boost::unit_test::framework::master_test_suite().argv; bool verbose = false; if (argc > 1) { if (argv[1][0] == '-' && argv[1][1] == 'v') { verbose = true; } else if (strlen(argv[1]) > 13 && strncmp(argv[1], "--log_output=", 13) == 0) { const char * const test_log_filename = argv[1] + 13; m_test_log_file.open(test_log_filename); if (m_test_log_file.is_open()) { boost::unit_test::unit_test_log.set_stream(m_test_log_file); boost::unit_test::unit_test_log.set_formatter(new safe_xml_log_formatter); } else { std::cerr << "unable to open " << test_log_filename << std::endl; } } } if (verbose) { PION_LOG_CONFIG_BASIC; } else { std::cout << "Use '-v' to enable logging of errors and warnings from pion.\n"; } pion::logger log_ptr = PION_GET_LOGGER("pion"); PION_LOG_SETLEVEL_WARN(log_ptr); } virtual ~config() { std::cout << "global teardown for all pion unit tests\n"; } /// xml log results output stream (needs to be global) static std::ofstream m_test_log_file; }; // removes line endings from a c-style string static inline char* trim(char* str) { for (long len = strlen(str) - 1; len >= 0; len--) { if (str[len] == '\n' || str[len] == '\r') str[len] = '\0'; else break; } return str; } // reads lines from a file, stripping line endings and ignoring blank lines // and comment lines (starting with a '#') static inline bool read_lines_from_file(const std::string& filename, std::list& lines) { // open file std::ifstream a_file(filename.c_str(), std::ios::in | std::ios::binary); if (! a_file.is_open()) return false; // read data from file lines.clear(); std::string one_line; while (std::getline(a_file, one_line)) { boost::trim(one_line); if (!one_line.empty() && one_line[0] != '#') lines.push_back(one_line); } // close file a_file.close(); return true; } // Check for file match, use std::list for sorting the files, which will allow // random order matching... static inline bool check_files_match(const std::string& fileA, const std::string& fileB) { // open and read data from files std::list a_lines, b_lines; BOOST_REQUIRE(read_lines_from_file(fileA, a_lines)); BOOST_REQUIRE(read_lines_from_file(fileB, b_lines)); // sort lines read a_lines.sort(); b_lines.sort(); // files match if lines match return (a_lines == b_lines); } static inline bool check_files_exact_match(const std::string& fileA, const std::string& fileB, bool ignore_line_endings = false) { // open files std::ifstream a_file(fileA.c_str(), std::ios::in | std::ios::binary); BOOST_REQUIRE(a_file.is_open()); std::ifstream b_file(fileB.c_str(), std::ios::in | std::ios::binary); BOOST_REQUIRE(b_file.is_open()); // read and compare data in files static const unsigned int BUF_SIZE = 4096; char a_buf[BUF_SIZE]; char b_buf[BUF_SIZE]; if (ignore_line_endings) { while (a_file.getline(a_buf, BUF_SIZE)) { if (! b_file.getline(b_buf, BUF_SIZE)) return false; trim(a_buf); trim(b_buf); if (strlen(a_buf) != strlen(b_buf)) return false; if (memcmp(a_buf, b_buf, strlen(a_buf)) != 0) return false; } if (b_file.getline(b_buf, BUF_SIZE)) return false; } else { while (a_file.read(a_buf, BUF_SIZE)) { if (! b_file.read(b_buf, BUF_SIZE)) return false; if (memcmp(a_buf, b_buf, BUF_SIZE) != 0) return false; } if (b_file.read(b_buf, BUF_SIZE)) return false; } if (a_file.gcount() != b_file.gcount()) return false; if (memcmp(a_buf, b_buf, a_file.gcount()) != 0) return false; a_file.close(); b_file.close(); // files match return true; } } // end namespace test } // end namespace pion /* Using BOOST_AUTO_TEST_SUITE_FIXTURE_TEMPLATE and BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE has two additional benefits relative to using BOOST_FIXTURE_TEST_SUITE and BOOST_AUTO_TEST_CASE: 1) it allows a test to be run with more than one fixture, and 2) it makes the current fixture part of the test name, e.g. checkPropertyX For an example of 1), see http_message_tests.cpp. There are probably simpler ways to achieve 2), but since it comes for free, it makes sense to use it. The benefit of this is that the test names don't have to include redundant information about the fixture, e.g. checkMyFixtureHasPropertyX. (In this example, checkPropertyX is not obviously better than checkMyFixtureHasPropertyX, but in many cases the test names become too long and/or hard to parse, or the fixture just isn't part of the name, making some error reports ambiguous.) (BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE is based on BOOST_AUTO_TEST_CASE_TEMPLATE, in unit_test_suite.hpp.) Minimal example demonstrating usage of BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE: class ObjectToTest_F { // suffix _F is used for fixtures public: ObjectToTest_F() { m_value = 2; } int m_value; int get_value() { return m_value; } }; // This illustrates the most common case, where just one fixture will be used, // so the list only has one fixture in it. // ObjectToTest_S is the name of the test suite. BOOST_AUTO_TEST_SUITE_FIXTURE_TEMPLATE(ObjectToTest_S, boost::mpl::list) // One method for testing the fixture... BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE(checkValueEqualsTwo) { BOOST_CHECK_EQUAL(F::m_value, 2); BOOST_CHECK_EQUAL(F::get_value(), 2); } // Another method for testing the fixture... BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE(checkValueEqualsTwoAgain) { BOOST_CHECK_EQUAL(this->m_value, 2); BOOST_CHECK_EQUAL(this->get_value(), 2); } // The simplest, but, alas, non conformant to the C++ standard, method for testing the fixture. // This will compile with MSVC (unless language extensions are disabled (/Za)). // It won't compile with gcc unless -fpermissive is used. // See http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html. BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE(checkValueEqualsTwoNonConformant) { BOOST_CHECK_EQUAL(m_value, 2); BOOST_CHECK_EQUAL(get_value(), 2); } BOOST_AUTO_TEST_SUITE_END() */ #define BOOST_AUTO_TEST_SUITE_FIXTURE_TEMPLATE(suite_name, fixture_types) \ BOOST_AUTO_TEST_SUITE(suite_name) \ typedef fixture_types BOOST_AUTO_TEST_CASE_FIXTURE_TYPES; \ /**/ #define BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE(test_name) \ template \ struct test_name : public F \ { void test_method(); }; \ \ struct BOOST_AUTO_TC_INVOKER( test_name ) { \ template \ static void run( boost::type* = 0 ) \ { \ test_name t; \ t.test_method(); \ } \ }; \ \ BOOST_AUTO_TU_REGISTRAR( test_name )( \ boost::unit_test::ut_detail::template_test_case_gen< \ BOOST_AUTO_TC_INVOKER( test_name ), \ BOOST_AUTO_TEST_CASE_FIXTURE_TYPES >( \ BOOST_STRINGIZE( test_name ) ) ); \ \ template \ void test_name::test_method() \ /**/ #endif pion-5.0.7+dfsg.orig/include/pion/test/Makefile.am0000644000372000001440000000030312420270445021337 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- pion_test_includedir = $(includedir)/pion/test pion_test_include_HEADERS = unit_test.hpp pion-5.0.7+dfsg.orig/include/pion/process.hpp0000644000372000001440000001003612420270445020517 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PROCESS_HEADER__ #define __PION_PROCESS_HEADER__ #include #include #include #include #include #include // Dump file generation support on Windows #ifdef _MSC_VER #include #include #include // based on dbghelp.h typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); #endif namespace pion { // begin namespace pion /// /// process: class for managing process/service related functions /// class PION_API process : private boost::noncopyable { public: // default destructor ~process() {} /// default constructor process(void) {} /// signals the shutdown condition static void shutdown(void); /// blocks until the shutdown condition has been signaled static void wait_for_shutdown(void); /// sets up basic signal handling for the process static void initialize(void); /// fork process and run as a background daemon static void daemonize(void); #ifdef _MSC_VER class dumpfile_init_exception : public std::exception { public: dumpfile_init_exception(const std::string& cause) : m_cause(cause) {} virtual const char* what() const { return m_cause.c_str(); } protected: std::string m_cause; }; /** * enables mini-dump generation on unhandled exceptions (AVs, etc.) * throws an dumpfile_init_exception if unable to set the unhandled exception processing * @param dir file system path to store mini dumps */ static void set_dumpfile_directory(const std::string& dir); protected: /// unhandled exception filter proc static LONG WINAPI unhandled_exception_filter(struct _EXCEPTION_POINTERS *pExceptionInfo); /// generates a name for a dump file static std::string generate_dumpfile_name(); #endif protected: /// data type for static/global process configuration information struct config_type { /// constructor just initializes native types #ifdef _MSC_VER config_type() : shutdown_now(false), h_dbghelp(NULL), p_dump_proc(NULL) {} #else config_type() : shutdown_now(false) {} #endif /// true if we should shutdown now bool shutdown_now; /// triggered when it is time to shutdown boost::condition shutdown_cond; /// used to protect the shutdown condition boost::mutex shutdown_mutex; // Dump file generation support on Windows #ifdef _MSC_VER /// mini-dump file location std::string dumpfile_dir; /// dbghelp.dll library handle HMODULE h_dbghelp; /// address of MiniDumpWriteDump inside dbghelp.dll MINIDUMPWRITEDUMP p_dump_proc; #endif }; /// returns a singleton instance of config_type static inline config_type& get_config(void) { boost::call_once(process::create_config, m_instance_flag); return *m_config_ptr; } private: /// creates the config_type singleton static void create_config(void); /// used to ensure thread safety of the config_type singleton static boost::once_flag m_instance_flag; /// pointer to the config_type singleton static config_type * m_config_ptr; }; } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/hash_map.hpp0000644000372000001440000001156412420270445020630 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_HASH_MAP_HEADER__ #define __PION_HASH_MAP_HEADER__ #include #include #include #include #include #if defined(PION_HAVE_UNORDERED_MAP) #include #elif defined(PION_HAVE_TR1_UNORDERED_MAP) #include #elif defined(PION_HAVE_EXT_HASH_MAP) #include #elif defined(PION_HAVE_HASH_MAP) #include #endif namespace pion { // begin namespace pion #if defined(PION_HAVE_UNORDERED_MAP) #define PION_HASH_MAP std::unordered_map #define PION_HASH_MULTIMAP std::unordered_multimap #define PION_HASH_STRING boost::hash #define PION_HASH(TYPE) boost::hash #elif defined(PION_HAVE_TR1_UNORDERED_MAP) #define PION_HASH_MAP std::tr1::unordered_map #define PION_HASH_MULTIMAP std::tr1::unordered_multimap #define PION_HASH_STRING boost::hash #define PION_HASH(TYPE) boost::hash #elif defined(PION_HAVE_EXT_HASH_MAP) #if __GNUC__ >= 3 #define PION_HASH_MAP __gnu_cxx::hash_map #define PION_HASH_MULTIMAP __gnu_cxx::hash_multimap #else #define PION_HASH_MAP hash_map #define PION_HASH_MULTIMAP hash_multimap #endif #define PION_HASH_STRING boost::hash #define PION_HASH(TYPE) boost::hash #elif defined(PION_HAVE_HASH_MAP) #ifdef _MSC_VER #define PION_HASH_MAP stdext::hash_map #define PION_HASH_MULTIMAP stdext::hash_multimap #define PION_HASH_STRING stdext::hash_compare > #define PION_HASH(TYPE) stdext::hash_compare > #else #define PION_HASH_MAP hash_map #define PION_HASH_MULTIMAP hash_multimap #define PION_HASH_STRING boost::hash #define PION_HASH(TYPE) boost::hash #endif #endif /// case insensitive string equality predicate /// copied from boost.unordered hash_equality documentation /// http://www.boost.org/doc/libs/1_50_0/doc/html/unordered/hash_equality.html struct iequal_to : std::binary_function { bool operator()(std::string const& x, std::string const& y) const { return boost::algorithm::iequals(x, y, std::locale()); } }; /// case insensitive hash generic function /// copied from boost.unordered hash_equality documentation /// http://www.boost.org/doc/libs/1_50_0/doc/html/unordered/hash_equality.html struct ihash : std::unary_function { std::size_t operator()(std::string const& x) const { std::size_t seed = 0; std::locale locale; for(std::string::const_iterator it = x.begin(); it != x.end(); ++it) { boost::hash_combine(seed, std::toupper(*it, locale)); } return seed; } }; #if defined(_MSC_VER) && !defined(PION_HAVE_UNORDERED_MAP) /// Case-insensitive "less than" predicate template struct is_iless : public std::binary_function<_Ty, _Ty, bool> { /// Constructor is_iless( const std::locale& Loc=std::locale() ) : m_Loc( Loc ) {} /// returns true if Arg1 is less than Arg2 bool operator()( const _Ty& Arg1, const _Ty& Arg2 ) const { return _Ty(boost::algorithm::to_upper_copy(Arg1, m_Loc)) < _Ty(boost::algorithm::to_upper_copy(Arg2, m_Loc)); } private: std::locale m_Loc; }; /// case insensitive extension of stdext::hash_compare for std::string struct ihash_windows : public stdext::hash_compare > { // makes operator() with two arguments visible, otherwise it would be hidden by the operator() defined here using stdext::hash_compare >::operator(); inline size_t operator()(const std::string& str) const { return ihash()(str); } }; /// data type for case-insensitive dictionary of strings typedef PION_HASH_MULTIMAP ihash_multimap; #else /// data type for case-insensitive dictionary of strings typedef PION_HASH_MULTIMAP ihash_multimap; #endif } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/plugin.hpp0000644000372000001440000003660712420270445020353 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PLUGIN_HEADER__ #define __PION_PLUGIN_HEADER__ #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion /// /// plugin: base class for plug-in management /// class PION_API plugin { public: /** * searches directories for a valid plug-in file * * @param path_to_file the path to the plug-in file, if found * @param the name name of the plug-in to search for * @return true if the plug-in file was found */ static inline bool find_plugin_file(std::string& path_to_file, const std::string& name) { return find_file(path_to_file, name, PION_PLUGIN_EXTENSION); } /** * searches directories for a valid plug-in configuration file * * @param path_to_file if found, is set to the complete path to the file * @param name the name of the configuration file to search for * @return true if the configuration file was found */ static inline bool find_config_file(std::string& path_to_file, const std::string& name) { return find_file(path_to_file, name, PION_CONFIG_EXTENSION); } /** * adds an entry point for a plugin that is statically linked * NOTE: USE PION_DECLARE_PLUGIN() macro instead!!! * * @param plugin_name the name of the plugin to add * @param create_func - pointer to the function to be used in to create plugin object * @param destroy_func - pointer to the function to be used to release plugin object */ static void add_static_entry_point(const std::string& plugin_name, void *create_func, void *destroy_func); /** * updates path for cygwin oddities, if necessary * * @param final_path path object for the file, will be modified if necessary * @param start_path original path to the file. if final_path is not valid, * this will be appended to PION_CYGWIN_DIRECTORY to attempt * attempt correction of final_path for cygwin */ static void check_cygwin_path(boost::filesystem::path& final_path, const std::string& path_string); /// appends a directory to the plug-in search path static void add_plugin_directory(const std::string& dir); /// clears all directories from the plug-in search path static void reset_plugin_directories(void); // default destructor virtual ~plugin() { release_data(); } /// returns true if a shared library is loaded/open inline bool is_open(void) const { return (m_plugin_data != NULL); } /// returns the name of the plugin that is currently open inline std::string get_plugin_name(void) const { return (is_open() ? m_plugin_data->m_plugin_name : std::string()); } /// returns a list of all Plugins found in all Plugin directories static void get_all_plugin_names(std::vector& plugin_names); /** * opens plug-in library within a shared object file. If the library is * already being used by another plugin object, then the existing * code will be re-used and the reference count will be increased. Beware * that this does NOT check the plug-in's base class (InterfaceClassType), * so you must be careful to ensure that the namespace is unique between * plug-ins that have different base classes. If the plug-in's name matches * an existing plug-in of a different base class, the resulting behavior is * undefined (it will probably crash your program). * * @param plugin_name name of the plug-in library to open (without extension, etc.) */ void open(const std::string& plugin_name); /** * opens plug-in library within a shared object file. If the library is * already being used by another plugin object, then the existing * code will be re-used and the reference count will be increased. Beware * that this does NOT check the plug-in's base class (InterfaceClassType), * so you must be careful to ensure that the namespace is unique between * plug-ins that have different base classes. If the plug-in's name matches * an existing plug-in of a different base class, the resulting behavior is * undefined (it will probably crash your program). * * @param plugin_file shared object file containing the plugin code */ void open_file(const std::string& plugin_file); /// closes plug-in library inline void close(void) { release_data(); } protected: /// /// data_type: object to hold shared library symbols /// struct data_type { /// default constructors for convenience data_type(void) : m_lib_handle(NULL), m_create_func(NULL), m_destroy_func(NULL), m_references(0) {} data_type(const std::string& plugin_name) : m_lib_handle(NULL), m_create_func(NULL), m_destroy_func(NULL), m_plugin_name(plugin_name), m_references(0) {} data_type(const data_type& p) : m_lib_handle(p.m_lib_handle), m_create_func(p.m_create_func), m_destroy_func(p.m_destroy_func), m_plugin_name(p.m_plugin_name), m_references(p.m_references) {} /// symbol library loaded from a shared object file void * m_lib_handle; /// function used to create instances of the plug-in object void * m_create_func; /// function used to destroy instances of the plug-in object void * m_destroy_func; /// the name of the plugin (must be unique per process) std::string m_plugin_name; /// number of references to this class unsigned long m_references; }; /// default constructor is private (use plugin_ptr class to create objects) plugin(void) : m_plugin_data(NULL) {} /// copy constructor plugin(const plugin& p) : m_plugin_data(NULL) { grab_data(p); } /// assignment operator plugin& operator=(const plugin& p) { grab_data(p); return *this; } /// returns a pointer to the plug-in's "create object" function inline void *get_create_function(void) { return (is_open() ? m_plugin_data->m_create_func : NULL); } /// returns a pointer to the plug-in's "destroy object" function inline void *get_destroy_function(void) { return (is_open() ? m_plugin_data->m_destroy_func : NULL); } /// releases the plug-in's shared library symbols void release_data(void); /// grabs a reference to another plug-in's shared library symbols void grab_data(const plugin& p); private: /// data type that maps plug-in names to their shared library data typedef std::map map_type; /// data type for static/global plugin configuration information struct config_type { /// directories containing plugin files std::vector m_plugin_dirs; /// maps plug-in names to shared library data map_type m_plugin_map; /// mutex to make class thread-safe boost::mutex m_plugin_mutex; }; /// returns a singleton instance of config_type static inline config_type& get_plugin_config(void) { boost::call_once(plugin::create_plugin_config, m_instance_flag); return *m_config_ptr; } /// creates the plugin_config singleton static void create_plugin_config(void); /** * searches directories for a valid plug-in file * * @param path_to_file if found, is set to the complete path to the file * @param name the name of the file to search for * @param extension will be appended to name if name is not found * * @return true if the file was found */ static bool find_file(std::string& path_to_file, const std::string& name, const std::string& extension); /** * normalizes complete and final path to a file while looking for it * * @param final_path if found, is set to the complete, normalized path to the file * @param start_path the original starting path to the file * @param name the name of the file to search for * @param extension will be appended to name if name is not found * * @return true if the file was found */ static bool check_for_file(std::string& final_path, const std::string& start_path, const std::string& name, const std::string& extension); /** * opens plug-in library within a shared object file * * @param plugin_file shared object file containing the plugin code * @param plugin_data data object to load the library into */ static void open_plugin(const std::string& plugin_file, data_type& plugin_data); /// returns the name of the plugin object (based on the plugin_file name) static std::string get_plugin_name(const std::string& plugin_file); /// load a dynamic library from plugin_file and return its handle static void *load_dynamic_library(const std::string& plugin_file); /// close the dynamic library corresponding with lib_handle static void close_dynamic_library(void *lib_handle); /// returns the address of a library symbal static void *get_library_symbol(void *lib_handle, const std::string& symbol); /// name of function defined in object code to create a new plug-in instance static const std::string PION_PLUGIN_CREATE; /// name of function defined in object code to destroy a plug-in instance static const std::string PION_PLUGIN_DESTROY; /// file extension used for Pion plug-in files (platform specific) static const std::string PION_PLUGIN_EXTENSION; /// file extension used for Pion configuration files static const std::string PION_CONFIG_EXTENSION; /// used to ensure thread safety of the plugin_config singleton static boost::once_flag m_instance_flag; /// pointer to the plugin_config singleton static config_type * m_config_ptr; /// points to the shared library and functions used by the plug-in data_type * m_plugin_data; }; /// /// plugin_ptr: smart pointer that manages plug-in code loaded from shared /// object libraries /// template class plugin_ptr : public plugin { protected: /// data type for a function that is used to create object instances typedef InterfaceClassType* CreateObjectFunction(void); /// data type for a function that is used to destroy object instances typedef void DestroyObjectFunction(InterfaceClassType*); public: /// default constructor & destructor plugin_ptr(void) : plugin() {} virtual ~plugin_ptr() {} /// copy constructor plugin_ptr(const plugin_ptr& p) : plugin(p) {} /// assignment operator plugin_ptr& operator=(const plugin_ptr& p) { grab_data(p); return *this; } /// creates a new instance of the plug-in object inline InterfaceClassType *create(void) { CreateObjectFunction *create_func = (CreateObjectFunction*)(get_create_function()); if (create_func == NULL) BOOST_THROW_EXCEPTION( error::plugin_undefined() ); return create_func(); } /// destroys an instance of the plug-in object inline void destroy(InterfaceClassType *object_ptr) { // fix warning ISO C++ forbids casting from pointer-to-object // to pointer to function union { void* v_; DestroyObjectFunction* f_; } Cast; Cast.v_ = get_destroy_function(); DestroyObjectFunction *destroy_func = Cast.f_; if (destroy_func == NULL) BOOST_THROW_EXCEPTION( error::plugin_undefined() ); destroy_func(object_ptr); } }; /// /// plugin_instance_ptr: smart pointer that manages a plug-in instance /// template class plugin_instance_ptr : private boost::noncopyable { public: /// default constructor & destructor plugin_instance_ptr(void) : m_instance_ptr(NULL) {} /// virtual destructor / may be extended virtual ~plugin_instance_ptr() { reset(); } /// reset the instance pointer inline void reset(void) { if (m_instance_ptr) { m_plugin_ptr.destroy(m_instance_ptr); } } /// create a new instance of the given plugin_type inline void create(const std::string& plugin_type) { reset(); m_plugin_ptr.open(plugin_type); m_instance_ptr = m_plugin_ptr.create(); } /// returns true if pointer is empty inline bool empty(void) const { return m_instance_ptr==NULL; } /// return a raw pointer to the instance inline InterfaceClassType *get(void) { return m_instance_ptr; } /// return a reference to the instance inline InterfaceClassType& operator*(void) { return *m_instance_ptr; } /// return a const reference to the instance inline const InterfaceClassType& operator*(void) const { return *m_instance_ptr; } /// return a reference to the instance inline InterfaceClassType* operator->(void) { return m_instance_ptr; } /// return a const reference to the instance inline const InterfaceClassType* operator->(void) const { return m_instance_ptr; } protected: /// smart pointer that manages the plugin's dynamic object code plugin_ptr m_plugin_ptr; /// raw pointer to the plugin instance InterfaceClassType * m_instance_ptr; }; /** * Macros to declare entry points for statically linked plugins in accordance * with the general naming convention. * * Typical use: * @code * PION_DECLARE_PLUGIN(EchoService) * .... * PION_DECLARE_PLUGIN(FileService) * * @endcode * */ #ifdef PION_STATIC_LINKING #define PION_DECLARE_PLUGIN(plugin_name) \ class plugin_name; \ extern "C" plugin_name *pion_create_##plugin_name(void); \ extern "C" void pion_destroy_##plugin_name(plugin_name *plugin_ptr); \ static pion::static_entry_point_helper helper_##plugin_name(#plugin_name, (void*) pion_create_##plugin_name, (void*) pion_destroy_##plugin_name); /// used by PION_DECLARE_PLUGIN to add an entry point for static-linked plugins class static_entry_point_helper { public: static_entry_point_helper(const std::string& name, void *create, void *destroy) { pion::plugin::add_static_entry_point(name, create, destroy); } }; #else #define PION_DECLARE_PLUGIN(plugin_name) #endif } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/user.hpp0000644000372000001440000002273212420270445020025 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_USER_HEADER__ #define __PION_USER_HEADER__ #include #include #include #include #include #include #include #include #include #include #ifdef PION_HAVE_SSL #if defined(__APPLE__) // suppress warnings about OpenSSL being deprecated in OSX #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif #include #endif namespace pion { // begin namespace pion /// /// user: base class to store user credentials /// class user : private boost::noncopyable { public: /// construct a new user object user(std::string const &username) : m_username(username) #ifdef PION_HAVE_SSL , m_password_hash_type(EMPTY) #endif {} /// construct a new user object user(std::string const &username, std::string const &password) : m_username(username) #ifdef PION_HAVE_SSL , m_password_hash_type(EMPTY) #endif { set_password(password); } /// virtual destructor virtual ~user() {} /// returns user name as a string std::string const & get_username() const { return m_username; } /// returns password for the user (encrypted if SSL is enabled) std::string const & get_password() const { return m_password; } /** * matches password credential for given user * * @param password password credentials */ virtual bool match_password(const std::string& password) const { #ifdef PION_HAVE_SSL if (m_password_hash_type == SHA_256) { unsigned char sha256_hash[SHA256_DIGEST_LENGTH]; SHA256(reinterpret_cast(password.data()), password.size(), sha256_hash); return (memcmp(sha256_hash, m_password_hash, SHA256_DIGEST_LENGTH) == 0); } else if (m_password_hash_type == SHA_1) { unsigned char sha1_hash[SHA_DIGEST_LENGTH]; SHA1(reinterpret_cast(password.data()), password.size(), sha1_hash); return (memcmp(sha1_hash, m_password_hash, SHA_DIGEST_LENGTH) == 0); } else return false; #else return m_password == password; #endif } /// sets password credentials for given user virtual void set_password(const std::string& password) { #ifdef PION_HAVE_SSL // store encrypted hash value SHA256((const unsigned char *)password.data(), password.size(), m_password_hash); m_password_hash_type = SHA_256; // update password string (convert binary to hex) m_password.clear(); char buf[3]; for (unsigned int n = 0; n < SHA256_DIGEST_LENGTH; ++n) { sprintf(buf, "%.2x", static_cast(m_password_hash[n])); m_password += buf; } #else m_password = password; #endif } #ifdef PION_HAVE_SSL /// sets encrypted password credentials for given user virtual void set_password_hash(const std::string& password_hash) { // update password string representation if (password_hash.size() == SHA256_DIGEST_LENGTH * 2) { m_password_hash_type = SHA_256; } else if (password_hash.size() == SHA_DIGEST_LENGTH * 2) { m_password_hash_type = SHA_1; } else { BOOST_THROW_EXCEPTION( error::bad_password_hash() ); } m_password = password_hash; // convert string from hex to binary value char buf[3]; buf[2] = '\0'; unsigned int hash_pos = 0; std::string::iterator str_it = m_password.begin(); while (str_it != m_password.end()) { buf[0] = *str_it; ++str_it; buf[1] = *str_it; ++str_it; m_password_hash[hash_pos++] = boost::numeric_cast(strtoul(buf, 0, 16)); } } #endif protected: /// username string const std::string m_username; /// password string (actual contents depends on implementation) std::string m_password; #ifdef PION_HAVE_SSL enum password_hash_type_t {EMPTY, SHA_1, SHA_256}; /// SHA_256 when hash created by set_password, determined by length of hash when hash is given password_hash_type_t m_password_hash_type; /// SHA256_DIGEST_LENGTH is sufficient for SHA-256 or SHA-1 unsigned char m_password_hash[SHA256_DIGEST_LENGTH]; #endif }; /// data type for a user pointer typedef boost::shared_ptr user_ptr; /// /// user_manager base class for user container/manager /// class user_manager : private boost::noncopyable { public: /// construct a new user_manager object user_manager(void) {} /// virtual destructor virtual ~user_manager() {} /// returns true if no users are defined inline bool empty(void) const { boost::mutex::scoped_lock lock(m_mutex); return m_users.empty(); } /** * used to add a new user with plaintext password * * @param username name or identifier of the user to add * @param password plaintext password of the user to add * * @return false if user with such a name already exists */ virtual bool add_user(const std::string &username, const std::string &password) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::iterator i = m_users.find(username); if (i!=m_users.end()) return false; user_ptr user_ptr(new user(username, password)); m_users.insert(std::make_pair(username, user_ptr)); return true; } /** * update password for given user * * @param username name or identifier of the user to update * @param password plaintext password of the user to update * * @return false if user with such a name doesn't exist */ virtual bool update_user(const std::string &username, const std::string &password) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::iterator i = m_users.find(username); if (i==m_users.end()) return false; i->second->set_password(password); return true; } #ifdef PION_HAVE_SSL /** * used to add a new user with encrypted password * * @param username name or identifier of the user to add * @param password_hash encrypted password of the user to add * * @return false if user with such a name already exists */ virtual bool add_user_hash(const std::string &username, const std::string &password_hash) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::iterator i = m_users.find(username); if (i!=m_users.end()) return false; user_ptr user_ptr(new user(username)); user_ptr->set_password_hash(password_hash); m_users.insert(std::make_pair(username, user_ptr)); return true; } /** * update password for given user with encrypted password * * @param username name or identifier of the user to update * @param password_hash encrypted password of the user to update * * @return false if user with such a name doesn't exist */ virtual bool update_user_hash(const std::string &username, const std::string &password_hash) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::iterator i = m_users.find(username); if (i==m_users.end()) return false; i->second->set_password_hash(password_hash); return true; } #endif /** * used to remove given user * * @return false if no user with such username */ virtual bool remove_user(const std::string &username) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::iterator i = m_users.find(username); if (i==m_users.end()) return false; m_users.erase(i); return true; } /** * Used to locate user object by username */ virtual user_ptr get_user(const std::string &username) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::const_iterator i = m_users.find(username); if (i==m_users.end()) return user_ptr(); else return i->second; } /** * Used to locate user object by username and password */ virtual user_ptr get_user(const std::string& username, const std::string& password) { boost::mutex::scoped_lock lock(m_mutex); user_map_t::const_iterator i = m_users.find(username); if (i==m_users.end() || !i->second->match_password(password)) return user_ptr(); else return i->second; } protected: /// data type for a map of usernames to user objects typedef std::map user_map_t; /// mutex used to protect access to the user list mutable boost::mutex m_mutex; /// user records container user_map_t m_users; }; /// data type for a user_manager pointer typedef boost::shared_ptr user_manager_ptr; } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/algorithm.hpp0000644000372000001440000004100412420270445021026 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_ALGORITHM_HEADER__ #define __PION_ALGORITHM_HEADER__ #include #include #include namespace pion { // begin namespace pion struct PION_API algorithm { /** base64 decoding * * @param input - base64 encoded string * @param output - decoded string ( may include non-text chars) * @return true if successful, false if input string contains non-base64 symbols */ static bool base64_decode(std::string const &input, std::string & output); /** base64 encoding * * @param input - arbitrary string ( may include non-text chars) * @param output - base64 encoded string * @return true if successful, */ static bool base64_encode(std::string const &input, std::string & output); /// escapes URL-encoded strings (a%20value+with%20spaces) static std::string url_decode(const std::string& str); /// encodes strings so that they are safe for URLs (with%20spaces) static std::string url_encode(const std::string& str); /// TODO: escapes XML/HTML-encoded strings (1 < 2) //static std::string xml_decode(const std::string& str); /// encodes strings so that they are safe for XML/HTML (2 > 1) static std::string xml_encode(const std::string& str); /// convert sequence of bytes in IEEE 754 format into a native floating point data type /// reference: http://en.wikipedia.org/wiki/Single_precision_floating-point_format static void float_from_bytes(long double& value, const unsigned char *ptr, size_t num_exp_bits, size_t num_fraction_bits); /// convert native floating point type into a sequence of bytes in IEEE 754 format /// reference: http://en.wikipedia.org/wiki/Single_precision_floating-point_format static void float_to_bytes(long double value, unsigned char *ptr, size_t num_exp_bits, size_t num_fraction_bits); /// convert sequence of one byte to 8-bit unsigned integer static inline boost::uint8_t to_uint8(unsigned char byte) { return boost::uint8_t(byte); } /// convert sequence of one byte to 8-bit signed integer static inline boost::int8_t to_int8(unsigned char byte) { return boost::int8_t(byte); } /// convert sequence of one byte to 8-bit unsigned integer static inline boost::uint8_t to_uint8(char byte) { return boost::uint8_t(byte); } /// convert sequence of one byte to 8-bit signed integer static inline boost::int8_t to_int8(char byte) { return boost::int8_t(byte); } /// convert sequence of two bytes to 16-bit unsigned integer static inline boost::uint16_t to_uint16(unsigned char high, unsigned char low) { return (((boost::uint16_t)high) << 8) | ((boost::uint16_t)low); } /// convert sequence of two bytes to 16-bit signed integer static inline boost::int16_t to_int16(unsigned char high, unsigned char low) { return (((boost::int16_t)high) << 8) | ((boost::int16_t)low); } /// convert sequence of three bytes to 24-bit unsigned integer static inline boost::uint32_t to_uint24(unsigned char high, unsigned char mid, unsigned char low) { return (((boost::uint32_t)high) << 16) | (((boost::uint32_t)mid) << 8) | ((boost::uint32_t)low); } /// convert sequence of three bytes to 24-bit signed integer static inline boost::int32_t to_int24(unsigned char high, unsigned char mid, unsigned char low) { return (((boost::int32_t)high) << 16) | (((boost::int32_t)mid) << 8) | ((boost::int32_t)low); } /// convert sequence of four bytes to 32-bit unsigned integer static inline boost::uint32_t to_uint32(unsigned char high, unsigned char mid1, unsigned char mid2, unsigned char low) { return (((boost::uint32_t)high) << 24) | (((boost::uint32_t)mid1) << 16) | (((boost::uint32_t)mid2) << 8) | ((boost::uint32_t)low); } /// convert sequence of four bytes to 32-bit signed integer static inline boost::int32_t to_int32(unsigned char high, unsigned char mid1, unsigned char mid2, unsigned char low) { return (((boost::int32_t)high) << 24) | (((boost::int32_t)mid1) << 16) | (((boost::int32_t)mid2) << 8) | ((boost::int32_t)low); } /// convert sequence of eight bytes to 64-bit unsigned integer static inline boost::uint64_t to_uint64(unsigned char high, unsigned char mid1, unsigned char mid2, unsigned char mid3, unsigned char mid4, unsigned char mid5, unsigned char mid6, unsigned char low) { return (((boost::uint64_t)high) << 56) | (((boost::uint64_t)mid1) << 48) | (((boost::uint64_t)mid2) << 40) | (((boost::uint64_t)mid3) << 32) | (((boost::uint64_t)mid4) << 24) | (((boost::uint64_t)mid5) << 16) | (((boost::uint64_t)mid6) << 8) | ((boost::uint64_t)low); } /// convert sequence of eight bytes to 64-bit signed integer static inline boost::int64_t to_int64(unsigned char high, unsigned char mid1, unsigned char mid2, unsigned char mid3, unsigned char mid4, unsigned char mid5, unsigned char mid6, unsigned char low) { return (((boost::int64_t)high) << 56) | (((boost::int64_t)mid1) << 48) | (((boost::int64_t)mid2) << 40) | (((boost::int64_t)mid3) << 32) | (((boost::int64_t)mid4) << 24) | (((boost::int64_t)mid5) << 16) | (((boost::int64_t)mid6) << 8) | ((boost::int64_t)low); } /// convert sequence of two bytes to 16-bit unsigned integer template static inline boost::uint16_t to_uint16(T1 high, T2 low) { return to_uint16(static_cast(high), static_cast(low)); } /// convert sequence of two bytes to 16-bit signed integer template static inline boost::int16_t to_int16(T1 high, T2 low) { return to_int16(static_cast(high), static_cast(low)); } /// convert sequence of three bytes to 24-bit unsigned integer template static inline boost::uint32_t to_uint24(T1 high, T2 mid, T3 low) { return to_uint24(static_cast(high), static_cast(mid), static_cast(low)); } /// convert sequence of three bytes to 24-bit signed integer template static inline boost::int32_t to_int24(T1 high, T2 mid, T3 low) { return to_int24(static_cast(high), static_cast(mid), static_cast(low)); } /// convert sequence of four bytes to 32-bit unsigned integer template static inline boost::uint32_t to_uint32(T1 high, T2 mid1, T3 mid2, T4 low) { return to_uint32(static_cast(high), static_cast(mid1), static_cast(mid2), static_cast(low)); } /// convert sequence of four bytes to 32-bit signed integer template static inline boost::int32_t to_int32(T1 high, T2 mid1, T3 mid2, T4 low) { return to_int32(static_cast(high), static_cast(mid1), static_cast(mid2), static_cast(low)); } /// convert sequence of eight bytes to 64-bit unsigned integer template static inline boost::uint64_t to_uint64(T1 high, T2 mid1, T3 mid2, T4 mid3, T5 mid4, T6 mid5, T7 mid6, T8 low) { return to_uint64(static_cast(high), static_cast(mid1), static_cast(mid2), static_cast(mid3), static_cast(mid4), static_cast(mid5), static_cast(mid6), static_cast(low)); } /// convert sequence of eight bytes to 64-bit signed integer template static inline boost::int64_t to_int64(T1 high, T2 mid1, T3 mid2, T4 mid3, T5 mid4, T6 mid5, T7 mid6, T8 low) { return to_int64(static_cast(high), static_cast(mid1), static_cast(mid2), static_cast(mid3), static_cast(mid4), static_cast(mid5), static_cast(mid6), static_cast(low)); } /// convert byte pointer into an 8-bit unsigned integer template static inline boost::uint8_t to_uint8(const Byte *buf) { return to_uint8(buf[0]); } /// convert byte pointer into an 8-bit signed integer template static inline boost::int8_t to_int8(const Byte *buf) { return to_int8(buf[0]); } /// convert sequence of two bytes to 16-bit unsigned integer template static inline boost::uint16_t to_uint16(const Byte *buf) { return to_uint16(buf[0], buf[1]); } /// convert sequence of two bytes to 16-bit signed integer template static inline boost::int16_t to_int16(const Byte *buf) { return to_int16(buf[0], buf[1]); } /// convert sequence of three bytes to 24-bit unsigned integer template static inline boost::uint32_t to_uint24(const Byte *buf) { return to_uint24(buf[0], buf[1], buf[2]); } /// convert sequence of three bytes to 24-bit signed integer template static inline boost::int32_t to_int24(const Byte *buf) { return to_int24(buf[0], buf[1], buf[2]); } /// convert sequence of four bytes to 32-bit unsigned integer template static inline boost::uint32_t to_uint32(const Byte *buf) { return to_uint32(buf[0], buf[1], buf[2], buf[3]); } /// convert sequence of four bytes to 32-bit signed integer template static inline boost::int32_t to_int32(const Byte *buf) { return to_int32(buf[0], buf[1], buf[2], buf[3]); } /// convert sequence of eight bytes to 64-bit unsigned integer template static inline boost::uint64_t to_uint64(const Byte *buf) { return to_uint64(buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); } /// convert sequence of eight bytes to 64-bit signed integer template static inline boost::int64_t to_int64(const Byte *buf) { return to_int64(buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); } /// convert 8-bit unsigned integer into sequence of one byte template static inline void from_uint8(Byte *buf, const boost::uint8_t n) { buf[0] = n & 0xFF; } /// convert 8-bit signed integer into sequence of one byte template static inline void from_int8(Byte *buf, const boost::int8_t n) { buf[0] = n & 0xFF; } /// convert 16-bit unsigned integer into sequence of two bytes template static inline void from_uint16(Byte *buf, const boost::uint16_t n) { buf[0] = (n >> 8) & 0xFF; buf[1] = n & 0xFF; } /// convert 16-bit signed integer into sequence of two bytes template static inline void from_int16(Byte *buf, const boost::int16_t n) { buf[0] = (n >> 8) & 0xFF; buf[1] = n & 0xFF; } /// convert 24-bit unsigned integer into sequence of three bytes template static inline void from_uint24(Byte *buf, const boost::uint32_t n) { buf[0] = (n >> 16) & 0xFF; buf[1] = (n >> 8) & 0xFF; buf[2] = n & 0xFF; } /// convert 24-bit signed integer into sequence of three bytes template static inline void from_int24(Byte *buf, const boost::int32_t n) { buf[0] = (n >> 16) & 0xFF; buf[1] = (n >> 8) & 0xFF; buf[2] = n & 0xFF; } /// convert 32-bit unsigned integer into sequence of four bytes template static inline void from_uint32(Byte *buf, const boost::uint32_t n) { buf[0] = (n >> 24) & 0xFF; buf[1] = (n >> 16) & 0xFF; buf[2] = (n >> 8) & 0xFF; buf[3] = n & 0xFF; } /// convert 32-bit signed integer into sequence of four bytes template static inline void from_int32(Byte *buf, const boost::int32_t n) { buf[0] = (n >> 24) & 0xFF; buf[1] = (n >> 16) & 0xFF; buf[2] = (n >> 8) & 0xFF; buf[3] = n & 0xFF; } /// convert 64-bit unsigned integer into sequence of eight bytes template static inline void from_uint64(Byte *buf, const boost::uint64_t n) { buf[0] = (n >> 56) & 0xFF; buf[1] = (n >> 48) & 0xFF; buf[2] = (n >> 40) & 0xFF; buf[3] = (n >> 32) & 0xFF; buf[4] = (n >> 24) & 0xFF; buf[5] = (n >> 16) & 0xFF; buf[6] = (n >> 8) & 0xFF; buf[7] = n & 0xFF; } /// convert 64-bit signed integer into sequence of eight bytes template static inline void from_int64(Byte *buf, const boost::int64_t n) { buf[0] = (n >> 56) & 0xFF; buf[1] = (n >> 48) & 0xFF; buf[2] = (n >> 40) & 0xFF; buf[3] = (n >> 32) & 0xFF; buf[4] = (n >> 24) & 0xFF; buf[5] = (n >> 16) & 0xFF; buf[6] = (n >> 8) & 0xFF; buf[7] = n & 0xFF; } /// convert sequence of four bytes in 32-bit "single precision" binary32 format into a float /// http://en.wikipedia.org/wiki/Single_precision_floating-point_format template static inline float to_float(const Byte *ptr) { long double value; float_from_bytes(value, (unsigned char *)ptr, 8U, 23U); return value; } /// convert sequence of eight bytes in 64-bit "double precision" binary64 format into a double /// http://en.wikipedia.org/wiki/Double_precision_floating-point_format template static inline double to_double(const Byte *ptr) { long double value; float_from_bytes(value, (unsigned char *)ptr, 11U, 52U); return value; } /// convert sequence of sixteen bytes in 128-bit "quadruple precision" format into a long double /// http://en.wikipedia.org/wiki/Quadruple_precision_floating-point_format template static inline long double to_long_double(const Byte *ptr) { long double value; float_from_bytes(value, (unsigned char *)ptr, 15U, 112U); return value; } /// convert float into sequence of four bytes in "single precision" binary32 format /// http://en.wikipedia.org/wiki/Single_precision_floating-point_format template static inline void from_float(Byte *ptr, const float n) { float_to_bytes(n, (unsigned char*)ptr, 8U, 23U); } /// convert double into sequence of eight bytes in "double precision" binary64 format /// http://en.wikipedia.org/wiki/Double_precision_floating-point_format template static inline void from_double(Byte *ptr, const double n) { float_to_bytes(n, (unsigned char*)ptr, 11U, 52U); } /// convert long double into sequence of sixteen bytes in 128-bit "quadruple precision" format /// http://en.wikipedia.org/wiki/Quadruple_precision_floating-point_format template static inline void from_long_double(Byte *ptr, const long double n) { float_to_bytes(n, (unsigned char*)ptr, 15U, 112U); } }; } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/pion/Makefile.am0000644000372000001440000000062312420270445020365 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- pion_includedir = $(includedir)/pion pion_include_HEADERS = \ admin_rights.hpp algorithm.hpp config.hpp error.hpp hash_map.hpp logger.hpp \ plugin.hpp plugin_manager.hpp process.hpp scheduler.hpp user.hpp EXTRA_DIST = config.hpp.win config.hpp.xcode config.hpp.in SUBDIRS = http spdy test tcp pion-5.0.7+dfsg.orig/include/pion/scheduler.hpp0000644000372000001440000002724412420270445021030 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_SCHEDULER_HEADER__ #define __PION_SCHEDULER_HEADER__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion /// /// scheduler: combines Boost.ASIO with a managed thread pool for scheduling /// class PION_API scheduler : private boost::noncopyable { public: /// constructs a new scheduler scheduler(void) : m_logger(PION_GET_LOGGER("pion.scheduler")), m_num_threads(DEFAULT_NUM_THREADS), m_active_users(0), m_is_running(false) {} /// virtual destructor virtual ~scheduler() {} /// Starts the thread scheduler (this is called automatically when necessary) virtual void startup(void) {} /// Stops the thread scheduler (this is called automatically when the program exits) virtual void shutdown(void); /// the calling thread will sleep until the scheduler has stopped void join(void); /// registers an active user with the thread scheduler. Shutdown of the /// scheduler is deferred until there are no more active users. This /// ensures that any work queued will not reference destructed objects void add_active_user(void); /// unregisters an active user with the thread scheduler void remove_active_user(void); /// returns true if the scheduler is running inline bool is_running(void) const { return m_is_running; } /// sets the number of threads to be used (these are shared by all servers) inline void set_num_threads(const boost::uint32_t n) { m_num_threads = n; } /// returns the number of threads currently in use inline boost::uint32_t get_num_threads(void) const { return m_num_threads; } /// sets the logger to be used inline void set_logger(logger log_ptr) { m_logger = log_ptr; } /// returns the logger currently in use inline logger get_logger(void) { return m_logger; } /// returns an async I/O service used to schedule work virtual boost::asio::io_service& get_io_service(void) = 0; /** * schedules work to be performed by one of the pooled threads * * @param work_func work function to be executed */ virtual void post(boost::function0 work_func) { get_io_service().post(work_func); } /** * thread function used to keep the io_service running * * @param my_service IO service used to re-schedule keep_running() * @param my_timer deadline timer used to keep the IO service active while running */ void keep_running(boost::asio::io_service& my_service, boost::asio::deadline_timer& my_timer); /** * puts the current thread to sleep for a specific period of time * * @param sleep_sec number of entire seconds to sleep for * @param sleep_nsec number of nanoseconds to sleep for (10^-9 in 1 second) */ inline static void sleep(boost::uint32_t sleep_sec, boost::uint32_t sleep_nsec) { boost::system_time wakeup_time(get_wakeup_time(sleep_sec, sleep_nsec)); boost::thread::sleep(wakeup_time); } /** * puts the current thread to sleep for a specific period of time, or until * a wakeup condition is signaled * * @param wakeup_condition if signaled, the condition will wakeup the thread early * @param wakeup_lock scoped lock protecting the wakeup condition * @param sleep_sec number of entire seconds to sleep for * @param sleep_nsec number of nanoseconds to sleep for (10^-9 in 1 second) */ template inline static void sleep(ConditionType& wakeup_condition, LockType& wakeup_lock, boost::uint32_t sleep_sec, boost::uint32_t sleep_nsec) { boost::system_time wakeup_time(get_wakeup_time(sleep_sec, sleep_nsec)); wakeup_condition.timed_wait(wakeup_lock, wakeup_time); } /// processes work passed to the asio service & handles uncaught exceptions void process_service_work(boost::asio::io_service& service); protected: /** * calculates a wakeup time in boost::system_time format * * @param sleep_sec number of seconds to sleep for * @param sleep_nsec number of nanoseconds to sleep for * * @return boost::system_time time to wake up from sleep */ static boost::system_time get_wakeup_time(boost::uint32_t sleep_sec, boost::uint32_t sleep_nsec); /// stops all services used to schedule work virtual void stop_services(void) {} /// stops all threads used to perform work virtual void stop_threads(void) {} /// finishes all services used to schedule work virtual void finish_services(void) {} /// finishes all threads used to perform work virtual void finish_threads(void) {} /// default number of worker threads in the thread pool static const boost::uint32_t DEFAULT_NUM_THREADS; /// number of nanoseconds in one full second (10 ^ 9) static const boost::uint32_t NSEC_IN_SECOND; /// number of microseconds in one full second (10 ^ 6) static const boost::uint32_t MICROSEC_IN_SECOND; /// number of seconds a timer should wait for to keep the IO services running static const boost::uint32_t KEEP_RUNNING_TIMER_SECONDS; /// mutex to make class thread-safe boost::mutex m_mutex; /// primary logging interface used by this class logger m_logger; /// condition triggered when there are no more active users boost::condition m_no_more_active_users; /// condition triggered when the scheduler has stopped boost::condition m_scheduler_has_stopped; /// total number of worker threads in the pool boost::uint32_t m_num_threads; /// the scheduler will not shutdown until there are no more active users boost::uint32_t m_active_users; /// true if the thread scheduler is running bool m_is_running; }; /// /// multi_thread_scheduler: uses a pool of threads to perform work /// class PION_API multi_thread_scheduler : public scheduler { public: /// constructs a new single_service_scheduler multi_thread_scheduler(void) {} /// virtual destructor virtual ~multi_thread_scheduler() {} protected: /// stops all threads used to perform work virtual void stop_threads(void) { if (! m_thread_pool.empty()) { PION_LOG_DEBUG(m_logger, "Waiting for threads to shutdown"); // wait until all threads in the pool have stopped boost::thread current_thread; for (ThreadPool::iterator i = m_thread_pool.begin(); i != m_thread_pool.end(); ++i) { // make sure we do not call join() for the current thread, // since this may yield "undefined behavior" if (**i != current_thread) (*i)->join(); } } } /// finishes all threads used to perform work virtual void finish_threads(void) { m_thread_pool.clear(); } /// typedef for a pool of worker threads typedef std::vector > ThreadPool; /// pool of threads used to perform work ThreadPool m_thread_pool; }; /// /// single_service_scheduler: uses a single IO service to schedule work /// class PION_API single_service_scheduler : public multi_thread_scheduler { public: /// constructs a new single_service_scheduler single_service_scheduler(void) : m_service(), m_timer(m_service) {} /// virtual destructor virtual ~single_service_scheduler() { shutdown(); } /// returns an async I/O service used to schedule work virtual boost::asio::io_service& get_io_service(void) { return m_service; } /// Starts the thread scheduler (this is called automatically when necessary) virtual void startup(void); protected: /// stops all services used to schedule work virtual void stop_services(void) { m_service.stop(); } /// finishes all services used to schedule work virtual void finish_services(void) { m_service.reset(); } /// service used to manage async I/O events boost::asio::io_service m_service; /// timer used to periodically check for shutdown boost::asio::deadline_timer m_timer; }; /// /// one_to_one_scheduler: uses a single IO service for each thread /// class PION_API one_to_one_scheduler : public multi_thread_scheduler { public: /// constructs a new one_to_one_scheduler one_to_one_scheduler(void) : m_service_pool(), m_next_service(0) {} /// virtual destructor virtual ~one_to_one_scheduler() { shutdown(); } /// returns an async I/O service used to schedule work virtual boost::asio::io_service& get_io_service(void) { boost::mutex::scoped_lock scheduler_lock(m_mutex); while (m_service_pool.size() < m_num_threads) { boost::shared_ptr service_ptr(new service_pair_type()); m_service_pool.push_back(service_ptr); } if (++m_next_service >= m_num_threads) m_next_service = 0; BOOST_ASSERT(m_next_service < m_num_threads); return m_service_pool[m_next_service]->first; } /** * returns an async I/O service used to schedule work (provides direct * access to avoid locking when possible) * * @param n integer number representing the service object */ virtual boost::asio::io_service& get_io_service(boost::uint32_t n) { BOOST_ASSERT(n < m_num_threads); BOOST_ASSERT(n < m_service_pool.size()); return m_service_pool[n]->first; } /// Starts the thread scheduler (this is called automatically when necessary) virtual void startup(void); protected: /// stops all services used to schedule work virtual void stop_services(void) { for (service_pool_type::iterator i = m_service_pool.begin(); i != m_service_pool.end(); ++i) { (*i)->first.stop(); } } /// finishes all services used to schedule work virtual void finish_services(void) { m_service_pool.clear(); } /// typedef for a pair object where first is an IO service and second is a deadline timer struct service_pair_type { service_pair_type(void) : first(), second(first) {} boost::asio::io_service first; boost::asio::deadline_timer second; }; /// typedef for a pool of IO services typedef std::vector > service_pool_type; /// pool of IO services used to schedule work service_pool_type m_service_pool; /// the next service to use for scheduling work boost::uint32_t m_next_service; }; } // end namespace pion #endif pion-5.0.7+dfsg.orig/include/Makefile.am0000644000372000001440000000017112420270445017416 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- SUBDIRS = pion pion-5.0.7+dfsg.orig/doc/0000755000372000001440000000000012420270445014505 5ustar robertouserspion-5.0.7+dfsg.orig/doc/README.osx0000644000372000001440000001517612420270445016207 0ustar robertousersMac OS X Build Instructions =========================== The Easy Way: ------------- Atomic Labs has a tarball available from the "Third Party Libraries" page on our website that contains all of the required libraries to build Pion, with support for both 32-bit and 64-bit Intel and PowerPC architectures. To get started quickly, just download and uncompress this into your /usr/local/ directory, and you should be able to skip down to one of the last two steps! Installing ICU on OSX: ---------------------- Boost requires the ICU library for i18n support. You can download the source code for ICU from: http://site.icu-project.org/ After downloading it, just run: # tar xvfz icu4c--src.tgz # cd icu/source # ./runConfigureICU MacOSX --enable-static # make all # make install As of version 4.2.1, it doesn't seem to be possible to build universal libraries of ICU (or at least we haven't figured it out yet), however you can build 64-bit binaries on OSX using an included patch file: # tar xvfz icu4c--src.tgz # cd icu # patch -p1 < /path/to/pion-source/common/build/icu-4.2.1-osx.patch # cd source # ./runConfigureICU MacOSX --enable-static # make all # make install Note that 64-bit builds of Boost on OSX seem to be extremely buggy, so this is not recommended. Installing Boost on OSX: ------------------------ Please see the README.boost file for general instructions. The bjam command to build all Boost libraries (1.43 and earlier) for OSX is: # bjam -sHAVE_ICU=1 --toolset=darwin release threading=multi stage The bjam command to build all Boost libraries (1.44 and later) for OSX is: # bjam -sICU_PATH=/usr/local --toolset=darwin release threading=multi stage Installing zlib, bzlib & openssl: --------------------------------- Pion requires zlib, bzlib and openssl for compression and SSL/TLS encryption support, respectively. These libraries are normally pre-installed on OS X. If you do not have them already, you should be able to grab the latest source code tarballs from the "Third Party Libraries" page on our website, or from the following sites: http://www.zlib.net http://www.bzip.org http://www.openssl.org Installing log4cplus: --------------------- Note that the use of a logging framework is entirely optional, so you may skip this step if you like. We recommend that you use log4cplus for logging. Please visit the "Third Party Libraries" page on our website to obtain the source code tarball for log4cplus. Then, just run: # tar xvfj log4cplus-.tar.bz2 # cd log4cplus- # ./configure --enable-threads=yes # make all # make install For Universal binaries, use: # CXXFLAGS="-arch i386 -arch x86_64 -arch ppc -arch ppc64" ./configure \ --disable-dependency-tracking Installing libxml2: ------------------- The Pion Platform requires the libxml2 development library for manipulating configuration files, and other things. This library is not used by the Pion Network Library, so you may skip this step if you are only building the Network Library. The libxml2 library is normally pre-installed on OS X. If you do not have it already, you should be able to grab the latest source code tarball from the "Third Party Libraries" page on our website, or from the following site: http://www.xmlsoft.org Installing lxml: ---------------- Pion's pupgrade.py script requires that you have the lxml library installed. This can be installed with one easy step: # sudo easy_install lxml If you get an error about an architecture not being installed, try using this command instead: # sudo env ARCHFLAGS="-arch x86_64" easy_install lxml Installing YAJL: ---------------- YAJL ("Yet Another JSON Library") is required to build support for the JSONCodec plugin. You may skip this step if you do not want to build support for JSON. To build YAJL, you must first have CMake installed on your system. You can download the source tarball for CMake from the "Third Party Libraries" page on our website, or from the following site: http://cmake.org You can download the source code tarball for YAJL from the "Third Party Libraries" page on our website. After downloading it, just run: # tar xvfz yajl-.tgz # cd yajl- # ./configure # make Note: to build universal libraries, edit the CMakeLists.txt file before running "./configure" and change this line: SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -ansi") to this: SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -ansi -arch i386 -arch x86_64 -arch ppc -arch ppc64") To install YAJL, we recommend that you just move the build files in the "build/yajl-" subdirectory into /usr/local: # sudo mv build/yajl-/lib/* /usr/local/lib # sudo mv build/yajl-/include/yajl /usr/local/include Building and installing Pion: ----------------------------- Now you should be able to build and install Pion: # tar xvfz pion--.tar.gz # cd pion-- # ./configure [--with-arch=ppc64,x86_64] [--with-cpu=nocona] # make all # make install To build and run Pion's unit tests, run "make check" Building with XCode: -------------------- There is an XCode project included in the root directory of each project called "pion-.xcodeproj". The XCode project assumes that you have the following optional libraries installed: openssl, zlib and log4cxx. It also is configured to build a Universal binary with support for the i386 and ppc architectures. You must have built all the dependency libraries with support for both architectures for this to work properly. A tarball containing all of these built for both the 32-bit and 64-bit Intel and PowerPC architectures is available on the "Third Party Libraries" on our website. Alternatively, you can just modify the XCode project config to build only for your native architecture. To run the Pion server from within XCode, you first need to configure the executable's command arguments by right-clicking on "pion" under the "Executables" group in the left menu, and selecting "Get Info." Under the "Arguments" tab, add the following argument: "-c ../../platform/server/platform.xml" Next, set "pion" as the "Active Target" and click on the "Build and Go" button. Building "pion" will also build all of the service, codec, database and reactor plug-ins. To run PionWebServer from within XCode, you first need to configure the executable's command arguments by right-clicking on PionWebServer under the "Executables" group in the left menu, and selecting "Get Info." Under the "Arguments" tab, add the following argument: "-c ../../net/utils/services.conf" Next, set PionWebServer as the "Active Target" and click on the "Build and Go" button. Building PionWebServer will also build all of the service plug-ins. pion-5.0.7+dfsg.orig/doc/README.linux0000644000372000001440000001377512420270445016540 0ustar robertousersLinux Build Instructions ======================== The Easy Way: ------------- Atomic Labs has a tarball available from the "Third Party Libraries" page on our website that contains all of the required libraries to build Pion for certain versions of Redhat Linux. To get started quickly, just download and uncompress this file into your /usr/local/ directory, and you should be able to skip down to the last step! Installing ICU: --------------- Boost requires the ICU library for i18n support. This library is normally pre-installed on Linux. If you do not have it already, you should be able to grab the latest version using your favorite package manager: # yum install libicu libicu-devel # up2date libicu libicu-devel Installing Boost: ----------------- Please see the README.boost file for instructions. If you have an older version of Boost (pre-1.35) already installed, you will likely will need to first uninstall it so that gcc and libtool do not get confused: # rpm -e boost boost-devel If you're using RHEL/CentOS 4 (or earlier), please note that Boost 1.37.0 does not seem to work with gcc 3.x. You should use gcc4 instead: # yum install gcc4 gcc4-c++ Before running "make" to build the Boost libraries, edit the tools/build/v2/user-config.jam file and change this: using gcc ; to this: using gcc : : g++4 ; Installing zlib, bzlib & openssl: --------------------------------- Pion requires zlib, bzlib and openssl for compression and SSL/TLS encryption support, respectively. These libraries are normally pre-installed on Linux. If you do not have them already, you should be able to use your favorite package manager (yum, up2date or aptget) to install the latest versions: # yum install openssl openssl-devel zlib zlib-devel bzip2 bzip2-devel bzip2-libs # up2date openssl openssl-devel zlib zlib-devel bzip2 bzip2-devel bzip2-libs Installing log4cplus: --------------------- Note that the use of a logging framework is entirely optional, so you may skip this step if you like. We recommend that you use log4cplus for logging. Please visit the "Third Party Libraries" page on our website to obtain the source code tarball for log4cplus. Then, just run: # tar xvfj log4cplus-.tar.bz2 # cd log4cplus- # ./configure --enable-threads=yes # make all # make install Installing libxml2: ------------------- The Pion Platform requires the libxml2 development library for manipulating configuration files, and other things. This library is not used by the Pion Network Library, so you may skip this step if you are only building the Network Library. The libxml2 library is normally pre-installed on Linux. If you do not have it already, you should be able to grab the latest version using your favorite package manager: # yum install libxml2 libxml2-devel # up2date libxml2 libxml2-devel Installing Python: ------------------ Pion's PythonReactor requires Python version 2.4 or greater. You may skip this step if you do not want to build support for Python. Python 2.4 (or greater) is already pre-installed and should work out of the box on most Linux systems. If you do not have it already, you should be able to grab the latest version using your favorite package manager: # yum install python python-devel # up2date python python-devel RHEL/CentOS 4 shipped with Python 2.3. For this platform, we recommend that you download, build and install Python 2.6 into your /usr/local directories. You can download the source code from: http://www.python.org # tar xvfj Python-2.6.X.tar.bz2 # cd Python-2.6.X # ./configure --with-threads # make all # make install When you run the "configure" script for Pion, add the "--with-python" option to use the new version installed in /usr/local/bin instead of the default one: # ./configure --with-python=/usr/local/bin/python Installing lxml: ---------------- Pion's pupgrade.py script requires that you have the lxml library installed. The easiest way to do this is using the easy_install utility: # yum install python-setuptools libxml2-devel libxslt-devel # easy_install lxml You can also obtain lxml RPMs from either the RPMforge or EPEL (Extra Packages for Enterprise Linux) repositories. We recommend that you use EPEL since it is more up-to-date. On EL5, you can use the following command to set up this repository: (32-bit) # rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm (64-bit) # rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm You can then use yum to install the library with the following command: # yum install python-lxml Installing YAJL: ---------------- YAJL ("Yet Another JSON Library") is required to build support for the JSONCodec plugin. You may skip this step if you do not want to build support for JSON. To build YAJL, you must first have Ruby and CMake installed on your system. If you do not have them already, you should be able to grab the latest versions using your favorite package manager: # yum install ruby cmake # up2date ruby cmake You can download the source code tarball for YAJL from the "Third Party Libraries" page on our website. After downloading it, just run: # tar xvfz yajl-.tgz # cd yajl- # ./configure # make To install YAJL, we recommend that you just move the build files in the "build/yajl-" subdirectory into /usr/local: # sudo mv build/yajl-/lib/* /usr/local/lib # sudo mv build/yajl-/include/yajl /usr/local/include Building and installing Pion: ----------------------------- Now you should be able to build and install Pion: # tar xvfz pion--.tar.gz # cd pion-- # ./configure # make all # make install To build and run Pion's unit tests, run "make check" Note: if you're using RHEL/CentOS 4 with Boost 1.37.0 & gcc4, use: # CC="gcc4" CXX="g++4" ./configure ... Known Problems -------------- The Pion executables may complain about loading shared libraries if the Boost and/or other libraries are not in your search path. Try this: export LD_LIBRARY_PATH=/usr/local/lib pion-5.0.7+dfsg.orig/doc/Doxyfile0000644000372000001440000014551512420270445016226 0ustar robertousers# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = pion # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 5.0.6 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = include src services utils # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = doc/pion-net.tag # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = NO # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO pion-5.0.7+dfsg.orig/doc/README.boost0000644000372000001440000000703712420270445016521 0ustar robertousersPion requires Boost 1.35.0 (or later). Since this is still a fairly recent release, few of our supported platforms currently have pre-built versions available of these libraries. Therefore, you will likely need to download, compile and install Boost using the source code tarballs. Obtaining Boost: ---------------- First, download the latest tarball from SourceForge.net: # wget http://downloads.sourceforge.net/boost/boost_1_42_0.tar.bz2 Next, uncompress the tarball into a new directory: # bzip2 -dc boost_1_42_0.tar.bz2 | tar xvf - Building and Installing Boost: ------------------------------ bjam (http://www.boost.org/tools/build/v2/index.html) is a tool you can use to build Boost that allows you to configure many different options for your build. For a description of options available when building Boost with bjam, please see the Getting Started Guide at http://www.boost.org/more/getting_started/. You can build bjam by running the included "bootstrap.bat" on Windows or "bootstrap.sh" on Unix. You can also download bjam executables from: http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941 NOTE: We strongly recommend using the version of bjam distributed with the Boost source code you are using. In some cases, using an older bjam than the version of source that you have will cause the build to fail without any warning or explanation. You only need to build eight of the Boost libraries for Pion: thread, system, filesystem, regex, date_time, signals, iostreams and unit_test_framework. If you wish to only build these eight libraries (this will save you a lot of time), include the following options when running bjam: "--with-thread --with-system --with-filesystem --with-regex --with-date_time --with-signals --with-iostreams --with-test" We recommend that you build Boost with Unicode and ICU support. If the ICU library is included with your operating system, this is auto-enabled for you in versions 1.44 and later, and can be usually be accomplished for earlier versions by adding "-sHAVE_ICU=1" to your bjam options. If you do not have ICU, you can download the ICU source code from: http://site.icu-project.org/ You can use "-sICU_PATH=" to specify altnerative paths for ICU. More information on building Boost with Unicode support can be found at (for older versions): http://www.boost.org/doc/libs/1_42_0/libs/regex/doc/html/boost_regex/install.html#boost_regex.install.building_with_unicode_and_icu_support (for newer versions): http://www.boost.org/doc/libs/1_46_0/libs/regex/doc/html/boost_regex/install.html#boost_regex.install.building_with_unicode_and_icu_support For example (when using Microsoft Visual C++ with Boost 1.43 or earlier): # bjam --toolset=msvc -sHAVE_ICU=1 \ --with-thread --with-system --with-filesystem --with-regex \ --with-date_time --with-signals --with-iostreams --with-test \ release threading=multi stage For example (when using gcc with Boost 1.44 or later and 4 processes): # bjam --toolset=gcc -j4 release threading=multi stage For example (when using gcc on OSX with Boost 1.44 and later) for OSX is: # bjam -sICU_PATH=/usr/local --toolset=darwin release threading=multi stage This will build the libraries required by Pion and place the files within the stage/ subdirectory of your build directory. To install, you can now just copy the files in stage/lib into your library include path, and copy the boost/ directory into your header include path. Some platforms may require additional steps for building Boost. Please see the appropriate README.platform file for more information. pion-5.0.7+dfsg.orig/doc/pion-net.png0000644000372000001440000015521112420270445016751 0ustar robertousersPNG  IHDR$ 'aiCCPICC Profilexҿka{A[FqAB,E&M[bHRrwMwrImuvpt89Y"(GE9o2`x>J2)GC[ikRذc 8sSN ZJZfEz kł]m9/m:kEiן֘hRY֤WDZr-?[&M  %29S"]z@/|n^9׵̸ukqu&s_ pHYs   IDATxw\Sǟ= Kq`BqABնUj]l먣_uU-uVEPqJ$! d$Ǒۈ %pyܜܓ99!( `*`0 `0i0 ƞPfl_kAX+`0ej(bhAAQAJ SC@cX,ڠ0L.-D#MQ6]Zv}}M=c&KKDzpBf SJ1LM)lX,$I*-_>rz9Qu'Q-x0ҹa~yFj޼y@@@@@@.] tҥK.oEQ͛7Go A(2̊cǎ 2$ w= ݻLZtC3L:6y%?o4I4 .`_r%88888ɓEEDDۗNSΝ;W\ٰaL&())y>Ǐryy}Y'O>}]zΝ;_D;vtvvF&9P5bfɤ=݁=g&h4 -rV+ݳAĈXl0Հ7n(-[ϟ?|09rs;wL&SQQѮ]o;v,`ʔ)" rJjjjΝrH$1cl߾GRV\ <8rH$SN@@@j}ɕ+Wn_ˆ ~EL&ZX;vXreQQ:3k֬:uꄅu9##E~pa]";ܠn"_9ˡ&$If]`M4rJ||<=ʄZ+W|w;;wD;v죏> }>={:u꧟~ںu+Pu .899@^^رc࣏> ={ܻwڵs7ocǎׯ_H9s&ܹs'..eotyyycƌAz`'N|kjjjXX؊+G]fݻwBmlPƧEyPb07x pmgggHh5 b...ecH4`Ν;{yyi4(@rrr~Ё dzͧ̌KQQ2fbb5РA0aaa...7n\fMO`ƌfͺ>(jrN7f(jn)9Ps!pS dJhlyyyG޽ے=<:@*UTT4`B1e:MVV3BCCww޽Yf0ydBh$ yF5sI&]xGDZ4 =~ؠ3JO\r * ^ԩ(x@]PE0 Р*̈́?M4AĉCBBG˵MfX,ƍw߾}\.\R*feȐ!SL:t(6H$֯_9<}h;]\\8Jw^DwM֭|i\fʕ+KQQQll[xuVM&3V~M*ct/ ^p0gg&Nsl9QT[ӸQaA}ܘ+mk͕+T,zEjhdtu֙p\ѭ V$Ig%rfe󊏌F'T*PE^h4*ɓ'=yK/@{#JnYwwݵZp@Ĝ:<.8.A2;Ճ]HCꗫ?; +<wiU&ݾ|9Y" >,o`=ek%b HMM =_ r}}B^` O>@8ȝ :ˉ& XZa;d/Jߩb9-oV2`o K;)} /-J޸݌Yy}C߾{ƌu?x,6L M.ݵzF7=i:x<[H,O=UlسqNX6?ug"l2d8ZY>rdΜk-#rs1ʹ9 +:Ιj\|gU!݃ .0!fy~: xYIMYCBd֍9/ ,<:XDZ:.m6+2r"× 6dxȽuado,.I>N0lA㷽 CS:6H&v{a0EQ*eQ8pXyX)챼_K=cZ=* Atc C7}5\zxwnjwaΘ,OUd]@vl0L Df7ZYT\gl|zt-Z m5~҅#y[xSb]0䊖d&D5Auԩkbfy<DbX*D"rs%WE``05V)|>bfrE"` IMޠtl RT,5k 2b`jl6ReZ[Ph4IDbSƤj8{رcKw,|' < ϧ}  Jbq8@,K L&jXl{6Uɓ'Y,jU*on۶m\vchRT>g`0og9ݺCSJh=R,СC^\I)=썆`jHT , :_fo&Lx7n89a@ԅ cX,EQ=suV[1ɴʾ.qoN0*3OM= SZƍAAAeNoUf= Sé⚗bmܸϟ?mڴMEQw/l0 R8~xDDıcǺvʴ-S{e`0U \]]{ʴ!AFT6lr ST)e<# +ވY0*~rN^_ *(ǡ։ zbT'~ʠebhze|@ 0\GOj^9plI}ŦBb1L۷oq4{6ULLLy<ͶZXo0S1G1=e71E\Hc>tWt/\\X-%i>mA{pј[6gdħ-]M jɓ'LY6*-`uRdh(}Ns'2mL^R{6(޸NZ Ћil$^o4ircjJi0ŠR9REsf#: V>4 xYC =[҅5fM0mQb$i6i-`L.GymLflsdj0HƼ5Hf]6q8ڶmƴ!A4hi[7d ?إ芿w^-{c:,0]{1'3}'o`US e.4n?8o1 b`yK8uMN;S8q)BE?h}SJn3}ۿ+CC[0>a6+#(Z>ؼ%,$ !:Kv{/& WN~@p]z0cVó _9rC ɦo? NQ|dO 霚Ot왷-5_mlmNȐuk~O3!d䀵 Cݢ=C^mK٫~QB($^~ 9ŢHFgb3lbS!H@@C-F|6}0CkBZ#yHdpXFz)Zo'-=a2own= Y?}ņ~,be1k Z5ĺ9>m/l7rc0J$ ۮ];ڷo߳gO8w\C={4LzFT@zzz+ZLǎ{IܹsFS]tׯ˥;:LbcG 3C 4Sb=-+ 2rQ^Gh%syvx;R f4'H )}κsÎ 0n5`hr?l`jT"hq4W9D@zPnFEQ#zŦbptq{'Vmk, wd~>VOL; aשi>lQOv: ygކ~qlD~иEA3@f@`?YG]:њ/V/^-S@ch(Үht#{o\;buAI"ғ7LYRqZVѨjR|q߾}l0V\Z$Bd6*T]RJa 9[U&{:|g0֒7 `s'EGG3I,s8GpzN bV|l+Yro?IRH2p|( 2JHWTi%YL5ޭ Nރ L;F" b`jHo(+2b"{~ш28΍d‘vAPC^uĈ%Xl0LMUh>FPsET&̆Tb`jjz^fQdfћN18V\gaڜji=[pb+_fP$P !1uQG|WR7PXد[G5W?t<O%e2cݠ~vo ƞ R[Alch!E 5oUaB]OŴY}CꪒF&؜ 1}YUS/ge}:qOMsQ>>]\Zo]wprm0l+o/MK2ub$ǫ_ܓ'sAD9FʹEe 3 #2.@V08`>CݵoKAf1 l}yu]r ,la~Ƽۨ?~yGάI<҇+bo憶AĮ6bwnw^K$EMceOZ1D=$X^P&WRʇ ulc/j@4XlH$Bbc9w^z577LblRhH$Q PO` U~o4apO ` y:FCrƻ~*˖ɮls`ub#Pٱ鸘݉K'ӵD6+̿P> >H=<,ɧE.(JޯcQY:a\. BTJQ$IF^%''t: Jo:0#DRT, :VCh`3mMѳ|>> Jvxt~"Ih谛?89ջ~b'b?t_HLz[vι5n6's7&tI sB#,A8 ('`2L&lˊ)S8 :u4qD{$H9/B4&aɤ5Jz\.A)V2ӀfzU 8(XgKdlʻ}ǐzyWZ-^|+λ͗3ܜ%@ pf.$HxHDK2V\\w}^bwųev)\.#x`0H93Xڗi-Q;/> i IDAT]Se:YӔquhAeXhiNo۷?w\AAaBBB*l8Q2 p'l0;#z{1Տh\=x`޼y͛7OHH8{3F-^/s6cь7eT,pٳg,Y2jԨw}zݻw ̈́I] 〼7Z{1 ]9zCgEŋ5bQqX S.5fqqٳf5kdy{P)`i݇*Dnnn|||@@?aUkN/7i+jyϦ=ztٲeǏ`  |z0 Xlպz3g,]4 is0 MCʏisCI79sixcj3AbbD"a ` - ՗ߩݹnZȧapl9 cF! 3n=7nzy3GN#*OжtE~fzW:SbS"Tׯ'$$+.. 7 C‚t⢢BJUTTjKJJʄ5(;zE$ B066ť&3gtҥY:P((@m*Pǎ#AmJU%e c Ų|˗׫Wis0LYh# o2PCzv>}Ξ={޽2qC>ۗU7:ok׮" ٠ bEExqQ* 2,11Q(1Z8(;N,]Ç8pyIVV?~СB@ 0UfIؼ3gFGG0m y)+˅6>4[CM~~e8rQ^ӧW_}eG{P/^X,v zEHu}pINNްaôi˜ z^(h4͊+֭[b>޽{Zj?x<;ڳg4EQTJJʘ1c+EV۱7ڋ!Irɒ%ׯ_シ6 ԃAb{`2֭[`A%$$]&LrqWWW;qݻc c?A :``05 ))믿uV,XJ'.((PTM4 cǎ]nfgΜq ?~ĉgΜi֬٢E"##nݺZѣWZUWG8*pm72ɽyy?/J6. Se4(<<<77w͚5W\y*ٳ^^^ 6 ^r1p<)6#Iƺcva0*@RM4iӦKHHyȑ#2.gݯ_~͛7͛o޼yY&޼͆ksbGMՍ QZ "4n!޵ $ s7ZUh0p*qAD訣w `([(A|=b00L˗/oڴUn޼9k,X̴])6rIۼ&h.J&.Vѩ4yUvj @\- ͪS?DEk+3{2n͙k: RRf}q=qjް9Ґ} x<#NzjH6me˖Mn5Sl$$_QKZ,?I'#ZJ7QtSoۗS +& 732FF.Ih$凎Xh Ku2pWLD(Nk1Zn!Cԭ[iC)6FG" |NP@nm>wݥcށ!@Ҧų"|%Ϟr0z̮kS 1\jslIRhKX5Dဓ uCRWĞN)4[臛3\_ ӎv'uN.Cތ$u#<:;wm8u):6vҨ)L S?؍ "ww:.@o}I 0?kZ4In_&e@{pQlh(AWQ^mD)ڄ^Ԑ>E* 69`0 OsJҤEATL!CI%<0bɲiTiӔ2 >  &CCsvD? i[̶y'WGȗ!쌐ϾCQyELuvȷdklP1# ~}EQ{f@DL|Ĝh, >%OoG;%6Vŋ۶m+((` }(} fKEQϕM.JPIQ\(:xr|| UF,Qd+ghE&iӦmڴwL`"'i6©&AL3ӵ$|IYwҿڒa?=!r{=⢣D#l^#S'p+Fҵ,)/;$a)6]gʃkAm۷o5~/vvvf c4l«>DnGg;ϫlڔ^j:Ǧp'6MC3zv˃-j\}(\:{JNfVQtPZUGׯ_JJ ӆ`0W*S-ԓMCQg>$yHv6X*m5<^1;@4\L24ܷ,"Fs ""B̙ }]Mu8jx Nպf͚'O~ 4` S1TzT&}QH,p^@RUx,q&Z={6NHHH$L`^EQ.]:tZ~w"## N{H$b橱s67n5jTӦM.\;vu֭Z?{aÆU_ .4i… L̎ÇWZ5iҤ;2m y=SLٷoߖ-[q1oMMŲrԟ~L`^ǏgΜvZDp/kFR9sLTI1G/^x…aر nnnL,^#6:ޒWΚ5o߾`6~zKZaqZ7no? 6l^wo4EGלc/V+lݺڵk`1^j/Νk׮͛7^.z'ԫWbX,GI02z{ RRRN٦M-[oH1)#YfWdTFtAlՊG0Lfly bB-`$3VVohAij^UԞzyؠٚƒ7gl6(ܹT=eb-r,FNJv$i0JJJo\)_bXTqe[`1IFa`Q 8sj ݳ;$I)*7Zo1A%z`YtiAN4Z fX<zTM&1mUګEg F36_гAu1bSdl6:c0LAQj֒^1j2&ݳX,C ߇@Umy؀aT YEnga̭tdУZ/|NiG>ӶU*x0Φ zҋ`<凮^N&_:Dž^4*oV#눅@*(}ǭcu`a? O?sUo0k/[s/]z-?w_˽6:(G1Fmq,^=M?̶Fx^ɣuw,i?4><-+rV>Ҹ3%9ue ؽ\wy/(:?͖f'[ox$_[;7y4kYFt0(~(6ļ~b6?@,֨&Nsl=3gոa!̟c`=^eayJHwABct??nS9=8_]fkT]y*^ص=e)mְg|KWN7^T±\(Ꝇ! Bß_Zp^AD61LER ^ېhW|jgW#s 0vQ' 8w t2b?2\q2G|rеQ[[!MBRɇsٙ}Ŗ9fcN<(l@ [Zv`?FD Eb O/|h\(2I m=џ]mGž7x8lMnB둿_Ԝ;)lGZpk$ 8|ܟwd-\ҹk= ]@ޓ]n5%0Ų{̀ l P:0}^>A~!AA=6Ց={ˤ&I #OMFo8{ SkРEosNbs8|>ՙYyymWGՁ_ozq`_޲O -=]g}\==;S[YISodu81L'gH=ʰ&dwa+Z.C*rikl #?~sdB)YB6C{EX =kG~`0UCzzpܺwUl߸>\6ȟis .w@ ]0!A9iyщw\‘{Mv&.4/8#m@)"|[*{sh.n7h6컟wkrG*fDl*6O jٞp9Y[Zv {o@۟&k**nXnem$$77vG&Jl On=S'EQ(V-**R(ݺu'>>nݺ..."H 0t/CթS /Lob.VBwy ^mgw![{AԃqG@SyӫJLw W =[&۟>`?N:2L"BG jjZP<|pȐ!L<{bUyqW:I\Hd'6flun;zh777'''X~#<1(vߊ^1Ix-.....FB DbX,fpAxxxXX/=H%R!/.ŇP_RLnJO%ҥYDn <+$ӡ7U !e/<_S 겣GvGZ)Z<s\>}lߢP(D"$ ޳N믿Bw\nAAkxʹw\b*@,6WA71:@"үt2U6]˗f3b}6oAO?_&ڲfx<+l.px<:c JorDrW^ W`Mmbi4Rm:Nӡ H 1yF֭[9ܹsG,ׯ_~Uzl>Ysd ǀb6 ⢣qtYAЮAg9˄mUA>>>Tܿzװa=z4lP(E 0D5O='\=qi  ǩ IDAT___6MO@W_,;..:`___䐉Ʊz6$&&>y򤰰PVkZ^+TAfYѸVF樔W+ dnnn_ѣGiiiiii/_͚5k֬Y>}4iRTПyhB(,,h4:e*94"wwuҎeSz<>y򤨨hmZ\\,$rDή=2^г9bdZl6G{YWxڵk߿XfX<њ;r+:uӧz}Vڴi3vX77S@J\ƅBH$2@$khA  s#BQBX,F-c.[V^W* ѣGȍsNݣF}vppo!EiU@ lg FZ$L&l6ӣԕgPrr{>#:A ;KRTJ]>xS\]];u1LMLE%jE?Ʉ"TI%%%K,Ϫab\.]9E1`mbTnFD"1ͨ0Sq]zb:e;tԩReN=zx{'jxLCJSy=#GAgΜ߿e\Sݦ@  XpE~ Bm۶#Gt᫯ .Վ KEk@U v/]D͛7X5A.DAwn`ZAQQE-G冊c(۸q7n\w ͚5;~Z>q͛7ccc[lY QQi4K4-eXPJTmXJСCAPn6===+*@)t<aU*k׮=}￿i&ggg{LJm_b%gO@Sf`~C('B[1@+u vR*&NPZ?ՂtWFlP+%6(+VnC:u*66vܹsf^RSSKJJfZ~Q=T8t(:2,wa4(E f($3_x1EQ^]2hAgo$I޽mV&b|Ee2Aj H H7F8vwIQԮG:ׯ`0ݻ&tرj.< jn ѷ*:|a]tqqiٲ TyseڵKJJƎ;tЊIwQсeQ9u1:k7TU?dXHؾ}i*BD3vB߿?s̺uZǾ'u+KJJ[BQTd2͟7l߾=%IAgzi6͝~ֈݢrX'-@ I5)*?|={O>UsinfH^6a. j`L3g>ۣs6a„۷׷yB@bC4LWwiu)>>>Ŷ'O<nk=?67bcƌ"uGJc2ݻ7?髰!vr(N#yQ>hvgg2z;ﻸ|UvuxV{~x>~X 8;;lڴiٲe-4&5ȯ*c֭C )s2>>>11{ovر3fT73k_^OOO_uheUں1;D")ӗ8 U1eغukIIɧ~ʔ,W^VtZvʕ'Nlժ]ʹ˗/^lŤoQt,mڴݻ +++!!aRi^gϮZ./lL&hwf޽^00^MhZWWͶ;|w}wƍȑ#g̘xJD`G͛7od2tԩk׮ rN>wM6U)&Icyk%g 3s\Ŵ]Z]3!?ydɒ% bڜW1}/b111LbOz1rʘ1c*ZHl۫o" HD*գV{O4ix<޼y󒓓O8-Qz6F3gΜ[V [ЈbAí~bA1T4M~$e˖1mNyquu?Ifmi{6oެY=FGR5 gXW5۳X,[n3fLΝWXQ8uԯ://i[7ѣG9rdU^UETf]1: T'4M ۝>ҥKk׮߿5 9rɓU*Ӷ,6o={"##gJגoCX֒Gv }ɴf͚ɓ'8pѢEL[T!"#####NZMyX,\bE_B n.kYCֆ=uD<0k(]#@R$qL:塗g39T״gϸ;J]P۷O_ fh4-jܸ * TGtܳ)//^ {@},ɾz_dQҳ aNyFNC[:Ex/ gĄGOƄwLMMtŋϙ3gر r2a>pB XlKVV x#c+}y6k(i;yt?{c *W_g63FVʔ{-H9R%pҮsIҎ0q m_4~yےjm@bz0 ,MTݑ+9>sr<8x&FlQ(˿ݏ.6Ν矝7n܈gdzrwʄP(ljjV! F u ( %{XY ȓ'q"|; (/퀱(}xYEHꊺ7o:J=ŋ]vܹBt]LF&8N7 P -dr'1ތ`ت0b&&f?a l]s! h45gK@T&sp\SQlݒ܊7nܨAR?h/!""Yن,""H$[N~=˗/GFFݻHٶȊjf#+J?o4B!kP6d-BjZSу9{6$99ĉ˖-9sQ>|ImmڵkeyMB;ӊ@MM*6Z0e1<}(јנA%HJldB]]]$ Be3TWݼySV|x(Wlnݺdɒ6,3z8_5F;t萲 y?=Y100x򥱱 QaThðFkhho߾vڑ#GvAAASE5SSG)EFS]ihhtV ,YRY ;wٳʶ=T3Y133+..?~|wv]Fa?YUU)GKK+<<|ՆÆ S9oG5KKKlQ@ DGUoG)xb ?sٲeJi:A~ɓ'ʶenB;0!;tcd'ן8vVS2BQ@ Į ﹼ|Ν|>?22ԴzXꫯ6l?7`ժU^^^#F$@ xUUUOoVUUөb?{R朗S541 <5@X[][k4(Vsj) Fd`]]]:NR)J/t!ׯ_.=zaOOٳgBBBBvvvdddO NtѣGgggw>!D"B Uollljb1a P Q_u{I #GTWW.aiF:EQ:NצhdD Ti2Ǐ#""tzLLxP)xyy={l۶m[lQ-PM=z;_C#$JD"HaT*K$07mnn{a"3LRWWP(D"S۳DN6m"lܸ믿>|EmĦXZZVWW|N2Nh)HJ#bD"cI߼ys…ʶ@ ;4 Bhhhd 3M\n߾}l~~~DDR@ |w˗/4hPwĴJl: #GvqqkhaDhbX,777{6JٳzKKKe֡(J"D"J%4 !,='4Nj|qز7}}}e2mڴn|h_C .{e<33OD{;4(J7lDJidDh׮]۽{ѣ^mP0,k7o޷o_O | >,FsΒI>!Z֤q1 ;u{kwwWT#C\.w޽ ?V͛wݽ{(tAO??%(2=59+_]]ݥK\]]mHOب6ldD.3~:u{#H/dƍgϞ:ur-QMqvv]bEL C$iݻw/~+ѤTtDp8vz;z6^JnݺuժUJD%6`XXX\|;| =y7993g($]^]]^SRR͛`]ڵ(eU ӧO?s挲7nС0tqƍ3ڵkʶKEړ'OVZ?۷?W)MqȐ!W Mgpttܷo_YYT-JѣPZZz%Kb[}t"|D"_=tR777Ӭ^zҥ7n5jR PMg  Rv}P!7::yΝ;rCEh4ƍm: BĜzc E{H{TOt ŸyӦM . S)MOfذaNNN?RzWM ڭLTęwf5*/rD9/h y#^^^ &MTt//삂Z%6-w˼ 7?Q_ gtVPhs9\ߪ pG6 0Al;3A|AK|e8 ;wܱcPPPdQuTݻ@%6-࿸@/ uB7! BAۘ PH 195SfTm=L:zaX "utsten{v,*mU'_TkaGI|){{z:d܋spêݸK?+ifse///0z4LEי0a'_ش@\~XMIVDZbc^vV&*ӦTyR W)U[ Ͽf{HF-xZ|^lÁ@ m![ s ꟬m(z\?2񊁥|UĻѪ-[YJvm*_RRRCCrF%62Dyv:3ub-ѳt[uul6 m4 X)*M`;TxՕ0YWDuu-^U?kg}V]]aD"]]]9U{nmjsy6C kDT:"q=u 5]_}fM% ^~T.?&Mtܹ'ODDDPu)(r~gu3NuEwQב.dSt{w>~C9GO{>wzD'@BCCLNLLLKK[|y ThiiM0!--ãS|۷WbbӪK'x)bH$BPٶ.-46*i’8]]]eB̙3gݺu .손*zzzMN)| ۱; ݛko7H!vV3L%}Y챟0e 3'quuwbh;pSX,VHHQp `nn~E6T{6r?MLLҠt6#%ɓ'OBf ZF=+J/q|կo?"Jl$;;{#F1b_lTtgΜg ȓ_p˖-ri X,B۷/.{c^,)(H$ʳҒ}]ٳo޸qR444̟?رc>:g#OfϞ]X{b IDATXx] "x<\TWԥ||7HFFN||t* Tb#OH$_|O?ɥ5|Lg6<I.B/\"H,&%%}d#NөeҤIW\Qt/*3'O.]Kk"H xFLKX,D"D"'7ʶHɤ}4hP˷T3ކcA&V\k׮cvqc@&B!'T_l 뷲Q&Ν;%޽{f̦abb"^|٧O;;|8q⻔:SGСC=QB=x`#xc&Hpp8%r1 ~qW9)**=pg}֎jf >tuu_TlaXtŋ?3Ŧ<쬚ي ccq}j:]V5hrv\>4_VMek :LreTgd?R7Ib1gފ$Ovy]ճ܈++x%D5Gb( mmytc=§tٮ׈987?Kׄi pt`0`ЅA̦ ǛAY9Y'_P_dfhn~*hdNظ{[Zj2Gcc#BQzm):Jlȼy޽{vp^F7U#%1c(c~3}|Ӝb04~Ls}t6KKL'(J@|?,$hmJ~R@,۽IW yIQ_]@֕E!AI{!W\B$11A U~ϽEjMH˗۷O.6BϽs~;ݿBwXrPޙӡG_Lvkp2f=2Tܺrs۞[A~c{ZmmmTTԣGmll:zj w a5TbX&O|w=-["7IxifKqCknj,ivK2|FNG nd ywy> 8R""i:]gӣUޮ @:lhh֕M4 (+gϞݿ;Y5H$i+~oƍď_QU@eLa0JM;ZƘ)}?/wհR" nq,{fý蚷 &ȓI:DuEÛ7gL!{ϟ?ߵkݹsEQlz'Du*Q8,ĉt# Q=_hkdiQY -H.]\kd/A؄"3Є&θ١̆VÀ궃ZVV'ցjp+ gΘ){8q"11q…DgðMeǥ~k <{lʕzf<>/h:T*04:/ JO%(ɭ'xӦM}РRUiiiDDDZn\)őH$OOϮ7$$$$>>^q]8o4===IiO?=x`[P7Bo!  JPh4m+ X|AHyS-N^xahh.,62NX4"QK,xTc(oPSSs#M==m߿|򢢢3 ;|oh.d)9PQJrALSSs…]9rU:dɒ[} @5|bÿ bQx[oU_x7AlrjjB=U_d e2Ozs)--˓{+n޼l+[7]Ұ~x < Y#w&/^022Rh ǎɪМhM ?fO[RSe'M XKmQ%-UNA?ӿq^yUs7<[2GxTϴ߈@;zJuGV__?޹sgݺu#FP\Gr$߰ar„  883~xP* [\\ ʕ+---QSSCDqݻw/^q.67 /3= X>S2 m[GeoƎ0̙]r{+e."nw`gҤI;vlGe2MŇÅ lvBB"cN"/i~ Lt,&_A~&Yչ]~A& 0UՃH6S$Лz.ۯ_?%LΥ5h5n>Ͽ d@ߨ@c4t #f\s|&hUd]Kbg'dxY)#ȗ˗Č3F/ DFpTȅ={<{l֭֊ĮoOBX,6bo54JZXh/QX 0D"@PI gc(qrB kMY|SzJ̹xXc-3 +ԪP4J(lʘ89 F溡,MwO n٦_888KҹH$xHy+,% ._ctҀNtJ3̊Ⲳsi]oR]Qw1FSS͛nn:YéAuto{`(mSOySɧ迣rO`֭III?Bb>rkjjܹom' lH u+hj7uX(-oU ^"57.06Rg3 ZZZ͡Nݻww1/477D">/n޼p,vF^EInť #I]]FdEQ3… lz\B++;fF``ȑ#g͚ND"pr'??(  |BPT jkkk;]B&_xQTTdaaAR%ikkSTLQx4MSSo߾VVVt:FQT䧅Dz;k O{ ??:gb7gFvvc"""؎D" <͛ɩ^EInŅĿd2H$Wlx<ެYRSS:999l6;33SA=__߯zƌVSS#D"L&3LMMM.H"TjNe/yÇ|,U])HNNH$FFFFFFw[F@ (jdd?:xxZBֽKlPQJr2F^':[;D"DU{ ͍d2D"?v<uСC4Ŧd2zٳgS@ (KD"AH$RT,x"?????/!...]iV3nܸ/VTTTTT\xʊLRAH$Bht:_7P(D"QA[-9wq!Y^10-gd&\`'lb\ê R̦+"OZaiI|qa2_x.f{,LOTD/uuusQDmPܴiۻvn@"d2FŸҨ XܕGn:y/ڔϘ1ܼsmvٳg߹s ŏ?FQbyxxkWh\4uu~ֈbUƖm E ;kt.U@Hs+s+E j̭\<5NXY7/NP(DH_FA5>5TNVTb4,,,,,,g|aC"' 5:αеeAހwa"hCLN˜)qb2a@" ĉ QYT3ã$-TA+" ]%r P{jt:K,UG4ݺ i@!T?+vc]Us/d=N=nNõJ?}EcD DVYw)I".SM+eWj Qd= &^`Obm,:| 5+b3YQiuά!)/#Վ]qZQسgϔ)S޺k-ݶ ~y<իϟohhaXxxv?xɓ׮]{ { <(OkIO1n!;ϿFDաX&\_HG,mkql}g:N%eVg^$( $5]+.XkbC0! m$^iiO2B: 8kЦxn9 ~!zqU~"'7r~k'kE k3CJlCWksI]sWquuMMM}ɍt-D",߿"2>)Ϸ>-"rv WaXVV_5a„(,PzK"Tah,WIF9$d+/'Ze\ٟ̄4Y&@"(.H:AAw0 JЭ R qꗧ_w΋:% ViN%W?5d'L3\ќu2C/ DLԦǥL8ÇSy}YG\?Ǣ=n/t8'N ۔'Ot.;(csz˖-_~i6:G lu-Lv+a{dԧL əyu1m#S9ê1{4]s w?z I/Uoyn""'uj[|No0Xy4qP;| iO(j- 5J_y~(E(^!EGMĦG`01m4ٮt? 'XvG^Ҵkz"}Zࢁm-ꔓ[iw|lW;Y՚ǝ7|ap/zGBw 3!u&@:G:POR:;,o:}R8+I1(Ck*rHߏ@ _999)\єj#gXX'|ҝz gNKK64'֬vw_^0v򏂤$_(h:3SB؏f¦6tX-qnAE4CXcC;piZHzf;d=ȿ9P_WGxU`aX p^u//Hi@a3h*:+o4ySRRr֭1c;Jlz #F(//3Rۡ+HJJʡM+D\y x%͍˩ǫohu}  d1 {bBٽ :}Tx= 1Haa܋~+0"Ԫe V;~Si89 ň|.92d=%@CCΝ;#""jI @a3y}tM&;*/AOAO>ҥKE`ՙƆTͨg[oH\&~ 0[2e_퓭ϴnmL~瞚Ke[({A>_rR0/L4KRPuPIgu!ߓ[\;LS ߕO\x1::z\$6UUUW-TW#yЬtRrr۔ >,coo9 0 b0_RPu|ۜi.[W/mrqpH_܁ IDATNB9 <{ku譲ڠ:JX]]YVV& ЇmUƁJl: 6AkۤIt%D;P- FciCySϞ={OKUG JomJEO&pu7se˖ 0 ..VP9Oqf>}ttt455i4ڪ#bx…aaaȜxzebX,D۷o9Wh;<-b'`Fϵ# E"QҶ-l3?

}ӧ ]IEmmS,--NN @ t:]KKK__PWWWKKKCCC]]H$vBlϋ/fuhX, <iBuE3WK$ @hnnƅ\ =%GU9乓\w]4tHV0-gd&\`'lb\ê R̦+"OZaiIRI$Lh"D"dzv`VQQǏ|/$...vp߿AAAAAG)MP( ECCCSSJein07n׉ 4@ P9*ƛ.;;͐.KgĦԾ˹paʔ)%y2#zv_VӭVe#@̭̭2RTsi-:̫E@;'j Cs5r6<[2GxTϴz; s:F H$oHԹ3gdeexm;;;[ZZv =***211?~ Ft:NP M6l.\occ# ;Mi6e\lեeR?C$Dt3L(|#2U D"GQEQ|.QFhx0%}Q~&{C QD2HWS=ءo@^g:@{de."nwlOB&oB| s3GG6}ܹ`0 q,//_O>=eʔSv(J&qРR$ _nCFb\]bW_:&j*bd2e4|DRv[,)E4<[ȸ_L@-.[#3yvwlglyp4{3A|SbRYRd ^qx(B4O!LZbll|ׯCtdҥ֭kYrV] ( FP(T*".\h#GU7( o{~WʿX%6F"taf"81*i&\_Huuz>4sjWQ\sEuJ>%^`REKCR; y?Cyyy߾})b Kuuuy oȞX]˗Qa]w >&JUtꊺWgN1fAZj|<}̙3.ߖuSTuV/QlY+BI'>X, MHH0`aæNo>_7o^xxxIIː!CvI ~'y Qkvbr1FyXXXp}>i8t*W5 4hk+qʕM@7n 9?:u dsɚkݞ'!eQVnDc"3"1CI3uL0|@y9);n4u*jzѤ駹}h$׿u(9G9@uʨ>~o>bP}=8B\*< v{Y<;vQc;VΘ1xwrakkÇ˫A|d]Ί[8O>v횯Ν;Mq]paĈ2lذ!55ȑ#$NK$%y4>T`:4W^0lر]G.F~יLǢV)%ܚZ ?ojtJ7lsI+⧳@9KI& +{}^wp#=O.wPN}w8TUmiT_j"(3Be=/e)o80 o;DcO7ϒi,(n,WNDumX8\x}0{OJլO~iܞ˪_B^ET$z+1MCW|n˿v哋%k[%cSq㧆:!6zv۷o+u!Ӌ/DG;wn˷y ^^^K,oR֭H$Hz]St%KtyѫS ZO{[Ih6F|! mL>V M_30X}Mltl&g[ &CFckB rdX9-c=Q)B rrA; x;)gjաueɁI۞Q6 &H$1$$ݻ͓nN\vm\\}||Ba}r_ qf#[xpg~võHybaH"L`3cYcMsցzcZ`dΎjݲظCG'Qb;>AG+t݇nmӺwVfyZf7%@^Z:]E`˃?f<57c?o0Эn=uی* $]~yd5NW/Qͭ3e1>kT<}7@;9ȳށ@,x=jG Vo"z\|ܲF+OW.O1mg(c#z`2EzYtҥKm+{n N.[pq+ ,l*t ]&@;.ѥ`#&٫N{F₤sQd pSߥڮ>g?͆ ֌ajv⢋a'L ]SXQnXE b[Ijf$㜖%r ~wMl]/>W\vT2tbA9Me3Qonz"K,_ǭ7HcMu7P^2d<ۻK`ҡL }BwBޝ}C|v!$WHdN~Dۑ+9>s&Y@ @ĥ!v@q[{<_ Uf 5i @g\CuL! PueX#\Pyt.=3ԗM2@Ǣ 1nQ)SL'kN'//i ew@ įD] &Ċѥΰ2`2L[7PCKƔkR<^G{p'iEBC [&N~ea%\L@O˞;m^+Z5KK.\z h1aCMt ]1i!TIz\q!O@nSO5ޠ.d@@PU ӆb1tKM s'ӚZ}k!' K&O^gK_T~UJ8m 19@z03g2,c  06ؘ2wJ3*mRU!)g:tcxP޽$6D< AK*;_j/Z8~yO[zlK~=d6$*# ,Z|QM[h-_~H!ժQmDz(wiqM0dh<~A$ @OiSmR0SP_ @&~4ʂf{CyTwqxH\0=я9fw T67v 4Q֕)@[Հ[x7^'n+Kk]@&_?[HhArvqQ,Y'/pvm}Ds|ޠQ+~g<i[fVQ6Kf)hc:e&nb\өwqM\k&3dA، W$b"RmU*X kkڪV{{+ۊVvm^ۢe)(("B {q`O̜] Ȯ4!ۡ&yD]p kݰ{o%ARoKH8ld튋|s@oy4AcuYW孎QbOmO.[^'|gO6twq^Wo^+Kx;|tU;+wwZ0AeYmRZ&.ό2J>c\ږQNC#?mzϐW~WAdWEAi;V_+m|V\;y'?}ik6DM4I1A%]}H(f#>ةyں띶QxRfU#iūƏ d4Z"::C6h:IxqfbFƭ 3`S%b( x7$c~1MjƤ94/ m-CFשuc@/4PX?3?ܔ.O"G5lcT/z'ܦDP|1Wl=Ο?… 'OMM bȵBگ(7O=Msb4QqL駟0 ;;{ʕ#Gl+6O?ʕ+=޽{{Nņ"z}IAs;F L67q6^sqqڴivLjuKMII?tҩS9sgvZUO>iii&),,,7nr~( $ITQswn4.<yБlDT mjK?mHG50AQ[|.9g6SLQ՛7onUIBpp#GF9bĈÇϙf6bX(c"*n4ay<0"MeҘL&cX.^Ç{{{䎇$IMex<eQCH$v9rd*jƍoG2tß{Ǯ|С(f%6PE40(:Fz=5*lavLilдd"t:^o2,do&>|X-22ҡ-Rh@պr˗oz^jZ A+aʹd~^xÇ? ŕ+W,ܾjxsVn_hVL `6ќMK\񬝑mfX07o׶o%oGl-3` 9(42)64,VfZAZhXDzUu,jFdpmo޼٥K{|A}_tC4w~7!&TtWdDF?Zh02226fbRgwM g#\X C;tl.Rv4b( gv}A, dz;v^x&;:YfW6IŴ@׋\t:4<*wYg: 3v'6Pk eal\#moTGVmT`X68N<,(99yΝ=9j+G߶V-+t:,6Bznt*dbhr-xJɍf}$I|{ݑ)))ٿw}f3 8ތC;&X,UUU(ih daf$#pnW(ih\3' ƂoqsdX1X,hWh 3CsG`KLVVel b0>h8Z!i2L=IBdS>z /F-؂Ng/D6y`"L+ENjD"OeeeYgsݝ6 Ac4D! &7ϲgrnW(ApH`04a a\j ;tZjGMpv=Q#6lBi5ʫ 4hȐ!K|^ ufp0?o]juc]b4eUz+@53s/+5@w:o`# C^}$.?l97mVr`xv)uV=+Jr2恂nkn:y3ߐ4o9B!g^UL{nBJV@(v ew]b/.=UTm0~R% :dz [݋9ē}ǎ'"Plp5'iR JrNn[3L⯿_+Xր)s'>}յ.)8F_~e]v4=YvocXб ~\V{?t@ݏ|NV: )ݱėw@u>wwūiʇ;/N}CU]-R̍*e%IC}wWF/~n`FvL4)>؅ҝ^s?&4:~X+ehM+ODŽ뗡?^JWeq޶hG%(_SFkk?e֍?Xmh-pGa!DNɓ_|w}쎴 FFiPCbP>zri5E?C:::@!A=C|!nOskgAXo`KLxn#!ϲHX|ϲNB}bN8:; (ع#0t,=S;M' av/I5]wyS~9}3-}*h{'ɬЦhÆMe C9bzVmk[ؽl,9//nel2www@ H$ EQC QSC+Xd%3Σf#@-l, ⒐w*Vs٩GC[ Y{Oh Ax+1Q_HxvB:._Ro%m[_'+Hڶ[Pp(E ٬]ɢ/**xI^$ȫ\ynǻ BEsgm_p݆,yqDX9qr0ZS%=W/Zs\VVvZ!>M7#]蝡2A-& |'>X$]j@~NirGm #6ߞ~p(C#{̺0nj2SK=x.]UݽF5hdy,r\zf }ġ.YEc_5W,'ִ8"qw!=TiBd>| 6n=ab4Alf:GNqѿ瓍`4(&zH Z^nCnCHH-,,DRչs爈?OFbT\Z:\Ybfy2oZm1c@dXE~́Kۦo: NKEo3}N" 㺒 1vv#2L9~}io_ԨCU~qo[3~lQ=NkΣg[&_2z`Z 'z?ӑ,@<"d]& >8p[ !A~P@S#Je!ߡYha8}uYFO `ěA= VZѵ };[BCn @6zE#p݁;NY1'_C9)/0HQp-o^$]ݦL@ X&& @ ?Ĵ.e󯰱+ԌzSiSrS 8պnݺ3gzyyt BIIIzzzzz:QJޥK,ۚj“d:_oOi7@Ж[\nrT&dpܸ]~ෙs/d)L{[ U#wS'q7q|@Wl'<{MR\L|#}VX6#)c= 8.0{GI(yՐԈ_~Gwqhڀ!xȯ_S5E2-)f'\IJ+sp2MZuvI%]*m QUlИΑ~9K$H;7n_|ny7 P[lpN.h3(+dXFm(6l.ZӖ=(i.Xy0-btAj ׯJׯ_?p~Ruk $Ԏ2\@#ͻGHH-4 Lbc0gKv*>xS>=3}ݒ-4۝'%Q9{%_h'X'Y#H.Idi|gU_zOFv@.-*GNj|?8PUCxSPVu3cɄMy|I]wo@C r3-CSy-g$c׹s xxCV=7!zFSǍ?M slLw߆]O2 \,,W?띓wEUZש^nݺ(NjUUUAAA?xӑ͹Sxbܹs.\0 @n[$B\|yǎq{͛7兆 ,2ehJBm"~ZEj-JDbNmYa/,fj_^41B^c1k*x2d#m.fsR%Ls<3:c֘:xxxD">rFVe-\L^ xVHkɬ̝ 0q0ch͌WX2U`ުm_z权_]:tpwwJls`g6lS뫪O(*UUB71Z ZܹsOdZ~xQnܸAӴNCGDM8"Ϛ!!L]()fl럶 DH5B3Z>bj# @nLGRi&Jb:ҷ7ĮѬ>fGi*++ ''gڵ' :444~A=,eeeOd:7ŗyo jv_?ֺ,{1t;hPzl*>F+F#*N $=zgΜyީS{>HZ RsAho4~F'eC 'F@HiLڵkgΜZ믿YfxJyB~fҎ:#5A։~xu1rpS.os|R7'e.oul ko@W|,^N6Up k=UU6n8a„O>9$ɪUƏ9^<͠hpIN,e 1J3K`.,5j2,=UkM߱UEkûn* 7uμM]]&`իgΜqƢEK.֭k$ќN hM$nn4|- A||%ؽ,# 0=:p v8qU7,s jsJSUU-]|̘?| ) ${=[.h6 k[oS}P6OC_vc[cy,iL sך$>O(S8O8Swj |> 3&h wFٷoӧ0LLLmj%NwW.Ur6;`(-ɉmJT9sEo A`.uyP/.%{+o )^>O,g ,{K#$F뿢L1~]X__[1G̏Ң|I\0g?/"*Joem$7|YJV4Νܹs@@ Jelll>}PZ)[ T*02v{'jv'4{ڷ#}F#(%U(r^QQBR:ؽNeMX_!O>$IAɚ h{MeeJw^IIɄ A@kn1= 0q0`:$zSfO;3'L'DhJH ZU4ed{]3߽~Co̘MCi)+K_zIW{J^R]e<7c<_7oH$\.Ǯ<":(:LE)jTh)w5J쟭 Zxk׮dN66LhDZJ,..(Ji4"3 ժT*Pp*++y<$I>d*|5BzN]s7n<+rsm6v/؟;I=J_{R*zN,,[\e\~2_ Rǔ[l͛bgԙL\nXx \&1N᠇Dx<^@@D"PE|`hpv{d24,D"dTԒ}x]vŬ~d20"H, \.k^y>n4$6W_HFX BH$ if>d4- ~rF,; =n1^?v~=:5&HQձ3iwIPHߠ9yn5R60R$Qnu ØL&ViD"މh"H$Ԑ܍Z"-G$I) *wD4 F( Pқ6XiKl; #֍ 9Y}gU *t 32{P%?h:8~X,<̓\UH0iVZ=- {gXcIY!KPz &qߦw|[qz~DC!=dXl0 mӺۆ 90Mz[iX! |6'ZEDRVL #4{,嶴k-&Ӕ-[ Dim6mv?Bs:ݙ 5/f}Ou앻[GzqTZb EAi;V_+=ZQ !J%łAK-cqI5zG5tu40Vi{jwe=g4M#MhZ=1%|x'/KyMdXvqv~&FT?~<<%!! 0Ro;=>nn=}?NINc+lK=#hd7RŦCaӰCzfZ0:YpZQ ci)ob2M0X 86! {pȂ#+n?p݈pHKKqQ[gro 0l=iLMk ]l Gz̷oߞע,*Vb+4+c旧,罥(|ζY̸VKEWaY or?gAsr:Gp5 0l, es 8@l***Ο?oX_϶܅؜ lm%|>Fkx]ƇoS: ϺP{b? \J:x tߘn\:gajez`#wa`?!O ߾-.%bwT_.sac'7^Tq;3V7=\?gV\+6ݚsc0GQOlz!c|X,A:Ɠ@itQ5.n*>d@w10;P}v['L3C1fL1:h*ےUãg6d^\5^ҹϩ+F_],(vzn}~G!U;~pg꠶<9:YA<ӀCg݋ 9rl6b lq6* T~Ħ{#zSAل싐u+fzЪlPV|zuςU7?;A[s!$ϛf{_rbodޟ2`hz;~AgZHoz:sLӜ\l6ooVK_vU67h/_}?5ϗH\xi%:Rg,17O>!:sHLXX YH8"}]7tA+\Oz{DjA ?7$I:8Ν;Ql۶->>egliڬt|o})x- N;KA$Oj|?8U #.H+qt77O'.CN8Anm/! ʈ(O=WB ճnߖ16b5hH%⯿*..fFۋ/잶8Dm!>/b1[>JQZ|eomrX+6u^>ڨm+f?4"!0cF߰yug~j]qݖu[ޞX}ƷGfE$6YYYO:GK?8xJz꫎; j\ARRRL&lfk 9-AlT.UI`(-.6RU݈pHKKtR{Jk4i:WsChfп+J@J ) rv0 i>?otWw>}ɴM4I]Q]۵6W&1VMekh4,@~31Xi0K~aaaAl(nM61e/D5 RXhؠ2Mli0~Tl ݜ컺]qqqroP(-&S7y;24A/4y Bu!芏 bצX!|^]`! 8ʼn<`i SEA*xÆq{3K4}aovV[W?|^jnU ŚQԙ-Hҁûn*Z˟M!h37Nfj1 1`imԡ}?}F_/6{(1@+_'ӧ;jK;@eA,[ /WȂL~',\N\Ս!$\BB 04}?znHb̆oJJSD@5K%{iW)99y뢹"NQZqz{Μ噜0 Q`iZN2GrѹoA͕jٜ܈n@_^EDDLXx-eJA<+HVD3:|ٜn.D`O }>rHxxxZZڈ#ݗ&0iTjd(L>!Fq:BKyJkfB|O yvM.%JiO|b' ~xx9a73:&AK:l6.)t zw$(-҆dNCZ3\IuE:?9KE$@{{`0ml:>7ĝi3P H&"p1~7C OwĻ-I+Kб~{>F9'ݍ7uTߪ%Q9{% `0EfNWYYRݻWRR2aֳ1(n.RCjӫ4&XоqL #ɐM6j/y<<.tar.bz2 # cd log4cxx- # ./configure # make all # make install Installing libxml2: ------------------- The Pion Platform requires the libxml2 development library for manipulating configuration files, and other things. This library is not used by the Pion Network Library, so you may skip this step if you are only building the Network Library. The easiest way to install libxml2 on FreeBSD is to use the included ports package: # pkg_add -r libxml2 Installing OSSP uuid: --------------------- The Pion Platform requires the OSSP uuid library to generate universally unique identifiers for most platforms, including FreeBSD. This library is not used by the Pion Network Library, so you may skip this step if you are only building the Network Library. You can download the source code tarball for the uuid library from the "Third Party Libraries" page on our website. After downloading it, just run: # tar xvfz uuid-.tar.gz # cd uuid- # ./configure # make all # make install Installing YAJL: ---------------- YAJL ("Yet Another JSON Library") is required to build support for the JSONCodec plugin. You may skip this step if you do not want to build support for JSON. To build YAJL, you must first have CMake installed on your system. You can download the source tarball for CMake from the "Third Party Libraries" page on our website, or from the following site: http://cmake.org You can download the source code tarball for YAJL from the "Third Party Libraries" page on our website. After downloading it, just run: # tar xvfz yajl-.tgz # cd yajl- # ./configure # make To install YAJL, we recommend that you just move the build files in the "build/yajl-" subdirectory into /usr/local: # sudo mv build/yajl-/lib/* /usr/local/lib # sudo mv build/yajl-/include/yajl /usr/local/include Building and installing Pion: ----------------------------- Now you should be able to build and install Pion: # tar xvfz pion--.tar.gz # cd pion-- # ./configure [--with-openssl] [--with-log4cxx=/usr/local] [--with-yajl] [--disable-tests] # make all # make install To build and run Pion's unit tests, run "make check" Known Problems -------------- The Boost.Test library v1.35.0 does not seem to build properly for FreeBSD. We recommend that you just disable unit tests using the "--disable-tests" configure script option. pion-5.0.7+dfsg.orig/doc/README.solaris0000644000372000001440000001536212420270445017047 0ustar robertousersSolaris Build Instructions ========================== Preparing the Build Environment: -------------------------------- Pion currently only supports the GCC (g++) compiler when building under Solaris. We plan to add support for the Sun Studio C++ compiler in the near future, after support for it is added to the ASIO library. The easiest way to setup a build environment in Solaris is to download and install the following packages from http://www.sunfreeware.com/: cmake, gcc, zlib, bzip2 and openssl. Make sure that the "make" and "ar" utilities are in your PATH. Normally, these are installed in the /usr/ccs/bin directory, which for some reason is not included in the default PATH. Also, make sure that /usr/local/bin is included in your PATH. Building Boost with ASIO: ------------------------- Please see the README.boost file for instructions. Boost 1.35.0 on Solaris seems to incorrectly detect the presense of the ICU library (for Unicode support), and enables support for it even though the development libraries are not actually installed and available, and contrary to Boost's documentation (which claims incorrectly that it is always disabled by default). Therefore, you will need to explicity disable ICU support when configuring Boost. If you are using the configure script, add the parameter "--without-icu". If you are using bjam, add the parameter "-sHAVE_ICU=0". Boost's build system is currently (as of 1.35.0) unable to detect the linker you are using, and therefore may pass incorrect arguments causing libraries to not be built correctly. This is especially a problem under Solaris if you are using the GCC distribution from SunFreeware.com because it uses the linker bundled with Solaris while Boost assumes the GCC toolset always uses the GCC linker. Luckily, the build system lets you tell it explicitly what linker you are using by modifying your "user-config.jam" file. If you are building Boost using the "configure" script, first run the "configure" command and then modify the "user-config.jam" file that it generates in Boost's root directory (change the existing "using gcc" line). If you are using Boost::Build (bjam), you need to instead modify the "user-config.jam" file in the "tools/build/v2" subdirectory (add the following line within the "GCC configuration" section): using gcc : : g++ : sun ; Installing zlib, bzlib & openssl: --------------------------------- Pion requires zlib, bzlib and openssl for compression and SSL/TLS encryption support, respectively. On Solaris, we recommend that you download and install the packages available on SunFreeware.com. However, you may instead choose to download and install the latest versions from the "Third Party Libraries" page on our website, or from the following sites: http://www.zlib.net http://www.bzip.org http://www.openssl.org Logging frameworks: ------------------- Note that the use of a logging framework is entirely optional, so you may skip this step if you like. We recommend that you use log4cxx for logging. Log4cxx requires that you have the Apache Portable Runtime (APR) installed, which is not normally included with Solaris. You can download the latest source code tarballs from the "Third Party Libraries" page on our website, or from the following site: http://apr.apache.org You will need to install both the "apr" and the "apr-util" packages. For each, just download the source and run: # bzip2 -dc apr-.tar.bz2 | tar xvf - # cd apr- # ./configure --prefix=/usr/local --enable-threads --with-apr=/usr/local # make all # make install Next, please visit the "Third Party Libraries" page on our website to obtain the source code tarball for log4cxx. Then, just run: # bzip2 -dc log4cxx-.tar.bz2 | tar xvf - # cd log4cxx- # ./configure # make all # make install Installing libxml2: ------------------- The Pion Platform requires the libxml2 development library for manipulating configuration files, and other things. This library is not used by the Pion Network Library, so you may skip this step if you are only building the Network Library. The libxml2 library is normally pre-installed with the Solaris development tools. If you do not have it already, you should be able to grab the latest source code tarball from the "Third Party Libraries" page on our website, or from the following site: http://www.xmlsoft.org Installing OSSP uuid: --------------------- The Pion Platform requires the OSSP uuid library to generate universally unique identifiers for most platforms, including Solaris. This library is not used by the Pion Network Library, so you may skip this step if you are only building the Network Library. You can download the source code tarball for the uuid library from the "Third Party Libraries" page on our website. After downloading it, just run: # gzip -dc uuid-.tar.gz | tar xvf - # cd uuid- # ./configure # make all # make install Installing YAJL: ---------------- YAJL ("Yet Another JSON Library") is required to build support for the JSONCodec plugin. You may skip this step if you do not want to build support for JSON. You can download the source code tarball for YAJL from the "Third Party Libraries" page on our website. After downloading it, just run: # tar xvfz yajl-.tgz # cd yajl- # cmake . # make To install YAJL, we recommend that you just move the build files in the "build/yajl-" subdirectory into /usr/local: # sudo mv build/yajl-/lib/* /usr/local/lib # sudo mv build/yajl-/include/yajl /usr/local/include Building and installing Pion: ----------------------------- Now you should be able to build and install Pion: # gzip -dc pion--.tar.gz | tar xvf - # cd pion-- # ./configure [--with-openssl=/usr/local/ssl] [--with-log4cxx] [--with-yajl] # make all # make install To build and run Pion's unit tests, run "make check" Known problems: --------------- If you're using the gcc compiler distributed at http://www.sunfreeware.com, you may encountered errors about not being able to find the libstdc++ shared library (and others). If this happens, try setting the LD_LIBRARY_PATH variable to include /usr/local/lib/. You should also include the Boost libraries and the logging library (if used) in this path: export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/ssl/lib Solaris includes some libraries, such as bzlib (bzip2) in shared object format located in the /usr/lib directory. Static versions of these are not provided. If you encounter problems while linking static versions of Pion's libraries, it may be because none of the required libraries are available in static format. Try using the "--disable-static" configure script flag to only build Pion's shared object libraries (the static libraries are not required). pion-5.0.7+dfsg.orig/doc/pion-net.pdf0000644000372000001440000013774012420270445016745 0ustar robertousers%PDF-1.3 % 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xI\ ѬU( # d,,SNK%;Nq|$` Tw֦~[~uá~Sp{WÍeT m3ַ]_ߙkEj1kٱ hkl˄+ibfN%42i6Φ[߄a08r-׊74]}򍵝릡 W>>^,Ɔ4l +&.fiFiMәaM3kf^aXmn1MH61Q9fμjI>CUgR &Nǝ4/lƛӸ+5]W~9n8ϰ:gk_N6 n_O7^IMRUz_~9<8 vBUikr:>4CXȌkuW-s7Ȝm-EVXDVEva9kPkv^bwQO]) {(2 "x}וuDJFYH,orvߚ1:{MrsχO^~TG. ?]@r &&g~?kCG_3]$~Q(\mU;R͡G''m&?6ye>>W9Beo'\Di%Jˮ Q\e*HUK\<OwaNF]n8 : evm5" Q[k?~|xۼǐ=gK9Nz K)--pdWL$ uwjЧTLH~G$ŊE41 @\z[fV9gqdIʠM]zZˑFˮZsӲkeqo,{;y.R IA{b 63peDEZbf f H(\g%D <}1hF E-ߒ>Za6geK.=iCms)*ċv, eGn𓖄AԆ뙜H}wx]Ur4XH3y'/;@'>EG<>HWA 4|N%IN1M\7R7v&@99PlEd%0% T5"Le *qXi(b)~1SoS4/ɓb9q>|;]kO_aoE:@xn~:) ;+WI yZ2όސ]ګ9 6b@nrd  0P@/s .t  S"^^6 D[ U]~^\8t/.biыs8wWC[$pWܳǟ?R7ض ѳ )Ӏ=)A&h~f[8׳nbx4Z`HrIޜv56ʰ+ըK70ZN!)Ne:HHӗpg &x6'd8}AEȒpXϫyqt*..RNaT??"6Ӽ^ ʪ@%[j:3e=Vcs$\W#aOR$J#P0mh"]r_xH\o˓UPA9DtEqbWEj C{u%/ &,_{lƨXN92[.x?9SMhH n̙ Uk-+) kj@:L}CGL]l86\l~C'r] pJ L(Ӽπ yQ#Ƕq~GfK]ĘBzh:6p'\yo[N\x'NWzfnuN[JIHV l484((ko}c>A.^sYWXZE ,}f 8%bG;QW_VA3e}>⪤Jt=ѽL5, 津xҔZG$azDF_/<0o:;4ODYQvn;{_"@q{h1ObC;AnR;zw+ /.Cj!9Yp 'DpKLB;k p1'#Y\(dL:n9p=\>Liw lbSmnUim a࠯)`\; y\[/j6Bz,+EB b0=ҟ4sihcA?t5с'A*JdPI(V֦$'*>ZmS&)/"]FMw&+pg9/<2La)6嶘a"ի&(rی-5os=}p@o[yC(9NGoa@ꁞDme-`}m!~5N,Df/xt8&NF۲+Gf O"xea6Q`}G 鿣DJwǬ0rkwSon4x6F1vLcT0YGT˅tQ T 9灧̓JmKĥ!燻*T93LL=(bZr~]0TCn>hlo&>v5zDVpAQd)!I߽o]pF2 OB+oVI>9sSv/5@U'n1uX-^A%;L@I /]0OK3kZӮ1Cߨ~YO3A,h=З- {>u9m86)Q}h"cm.Լ$jZv9D)+ƈnkZoGђ i+6Jz.OC,$t}&:g# tĪ6ڙ}uĂ  J= FHPhW/"WhUֱHɸ ]_X# XGNlK+# ^k]HmZj9 F{Ȧt; .,N'2DDM7B-oYg_rqʑn $K \qr4w&J bl,cJB`FE<*rE6\-1L3q% oKϏn>3$~EȼE8'[7. ҕy^p@F}.荜"j |Q{̠;V .i3 a|=zsY5NqVӑj-=e_ImGb))+-r2+G~F)s&^LJD#@KiuZhi5&!.9T}[B} (, Z>-^RT2F9Se*@Z^qOwcLг Km<@c|DF@Yb28r,5 Z9{vm$:Z"omk'QH~.q֙zc$^[]w`5αjū%=<"i(P`_@Kǫj7bq:$D@pVz+yȢ^./$f5v: ~*198pݔmw$1W=8{ՎZP\j}~?" endstream endobj 5 0 obj 4222 endobj 2 0 obj << /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 730 542] >> endobj 6 0 obj << /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ColorSpace << /Cs1 7 0 R /Cs2 40 0 R >> /Font << /F1.0 41 0 R /F2.0 42 0 R >> /XObject << /Im4 14 0 R /Im7 20 0 R /Im10 26 0 R /Im14 34 0 R /Im16 38 0 R /Im12 30 0 R /Im1 8 0 R /Im8 22 0 R /Im5 16 0 R /Im9 24 0 R /Im2 10 0 R /Im3 12 0 R /Im11 28 0 R /Im13 32 0 R /Im15 36 0 R /Im6 18 0 R >> >> endobj 14 0 obj << /Length 15 0 R /Type /XObject /Subtype /Image /Width 140 /Height 57 /ColorSpace 40 0 R /SMask 43 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 030] endstream endobj 15 0 obj 127 endobj 20 0 obj << /Length 21 0 R /Type /XObject /Subtype /Image /Width 139 /Height 57 /ColorSpace 40 0 R /SMask 45 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xЁàSPa 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`30\ endstream endobj 21 0 obj 127 endobj 26 0 obj << /Length 27 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 47 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 27 0 obj 141 endobj 34 0 obj << /Length 35 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 49 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 35 0 obj 141 endobj 38 0 obj << /Length 39 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 51 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 39 0 obj 141 endobj 30 0 obj << /Length 31 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 53 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 31 0 obj 141 endobj 8 0 obj << /Length 9 0 R /Type /XObject /Subtype /Image /Width 129 /Height 57 /ColorSpace 40 0 R /SMask 55 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x1 Om @a 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`V+ endstream endobj 9 0 obj 120 endobj 22 0 obj << /Length 23 0 R /Type /XObject /Subtype /Image /Width 140 /Height 57 /ColorSpace 40 0 R /SMask 57 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 030] endstream endobj 23 0 obj 127 endobj 16 0 obj << /Length 17 0 R /Type /XObject /Subtype /Image /Width 162 /Height 57 /ColorSpace 40 0 R /SMask 59 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x1 Om ?@a 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`w`l6 endstream endobj 17 0 obj 144 endobj 24 0 obj << /Length 25 0 R /Type /XObject /Subtype /Image /Width 139 /Height 57 /ColorSpace 40 0 R /SMask 61 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xЁàSPa 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`30\ endstream endobj 25 0 obj 127 endobj 10 0 obj << /Length 11 0 R /Type /XObject /Subtype /Image /Width 140 /Height 57 /ColorSpace 40 0 R /SMask 63 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 030] endstream endobj 11 0 obj 127 endobj 12 0 obj << /Length 13 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 65 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 13 0 obj 141 endobj 28 0 obj << /Length 29 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 67 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 29 0 obj 141 endobj 32 0 obj << /Length 33 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace 40 0 R /SMask 69 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`i endstream endobj 33 0 obj 141 endobj 36 0 obj << /Length 37 0 R /Type /XObject /Subtype /Image /Width 129 /Height 57 /ColorSpace 40 0 R /SMask 71 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x1 Om @a 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`V+ endstream endobj 37 0 obj 120 endobj 18 0 obj << /Length 19 0 R /Type /XObject /Subtype /Image /Width 122 /Height 57 /ColorSpace 40 0 R /SMask 73 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream x  Om( 0` 0` 0` 0` 0` 0` 0` 0` 0` 0`Q~ endstream endobj 19 0 obj 114 endobj 57 0 obj << /Length 58 0 R /Type /XObject /Subtype /Image /Width 140 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream x홱k`5SjVP"E-bd)K A .R Z_j=] YO^$t^ xL+A F̄f#0 Mр~$F ',$i(j$IZ37!)8iǵg|?P7 ‘(,E¡v;0 L8d l2qc~`Q: OO9\43Ai%1zN:#6yP {:HܰzI~&y %R*W,]%?K2~7E_Yt8 T7-8j6UI,x[ &cR Vjܹn*4YpT{]&t," C ڒFܪ'о Gv&U*!V~V endstream endobj 58 0 obj 751 endobj 51 0 obj << /Length 52 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOYƙaf`0cF>bH?5qj&ۅb{^6w)MWUtm rF쿶gQ[Icw7=y}sN{Z*4ÛBGQpih Dϧ$as #\c<ϷAx<Dz&Ug?fضv!BU 4Q|`h7BTvsYzi(KOv^K wfbz^ } *xXC:Г+kMh{+Dyمdz5[o* e#JxHtq :\zXNޤLXApd>' @(X( i:%_ 8>Iѫ=I6+uʏ D @!1cCP{$je5q V:rt j"(3 6 5 (&BӁ@fe9ZEYTr`Ǫ(Dq,"c-JqjDz)mgvGM򟀏\ +v/ endstream endobj 52 0 obj 1081 endobj 63 0 obj << /Length 64 0 R /Type /XObject /Subtype /Image /Width 140 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOie.LR –R*bKil46%ۥ75-Xmҋ&)[Qc Vl?M}_'Ϝ79<--M~p8?bur1 qQ!BP B$P{(X"+P(2"< p 'HZ(mZZHi!!+T:bAaZFJ!R3O\puZFLp\@3 !824u[bmiM+áد`Eox:MjY+kSݦ4RO`Ǫo nM &LNH$ɼ d<2sT!Vӂ2}5{.,C~y!~ _u[42?"glvZ\Cq59Spx^`b`b^ baqq4g3T] j38=ϯnTUX?74Q/mKӗ4>m=1پTu1i`hVB7_6wvL7"Lϵ\] >RzhyHMOeŷK xfR'.ZJw\Xi{wәIO?J zXPОv"ԃ`*] 8(NJzkwohf7ãVRBc%;8}(~Eâ?) e[@ɔ:>.b)e]|򄔔Qi fAU1RJ℈șvJJlgZD\0h%)bp)I$G$6BP.H<V#Rغ&|0@jǕԊ* (6?~Ζ֊ endstream endobj 64 0 obj 1125 endobj 71 0 obj << /Length 72 0 R /Type /XObject /Subtype /Image /Width 129 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOR{9NYbhx1-GX? M﹙N,eٰde(ϛlSQqO' H(yDBS!0 La("9 %FP\Au()$8nX*SR*HӦjhڨת(L*.*ϗ*=]k=k֫Hy^;`'UfB6w\&q> J0BM[.OJW(]WJ L"<|,UTޮ?1> ԙTrPQk`Ibym3Hzsm9$2k DRknesK짿)^_Mf @J,7Œ﷿|ȷ/W{7.;,:Bz䀔3N_A|q}+ { p‘ɾMD>WQ% .~?wHb *!/(xyKy͌, (;Pv@فet'v'p[Ƈ}}X?V87Gc;`sdlY "@>og6Eپ|2" Qhl8_XyHfB|φB69w tD@V_O #>_Hdllbd)mhǣSx*:~6j|GT4]bٿC}bG$Idf/{W=^ x/62Z &ЖΖ6Oi8Yh)y$RTN fV`JC1W-68Au)J6x[`r%AQ*TRcHIW͕ܽ#Rr C>v/K 7+JsN'<ܘp endstream endobj 72 0 obj 1088 endobj 49 0 obj << /Length 50 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xSWe/ʲ+"rY$A_PcʔEIRMMkflRMPXC$JǨqͤM+_2=f߇eg缜>YY><<1' F|% 0DbN"Q6PD"EޗȃE$%a\)PrrHC'`#HZPYM!04 ˪<"q SUA(&ڢbSiPJMFP)IB,!B,Uh eu ֦f\6Zj+K9C*$Źr$-UB9Mbhȵ%u6Ǘ7\=} u\c("Uc#sUϜ{zdb|o_9.T)lAr"XsO=RobH N4DHu_ <IAsbaR KZ{݉酕`$g_ƿyMQ# QV׷̯ ?s?~ZgPĉ@Fmjh32dUxw0w/=eT dwnD9x\z4봖D#D~$=F4<=E10ʌ 3Ow0^≳[O^MSřF龎$>y6f]LfNo^vb_mj{|A$;ϹKSOGIIe8nVC;{ .o;,wN( 斛&B~Z pf٠.Nm]c p_ t٪uFP-or<^b$\+[|Pʚ.u=G~L<9qwFVz2~"Zhjr{K0{?G<:[ h?9P\.wHܮvk^F$l]jswfYzVF0$9DܘWeUzKC#8,UeU2I= DVM 1uZ\Je H*&P$2BRDTe.CN ʂ KŔfBT,K 3Ƭ<r,`0il| aIXA`.=3}udρv endstream endobj 50 0 obj 1156 endobj 53 0 obj << /Length 54 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOwq'ǝCNO֢aX+lݠҹ-A.&V)MK@Y?&}Q36Y~΄w^Oyh*ЪC"AP U CQіQ*tNOH HqQ1lL ]E: A΋f83 4P([\5"7Mnkm&cg%bz79]=wwUG ' 4W]r>,y}W墣~ߐi-&#qVBDG1kRwg^(Sɀ|ke5$^1JеB8;]X\d:8~{im@.<|x MՕR4rV$~AHv~u74ۣg xJo%cdϗ-5+غ'~Zx{h̤ǢC.+vo~,盽}J.E&Gm,R_[x::ɬ~w{#KWՊ9> stream xSk+.,,A@D d\+)R8c9J̤6I8TrJ*ю&Si'=΂ڜ=M|0/g}+@ qU0\,&!uA д 4-H8A|Vɩ U͗!. #xDΪzcsQUr #pnC0FHd9fwqT1˚Qb8p4v,z4cHRgq4;jBrEXVY,QhK_k7r7#VQUHe9N`ZWe5p41j <ݽR2k<4=WFhw{rI<}WOXFb֚bbe $ uCS ?!Xn0(K -'7frك c$Y49`x|Ɨoۗ 4)*_{q{gl\{1q2KbWåHt.]ᒻۛ/磑K bN%9jݖa=~<_)7U ¤MC`4$=;{@aBto3c}Aq8{ޖ{om|§wo x톃ME6O||y=r|~Vgc+:8cP ]yXQ@Xy(6i?[USdU(h-SKq,=}<r[ Le{B=#Spjbd'䱛T2/Π@WVںCã@w2]A38Ũ֓zwuV0D"Y 4|jҰP6 m,*k@tJ0#Q0M `.-*` :"|f,DI)rjN_dB^Us,#%wN̔3  FNKt͜)\Sy$2cG/HJ@P"Hvs_Z endstream endobj 74 0 obj 1095 endobj 69 0 obj << /Length 70 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOw~w' / EPiLpHhgPª(ڙ:YڮT&`jMh0v3wx=8.=xyXy>l<)H4EP% 0 Adq0.@q PDF !IEb4%Dч).+TjM)84ZIhP8[e'e*`0d4JR14c!"y\c9.:j?kd/XHrjkHZMKVFY !n$WgYkCBZ8;p41MLdzjr<mHXVPv%2;}ѹ;VguLE"\~ O>ZXuliQdf֠ yh"x>Nߕq0fN{sr|9_%ϼ+WIr[Pd/cK$8N,{F 4H^bPK̘`|R6TY&O͞&WZWKI>9ȆQ.AIUeFVoGb./SJIf:R"Wkur $rNE܂,JEuBJ,(*(%2i)`:$k A@DR 0Yb6cFGy,a؏Y*la$jʀH:>i_:Hyjv7 endstream endobj 70 0 obj 1178 endobj 65 0 obj << /Length 66 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOgǹo|+g)_=ftl_\lCzĭ(P&4&4(YlQ&MZ[j0_szm.s&~$s<=WD!E1'a( eu8ju$hùҵN! =A1BKIJl#@ujEki)aVJaYFOj"(w8hܝq |[+g7iRWKhw^n#8 KjLfm-`H(njk@5ec?MwE'b09"{iF'56yo:9l*y*2:lF WZ:{ӳ~]>F6K%.Lk'oON۳shVs1e D}7(x]| bq}-d>5l߯ :;L?f &/x;@;<`ٟJw>cg{kcm9;&*c3Kכ*B\Xo$ۑxjSAR)l),>ߖ>V>Ac, 3A.~[|J Y\uBe5 PZD -Ԟ һŊ``UbtVI[= rn4i"M6 =d鋍mmgmJrڻn˿P^IT*$x#YSև 1VO@$ҙJaL:#HA3'Djn~p~0u‘D25 9>e`jµ{A1<?0YA 7Yy?0 HVtv#0ѯ7[G&:Ip.uB!1*PlZI-g9*DuDa 7 0É(L%j- &¥&Qp1Pk8 v܏cq$Qq{Z+7x endstream endobj 66 0 obj 1054 endobj 55 0 obj << /Length 56 0 R /Type /XObject /Subtype /Image /Width 129 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOR{9NYbhx1-GX? M﹙N,eٰde(ϛlSQqO' H(yDBS!0 La("9 %FP\Au()$8nX*SR*HӦjhڨת(L*.*ϗ*=]k=k֫Hy^;`'UfB6w\&q> J0BM[.OJW(]WJ L"<|,UTޮ?1> ԙTrPQk`Ibym3Hzsm9$2k DRknesK짿)^_Mf @J,7Œ﷿|ȷ/W{7.;,:Bz䀔3N_A|q}+ { p‘ɾMD>WQ% .~?wHb *!/(xyKy͌, (;Pv@فet'v'p[Ƈ}}X?V87Gc;`sdlY "@>og6Eپ|2" Qhl8_XyHfB|φB69w tD@V_O #>_Hdllbd)mhǣSx*:~6j|GT4]bٿC}bG$Idf/{W=^ x/62Z &ЖΖ6Oi8Yh)y$RTN fV`JC1W-68Au)J6x[`r%AQ*TRcHIW͕ܽ#Rr C>v/K 7+JsN'<ܘp endstream endobj 56 0 obj 1088 endobj 43 0 obj << /Length 44 0 R /Type /XObject /Subtype /Image /Width 140 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOP׵m(t16c3"f2L2 B! DnF %CEn_Udz~|:O6KɤAPŠ3D@PWA*H!IpRc "p%:i)54  :a S&2,iH($E -j6VSBP͙..x0  )Z垒#4pWU %P[:-z91r\urUTC-jn V+8TaLv/p=RCuE E#%[746R&Ɔn :0Imʆ''#3sp2y=5/iǂ+ך:ƧW?|ե`NǙ^puRi ;:5]߀ûeyYL_ov9l̾hsY4Mpprn>v~75*fUz){[koF·5,Àe+vp||#LJ/KgKQPiٮŵ!hWUE+/7!\%/BN›~'yMWɋ&轈SƱE> stream xO`Żn[Gwa0Ac8nөL  a p8M B,O[Mϗ𦧧m AV" bXZ ,\Kq @E8L5 r*i%Pt8zLZ&g4Zl&K)G% "IJ6͖:`6 -#P1{a F*LV(+RGbki9CR3B{tjU'C\-Mbؓ(dJZr}{T/4T9fFA Y$LCw# T:yGl&FI1f\gZ=jX]Z`PخC!UzKIyӱ/@*lq_Oe3e)p 2xNLϾnb3Cqr>۱ɹK@w*( 1JkW6] G 5zl TUd¡.pUsÑuZ[.Άo_wZs);jZ:ƦՍMZ_n"o8j5M8Op\s|T`\3mǞykc%0䮿u0OM ӸBi"d $aqrIc)dFh-B@X g˿!FvNqx?h:;;vΘhD ƏQM47ā=Zb(ٴiO+ T%> Oy %7%[{[b= 8A 4_2 endstream endobj 60 0 obj 826 endobj 47 0 obj << /Length 48 0 R /Type /XObject /Subtype /Image /Width 161 /Height 56 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOZWǹOp˽YPiiYQ[UMlL)uk3k 3Am]VI[k•:cm:šl 9wr~<^E @b`AQ Thub|8H 0 B0 )$40RVCFBՐU"C p2JVVkCfZdnTd4T2 )pvBKF˩3NP9춓fVNBlaLH2zslըThN`>!QNš+`0#W6NV#²kTcuߌNT,r#<t%MQF8C@ݿ &1R1BJa8OKρiiq|<y\'bI1h̯N+/k_ Jd4&yåI\[^nTQA]sgWwളvO&57(Y\lv)~kN&%N_|N{?߮&fAOY7R;1us3m= d,H,*.5%*)W$(X*X#mr̔؄b1csroqyQi~iZ6MڂњO^n$ٶӤ|_iju_qAbyp㾾Ւ\_,!:(rt(=}p֎ [X\tx4yO#eu͎/SMeⷖu鎾nDb`̱ѫS0יt\C_Y A 锣>7tξC!:E$56 0hYY Q9$-Wo04? rx USLTk4 q(M9D>NT)`E<c|.L ZDz{6lŽtZ37w endstream endobj 48 0 obj 1079 endobj 45 0 obj << /Length 46 0 R /Type /XObject /Subtype /Image /Width 139 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOg9ENF9Xu `EQ&87[lm-jfM* `Mhl%~9~y**@lePDTD",G01K &`@DDJRrZdࡠ)c`ͨ:No02+ B`"gԬq-p,fSARPD$ JY]N8t9:mg8AŲP4a]j6h2\\5FKk76 N >Nzmf_EaκazTk4 蹮H>Ajo{cg|3,NZb,M-27<+z3qpu Y Pim%Ӈw8>μNc.N_Rcl<Y>z Eq0-*Xu`lA=*'TU`Rʟ +UN |u?m+r/TAU*a>AU)Wxj7'=J$cຆ'oD=y~u8:⛏_x':c?A} Xd[N3[Ғ)Ysg蟉w{H&KZZZZk:_ŷC`C~^S]hsFx; VנּPcjT"G=6xQ+=VTI)F g 0= +[AM, s67!o>3pho6jUxAAń56w N~5 EQ>#d ЖK>wp#VRd("~"IճYVU G] '=*0n`S`W|4Kp) CH (  (M!%%Ʌ'_24 endstream endobj 46 0 obj 1104 endobj 61 0 obj << /Length 62 0 R /Type /XObject /Subtype /Image /Width 139 /Height 57 /ColorSpace /DeviceGray /BitsPerComponent 8 /Filter /FlateDecode >> stream xOg9;8|`_5\ݖby34~#I)-Cb()dwߺz$ %e2齭$dA$*"u}=킠Q HhO;I}=_3R|ϗmcم[*,/Rc"x]D T=N('W=W>cUb$`z `c_kR|w }NgRVP . g[,F( Tֳݠ+ v9BodiRJP!ŭTv ZP![8ʦH$" Y(MfH:σbݨcIhqՂ >d0l8G,0jEP! a $0BQȣ)> stream xOZg978#G.CCѣ-wm5*X[3[+blZ/5e:qi=Y>?𞜐}y(s}#AQ '2PAReu8!&IRR"&04E!b\e/@eUJE&8#qokլBFI"(Зj&s_q &|iɇ<CIc L :NsZXrVW[M]k0qu65VhU2BTL+4zOo_D>yo\km*4|ƘDJ=}w1:r/7:*M6Gr,U׶MMAdvzrldZsj .UhM ׽CM=9 LBM\m\I;ZGha~nbqja$fwWߏOMmw˩*a&;fx$AP\8n' Ljlu6ܟz}0v8fN-[(NTlv^inr@Md.Ym5:<6eiT$Aq (zTRål*jej#B@TGyZѠӨYLD t#W(U,\@(gr(!LL@'> stream xROHQ6Axw )vuYm[Ңgߺ3ӛ5œ]`鲙}v*b{a[QÓ'a?dy֭S{=5ڊ^-CT#hsM9s1F9 1w7;aYf ]%{w;ћ9 \Ir< X}I<>Uw(gRVzWOelπ~v{|u׶>UEP>,l%KTn)=J+vp,ZSk9xw"zmMWzmʨ)(ͳDf[xf8:罊ZIE?9Z*UVPog~~\?A< =ѯ tIsQIi!3NTc)[d@f endstream endobj 76 0 obj 704 endobj 7 0 obj [ /ICCBased 75 0 R ] endobj 77 0 obj << /Length 78 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream xMHaї$T& R+SeL b}wg-E"u.VDNC:DuE^";cT03y|URcE4`λޘvztLUF\)s:k-iYj6|vP4*wd>,y vڴ=S԰79 ڸ@`ӋmvUl5`P=Gj)kP*}6~^/~.~a2 nײ0%f|U 9l7?j`l7"tiNf]?uhgM Zʲ4i[&LY_x {xO$̥߬S]%֧&7g̞>r=g8`候 8rʶ<dWT'<eL~.u"A=9뗚]>313X3-$e}u,gmg664$ыEzL*LZ_j_]Xy[?Xs N/ ]|msϚƫk_WfȸA2)oz-di2|m٣j|5ԥej8ɮeE7[Q|IM%ײxf)|6\ k`Ҳ䍐.> endobj 79 0 obj << /Type /Catalog /Pages 3 0 R /Version /1.4 >> endobj 80 0 obj << /Length 81 0 R /Length1 11844 /Filter /FlateDecode >> stream xzy|TEpUݵt;Nwt6 I ; L4@ / n@5M@cqFtTgyCM߮޺gsN[# 1(4saC3n7 z/%O#!, )A9 fҏr wŒLH%@ R4\( ,ʝ@j8Jڀ YȉPHi;хa#4hi1:A;Q T4mG|tOG==@A"h zbo9D[0-XƠ [њs( AkqTn@0:MF~xCIWba50VlL p@ehAa/s1tOg.+~Ěbπ&dCZ{gL6d쯱(P"[f< `W x H gh\UP:ټBLiaNc83Fpõp:yqx%~o id2!K23,g.av^&v,v&.ю@*$:kl؋pWI]Od#_ GDOI L6FE+}V24݉f4`2\]S4:']cEb pŷ9x~5 o 0ȈL$d!i#6ʤ1iL\gucX=;ֳ pf;nM+rS6nɽŽǯ7oB0FGX92+,Nsh&.Ǎh+pcn@ ]C@fcV1#H6Hk ;Jvg ) `6-Cvnp RiTϛIvj1.IQ'(r(2*<>AKӪSB9z0}g$v͔^`l1s ~М #moT~~yl8ԗ)_qu|ޯnio0nYoX7BG0 gi?2vCƟ׆G"hZ" ިYmx+8}s뒸"֮vF9T/s"uN.9W{Ǫګ-B<4ٌ$k) \Sb&Q-ؠ!&c2r2%j!-|.f1dbuqzz<:=AIF6/wp<^.O\vv.^dŋEIn5 uƳ n<guӸ׸}kÙ^2 >t)IN`=|tC!?O9O\BVjtM:VZU\$VtbHyYo`AuqIxTݧt@RCjU(p]Nv];v^`F~܂.${i[V$ڂׯK쑡(1z@f2GBH\n7K `CoFVl y._v^u8u6=vtOu *8g.509󬖀{-u/rW{߁ /NX5BA0`3H‹q=&/8SIf! \8e*'0 m\*Y+Eg[ Q9ٕ3oMggqIJ;x7X:&woAd7H{|U{ѷB4EvhRVդڗUCS k3eeۆvh,U&%ٙ1y#Eo%ՌD,sN -2j~(}yu$T8H|ėQfP*41ۓȪ7c gHWc. shm0h QVKZK梿Q:SeEY :PJ^.P'z Bc=cͼ<{zzgccbt[їߊJp&>"d,Fec͟W' ERXs]`p)Mj'F[w?-| 'awnu7.l̙{J+)r;?^WФe o:ޜ1rFW%زb)s1i_YUo-aTeP_>$|ڌ'; xjw {llL BF;'hB%Ҁ>^'ZKCw_SSϤ5ra2`$ϊj$pM()(ĉ$)֮ۋ+&&s6n|G|#Nr'z|7z5 y׭򵽟zkی͆0sK$==f)31DNxEHG#XF_?XrlGpнxeHUoaOyY*rR%KS>[)L)jCG <*$_.U/~hSjso޾ر 3Ww.|vG떾{}!АE@v4;X5B5Uk弢$Hۅ$9\0)ho1;e?DcZL6alRn6Ȑ*A$^h>E }i]W<wLs/s0z'// MJ̬]d-e/Voq2$r:Jׅ!ъC:s=/_zg4gdȹSw) v ^am0kH8\)hTDSlq ?Ⱦ$Q?'d {BL*,|;aU'ujWz)>BvveFz'<7tq&5dtoNjТ:*BpXRtK kxi$*0yoHV} ضG&eLX~ۄѿbӟS::9aG5yQ=`D8= .|`[ 1_O(UF#e5b!^k}w,!9:%OYB0٘!,J?緙 W{ ).}ぶo'PhRjT dʍU=هGŽ{D%4?O\ϟ,IZ9EI[Z1oF^蹗RN[fl_J:JNޞ}-+ oFŝ/V7Mx¸F$Nt߹ǻf!ZNLd1T YpjxFN#@`@㫴T_Y=}0{n}>b߈ 3߂woѯE_7QzuJF-#I]6D^e)UoɉfOOZvɴk@I8 VY|Y16|1J8IQNygtsQ{z \[yXh t/EX>!gn~جM028w;F}Ld  1UjLxiSEQ]B- JCgudnv'@Hv^2tcju*>bNȐUP[~[~]H֎Wt:Ÿ>2r|f}{ {)[nj2VjG\dA|~Ɨ0*QMT2LrEKI\lՀ6V S}.]dK A0<,u/řjM=l֑y!]S.0Ѡp0vn v4>5/pWGOIꟓ2׷\=l*|ۍ4ٵgՙؕFdU藻+n܍dMw@̿u|x뻆}9*R.=Y6Oaq2a0-7s⾺S4fۈ,cWwI2`w4t<O9WM۸}ws_Ő$&ds͒}i}|zѝY3'uR S @G \ 񹨉41sv!n$"!(n-;ÞđKRIK)l#p]l>0 鄰ꐃjMOax HEb59xy,-|i@D"Zik D/U "!/ hE-σzJ tC\QJv'Y73M i(~aX̧(ֺYk9IyVl>8?>n˿~^٬h;^]oM Du>:RQ߄?dcbViksRan;mo3l3vN ֏0ӳivԶTΤ7/+vQEAieԛ_x'Y`I%S A#1qZTgAJOA]PG]&@je*r*H:DZ!}ЇP)k j? NpVXF6F?N'Zn Y VL2W 68KƠ JI:,~)WTQ 'a UN4y Zg̛wy g~gN@l:8g9 T)nS$$87ME5NMGh跹J!CJÖ́ng!1h~-؁^hwb(^,xTH:'N\|\>? gܝd4 9^' S񎃁zڋ!Abݎ\k8r99'_9Jt?O\kLJCνWv;7A/ã [r1[#dƧ΂!ng313ci9sp &4N}s( 9}x'J;G 5q*5+BU[U~o`>嬰FCMp8UЁE"D#R' G@E^ tRˇEV$"uاa#]1*xG=vrcJj<x,4 NQ=уRSDSXYe͜z/τp'^ G޼ r/0L2|[ϑy*fIíp$:0гG3h0;])wh:)?TL90'45ZAl,[\w˻ kqONQzG画Í]u]u]F]&-icbpL+ubxi5p> endobj 83 0 obj [ 722 0 0 0 0 722 0 0 0 0 833 0 0 667 0 722 667 611 0 0 944 0 0 0 0 0 0 0 0 0 556 556 500 556 556 0 556 0 222 0 0 222 0 556 556 556 556 333 500 278 556 500 0 500 500 ] endobj 41 0 obj << /Type /Font /Subtype /TrueType /BaseFont /FTTUWZ+Helvetica /FontDescriptor 82 0 R /Widths 83 0 R /FirstChar 67 /LastChar 121 /Encoding /MacRomanEncoding >> endobj 84 0 obj << /Length 85 0 R /Length1 7924 /Filter /FlateDecode >> stream xY tTչ}^J2d2f&3ɐH!$+IBhAR@hP\P$tЫkb>"JXx-Jaf΄T\]^ֺ.Y6rWoƉ{ ǻ֮q~{V {;}d{'.۫/} IS(};c5j_C;4Ҟ5jޡ4yM]A[)ҙu}5˔&}1}\OSwwk)]wsw_yrt/C"< `i~lCwjc(a fĎ@ӽ- -xNņb v8F1|+alZjwjA#l mo1[HlS.*[]taZK C=E{>!gj\^}W{c" #V<a>Oo3V΂{$l`<Oo%x>"xnvaYvSW½K{%9aP0Zp#|[Q0!g ЈEXp/'4w}B͊Zҷmg!vp&n ;ʽ}ƛ(ga8AG=+KvI9P3'{a+Yr;q!x`(6>8$\oD@ Kq6|B {{Ä)| ^Wq(ؘY{/a/87+O,_o=~a0CX" }.'pQKF"푢IXO< q}lJV] '`1b؃m#k> nJ͍UqpZ,]^Wnss&yZF1r%.+$d 6-[Cgu+0N'R}9)e#^R܅B_p{|kUSSm |!T_0hZj c03 [T8 ?D~>e(Fjh5g8s 8k=R|*{[BWHnMvN~ ~ UhV@R*Pz2BvS&zHGZBG[[V8RBqu s a.Υx/ u`@sA::0>̺x: y,# Jx - +]p.ժp:aW3]+J6kU5/beCYe1R UJ%O6L^ {—O~>37>NasG˃G9 %h8IJ&Ja0j>i4 U ڇSةOgGk/F{ sBHÖ0D dD$C5:I􆣮cZ4DL>PUYyJ#Ņrzn}l)g yilH!'"3|"5KJØAC]E#PU5+))vҲ+f(!{cIFjΥƕ߉F^|$<{N/Ȋi H{p|]Z#DۻŦh/gf*|>3=-CKSpܙJ{Cza.!># gM#U '|dEE*!O\&bhNM\ZV-+/:%۝)RڑR-bvj3N)/+Oaom.sFG[wD]tD[Sw`܄ :}͏EǒMfh6ϙ ${ɥYUwS[\0eI YrGČ/+`C~pZ:y%̞9z+sq̨*U* GlNeLo׬:9UǮ=_o.E enɺu'OxOѡ2gvhI ݻf=?erDv/槓EN&hSwOtZA4 z8y'ޑqi%%-R62ޞni73s^rbqȳ0'_xCM\bbtIt}22ˆ̉Mf{#qD۳Uw HAT#B@/DwYnEɥdpj|0do">%m~۩Z9E"ibbAKD m;/>sܚVo nhBL¸]btPxA]*y0ۡBi NkAD ސ)U]~ZhBp0z]ӱRQ:C}+rb2]djjV&x5zڒ޲ ѳR^ҿo<d.0;2fUsܪdK 5ȓ,j ی%<%=7.z7K6W?;i6G̱uBwac~ÐozWr"V$^^!a1qթ@zlbcc*r,}LU7&ݦ,&f.IH?>}'_B|EJNEGG<P Q=I)к$}]b%J'/wG G1'z,ơǢE83DჁ9Z7@*.yuuutt/h(NL 3aTP/uHLEZ`I*KnчbjA7Y׉sh4dV&V#JZp1)UJ#0@GR6Pc6=g{mņU Vr _ID҇@@[_hW̼մ 80|&z,1MAO<-ጏƢ۟.,dLlZeo|󌞌߅!S0)?L֊.ZՑ ER̉/tKFᷰhyQ|@ʶL~ \lf, ga'e/jyRh#7*Bd7ҹ=Hu)w#>1lM5KW^+XP}ӪeߨWL9ygg&߃џF:o%t9/ ufRB!7oP#?@jEYl=CxW}P6$kKk˖YZr?9!Č`CY[qDʗ:.5(;??.9YŒ 9;\7<+̝:V e(, B9_--I<)Gʖ\D)]J$kDAhhD ФcY*'!ո|U$wea0"ܑZ> endobj 87 0 obj [ 278 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 611 0 722 0 667 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 611 0 0 556 0 0 0 278 0 556 0 0 611 611 0 0 389 0 333 0 0 778 0 556 ] endobj 42 0 obj << /Type /Font /Subtype /TrueType /BaseFont /LQPRFW+Helvetica-Bold /FontDescriptor 86 0 R /Widths 87 0 R /FirstChar 32 /LastChar 121 /Encoding /MacRomanEncoding >> endobj 1 0 obj << /Producer (Mac OS X 10.5.3 Quartz PDFContext) /CreationDate (D:20080616183824Z00'00') /ModDate (D:20080616183824Z00'00') >> endobj xref 0 88 0000000000 65535 f 0000046659 00000 n 0000004338 00000 n 0000031821 00000 n 0000000022 00000 n 0000004318 00000 n 0000004442 00000 n 0000030833 00000 n 0000006833 00000 n 0000007133 00000 n 0000008156 00000 n 0000008465 00000 n 0000008485 00000 n 0000008808 00000 n 0000004803 00000 n 0000005112 00000 n 0000007481 00000 n 0000007807 00000 n 0000009836 00000 n 0000010132 00000 n 0000005132 00000 n 0000005441 00000 n 0000007152 00000 n 0000007461 00000 n 0000007827 00000 n 0000008136 00000 n 0000005461 00000 n 0000005784 00000 n 0000008828 00000 n 0000009151 00000 n 0000006490 00000 n 0000006813 00000 n 0000009171 00000 n 0000009494 00000 n 0000005804 00000 n 0000006127 00000 n 0000009514 00000 n 0000009816 00000 n 0000006147 00000 n 0000006470 00000 n 0000031784 00000 n 0000040653 00000 n 0000046479 00000 n 0000022800 00000 n 0000023762 00000 n 0000026074 00000 n 0000027351 00000 n 0000024801 00000 n 0000026053 00000 n 0000014972 00000 n 0000016301 00000 n 0000011096 00000 n 0000012350 00000 n 0000016322 00000 n 0000017588 00000 n 0000021518 00000 n 0000022779 00000 n 0000010152 00000 n 0000011076 00000 n 0000023782 00000 n 0000024781 00000 n 0000027372 00000 n 0000028647 00000 n 0000012371 00000 n 0000013669 00000 n 0000020270 00000 n 0000021497 00000 n 0000028668 00000 n 0000029984 00000 n 0000018898 00000 n 0000020249 00000 n 0000013690 00000 n 0000014951 00000 n 0000017609 00000 n 0000018877 00000 n 0000030005 00000 n 0000030813 00000 n 0000030869 00000 n 0000031764 00000 n 0000031904 00000 n 0000031968 00000 n 0000040212 00000 n 0000040233 00000 n 0000040469 00000 n 0000040828 00000 n 0000045984 00000 n 0000046005 00000 n 0000046249 00000 n trailer << /Size 88 /Root 79 0 R /Info 1 0 R /ID [ <06bb8a184bebf551c289cefd1476dc39> <06bb8a184bebf551c289cefd1476dc39> ] >> startxref 46801 %%EOF 1 0 obj <> endobj xref 1 1 0000048719 00000 n trailer < <06bb8a184bebf551c289cefd1476dc39>] /Info 1 0 R /Prev 46801 /Root 79 0 R /Size 88>> startxref 48935 %%EOF pion-5.0.7+dfsg.orig/doc/README.ubuntu0000644000372000001440000000556112420270445016715 0ustar robertousersUbuntu Linux Build Instructions =============================== Note that these instructions are based on Ubuntu 9.04 (Jaunty), and may differ for other versions of Ubuntu. Installing dependencies: ------------------------ You can install the development tools required by Pion using apt-get: # apt-get install autoconf libtool make gcc g++ ruby cmake doxygen pkg-config You can install most of the third-party libraries required by Pion using apt-get: # apt-get install zlib1g-dev libssl-dev libxml2-dev libbz2-dev libpcap-dev python-lxml To install the Boost development libraries, use this on Ubuntu 9.04: # apt-get install libboost1.37-dev Use this instead on Ubuntu 9.10: # apt-get install libboost1.40-all-dev Installing log4cplus: --------------------- Note that the use of a logging framework is entirely optional, so you may skip this step if you like. We recommend that you use log4cplus for logging. Please visit the "Third Party Libraries" page on our website to obtain the source code tarball for log4cplus. Then, just run: # tar xvfj log4cplus-.tar.bz2 # cd log4cplus- # ./configure --enable-threads=yes # make all # make install Installing Python: ------------------ Pion's PythonReactor requires Python version 2.4 or greater. You may skip this step if you do not want to build support for Python. Python 2.4 (or greater) is already pre-installed and should work out of the box on most Linux systems. If you do not have it already, you should be able to grab the latest version using your favorite package manager: # apt-get install python python-dev Installing YAJL: ---------------- YAJL ("Yet Another JSON Library") is required to build support for the JSONCodec plugin. You may skip this step if you do not want to build support for JSON. On Ubuntu 10.04 and later, you can install this easily with: # sudo apt-get install libyajl-dev You can download the source code tarball for YAJL from the "Third Party Libraries" page on our website. After downloading it, just run: # tar xvfz yajl-.tgz # cd yajl- # ./configure # make One of the unit tests seems to fail on Ubuntu, but you can just ignore it. To install YAJL, we recommend that you just move the build files in the "build/yajl-" subdirectory into /usr/local: # sudo mv build/yajl-/lib/* /usr/local/lib # sudo mv build/yajl-/include/yajl /usr/local/include Building and installing Pion: ----------------------------- Now you should be able to build and install Pion: # tar xvfz pion--.tar.gz # cd pion-- # ./configure # make all # make install To build and run Pion's unit tests, run "make check" Known Problems -------------- The Pion executables may complain about loading shared libraries if the Boost and/or other libraries are not in your search path. Try this: export LD_LIBRARY_PATH=/usr/local/lib pion-5.0.7+dfsg.orig/doc/pion-net.graffle0000644000372000001440000015573112420270445017602 0ustar robertousers ActiveLayerIndex 0 ApplicationVersion com.omnigroup.OmniGrafflePro 129.15 AutoAdjust CanvasColor w 1 CanvasOrigin {0, 0} CanvasScale 1 ColumnAlign 1 ColumnSpacing 36 CreationDate 2007-04-15 18:28:00 -0700 Creator Michael Dickey DisplayScale 1 in = 1 in GraphDocumentVersion 5 GraphicsList Bounds {{248.518, 290.329}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 175 Line ID 174 Position 0.31719011068344116 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 173 ID 174 Points {275.018, 307.329} {275.018, 275.802} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 133 Bounds {{205.018, 240.302}, {140, 35}} Class ShapedGraphic ID 173 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPParser} Bounds {{53, 330.051}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 172 Line ID 171 Position 0.47587314248085022 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 87 ID 171 Points {79.5, 434.36} {79.5, 229.874} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 166 Bounds {{26, 435.36}, {107, 35}} Class ShapedGraphic ID 166 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPServer} Bounds {{329.666, 450.201}, {36, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 162 Line ID 161 Position 0.2698262631893158 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 uses} Class LineGraphic Head ID 135 Info 8 ID 161 Points {314.984, 466.519} {436.105, 431.985} Style stroke HeadArrow FilledArrow Pattern 1 TailArrow 0 Tail ID 25 Bounds {{271.744, 438.958}, {36, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 160 Line ID 159 Position 0.25524911284446716 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 uses} Class LineGraphic Head ID 27 ID 159 Points {275.096, 459.202} {332.482, 407.315} Style stroke HeadArrow FilledArrow Pattern 1 TailArrow 0 Tail ID 25 Bounds {{669.433, 346.528}, {55, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 158 Line ID 157 Position 0.3034064769744873 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 includes} Class LineGraphic Head ID 72 ID 157 Points {669.895, 413.874} {702, 318.421} {639.482, 230.808} Style stroke HeadArrow FilledArrow LineType 1 TailArrow 0 Tail ID 136 Bounds {{129.407, 291.115}, {55, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 156 Line ID 155 Position 0.17846563458442688 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 includes} Class LineGraphic Head ID 110 ID 155 Points {193.177, 371.496} {159.169, 240} {427.004, 217.528} Style stroke HeadArrow FilledArrow LineType 1 TailArrow 0 Tail ID 132 Bounds {{205.737, 353.884}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 151 Line ID 150 Position 0.37797626852989197 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 133 ID 150 Points {219.27, 371.66} {253.577, 343.149} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 132 Bounds {{599.736, 388.194}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 147 Line ID 146 Position 0.45945680141448975 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 134 ID 146 Points {645.533, 413.999} {603.533, 373.07} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 136 Bounds {{290.7, 353.386}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 144 Line ID 143 Position 0.39542737603187561 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 133 ID 143 Points {330.766, 371.66} {296.459, 343.149} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 27 Bounds {{505.754, 388.047}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 142 Line ID 141 Position 0.46703839302062988 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 134 ID 141 Points {506.586, 414.348} {561.545, 373.022} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 135 Bounds {{446.884, 370.71}, {55, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 140 Line ID 137 Position 0.19981692731380463 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 includes} Class LineGraphic Head ID 110 ID 137 Points {471.586, 414.348} {485.588, 230.991} Style stroke HeadArrow FilledArrow TailArrow 0 Tail ID 135 Info 3 Bounds {{593.849, 414.348}, {140, 35}} Class ShapedGraphic ID 136 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPRequestWriter} Bounds {{436.586, 414.348}, {140, 35}} Class ShapedGraphic ID 135 Magnets {1, 1} {1, -1} {-0.25, -0.499999} {-1, 1} {0, 1} {0, -1} {1, 0} {-1, 0} Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPResponseWriter} Bounds {{515.217, 337.721}, {140, 35}} Class ShapedGraphic ID 134 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPWriter} Bounds {{205.018, 307.829}, {140, 35}} Class ShapedGraphic ID 133 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPReader} Bounds {{127.828, 371.98}, {140, 35}} Class ShapedGraphic ID 132 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPResponseReader} Bounds {{599.914, 93.2868}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 131 Line ID 130 Position 0.40399140119552612 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 109 ID 130 Points {626.414, 117.242} {626.414, 75.2727} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 127 Bounds {{567.414, 117.742}, {118, 35}} Class ShapedGraphic ID 127 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPMessage} Bounds {{525.231, 169.625}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 116 Line ID 111 Position 0.43068146705627441 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Bounds {{599.914, 170.134}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 115 Line ID 112 Position 0.41371780633926392 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 127 ID 112 Points {626.414, 193.994} {626.414, 153.242} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 72 Class LineGraphic Head ID 127 ID 111 Points {519.456, 194.509} {594.395, 152.984} Style stroke HeadArrow FilledArrow TailArrow 0 Width 2 Tail ID 110 Bounds {{428, 194.994}, {118, 35}} Class ShapedGraphic ID 110 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPResponse} Bounds {{567.414, 39.7727}, {118, 35}} Class ShapedGraphic ID 109 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPTypes} Bounds {{53, 492.34}, {53, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 103 Line ID 102 Position 0.46208575367927551 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 extends} Class LineGraphic Head ID 166 ID 102 Points {79.5, 523.376} {79.5, 471.36} Style stroke HeadArrow FilledArrow LineType 1 TailArrow 0 Width 2 Tail ID 1 Bounds {{29.5, 193.874}, {100, 35}} Class ShapedGraphic ID 87 Shape Rectangle Style fill Color b 0.534124 g 0.984429 r 1 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 TCPServer} Bounds {{136.936, 503.659}, {55, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 84 Line ID 83 Position 0.46410125494003296 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 includes} Class LineGraphic Head ID 25 ID 83 Points {128.053, 524.031} {206.447, 495.218} Style stroke HeadArrow FilledArrow TailArrow 0 Tail ID 1 Bounds {{104.169, 162.986}, {55, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 75 Line ID 74 Position 0.40371024608612061 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 includes} Class LineGraphic Head ID 71 ID 74 Points {102.342, 193.252} {174.986, 135.622} Style stroke HeadArrow FilledArrow TailArrow 0 Tail ID 87 Bounds {{308.5, 39.7727}, {151, 17}} Class ShapedGraphic FitText YES Flow Resize FontInfo Font Helvetica Size 14 ID 73 Shape Rectangle Style fill Draws NO shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\b\fs28 \cf0 Pion Network Library} Wrap NO Bounds {{388.388, 341.377}, {55, 14}} Class ShapedGraphic FitText YES FontInfo Color w 0 Font Helvetica Size 12 ID 46 Line ID 40 Position 0.16527046263217926 RotationType 0 Shape Rectangle Style shadow Draws NO stroke Draws NO Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 includes} Class LineGraphic Head ID 72 ID 40 Points {379.74, 371.709} {598.461, 230.536} Style stroke HeadArrow FilledArrow TailArrow 0 Tail ID 27 Bounds {{127.828, 100}, {140, 35}} Class ShapedGraphic ID 71 Shape Rectangle Style fill Color b 0.534124 g 0.984429 r 1 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 TCPConnection} Bounds {{567.414, 194.994}, {118, 35}} Class ShapedGraphic ID 72 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPRequest} Bounds {{282.207, 371.98}, {140, 35}} Class ShapedGraphic ID 27 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Pattern 1 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 HTTPRequestReader} Bounds {{196, 459.873}, {118, 35}} Class ShapedGraphic ID 25 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 WebService} Bounds {{26, 524.376}, {107, 35}} Class ShapedGraphic ID 1 Shape Rectangle Style fill Color b 0.510824 g 1 r 0.672452 stroke Width 2 Text Text {\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural \f0\fs24 \cf0 WebServer} GridInfo GuidesLocked NO GuidesVisible YES HPages 1 ImageCounter 1 IsPalette NO KeepToScale Layers Lock NO Name Layer 1 Print YES View YES LayoutInfo LinksVisible NO MagnetsVisible NO MasterSheet Master 1 MasterSheets ActiveLayerIndex 0 AutoAdjust CanvasColor w 1 CanvasOrigin {0, 0} CanvasScale 1 ColumnAlign 1 ColumnSpacing 36 DisplayScale 1 in = 1 in GraphicsList GridInfo HPages 1 IsPalette NO KeepToScale Layers Lock NO Name Layer 1 Print YES View YES LayoutInfo Orientation 2 OutlineStyle Basic RowAlign 1 RowSpacing 36 SheetTitle Master 1 UniqueID 1 VPages 1 ModificationDate 2008-06-16 11:34:53 -0700 Modifier Michael Dickey NotesVisible NO Orientation 2 OriginVisible NO OutlineStyle Basic PageBreaks YES PrintInfo NSBottomMargin coded BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG NSLeftMargin coded BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG NSOrientation int 1 NSPaperSize size {792, 612} NSRightMargin coded BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG NSTopMargin coded BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFklwCG ReadOnly NO RowAlign 1 RowSpacing 36 SheetTitle Canvas 1 SmartAlignmentGuidesActive YES SmartDistanceGuidesActive YES UniqueID 1 UseEntirePage VPages 1 WindowInfo CurrentSheet 0 DrawerTab Outline DrawerWidth 209 Frame {{391, 155}, {1015, 783}} VisibleRegion {{-116, -40}, {1000, 669}} Zoom 1 pion-5.0.7+dfsg.orig/doc/README0000644000372000001440000000034612420270445015370 0ustar robertousersThis directory is for reserved for documentation specific to the Pion Network Library. For general Pion documentation, please see the documentation directory for the Pion Common Library, located in: /common/doc/. pion-5.0.7+dfsg.orig/doc/README.msvc0000644000372000001440000002404312420270445016337 0ustar robertousersMicrosoft Visual C++ Build Instructions ======================================= The Easy Way: ------------- Atomic Labs has a zip file available from the "Third Party Libraries" page on our website that contains all of the required libraries to build Pion for MSVC 2008. To get started quickly, just download and uncompress this file into your C:\ directory, and you should be able to skip most of the following instructions (however, Path updates are still required). Building Boost: --------------- First, download and unzip the Boost 1.42.0 source code from: http://sourceforge.net/projects/boost/files/boost/1.42.0 We recommend that you use the bjam tool to build Boost for MSVC. You can download the latest bjam executable from: http://sourceforge.net/projects/boost/files/boost-jam (Click on boost-jam-3.1.18-1-ntx86.zip, or similar) Copy the included "bjam" executable into your C:\Windows\System32 directory. Open the Visual Studio 2008 Command Prompt, change to the Boost source code directory, and type: bjam --toolset=msvc debug release threading=multi stage Or, if you wish to build only the libraries required by Pion (this saves a little time and disk space but not a whole lot): bjam --toolset=msvc --with-thread --with-system --with-filesystem \ --with-regex --with-date_time --with-unit_test_framework \ --with-signals debug release threading=multi stage Boost.Iostreams is also required, but must be compiled separately for Windows; see Building Boost.Iostreams below. We recommend that you create a C:\boost-1.42.0 directory with C:\boost-1.42.0\lib and C:\boost-1.42.0\boost subdirectories. To install boost-1.42.0 into these directories, just copy the files in stage\lib into C:\boost-1.42.0\lib, and copy the entire boost directory (which contains all the header files) into C:\boost-1.42.0\boost. Finally, add C:\boost-1.42.0\lib to your Path. Building Boost.Iostreams: ------------------------- Boost.Iostreams is built by default without compression/decompression support on Windows (since zlib and bzip2 aren't installed as part of Windows.) Since Pion uses boost::iostreams::gzip_decompressor and boost::iostreams::bzip2_decompressor, zlib and bzip2 must be installed (see instructions later in this document) and Boost.Iostreams must be rebuilt: open a command prompt in ...\boost_1_42_0\libs\iostreams\build, and run the following command (changing the paths if you installed zlib and/or bzip2 elsewhere.) bjam debug release -sZLIB_BINARY=zdll -sZLIB_INCLUDE=C:/zlib-1.2.3/include \ -sZLIB_LIBPATH=C:/zlib-1.2.3/lib -sBZIP2_BINARY=bzip2 \ -sBZIP2_INCLUDE=C:/bzip2-1.0.5/include -sBZIP2_LIBPATH=C:/bzip2-1.0.5/lib Then copy boost_iostreams-vc90-mt-gd-1_42.{dll|lib} and boost_iostreams-vc90-mt-1_42.{dll|lib} from ...\boost_1_42_0\bin.v2\libs\iostreams\build to C:\Boost\Lib. Building Boost.Regex: ------------------------- Boost.Regex is built by default without Unicode support via ICU. Since Pion uses boost::u32regex, ICU must be installed (see instructions later in this document) and Boost.Regex must be rebuilt: open a command prompt in ...\boost_1_42_0\libs\regex\build, and run the following command (changing the path if you installed ICU elsewhere.) bjam debug release -sICU_PATH=C:\icu-3.6 Then copy boost_regex-vc90-mt-gd-1_42.{dll|lib} and boost_regex-vc90-mt-1_42.{dll|lib} from ...\boost_1_42_0\bin.v2\libs\regex\build to C:\boost-1.42.0\lib. Documentation is available at the Boost website: http://www.boost.org/doc/libs/1_42_0/libs/regex/doc/html/boost_regex/install.html#boost_regex.install.building_with_unicode_and_icu_support Installing OpenSSL: ------------------- ASIO requires OpenSSL for SSL/TLS encryption support. You can get Win 32 binaries for OpenSSL from: http://www.pion.org/files/openssl-0.9.8l-win32.zip Unzip directly into C: (or change OPENSSL_HOME accordingly.) The zip file includes both static (in /lib) and DLL (in /bin) versions of ssleay32 and libeay32. If you want to use the DLL versions, you will need to add C:\openssl-0.9.8l\bin to your path (or otherwise include the DLLs). If you want to build them yourself, you can get the source tarball from: http://www.openssl.org/source/openssl-0.9.8l.tar.gz You can build the static or DLL versions of ssleay32 and libeay32 by using nt.mak or ntdll.mak, respectively, as explained in INSTALL.W32. Pion expects them to be in $(OPENSSL_HOME)\lib or $(OPENSSL_HOME)\bin, repectively, where OPENSSL_HOME is C:\openssl-0.9.8l unless you've changed it. Pion is currently set up to link to ssleay32d.lib and libeay32d.lib for the debug configuration; the easiest way to get these files is from the above zip file. Note that if you try to use the release versions of ssleay32.lib and libeay32.lib with a debug configuration of Pion, you will probably have trouble running the unit tests, due to msvcr80.dll and msvcr80d.dll being loaded at the same time. (Yes, this is even true for the static versions.) Linking with OpenSSL: --------------------- Macro OPENSSL_HOME in pion.vsprops is set to C:\openssl-0.9.8l. If you installed OpenSSL somewhere other than C:\openssl-0.9.8l, change OPENSSL_HOME accordingly. By default, Pion links with the DLL versions, which should be in $(OPENSSL_HOME)\bin. To link with the static versions, you will have to change $(OPENSSL_HOME)\bin to $(OPENSSL_HOME)\lib in common\build\Release_DLL_pion.vsprops, common\build\Debug_DLL_pion.vsprops and platform\server\pion.vcproj. Include PION_HAVE_SSL or PION_FULL in Preprocessor Definitions for the project, or in PionConfig.hpp.win, uncomment '#define PION_HAVE_SSL'. (The Debug_DLL_full and Release_DLL_full configurations have PION_FULL defined.) Logging frameworks: ------------------- Note that the use of a logging framework is entirely optional, so you may skip this step if you like. If no logging option is defined, std::cout and std::cerr will be used for logging. To disable logging, include PION_DISABLE_LOGGING in Preprocessor Definitions for the project, or in PionConfig.hpp.win, uncomment '#define PION_DISABLE_LOGGING'. We recommend log4cplus (http://log4cplus.sourceforge.net/) for logging. A binary distribution is available at http://pion.org/files/log4cplus-1.0.3-win32.zip. Extract it into C:\, or change user macro LOG4CPLUS_HOME in pion.vsprops, currently set to C:\log4cplus-1.0.3, accordingly. Add \bin to your path. Include PION_USE_LOG4CPLUS or PION_FULL in Preprocessor Definitions for the project, or in PionConfig.hpp.win, uncomment '#define PION_USE_LOG4CPLUS'. JSON (optional): ---------------- Building JSONCodec requires YAJL (http://lloyd.github.com/yajl/). A binary distribution is available at http://pion.org/files/yajl-1.0.9.win32.zip. Unzip directly into C: (or change JSONCodec.vcproj accordingly) and add C:\yajl-1.0.9\bin to your path. JSONCodec is only built in the Debug_DLL_full and Release_DLL_full configurations of pion-platform.sln. Python (optional): ------------------ Building PythonReactor requires python 2.6 to be installed. A Windows installer is available at http://www.python.org/ftp/python/2.6.2/python-2.6.2.msi. Install it in the default location (or change PythonReactor.vcproj accordingly). Unfortunately, the installer doesn't include the debug version of the library, so you will need to build python26_d yourself in order to build the debug version of PythonReactor. The source code is available at http://www.python.org/ftp/python/2.6.2/Python-2.6.2.tar.bz2: open pcbuild.sln, build the debug version of python.vcproj, then copy python26_d.lib to C:\Python26\libs and python26_d.dll to C:\Windows\SysWOW64 (or wherever the installer put python26.lib and python26.dll, respectively). PythonReactor is only built in the Debug_DLL_full and Release_DLL_full configurations of pion-platform.sln. Additional libraries (required for PLATFORM build) -------------------------------------------------- zlib: - download http://xmlsoft.org/sources/win32/zlib-1.2.3.win32.zip - open it into C:\zlib-1.2.3 - add C:\zlib-1.2.3\bin to your path - (if installed somewhere other than C:\zlib-1.2.3, change user macro ZLIB_HOME in pion.vsprops accordingly) iconv: - download http://xmlsoft.org/sources/win32/iconv-1.9.2.win32.zip - open it into C:\iconv-1.9.2\ - add C:\iconv-1.9.2\bin to your path libxml: - download http://xmlsoft.org/sources/win32/libxml2-2.6.30.win32.zip - open it into C:\libxml2-2.6.30\ - add C:\libxml2-2.6.30\bin to your path - (if installed somewhere other than C:\libxml2-2.6.30, change user macro LIBXML_HOME in pion.vsprops accordingly) bzip2: - download http://gnuwin32.sourceforge.net/downlinks/bzip2-bin-zip.php - open it into C:\bzip2-1.0.5 - add C:\bzip2-1.0.5\bin to your path - (if installed somewhere other than C:\bzip2-1.0.5, change user macro BZIP2_HOME in pion.vsprops accordingly) icu: - download ftp://ftp.software.ibm.com/software/globalization/icu/3.6/icu4c-3_6-Win32-msvc7_1.zip - open it into C:\icu-3.6 - add C:\icu-3.6\bin to your path - (if installed somewhere other than C:\icu-3.6, change user macro ICU_HOME in pion.vsprops accordingly) Building and installing Pion: ----------------------------- Now you should be able to build the solution file called pion-.sln. See platform/server/README.msvc for more information about running Pion. Running the test programs: -------------------------- Make sure "C:\boost-1.42.0\lib" is on your path. If you got the source code from the Subversion repository and haven't yet run Doxygen, then create the documentation files (used as part of the Pion Network Library tests) as follows: cd \.. doxygen net\doc\Doxyfile Alternatively, just create file "\doc\html\index.html": pion-net Documentation

pion-net Documentation

Otherwise, PionWebServer and unit tests fail with "no such directory" error. To test PionWebServer, try running it from "\utils\" with the following command line args: -c testservices.conf To run from within the IDE, go to PionWebServer Property Pages -> Debugging, and set 'Command Arguments' to the above. pion-5.0.7+dfsg.orig/build/0000755000372000001440000000000013015400173015031 5ustar robertouserspion-5.0.7+dfsg.orig/build/third_party_libs_x64.props0000644000372000001440000000760312420270445022175 0ustar robertousers C:\vc12 $(LIB_ROOT)\boost-1.56.0 $(LIB_ROOT)\boost-1.56.0\lib $(LIB_ROOT)\bzip2-1.0.6\lib64 $(LIB_ROOT)\iconv-1.9.2\include $(LIB_ROOT)\iconv-1.9.2\bin\x64 $(LIB_ROOT)\icu4c-53.1\icu\include $(LIB_ROOT)\icu4c-53.1\icu\lib64 $(LIB_ROOT)\icu4c-53.1\icu\bin64 $(LIB_ROOT)\libxml2-2.9.0\include $(LIB_ROOT)\libxml2-2.9.0\bin\x64 $(LIB_ROOT)\log4cplus-1.1.3-rc2\include $(LIB_ROOT)\log4cplus-1.1.3-rc2\bin\x64 $(LIB_ROOT)\openssl-1.0.1j\inc64 $(LIB_ROOT)\openssl-1.0.1j\bin\x64 $(LIB_ROOT)\zlib-1.2.8\include $(LIB_ROOT)\zlib-1.2.8\lib64 $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_BIN);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(OPENSSL_LIB);$(ZLIB_LIB);$(PATH) $(LIB_ROOT)\sqlite-3.7.14.1\ $(LIB_ROOT)\sqlite-3.7.14.1\lib64-ICU-53 <_ProjectFileVersion>10.0.40219.1 $(BOOST_INC);$(ICONV_INC);$(ICU_INC);$(LIBXML_INC);$(LOG4CPLUS_INC);$(OPENSSL_INC);$(PYTHON_INC);$(YAJL_INC);$(ZLIB_INC);%(AdditionalIncludeDirectories) $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_LIB);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_LIB);%(AdditionalLibraryDirectories) $(LIB_ROOT) $(BOOST_INC) $(BOOST_LIB) $(BZIP2_LIB) $(ICONV_INC) $(ICONV_LIB) $(ICU_INC) $(ICU_LIB) $(ICU_BIN) $(LIBXML_INC) $(LIBXML_LIB) $(LOG4CPLUS_INC) $(LOG4CPLUS_LIB) $(OPENSSL_INC) $(OPENSSL_LIB) $(ZLIB_INC) $(ZLIB_LIB) $(PION_PATH) $(SQLITE_INC) $(SQLITE_LIB) pion-5.0.7+dfsg.orig/build/pion-setup.inc0000644000372000001440000001264512420270445017645 0ustar robertousers# -------------------------------------- # pion-setup autoconf configuration file # -------------------------------------- # DO NOT USE autoheader (the .hpp.in file is not automanaged) AUTOHEADER="echo autoheader ignored" # Check for programs AC_PROG_CXX AC_PROG_INSTALL # Use C++ language AC_LANG_CPLUSPLUS AX_COMPILER_VENDOR # library to link with for dlopen, etc. PION_DLOPEN_LIBS=$lt_cv_dlopen_libs AC_SUBST(PION_DLOPEN_LIBS) # Set basic compiler options case "$build_os" in *solaris*) if test "$ax_cv_cxx_compiler_vendor" = "sun"; then # Solaris: Sun Studio C++ compiler CPPFLAGS="$CPPFLAGS -mt -library=stlport4" LDFLAGS="$LDFLAGS -mt -library=stlport4" PION_OPT_FLAGS="-O2 -DNDEBUG" PION_DEBUG_FLAGS="-g" else # Solaris: GCC compiler CPPFLAGS="$CPPFLAGS -pthreads -D_REENTRANT" LDFLAGS="$LDFLAGS -pthreads" PION_OPT_FLAGS="-O2 -ggdb -Wall -Wno-strict-aliasing -DNDEBUG" PION_DEBUG_FLAGS="-O0 -ggdb -Wall -Wno-strict-aliasing -fkeep-inline-functions" fi PION_EXTERNAL_LIBS="-lsocket -lnsl -lposix4" ;; *darwin*) # Mac OS X: GCC compiler # -pthread is implied (automatically set by compiler) CPPFLAGS="$CPPFLAGS -D_REENTRANT" #LDFLAGS="$LDFLAGS" #PION_OPT_FLAGS="-O3 -ggdb -fomit-frame-pointer -fstrict-aliasing -fno-tree-pre -falign-loops -Wall -Wno-strict-aliasing -DNDEBUG" PION_OPT_FLAGS="-O3 -ggdb -fomit-frame-pointer -fstrict-aliasing -Wall -Wno-strict-aliasing -DNDEBUG" PION_DEBUG_FLAGS="-O0 -ggdb -Wall -Wno-strict-aliasing -fkeep-inline-functions" # Check for OSX binary architecture AC_MSG_CHECKING([for OSX binary architectures]) AC_ARG_WITH([arch], AC_HELP_STRING([--with-arch@<:@=LIST@:>@],[specify comma-separated list of OSX architectures]), [with_arch=$withval], [with_arch=default]) if test "$with_arch" = "no"; then AC_MSG_RESULT(no) elif test "$with_arch" = "default"; then AC_MSG_RESULT(no) # Note: Pion seems to crashe consistently when built with x86_64 # AC_MSG_RESULT(x86_64) # with_arch="-arch x86_64" # PION_OPT_FLAGS="$PION_OPT_FLAGS $with_arch" # PION_DEBUG_FLAGS="$PION_DEBUG_FLAGS $with_arch" else AC_MSG_RESULT($with_arch) with_arch="-arch `echo $with_arch | sed 's#,# -arch #g'`" PION_OPT_FLAGS="$PION_OPT_FLAGS $with_arch" PION_DEBUG_FLAGS="$PION_DEBUG_FLAGS $with_arch" fi ;; *cygwin*) # Cygwin GCC compiler (Windows) CPPFLAGS="$CPPFLAGS -mthreads -D_REENTRANT -DPION_WIN32 -D__USE_W32_SOCKETS" LDFLAGS="$LDFLAGS -mthreads -Wl,-E" PION_OPT_FLAGS="-O2 -ggdb -Wall -Wno-strict-aliasing -DNDEBUG" PION_DEBUG_FLAGS="-O0 -ggdb -Wall -Wno-strict-aliasing -fkeep-inline-functions" PION_EXTERNAL_LIBS="-lws2_32 -lmswsock" ;; *freebsd*) # FreeBSD: GCC compiler CPPFLAGS="$CPPFLAGS -pthread -D_REENTRANT" LDFLAGS="$LDFLAGS -pthread -Wl,-E" PION_OPT_FLAGS="-O2 -ggdb -Wall -Wno-strict-aliasing -DNDEBUG" PION_DEBUG_FLAGS="-O0 -ggdb -Wall -Wno-strict-aliasing -fkeep-inline-functions" ;; *) # Other (Linux): GCC compiler CPPFLAGS="$CPPFLAGS -pthread -D_REENTRANT" LDFLAGS="$LDFLAGS -pthread -Wl,-E" LIBS="-lrt -ldl" PION_OPT_FLAGS="-O2 -ggdb -Wall -Wno-strict-aliasing -DNDEBUG" PION_DEBUG_FLAGS="-O0 -ggdb -Wall -Wno-strict-aliasing -fkeep-inline-functions" ;; esac # Check for --with-cpu (gcc CPU architecture) AC_MSG_CHECKING([for specific CPU architecture]) AC_ARG_WITH([cpu], AC_HELP_STRING([--with-cpu@<:@=MARCH@:>@],[specify specific CPU architecture for gcc]), [with_cpu=$withval], [with_cpu=default]) if test "$with_cpu" = "no"; then AC_MSG_RESULT(no) else if test "$with_cpu" = "default"; then if test "$with_arch" = "no" || test "$with_arch" = "default" ; then if test "$ax_cv_cxx_compiler_vendor" = "gnu"; then # check __x86_64__ to determine default AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ #if defined(__x86_64__) // x86_64 defined -> leave undefined #else #error __x86_64__ not defined -> i686 #endif ]])], [], [with_cpu="i686"]) fi fi fi if test "$with_cpu" = "default"; then AC_MSG_RESULT(no) else # check to make sure it works CFLAGS_SAVED=$CFLAGS CXXFLAGS_SAVED=$CXXFLAGS CFLAGS="$CFLAGS -march=$with_cpu" CXXFLAGS="$CXXFLAGS -march=$with_cpu" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [ AC_MSG_RESULT($with_cpu) PION_OPT_FLAGS="$PION_OPT_FLAGS -march=$with_cpu" PION_DEBUG_FLAGS="$PION_DEBUG_FLAGS -march=$with_cpu" ], [ AC_MSG_RESULT(no) ]) CFLAGS=$CFLAGS_SAVED CXXFLAGS=$CXXFLAGS_SAVED fi fi # Check for debug AC_MSG_CHECKING([for debugging]) AC_ARG_WITH([debug], AC_HELP_STRING([--with-debug],[build with debugging information]), [with_debug=$withval], [with_debug=no]) if test "$with_debug" = "no"; then AC_MSG_RESULT(no) CFLAGS="$CFLAGS $PION_OPT_FLAGS" CXXFLAGS="$CXXFLAGS $PION_OPT_FLAGS" else AC_MSG_RESULT(yes) CFLAGS="$CFLAGS $PION_DEBUG_FLAGS" CXXFLAGS="$CXXFLAGS $PION_DEBUG_FLAGS" fi # Check for --with-plugins AC_MSG_CHECKING([for plug-ins directory]) AC_ARG_WITH([plugins], AC_HELP_STRING([--with-plugins@<:@=DIR@:>@],[directory where Pion Plug-ins are installed]), [with_plugins=$withval], [with_plugins=no]) if test "$with_plugins" = "no"; then if test "x$prefix" = "xNONE"; then PION_PLUGINS_DIRECTORY=/usr/local/share/pion/plugins else PION_PLUGINS_DIRECTORY=${prefix}/share/pion/plugins fi else PION_PLUGINS_DIRECTORY=$with_plugins fi AC_MSG_RESULT($PION_PLUGINS_DIRECTORY) AC_DEFINE_UNQUOTED([PION_PLUGINS_DIRECTORY],["$PION_PLUGINS_DIRECTORY"],[Define to the directory where Pion Plug-ins are installed.]) AC_SUBST(PION_PLUGINS_DIRECTORY) pion-5.0.7+dfsg.orig/build/third_party_libs_win32.props0000644000372000001440000001212312420270445022507 0ustar robertousers C:\boost\include\boost-1_51 C:\boost\lib C:\bzip2-1.0.6\include C:\bzip2-1.0.6\lib C:\iconv-1.9.2\include C:\iconv-1.9.2\lib C:\iconv-1.9.2\bin C:\icu4c-49_1_2\icu\include C:\icu4c-49_1_2\icu\lib C:\icu4c-49_1_2\icu\bin C:\libxml2-2.9.0\include C:\libxml2-2.9.0\lib C:\libxml2-2.9.0\bin C:\log4cplus-1.0.4.1\include C:\log4cplus-1.0.4.1\bin C:\apache\apache-log4cxx-0.10.0\src\main\include C:\apache\apache-log4cxx-0.10.0\bin C:\openssl-1.0.1j\inc32 C:\openssl-1.0.1j\bin C:\Python26\include C:\Python26\libs C:\yajl-2.0.5\include C:\yajl-2.0.5\lib\Release C:\zlib-1.2.7\include C:\zlib-1.2.7\lib C:\zlib-1.2.7\bin $(BOOST_LIB);$(BZIP2_BIN);$(ICONV_BIN);$(ICU_BIN);$(LIBXML_BIN);$(LOG4CPLUS_LIB);$(LOG4CXX_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_BIN);$(PATH) C:\sqlite-3.7.14.1\ C:\sqlite-3.7.14.1\lib\ <_ProjectFileVersion>10.0.40219.1 $(BOOST_INC);$(BZIP2_INC);$(ICONV_INC);$(ICU_INC);$(LIBXML_INC);$(LOG4CPLUS_INC);$(LOG4CXX_INC);$(OPENSSL_INC);$(PYTHON_INC);$(YAJL_INC);$(ZLIB_INC);$(SQLITE_INC);%(AdditionalIncludeDirectories) $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_LIB);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(LOG4CXX_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_LIB);$(SQLITE_LIB);%(AdditionalLibraryDirectories) $(BOOST_INC) $(BOOST_LIB) $(BZIP2_INC) $(BZIP2_LIB) $(ICONV_INC) $(ICONV_LIB) $(ICONV_BIN) $(ICU_INC) $(ICU_LIB) $(ICU_BIN) $(LIBXML_INC) $(LIBXML_LIB) $(LIBXML_BIN) $(LOG4CPLUS_INC) $(LOG4CPLUS_LIB) $(LOG4CXX_INC) $(LOG4CXX_LIB) $(OPENSSL_INC) $(OPENSSL_LIB) $(PYTHON_INC) $(PYTHON_LIB) $(YAJL_INC) $(YAJL_LIB) $(ZLIB_INC) $(ZLIB_LIB) $(ZLIB_BIN) $(PION_PATH) $(SQLITE_INC) $(SQLITE_LIB) pion-5.0.7+dfsg.orig/build/make_config.pl0000644000372000001440000000372312420270445017643 0ustar robertousers#!/usr/bin/perl # -------------------------------------------------- # pion-platform configuration directory build script # -------------------------------------------------- use File::Spec; use File::Path; use File::Copy; use File::Glob ':glob'; # include perl source with common subroutines require File::Spec->catfile( ("common", "build"), "common.pl"); # ----------------------------------- # process argv & set global variables # ----------------------------------- # check command line parameters die("usage: make_config.pl [=]+") if ($#ARGV < 1); # set some global variables $SRCDIR = $ARGV[0]; $DESTDIR = $ARGV[1]; # ------------ # main process # ------------ # check source directory die "Source directory does not exist: $SRCDIR" if (! -d $SRCDIR); # build template parameter hash (start with default values) my %templates = ("PION_PLUGINS_DIRECTORY" => "../../platform/codecs/.libs/../../platform/databases/.libs/../../platform/reactors/.libs../../platform/protocols/.libs/../../platform/services/.libs/../../net/services/.libs/", "PION_DATA_DIRECTORY" => ".", "PION_UI_DIRECTORY" => "../../platform/ui", "PION_LOG_CONFIG" => "logconfig.txt", "PION_CONFIG_CHANGE_LOG" => "config.log"); # update template parameter hash using values provided my $do_merge = 0; for ($n = 2; $n <= $#ARGV; ++$n) { die "Bad template argument: \"$ARGV[$n]\"" if (! ($ARGV[$n] =~ m/([^=]+)=(.*)/) ); if ($1 eq "MERGE") { $do_merge = 1 } else { $templates{$1} = $2; } } # clear out old files and directories at destination if (not $do_merge) { @oldfiles = bsd_glob($DESTDIR . "/*"); foreach (@oldfiles) { rmtree($_); } } # copy files using templates copyDirWithoutDotFiles($SRCDIR, $DESTDIR, %templates); print "* Done building configuration directory ($SRCDIR => $DESTDIR)\n"; pion-5.0.7+dfsg.orig/build/ax_prog_doxygen.m40000644000372000001440000004277412420270445020513 0ustar robertousers# =========================================================================== # http://autoconf-archive.cryp.to/ax_prog_doxygen.html # =========================================================================== # # SYNOPSIS # # DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR]) # DX_DOXYGEN_FEATURE(ON|OFF) # DX_DOT_FEATURE(ON|OFF) # DX_HTML_FEATURE(ON|OFF) # DX_CHM_FEATURE(ON|OFF) # DX_CHI_FEATURE(ON|OFF) # DX_MAN_FEATURE(ON|OFF) # DX_RTF_FEATURE(ON|OFF) # DX_XML_FEATURE(ON|OFF) # DX_PDF_FEATURE(ON|OFF) # DX_PS_FEATURE(ON|OFF) # # DESCRIPTION # # The DX_*_FEATURE macros control the default setting for the given # Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for # generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML # help (for MS users), 'CHI' for generating a seperate .chi file by the # .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate # output formats. The environment variable DOXYGEN_PAPER_SIZE may be # specified to override the default 'a4wide' paper size. # # By default, HTML, PDF and PS documentation is generated as this seems to # be the most popular and portable combination. MAN pages created by # Doxygen are usually problematic, though by picking an appropriate subset # and doing some massaging they might be better than nothing. CHM and RTF # are specific for MS (note that you can't generate both HTML and CHM at # the same time). The XML is rather useless unless you apply specialized # post-processing to it. # # The macros mainly control the default state of the feature. The use can # override the default by specifying --enable or --disable. The macros # ensure that contradictory flags are not given (e.g., # --enable-doxygen-html and --enable-doxygen-chm, # --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each # feature will be automatically disabled (with a warning) if the required # programs are missing. # # Once all the feature defaults have been specified, call DX_INIT_DOXYGEN # with the following parameters: a one-word name for the project for use # as a filename base etc., an optional configuration file name (the # default is 'Doxyfile', the same as Doxygen's default), and an optional # output directory name (the default is 'doxygen-doc'). # # Automake Support # # The following is a template aminclude.am file for use with Automake. # Make targets and variables values are controlled by the various # DX_COND_* conditionals set by autoconf. # # The provided targets are: # # doxygen-doc: Generate all doxygen documentation. # # doxygen-run: Run doxygen, which will generate some of the # documentation (HTML, CHM, CHI, MAN, RTF, XML) # but will not do the post processing required # for the rest of it (PS, PDF, and some MAN). # # doxygen-man: Rename some doxygen generated man pages. # # doxygen-ps: Generate doxygen PostScript documentation. # # doxygen-pdf: Generate doxygen PDF documentation. # # Note that by default these are not integrated into the automake targets. # If doxygen is used to generate man pages, you can achieve this # integration by setting man3_MANS to the list of man pages generated and # then adding the dependency: # # $(man3_MANS): doxygen-doc # # This will cause make to run doxygen and generate all the documentation. # # The following variable is intended for use in Makefile.am: # # DX_CLEANFILES = everything to clean. # # Then add this variable to MOSTLYCLEANFILES. # # ----- begin aminclude.am ------------------------------------- # # ## --------------------------------- ## # ## Format-independent Doxygen rules. ## # ## --------------------------------- ## # # if DX_COND_doc # # ## ------------------------------- ## # ## Rules specific for HTML output. ## # ## ------------------------------- ## # # if DX_COND_html # # DX_CLEAN_HTML = @DX_DOCDIR@/html # # endif DX_COND_html # # ## ------------------------------ ## # ## Rules specific for CHM output. ## # ## ------------------------------ ## # # if DX_COND_chm # # DX_CLEAN_CHM = @DX_DOCDIR@/chm # # if DX_COND_chi # # DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi # # endif DX_COND_chi # # endif DX_COND_chm # # ## ------------------------------ ## # ## Rules specific for MAN output. ## # ## ------------------------------ ## # # if DX_COND_man # # DX_CLEAN_MAN = @DX_DOCDIR@/man # # endif DX_COND_man # # ## ------------------------------ ## # ## Rules specific for RTF output. ## # ## ------------------------------ ## # # if DX_COND_rtf # # DX_CLEAN_RTF = @DX_DOCDIR@/rtf # # endif DX_COND_rtf # # ## ------------------------------ ## # ## Rules specific for XML output. ## # ## ------------------------------ ## # # if DX_COND_xml # # DX_CLEAN_XML = @DX_DOCDIR@/xml # # endif DX_COND_xml # # ## ----------------------------- ## # ## Rules specific for PS output. ## # ## ----------------------------- ## # # if DX_COND_ps # # DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps # # DX_PS_GOAL = doxygen-ps # # doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps # # @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag # cd @DX_DOCDIR@/latex; \ # rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ # $(DX_LATEX) refman.tex; \ # $(MAKEINDEX_PATH) refman.idx; \ # $(DX_LATEX) refman.tex; \ # countdown=5; \ # while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ # refman.log > /dev/null 2>&1 \ # && test $$countdown -gt 0; do \ # $(DX_LATEX) refman.tex; \ # countdown=`expr $$countdown - 1`; \ # done; \ # $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi # # endif DX_COND_ps # # ## ------------------------------ ## # ## Rules specific for PDF output. ## # ## ------------------------------ ## # # if DX_COND_pdf # # DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf # # DX_PDF_GOAL = doxygen-pdf # # doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf # # @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag # cd @DX_DOCDIR@/latex; \ # rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ # $(DX_PDFLATEX) refman.tex; \ # $(DX_MAKEINDEX) refman.idx; \ # $(DX_PDFLATEX) refman.tex; \ # countdown=5; \ # while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ # refman.log > /dev/null 2>&1 \ # && test $$countdown -gt 0; do \ # $(DX_PDFLATEX) refman.tex; \ # countdown=`expr $$countdown - 1`; \ # done; \ # mv refman.pdf ../@PACKAGE@.pdf # # endif DX_COND_pdf # # ## ------------------------------------------------- ## # ## Rules specific for LaTeX (shared for PS and PDF). ## # ## ------------------------------------------------- ## # # if DX_COND_latex # # DX_CLEAN_LATEX = @DX_DOCDIR@/latex # # endif DX_COND_latex # # .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) # # .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) # # doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag # # doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) # # @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) # rm -rf @DX_DOCDIR@ # $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) # # DX_CLEANFILES = \ # @DX_DOCDIR@/@PACKAGE@.tag \ # -r \ # $(DX_CLEAN_HTML) \ # $(DX_CLEAN_CHM) \ # $(DX_CLEAN_CHI) \ # $(DX_CLEAN_MAN) \ # $(DX_CLEAN_RTF) \ # $(DX_CLEAN_XML) \ # $(DX_CLEAN_PS) \ # $(DX_CLEAN_PDF) \ # $(DX_CLEAN_LATEX) # # endif DX_COND_doc # # ----- end aminclude.am --------------------------------------- # # LAST MODIFICATION # # 2008-04-12 # # COPYLEFT # # Copyright (c) 2008 Oren Ben-Kiki # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. ## ----------## ## Defaults. ## ## ----------## DX_ENV="" AC_DEFUN([DX_FEATURE_doc], OFF) AC_DEFUN([DX_FEATURE_dot], OFF) AC_DEFUN([DX_FEATURE_man], OFF) AC_DEFUN([DX_FEATURE_html], ON) AC_DEFUN([DX_FEATURE_chm], OFF) AC_DEFUN([DX_FEATURE_chi], OFF) AC_DEFUN([DX_FEATURE_rtf], OFF) AC_DEFUN([DX_FEATURE_xml], OFF) AC_DEFUN([DX_FEATURE_pdf], OFF) AC_DEFUN([DX_FEATURE_ps], OFF) ## --------------- ## ## Private macros. ## ## --------------- ## # DX_ENV_APPEND(VARIABLE, VALUE) # ------------------------------ # Append VARIABLE="VALUE" to DX_ENV for invoking doxygen. AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])]) # DX_DIRNAME_EXPR # --------------- # Expand into a shell expression prints the directory part of a path. AC_DEFUN([DX_DIRNAME_EXPR], [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']]) # DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF) # ------------------------------------- # Expands according to the M4 (static) status of the feature. AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])]) # DX_REQUIRE_PROG(VARIABLE, PROGRAM) # ---------------------------------- # Require the specified program to be found for the DX_CURRENT_FEATURE to work. AC_DEFUN([DX_REQUIRE_PROG], [ AC_PATH_TOOL([$1], [$2]) if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION]) # Fixing for autoconf 2.59 and above -- TaO090102 AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0) # AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0) fi ]) # DX_TEST_FEATURE(FEATURE) # ------------------------ # Expand to a shell expression testing whether the feature is active. AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1]) # DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE) # ------------------------------------------------- # Verify that a required features has the right state before trying to turn on # the DX_CURRENT_FEATURE. AC_DEFUN([DX_CHECK_DEPEND], [ test "$DX_FLAG_$1" = "$2" \ || AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1, requires, contradicts) doxygen-DX_CURRENT_FEATURE]) ]) # DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE) # ---------------------------------------------------------- # Turn off the DX_CURRENT_FEATURE if the required feature is off. AC_DEFUN([DX_CLEAR_DEPEND], [ # Fixing for autoconf 2.59 and above -- TaO090102 test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0) #test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0) ]) # DX_FEATURE_ARG(FEATURE, DESCRIPTION, # CHECK_DEPEND, CLEAR_DEPEND, # REQUIRE, DO-IF-ON, DO-IF-OFF) # -------------------------------------------- # Parse the command-line option controlling a feature. CHECK_DEPEND is called # if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND), # otherwise CLEAR_DEPEND is called to turn off the default state if a required # feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional # requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and # DO-IF-ON or DO-IF-OFF are called according to the final state of the feature. AC_DEFUN([DX_ARG_ABLE], [ AC_DEFUN([DX_CURRENT_FEATURE], [$1]) AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2]) AC_ARG_ENABLE(doxygen-$1, [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1], [--enable-doxygen-$1]), DX_IF_FEATURE([$1], [don't $2], [$2]))], [ case "$enableval" in #( y|Y|yes|Yes|YES) AC_SUBST([DX_FLAG_$1], 1) $3 ;; #( n|N|no|No|NO) AC_SUBST([DX_FLAG_$1], 0) ;; #( *) AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1]) ;; esac ], [ AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)]) $4 ]) if DX_TEST_FEATURE([$1]); then $5 : fi if DX_TEST_FEATURE([$1]); then AM_CONDITIONAL(DX_COND_$1, :) $6 : else AM_CONDITIONAL(DX_COND_$1, false) $7 : fi ]) ## -------------- ## ## Public macros. ## ## -------------- ## # DX_XXX_FEATURE(DEFAULT_STATE) # ----------------------------- AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])]) AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])]) AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])]) AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])]) AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])]) AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])]) AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])]) AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])]) AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])]) # DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR]) # --------------------------------------------------------- # PROJECT also serves as the base name for the documentation files. # The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc". AC_DEFUN([DX_INIT_DOXYGEN], [ # Files: AC_SUBST([DX_PROJECT], [$1]) AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])]) AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])]) # Environment variables used inside doxygen.cfg: DX_ENV_APPEND(SRCDIR, $srcdir) DX_ENV_APPEND(PROJECT, $DX_PROJECT) DX_ENV_APPEND(DOCDIR, $DX_DOCDIR) DX_ENV_APPEND(VERSION, $PACKAGE_VERSION) # Doxygen itself: DX_ARG_ABLE(doc, [generate any doxygen documentation], [], [], [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen) DX_REQUIRE_PROG([DX_PERL], perl)], [DX_ENV_APPEND(PERL_PATH, $DX_PERL)]) # Dot for graphics: DX_ARG_ABLE(dot, [generate graphics for doxygen documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_DOT], dot)], [DX_ENV_APPEND(HAVE_DOT, YES) DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])], [DX_ENV_APPEND(HAVE_DOT, NO)]) # Man pages generation: DX_ARG_ABLE(man, [generate doxygen manual pages], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_MAN, YES)], [DX_ENV_APPEND(GENERATE_MAN, NO)]) # RTF file generation: DX_ARG_ABLE(rtf, [generate doxygen RTF documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_RTF, YES)], [DX_ENV_APPEND(GENERATE_RTF, NO)]) # XML file generation: DX_ARG_ABLE(xml, [generate doxygen XML documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [], [DX_ENV_APPEND(GENERATE_XML, YES)], [DX_ENV_APPEND(GENERATE_XML, NO)]) # (Compressed) HTML help generation: DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_HHC], hhc)], [DX_ENV_APPEND(HHC_PATH, $DX_HHC) DX_ENV_APPEND(GENERATE_HTML, YES) DX_ENV_APPEND(GENERATE_HTMLHELP, YES)], [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)]) # Seperate CHI file generation. DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file], [DX_CHECK_DEPEND(chm, 1)], [DX_CLEAR_DEPEND(chm, 1)], [], [DX_ENV_APPEND(GENERATE_CHI, YES)], [DX_ENV_APPEND(GENERATE_CHI, NO)]) # Plain HTML pages generation: DX_ARG_ABLE(html, [generate doxygen plain HTML documentation], [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)], [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)], [], [DX_ENV_APPEND(GENERATE_HTML, YES)], [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)]) # PostScript file generation: DX_ARG_ABLE(ps, [generate doxygen PostScript documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_LATEX], latex) DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) DX_REQUIRE_PROG([DX_DVIPS], dvips) DX_REQUIRE_PROG([DX_EGREP], egrep)]) # PDF file generation: DX_ARG_ABLE(pdf, [generate doxygen PDF documentation], [DX_CHECK_DEPEND(doc, 1)], [DX_CLEAR_DEPEND(doc, 1)], [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex) DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex) DX_REQUIRE_PROG([DX_EGREP], egrep)]) # LaTeX generation for PS and/or PDF: if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then AM_CONDITIONAL(DX_COND_latex, :) DX_ENV_APPEND(GENERATE_LATEX, YES) else AM_CONDITIONAL(DX_COND_latex, false) DX_ENV_APPEND(GENERATE_LATEX, NO) fi # Paper size for PS and/or PDF: AC_ARG_VAR(DOXYGEN_PAPER_SIZE, [a4wide (default), a4, letter, legal or executive]) case "$DOXYGEN_PAPER_SIZE" in #( "") AC_SUBST(DOXYGEN_PAPER_SIZE, "") ;; #( a4wide|a4|letter|legal|executive) DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE) ;; #( *) AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE']) ;; esac #For debugging: #echo DX_FLAG_doc=$DX_FLAG_doc #echo DX_FLAG_dot=$DX_FLAG_dot #echo DX_FLAG_man=$DX_FLAG_man #echo DX_FLAG_html=$DX_FLAG_html #echo DX_FLAG_chm=$DX_FLAG_chm #echo DX_FLAG_chi=$DX_FLAG_chi #echo DX_FLAG_rtf=$DX_FLAG_rtf #echo DX_FLAG_xml=$DX_FLAG_xml #echo DX_FLAG_pdf=$DX_FLAG_pdf #echo DX_FLAG_ps=$DX_FLAG_ps #echo DX_ENV=$DX_ENV ]) pion-5.0.7+dfsg.orig/build/pion.ico0000644000372000001440000000725612420270445016512 0ustar robertousers(6 ^@@h F( wwwwwwwwwwwwwwwwwwwwwwwwwxwwwwxwwxwxwxwwwxwxwwwwwwwwwwwwwwwwww( @wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxwwwwwwxwxwwwwwwwwwwwxwwwxwwwxwwwwwwwwwwwwwwwwwwwwwxwwwwwwwwxwwwwwwwwxwwwwwwwwxwwwwwwwwxwwwwwwwwxwwwwwwwwwwwxwwwwwwwwwwwxwwwwwxwwwwwxwwwwwwwwwwwwwxwwwwwwwwwxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww(@xxxwxxxxwwxwxwxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxwwxwxwxwxxwwwxxxpion-5.0.7+dfsg.orig/build/doxygen.inc0000644000372000001440000000670712420270445017221 0ustar robertousers## --------------------------------- ## ## Format-independent Doxygen rules. ## ## --------------------------------- ## if DX_COND_doc ## ------------------------------- ## ## Rules specific for HTML output. ## ## ------------------------------- ## if DX_COND_html DX_CLEAN_HTML = @DX_DOCDIR@/html endif DX_COND_html ## ------------------------------ ## ## Rules specific for CHM output. ## ## ------------------------------ ## if DX_COND_chm DX_CLEAN_CHM = @DX_DOCDIR@/chm if DX_COND_chi DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi endif DX_COND_chi endif DX_COND_chm ## ------------------------------ ## ## Rules specific for MAN output. ## ## ------------------------------ ## if DX_COND_man DX_CLEAN_MAN = @DX_DOCDIR@/man endif DX_COND_man ## ------------------------------ ## ## Rules specific for RTF output. ## ## ------------------------------ ## if DX_COND_rtf DX_CLEAN_RTF = @DX_DOCDIR@/rtf endif DX_COND_rtf ## ------------------------------ ## ## Rules specific for XML output. ## ## ------------------------------ ## if DX_COND_xml DX_CLEAN_XML = @DX_DOCDIR@/xml endif DX_COND_xml ## ----------------------------- ## ## Rules specific for PS output. ## ## ----------------------------- ## if DX_COND_ps DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps DX_PS_GOAL = doxygen-ps doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag cd @DX_DOCDIR@/latex; \ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ $(DX_LATEX) refman.tex; \ $(MAKEINDEX_PATH) refman.idx; \ $(DX_LATEX) refman.tex; \ countdown=5; \ while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ refman.log > /dev/null 2>&1 \ && test $$countdown -gt 0; do \ $(DX_LATEX) refman.tex; \ countdown=`expr $$countdown - 1`; \ done; \ $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi endif DX_COND_ps ## ------------------------------ ## ## Rules specific for PDF output. ## ## ------------------------------ ## if DX_COND_pdf DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf DX_PDF_GOAL = doxygen-pdf doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag cd @DX_DOCDIR@/latex; \ rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ $(DX_PDFLATEX) refman.tex; \ $(DX_MAKEINDEX) refman.idx; \ $(DX_PDFLATEX) refman.tex; \ countdown=5; \ while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ refman.log > /dev/null 2>&1 \ && test $$countdown -gt 0; do \ $(DX_PDFLATEX) refman.tex; \ countdown=`expr $$countdown - 1`; \ done; \ mv refman.pdf ../@PACKAGE@.pdf endif DX_COND_pdf ## ------------------------------------------------- ## ## Rules specific for LaTeX (shared for PS and PDF). ## ## ------------------------------------------------- ## if DX_COND_latex DX_CLEAN_LATEX = @DX_DOCDIR@/latex endif DX_COND_latex ## --------------- ## ## Global settings ## ## --------------- ## DX_CLEANFILES = \ @DX_DOCDIR@/@PACKAGE@.tag \ $(DX_CLEAN_HTML) \ $(DX_CLEAN_CHM) \ $(DX_CLEAN_CHI) \ $(DX_CLEAN_MAN) \ $(DX_CLEAN_RTF) \ $(DX_CLEAN_XML) \ $(DX_CLEAN_PS) \ $(DX_CLEAN_PDF) \ $(DX_CLEAN_LATEX) .PHONY: doxygen-run doxygen-doc doxygen-clean $(DX_PS_GOAL) $(DX_PDF_GOAL) .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) @DX_DOCDIR@/@PACKAGE@.tag: $(srcdir)/$(DX_CONFIG) rm -rf $(DX_CLEANFILES) $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) doxygen-clean: rm -rf $(DX_CLEANFILES) endif DX_COND_doc pion-5.0.7+dfsg.orig/build/32_64.diff0000644000372000001440000000322212420270445016425 0ustar robertousersIndex: builtin.jam =================================================================== --- builtin.jam (revision 43575) +++ builtin.jam (working copy) @@ -185,7 +185,7 @@ # The addressing model to generate code for. Currently a limited set only # specifying the bit size of pointers. -feature.feature address-model : 16 32 64 : propagated optional ; +feature.feature address-model : 16 32 64 32_64 : propagated optional ; # Type of CPU architecture to compile for. feature.feature architecture : Index: darwin.jam =================================================================== --- darwin.jam (revision 43575) +++ darwin.jam (working copy) @@ -115,6 +115,10 @@ { feature.set-default macosx-version : 10.4 ; } +if 10.5 in [ feature.values macosx-version ] +{ + feature.set-default macosx-version : 10.5 ; +} # Add the options for all the found SDKs. for local sdk in $(.macosx-sdk) @@ -146,14 +150,18 @@ : $(values) ; } + arch-addr-flags darwin OPTIONS : combined : 32 : -arch i386 -arch ppc : default ; arch-addr-flags darwin OPTIONS : combined : 64 : -arch x86_64 -arch ppc64 ; +arch-addr-flags darwin OPTIONS : combined : 32_64 : -arch i386 -arch ppc -arch x86_64 -arch ppc64 ; arch-addr-flags darwin OPTIONS : x86 : 32 : -arch i386 : default ; arch-addr-flags darwin OPTIONS : x86 : 64 : -arch x86_64 ; +arch-addr-flags darwin OPTIONS : x86 : 32_64 : -arch i386 -arch x86_64 ; arch-addr-flags darwin OPTIONS : power : 32 : -arch ppc : default ; arch-addr-flags darwin OPTIONS : power : 64 : -arch ppc64 ; +arch-addr-flags darwin OPTIONS : power : 32_64 : -arch ppc -arch ppc64 ; flags darwin.link OPTIONS static pion-5.0.7+dfsg.orig/build/ax_boost_base.m40000644000372000001440000001510712420270445020115 0ustar robertousers##### http://autoconf-archive.cryp.to/ax_boost_base.html # # SYNOPSIS # # AX_BOOST_BASE([MINIMUM-VERSION]) # # DESCRIPTION # # Test for the Boost C++ libraries of a particular version (or newer) # # If no path to the installed boost library is given the macro # searchs under /usr, /usr/local, and /opt, and evaluates the # $BOOST_ROOT environment variable. Further documentation is # available at . # # This macro calls: # # AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) # # And sets: # # HAVE_BOOST # # LAST MODIFICATION # # 2007-03-15 # # COPYLEFT # # Copyright (c) 2007 Thomas Porschberg # # Copying and distribution of this file, with or without # modification, are permitted in any medium without royalty provided # the copyright notice and this notice are preserved. AC_DEFUN([AX_BOOST_BASE], [ AC_ARG_WITH([boost], AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]), [ if test "$withval" = "no"; then want_boost="no" elif test "$withval" = "yes"; then want_boost="yes" ac_boost_path="" else want_boost="yes" ac_boost_path="$withval" fi ], [want_boost="yes"]) if test "x$want_boost" = "xyes"; then boost_lib_version_req=ifelse([$1], ,1.20.0,$1) boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` if test "x$boost_lib_version_req_sub_minor" = "x" ; then boost_lib_version_req_sub_minor="0" fi WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) succeeded=no dnl first we check the system location for boost libraries dnl this location ist chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM if test "$ac_boost_path" != ""; then BOOST_HOME_DIR="$ac_boost_path" BOOST_LDFLAGS="-L$ac_boost_path/lib" BOOST_CPPFLAGS="-I$ac_boost_path/include" else for ac_boost_path_tmp in /usr /usr/local /opt ; do if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then BOOST_HOME_DIR="$ac_boost_path_tmp" BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib" BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" break; fi done fi CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS_SAVED="$LDFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes ],[ ]) AC_LANG_POP([C++]) dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version if test "x$succeeded" != "xyes"; then _version=0 if test "$ac_boost_path" != ""; then BOOST_HOME_DIR="$ac_boost_path" BOOST_LDFLAGS="-L$ac_boost_path/lib" if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp fi VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" done fi else for ac_boost_path in /usr /usr/local /opt ; do if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` V_CHECK=`expr $_version_tmp \> $_version` if test "$V_CHECK" = "1" ; then _version=$_version_tmp best_path=$ac_boost_path fi done fi done VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" BOOST_LDFLAGS="-L$best_path/lib" BOOST_HOME_DIR="$best_path" if test "x$BOOST_ROOT" != "x"; then if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` V_CHECK=`expr $stage_version_shorten \>\= $_version` if test "$V_CHECK" = "1" ; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) BOOST_CPPFLAGS="-I$BOOST_ROOT" BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib" fi fi fi fi CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" export CPPFLAGS LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" export LDFLAGS AC_LANG_PUSH(C++) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include ]], [[ #if BOOST_VERSION >= $WANT_BOOST_VERSION // Everything is okay #else # error Boost version is too old #endif ]])],[ AC_MSG_RESULT(yes) succeeded=yes found_system=yes ],[ ]) AC_LANG_POP([C++]) fi if test "$succeeded" != "yes" ; then if test "$_version" = "0" ; then AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) else AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) fi else AC_SUBST(BOOST_HOME_DIR) AC_SUBST(BOOST_CPPFLAGS) AC_SUBST(BOOST_LDFLAGS) AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) fi CPPFLAGS="$CPPFLAGS_SAVED" LDFLAGS="$LDFLAGS_SAVED" fi ]) pion-5.0.7+dfsg.orig/build/common.inc0000644000372000001440000000025412420270445017023 0ustar robertousers# --------------------------------------- # pion-common automake configuration file # --------------------------------------- docs: doxygen-doc clean-docs: doxygen-clean pion-5.0.7+dfsg.orig/build/pion-net.props0000644000372000001440000000072312420270445017657 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 $(PION_NET_HOME)\include;%(AdditionalIncludeDirectories) pion-5.0.7+dfsg.orig/build/winbuild.bat0000644000372000001440000000274312420270445017352 0ustar robertousers@ECHO OFF SET PION_LIBS=C:\Atomic Labs\pion-libraries SETLOCAL EnableDelayedExpansion SET PION_HOME=C:\Atomic Labs\pion-platform SET INCLUDE=%PION_LIBS%\boost-1.37.0;%PION_LIBS%\bzip2-1.0.5\include;%PION_LIBS%\dssl-1.6.8\src;%PION_LIBS%\iconv-1.9.2\include;%PION_LIBS%\libxml2-2.6.30\include;%PION_LIBS%\log4cplus-1.0.3\include;%PION_LIBS%\openssl-0.9.8l\inc32;%PION_LIBS%\sqlapi-3.7.24;%PION_LIBS%\yajl-1.0.5\include;%PION_LIBS%\zlib-1.2.3\include;%PION_LIBS%\WpdPack-4.0.2\Include;%INCLUDE% SET LIB=%PION_LIBS%\boost-1.37.0\lib;%PION_LIBS%\bzip2-1.0.5\lib;%PION_LIBS%\dssl-1.6.8\release;%PION_LIBS%\iconv-1.9.2\lib;%PION_LIBS%\libxml2-2.6.30\lib;%PION_LIBS%\log4cplus-1.0.3\bin;%PION_LIBS%\openssl-0.9.8l\bin;%PION_LIBS%\sqlapi-3.7.24\lib;%PION_LIBS%\yajl-1.0.5\bin;%PION_LIBS%\zlib-1.2.3\lib;%PION_LIBS%\WpdPack-4.0.2\Lib;%LIB% SET PATH=%PION_LIBS%\boost-1.37.0\lib;%PION_LIBS%\bzip2-1.0.5\bin;%PION_LIBS%\iconv-1.9.2\bin;%PION_LIBS%\libxml2-2.6.30\bin;%PION_LIBS%\log4cplus-1.0.3\bin;%PION_LIBS%\openssl-0.9.8l\bin;%PION_LIBS%\sqlapi-3.7.24\bin;%PION_LIBS%\yajl-1.0.5\bin;%PION_LIBS%\zlib-1.2.3\bin;%PION_LIBS%\WpdPack-4.0.2\Bin;%PATH% SET opts=/nologo /platform:Win32 /logcommands /nohtmllog /M1 /useenv SET conf=Release_DLL_full FOR %%I IN (%*) DO (SET opt=%%~I IF "!opt:~0,1!"=="/" SET opts=!opts! %%I IF "!opt!"=="debug" SET conf=Debug_DLL_full IF "!opt!"=="release" SET conf=Release_DLL_full) FOR %%S in (*.sln) DO vcbuild %opts% "/logfile:%%~nS[%conf%].log" %%S "%conf%|Win32" pion-5.0.7+dfsg.orig/build/Release_static_pion.props0000644000372000001440000000125312420270445022101 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 PION_STATIC_LINKING;NDEBUG;PION_FULL;%(PreprocessorDefinitions) MultiThreadedDLL ProgramDatabase pion-5.0.7+dfsg.orig/build/third_party_static_libs_x64.props0000644000372000001440000001021412420270445023534 0ustar robertousers c:\vc12 $(LIB_ROOT)\boost-1.56.0 $(LIB_ROOT)\boost-1.56.0\lib $(LIB_ROOT)\bzip2-1.0.6\include $(LIB_ROOT)\bzip2-1.0.6\lib $(LIB_ROOT)\iconv-1.9.2\include $(LIB_ROOT)\iconv-1.9.2\lib\x64 $(LIB_ROOT)\icu4c-53.1\icu\include $(LIB_ROOT)\icu4c-53.1\icu\lib64 $(LIB_ROOT)\libxml2-2.9.0\include $(LIB_ROOT)\libxml2-2.9.0\lib\x64 $(LIB_ROOT)\log4cplus-1.1.3-rc2\include $(LIB_ROOT)\log4cplus-1.1.3-rc2\bin\x64 $(LIB_ROOT)\apache\apache-log4cxx-0.10.0\src\main\include $(LIB_ROOT)\apache\apache-log4cxx-0.10.0\bin $(LIB_ROOT)\openssl-1.0.1j\inc64 $(LIB_ROOT)\openssl-1.0.1j\lib\x64 $(LIB_ROOT)\zlib-1.2.8\include $(LIB_ROOT)\zlib-1.2.8\lib64 <_ProjectFileVersion>10.0.40219.1 $(BOOST_INC);$(BZIP2_INC);$(ICONV_INC);$(ICU_INC);$(LIBXML_INC);$(LOG4CPLUS_INC);$(LOG4CXX_INC);$(OPENSSL_INC);$(PYTHON_INC);$(YAJL_INC);$(ZLIB_INC);%(AdditionalIncludeDirectories) LOG4CPLUS_STATIC;LOG4CXX_STATIC;U_STATIC_IMPLEMENTATION;LIBXML_STATIC;%(PreprocessorDefinitions) $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_LIB);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(LOG4CXX_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_LIB);%(AdditionalLibraryDirectories) $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_LIB);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_LIB);%(AdditionalLibraryDirectories) $(LIB_ROOT) $(BOOST_INC) $(BOOST_LIB) $(BZIP2_INC) $(BZIP2_LIB) $(ICONV_INC) $(ICONV_LIB) $(ICU_INC) $(ICU_LIB) $(LIBXML_INC) $(LIBXML_LIB) $(LOG4CPLUS_INC) $(LOG4CPLUS_LIB) $(LOG4CXX_INC) $(LOG4CXX_LIB) $(OPENSSL_INC) $(OPENSSL_LIB) $(ZLIB_INC) $(ZLIB_LIB) pion-5.0.7+dfsg.orig/build/mac_switch_gcc.sh0000755000372000001440000000043712420270445020337 0ustar robertousers#!/bin/sh echo Switching to gcc-$1 ln -sf /usr/bin/gcc-$1 /usr/bin/cc ln -sf /usr/bin/gcc-$1 /usr/bin/CC ln -sf /usr/bin/gcc-$1 /usr/bin/gcc ln -sf /usr/bin/cpp-$1 /usr/bin/cpp ln -sf /usr/bin/c++-$1 /usr/bin/c++ ln -sf /usr/bin/g++-$1 /usr/bin/g++ ln -sf /usr/bin/gcov-$1 /usr/bin/gcov pion-5.0.7+dfsg.orig/build/link_log4cxx.sh0000755000372000001440000001021612420270445020003 0ustar robertousers#!/bin/sh cd src/main/cpp g++ -shared -nostdlib /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbeginS.o \ .libs/action.o .libs/appenderattachableimpl.o .libs/appenderskeleton.o .libs/aprinitializer.o .libs/asyncappender.o .libs/basicconfigurator.o \ .libs/bufferedwriter.o .libs/bytearrayinputstream.o .libs/bytearrayoutputstream.o .libs/bytebuffer.o .libs/cacheddateformat.o \ .libs/charsetdecoder.o .libs/charsetencoder.o .libs/class.o .libs/classnamepatternconverter.o .libs/classregistration.o .libs/condition.o \ .libs/configurator.o .libs/consoleappender.o .libs/cyclicbuffer.o .libs/dailyrollingfileappender.o .libs/datagrampacket.o .libs/datagramsocket.o \ .libs/date.o .libs/dateformat.o .libs/datelayout.o .libs/datepatternconverter.o .libs/defaultloggerfactory.o .libs/defaultconfigurator.o \ .libs/defaultrepositoryselector.o .libs/domconfigurator.o .libs/exception.o .libs/fallbackerrorhandler.o .libs/file.o .libs/fileappender.o \ .libs/filedatepatternconverter.o .libs/fileinputstream.o .libs/filelocationpatternconverter.o .libs/fileoutputstream.o .libs/filerenameaction.o \ .libs/filewatchdog.o .libs/filter.o .libs/filterbasedtriggeringpolicy.o .libs/fixedwindowrollingpolicy.o .libs/formattinginfo.o \ .libs/fulllocationpatternconverter.o .libs/gzcompressaction.o .libs/hierarchy.o .libs/htmllayout.o .libs/inetaddress.o .libs/inputstream.o \ .libs/inputstreamreader.o .libs/integer.o .libs/integerpatternconverter.o .libs/layout.o .libs/level.o .libs/levelmatchfilter.o \ .libs/levelrangefilter.o .libs/levelpatternconverter.o .libs/linelocationpatternconverter.o .libs/lineseparatorpatternconverter.o \ .libs/literalpatternconverter.o .libs/loggerpatternconverter.o .libs/loggingeventpatternconverter.o .libs/loader.o .libs/locale.o \ .libs/locationinfo.o .libs/logger.o .libs/loggingevent.o .libs/loglog.o .libs/logmanager.o .libs/logstream.o .libs/manualtriggeringpolicy.o \ .libs/messagebuffer.o .libs/messagepatternconverter.o .libs/methodlocationpatternconverter.o .libs/mdc.o .libs/mutex.o .libs/nameabbreviator.o \ .libs/namepatternconverter.o .libs/ndcpatternconverter.o .libs/ndc.o .libs/nteventlogappender.o .libs/objectimpl.o .libs/objectptr.o \ .libs/objectoutputstream.o .libs/obsoleterollingfileappender.o .libs/odbcappender.o .libs/onlyonceerrorhandler.o .libs/optionconverter.o \ .libs/outputdebugstringappender.o .libs/outputstream.o .libs/outputstreamwriter.o .libs/patternconverter.o .libs/patternlayout.o \ .libs/patternparser.o .libs/pool.o .libs/properties.o .libs/propertiespatternconverter.o .libs/propertyconfigurator.o \ .libs/propertyresourcebundle.o .libs/propertysetter.o .libs/reader.o .libs/relativetimedateformat.o .libs/relativetimepatternconverter.o \ .libs/resourcebundle.o .libs/rollingfileappender.o .libs/rollingpolicy.o .libs/rollingpolicybase.o .libs/rolloverdescription.o .libs/rootlogger.o \ .libs/serversocket.o .libs/simpledateformat.o .libs/simplelayout.o .libs/sizebasedtriggeringpolicy.o .libs/smtpappender.o .libs/socket.o \ .libs/socketappender.o .libs/socketappenderskeleton.o .libs/sockethubappender.o .libs/socketoutputstream.o .libs/strftimedateformat.o \ .libs/stringhelper.o .libs/stringmatchfilter.o .libs/stringtokenizer.o .libs/synchronized.o .libs/syslogappender.o .libs/syslogwriter.o \ .libs/system.o .libs/systemerrwriter.o .libs/systemoutwriter.o .libs/telnetappender.o .libs/threadcxx.o .libs/threadlocal.o \ .libs/threadspecificdata.o .libs/threadpatternconverter.o .libs/throwableinformationpatternconverter.o .libs/timezone.o \ .libs/timebasedrollingpolicy.o .libs/transform.o .libs/triggeringpolicy.o .libs/transcoder.o .libs/ttcclayout.o .libs/writer.o \ .libs/writerappender.o .libs/xmllayout.o .libs/xmlsocketappender.o .libs/zipcompressaction.o /usr/lib64/libaprutil-1.so -lldap -llber -ldb-4.3 \ -lexpat /usr/lib64/libapr-1.so -lpthread -ldl -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64 \ -L/lib/../lib64 -L/usr/lib/../lib64 -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtendS.o \ /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crtn.o -Wl,-soname -Wl,liblog4cxx.so.10 -o .libs/liblog4cxx.so.10.0.0 pion-5.0.7+dfsg.orig/build/winrun.bat0000644000372000001440000000062312420270445017052 0ustar robertousers@ECHO OFF SET PION_LIBS=C:\Atomic Labs\pion-libraries SETLOCAL EnableDelayedExpansion SET PATH=%PION_LIBS%\boost-1.37.0\lib;%PION_LIBS%\bzip2-1.0.5\bin;%PION_LIBS%\iconv-1.9.2\bin;%PION_LIBS%\libxml2-2.6.30\bin;%PION_LIBS%\log4cplus-1.0.3\bin;%PION_LIBS%\openssl-0.9.8l\bin;%PION_LIBS%\sqlapi-3.7.24\bin;%PION_LIBS%\yajl-1.0.5\bin;%PION_LIBS%\zlib-1.2.3\bin;%PION_LIBS%\WpdPack-4.0.2\Bin;%PATH% %* pion-5.0.7+dfsg.orig/build/Debug_static_pion.props0000644000372000001440000000143412420270445021550 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 Disabled PION_STATIC_LINKING;_DEBUG;PION_FULL;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL EditAndContinue pion-5.0.7+dfsg.orig/build/common.pl0000644000372000001440000000351012420270445016663 0ustar robertousers# ------------------------------------------------ # pion-common common perl subroutines used by pion # ------------------------------------------------ use File::Spec; use File::Path; use File::Copy; # ---------------------- # some helpful functions # ---------------------- # recursively copies an entire directory tree, excluding anything that starts with a dot sub copyDirWithoutDotFiles(@) { my $src_dir = shift(); my $dst_dir = shift(); my %templates = @_; # make sure directory exists mkpath($dst_dir); # get list of files in source directory opendir(DIR, $src_dir); my @files = readdir(DIR); closedir(DIR); # iterate through source files foreach (@files) { if ( ! /^\./ ) { my $src_file = File::Spec->catfile($src_dir, $_); my $dst_file = File::Spec->catfile($dst_dir, $_); if (-d $src_file) { copyDirWithoutDotFiles($src_file, $dst_file, %templates); } elsif ( scalar keys %templates == 0 ) { # no templates specified -> just copy the file as-is copy($src_file, $dst_file); } else { # template parameters were specified # process key->value parameters while copying the file # WARNING: this probably only works for text files open(FROMFILE, $src_file) or die "could not open source template ($src_file)"; open(TOFILE, ">", $dst_file) or die "could not open $dst_file for writing"; while ( ) { while ( ($key, $value) = each %templates ) { s,\@$key\@,$value,; } print TOFILE $_; } close(FROMFILE); close(TOFILE); } } } } 1;pion-5.0.7+dfsg.orig/build/ax_compiler_vendor.m40000644000372000001440000000570412420270445021166 0ustar robertousers##### http://autoconf-archive.cryp.to/ax_compiler_vendor.html # # SYNOPSIS # # AX_COMPILER_VENDOR # # DESCRIPTION # # Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, # sun, hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, # microsoft, watcom, etc. The vendor is returned in the cache # variable $ax_cv_c_compiler_vendor for C and # $ax_cv_cxx_compiler_vendor for C++. # # LAST MODIFICATION # # 2005-05-30 # # COPYLEFT # # Copyright (c) 2005 Steven G. Johnson # Copyright (c) 2005 Matteo Frigo # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # # As a special exception, the respective Autoconf Macro's copyright # owner gives unlimited permission to copy, distribute and modify the # configure scripts that are the output of Autoconf when processing # the Macro. You need not follow the terms of the GNU General Public # License when using or distributing such scripts, even though # portions of the text of the Macro appear in them. The GNU General # Public License (GPL) does govern all other use of the material that # constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the # Autoconf Macro released by the Autoconf Macro Archive. When you # make and distribute a modified version of the Autoconf Macro, you # may extend this special exception to the GPL to apply to your # modified version as well. AC_DEFUN([AX_COMPILER_VENDOR], [ AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown # note: don't check for gcc first since some other compilers define __GNUC__ for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")" AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ #if !($vencpp) thisisanerror; #endif ])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break]) done ]) ]) pion-5.0.7+dfsg.orig/build/make_rpm.pl0000644000372000001440000002062412420270445017173 0ustar robertousers#!/usr/bin/perl # -------------------------------------------------- # make_rpm.pl: script for building pion rpm packages # -------------------------------------------------- use Cwd; use File::Spec; use File::Path; use File::Copy; use File::Glob ':glob'; # include perl source with common subroutines require File::Spec->catfile( ("..", "pion-core", "common", "build"), "common.pl"); # ----------------------------------- # process argv & set global variables # ----------------------------------- # check command line parameters die("usage: make_rpm.pl [--nostrip]") if ($#ARGV < 1 || $#ARGV > 2 || ($#ARGV == 2 && $ARGV[2] ne "--nostrip")); # must be run as root die("This script must be run as root!") if $>!=0; # set some global variables $VERSION = $ARGV[0]; $RELEASE = $ARGV[1]; # check for --nostrip option if ($ARGV[2] eq "--nostrip") { $INSTALL_BIN = 'install'; $SPEC_OPTIONS = '%define __os_install_post %{nil}'; } else { $INSTALL_BIN = 'install -s'; $SPEC_OPTIONS = ''; } # check validity of RELEASE parameter die("Second parameter must be format (i.e. \"1.el5\")") if ($RELEASE !~ m/^\d+\..+$/); # find binary directory $BIN_DIR = "bin"; $RPMS_DIR = "/usr/src/redhat/RPMS"; $BUILD_DIR = "/usr/src/redhat/BUILD"; $DIR_GLOB = $BIN_DIR . "/pion-*" . $VERSION; @PACKAGES = bsd_glob( $DIR_GLOB ); die("error: unable to find binary directory") if ($#PACKAGES != 0); $EDITION = $PACKAGE_BASE = $PACKAGE_DIR = $PACKAGES[0]; if ( $PACKAGE_DIR =~ m/.*pion-[a-z]+-.*/ ) { $PACKAGE_BASE =~ s/.*(pion-[a-z]+)-.*/$1/; $EDITION =~ s/.*pion-([a-z]+)-.*/$1/; } else { $PACKAGE_BASE =~ s/.*(pion)-.*/$1/; $EDITION = ""; } $BIN_SRC_BASE = $PACKAGE_BASE . "-" . $VERSION . "-" . $RELEASE; $BIN_SRC_DIR = "$BUILD_DIR/$BIN_SRC_BASE"; $SPEC_FILE_NAME = "/tmp/$BIN_SRC_BASE.spec"; $CONFIG_DIR = File::Spec->catdir( ($PACKAGE_DIR, "config") ); $PLUGINS_DIR = File::Spec->catdir( ($PACKAGE_DIR, "plugins") ); $LIBS_DIR = File::Spec->catdir( ($PACKAGE_DIR, "libs") ); $UI_DIR = File::Spec->catdir( ($PACKAGE_DIR, "ui") ); # ------------ # main process # ------------ die("error: $PACKAGE_DIR is not a directory") if (! -d $PACKAGE_DIR); die("error: $CONFIG_DIR is not a directory") if (! -d $CONFIG_DIR); die("error: $PLUGINS_DIR is not a directory") if (! -d $PLUGINS_DIR); die("error: $LIBS_DIR is not a directory") if (! -d $LIBS_DIR); die("error: $UI_DIR is not a directory") if (! -d $UI_DIR); print "* Building RPM binary package for " . $TARBALL_BASE . "\n"; print "* Generating RPM spec file..\n"; # prepare some vars for spec file if ($EDITION eq "core") { $spec_license = "GPL"; $config_file_glob = "*.{xml,txt,pem}"; $install_perl_scripts = ""; $extra_config_files = ""; } else { $spec_license = "commercial"; $config_file_glob = "*.{xml,txt,pem}"; $install_perl_scripts = "install -m 660 $BIN_SRC_DIR/config/*.pl \$RPM_BUILD_ROOT/var/lib/pion"; $extra_config_files = "\%config /etc/pion/SearchEngines.xml\n\%config(noreplace) /etc/pion/ReplayQueries.xml\n\%config(noreplace) /etc/pion/robots.xml"; } $SPEC_POST="/sbin/ldconfig"; $SPEC_POSTUN="/sbin/ldconfig"; @spec_libs = bsd_glob($LIBS_DIR . "/*"); @purge_scripts = bsd_glob($CONFIG_DIR . "/*.pl"); # open and write the spec file open(SPEC_FILE, ">$SPEC_FILE_NAME") or die("Unable to open spec file: $SPEC_FILE_NAME"); print SPEC_FILE << "END_SPEC_FILE"; Summary: Software for real-time data capture, processing and integration Name: $PACKAGE_BASE Version: $VERSION Release: $RELEASE Vendor: Atomic Labs, Inc. License: $spec_license Group: System Environment/Daemons BuildRoot: /tmp/\%{name}-buildroot \%define debug_package \%{nil} \%description Pion captures millions of events per second from hard to manage sources such as log files, live network traffic and clickstream data. Data is filtered and sorted before being delivered to Pion's visual event processing interface. Events captured by Pion are processed in real-time through Pion's visual event processing interface. Data can easily be filtered, transformed, sessionized and aggregated before being delivered to the data warehouse for storage and future use. Data can be easily loaded into a variety of popular databases, or into an embedded SQLite database for quick access. Connect Pion's data up to your reporting packages and real-time dashboards for up-to-the-minute operational intelligence. \%prep \%build \%pre useradd -r -c "Pion" pion 2> /dev/null || true \%post $SPEC_POST \%postun #userdel pion 2> /dev/null || true $SPEC_POSTUN \%install rm -rf \$RPM_BUILD_ROOT mkdir -p \$RPM_BUILD_ROOT/etc/rc.d/init.d mkdir -p \$RPM_BUILD_ROOT/etc/pion mkdir -p \$RPM_BUILD_ROOT/etc/pion/vocabularies mkdir -p \$RPM_BUILD_ROOT/etc/pion/pymodules mkdir -p \$RPM_BUILD_ROOT/var/log/pion mkdir -p \$RPM_BUILD_ROOT/var/lib/pion mkdir -p \$RPM_BUILD_ROOT/usr/bin mkdir -p \$RPM_BUILD_ROOT/usr/lib mkdir -p \$RPM_BUILD_ROOT/usr/share/pion/ui mkdir -p \$RPM_BUILD_ROOT/usr/share/pion/plugins mkdir -p \$RPM_BUILD_ROOT/usr/share/doc/$PACKAGE_BASE-$VERSION install -m 660 $BIN_SRC_DIR/config/$config_file_glob \$RPM_BUILD_ROOT/etc/pion $install_perl_scripts install -m 660 $BIN_SRC_DIR/config/vocabularies/*.xml \$RPM_BUILD_ROOT/etc/pion/vocabularies install -m 660 $BIN_SRC_DIR/config/pymodules/*.py \$RPM_BUILD_ROOT/etc/pion/pymodules install -m 775 $BIN_SRC_DIR/pion.service \$RPM_BUILD_ROOT/etc/rc.d/init.d/pion $INSTALL_BIN $BIN_SRC_DIR/plugins/* \$RPM_BUILD_ROOT/usr/share/pion/plugins $INSTALL_BIN $BIN_SRC_DIR/libs/* \$RPM_BUILD_ROOT/usr/lib $INSTALL_BIN $BIN_SRC_DIR/pion \$RPM_BUILD_ROOT/usr/bin/pion $INSTALL_BIN $BIN_SRC_DIR/piondb \$RPM_BUILD_ROOT/usr/bin/piondb install $BIN_SRC_DIR/pget.py \$RPM_BUILD_ROOT/usr/bin/pget.py install $BIN_SRC_DIR/pmon.py \$RPM_BUILD_ROOT/usr/bin/pmon.py install $BIN_SRC_DIR/pupgrade.py \$RPM_BUILD_ROOT/usr/bin/pupgrade.py install $BIN_SRC_DIR/httpbl.py \$RPM_BUILD_ROOT/usr/bin/httpbl.py cp -r $BIN_SRC_DIR/ui/* \$RPM_BUILD_ROOT/usr/share/pion/ui cp $BIN_SRC_DIR/*.txt $BIN_SRC_DIR/*.pdf \$RPM_BUILD_DIR \%clean rm -rf \$RPM_BUILD_ROOT %define debug_package %{nil} $SPEC_OPTIONS \%files \%defattr(-,pion,pion) \%dir /etc/pion/ \%config /etc/pion/pymodules \%config /etc/pion/logconfig.txt \%config(noreplace) /etc/pion/codecs.xml \%config(noreplace) /etc/pion/databases.xml \%config(noreplace) /etc/pion/dbengines.xml \%config(noreplace) /etc/pion/platform.xml \%config(noreplace) /etc/pion/protocols.xml \%config(noreplace) /etc/pion/reactors.xml \%config(noreplace) /etc/pion/services.xml \%config(noreplace) /etc/pion/sslkey.pem \%config(noreplace) /etc/pion/users.xml \%config(noreplace) /etc/pion/vocabularies.xml \%config(noreplace) /etc/pion/vocabularies $extra_config_files \%dir /var/lib/pion \%dir /var/log/pion \%defattr(-,root,root) \%doc HISTORY.txt \%doc LICENSE.txt \%doc README.txt \%doc pion-overview.pdf \%doc pion-replay-guide.pdf \%doc pion-setup-wizard.pdf \%defattr(755,root,root) /usr/bin/pion /usr/bin/piondb /usr/bin/pget.py* /usr/bin/pmon.py* /usr/bin/pupgrade.py* /usr/bin/httpbl.py* \%defattr(-,root,root) /usr/share/pion/ui \%defattr(755,root,root) /etc/rc.d/init.d/pion /usr/share/pion/plugins END_SPEC_FILE # output library file names foreach $_ (@spec_libs) { s[$LIBS_DIR][/usr/lib]; print SPEC_FILE $_ . "\n"; } # output purge scripts (if any) foreach $_ (@purge_scripts) { s[$CONFIG_DIR][/var/lib/pion]; print SPEC_FILE $_ . "\n"; } # close the spec file close(SPEC_FILE); print "* Preparing binary source directory..\n"; `rm -rf $BIN_SRC_DIR`; copyDirWithoutDotFiles($PACKAGE_DIR, $BIN_SRC_DIR); if ($EDITION eq "core") { copyDirWithoutDotFiles("platform/build/rpm", $BIN_SRC_DIR); } else { # find the pion-core directory $_ = getcwd(); if (/pion-[^-]+-/) { s,/$,,; s,\\$,,; s,pion-[^-]+-(.*),pion-core-$1,; if (-d $_) { $PION_PLATFORM_DIR = $_; } else { $PION_PLATFORM_DIR = File::Spec->catdir( ("..", "pion-core") ); } } else { $PION_PLATFORM_DIR = File::Spec->catdir( ("..", "pion-core") ); } die("Could not find pion-core directory: $PION_CORE_DIR") if (! -d $PION_PLATFORM_DIR); copyDirWithoutDotFiles($PION_PLATFORM_DIR . "/platform/build/rpm", $BIN_SRC_DIR); copyDirWithoutDotFiles("enterprise/build/rpm", $BIN_SRC_DIR); } print "* Creating RPM files..\n"; `rpmbuild --quiet -bb $SPEC_FILE_NAME`; print "* Cleaning up..\n"; `mv $RPMS_DIR/*/* .`; `rm $SPEC_FILE_NAME`; `rm -rf $BIN_SRC_DIR`; print "* Done.\n"; pion-5.0.7+dfsg.orig/build/pion-config.inc0000644000372000001440000002666112420270445017755 0ustar robertousers# -------------------------------- # Pion autoconf configuration file # -------------------------------- # Set Pion version information PION_LIBRARY_VERSION=`echo $PACKAGE_VERSION | sed 's;^\([[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\).*$;\1;'` # AC_MSG_NOTICE("Pion Library Version: $PION_LIBRARY_VERSION") AC_SUBST(PION_LIBRARY_VERSION) AC_DEFINE_UNQUOTED([PION_VERSION],["$PACKAGE_VERSION"],[Define to the version number of Pion.]) # Note: AM_CONFIG_HEADER is deprecated AC_CONFIG_HEADERS(include/pion/config.hpp) # Check for --with-cygwin AC_MSG_CHECKING([for cygwin directory]) AC_ARG_WITH([cygwin], AC_HELP_STRING([--with-cygwin@<:@=DIR@:>@],[directory where cygwin is installed (Windows only)]), [with_cygwin=$withval], [with_cygwin=maybe]) if test "$with_cygwin" = "maybe"; then case "$build_os" in *cygwin*) PION_CYGWIN_DIRECTORY="c:/cygwin" AC_MSG_RESULT($PION_CYGWIN_DIRECTORY) ;; *) AC_MSG_RESULT(no) ;; esac elif test "$with_cygwin" != "no"; then PION_CYGWIN_DIRECTOR="$with_cygwin" AC_MSG_RESULT($PION_CYGWIN_DIRECTORY) else AC_MSG_RESULT(no) fi AC_DEFINE_UNQUOTED([PION_CYGWIN_DIRECTORY],["$PION_CYGWIN_DIRECTORY"],[Define to the directory where cygwin is installed.]) AC_SUBST(PION_CYGWIN_DIRECTORY) # Check for malloc_trim support AC_MSG_CHECKING(for malloc_trim() support) AC_TRY_LINK([#include ], [ malloc_trim(0); ], [ AC_MSG_RESULT(yes) AC_DEFINE([PION_HAVE_MALLOC_TRIM],[1],[Define to 1 if C library supports malloc_trim()]) ], [ AC_MSG_RESULT(no) ]) # Check for unordered container support AC_CHECK_HEADERS([unordered_map],[unordered_map_type=unordered_map],[]) if test "x$unordered_map_type" = "x"; then AC_CHECK_HEADERS([tr1/unordered_map],[unordered_map_type=tr1_unordered_map],[]) if test "x$unordered_map_type" = "xtr1_unordered_map"; then # test to make sure it's good enough AC_MSG_CHECKING(if unordered_map is ok) AC_TRY_LINK([#include ],[ #if defined(__APPLE__) && (!defined(__apple_build_version__) || __apple_build_version__ < 5000000) #error completely broken on OSX, even for gcc 4.2 #elif !defined(__GNUC__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) return(0); #else #error only use gcc versions 4.1 or greater #endif ], [ AC_MSG_RESULT(ok) ], [ AC_MSG_RESULT(failed) unordered_map_type="" ]) fi fi if test "x$unordered_map_type" = "x"; then AC_CHECK_HEADERS([ext/hash_map],[unordered_map_type=ext_hash_map],[]) fi if test "x$unordered_map_type" = "x"; then AC_CHECK_HEADERS([hash_map],[unordered_map_type=hash_map],[]) fi if test "$unordered_map_type" = "unordered_map"; then AC_DEFINE([PION_HAVE_UNORDERED_MAP],[1],[Define to 1 if you have the header file.]) elif test "$unordered_map_type" = "tr1_unordered_map"; then AC_DEFINE([PION_HAVE_TR1_UNORDERED_MAP],[1],[Define to 1 if you have the header file.]) elif test "$unordered_map_type" = "ext_hash_map"; then AC_DEFINE([PION_HAVE_EXT_HASH_MAP],[1],[Define to 1 if you have the header file.]) elif test "$unordered_map_type" = "hash_map"; then AC_DEFINE([PION_HAVE_HASH_MAP],[1],[Define to 1 if you have the header file.]) else AC_MSG_ERROR([C++ compiler does not seem to support unordered containers]) fi # Check for zlib AC_MSG_CHECKING([for gzip compression support (zlib)]) AC_ARG_WITH([zlib], AC_HELP_STRING([--with-zlib@<:@=DIR@:>@],[location of zlib library (for gzip compression); use --without-zlib to disable]), [ zlib_location=$withval ], [ zlib_location=yes ]) # Check if zlib location is specified if test "x_$zlib_location" != "x_no"; then AC_MSG_RESULT(yes) if test "x_$zlib_location" != "x_yes"; then # alternative location provided CPPFLAGS="$CPPFLAGS -I$zlib_location/include" LDFLAGS="$LDFLAGS -L$zlib_location/lib" fi # Check for zlib headers AC_CHECK_HEADERS([zlib.h],,AC_MSG_ERROR([Unable to find the zlib headers])) # Check for zlib library LIBS="$LIBS_SAVED -lz" AC_MSG_CHECKING(linking with zlib) AC_TRY_LINK([#include ],[ zlibVersion(); return(0); ], [ AC_MSG_RESULT(ok) ], [ AC_MSG_RESULT(failed) AC_MSG_ERROR(Unable to link with the zlib library) ]) LIBS="$LIBS_SAVED" PION_ZLIB="-lz" # Found the zlib library AC_DEFINE([PION_HAVE_ZLIB],[1],[Define to 1 if you have the `zlib' library.]) else # zlib is disabled AC_MSG_RESULT(no) fi AC_SUBST(PION_ZLIB) # Check for bzlib AC_MSG_CHECKING([for bzip2 compression support (bzlib)]) AC_ARG_WITH([bzlib], AC_HELP_STRING([--with-bzlib@<:@=DIR@:>@],[location of bzlib library (for bzip2 compression); use --without-bzlib to disable]), [ bzlib_location=$withval ], [ bzlib_location=yes ]) # Check if bzlib location is specified if test "x_$bzlib_location" != "x_no"; then AC_MSG_RESULT(yes) if test "x_$bzlib_location" != "x_yes"; then # alternative location provided CPPFLAGS="$CPPFLAGS -I$bzlib_location/include" LDFLAGS="$LDFLAGS -L$bzlib_location/lib" fi # Check for bzlib headers AC_CHECK_HEADERS([bzlib.h],,AC_MSG_ERROR([Unable to find the bzlib headers])) # Check for bzlib library LIBS="$LIBS_SAVED -lbz2" AC_MSG_CHECKING(linking with bzlib) AC_TRY_LINK([#include ],[ BZ2_bzlibVersion(); return(0); ], [ AC_MSG_RESULT(ok) ], [ AC_MSG_RESULT(failed) AC_MSG_ERROR(Unable to link with the bzlib library; use --without-bzlib to disable) ]) LIBS="$LIBS_SAVED" PION_BZLIB="-lbz2" # Found the bzlib library AC_DEFINE([PION_HAVE_BZLIB],[1],[Define to 1 if you have the `bzlib' library.]) else # bzlib is disabled AC_MSG_RESULT(no) fi AC_SUBST(PION_BZLIB) # Check for OpenSSL AC_MSG_CHECKING([for SSL support (openssl)]) AC_ARG_WITH([openssl], AC_HELP_STRING([--with-openssl@<:@=DIR@:>@],[location of OpenSSL library (enables SSL support); use --without-openssl to disable]), [ openssl_location=$withval ], [ openssl_location=yes ]) # Check if openssl location is specified if test "x_$openssl_location" != "x_no"; then AC_MSG_RESULT(yes) if test "x_$openssl_location" != "x_yes"; then # alternative location provided CPPFLAGS="$CPPFLAGS -I$openssl_location/include" LDFLAGS="$LDFLAGS -L$openssl_location/lib" fi # Check for OpenSSL headers AC_CHECK_HEADERS([openssl/ssl.h],,AC_MSG_ERROR([Unable to find the OpenSSL headers])) # Check for OpenSSL library LIBS_SAVED="$LIBS" LIBS="-lssl -lcrypto $LIBS_SAVED" AC_MSG_CHECKING(linking with openssl) AC_TRY_LINK([#include ],[ SSL_library_init(); return(0); ], [ AC_MSG_RESULT(ok) ], [ AC_MSG_RESULT(failed) AC_MSG_ERROR(Unable to link with the openssl library; use --without-openssl to disable) ]) LIBS="$LIBS_SAVED" PION_SSL_LIB="-lssl -lcrypto" # Found the OpenSSL library AC_MSG_NOTICE(Building Pion with support for SSL (using OpenSSL)) AC_DEFINE([PION_HAVE_SSL],[1],[Define to 1 if you have the `OpenSSL' library.]) else # SSL is disabled AC_MSG_RESULT(no) fi AC_SUBST(PION_SSL_LIB) # Check for logging support AC_ARG_ENABLE([logging], AC_HELP_STRING([--disable-logging],[disable all logging support (including std::ostream)]), [enable_logging=$enableval], [enable_logging=yes]) AC_ARG_WITH([ostream-logging], AC_HELP_STRING([--with-ostream-logging],[use std::ostream logging instead of library]), [ ostream_logging=yes ], [ ostream_logging=no ]) AC_ARG_WITH([log4cplus], AC_HELP_STRING([--with-log4cplus@<:@=DIR@:>@],[location of log4cplus library (recommended)]), [ log4cplus_location=$withval without_log4cxx=true without_log4cpp=true], []) AC_ARG_WITH([log4cxx], AC_HELP_STRING([--with-log4cxx@<:@=DIR@:>@],[location of log4cxx library]), [ log4cxx_location=$withval without_log4cplus=true without_log4cpp=true], []) AC_ARG_WITH([log4cpp], AC_HELP_STRING([--with-log4cpp@<:@=DIR@:>@],[location of log4cpp library]), [ log4cpp_location=$withval without_log4cplus=true without_log4cxx=true], []) if test "x$enable_logging" == "xno"; then # Display notice if no logging found AC_MSG_NOTICE(Logging has been disabled) AC_DEFINE([PION_DISABLE_LOGGING],[1],[Define to 1 to disable logging.]) elif test "x$ostream_logging" == "xyes"; then AC_MSG_NOTICE(Using std::ostream for logging) AC_DEFINE([PION_USE_OSTREAM_LOGGING],[1],[Define to 1 to use std::cout and std::cerr for logging.]) else # check for an available logging library (log4cplus, then log4cxx, then log4cpp) # log4cplus if test "$without_log4cplus" != "true"; then # Check if log4cplus location is specified if test "x$log4cplus_location" != "xyes" then CPPFLAGS="$CPPFLAGS -I$log4cplus_location/include" LDFLAGS="$LDFLAGS -L$log4cplus_location/lib" fi # Check for log4cplus library LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -llog4cplus" AC_MSG_CHECKING(log4cplus library) AC_TRY_LINK([#include ],[ log4cplus::Logger::getRoot(); return 0; ], [ # Found the log4cplus library AC_MSG_RESULT(ok) AC_DEFINE([PION_USE_LOG4CPLUS],[1],[Define to 1 if you have the `log4cplus' library (-llog4cplus).]) AC_MSG_NOTICE(Using log4cplus for logging) without_log4cxx=true without_log4cpp=true PION_LOG_LIB="-llog4cplus" ], [ AC_MSG_RESULT(no) ]) LIBS="$LIBS_SAVED" fi # log4cxx if test "$without_log4cxx" != "true"; then # Check if log4cxx location is specified if test "x$log4cxx_location" != "xyes" then CPPFLAGS="$CPPFLAGS -I$log4cxx_location/include" LDFLAGS="$LDFLAGS -L$log4cxx_location/lib" fi # Check for log4cxx library LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -llog4cxx" AC_MSG_CHECKING(log4cxx library) AC_TRY_LINK([#include ],[ log4cxx::Logger::getRootLogger(); return 0; ], [ # Found the log4cxx library AC_MSG_RESULT(ok) AC_DEFINE([PION_USE_LOG4CXX],[1],[Define to 1 if you have the `log4cxx' library (-llog4cxx).]) AC_MSG_NOTICE(Using log4cxx for logging) without_log4cplus=true without_log4cpp=true PION_LOG_LIB="-llog4cxx" ], [ AC_MSG_RESULT(no) ]) LIBS="$LIBS_SAVED" fi # log4cpp if test "$without_log4cpp" != "true"; then # Check if log4cpp location is specified if test "x$log4cpp_location" != "xyes" then CPPFLAGS="$CPPFLAGS -I$log4cpp_location/include" LDFLAGS="$LDFLAGS -L$log4cpp_location/lib" fi # Check for log4cpp library LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -llog4cpp" AC_MSG_CHECKING(log4cpp library) AC_TRY_LINK([#include ],[ log4cpp::Category::getRoot(); return 0; ], [ # Found the log4cpp library AC_MSG_RESULT(ok) AC_DEFINE([PION_USE_LOG4CPP],[1],[Define to 1 if you have the `log4cpp' library (-llog4cpp).]) AC_MSG_NOTICE(Using log4cpp for logging) without_log4cplus=true without_log4cxx=true PION_LOG_LIB="-llog4cpp" ], [ AC_MSG_RESULT(no) ]) LIBS="$LIBS_SAVED" fi # no log library found if test "x$PION_LOG_LIB" == "x"; then if test "x$ostream_logging" == "xno"; then AC_MSG_WARN(No logging library found - disabling logging) AC_DEFINE([PION_DISABLE_LOGGING],[1],[Define to 1 to disable logging.]) else AC_MSG_WARN(No logging library found - using std::ostream for logging) AC_DEFINE([PION_USE_OSTREAM_LOGGING],[1],[Define to 1 to use std::cout and std::cerr for logging.]) fi fi fi AC_SUBST(PION_LOG_LIB) # Set external library dependencies PION_EXTERNAL_LIBS="$BOOST_THREAD_LIB $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_REGEX_LIB $BOOST_DATE_TIME_LIB $PION_LOG_LIB $PION_SSL_LIB $PION_ZLIB $PION_BZLIB $PION_EXTERNAL_LIBS" AC_SUBST(PION_EXTERNAL_LIBS) pion-5.0.7+dfsg.orig/build/depth_3_pion-common.props0000644000372000001440000000076012420270445021770 0ustar robertousers ../.. <_ProjectFileVersion>10.0.40219.1 $(PION_COMMON_HOME) pion-5.0.7+dfsg.orig/build/pion-boost.inc0000644000372000001440000001311712420270445017626 0ustar robertousers# -------------------------------- # Pion autoconf configuration file # -------------------------------- # Check for Boost AX_BOOST_BASE([1.35]) # AC_MSG_NOTICE(Boost home directory: $BOOST_HOME_DIR) CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" # Check for Boost library extension AC_MSG_CHECKING([boost library extension]) AC_ARG_WITH([boost-extension], AC_HELP_STRING([--with-boost-extension@<:@=EXT@:>@],[extension used for boost library files]), [ boost_ext=$withval ], [ detect_boost_ext=true ]) # Check if openssl location is specified if test "$detect_boost_ext" != "true"; then # use provided extension for boost library files BOOST_LIB_EXTENSION="$boost_ext" else # Attempt to Autodetect Boost library extension by looking for thread library (i.e. "-gcc41-mt") for boost_thread_library in `ls $BOOST_HOME_DIR/lib*/libboost_thread*-mt*{dylib,dll,so,a}* 2>/dev/null` ; do if test -r $boost_thread_library ; then BOOST_LIB_EXTENSION=`echo $boost_thread_library | sed 's,.*/,,' | sed -e 's;^libboost_thread\(.*\)\.dylib.*$;\1;' -e 's;^libboost_thread\(.*\)\.dll*$;\1;' -e 's;^libboost_thread\(.*\)\.so.*$;\1;' -e 's;^libboost_thread\(.*\)\.a*$;\1;'` break fi done fi if test "x$BOOST_LIB_EXTENSION" = "x"; then AC_MSG_RESULT("(none)") else AC_MSG_RESULT($BOOST_LIB_EXTENSION) fi AC_SUBST(BOOST_LIB_EXTENSION) # Check for Boost Date Time library BOOST_TRY_LIB=date_time BOOST_TRY_LINK="boost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}" LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -l${BOOST_TRY_LINK}" AC_MSG_CHECKING([for boost::${BOOST_TRY_LIB} library]) AC_TRY_LINK([#include ], [ boost::gregorian::date d(2007, 11, 11); return 0; ], [ AC_MSG_RESULT(ok) BOOST_DATE_TIME_LIB="-l${BOOST_TRY_LINK}" ], [ AC_MSG_RESULT(not found) AC_MSG_ERROR(Unable to link with the boost::${BOOST_TRY_LIB} library) ]) LIBS="$LIBS_SAVED" AC_SUBST(BOOST_DATE_TIME_LIB) # Check for Boost System library BOOST_TRY_LIB=system BOOST_TRY_LINK="boost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}" LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -l${BOOST_TRY_LINK}" AC_MSG_CHECKING([for boost::${BOOST_TRY_LIB} library]) AC_TRY_LINK([#include ], [ boost::system::error_code error_code; std::string message(error_code.message()); return 0; ], [ AC_MSG_RESULT(ok) BOOST_SYSTEM_LIB="-l${BOOST_TRY_LINK}" ], [ AC_MSG_RESULT(not found) AC_MSG_ERROR(Unable to link with the boost::${BOOST_TRY_LIB} library) ]) LIBS="$LIBS_SAVED" AC_SUBST(BOOST_SYSTEM_LIB) # Check for Boost Thread library BOOST_TRY_LIB=thread BOOST_TRY_LINK="boost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}" LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -l${BOOST_TRY_LINK} ${BOOST_SYSTEM_LIB} ${BOOST_DATE_TIME_LIB}" AC_MSG_CHECKING([for boost::${BOOST_TRY_LIB} library]) AC_TRY_LINK([#include #include ], [ boost::thread current_thread; return 0; ], [ AC_MSG_RESULT(ok) BOOST_THREAD_LIB="-l${BOOST_TRY_LINK}" ], [ AC_MSG_RESULT(not found) AC_MSG_ERROR(Unable to link with the boost::${BOOST_TRY_LIB} library) ]) LIBS="$LIBS_SAVED" AC_SUBST(BOOST_THREAD_LIB) # Check for Boost Filesystem library BOOST_TRY_LIB=filesystem BOOST_TRY_LINK="boost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}" LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -l${BOOST_TRY_LINK} $BOOST_SYSTEM_LIB" AC_MSG_CHECKING([for boost::${BOOST_TRY_LIB} library]) AC_TRY_LINK([#include ], [ boost::filesystem::path a_path; return 0; ], [ AC_MSG_RESULT(ok) BOOST_FILESYSTEM_LIB="-l${BOOST_TRY_LINK}" ], [ AC_MSG_RESULT(not found) AC_MSG_ERROR(Unable to link with the boost::${BOOST_TRY_LIB} library) ]) LIBS="$LIBS_SAVED" AC_SUBST(BOOST_FILESYSTEM_LIB) # Check for Boost Regex library BOOST_TRY_LIB=regex BOOST_TRY_LINK="boost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}" LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED -l${BOOST_TRY_LINK}" AC_MSG_CHECKING([for boost::${BOOST_TRY_LIB} library]) AC_TRY_LINK([#include ], [ boost::regex exp(".*"); return 0; ], [ AC_MSG_RESULT(ok) BOOST_REGEX_LIB="-l${BOOST_TRY_LINK}" ], [ AC_MSG_RESULT(not found) AC_MSG_ERROR(Unable to link with the boost::${BOOST_TRY_LIB} library) ]) LIBS="$LIBS_SAVED" AC_SUBST(BOOST_REGEX_LIB) # Check for Boost Unit Test Framework AC_ARG_ENABLE([tests], AC_HELP_STRING([--disable-tests],[do not build and run the unit tests]), [enable_tests=$enableval], [enable_tests=yes]) if test "x$enable_tests" == "xno"; then # Display notice if unit tests are disabled AC_MSG_NOTICE([Unit tests are disabled]) else BOOST_TRY_LIB=unit_test_framework BOOST_TRY_LINK="$BOOST_HOME_DIR/lib/libboost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}.a" # check if static version of lib is available if !(test -r "$BOOST_TRY_LINK"); then BOOST_TRY_LINK="-lboost_${BOOST_TRY_LIB}${BOOST_LIB_EXTENSION}" PION_TESTS_CPPFLAGS="-DBOOST_TEST_DYN_LINK" fi LIBS_SAVED="$LIBS" LIBS="$LIBS_SAVED ${BOOST_TRY_LINK}" CPPFLAGS_SAVED="$CPPFLAGS" CPPFLAGS="$CPPFLAGS ${PION_TESTS_CPPFLAGS}" AC_MSG_CHECKING([for boost::test library]) AC_TRY_LINK([#include using namespace boost::unit_test; test_suite* init_unit_test_suite( int argc, char* argv[] ) { return BOOST_TEST_SUITE("Master test suite"); }], [], [ AC_MSG_RESULT(ok) BOOST_TEST_LIB="${BOOST_TRY_LINK}" ], [ AC_MSG_RESULT(not found) AC_MSG_ERROR(Unable to link with the boost::${BOOST_TRY_LIB} library) ]) LIBS="$LIBS_SAVED" CPPFLAGS="$CPPFLAGS_SAVED" PION_TESTS_MAKEDIRS="tests" fi AC_SUBST(BOOST_TEST_LIB) AC_SUBST(PION_TESTS_MAKEDIRS) AC_SUBST(PION_TESTS_CPPFLAGS) pion-5.0.7+dfsg.orig/build/pion_plugin.props0000644000372000001440000000063412420270445020452 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 $(Configuration)_$(PlatformName)\ pion-5.0.7+dfsg.orig/build/Release_DLL_pion.props0000644000372000001440000000167312420270445021233 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 false /GL %(AdditionalOptions) BOOST_ALL_DYN_LINK;NDEBUG;%(PreprocessorDefinitions) MultiThreadedDLL ProgramDatabase true UseLinkTimeCodeGeneration pion-5.0.7+dfsg.orig/build/pion.props0000644000372000001440000000232112420270445017067 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)bin\$(Configuration)_$(PlatformName)\ $(SolutionDir)IntermediateOutput\$(ProjectName)\$(Configuration)_$(PlatformName)\ $(PION_COMMON_HOME)\include;%(AdditionalIncludeDirectories) _WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;_WIN32_WINNT=0x0500;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) true Level3 4267;4311;4312;4250;4251;4275;4503;%(DisableSpecificWarnings) Windows MachineX86 pion-5.0.7+dfsg.orig/build/third_party_static_libs_win32.props0000644000372000001440000001127012420270445024060 0ustar robertousers C:\boost\include\boost-1_51 C:\boost\lib C:\bzip2-1.0.6\include C:\bzip2-1.0.6\lib C:\iconv-1.9.2\include C:\iconv-1.9.2\lib C:\icu4c-49_1_2\icu\include C:\icu4c-49_1_2\icu\lib C:\libxml2-2.9.0\include C:\libxml2-2.9.0\lib C:\log4cplus-1.0.4.1\include C:\log4cplus-1.0.4.1\bin C:\apache\apache-log4cxx-0.10.0\src\main\include C:\apache\apache-log4cxx-0.10.0\bin C:\openssl-1.0.1j\inc32 C:\openssl-1.0.1j\lib C:\Python26\include C:\Python26\libs C:\yajl-2.0.5\include C:\yajl-2.0.5\bin C:\zlib-1.2.7\include C:\zlib-1.2.7\lib C:\sqlite-3.7.14.1\ C:\sqlite-3.7.14.1\lib\ <_ProjectFileVersion>10.0.40219.1 $(BOOST_INC);$(BZIP2_INC);$(ICONV_INC);$(ICU_INC);$(LIBXML_INC);$(LOG4CPLUS_INC);$(LOG4CXX_INC);$(OPENSSL_INC);$(PYTHON_INC);$(YAJL_INC);$(ZLIB_INC);$(SQLITE_INC);%(AdditionalIncludeDirectories) LOG4CPLUS_STATIC;LOG4CXX_STATIC;U_STATIC_IMPLEMENTATION;LIBXML_STATIC;%(PreprocessorDefinitions) $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_LIB);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(LOG4CXX_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_LIB);%(AdditionalLibraryDirectories) $(BOOST_LIB);$(BZIP2_LIB);$(ICONV_LIB);$(ICU_LIB);$(LIBXML_LIB);$(LOG4CPLUS_LIB);$(OPENSSL_LIB);$(PYTHON_LIB);$(YAJL_LIB);$(ZLIB_LIB);$(SQLITE_LIB);%(AdditionalLibraryDirectories) $(BOOST_INC) $(BOOST_LIB) $(BZIP2_INC) $(BZIP2_LIB) $(ICONV_INC) $(ICONV_LIB) $(ICU_INC) $(ICU_LIB) $(LIBXML_INC) $(LIBXML_LIB) $(LOG4CPLUS_INC) $(LOG4CPLUS_LIB) $(LOG4CXX_INC) $(LOG4CXX_LIB) $(OPENSSL_INC) $(OPENSSL_LIB) $(PYTHON_INC) $(PYTHON_LIB) $(YAJL_INC) $(YAJL_LIB) $(ZLIB_INC) $(ZLIB_LIB) $(SQLITE_INC) $(SQLITE_LIB) pion-5.0.7+dfsg.orig/build/depth_2_pion-net.props0000644000372000001440000000133612420270445021265 0ustar robertousers ..\..\common .. <_ProjectFileVersion>10.0.40219.1 $(PION_COMMON_HOME) $(PION_NET_HOME) pion-5.0.7+dfsg.orig/build/Debug_DLL_pion.props0000644000372000001440000000151512420270445020674 0ustar robertousers <_ProjectFileVersion>10.0.40219.1 true Disabled BOOST_ALL_DYN_LINK;_DEBUG;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true pion-5.0.7+dfsg.orig/AUTHORS0000644000372000001440000000106012420270445015005 0ustar robertousersAuthors of the Pion Network Library: ==================================== Mignon Belongie Michael Dickey Stas Khirman Andrew C. Morrow Taneli Otala Parts of the Pion Network Library were derived from or inspired by the HTTP Server example in the asio documentation. Many thanks to Christopher M. Kohlhoff and all the contributors of Boost and asio, without whom this library would not have been possible. pion-5.0.7+dfsg.orig/cmake/0000755000372000001440000000000012420270445015020 5ustar robertouserspion-5.0.7+dfsg.orig/cmake/testservices.conf.cmake0000644000372000001440000000245312420270445021475 0ustar robertousers## ## Simple configuration file to test pion-net web services ## ## Adds path to compiled web services built from source tarball ## path @PION_PLUGIN_PATH@ ## Hello World Service ## service /hello HelloService ## Service to echo requests ## service /echo EchoService ## Service to display & update cookies ## service /cookie CookieService ## Service to display log events ## service /log LogService ## Service to serve sample pion-net documentation ## service /doc FileService option /doc directory=@PION_SRC_ROOT@/tests/doc/html option /doc file=@PION_SRC_ROOT@/tests/doc/html/index.html option /doc cache=2 option /doc scan=3 ## Use testservices.html as an index page ## service /index.html FileService option /index.html file=@PION_SRC_ROOT@/utils/testservices.html ## service / FileService option / file=@PION_SRC_ROOT@/utils/testservices.html ## Service to demonstrate Authentication interface ## service /auth EchoService ## ## define type of authentication ## ## MUST be a first command in configuration file ## auth type can be defined once and only once! ## auth cookie ## ## Add /auth resource to set of password protected ## restrict /auth ## ## Add /protected resource to set of password protected ## restrict /protected ## ## define user ## user stas 123456 ## ## define user ## user mike 123456 pion-5.0.7+dfsg.orig/cmake/FindLog4cplus.cmake0000644000372000001440000001127212420270445020502 0ustar robertousers#------------------------------------------------------------------------------------- # Locate Log4cplus library # This module defines # LOG4CPLUS_FOUND, if false, do not try to link to Log4cplus # LOG4CPLUS_LIBRARIES # LOG4CPLUS_INCLUDE_DIR, where to find log4cplus.hppa # # Original script was picked up here # https://github.com/manvelavetisian/cmake-modules/blob/master/FindLog4cplus.cmake # # 2013 - snikulov # And modified # Additional params which can be set to search for libs # Log4Cplus_USE_STATIC_LIBS # Log4Cplus_USE_UNICODE # Location hint can be provided through # environment var LOG4CPLUS_ROOT in addition to LOG4CPLUS_DIR # cmake vars LOG4CPLUS_DIR & LOG4CPLUS_ROOT # #------------------------------------------------------------------------------------- # get version macro # first param - path to include macro(log4cplus_get_version _include_PATH vmajor vminor vpatch) file(STRINGS "${_include_PATH}/log4cplus/version.h" _log4cplus_VER_STRING_AUX REGEX ".*#define[ ]+LOG4CPLUS_VERSION[ ]+") string(REGEX MATCHALL "[0-9]+" _log4clpus_VER_LIST "${_log4cplus_VER_STRING_AUX}") list(LENGTH _log4clpus_VER_LIST _log4cplus_VER_LIST_LEN) # we also count '4' from the name... if(_log4cplus_VER_LIST_LEN EQUAL 5) list(GET _log4clpus_VER_LIST 2 ${vmajor}) list(GET _log4clpus_VER_LIST 3 ${vminor}) list(GET _log4clpus_VER_LIST 4 ${vpatch}) endif() endmacro() find_path(LOG4CPLUS_INCLUDE_DIR NAMES logger.h version.h PATH_PREFIXES log4cplus PATHS /usr/local/include /usr/include /opt/local/include /opt/csw/include /opt/include $ENV{LOG4CPLUS_DIR}/include $ENV{LOG4CPLUS_ROOT}/include ${LOG4CPLUS_DIR}/include ${LOG4CPLUS_ROOT}/include NO_DEFAULT_PATH ) if(Log4Cplus_USE_STATIC_LIBS) set(log4cplus_postfix "${log4cplus_postfix}S") endif() if(Log4Cplus_USE_UNICODE) set(log4cplus_postfix "${log4cplus_postfix}U") endif() set(LOG4CPLUS_LIB_NAMES_RELEASE "log4cplus${log4cplus_postfix}") set(LOG4CPLUS_LIB_NAMES_DEBUG "log4cplus${log4cplus_postfix}D") find_library(LOG4CPLUS_LIBRARY_RELEASE NAMES ${LOG4CPLUS_LIB_NAMES_RELEASE} PATHS /usr/local /usr /sw /opt/local /opt/csw /opt $ENV{LOG4CPLUS_DIR}/lib ${LOG4CPLUS_DIR}/lib $ENV{LOG4CPLUS_ROOT}/lib ${LOG4CPLUS_ROOT}/lib NO_DEFAULT_PATH ) find_library(LOG4CPLUS_LIBRARY_DEBUG NAMES ${LOG4CPLUS_LIB_NAMES_DEBUG} PATHS /usr/local /usr /sw /opt/local /opt/csw /opt $ENV{LOG4CPLUS_DIR}/lib ${LOG4CPLUS_DIR}/lib $ENV{LOG4CPLUS_ROOT}/lib ${LOG4CPLUS_ROOT}/lib NO_DEFAULT_PATH ) if(LOG4CPLUS_INCLUDE_DIR) log4cplus_get_version( ${LOG4CPLUS_INCLUDE_DIR} LOG4CPLUS_VER_MAJOR LOG4CPLUS_VER_MINOR LOG4CPLUS_VER_PATCH) endif() if(LOG4CPLUS_LIBRARY_DEBUG AND LOG4CPLUS_LIBRARY_RELEASE) set(LOG4CPLUS_LIBRARIES debug ${LOG4CPLUS_LIBRARY_DEBUG} optimized ${LOG4CPLUS_LIBRARY_RELEASE} CACHE STRING "Log4cplus Libraries") endif() include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LOG4CPLUS_FOUND to TRUE if # all listed variables are TRUE FIND_PACKAGE_HANDLE_STANDARD_ARGS(Log4cplus DEFAULT_MSG LOG4CPLUS_LIBRARIES LOG4CPLUS_INCLUDE_DIR) MARK_AS_ADVANCED(LOG4CPLUS_INCLUDE_DIR LOG4CPLUS_LIBRARIES LOG4CPLUS_LIBRARY_DEBUG LOG4CPLUS_LIBRARY_RELEASE LOG4CPLUS_VER_MAJOR LOG4CPLUS_VER_MINOR LOG4CPLUS_VER_PATCH) if(LOG4CPLUS_FOUND) message("-- Log4cplus version is: ${LOG4CPLUS_VER_MAJOR}.${LOG4CPLUS_VER_MINOR}.${LOG4CPLUS_VER_PATCH}") # if we found the log4cplus - and using dll's # short hack for install and copy if(NOT Log4Cplus_USE_STATIC_LIBS AND CMAKE_SYSTEM_NAME STREQUAL "Windows") find_file(LOG4CPLUS_DLL_RELEASE NAMES ${LOG4CPLUS_LIB_NAMES_RELEASE}.dll PATHS $ENV{LOG4CPLUS_DIR}/bin ${LOG4CPLUS_DIR}/bin $ENV{LOG4CPLUS_ROOT}/bin ${LOG4CPLUS_ROOT}/bin NO_DEFAULT_PATH ) find_file(LOG4CPLUS_DLL_DEBUG NAMES ${LOG4CPLUS_LIB_NAMES_DEBUG}.dll PATHS $ENV{LOG4CPLUS_DIR}/bin ${LOG4CPLUS_DIR}/bin $ENV{LOG4CPLUS_ROOT}/bin ${LOG4CPLUS_ROOT}/bin NO_DEFAULT_PATH ) get_filename_component(LOG4CPLUS_RUNTIME_DIR ${LOG4CPLUS_DLL_DEBUG} PATH) MARK_AS_ADVANCED(LOG4CPLUS_DLL_DEBUG LOG4CPLUS_DLL_RELEASE LOG4CPLUS_RUNTIME_DIR) endif() endif() pion-5.0.7+dfsg.orig/cmake/GenTestInclude.cmake0000644000372000001440000000032112420270445020673 0ustar robertousersconfigure_file(${PION_SRC_ROOT}/cmake/plugin_path.inc.cmake ${PION_PLUGIN_PATH}/plugin_path.hpp @ONLY) configure_file(${PION_SRC_ROOT}/cmake/testservices.conf.cmake ${PION_PLUGIN_PATH}/testservices.conf @ONLY)pion-5.0.7+dfsg.orig/cmake/PionConfigure.cmake0000644000372000001440000000210212420270445020564 0ustar robertousers# --------------------------------------------------------------------- # pion: a Boost C++ framework for building lightweight HTTP interfaces # --------------------------------------------------------------------- # Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) # # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt # --------------------------------------------------------------------- include(CheckIncludeFile) include(CheckIncludeFileCXX) include(CheckFunctionExists) include(CheckLibraryExists) include(CheckSymbolExists) include(CheckTypeSize) include(CheckCSourceCompiles) include(CheckCXXSourceCompiles) # check for required includes CHECK_INCLUDE_FILE_CXX("unordered_map" PION_HAVE_UNORDERED_MAP) if(NOT PION_HAVE_UNORDERED_MAP) CHECK_INCLUDE_FILE_CXX("ext/hash_map" PION_HAVE_EXT_HASH_MAP) if(NOT PION_HAVE_EXT_HASH_MAP) CHECK_INCLUDE_FILE_CXX("hash_map" PION_HAVE_HASH_MAP) endif() endif() # check for required functions check_function_exists(malloc_trim PION_HAVE_MALLOC_TRIM) pion-5.0.7+dfsg.orig/cmake/PionUtils.cmake0000644000372000001440000000362312420270445017754 0ustar robertousers# --------------------------------------------------------------------- # pion: a Boost C++ framework for building lightweight HTTP interfaces # --------------------------------------------------------------------- # Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) # # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt # --------------------------------------------------------------------- macro(pion_get_version _config_ac_PATH vmajor vminor vpatch) file(STRINGS "${_config_ac_PATH}/configure.ac" _pion_VER_STRING_AUX REGEX "^AC_INIT") # message("_pion_VER_STRING_AUX = ${_pion_VER_STRING_AUX}") string(REGEX MATCH "[0-9]+[.][0-9]+[.][0-9]+" _pion_VER_STR ${_pion_VER_STRING_AUX}) # message("_pion_VER_STR = ${_pion_VER_STR}") string(REGEX MATCHALL "[0-9]+" _pion_VER_LIST ${_pion_VER_STR}) # message("_pion_VER_LIST = ${_pion_VER_LIST}") list(GET _pion_VER_LIST 0 ${vmajor}) list(GET _pion_VER_LIST 1 ${vminor}) list(GET _pion_VER_LIST 2 ${vpatch}) endmacro() macro(pion_update_compilation_opts) # Make VC compiler more verbose if(MSVC) foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) if(${flag_var} MATCHES "/W[0-3]") string(REGEX REPLACE "/W[0-3]" "/W4" ${flag_var} "${${flag_var}}") endif() endforeach(flag_var) add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_DEPRECATE) endif() if(CMAKE_COMPILER_IS_GNUCXX) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -W") endif() message("CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}") endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -W") endif() endmacro() pion-5.0.7+dfsg.orig/cmake/config.hpp.cmake0000644000372000001440000000721212420270445020057 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #ifndef __PION_PIONCONFIG_HEADER__ #define __PION_PIONCONFIG_HEADER__ #cmakedefine PION_HAVE_SSL ${PION_HAVE_SSL} #cmakedefine PION_HAVE_JSON ${PION_HAVE_JSON} #cmakedefine PION_HAVE_PYTHON ${PION_HAVE_PYTHON} /* Define to the version number of pion. */ #cmakedefine PION_VERSION "${PION_VERSION}" /* Define to the directory where Pion plug-ins are installed. */ //#undef PION_PLUGINS_DIRECTORY #define PION_PLUGINS_DIRECTORY "." /* Define to 1 if C library supports malloc_trim() */ #cmakedefine PION_HAVE_MALLOC_TRIM ${PION_HAVE_MALLOC_TRIM} // ----------------------------------------------------------------------- // hash_map support // // At least one of the following options should be defined. /* Define to 1 if you have the header file. */ #cmakedefine PION_HAVE_EXT_HASH_MAP ${PION_HAVE_EXT_HASH_MAP} /* Define to 1 if you have the header file. */ #cmakedefine PION_HAVE_HASH_MAP ${PION_HAVE_HASH_MAP} /* Define to 1 if you have the header file. */ #cmakedefine PION_HAVE_UNORDERED_MAP ${PION_HAVE_UNORDERED_MAP} // ----------------------------------------------------------------------- // Logging Options // // At most one of the logging options below should be defined. If none of // them are defined, std::cout and std::cerr will be used for logging. /* To use the `log4cplus' library for logging, include PION_USE_LOG4CPLUS or PION_FULL in Preprocessor Definitions, or uncomment the following line. */ #cmakedefine PION_USE_LOG4CPLUS ${PION_USE_LOG4CPLUS} /* To use the `log4cxx' library for logging, include PION_USE_LOG4CXX in Preprocessor Definitions, or uncomment the following line. */ #cmakedefine PION_USE_LOG4CXX ${PION_USE_LOG4CXX} /* To use the `log4cpp' library for logging, include PION_USE_LOG4CPP in Preprocessor Definitions, or uncomment the following line. */ #cmakedefine PION_USE_LOG4CPP ${PION_USE_LOG4CPP} /* To disable logging, include PION_DISABLE_LOGGING in Preprocessor Definitions, or uncomment the following line. */ #cmakedefine PION_DISABLE_LOGGING ${PION_DISABLE_LOGGING} // ----------------------------------------------------------------------- /* Define to 1 if you have the `zlib' library. */ #cmakedefine PION_HAVE_ZLIB ${PION_HAVE_ZLIB} /* Define to 1 if you have the `bzlib' library. */ #cmakedefine PION_HAVE_BZLIB ${PION_HAVE_BZLIB} #if defined(_WIN32) || defined(_WINDOWS) #define PION_WIN32 1 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif #endif // _WIN32 #include #ifdef _MSC_VER #ifdef PION_EXPORTS #define PION_API __declspec(dllexport) #elif defined PION_STATIC_LINKING #define PION_API #else #define PION_API __declspec(dllimport) #endif #ifdef PION_STATIC_LINKING #define PION_PLUGIN #else #define PION_PLUGIN __declspec(dllexport) #endif /* Verify correctness of the PION_STATIC_LINKING setup */ #ifdef PION_STATIC_LINKING #ifdef _USRDLL #error Need to be compiled as a static library for PION_STATIC_LINKING #endif #endif #else /* This is used by Windows projects to flag exported symbols */ #define PION_API #define PION_PLUGIN #endif // _MSC_VER #endif //__PION_PIONCONFIG_HEADER__ pion-5.0.7+dfsg.orig/cmake/plugin_path.inc.cmake0000644000372000001440000000034212420270445021103 0ustar robertousersstatic const std::string PATH_TO_PLUGINS("@PION_PLUGIN_PATH@"); static const std::string SSL_PEM_FILE("@PION_SRC_ROOT@/utils/sslkey.pem"); static const std::string SERVICES_CONFIG_FILE("@PION_PLUGIN_PATH@/testservices.conf"); pion-5.0.7+dfsg.orig/utils/0000755000372000001440000000000012420270445015100 5ustar robertouserspion-5.0.7+dfsg.orig/utils/piond.vcxproj.filters0000644000372000001440000000200712420270445021274 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files pion-5.0.7+dfsg.orig/utils/testservices.conf0000644000372000001440000000236512420270445020500 0ustar robertousers## ## Simple configuration file to test pion-net web services ## ## Adds path to compiled web services built from source tarball ## path ../services/.libs path ../bin/Debug ## Hello World Service ## service /hello HelloService ## Service to echo requests ## service /echo EchoService ## Service to display & update cookies ## service /cookie CookieService ## Service to display log events ## service /log LogService ## Service to serve pion-net documentation ## service /doc FileService option /doc directory=../doc/html option /doc file=../doc/html/index.html option /doc cache=2 option /doc scan=3 ## Use testservices.html as an index page ## service /index.html FileService option /index.html file=../utils/testservices.html ## service / FileService option / file=../utils/testservices.html ## Service to demonstrate Authentication interface ## service /auth EchoService ## ## define type of authentication ## ## MUST be a first command in configuration file ## auth type can be defined once and only once! ## auth cookie ## ## Add /auth resource to set of password protected ## restrict /auth ## ## Add /protected resource to set of password protected ## restrict /protected ## ## define user ## user stas 123456 ## ## define user ## user mike 123456 pion-5.0.7+dfsg.orig/utils/piond.cpp0000644000372000001440000001574612420270445016732 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include // these are used only when linking to static web service libraries // #ifdef PION_STATIC_LINKING PION_DECLARE_PLUGIN(EchoService) PION_DECLARE_PLUGIN(FileService) PION_DECLARE_PLUGIN(HelloService) PION_DECLARE_PLUGIN(LogService) PION_DECLARE_PLUGIN(CookieService) using namespace std; using namespace pion; /// displays an error message if the arguments are invalid void argument_error(void) { std::cerr << "usage: piond [OPTIONS] RESOURCE WEBSERVICE" << std::endl << " piond [OPTIONS] -c SERVICE_CONFIG_FILE" << std::endl << "options: [-ssl PEM_FILE] [-i IP] [-p PORT] [-d PLUGINS_DIR] [-o OPTION=VALUE] [-v]" << std::endl; } /// main control function int main (int argc, char *argv[]) { static const unsigned int DEFAULT_PORT = 8080; // used to keep track of web service name=value options typedef std::vector > ServiceOptionsType; ServiceOptionsType service_options; // parse command line: determine port number, RESOURCE and WEBSERVICE boost::asio::ip::tcp::endpoint cfg_endpoint(boost::asio::ip::tcp::v4(), DEFAULT_PORT); std::string service_config_file; std::string resource_name; std::string service_name; std::string ssl_pem_file; bool ssl_flag = false; bool verbose_flag = false; for (int argnum=1; argnum < argc; ++argnum) { if (argv[argnum][0] == '-') { if (argv[argnum][1] == 'p' && argv[argnum][2] == '\0' && argnum+1 < argc) { // set port number ++argnum; cfg_endpoint.port(strtoul(argv[argnum], 0, 10)); if (cfg_endpoint.port() == 0) cfg_endpoint.port(DEFAULT_PORT); } else if (argv[argnum][1] == 'i' && argv[argnum][2] == '\0' && argnum+1 < argc) { // set ip address cfg_endpoint.address(boost::asio::ip::address::from_string(argv[++argnum])); } else if (argv[argnum][1] == 'c' && argv[argnum][2] == '\0' && argnum+1 < argc) { service_config_file = argv[++argnum]; } else if (argv[argnum][1] == 'd' && argv[argnum][2] == '\0' && argnum+1 < argc) { // add the service plug-ins directory to the search path try { plugin::add_plugin_directory(argv[++argnum]); } catch (error::directory_not_found&) { std::cerr << "piond: Web service plug-ins directory does not exist: " << argv[argnum] << std::endl; return 1; } } else if (argv[argnum][1] == 'o' && argv[argnum][2] == '\0' && argnum+1 < argc) { std::string option_name(argv[++argnum]); std::string::size_type pos = option_name.find('='); if (pos == std::string::npos) { argument_error(); return 1; } std::string option_value(option_name, pos + 1); option_name.resize(pos); service_options.push_back( std::make_pair(option_name, option_value) ); } else if (argv[argnum][1] == 's' && argv[argnum][2] == 's' && argv[argnum][3] == 'l' && argv[argnum][4] == '\0' && argnum+1 < argc) { ssl_flag = true; ssl_pem_file = argv[++argnum]; } else if (argv[argnum][1] == 'v' && argv[argnum][2] == '\0') { verbose_flag = true; } else { argument_error(); return 1; } } else if (argnum+2 == argc) { // second to last argument = RESOURCE resource_name = argv[argnum]; } else if (argnum+1 == argc) { // last argument = WEBSERVICE service_name = argv[argnum]; } else { argument_error(); return 1; } } if (service_config_file.empty() && (resource_name.empty() || service_name.empty())) { argument_error(); return 1; } // initialize signal handlers, etc. process::initialize(); // initialize log system (use simple configuration) logger main_log(PION_GET_LOGGER("piond")); logger pion_log(PION_GET_LOGGER("pion")); if (verbose_flag) { PION_LOG_SETLEVEL_DEBUG(main_log); PION_LOG_SETLEVEL_DEBUG(pion_log); } else { PION_LOG_SETLEVEL_INFO(main_log); PION_LOG_SETLEVEL_INFO(pion_log); } PION_LOG_CONFIG_BASIC; try { // add the Pion plug-ins installation directory to our path try { plugin::add_plugin_directory(PION_PLUGINS_DIRECTORY); } catch (error::directory_not_found&) { PION_LOG_WARN(main_log, "Default plug-ins directory does not exist: " << PION_PLUGINS_DIRECTORY); } // add the directory of the program we're running to our path try { plugin::add_plugin_directory(boost::filesystem::path(argv[0]).branch_path().string()); } catch (error::directory_not_found&) { PION_LOG_WARN(main_log, "Directory of current executable does not exist: " << boost::filesystem::path(argv[0]).branch_path()); } // create a server for HTTP & add the Hello Service http::plugin_server web_server(cfg_endpoint); if (ssl_flag) { #ifdef PION_HAVE_SSL // configure server for SSL web_server.set_ssl_key_file(ssl_pem_file); PION_LOG_INFO(main_log, "SSL support enabled using key file: " << ssl_pem_file); #else PION_LOG_ERROR(main_log, "SSL support is not enabled"); #endif } if (service_config_file.empty()) { // load a single web service using the command line arguments web_server.load_service(resource_name, service_name); // set web service options if any are defined for (ServiceOptionsType::iterator i = service_options.begin(); i != service_options.end(); ++i) { web_server.set_service_option(resource_name, i->first, i->second); } } else { // load services using the configuration file web_server.load_service_config(service_config_file); } // startup the server web_server.start(); process::wait_for_shutdown(); } catch (std::exception& e) { PION_LOG_FATAL(main_log, pion::diagnostic_information(e)); } return 0; } pion-5.0.7+dfsg.orig/utils/testservices.html0000644000372000001440000000132412420270445020511 0ustar robertousers Test Website

Test Website


Demonstration of Authentication interface

pion-5.0.7+dfsg.orig/utils/CMakeLists.txt0000644000372000001440000000241512420270445017642 0ustar robertousers# --------------------------------------------------------------------- # pion: a Boost C++ framework for building lightweight HTTP interfaces # --------------------------------------------------------------------- # Copyright (C) 2013 Splunk Inc. (https://github.com/splunk/pion) # # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt # --------------------------------------------------------------------- cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR) set(PROJECT_NAME utils) project(${PROJECT_NAME} CXX) message("BUILD_PIOND = ${BUILD_PIOND}") if (BUILD_PIOND) set(PIOND_SRC_FILES piond.cpp) add_executable(piond ${PIOND_SRC_FILES}) target_link_libraries(piond pion ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS piond RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) endif() message("BUILD_HELLOSERVER = ${BUILD_HELLOSERVER}") if (BUILD_HELLOSERVER) set(HELLOSRVR_SRC_FILES helloserver.cpp) add_executable(helloserver ${HELLOSRVR_SRC_FILES}) target_link_libraries(helloserver pion ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS helloserver RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) endif() pion-5.0.7+dfsg.orig/utils/piond.vcxproj0000644000372000001440000004052412420270445017633 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {2CF6432F-56EA-43AD-BCCB-C31A4DB75853} PionWebServer Win32Proj Application true v120 Application v120 Application v120 Application v120 Application true v120 Application v120 Application v120 Application v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset _CONSOLE;%(PreprocessorDefinitions) %(AdditionalDependencies) ..\services\.libs;%(AdditionalLibraryDirectories) Console false X64 _CONSOLE;%(PreprocessorDefinitions) ProgramDatabase %(AdditionalDependencies) ..\services\.libs;%(AdditionalLibraryDirectories) Console false MachineX64 _CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL %(AdditionalDependencies) ..\services\.libs;%(AdditionalLibraryDirectories) Console false X64 _CONSOLE;%(PreprocessorDefinitions) MultiThreadedDLL %(AdditionalDependencies) ..\services\.libs;%(AdditionalLibraryDirectories) Console false MachineX64 _CONSOLE;PION_FULL;%(PreprocessorDefinitions) Console false X64 _CONSOLE;PION_FULL;%(PreprocessorDefinitions) ProgramDatabase Console false MachineX64 _CONSOLE;PION_FULL;%(PreprocessorDefinitions) Console false X64 _CONSOLE;PION_FULL;%(PreprocessorDefinitions) Console false MachineX64 {1cf012d8-a47c-4d2b-952d-d90d19795a07} {09c3d3d7-7ce0-48d1-994f-eb534c07cf8b} {70ca1fa9-ba9a-4ea4-9b7b-c747238991c1} {9ee2433a-b460-45e0-8968-ec5ce8ef9875} {12f95fe7-ace1-4281-86bf-4117ae2d633e} {61f4b4d5-3608-4264-9f4b-b0da3e3fdf62} false pion-5.0.7+dfsg.orig/utils/sslkey.pem0000644000372000001440000000347712420270445017130 0ustar robertousers-----BEGIN CERTIFICATE----- MIICmzCCAgSgAwIBAgIJAKwms4sSPw+/MA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNV BAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHbGlicGlvbjEQMA4GA1UEAxMH bGlicGlvbjAeFw0wNzA2MDEwMTEzMDBaFw0wODA1MzEwMTEzMDBaMD4xCzAJBgNV BAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHbGlicGlvbjEQMA4GA1UEAxMH bGlicGlvbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwZDYFDNhlL4P1XHL lk0WtoBViGDd5yhLCUj/vDz3GIY9sufJHMBqZNZGovOOFOWH+m3yS1NPaUqzqWvz juMkCh3NsUZHWINJWb218bzj8ExOBJ0pgRL5anw96JN5hQ4/mr4x1v+5LcVyQVYU M2KYiLDBP+QHsWbOnQvmU3Re4vcCAwEAAaOBoDCBnTAdBgNVHQ4EFgQUg0XgzuBc fuCL2uTcHcqULKhVg3gwbgYDVR0jBGcwZYAUg0XgzuBcfuCL2uTcHcqULKhVg3ih QqRAMD4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHbGlicGlv bjEQMA4GA1UEAxMHbGlicGlvboIJAKwms4sSPw+/MAwGA1UdEwQFMAMBAf8wDQYJ KoZIhvcNAQEFBQADgYEAOOot4Yynj5Cg65+Nt5vGcIhC9321ywUnDRKEk7yu3UXA 1llqxiZE8thH0JUMoNcEWxVdEvHM8OUWaWzyyqcVZ4GyCidmE8JJUULB81b4qA+x 7rqsuTi7yLbHP3vAaZyhL0cmsxPyPB1XxQRvyAIAPWAKtJOOlQV0e055I1FyDAg= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDBkNgUM2GUvg/VccuWTRa2gFWIYN3nKEsJSP+8PPcYhj2y58kc wGpk1kai844U5Yf6bfJLU09pSrOpa/OO4yQKHc2xRkdYg0lZvbXxvOPwTE4EnSmB EvlqfD3ok3mFDj+avjHW/7ktxXJBVhQzYpiIsME/5AexZs6dC+ZTdF7i9wIDAQAB AoGBAIUJ/LnFpugIyfE2SWuAiH/fLOqTSXE7bHdxSPQkIuEkQvvX+45bYcT00Y/m Pl12dUNWlhXXqNkBkwJ7Q+eNjpKDTTPCNo6Padg9ouHgJ5pRA9SdTTsR44UdAJpB qsuJAwYcxketfwQ5QJpZZx7slA2dl92dvo+GDGxARHKEjCQBAkEA5XzR+o/XiIjz K81aq7bw5CdD+fkm4xfEYW4Mqpbg7iM0Rt4unH+savS6ghCdJescRpa4YrVuHObh 3rx917AydwJBANftn7bHEl7juu+wQnta0GQME7ipUHB/YNsmHQzvNLARCd/aNrjk J5P6bQOzPtQ/ED6T8sB5OHbTmV43zLHmc4ECQQCT8dZE3DqtMOzjzi2oCfZef9nY 64DgYlAeJ55O05oKq/NlxJL0HXMAOOmMND27VkkSUNRp/mEQjOAMgiP2ywadAkAT eoQl4N9vX+vFI4lbx111KQG+bseq3lLGcjG8sPd3ypGxd+Xn1+0aFEUxSEIqs2Wr v3zukADf90amkTIN+lQBAkEA3pBbxrW0cYU4YfZmPqP4ABCBNedU3g1TDQbUYZ+2 MfMhjws5yzwGhqwaLJzsJOUL4wmvji/LP4gNw7l3B9qaBA== -----END RSA PRIVATE KEY----- pion-5.0.7+dfsg.orig/utils/helloserver.cpp0000644000372000001440000000443712420270445020146 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include using namespace std; using namespace pion; /// simple TCP server that just sends "Hello there!" to each connection class HelloServer : public tcp::server { public: HelloServer(const unsigned int tcp_port) : tcp::server(tcp_port) {} virtual ~HelloServer() {} virtual void handle_connection(tcp::connection_ptr& tcp_conn) { static const std::string HELLO_MESSAGE("Hello there!\x0D\x0A"); tcp_conn->set_lifecycle(pion::tcp::connection::LIFECYCLE_CLOSE); // make sure it will get closed tcp_conn->async_write(boost::asio::buffer(HELLO_MESSAGE), boost::bind(&pion::tcp::connection::finish, tcp_conn)); } }; /// main control function int main (int argc, char *argv[]) { static const unsigned int DEFAULT_PORT = 8080; // parse command line: determine port number unsigned int port = DEFAULT_PORT; if (argc == 2) { port = strtoul(argv[1], 0, 10); if (port == 0) port = DEFAULT_PORT; } else if (argc != 1) { std::cerr << "usage: helloserver [port]" << std::endl; return 1; } // initialize signal handlers, etc. process::initialize(); // initialize log system (use simple configuration) logger main_log(PION_GET_LOGGER("helloserver")); logger pion_log(PION_GET_LOGGER("pion")); PION_LOG_SETLEVEL_INFO(main_log); PION_LOG_SETLEVEL_INFO(pion_log); PION_LOG_CONFIG_BASIC; try { // create a new server to handle the Hello TCP protocol tcp::server_ptr hello_server(new HelloServer(port)); hello_server->start(); process::wait_for_shutdown(); } catch (std::exception& e) { PION_LOG_FATAL(main_log, pion::diagnostic_information(e)); } return 0; } pion-5.0.7+dfsg.orig/utils/Makefile.am0000644000372000001440000000077312420270445017143 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- AM_CPPFLAGS = -I../include bin_PROGRAMS = helloserver piond helloserver_SOURCES = helloserver.cpp helloserver_LDADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ helloserver_DEPENDENCIES = ../src/libpion.la piond_SOURCES = piond.cpp piond_LDADD = ../src/libpion.la @PION_EXTERNAL_LIBS@ piond_DEPENDENCIES = ../src/libpion.la EXTRA_DIST = sslkey.pem testservices.html *.conf *.vcxproj *.vcxproj.filters pion-5.0.7+dfsg.orig/pion.xcodeproj/0000755000372000001440000000000012420270445016701 5ustar robertouserspion-5.0.7+dfsg.orig/pion.xcodeproj/project.pbxproj0000644000372000001440000036560012420270445021767 0ustar robertousers// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 6140E4F516111BED0052E5A0 /* decompressor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F216111BED0052E5A0 /* decompressor.hpp */; }; 6140E4F616111BED0052E5A0 /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F316111BED0052E5A0 /* parser.hpp */; }; 6140E4F716111BED0052E5A0 /* types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F416111BED0052E5A0 /* types.hpp */; }; 61AECCA0161268B300BF2B16 /* spdy_decompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECC9E161268B300BF2B16 /* spdy_decompressor.cpp */; }; 61AECCA1161268B300BF2B16 /* spdy_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECC9F161268B300BF2B16 /* spdy_parser.cpp */; }; 61AECCA4161269BF00BF2B16 /* spdy_parser_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECCA21612699D00BF2B16 /* spdy_parser_tests.cpp */; }; E31BC82715C1D24600168895 /* error.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E31BC82615C1D24600168895 /* error.hpp */; }; E3474E66162E0D99003AA5ED /* admin_rights.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5815BF2D0E00D76F6C /* admin_rights.hpp */; }; E3474E67162E0D99003AA5ED /* algorithm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5915BF2D0E00D76F6C /* algorithm.hpp */; }; E3474E68162E0D99003AA5ED /* config.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5A15BF2D0E00D76F6C /* config.hpp */; }; E3474E69162E0D99003AA5ED /* hash_map.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5C15BF2D0E00D76F6C /* hash_map.hpp */; }; E3474E6A162E0D99003AA5ED /* logger.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5D15BF2D0E00D76F6C /* logger.hpp */; }; E3474E6B162E0D99003AA5ED /* plugin_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5E15BF2D0E00D76F6C /* plugin_manager.hpp */; }; E3474E6C162E0D99003AA5ED /* plugin.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5F15BF2D0E00D76F6C /* plugin.hpp */; }; E3474E6D162E0D99003AA5ED /* process.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE6015BF2D0E00D76F6C /* process.hpp */; }; E3474E6E162E0D99003AA5ED /* scheduler.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE6115BF2D0E00D76F6C /* scheduler.hpp */; }; E3474E6F162E0D99003AA5ED /* connection.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7015BF2D4700D76F6C /* connection.hpp */; }; E3474E70162E0D99003AA5ED /* server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7115BF2D4700D76F6C /* server.hpp */; }; E3474E71162E0D99003AA5ED /* stream.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7215BF2D4700D76F6C /* stream.hpp */; }; E3474E72162E0D99003AA5ED /* timer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7315BF2D4700D76F6C /* timer.hpp */; }; E3474E73162E0D99003AA5ED /* auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7815BF2D5B00D76F6C /* auth.hpp */; }; E3474E74162E0D99003AA5ED /* basic_auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7915BF2D5B00D76F6C /* basic_auth.hpp */; }; E3474E75162E0D99003AA5ED /* cookie_auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7A15BF2D5B00D76F6C /* cookie_auth.hpp */; }; E3474E76162E0D99003AA5ED /* message.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7B15BF2D5B00D76F6C /* message.hpp */; }; E3474E77162E0D99003AA5ED /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7C15BF2D5B00D76F6C /* parser.hpp */; }; E3474E78162E0D99003AA5ED /* plugin_server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7D15BF2D5B00D76F6C /* plugin_server.hpp */; }; E3474E79162E0D99003AA5ED /* plugin_service.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7E15BF2D5B00D76F6C /* plugin_service.hpp */; }; E3474E7A162E0D99003AA5ED /* reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7F15BF2D5B00D76F6C /* reader.hpp */; }; E3474E7B162E0D99003AA5ED /* request_reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8015BF2D5B00D76F6C /* request_reader.hpp */; }; E3474E7C162E0D99003AA5ED /* request_writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8115BF2D5B00D76F6C /* request_writer.hpp */; }; E3474E7D162E0D99003AA5ED /* request.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8215BF2D5B00D76F6C /* request.hpp */; }; E3474E7E162E0D99003AA5ED /* response_reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8315BF2D5B00D76F6C /* response_reader.hpp */; }; E3474E7F162E0D99003AA5ED /* response_writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8415BF2D5B00D76F6C /* response_writer.hpp */; }; E3474E80162E0D99003AA5ED /* response.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8515BF2D5B00D76F6C /* response.hpp */; }; E3474E81162E0D99003AA5ED /* server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8615BF2D5B00D76F6C /* server.hpp */; }; E3474E82162E0D99003AA5ED /* types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8715BF2D5B00D76F6C /* types.hpp */; }; E3474E83162E0D99003AA5ED /* writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8915BF2D5B00D76F6C /* writer.hpp */; }; E3474E84162E0D99003AA5ED /* error.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E31BC82615C1D24600168895 /* error.hpp */; }; E3474E85162E0D99003AA5ED /* user.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E3A00AE915CC740A00F79569 /* user.hpp */; }; E3474E86162E0D99003AA5ED /* decompressor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F216111BED0052E5A0 /* decompressor.hpp */; }; E3474E87162E0D99003AA5ED /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F316111BED0052E5A0 /* parser.hpp */; }; E3474E88162E0D99003AA5ED /* types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F416111BED0052E5A0 /* types.hpp */; }; E3474E8A162E0D99003AA5ED /* admin_rights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9C15BF2D8A00D76F6C /* admin_rights.cpp */; }; E3474E8B162E0D99003AA5ED /* algorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9D15BF2D8A00D76F6C /* algorithm.cpp */; }; E3474E8C162E0D99003AA5ED /* http_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9E15BF2D8A00D76F6C /* http_auth.cpp */; }; E3474E8D162E0D99003AA5ED /* http_basic_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9F15BF2D8A00D76F6C /* http_basic_auth.cpp */; }; E3474E8E162E0D99003AA5ED /* http_cookie_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA015BF2D8A00D76F6C /* http_cookie_auth.cpp */; }; E3474E8F162E0D99003AA5ED /* http_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA115BF2D8A00D76F6C /* http_message.cpp */; }; E3474E90162E0D99003AA5ED /* http_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA215BF2D8A00D76F6C /* http_parser.cpp */; }; E3474E91162E0D99003AA5ED /* http_plugin_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA315BF2D8A00D76F6C /* http_plugin_server.cpp */; }; E3474E92162E0D99003AA5ED /* http_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA415BF2D8A00D76F6C /* http_reader.cpp */; }; E3474E93162E0D99003AA5ED /* http_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA515BF2D8A00D76F6C /* http_server.cpp */; }; E3474E94162E0D99003AA5ED /* http_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA615BF2D8A00D76F6C /* http_types.cpp */; }; E3474E95162E0D99003AA5ED /* http_writer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA715BF2D8A00D76F6C /* http_writer.cpp */; }; E3474E96162E0D99003AA5ED /* logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA815BF2D8A00D76F6C /* logger.cpp */; }; E3474E97162E0D99003AA5ED /* plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA915BF2D8A00D76F6C /* plugin.cpp */; }; E3474E98162E0D99003AA5ED /* process.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAA15BF2D8A00D76F6C /* process.cpp */; }; E3474E99162E0D99003AA5ED /* scheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAB15BF2D8A00D76F6C /* scheduler.cpp */; }; E3474E9A162E0D99003AA5ED /* tcp_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAC15BF2D8A00D76F6C /* tcp_server.cpp */; }; E3474E9B162E0D99003AA5ED /* tcp_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAD15BF2D8A00D76F6C /* tcp_timer.cpp */; }; E3474E9C162E0D99003AA5ED /* spdy_decompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECC9E161268B300BF2B16 /* spdy_decompressor.cpp */; }; E3474E9D162E0D99003AA5ED /* spdy_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECC9F161268B300BF2B16 /* spdy_parser.cpp */; }; E3474EE7162E1053003AA5ED /* admin_rights.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5815BF2D0E00D76F6C /* admin_rights.hpp */; }; E3474EE8162E1053003AA5ED /* algorithm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5915BF2D0E00D76F6C /* algorithm.hpp */; }; E3474EE9162E1053003AA5ED /* config.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5A15BF2D0E00D76F6C /* config.hpp */; }; E3474EEA162E1053003AA5ED /* hash_map.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5C15BF2D0E00D76F6C /* hash_map.hpp */; }; E3474EEB162E1053003AA5ED /* logger.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5D15BF2D0E00D76F6C /* logger.hpp */; }; E3474EEC162E1053003AA5ED /* plugin_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5E15BF2D0E00D76F6C /* plugin_manager.hpp */; }; E3474EED162E1053003AA5ED /* plugin.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5F15BF2D0E00D76F6C /* plugin.hpp */; }; E3474EEE162E1053003AA5ED /* process.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE6015BF2D0E00D76F6C /* process.hpp */; }; E3474EEF162E1053003AA5ED /* scheduler.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE6115BF2D0E00D76F6C /* scheduler.hpp */; }; E3474EF0162E1053003AA5ED /* connection.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7015BF2D4700D76F6C /* connection.hpp */; }; E3474EF1162E1053003AA5ED /* server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7115BF2D4700D76F6C /* server.hpp */; }; E3474EF2162E1053003AA5ED /* stream.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7215BF2D4700D76F6C /* stream.hpp */; }; E3474EF3162E1053003AA5ED /* timer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7315BF2D4700D76F6C /* timer.hpp */; }; E3474EF4162E1053003AA5ED /* auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7815BF2D5B00D76F6C /* auth.hpp */; }; E3474EF5162E1053003AA5ED /* basic_auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7915BF2D5B00D76F6C /* basic_auth.hpp */; }; E3474EF6162E1053003AA5ED /* cookie_auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7A15BF2D5B00D76F6C /* cookie_auth.hpp */; }; E3474EF7162E1053003AA5ED /* message.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7B15BF2D5B00D76F6C /* message.hpp */; }; E3474EF8162E1053003AA5ED /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7C15BF2D5B00D76F6C /* parser.hpp */; }; E3474EF9162E1053003AA5ED /* plugin_server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7D15BF2D5B00D76F6C /* plugin_server.hpp */; }; E3474EFA162E1053003AA5ED /* plugin_service.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7E15BF2D5B00D76F6C /* plugin_service.hpp */; }; E3474EFB162E1053003AA5ED /* reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7F15BF2D5B00D76F6C /* reader.hpp */; }; E3474EFC162E1053003AA5ED /* request_reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8015BF2D5B00D76F6C /* request_reader.hpp */; }; E3474EFD162E1053003AA5ED /* request_writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8115BF2D5B00D76F6C /* request_writer.hpp */; }; E3474EFE162E1053003AA5ED /* request.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8215BF2D5B00D76F6C /* request.hpp */; }; E3474EFF162E1053003AA5ED /* response_reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8315BF2D5B00D76F6C /* response_reader.hpp */; }; E3474F00162E1053003AA5ED /* response_writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8415BF2D5B00D76F6C /* response_writer.hpp */; }; E3474F01162E1053003AA5ED /* response.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8515BF2D5B00D76F6C /* response.hpp */; }; E3474F02162E1053003AA5ED /* server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8615BF2D5B00D76F6C /* server.hpp */; }; E3474F03162E1053003AA5ED /* types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8715BF2D5B00D76F6C /* types.hpp */; }; E3474F04162E1053003AA5ED /* writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8915BF2D5B00D76F6C /* writer.hpp */; }; E3474F05162E1053003AA5ED /* error.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E31BC82615C1D24600168895 /* error.hpp */; }; E3474F06162E1053003AA5ED /* user.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E3A00AE915CC740A00F79569 /* user.hpp */; }; E3474F07162E1053003AA5ED /* decompressor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F216111BED0052E5A0 /* decompressor.hpp */; }; E3474F08162E1053003AA5ED /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F316111BED0052E5A0 /* parser.hpp */; }; E3474F09162E1053003AA5ED /* types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6140E4F416111BED0052E5A0 /* types.hpp */; }; E3474F0B162E1053003AA5ED /* admin_rights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9C15BF2D8A00D76F6C /* admin_rights.cpp */; }; E3474F0C162E1053003AA5ED /* algorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9D15BF2D8A00D76F6C /* algorithm.cpp */; }; E3474F0D162E1053003AA5ED /* http_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9E15BF2D8A00D76F6C /* http_auth.cpp */; }; E3474F0E162E1053003AA5ED /* http_basic_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9F15BF2D8A00D76F6C /* http_basic_auth.cpp */; }; E3474F0F162E1053003AA5ED /* http_cookie_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA015BF2D8A00D76F6C /* http_cookie_auth.cpp */; }; E3474F10162E1053003AA5ED /* http_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA115BF2D8A00D76F6C /* http_message.cpp */; }; E3474F11162E1053003AA5ED /* http_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA215BF2D8A00D76F6C /* http_parser.cpp */; }; E3474F12162E1053003AA5ED /* http_plugin_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA315BF2D8A00D76F6C /* http_plugin_server.cpp */; }; E3474F13162E1053003AA5ED /* http_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA415BF2D8A00D76F6C /* http_reader.cpp */; }; E3474F14162E1053003AA5ED /* http_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA515BF2D8A00D76F6C /* http_server.cpp */; }; E3474F15162E1053003AA5ED /* http_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA615BF2D8A00D76F6C /* http_types.cpp */; }; E3474F16162E1053003AA5ED /* http_writer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA715BF2D8A00D76F6C /* http_writer.cpp */; }; E3474F17162E1053003AA5ED /* logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA815BF2D8A00D76F6C /* logger.cpp */; }; E3474F18162E1053003AA5ED /* plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA915BF2D8A00D76F6C /* plugin.cpp */; }; E3474F19162E1053003AA5ED /* process.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAA15BF2D8A00D76F6C /* process.cpp */; }; E3474F1A162E1053003AA5ED /* scheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAB15BF2D8A00D76F6C /* scheduler.cpp */; }; E3474F1B162E1053003AA5ED /* tcp_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAC15BF2D8A00D76F6C /* tcp_server.cpp */; }; E3474F1C162E1053003AA5ED /* tcp_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAD15BF2D8A00D76F6C /* tcp_timer.cpp */; }; E3474F1D162E1053003AA5ED /* spdy_decompressor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECC9E161268B300BF2B16 /* spdy_decompressor.cpp */; }; E3474F1E162E1053003AA5ED /* spdy_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61AECC9F161268B300BF2B16 /* spdy_parser.cpp */; }; E35CCE6315BF2D0E00D76F6C /* admin_rights.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5815BF2D0E00D76F6C /* admin_rights.hpp */; }; E35CCE6415BF2D0E00D76F6C /* algorithm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5915BF2D0E00D76F6C /* algorithm.hpp */; }; E35CCE6515BF2D0E00D76F6C /* config.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5A15BF2D0E00D76F6C /* config.hpp */; }; E35CCE6715BF2D0E00D76F6C /* hash_map.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5C15BF2D0E00D76F6C /* hash_map.hpp */; }; E35CCE6815BF2D0E00D76F6C /* logger.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5D15BF2D0E00D76F6C /* logger.hpp */; }; E35CCE6915BF2D0E00D76F6C /* plugin_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5E15BF2D0E00D76F6C /* plugin_manager.hpp */; }; E35CCE6A15BF2D0E00D76F6C /* plugin.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE5F15BF2D0E00D76F6C /* plugin.hpp */; }; E35CCE6B15BF2D0E00D76F6C /* process.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE6015BF2D0E00D76F6C /* process.hpp */; }; E35CCE6C15BF2D0E00D76F6C /* scheduler.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE6115BF2D0E00D76F6C /* scheduler.hpp */; }; E35CCE7415BF2D4700D76F6C /* connection.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7015BF2D4700D76F6C /* connection.hpp */; }; E35CCE7515BF2D4700D76F6C /* server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7115BF2D4700D76F6C /* server.hpp */; }; E35CCE7615BF2D4700D76F6C /* stream.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7215BF2D4700D76F6C /* stream.hpp */; }; E35CCE7715BF2D4700D76F6C /* timer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7315BF2D4700D76F6C /* timer.hpp */; }; E35CCE8A15BF2D5B00D76F6C /* auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7815BF2D5B00D76F6C /* auth.hpp */; }; E35CCE8B15BF2D5B00D76F6C /* basic_auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7915BF2D5B00D76F6C /* basic_auth.hpp */; }; E35CCE8C15BF2D5B00D76F6C /* cookie_auth.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7A15BF2D5B00D76F6C /* cookie_auth.hpp */; }; E35CCE8D15BF2D5B00D76F6C /* message.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7B15BF2D5B00D76F6C /* message.hpp */; }; E35CCE8E15BF2D5B00D76F6C /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7C15BF2D5B00D76F6C /* parser.hpp */; }; E35CCE8F15BF2D5B00D76F6C /* plugin_server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7D15BF2D5B00D76F6C /* plugin_server.hpp */; }; E35CCE9015BF2D5B00D76F6C /* plugin_service.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7E15BF2D5B00D76F6C /* plugin_service.hpp */; }; E35CCE9115BF2D5B00D76F6C /* reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE7F15BF2D5B00D76F6C /* reader.hpp */; }; E35CCE9215BF2D5B00D76F6C /* request_reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8015BF2D5B00D76F6C /* request_reader.hpp */; }; E35CCE9315BF2D5B00D76F6C /* request_writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8115BF2D5B00D76F6C /* request_writer.hpp */; }; E35CCE9415BF2D5B00D76F6C /* request.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8215BF2D5B00D76F6C /* request.hpp */; }; E35CCE9515BF2D5B00D76F6C /* response_reader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8315BF2D5B00D76F6C /* response_reader.hpp */; }; E35CCE9615BF2D5B00D76F6C /* response_writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8415BF2D5B00D76F6C /* response_writer.hpp */; }; E35CCE9715BF2D5B00D76F6C /* response.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8515BF2D5B00D76F6C /* response.hpp */; }; E35CCE9815BF2D5B00D76F6C /* server.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8615BF2D5B00D76F6C /* server.hpp */; }; E35CCE9915BF2D5B00D76F6C /* types.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8715BF2D5B00D76F6C /* types.hpp */; }; E35CCE9B15BF2D5B00D76F6C /* writer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCE8915BF2D5B00D76F6C /* writer.hpp */; }; E35CCEAE15BF2D8A00D76F6C /* admin_rights.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9C15BF2D8A00D76F6C /* admin_rights.cpp */; }; E35CCEAF15BF2D8A00D76F6C /* algorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9D15BF2D8A00D76F6C /* algorithm.cpp */; }; E35CCEB015BF2D8A00D76F6C /* http_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9E15BF2D8A00D76F6C /* http_auth.cpp */; }; E35CCEB115BF2D8A00D76F6C /* http_basic_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCE9F15BF2D8A00D76F6C /* http_basic_auth.cpp */; }; E35CCEB215BF2D8A00D76F6C /* http_cookie_auth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA015BF2D8A00D76F6C /* http_cookie_auth.cpp */; }; E35CCEB315BF2D8A00D76F6C /* http_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA115BF2D8A00D76F6C /* http_message.cpp */; }; E35CCEB415BF2D8A00D76F6C /* http_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA215BF2D8A00D76F6C /* http_parser.cpp */; }; E35CCEB515BF2D8A00D76F6C /* http_plugin_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA315BF2D8A00D76F6C /* http_plugin_server.cpp */; }; E35CCEB615BF2D8A00D76F6C /* http_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA415BF2D8A00D76F6C /* http_reader.cpp */; }; E35CCEB715BF2D8A00D76F6C /* http_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA515BF2D8A00D76F6C /* http_server.cpp */; }; E35CCEB815BF2D8A00D76F6C /* http_types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA615BF2D8A00D76F6C /* http_types.cpp */; }; E35CCEB915BF2D8A00D76F6C /* http_writer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA715BF2D8A00D76F6C /* http_writer.cpp */; }; E35CCEBA15BF2D8A00D76F6C /* logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA815BF2D8A00D76F6C /* logger.cpp */; }; E35CCEBB15BF2D8A00D76F6C /* plugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEA915BF2D8A00D76F6C /* plugin.cpp */; }; E35CCEBC15BF2D8A00D76F6C /* process.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAA15BF2D8A00D76F6C /* process.cpp */; }; E35CCEBD15BF2D8A00D76F6C /* scheduler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAB15BF2D8A00D76F6C /* scheduler.cpp */; }; E35CCEBE15BF2D8A00D76F6C /* tcp_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAC15BF2D8A00D76F6C /* tcp_server.cpp */; }; E35CCEBF15BF2D8A00D76F6C /* tcp_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEAD15BF2D8A00D76F6C /* tcp_timer.cpp */; }; E35CCF2315BF2F9300D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3615BF2FBA00D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3715BF2FBD00D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3815BF2FC000D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3915BF2FC400D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3A15BF2FC800D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3B15BF2FCB00D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3C15BF2FCE00D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3D15BF2FD100D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF3E15BF2FFA00D76F6C /* hasCreateAndDestroy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEDC15BF2E4100D76F6C /* hasCreateAndDestroy.cpp */; }; E35CCF3F15BF2FFF00D76F6C /* hasCreateAndDestroy.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEDD15BF2E4100D76F6C /* hasCreateAndDestroy.hpp */; }; E35CCF4015BF300600D76F6C /* hasCreateButNoDestroy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEDE15BF2E4100D76F6C /* hasCreateButNoDestroy.cpp */; }; E35CCF4115BF301700D76F6C /* hasCreateButNoDestroy.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEDF15BF2E4100D76F6C /* hasCreateButNoDestroy.hpp */; }; E35CCF4215BF302200D76F6C /* hasNoCreate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEE015BF2E4100D76F6C /* hasNoCreate.cpp */; }; E35CCF4315BF302300D76F6C /* hasNoCreate.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEE115BF2E4100D76F6C /* hasNoCreate.hpp */; }; E35CCF4415BF303F00D76F6C /* InterfaceStub.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEE215BF2E4100D76F6C /* InterfaceStub.hpp */; }; E35CCF4515BF304300D76F6C /* InterfaceStub.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEE215BF2E4100D76F6C /* InterfaceStub.hpp */; }; E35CCF4615BF304700D76F6C /* InterfaceStub.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEE215BF2E4100D76F6C /* InterfaceStub.hpp */; }; E35CCF4715BF304C00D76F6C /* AllowNothingService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEC015BF2DB500D76F6C /* AllowNothingService.cpp */; }; E35CCF4815BF304E00D76F6C /* AllowNothingService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEC115BF2DB500D76F6C /* AllowNothingService.hpp */; }; E35CCF4915BF305100D76F6C /* CookieService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEC315BF2DB500D76F6C /* CookieService.hpp */; }; E35CCF4A15BF305200D76F6C /* CookieService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEC215BF2DB500D76F6C /* CookieService.cpp */; }; E35CCF4B15BF305800D76F6C /* EchoService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEC415BF2DB500D76F6C /* EchoService.cpp */; }; E35CCF4C15BF305A00D76F6C /* EchoService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEC515BF2DB500D76F6C /* EchoService.hpp */; }; E35CCF4D15BF305D00D76F6C /* FileService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEC615BF2DB500D76F6C /* FileService.cpp */; }; E35CCF4E15BF305E00D76F6C /* FileService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEC715BF2DB500D76F6C /* FileService.hpp */; }; E35CCF4F15BF306200D76F6C /* HelloService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCEC915BF2DB500D76F6C /* HelloService.hpp */; }; E35CCF5015BF306400D76F6C /* HelloService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEC815BF2DB500D76F6C /* HelloService.cpp */; }; E35CCF5115BF307100D76F6C /* LogService.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E35CCECB15BF2DB500D76F6C /* LogService.hpp */; }; E35CCF5215BF307400D76F6C /* LogService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCECA15BF2DB500D76F6C /* LogService.cpp */; }; E35CCF5315BF307B00D76F6C /* piond.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCECD15BF2DC800D76F6C /* piond.cpp */; }; E35CCF5B15BF30A300D76F6C /* http_types_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED515BF2DE500D76F6C /* http_types_tests.cpp */; }; E35CCF6715BF30AA00D76F6C /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E35CCF6D15BF30BE00D76F6C /* helloserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCECC15BF2DC800D76F6C /* helloserver.cpp */; }; E3623BE517FB96DA00A14A84 /* process_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3623BE417FB96DA00A14A84 /* process_tests.cpp */; }; E36D8BF40D29D72200B4C134 /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E370CF3B158E700F00E46EE9 /* libpion.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; }; E3A00AEA15CC740A00F79569 /* user.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E3A00AE915CC740A00F79569 /* user.hpp */; }; E3A1AE3215C878E100FFE9E3 /* piontests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED615BF2DE500D76F6C /* piontests.cpp */; }; E3A1AE3315C87FD500FFE9E3 /* algorithm_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCECE15BF2DE500D76F6C /* algorithm_tests.cpp */; }; E3A1AE3415C87FD500FFE9E3 /* file_service_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCECF15BF2DE500D76F6C /* file_service_tests.cpp */; }; E3A1AE3515C87FD500FFE9E3 /* http_message_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED015BF2DE500D76F6C /* http_message_tests.cpp */; }; E3A1AE3615C87FD500FFE9E3 /* http_parser_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED115BF2DE500D76F6C /* http_parser_tests.cpp */; }; E3A1AE3715C87FD500FFE9E3 /* http_plugin_server_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED215BF2DE500D76F6C /* http_plugin_server_tests.cpp */; }; E3A1AE3815C87FD500FFE9E3 /* http_request_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED315BF2DE500D76F6C /* http_request_tests.cpp */; }; E3A1AE3915C87FD500FFE9E3 /* http_response_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED415BF2DE500D76F6C /* http_response_tests.cpp */; }; E3A1AE3A15C87FD500FFE9E3 /* plugin_manager_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED715BF2DE500D76F6C /* plugin_manager_tests.cpp */; }; E3A1AE3B15C87FD500FFE9E3 /* plugin_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED815BF2DE500D76F6C /* plugin_tests.cpp */; }; E3A1AE3C15C87FD500FFE9E3 /* tcp_server_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCED915BF2DE500D76F6C /* tcp_server_tests.cpp */; }; E3A1AE3D15C87FD500FFE9E3 /* tcp_stream_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CCEDA15BF2DE500D76F6C /* tcp_stream_tests.cpp */; }; E3B5EA9A15C896050023988F /* unit_test.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E3B5EA9915C896050023988F /* unit_test.hpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ E35CCF2415BF2F9A00D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF2615BF2F9F00D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF2815BF2FA200D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF2A15BF2FA500D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF2C15BF2FA800D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF2E15BF2FAB00D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF3015BF2FAE00D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF3215BF2FB100D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF3415BF2FB300D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion: dynamic"; }; E35CCF6315BF30AA00D76F6C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion-net: dynamic"; }; E36D8BED0D29D6F200B4C134 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion-net: dynamic"; }; E370CE7E158D962700E46EE9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; remoteGlobalIDString = E36D8A5E0D29C9D800B4C134; remoteInfo = "pion-net: dynamic"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 6140E4F216111BED0052E5A0 /* decompressor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = decompressor.hpp; sourceTree = ""; }; 6140E4F316111BED0052E5A0 /* parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = parser.hpp; sourceTree = ""; }; 6140E4F416111BED0052E5A0 /* types.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = types.hpp; sourceTree = ""; }; 61AECC9E161268B300BF2B16 /* spdy_decompressor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = spdy_decompressor.cpp; path = src/spdy_decompressor.cpp; sourceTree = ""; }; 61AECC9F161268B300BF2B16 /* spdy_parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = spdy_parser.cpp; path = src/spdy_parser.cpp; sourceTree = ""; }; 61AECCA21612699D00BF2B16 /* spdy_parser_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = spdy_parser_tests.cpp; path = tests/spdy_parser_tests.cpp; sourceTree = ""; }; E31BC82615C1D24600168895 /* error.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = error.hpp; path = include/pion/error.hpp; sourceTree = ""; }; E3474EA2162E0D99003AA5ED /* libpion-pic.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "libpion-pic.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E3474F23162E1053003AA5ED /* libpion.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libpion.a; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCE5815BF2D0E00D76F6C /* admin_rights.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = admin_rights.hpp; path = include/pion/admin_rights.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE5915BF2D0E00D76F6C /* algorithm.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = algorithm.hpp; path = include/pion/algorithm.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE5A15BF2D0E00D76F6C /* config.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = config.hpp; path = include/pion/config.hpp; sourceTree = ""; }; E35CCE5C15BF2D0E00D76F6C /* hash_map.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = hash_map.hpp; path = include/pion/hash_map.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE5D15BF2D0E00D76F6C /* logger.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = logger.hpp; path = include/pion/logger.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE5E15BF2D0E00D76F6C /* plugin_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = plugin_manager.hpp; path = include/pion/plugin_manager.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE5F15BF2D0E00D76F6C /* plugin.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = plugin.hpp; path = include/pion/plugin.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE6015BF2D0E00D76F6C /* process.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = process.hpp; path = include/pion/process.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE6115BF2D0E00D76F6C /* scheduler.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = scheduler.hpp; path = include/pion/scheduler.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7015BF2D4700D76F6C /* connection.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = connection.hpp; path = include/pion/tcp/connection.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7115BF2D4700D76F6C /* server.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = server.hpp; path = include/pion/tcp/server.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7215BF2D4700D76F6C /* stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stream.hpp; path = include/pion/tcp/stream.hpp; sourceTree = ""; }; E35CCE7315BF2D4700D76F6C /* timer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = timer.hpp; path = include/pion/tcp/timer.hpp; sourceTree = ""; }; E35CCE7815BF2D5B00D76F6C /* auth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = auth.hpp; path = include/pion/http/auth.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7915BF2D5B00D76F6C /* basic_auth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = basic_auth.hpp; path = include/pion/http/basic_auth.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7A15BF2D5B00D76F6C /* cookie_auth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = cookie_auth.hpp; path = include/pion/http/cookie_auth.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7B15BF2D5B00D76F6C /* message.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = message.hpp; path = include/pion/http/message.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7C15BF2D5B00D76F6C /* parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = parser.hpp; path = include/pion/http/parser.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7D15BF2D5B00D76F6C /* plugin_server.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = plugin_server.hpp; path = include/pion/http/plugin_server.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7E15BF2D5B00D76F6C /* plugin_service.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = plugin_service.hpp; path = include/pion/http/plugin_service.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE7F15BF2D5B00D76F6C /* reader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = reader.hpp; path = include/pion/http/reader.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8015BF2D5B00D76F6C /* request_reader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = request_reader.hpp; path = include/pion/http/request_reader.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8115BF2D5B00D76F6C /* request_writer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = request_writer.hpp; path = include/pion/http/request_writer.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8215BF2D5B00D76F6C /* request.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = request.hpp; path = include/pion/http/request.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8315BF2D5B00D76F6C /* response_reader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = response_reader.hpp; path = include/pion/http/response_reader.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8415BF2D5B00D76F6C /* response_writer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = response_writer.hpp; path = include/pion/http/response_writer.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8515BF2D5B00D76F6C /* response.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = response.hpp; path = include/pion/http/response.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8615BF2D5B00D76F6C /* server.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = server.hpp; path = include/pion/http/server.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8715BF2D5B00D76F6C /* types.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = types.hpp; path = include/pion/http/types.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE8915BF2D5B00D76F6C /* writer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = writer.hpp; path = include/pion/http/writer.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE9C15BF2D8A00D76F6C /* admin_rights.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = admin_rights.cpp; path = src/admin_rights.cpp; sourceTree = ""; }; E35CCE9D15BF2D8A00D76F6C /* algorithm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = algorithm.cpp; path = src/algorithm.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE9E15BF2D8A00D76F6C /* http_auth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_auth.cpp; path = src/http_auth.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCE9F15BF2D8A00D76F6C /* http_basic_auth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_basic_auth.cpp; path = src/http_basic_auth.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA015BF2D8A00D76F6C /* http_cookie_auth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_cookie_auth.cpp; path = src/http_cookie_auth.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA115BF2D8A00D76F6C /* http_message.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_message.cpp; path = src/http_message.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA215BF2D8A00D76F6C /* http_parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_parser.cpp; path = src/http_parser.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA315BF2D8A00D76F6C /* http_plugin_server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_plugin_server.cpp; path = src/http_plugin_server.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA415BF2D8A00D76F6C /* http_reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_reader.cpp; path = src/http_reader.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA515BF2D8A00D76F6C /* http_server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_server.cpp; path = src/http_server.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA615BF2D8A00D76F6C /* http_types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_types.cpp; path = src/http_types.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA715BF2D8A00D76F6C /* http_writer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_writer.cpp; path = src/http_writer.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA815BF2D8A00D76F6C /* logger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = logger.cpp; path = src/logger.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEA915BF2D8A00D76F6C /* plugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = plugin.cpp; path = src/plugin.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEAA15BF2D8A00D76F6C /* process.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = process.cpp; path = src/process.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEAB15BF2D8A00D76F6C /* scheduler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = scheduler.cpp; path = src/scheduler.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEAC15BF2D8A00D76F6C /* tcp_server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = tcp_server.cpp; path = src/tcp_server.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEAD15BF2D8A00D76F6C /* tcp_timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tcp_timer.cpp; path = src/tcp_timer.cpp; sourceTree = ""; }; E35CCEC015BF2DB500D76F6C /* AllowNothingService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = AllowNothingService.cpp; path = services/AllowNothingService.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC115BF2DB500D76F6C /* AllowNothingService.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = AllowNothingService.hpp; path = services/AllowNothingService.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC215BF2DB500D76F6C /* CookieService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CookieService.cpp; path = services/CookieService.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC315BF2DB500D76F6C /* CookieService.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = CookieService.hpp; path = services/CookieService.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC415BF2DB500D76F6C /* EchoService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = EchoService.cpp; path = services/EchoService.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC515BF2DB500D76F6C /* EchoService.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = EchoService.hpp; path = services/EchoService.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC615BF2DB500D76F6C /* FileService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = FileService.cpp; path = services/FileService.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC715BF2DB500D76F6C /* FileService.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = FileService.hpp; path = services/FileService.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC815BF2DB500D76F6C /* HelloService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = HelloService.cpp; path = services/HelloService.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEC915BF2DB500D76F6C /* HelloService.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = HelloService.hpp; path = services/HelloService.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCECA15BF2DB500D76F6C /* LogService.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = LogService.cpp; path = services/LogService.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCECB15BF2DB500D76F6C /* LogService.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = LogService.hpp; path = services/LogService.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCECC15BF2DC800D76F6C /* helloserver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = helloserver.cpp; path = utils/helloserver.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCECD15BF2DC800D76F6C /* piond.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = piond.cpp; path = utils/piond.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCECE15BF2DE500D76F6C /* algorithm_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = algorithm_tests.cpp; path = tests/algorithm_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCECF15BF2DE500D76F6C /* file_service_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = file_service_tests.cpp; path = tests/file_service_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED015BF2DE500D76F6C /* http_message_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_message_tests.cpp; path = tests/http_message_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED115BF2DE500D76F6C /* http_parser_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_parser_tests.cpp; path = tests/http_parser_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED215BF2DE500D76F6C /* http_plugin_server_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_plugin_server_tests.cpp; path = tests/http_plugin_server_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED315BF2DE500D76F6C /* http_request_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_request_tests.cpp; path = tests/http_request_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED415BF2DE500D76F6C /* http_response_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_response_tests.cpp; path = tests/http_response_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED515BF2DE500D76F6C /* http_types_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = http_types_tests.cpp; path = tests/http_types_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED615BF2DE500D76F6C /* piontests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = piontests.cpp; path = tests/piontests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED715BF2DE500D76F6C /* plugin_manager_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = plugin_manager_tests.cpp; path = tests/plugin_manager_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED815BF2DE500D76F6C /* plugin_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = plugin_tests.cpp; path = tests/plugin_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCED915BF2DE500D76F6C /* tcp_server_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = tcp_server_tests.cpp; path = tests/tcp_server_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEDA15BF2DE500D76F6C /* tcp_stream_tests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = tcp_stream_tests.cpp; path = tests/tcp_stream_tests.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEDC15BF2E4100D76F6C /* hasCreateAndDestroy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = hasCreateAndDestroy.cpp; path = tests/plugins/hasCreateAndDestroy.cpp; sourceTree = ""; }; E35CCEDD15BF2E4100D76F6C /* hasCreateAndDestroy.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = hasCreateAndDestroy.hpp; path = tests/plugins/hasCreateAndDestroy.hpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; E35CCEDE15BF2E4100D76F6C /* hasCreateButNoDestroy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = hasCreateButNoDestroy.cpp; path = tests/plugins/hasCreateButNoDestroy.cpp; sourceTree = ""; }; E35CCEDF15BF2E4100D76F6C /* hasCreateButNoDestroy.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = hasCreateButNoDestroy.hpp; path = tests/plugins/hasCreateButNoDestroy.hpp; sourceTree = ""; }; E35CCEE015BF2E4100D76F6C /* hasNoCreate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = hasNoCreate.cpp; path = tests/plugins/hasNoCreate.cpp; sourceTree = ""; }; E35CCEE115BF2E4100D76F6C /* hasNoCreate.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = hasNoCreate.hpp; path = tests/plugins/hasNoCreate.hpp; sourceTree = ""; }; E35CCEE215BF2E4100D76F6C /* InterfaceStub.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = InterfaceStub.hpp; path = tests/plugins/InterfaceStub.hpp; sourceTree = ""; }; E35CCEEA15BF2EE100D76F6C /* AllowNothingService.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = AllowNothingService.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCEF215BF2EFB00D76F6C /* CookieService.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = CookieService.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCEFA15BF2F0800D76F6C /* EchoService.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = EchoService.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCF0215BF2F1300D76F6C /* FileService.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = FileService.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCF0A15BF2F1E00D76F6C /* HelloService.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = HelloService.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCF1215BF2F2900D76F6C /* LogService.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = LogService.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCF1A15BF2F5700D76F6C /* hasCreateAndDestroy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = hasCreateAndDestroy.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCF2215BF2F6F00D76F6C /* hasNoCreate.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = hasNoCreate.so; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCF6B15BF30AA00D76F6C /* helloserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = helloserver; sourceTree = BUILT_PRODUCTS_DIR; }; E35CCFB115BF3AB600D76F6C /* testservices.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = testservices.conf; path = tests/config/testservices.conf; sourceTree = ""; }; E3623BE417FB96DA00A14A84 /* process_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = process_tests.cpp; path = tests/process_tests.cpp; sourceTree = ""; }; E36D8A5F0D29C9D800B4C134 /* libpion.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libpion.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; E36D8BE70D29D6DC00B4C134 /* piond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = piond; sourceTree = BUILT_PRODUCTS_DIR; }; E370CEC0158D962700E46EE9 /* piontests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = piontests; sourceTree = BUILT_PRODUCTS_DIR; }; E370CF30158E6C1A00E46EE9 /* hasCreateButNoDestroy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = hasCreateButNoDestroy.so; sourceTree = BUILT_PRODUCTS_DIR; }; E3A00AE915CC740A00F79569 /* user.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = user.hpp; path = include/pion/user.hpp; sourceTree = ""; }; E3B5EA9915C896050023988F /* unit_test.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = unit_test.hpp; path = include/pion/test/unit_test.hpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ E3474E9E162E0D99003AA5ED /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; E3474F1F162E1053003AA5ED /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEE615BF2EE100D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3815BF2FC000D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEEE15BF2EFB00D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3915BF2FC400D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEF615BF2F0800D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3A15BF2FC800D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEFE15BF2F1300D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3B15BF2FCB00D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF0615BF2F1E00D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3C15BF2FCE00D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF0E15BF2F2900D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3D15BF2FD100D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF1615BF2F5700D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF2315BF2F9300D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF1E15BF2F6F00D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3715BF2FBD00D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF6615BF30AA00D76F6C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF6715BF30AA00D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E36D8A5D0D29C9D800B4C134 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; E36D8BE50D29D6DC00B4C134 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E36D8BF40D29D72200B4C134 /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E370CEB8158D962700E46EE9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E370CF3B158E700F00E46EE9 /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; E370CF2A158E6C1A00E46EE9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3615BF2FBA00D76F6C /* libpion.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 08FB7794FE84155DC02AAC07 /* libpion */ = { isa = PBXGroup; children = ( E35CCE5315BF2CAF00D76F6C /* include */, E35CCE5415BF2CB400D76F6C /* src */, E35CCE5515BF2CB800D76F6C /* services */, E35CCE5615BF2CC000D76F6C /* utils */, E35CCE5715BF2CC600D76F6C /* tests */, 1AB674ADFE9D54B511CA2CBB /* Products */, ); name = libpion; sourceTree = ""; }; 1AB674ADFE9D54B511CA2CBB /* Products */ = { isa = PBXGroup; children = ( E36D8A5F0D29C9D800B4C134 /* libpion.dylib */, E36D8BE70D29D6DC00B4C134 /* piond */, E370CEC0158D962700E46EE9 /* piontests */, E370CF30158E6C1A00E46EE9 /* hasCreateButNoDestroy.so */, E35CCEEA15BF2EE100D76F6C /* AllowNothingService.so */, E35CCEF215BF2EFB00D76F6C /* CookieService.so */, E35CCEFA15BF2F0800D76F6C /* EchoService.so */, E35CCF0215BF2F1300D76F6C /* FileService.so */, E35CCF0A15BF2F1E00D76F6C /* HelloService.so */, E35CCF1215BF2F2900D76F6C /* LogService.so */, E35CCF1A15BF2F5700D76F6C /* hasCreateAndDestroy.so */, E35CCF2215BF2F6F00D76F6C /* hasNoCreate.so */, E35CCF6B15BF30AA00D76F6C /* helloserver */, E3474EA2162E0D99003AA5ED /* libpion-pic.a */, E3474F23162E1053003AA5ED /* libpion.a */, ); name = Products; sourceTree = ""; }; 6140E4F116111BED0052E5A0 /* spdy */ = { isa = PBXGroup; children = ( 6140E4F216111BED0052E5A0 /* decompressor.hpp */, 6140E4F316111BED0052E5A0 /* parser.hpp */, 6140E4F416111BED0052E5A0 /* types.hpp */, ); name = spdy; path = include/pion/spdy; sourceTree = ""; }; E35CCE5315BF2CAF00D76F6C /* include */ = { isa = PBXGroup; children = ( 6140E4F116111BED0052E5A0 /* spdy */, E35CCE6E15BF2D1300D76F6C /* tcp */, E35CCE6F15BF2D1800D76F6C /* http */, E3B5EA9715C895E00023988F /* test */, E35CCE5815BF2D0E00D76F6C /* admin_rights.hpp */, E35CCE5915BF2D0E00D76F6C /* algorithm.hpp */, E35CCE5A15BF2D0E00D76F6C /* config.hpp */, E31BC82615C1D24600168895 /* error.hpp */, E35CCE5C15BF2D0E00D76F6C /* hash_map.hpp */, E35CCE5D15BF2D0E00D76F6C /* logger.hpp */, E35CCE5F15BF2D0E00D76F6C /* plugin.hpp */, E35CCE5E15BF2D0E00D76F6C /* plugin_manager.hpp */, E35CCE6015BF2D0E00D76F6C /* process.hpp */, E35CCE6115BF2D0E00D76F6C /* scheduler.hpp */, E3A00AE915CC740A00F79569 /* user.hpp */, ); name = include; sourceTree = ""; }; E35CCE5415BF2CB400D76F6C /* src */ = { isa = PBXGroup; children = ( E35CCE9C15BF2D8A00D76F6C /* admin_rights.cpp */, E35CCE9D15BF2D8A00D76F6C /* algorithm.cpp */, E35CCE9E15BF2D8A00D76F6C /* http_auth.cpp */, E35CCE9F15BF2D8A00D76F6C /* http_basic_auth.cpp */, E35CCEA015BF2D8A00D76F6C /* http_cookie_auth.cpp */, E35CCEA115BF2D8A00D76F6C /* http_message.cpp */, E35CCEA215BF2D8A00D76F6C /* http_parser.cpp */, E35CCEA315BF2D8A00D76F6C /* http_plugin_server.cpp */, E35CCEA415BF2D8A00D76F6C /* http_reader.cpp */, E35CCEA515BF2D8A00D76F6C /* http_server.cpp */, E35CCEA615BF2D8A00D76F6C /* http_types.cpp */, E35CCEA715BF2D8A00D76F6C /* http_writer.cpp */, E35CCEA815BF2D8A00D76F6C /* logger.cpp */, E35CCEA915BF2D8A00D76F6C /* plugin.cpp */, E35CCEAA15BF2D8A00D76F6C /* process.cpp */, E35CCEAB15BF2D8A00D76F6C /* scheduler.cpp */, 61AECC9E161268B300BF2B16 /* spdy_decompressor.cpp */, 61AECC9F161268B300BF2B16 /* spdy_parser.cpp */, E35CCEAC15BF2D8A00D76F6C /* tcp_server.cpp */, E35CCEAD15BF2D8A00D76F6C /* tcp_timer.cpp */, ); name = src; sourceTree = ""; }; E35CCE5515BF2CB800D76F6C /* services */ = { isa = PBXGroup; children = ( E35CCEC015BF2DB500D76F6C /* AllowNothingService.cpp */, E35CCEC115BF2DB500D76F6C /* AllowNothingService.hpp */, E35CCEC215BF2DB500D76F6C /* CookieService.cpp */, E35CCEC315BF2DB500D76F6C /* CookieService.hpp */, E35CCEC415BF2DB500D76F6C /* EchoService.cpp */, E35CCEC515BF2DB500D76F6C /* EchoService.hpp */, E35CCEC615BF2DB500D76F6C /* FileService.cpp */, E35CCEC715BF2DB500D76F6C /* FileService.hpp */, E35CCEC815BF2DB500D76F6C /* HelloService.cpp */, E35CCEC915BF2DB500D76F6C /* HelloService.hpp */, E35CCECA15BF2DB500D76F6C /* LogService.cpp */, E35CCECB15BF2DB500D76F6C /* LogService.hpp */, ); name = services; sourceTree = ""; }; E35CCE5615BF2CC000D76F6C /* utils */ = { isa = PBXGroup; children = ( E35CCECC15BF2DC800D76F6C /* helloserver.cpp */, E35CCECD15BF2DC800D76F6C /* piond.cpp */, ); name = utils; sourceTree = ""; }; E35CCE5715BF2CC600D76F6C /* tests */ = { isa = PBXGroup; children = ( E35CCFB015BF3AAF00D76F6C /* config */, E35CCEDB15BF2E1F00D76F6C /* plugins */, E35CCECE15BF2DE500D76F6C /* algorithm_tests.cpp */, E35CCECF15BF2DE500D76F6C /* file_service_tests.cpp */, E35CCED015BF2DE500D76F6C /* http_message_tests.cpp */, E35CCED115BF2DE500D76F6C /* http_parser_tests.cpp */, E35CCED215BF2DE500D76F6C /* http_plugin_server_tests.cpp */, E35CCED315BF2DE500D76F6C /* http_request_tests.cpp */, E35CCED415BF2DE500D76F6C /* http_response_tests.cpp */, E35CCED515BF2DE500D76F6C /* http_types_tests.cpp */, E35CCED615BF2DE500D76F6C /* piontests.cpp */, E35CCED715BF2DE500D76F6C /* plugin_manager_tests.cpp */, E35CCED815BF2DE500D76F6C /* plugin_tests.cpp */, E3623BE417FB96DA00A14A84 /* process_tests.cpp */, 61AECCA21612699D00BF2B16 /* spdy_parser_tests.cpp */, E35CCED915BF2DE500D76F6C /* tcp_server_tests.cpp */, E35CCEDA15BF2DE500D76F6C /* tcp_stream_tests.cpp */, ); name = tests; sourceTree = ""; }; E35CCE6E15BF2D1300D76F6C /* tcp */ = { isa = PBXGroup; children = ( E35CCE7015BF2D4700D76F6C /* connection.hpp */, E35CCE7115BF2D4700D76F6C /* server.hpp */, E35CCE7215BF2D4700D76F6C /* stream.hpp */, E35CCE7315BF2D4700D76F6C /* timer.hpp */, ); name = tcp; sourceTree = ""; }; E35CCE6F15BF2D1800D76F6C /* http */ = { isa = PBXGroup; children = ( E35CCE7815BF2D5B00D76F6C /* auth.hpp */, E35CCE7915BF2D5B00D76F6C /* basic_auth.hpp */, E35CCE7A15BF2D5B00D76F6C /* cookie_auth.hpp */, E35CCE7B15BF2D5B00D76F6C /* message.hpp */, E35CCE7C15BF2D5B00D76F6C /* parser.hpp */, E35CCE7D15BF2D5B00D76F6C /* plugin_server.hpp */, E35CCE7E15BF2D5B00D76F6C /* plugin_service.hpp */, E35CCE7F15BF2D5B00D76F6C /* reader.hpp */, E35CCE8015BF2D5B00D76F6C /* request_reader.hpp */, E35CCE8115BF2D5B00D76F6C /* request_writer.hpp */, E35CCE8215BF2D5B00D76F6C /* request.hpp */, E35CCE8315BF2D5B00D76F6C /* response_reader.hpp */, E35CCE8415BF2D5B00D76F6C /* response_writer.hpp */, E35CCE8515BF2D5B00D76F6C /* response.hpp */, E35CCE8615BF2D5B00D76F6C /* server.hpp */, E35CCE8715BF2D5B00D76F6C /* types.hpp */, E35CCE8915BF2D5B00D76F6C /* writer.hpp */, ); name = http; sourceTree = ""; }; E35CCEDB15BF2E1F00D76F6C /* plugins */ = { isa = PBXGroup; children = ( E35CCEDC15BF2E4100D76F6C /* hasCreateAndDestroy.cpp */, E35CCEDD15BF2E4100D76F6C /* hasCreateAndDestroy.hpp */, E35CCEDE15BF2E4100D76F6C /* hasCreateButNoDestroy.cpp */, E35CCEDF15BF2E4100D76F6C /* hasCreateButNoDestroy.hpp */, E35CCEE015BF2E4100D76F6C /* hasNoCreate.cpp */, E35CCEE115BF2E4100D76F6C /* hasNoCreate.hpp */, E35CCEE215BF2E4100D76F6C /* InterfaceStub.hpp */, ); name = plugins; sourceTree = ""; }; E35CCFB015BF3AAF00D76F6C /* config */ = { isa = PBXGroup; children = ( E35CCFB115BF3AB600D76F6C /* testservices.conf */, ); name = config; sourceTree = ""; }; E3B5EA9715C895E00023988F /* test */ = { isa = PBXGroup; children = ( E3B5EA9915C896050023988F /* unit_test.hpp */, ); name = test; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ E3474E65162E0D99003AA5ED /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E3474E66162E0D99003AA5ED /* admin_rights.hpp in Headers */, E3474E67162E0D99003AA5ED /* algorithm.hpp in Headers */, E3474E68162E0D99003AA5ED /* config.hpp in Headers */, E3474E69162E0D99003AA5ED /* hash_map.hpp in Headers */, E3474E6A162E0D99003AA5ED /* logger.hpp in Headers */, E3474E6B162E0D99003AA5ED /* plugin_manager.hpp in Headers */, E3474E6C162E0D99003AA5ED /* plugin.hpp in Headers */, E3474E6D162E0D99003AA5ED /* process.hpp in Headers */, E3474E6E162E0D99003AA5ED /* scheduler.hpp in Headers */, E3474E6F162E0D99003AA5ED /* connection.hpp in Headers */, E3474E70162E0D99003AA5ED /* server.hpp in Headers */, E3474E71162E0D99003AA5ED /* stream.hpp in Headers */, E3474E72162E0D99003AA5ED /* timer.hpp in Headers */, E3474E73162E0D99003AA5ED /* auth.hpp in Headers */, E3474E74162E0D99003AA5ED /* basic_auth.hpp in Headers */, E3474E75162E0D99003AA5ED /* cookie_auth.hpp in Headers */, E3474E76162E0D99003AA5ED /* message.hpp in Headers */, E3474E77162E0D99003AA5ED /* parser.hpp in Headers */, E3474E78162E0D99003AA5ED /* plugin_server.hpp in Headers */, E3474E79162E0D99003AA5ED /* plugin_service.hpp in Headers */, E3474E7A162E0D99003AA5ED /* reader.hpp in Headers */, E3474E7B162E0D99003AA5ED /* request_reader.hpp in Headers */, E3474E7C162E0D99003AA5ED /* request_writer.hpp in Headers */, E3474E7D162E0D99003AA5ED /* request.hpp in Headers */, E3474E7E162E0D99003AA5ED /* response_reader.hpp in Headers */, E3474E7F162E0D99003AA5ED /* response_writer.hpp in Headers */, E3474E80162E0D99003AA5ED /* response.hpp in Headers */, E3474E81162E0D99003AA5ED /* server.hpp in Headers */, E3474E82162E0D99003AA5ED /* types.hpp in Headers */, E3474E83162E0D99003AA5ED /* writer.hpp in Headers */, E3474E84162E0D99003AA5ED /* error.hpp in Headers */, E3474E85162E0D99003AA5ED /* user.hpp in Headers */, E3474E86162E0D99003AA5ED /* decompressor.hpp in Headers */, E3474E87162E0D99003AA5ED /* parser.hpp in Headers */, E3474E88162E0D99003AA5ED /* types.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E3474EE6162E1053003AA5ED /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E3474EE7162E1053003AA5ED /* admin_rights.hpp in Headers */, E3474EE8162E1053003AA5ED /* algorithm.hpp in Headers */, E3474EE9162E1053003AA5ED /* config.hpp in Headers */, E3474EEA162E1053003AA5ED /* hash_map.hpp in Headers */, E3474EEB162E1053003AA5ED /* logger.hpp in Headers */, E3474EEC162E1053003AA5ED /* plugin_manager.hpp in Headers */, E3474EED162E1053003AA5ED /* plugin.hpp in Headers */, E3474EEE162E1053003AA5ED /* process.hpp in Headers */, E3474EEF162E1053003AA5ED /* scheduler.hpp in Headers */, E3474EF0162E1053003AA5ED /* connection.hpp in Headers */, E3474EF1162E1053003AA5ED /* server.hpp in Headers */, E3474EF2162E1053003AA5ED /* stream.hpp in Headers */, E3474EF3162E1053003AA5ED /* timer.hpp in Headers */, E3474EF4162E1053003AA5ED /* auth.hpp in Headers */, E3474EF5162E1053003AA5ED /* basic_auth.hpp in Headers */, E3474EF6162E1053003AA5ED /* cookie_auth.hpp in Headers */, E3474EF7162E1053003AA5ED /* message.hpp in Headers */, E3474EF8162E1053003AA5ED /* parser.hpp in Headers */, E3474EF9162E1053003AA5ED /* plugin_server.hpp in Headers */, E3474EFA162E1053003AA5ED /* plugin_service.hpp in Headers */, E3474EFB162E1053003AA5ED /* reader.hpp in Headers */, E3474EFC162E1053003AA5ED /* request_reader.hpp in Headers */, E3474EFD162E1053003AA5ED /* request_writer.hpp in Headers */, E3474EFE162E1053003AA5ED /* request.hpp in Headers */, E3474EFF162E1053003AA5ED /* response_reader.hpp in Headers */, E3474F00162E1053003AA5ED /* response_writer.hpp in Headers */, E3474F01162E1053003AA5ED /* response.hpp in Headers */, E3474F02162E1053003AA5ED /* server.hpp in Headers */, E3474F03162E1053003AA5ED /* types.hpp in Headers */, E3474F04162E1053003AA5ED /* writer.hpp in Headers */, E3474F05162E1053003AA5ED /* error.hpp in Headers */, E3474F06162E1053003AA5ED /* user.hpp in Headers */, E3474F07162E1053003AA5ED /* decompressor.hpp in Headers */, E3474F08162E1053003AA5ED /* parser.hpp in Headers */, E3474F09162E1053003AA5ED /* types.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEE415BF2EE100D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4815BF304E00D76F6C /* AllowNothingService.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEEC15BF2EFB00D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4915BF305100D76F6C /* CookieService.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEF415BF2F0800D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4C15BF305A00D76F6C /* EchoService.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEFC15BF2F1300D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4E15BF305E00D76F6C /* FileService.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF0415BF2F1E00D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4F15BF306200D76F6C /* HelloService.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF0C15BF2F2900D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF5115BF307100D76F6C /* LogService.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF1415BF2F5700D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3F15BF2FFF00D76F6C /* hasCreateAndDestroy.hpp in Headers */, E35CCF4415BF303F00D76F6C /* InterfaceStub.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF1C15BF2F6F00D76F6C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4315BF302300D76F6C /* hasNoCreate.hpp in Headers */, E35CCF4615BF304700D76F6C /* InterfaceStub.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E36D8A5B0D29C9D800B4C134 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCE6315BF2D0E00D76F6C /* admin_rights.hpp in Headers */, E35CCE6415BF2D0E00D76F6C /* algorithm.hpp in Headers */, E35CCE6515BF2D0E00D76F6C /* config.hpp in Headers */, E35CCE6715BF2D0E00D76F6C /* hash_map.hpp in Headers */, E35CCE6815BF2D0E00D76F6C /* logger.hpp in Headers */, E35CCE6915BF2D0E00D76F6C /* plugin_manager.hpp in Headers */, E35CCE6A15BF2D0E00D76F6C /* plugin.hpp in Headers */, E35CCE6B15BF2D0E00D76F6C /* process.hpp in Headers */, E35CCE6C15BF2D0E00D76F6C /* scheduler.hpp in Headers */, E35CCE7415BF2D4700D76F6C /* connection.hpp in Headers */, E35CCE7515BF2D4700D76F6C /* server.hpp in Headers */, E35CCE7615BF2D4700D76F6C /* stream.hpp in Headers */, E35CCE7715BF2D4700D76F6C /* timer.hpp in Headers */, E35CCE8A15BF2D5B00D76F6C /* auth.hpp in Headers */, E35CCE8B15BF2D5B00D76F6C /* basic_auth.hpp in Headers */, E35CCE8C15BF2D5B00D76F6C /* cookie_auth.hpp in Headers */, E35CCE8D15BF2D5B00D76F6C /* message.hpp in Headers */, E35CCE8E15BF2D5B00D76F6C /* parser.hpp in Headers */, E35CCE8F15BF2D5B00D76F6C /* plugin_server.hpp in Headers */, E35CCE9015BF2D5B00D76F6C /* plugin_service.hpp in Headers */, E35CCE9115BF2D5B00D76F6C /* reader.hpp in Headers */, E35CCE9215BF2D5B00D76F6C /* request_reader.hpp in Headers */, E35CCE9315BF2D5B00D76F6C /* request_writer.hpp in Headers */, E35CCE9415BF2D5B00D76F6C /* request.hpp in Headers */, E35CCE9515BF2D5B00D76F6C /* response_reader.hpp in Headers */, E35CCE9615BF2D5B00D76F6C /* response_writer.hpp in Headers */, E35CCE9715BF2D5B00D76F6C /* response.hpp in Headers */, E35CCE9815BF2D5B00D76F6C /* server.hpp in Headers */, E35CCE9915BF2D5B00D76F6C /* types.hpp in Headers */, E35CCE9B15BF2D5B00D76F6C /* writer.hpp in Headers */, E31BC82715C1D24600168895 /* error.hpp in Headers */, E3A00AEA15CC740A00F79569 /* user.hpp in Headers */, 6140E4F516111BED0052E5A0 /* decompressor.hpp in Headers */, 6140E4F616111BED0052E5A0 /* parser.hpp in Headers */, 6140E4F716111BED0052E5A0 /* types.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E370CF13158E6BAB00E46EE9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E3B5EA9A15C896050023988F /* unit_test.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; E370CF26158E6C1A00E46EE9 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4115BF301700D76F6C /* hasCreateButNoDestroy.hpp in Headers */, E35CCF4515BF304300D76F6C /* InterfaceStub.hpp in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ E3474E63162E0D99003AA5ED /* pion: static pic */ = { isa = PBXNativeTarget; buildConfigurationList = E3474E9F162E0D99003AA5ED /* Build configuration list for PBXNativeTarget "pion: static pic" */; buildPhases = ( E3474E64162E0D99003AA5ED /* ShellScript */, E3474E65162E0D99003AA5ED /* Headers */, E3474E89162E0D99003AA5ED /* Sources */, E3474E9E162E0D99003AA5ED /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "pion: static pic"; productName = "pion-net: dynamic"; productReference = E3474EA2162E0D99003AA5ED /* libpion-pic.a */; productType = "com.apple.product-type.library.dynamic"; }; E3474EE4162E1053003AA5ED /* pion: static */ = { isa = PBXNativeTarget; buildConfigurationList = E3474F20162E1053003AA5ED /* Build configuration list for PBXNativeTarget "pion: static" */; buildPhases = ( E3474EE5162E1053003AA5ED /* ShellScript */, E3474EE6162E1053003AA5ED /* Headers */, E3474F0A162E1053003AA5ED /* Sources */, E3474F1F162E1053003AA5ED /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "pion: static"; productName = "pion-net: dynamic"; productReference = E3474F23162E1053003AA5ED /* libpion.a */; productType = "com.apple.product-type.library.dynamic"; }; E35CCEE315BF2EE100D76F6C /* AllowNothingService */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCEE715BF2EE100D76F6C /* Build configuration list for PBXNativeTarget "AllowNothingService" */; buildPhases = ( E35CCEE415BF2EE100D76F6C /* Headers */, E35CCEE515BF2EE100D76F6C /* Sources */, E35CCEE615BF2EE100D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF2B15BF2FA500D76F6C /* PBXTargetDependency */, ); name = AllowNothingService; productName = ELFCodec; productReference = E35CCEEA15BF2EE100D76F6C /* AllowNothingService.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCEEB15BF2EFB00D76F6C /* CookieService */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCEEF15BF2EFB00D76F6C /* Build configuration list for PBXNativeTarget "CookieService" */; buildPhases = ( E35CCEEC15BF2EFB00D76F6C /* Headers */, E35CCEED15BF2EFB00D76F6C /* Sources */, E35CCEEE15BF2EFB00D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF2D15BF2FA800D76F6C /* PBXTargetDependency */, ); name = CookieService; productName = ELFCodec; productReference = E35CCEF215BF2EFB00D76F6C /* CookieService.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCEF315BF2F0800D76F6C /* EchoService */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCEF715BF2F0800D76F6C /* Build configuration list for PBXNativeTarget "EchoService" */; buildPhases = ( E35CCEF415BF2F0800D76F6C /* Headers */, E35CCEF515BF2F0800D76F6C /* Sources */, E35CCEF615BF2F0800D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF2F15BF2FAB00D76F6C /* PBXTargetDependency */, ); name = EchoService; productName = ELFCodec; productReference = E35CCEFA15BF2F0800D76F6C /* EchoService.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCEFB15BF2F1300D76F6C /* FileService */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCEFF15BF2F1300D76F6C /* Build configuration list for PBXNativeTarget "FileService" */; buildPhases = ( E35CCEFC15BF2F1300D76F6C /* Headers */, E35CCEFD15BF2F1300D76F6C /* Sources */, E35CCEFE15BF2F1300D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF3115BF2FAE00D76F6C /* PBXTargetDependency */, ); name = FileService; productName = ELFCodec; productReference = E35CCF0215BF2F1300D76F6C /* FileService.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCF0315BF2F1E00D76F6C /* HelloService */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCF0715BF2F1E00D76F6C /* Build configuration list for PBXNativeTarget "HelloService" */; buildPhases = ( E35CCF0415BF2F1E00D76F6C /* Headers */, E35CCF0515BF2F1E00D76F6C /* Sources */, E35CCF0615BF2F1E00D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF3315BF2FB100D76F6C /* PBXTargetDependency */, ); name = HelloService; productName = ELFCodec; productReference = E35CCF0A15BF2F1E00D76F6C /* HelloService.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCF0B15BF2F2900D76F6C /* LogService */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCF0F15BF2F2900D76F6C /* Build configuration list for PBXNativeTarget "LogService" */; buildPhases = ( E35CCF0C15BF2F2900D76F6C /* Headers */, E35CCF0D15BF2F2900D76F6C /* Sources */, E35CCF0E15BF2F2900D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF3515BF2FB300D76F6C /* PBXTargetDependency */, ); name = LogService; productName = ELFCodec; productReference = E35CCF1215BF2F2900D76F6C /* LogService.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCF1315BF2F5700D76F6C /* hasCreateAndDestroy */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCF1715BF2F5700D76F6C /* Build configuration list for PBXNativeTarget "hasCreateAndDestroy" */; buildPhases = ( E35CCF1415BF2F5700D76F6C /* Headers */, E35CCF1515BF2F5700D76F6C /* Sources */, E35CCF1615BF2F5700D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF2515BF2F9A00D76F6C /* PBXTargetDependency */, ); name = hasCreateAndDestroy; productName = ELFCodec; productReference = E35CCF1A15BF2F5700D76F6C /* hasCreateAndDestroy.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCF1B15BF2F6F00D76F6C /* hasNoCreate */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCF1F15BF2F6F00D76F6C /* Build configuration list for PBXNativeTarget "hasNoCreate" */; buildPhases = ( E35CCF1C15BF2F6F00D76F6C /* Headers */, E35CCF1D15BF2F6F00D76F6C /* Sources */, E35CCF1E15BF2F6F00D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF2915BF2FA200D76F6C /* PBXTargetDependency */, ); name = hasNoCreate; productName = ELFCodec; productReference = E35CCF2215BF2F6F00D76F6C /* hasNoCreate.so */; productType = "com.apple.product-type.library.dynamic"; }; E35CCF6115BF30AA00D76F6C /* helloserver */ = { isa = PBXNativeTarget; buildConfigurationList = E35CCF6815BF30AA00D76F6C /* Build configuration list for PBXNativeTarget "helloserver" */; buildPhases = ( E35CCF6415BF30AA00D76F6C /* Sources */, E35CCF6615BF30AA00D76F6C /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF6215BF30AA00D76F6C /* PBXTargetDependency */, ); name = helloserver; productName = piond; productReference = E35CCF6B15BF30AA00D76F6C /* helloserver */; productType = "com.apple.product-type.tool"; }; E36D8A5E0D29C9D800B4C134 /* pion: dynamic */ = { isa = PBXNativeTarget; buildConfigurationList = E36D8A9F0D29CB0F00B4C134 /* Build configuration list for PBXNativeTarget "pion: dynamic" */; buildPhases = ( E374024E15CEF78A00208977 /* ShellScript */, E36D8A5B0D29C9D800B4C134 /* Headers */, E36D8A5C0D29C9D800B4C134 /* Sources */, E36D8A5D0D29C9D800B4C134 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "pion: dynamic"; productName = "pion-net: dynamic"; productReference = E36D8A5F0D29C9D800B4C134 /* libpion.dylib */; productType = "com.apple.product-type.library.dynamic"; }; E36D8BE60D29D6DC00B4C134 /* piond */ = { isa = PBXNativeTarget; buildConfigurationList = E36D8C0A0D29D75C00B4C134 /* Build configuration list for PBXNativeTarget "piond" */; buildPhases = ( E36D8BE40D29D6DC00B4C134 /* Sources */, E36D8BE50D29D6DC00B4C134 /* Frameworks */, ); buildRules = ( ); dependencies = ( E36D8BEE0D29D6F200B4C134 /* PBXTargetDependency */, ); name = piond; productName = piond; productReference = E36D8BE70D29D6DC00B4C134 /* piond */; productType = "com.apple.product-type.tool"; }; E370CE78158D962700E46EE9 /* piontests */ = { isa = PBXNativeTarget; buildConfigurationList = E370CEBD158D962700E46EE9 /* Build configuration list for PBXNativeTarget "piontests" */; buildPhases = ( E370CF13158E6BAB00E46EE9 /* Headers */, E370CEA5158D962700E46EE9 /* Sources */, E370CEB8158D962700E46EE9 /* Frameworks */, ); buildRules = ( ); dependencies = ( E370CE7D158D962700E46EE9 /* PBXTargetDependency */, ); name = piontests; productName = PionReactorUnitTests; productReference = E370CEC0158D962700E46EE9 /* piontests */; productType = "com.apple.product-type.tool"; }; E370CF23158E6C1A00E46EE9 /* hasCreateButNoDestroy */ = { isa = PBXNativeTarget; buildConfigurationList = E370CF2D158E6C1A00E46EE9 /* Build configuration list for PBXNativeTarget "hasCreateButNoDestroy" */; buildPhases = ( E370CF26158E6C1A00E46EE9 /* Headers */, E370CF28158E6C1A00E46EE9 /* Sources */, E370CF2A158E6C1A00E46EE9 /* Frameworks */, ); buildRules = ( ); dependencies = ( E35CCF2715BF2F9F00D76F6C /* PBXTargetDependency */, ); name = hasCreateButNoDestroy; productName = ELFCodec; productReference = E370CF30158E6C1A00E46EE9 /* hasCreateButNoDestroy.so */; productType = "com.apple.product-type.library.dynamic"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0510; }; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "pion" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( en, ); mainGroup = 08FB7794FE84155DC02AAC07 /* libpion */; projectDirPath = ""; projectRoot = ""; targets = ( E36D8A5E0D29C9D800B4C134 /* pion: dynamic */, E3474EE4162E1053003AA5ED /* pion: static */, E3474E63162E0D99003AA5ED /* pion: static pic */, E35CCF1315BF2F5700D76F6C /* hasCreateAndDestroy */, E370CF23158E6C1A00E46EE9 /* hasCreateButNoDestroy */, E35CCF1B15BF2F6F00D76F6C /* hasNoCreate */, E35CCEE315BF2EE100D76F6C /* AllowNothingService */, E35CCEEB15BF2EFB00D76F6C /* CookieService */, E35CCEF315BF2F0800D76F6C /* EchoService */, E35CCEFB15BF2F1300D76F6C /* FileService */, E35CCF0315BF2F1E00D76F6C /* HelloService */, E35CCF0B15BF2F2900D76F6C /* LogService */, E35CCF6115BF30AA00D76F6C /* helloserver */, E36D8BE60D29D6DC00B4C134 /* piond */, E370CE78158D962700E46EE9 /* piontests */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ E3474E64162E0D99003AA5ED /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "if [ ! -f \"${PROJECT_DIR}/include/pion/config.hpp\" ]; then\n cp ${PROJECT_DIR}/include/pion/config.hpp.xcode ${PROJECT_DIR}/include/pion/config.hpp\nfi"; }; E3474EE5162E1053003AA5ED /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "if [ ! -f \"${PROJECT_DIR}/include/pion/config.hpp\" ]; then\n cp ${PROJECT_DIR}/include/pion/config.hpp.xcode ${PROJECT_DIR}/include/pion/config.hpp\nfi"; }; E374024E15CEF78A00208977 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "if [ ! -f \"${PROJECT_DIR}/include/pion/config.hpp\" ]; then\n cp ${PROJECT_DIR}/include/pion/config.hpp.xcode ${PROJECT_DIR}/include/pion/config.hpp\nfi"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ E3474E89162E0D99003AA5ED /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E3474E8A162E0D99003AA5ED /* admin_rights.cpp in Sources */, E3474E8B162E0D99003AA5ED /* algorithm.cpp in Sources */, E3474E8C162E0D99003AA5ED /* http_auth.cpp in Sources */, E3474E8D162E0D99003AA5ED /* http_basic_auth.cpp in Sources */, E3474E8E162E0D99003AA5ED /* http_cookie_auth.cpp in Sources */, E3474E8F162E0D99003AA5ED /* http_message.cpp in Sources */, E3474E90162E0D99003AA5ED /* http_parser.cpp in Sources */, E3474E91162E0D99003AA5ED /* http_plugin_server.cpp in Sources */, E3474E92162E0D99003AA5ED /* http_reader.cpp in Sources */, E3474E93162E0D99003AA5ED /* http_server.cpp in Sources */, E3474E94162E0D99003AA5ED /* http_types.cpp in Sources */, E3474E95162E0D99003AA5ED /* http_writer.cpp in Sources */, E3474E96162E0D99003AA5ED /* logger.cpp in Sources */, E3474E97162E0D99003AA5ED /* plugin.cpp in Sources */, E3474E98162E0D99003AA5ED /* process.cpp in Sources */, E3474E99162E0D99003AA5ED /* scheduler.cpp in Sources */, E3474E9A162E0D99003AA5ED /* tcp_server.cpp in Sources */, E3474E9B162E0D99003AA5ED /* tcp_timer.cpp in Sources */, E3474E9C162E0D99003AA5ED /* spdy_decompressor.cpp in Sources */, E3474E9D162E0D99003AA5ED /* spdy_parser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E3474F0A162E1053003AA5ED /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E3474F0B162E1053003AA5ED /* admin_rights.cpp in Sources */, E3474F0C162E1053003AA5ED /* algorithm.cpp in Sources */, E3474F0D162E1053003AA5ED /* http_auth.cpp in Sources */, E3474F0E162E1053003AA5ED /* http_basic_auth.cpp in Sources */, E3474F0F162E1053003AA5ED /* http_cookie_auth.cpp in Sources */, E3474F10162E1053003AA5ED /* http_message.cpp in Sources */, E3474F11162E1053003AA5ED /* http_parser.cpp in Sources */, E3474F12162E1053003AA5ED /* http_plugin_server.cpp in Sources */, E3474F13162E1053003AA5ED /* http_reader.cpp in Sources */, E3474F14162E1053003AA5ED /* http_server.cpp in Sources */, E3474F15162E1053003AA5ED /* http_types.cpp in Sources */, E3474F16162E1053003AA5ED /* http_writer.cpp in Sources */, E3474F17162E1053003AA5ED /* logger.cpp in Sources */, E3474F18162E1053003AA5ED /* plugin.cpp in Sources */, E3474F19162E1053003AA5ED /* process.cpp in Sources */, E3474F1A162E1053003AA5ED /* scheduler.cpp in Sources */, E3474F1B162E1053003AA5ED /* tcp_server.cpp in Sources */, E3474F1C162E1053003AA5ED /* tcp_timer.cpp in Sources */, E3474F1D162E1053003AA5ED /* spdy_decompressor.cpp in Sources */, E3474F1E162E1053003AA5ED /* spdy_parser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEE515BF2EE100D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4715BF304C00D76F6C /* AllowNothingService.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEED15BF2EFB00D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4A15BF305200D76F6C /* CookieService.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEF515BF2F0800D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4B15BF305800D76F6C /* EchoService.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCEFD15BF2F1300D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4D15BF305D00D76F6C /* FileService.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF0515BF2F1E00D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF5015BF306400D76F6C /* HelloService.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF0D15BF2F2900D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF5215BF307400D76F6C /* LogService.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF1515BF2F5700D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF3E15BF2FFA00D76F6C /* hasCreateAndDestroy.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF1D15BF2F6F00D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4215BF302200D76F6C /* hasNoCreate.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E35CCF6415BF30AA00D76F6C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF6D15BF30BE00D76F6C /* helloserver.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E36D8A5C0D29C9D800B4C134 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCEAE15BF2D8A00D76F6C /* admin_rights.cpp in Sources */, E35CCEAF15BF2D8A00D76F6C /* algorithm.cpp in Sources */, E35CCEB015BF2D8A00D76F6C /* http_auth.cpp in Sources */, E35CCEB115BF2D8A00D76F6C /* http_basic_auth.cpp in Sources */, E35CCEB215BF2D8A00D76F6C /* http_cookie_auth.cpp in Sources */, E35CCEB315BF2D8A00D76F6C /* http_message.cpp in Sources */, E35CCEB415BF2D8A00D76F6C /* http_parser.cpp in Sources */, E35CCEB515BF2D8A00D76F6C /* http_plugin_server.cpp in Sources */, E35CCEB615BF2D8A00D76F6C /* http_reader.cpp in Sources */, E35CCEB715BF2D8A00D76F6C /* http_server.cpp in Sources */, E35CCEB815BF2D8A00D76F6C /* http_types.cpp in Sources */, E35CCEB915BF2D8A00D76F6C /* http_writer.cpp in Sources */, E35CCEBA15BF2D8A00D76F6C /* logger.cpp in Sources */, E35CCEBB15BF2D8A00D76F6C /* plugin.cpp in Sources */, E35CCEBC15BF2D8A00D76F6C /* process.cpp in Sources */, E35CCEBD15BF2D8A00D76F6C /* scheduler.cpp in Sources */, E35CCEBE15BF2D8A00D76F6C /* tcp_server.cpp in Sources */, E35CCEBF15BF2D8A00D76F6C /* tcp_timer.cpp in Sources */, 61AECCA0161268B300BF2B16 /* spdy_decompressor.cpp in Sources */, 61AECCA1161268B300BF2B16 /* spdy_parser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E36D8BE40D29D6DC00B4C134 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF5315BF307B00D76F6C /* piond.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E370CEA5158D962700E46EE9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E3A1AE3315C87FD500FFE9E3 /* algorithm_tests.cpp in Sources */, E3A1AE3415C87FD500FFE9E3 /* file_service_tests.cpp in Sources */, E3A1AE3515C87FD500FFE9E3 /* http_message_tests.cpp in Sources */, E3A1AE3615C87FD500FFE9E3 /* http_parser_tests.cpp in Sources */, E3A1AE3715C87FD500FFE9E3 /* http_plugin_server_tests.cpp in Sources */, E3A1AE3815C87FD500FFE9E3 /* http_request_tests.cpp in Sources */, E3A1AE3915C87FD500FFE9E3 /* http_response_tests.cpp in Sources */, E3A1AE3A15C87FD500FFE9E3 /* plugin_manager_tests.cpp in Sources */, E3A1AE3B15C87FD500FFE9E3 /* plugin_tests.cpp in Sources */, E3A1AE3C15C87FD500FFE9E3 /* tcp_server_tests.cpp in Sources */, E3A1AE3D15C87FD500FFE9E3 /* tcp_stream_tests.cpp in Sources */, E3A1AE3215C878E100FFE9E3 /* piontests.cpp in Sources */, E35CCF5B15BF30A300D76F6C /* http_types_tests.cpp in Sources */, 61AECCA4161269BF00BF2B16 /* spdy_parser_tests.cpp in Sources */, E3623BE517FB96DA00A14A84 /* process_tests.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; E370CF28158E6C1A00E46EE9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E35CCF4015BF300600D76F6C /* hasCreateButNoDestroy.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ E35CCF2515BF2F9A00D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF2415BF2F9A00D76F6C /* PBXContainerItemProxy */; }; E35CCF2715BF2F9F00D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF2615BF2F9F00D76F6C /* PBXContainerItemProxy */; }; E35CCF2915BF2FA200D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF2815BF2FA200D76F6C /* PBXContainerItemProxy */; }; E35CCF2B15BF2FA500D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF2A15BF2FA500D76F6C /* PBXContainerItemProxy */; }; E35CCF2D15BF2FA800D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF2C15BF2FA800D76F6C /* PBXContainerItemProxy */; }; E35CCF2F15BF2FAB00D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF2E15BF2FAB00D76F6C /* PBXContainerItemProxy */; }; E35CCF3115BF2FAE00D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF3015BF2FAE00D76F6C /* PBXContainerItemProxy */; }; E35CCF3315BF2FB100D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF3215BF2FB100D76F6C /* PBXContainerItemProxy */; }; E35CCF3515BF2FB300D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF3415BF2FB300D76F6C /* PBXContainerItemProxy */; }; E35CCF6215BF30AA00D76F6C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E35CCF6315BF30AA00D76F6C /* PBXContainerItemProxy */; }; E36D8BEE0D29D6F200B4C134 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E36D8BED0D29D6F200B4C134 /* PBXContainerItemProxy */; }; E370CE7D158D962700E46EE9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E36D8A5E0D29C9D800B4C134 /* pion: dynamic */; targetProxy = E370CE7E158D962700E46EE9 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 1DEB923608733DC60010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BOOST_VERSION = 1.51.0; CLANG_CXX_LIBRARY = "libstdc++"; DEP_PATH = "/Users/$(USER)/.cloudmeter"; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( _REENTRANT, PION_XCODE, ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; ICU_VERSION = 49.1.2; LIBRARY_SEARCH_PATHS = "$(CONFIGURATION_BUILD_DIR)"; LOG4CPLUS_VERSION = 1.0.4.1; OBJROOT = "$(PROJECT_DIR)/bin/tmp"; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "-fkeep-inline-functions", "-isystem", "$(DEP_PATH)/openssl-$(SSL_VERSION)/include", ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-isystem", "$(DEP_PATH)/log4cplus-$(LOG4CPLUS_VERSION)/include", "-isystem", "$(DEP_PATH)/boost-$(BOOST_VERSION)/include", ); OTHER_LDFLAGS = ( "-lz", "-lbz2", ); SDKROOT = macosx; SSL_VERSION = 1.0.1h; SYMROOT = "$(PROJECT_DIR)/bin"; USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/include"; }; name = Debug; }; 1DEB923708733DC60010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BOOST_VERSION = 1.51.0; CLANG_CXX_LIBRARY = "libstdc++"; DEP_PATH = "/Users/$(USER)/.cloudmeter"; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = ( _REENTRANT, PION_XCODE, NDEBUG, ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; ICU_VERSION = 49.1.2; LIBRARY_SEARCH_PATHS = "$(CONFIGURATION_BUILD_DIR)"; LOG4CPLUS_VERSION = 1.0.4.1; OBJROOT = "$(PROJECT_DIR)/bin/tmp"; OTHER_CFLAGS = ( "-isystem", "$(DEP_PATH)/openssl-$(SSL_VERSION)/include", ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-isystem", "$(DEP_PATH)/log4cplus-$(LOG4CPLUS_VERSION)/include", "-isystem", "$(DEP_PATH)/boost-$(BOOST_VERSION)/include", ); OTHER_LDFLAGS = ( "-lz", "-lbz2", ); SDKROOT = macosx; SSL_VERSION = 1.0.1h; SYMROOT = "$(PROJECT_DIR)/bin"; USER_HEADER_SEARCH_PATHS = "${PROJECT_DIR}/include"; }; name = Release; }; E3474EA0162E0D99003AA5ED /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = lib; INSTALL_PATH = /usr/local/lib; MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; PRODUCT_NAME = "pion-pic"; }; name = Debug; }; E3474EA1162E0D99003AA5ED /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = lib; INSTALL_PATH = /usr/local/lib; MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; PRODUCT_NAME = "pion-pic"; }; name = Release; }; E3474F21162E1053003AA5ED /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = lib; GCC_DYNAMIC_NO_PIC = YES; INSTALL_PATH = /usr/local/lib; MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; PRODUCT_NAME = pion; }; name = Debug; }; E3474F22162E1053003AA5ED /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = lib; GCC_DYNAMIC_NO_PIC = YES; INSTALL_PATH = /usr/local/lib; MACH_O_TYPE = staticlib; OTHER_LDFLAGS = ""; PRODUCT_NAME = pion; }; name = Release; }; E35CCEE815BF2EE100D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = AllowNothingService; }; name = Debug; }; E35CCEE915BF2EE100D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = AllowNothingService; }; name = Release; }; E35CCEF015BF2EFB00D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = CookieService; }; name = Debug; }; E35CCEF115BF2EFB00D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = CookieService; }; name = Release; }; E35CCEF815BF2F0800D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = EchoService; }; name = Debug; }; E35CCEF915BF2F0800D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = EchoService; }; name = Release; }; E35CCF0015BF2F1300D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = FileService; }; name = Debug; }; E35CCF0115BF2F1300D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = FileService; }; name = Release; }; E35CCF0815BF2F1E00D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = HelloService; }; name = Debug; }; E35CCF0915BF2F1E00D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = HelloService; }; name = Release; }; E35CCF1015BF2F2900D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = LogService; }; name = Debug; }; E35CCF1115BF2F2900D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = LogService; }; name = Release; }; E35CCF1815BF2F5700D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = hasCreateAndDestroy; }; name = Debug; }; E35CCF1915BF2F5700D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = hasCreateAndDestroy; }; name = Release; }; E35CCF2015BF2F6F00D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = hasNoCreate; }; name = Debug; }; E35CCF2115BF2F6F00D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = hasNoCreate; }; name = Release; }; E35CCF6915BF30AA00D76F6C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = helloserver; }; name = Debug; }; E35CCF6A15BF30AA00D76F6C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = helloserver; }; name = Release; }; E36D8A600D29C9D900B4C134 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = lib; INSTALL_PATH = /usr/local/lib; OTHER_LDFLAGS = ( "-Wl,-force_load", "-Wl,$(DEP_PATH)/openssl-$(SSL_VERSION)/lib/libssl-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/openssl-$(SSL_VERSION)/lib/libcrypto-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicudata-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicui18n-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicutu-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicuuc-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_chrono-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_date_time-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_filesystem-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_iostreams-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_regex-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_signals-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_system-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_thread-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/log4cplus-$(LOG4CPLUS_VERSION)/lib/liblog4cplus-pic.a", "$(OTHER_LDFLAGS)", ); PRODUCT_NAME = pion; }; name = Debug; }; E36D8A610D29C9D900B4C134 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_PREFIX = lib; INSTALL_PATH = /usr/local/lib; OTHER_LDFLAGS = ( "-Wl,-force_load", "-Wl,$(DEP_PATH)/openssl-$(SSL_VERSION)/lib/libssl-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/openssl-$(SSL_VERSION)/lib/libcrypto-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicudata-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicui18n-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicutu-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/icu-$(ICU_VERSION)/lib/libicuuc-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_chrono-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_date_time-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_filesystem-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_iostreams-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_regex-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_signals-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_system-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_thread-pic.a", "-Wl,-force_load", "-Wl,$(DEP_PATH)/log4cplus-$(LOG4CPLUS_VERSION)/lib/liblog4cplus-pic.a", "$(OTHER_LDFLAGS)", ); PRODUCT_NAME = pion; }; name = Release; }; E36D8BE90D29D6DC00B4C134 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = piond; }; name = Debug; }; E36D8BEA0D29D6DC00B4C134 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { INSTALL_PATH = /usr/local/bin; PRODUCT_NAME = piond; }; name = Release; }; E370CEBE158D962700E46EE9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { INSTALL_PATH = /usr/local/bin; OTHER_LDFLAGS = ( "$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_unit_test_framework.a", "$(OTHER_LDFLAGS)", ); PRODUCT_NAME = piontests; }; name = Debug; }; E370CEBF158D962700E46EE9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { INSTALL_PATH = /usr/local/bin; OTHER_LDFLAGS = ( "$(DEP_PATH)/boost-$(BOOST_VERSION)/lib/libboost_unit_test_framework.a", "$(OTHER_LDFLAGS)", ); PRODUCT_NAME = piontests; }; name = Release; }; E370CF2E158E6C1A00E46EE9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = hasCreateButNoDestroy; }; name = Debug; }; E370CF2F158E6C1A00E46EE9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = so; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/share/pion/plugins; PRODUCT_NAME = hasCreateButNoDestroy; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "pion" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB923608733DC60010E9CD /* Debug */, 1DEB923708733DC60010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E3474E9F162E0D99003AA5ED /* Build configuration list for PBXNativeTarget "pion: static pic" */ = { isa = XCConfigurationList; buildConfigurations = ( E3474EA0162E0D99003AA5ED /* Debug */, E3474EA1162E0D99003AA5ED /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E3474F20162E1053003AA5ED /* Build configuration list for PBXNativeTarget "pion: static" */ = { isa = XCConfigurationList; buildConfigurations = ( E3474F21162E1053003AA5ED /* Debug */, E3474F22162E1053003AA5ED /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCEE715BF2EE100D76F6C /* Build configuration list for PBXNativeTarget "AllowNothingService" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCEE815BF2EE100D76F6C /* Debug */, E35CCEE915BF2EE100D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCEEF15BF2EFB00D76F6C /* Build configuration list for PBXNativeTarget "CookieService" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCEF015BF2EFB00D76F6C /* Debug */, E35CCEF115BF2EFB00D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCEF715BF2F0800D76F6C /* Build configuration list for PBXNativeTarget "EchoService" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCEF815BF2F0800D76F6C /* Debug */, E35CCEF915BF2F0800D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCEFF15BF2F1300D76F6C /* Build configuration list for PBXNativeTarget "FileService" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCF0015BF2F1300D76F6C /* Debug */, E35CCF0115BF2F1300D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCF0715BF2F1E00D76F6C /* Build configuration list for PBXNativeTarget "HelloService" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCF0815BF2F1E00D76F6C /* Debug */, E35CCF0915BF2F1E00D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCF0F15BF2F2900D76F6C /* Build configuration list for PBXNativeTarget "LogService" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCF1015BF2F2900D76F6C /* Debug */, E35CCF1115BF2F2900D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCF1715BF2F5700D76F6C /* Build configuration list for PBXNativeTarget "hasCreateAndDestroy" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCF1815BF2F5700D76F6C /* Debug */, E35CCF1915BF2F5700D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCF1F15BF2F6F00D76F6C /* Build configuration list for PBXNativeTarget "hasNoCreate" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCF2015BF2F6F00D76F6C /* Debug */, E35CCF2115BF2F6F00D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E35CCF6815BF30AA00D76F6C /* Build configuration list for PBXNativeTarget "helloserver" */ = { isa = XCConfigurationList; buildConfigurations = ( E35CCF6915BF30AA00D76F6C /* Debug */, E35CCF6A15BF30AA00D76F6C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E36D8A9F0D29CB0F00B4C134 /* Build configuration list for PBXNativeTarget "pion: dynamic" */ = { isa = XCConfigurationList; buildConfigurations = ( E36D8A600D29C9D900B4C134 /* Debug */, E36D8A610D29C9D900B4C134 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E36D8C0A0D29D75C00B4C134 /* Build configuration list for PBXNativeTarget "piond" */ = { isa = XCConfigurationList; buildConfigurations = ( E36D8BE90D29D6DC00B4C134 /* Debug */, E36D8BEA0D29D6DC00B4C134 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E370CEBD158D962700E46EE9 /* Build configuration list for PBXNativeTarget "piontests" */ = { isa = XCConfigurationList; buildConfigurations = ( E370CEBE158D962700E46EE9 /* Debug */, E370CEBF158D962700E46EE9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; E370CF2D158E6C1A00E46EE9 /* Build configuration list for PBXNativeTarget "hasCreateButNoDestroy" */ = { isa = XCConfigurationList; buildConfigurations = ( E370CF2E158E6C1A00E46EE9 /* Debug */, E370CF2F158E6C1A00E46EE9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; } pion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/0000755000372000001440000000000012420270445021334 5ustar robertouserspion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/xcschemes/0000755000372000001440000000000012420270445023316 5ustar robertouserspion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/xcschemes/pion - piond server.xcscheme0000644000372000001440000001737512420270445030517 0ustar robertousers pion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/xcschemes/pion - unit tests.xcscheme0000644000372000001440000002036412420270445030211 0ustar robertousers pion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/xcschemes/pion - hello server.xcscheme0000644000372000001440000000610312420270445030474 0ustar robertousers pion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/xcschemes/pion - library.xcscheme0000644000372000001440000000506312420270445027552 0ustar robertousers pion-5.0.7+dfsg.orig/pion.xcodeproj/xcshareddata/xcschemes/pion - service plugins.xcscheme0000644000372000001440000001151212420270445031204 0ustar robertousers pion-5.0.7+dfsg.orig/pion.xcodeproj/project.xcworkspace/0000755000372000001440000000000012420270445022677 5ustar robertouserspion-5.0.7+dfsg.orig/pion.xcodeproj/project.xcworkspace/contents.xcworkspacedata0000644000372000001440000000022512420270445027640 0ustar robertousers pion-5.0.7+dfsg.orig/pion.xcodeproj/project.xcworkspace/xcshareddata/0000755000372000001440000000000012420270445025332 5ustar robertouserspion-5.0.7+dfsg.orig/pion.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings0000644000372000001440000000041012420270445033121 0ustar robertousers IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded pion-5.0.7+dfsg.orig/autogen.sh0000755000372000001440000000045712420270445015747 0ustar robertousers#!/bin/sh # # This script initializes the GNU autotools environment for Pion # # DO NOT USE autoheader -> config.h.in file is NOT automanaged!!! AUTOHEADER=`which true` export AUTOHEADER # Make sure m4 directory exists if [ ! -d "m4" ]; then mkdir m4 fi # Generate configure script autoreconf -ifs pion-5.0.7+dfsg.orig/src/0000755000372000001440000000000012420270445014527 5ustar robertouserspion-5.0.7+dfsg.orig/src/process.cpp0000644000372000001440000001705612420270445016722 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #ifndef _MSC_VER #include #include #include #endif #include #include #include #include #include namespace pion { // begin namespace pion // static members of process boost::once_flag process::m_instance_flag = BOOST_ONCE_INIT; process::config_type *process::m_config_ptr = NULL; // process member functions void process::shutdown(void) { config_type& cfg = get_config(); boost::mutex::scoped_lock shutdown_lock(cfg.shutdown_mutex); if (! cfg.shutdown_now) { cfg.shutdown_now = true; cfg.shutdown_cond.notify_all(); } } void process::wait_for_shutdown(void) { config_type& cfg = get_config(); boost::mutex::scoped_lock shutdown_lock(cfg.shutdown_mutex); while (! cfg.shutdown_now) cfg.shutdown_cond.wait(shutdown_lock); } void process::create_config(void) { static config_type UNIQUE_PION_PROCESS_CONFIG; m_config_ptr = &UNIQUE_PION_PROCESS_CONFIG; } #ifdef _MSC_VER BOOL WINAPI console_ctrl_handler(DWORD ctrl_type) { switch(ctrl_type) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: case CTRL_CLOSE_EVENT: case CTRL_SHUTDOWN_EVENT: process::shutdown(); return TRUE; default: return FALSE; } } void process::set_dumpfile_directory(const std::string& dir) { config_type& cfg = get_config(); static const TCHAR* DBGHELP_DLL = _T("DBGHELP.DLL"); if (!dir.empty() && !boost::filesystem::is_directory(dir)) { throw dumpfile_init_exception("Dump file directory doesn't exist: " + dir); } cfg.dumpfile_dir = dir; // load dbghelp.dll if (!dir.empty()) { HMODULE hDll = NULL; TCHAR szDbgHelpPath[_MAX_PATH]; // try loading side-by-side version of DbgHelp.dll first if (GetModuleFileName(NULL, szDbgHelpPath, _MAX_PATH)) { TCHAR *pSlash = _tcsrchr(szDbgHelpPath, _T('\\')); if (pSlash) { _tcscpy(pSlash+1, DBGHELP_DLL); hDll = ::LoadLibrary( szDbgHelpPath ); } } // if not found, load the default version if (hDll == NULL) { hDll = ::LoadLibrary( DBGHELP_DLL ); } cfg.h_dbghelp = hDll; if (hDll == NULL) { throw dumpfile_init_exception("Failed to load DbgHelp.dll"); } } else { cfg.h_dbghelp = NULL; } // get MiniDumpWriteDump proc address if (cfg.h_dbghelp != NULL) { cfg.p_dump_proc = (MINIDUMPWRITEDUMP)::GetProcAddress(cfg.h_dbghelp, "MiniDumpWriteDump"); if (cfg.p_dump_proc == NULL) { throw dumpfile_init_exception("Failed to get MiniDumpWriteDump proc address, probably dbghelp.dll version is too old"); } } else { cfg.p_dump_proc = NULL; } pion::logger _logger = PION_GET_LOGGER("pion.process"); // (re)set the exception filter if (cfg.p_dump_proc) { ::SetUnhandledExceptionFilter(process::unhandled_exception_filter); PION_LOG_INFO(_logger, "Dump file generation enabled to " << cfg.dumpfile_dir ); } else { ::SetUnhandledExceptionFilter(NULL); PION_LOG_INFO(_logger, "Unhandled exception handling reset to default"); } } std::string process::generate_dumpfile_name() { config_type& cfg = get_config(); // generate file name based on current timestamp using namespace boost::posix_time; static std::locale loc(std::cout.getloc(), new time_facet("%Y%m%d_%H%M%S")); std::stringstream ss; ss.imbue(loc); ss << second_clock::universal_time() << ".dmp"; // build the full path boost::filesystem::path p(boost::filesystem::system_complete(cfg.dumpfile_dir)); p /= ss.str(); p.normalize(); p.make_preferred(); # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 return p.string(); #else return p.file_string(); #endif } LONG WINAPI process::unhandled_exception_filter(struct _EXCEPTION_POINTERS *pExceptionInfo) { config_type& cfg = get_config(); pion::logger _logger = PION_GET_LOGGER("pion.process"); // make sure we have all the necessary setup if (cfg.dumpfile_dir.empty() || cfg.p_dump_proc == NULL) { PION_LOG_FATAL(_logger, "Unhandled exception caught when dump file handling not configured!"); PION_SHUTDOWN_LOGGER; return EXCEPTION_CONTINUE_SEARCH; } std::string dumpfile_path = generate_dumpfile_name(); LONG rc = EXCEPTION_CONTINUE_SEARCH; // create the dump file and, if successful, write it HANDLE hFile = ::CreateFile(dumpfile_path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile!=INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = NULL; // write the dump BOOL bOK = cfg.p_dump_proc(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL ); if (bOK) { PION_LOG_INFO(_logger, "Saved process dump file to " << dumpfile_path); } else { PION_LOG_ERROR(_logger, "Failed to save dump file to " << dumpfile_path << " error code: " << GetLastError()); } ::CloseHandle(hFile); rc = EXCEPTION_EXECUTE_HANDLER; // dump saved, so we can die peacefully.. } else { PION_LOG_ERROR(_logger, "Failed to create dump file " << dumpfile_path << " error code: " << GetLastError()); } PION_LOG_FATAL(_logger, "Unhandled exception caught. The process will be terminated!"); PION_SHUTDOWN_LOGGER; return rc; } void process::initialize(void) { SetConsoleCtrlHandler(console_ctrl_handler, TRUE); } void process::daemonize(void) { // not supported } #else // NOT #ifdef _MSC_VER void handle_signal(int sig) { process::shutdown(); } void process::initialize(void) { signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); } void process::daemonize(void) { // adopted from "Unix Daemon Server Programming" // http://www.enderunix.org/docs/eng/daemon.php // return early if already running as a daemon if(getppid()==1) return; // for out the process int i = fork(); if (i<0) exit(1); // error forking if (i>0) exit(0); // exit if parent // child (daemon process) continues here after the fork... // obtain a new process group setsid(); // close all descriptors for (i=getdtablesize();i>=0;--i) close(i); // bind stdio to /dev/null (ignore errors) i=open("/dev/null",O_RDWR); if (i != -1) { if (dup(i) == -1) {} if (dup(i) == -1) {} } // restrict file creation mode to 0750 umask(027); } #endif // #ifdef _MSC_VER } // end namespace pion pion-5.0.7+dfsg.orig/src/http_reader.cpp0000644000372000001440000001321312420270445017534 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // reader static members const boost::uint32_t reader::DEFAULT_READ_TIMEOUT = 10; // reader member functions void reader::receive(void) { if (m_tcp_conn->get_pipelined()) { // there are pipelined messages available in the connection's read buffer m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // default to close the connection m_tcp_conn->load_read_pos(m_read_ptr, m_read_end_ptr); consume_bytes(); } else { // no pipelined messages available in the read buffer -> read bytes from the socket m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // default to close the connection read_bytes_with_timeout(); } } void reader::consume_bytes(const boost::system::error_code& read_error, std::size_t bytes_read) { // cancel read timer if operation didn't time-out if (m_timer_ptr) { m_timer_ptr->cancel(); m_timer_ptr.reset(); } if (read_error) { // a read error occured handle_read_error(read_error); return; } PION_LOG_DEBUG(m_logger, "Read " << bytes_read << " bytes from HTTP " << (is_parsing_request() ? "request" : "response")); // set pointers for new HTTP header data to be consumed set_read_buffer(m_tcp_conn->get_read_buffer().data(), bytes_read); consume_bytes(); } void reader::consume_bytes(void) { // parse the bytes read from the last operation // // note that boost::tribool may have one of THREE states: // // false: encountered an error while parsing message // true: finished successfully parsing the message // indeterminate: parsed bytes, but the message is not yet finished // boost::system::error_code ec; boost::tribool result = parse(get_message(), ec); if (gcount() > 0) { // parsed > 0 bytes in HTTP headers PION_LOG_DEBUG(m_logger, "Parsed " << gcount() << " HTTP bytes"); } if (result == true) { // finished reading HTTP message and it is valid // set the connection's lifecycle type if (get_message().check_keep_alive()) { if ( eof() ) { // the connection should be kept alive, but does not have pipelined messages m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_KEEPALIVE); } else { // the connection has pipelined messages m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_PIPELINED); // save the read position as a bookmark so that it can be retrieved // by a new HTTP parser, which will be created after the current // message has been handled m_tcp_conn->save_read_pos(m_read_ptr, m_read_end_ptr); PION_LOG_DEBUG(m_logger, "HTTP pipelined " << (is_parsing_request() ? "request (" : "response (") << bytes_available() << " bytes available)"); } } else { m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); } // we have finished parsing the HTTP message finished_reading(ec); } else if (result == false) { // the message is invalid or an error occured m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // make sure it will get closed get_message().set_is_valid(false); finished_reading(ec); } else { // not yet finished parsing the message -> read more data read_bytes_with_timeout(); } } void reader::read_bytes_with_timeout(void) { if (m_read_timeout > 0) { m_timer_ptr.reset(new tcp::timer(m_tcp_conn)); m_timer_ptr->start(m_read_timeout); } else if (m_timer_ptr) { m_timer_ptr.reset(); } read_bytes(); } void reader::handle_read_error(const boost::system::error_code& read_error) { // close the connection, forcing the client to establish a new one m_tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // make sure it will get closed // check if this is just a message with unknown content length if (! check_premature_eof(get_message())) { boost::system::error_code ec; // clear error code finished_reading(ec); return; } // only log errors if the parsing has already begun if (get_total_bytes_read() > 0) { if (read_error == boost::asio::error::operation_aborted) { // if the operation was aborted, the acceptor was stopped, // which means another thread is shutting-down the server PION_LOG_INFO(m_logger, "HTTP " << (is_parsing_request() ? "request" : "response") << " parsing aborted (shutting down)"); } else { PION_LOG_INFO(m_logger, "HTTP " << (is_parsing_request() ? "request" : "response") << " parsing aborted (" << read_error.message() << ')'); } } finished_reading(read_error); } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/spdy_decompressor.cpp0000644000372000001440000001522312420270445021002 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include namespace pion { // begin namespace pion namespace spdy { // begin namespace spdy // decompressor static members const char decompressor::SPDY_ZLIB_DICTIONARY[] = "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-" "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi" "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser" "-agent10010120020120220320420520630030130230330430530630740040140240340440" "5406407408409410411412413414415416417500501502503504505accept-rangesageeta" "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic" "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran" "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati" "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo" "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe" "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic" "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1" ".1statusversionurl"; // decompressor member functions decompressor::decompressor() : m_request_zstream(NULL), m_response_zstream(NULL) { m_request_zstream = (z_streamp)malloc(sizeof(z_stream)); BOOST_ASSERT(m_request_zstream); m_request_zstream->zalloc = Z_NULL; m_request_zstream->zfree = Z_NULL; m_request_zstream->opaque = Z_NULL; m_request_zstream->next_in = Z_NULL; m_request_zstream->next_out = Z_NULL; m_request_zstream->avail_in = 0; m_request_zstream->avail_out = 0; m_response_zstream = (z_streamp)malloc(sizeof(z_stream)); BOOST_ASSERT(m_response_zstream); m_response_zstream->zalloc = Z_NULL; m_response_zstream->zfree = Z_NULL; m_response_zstream->opaque = Z_NULL; m_response_zstream->next_in = Z_NULL; m_response_zstream->next_out = Z_NULL; m_response_zstream->avail_in = 0; m_response_zstream->avail_out = 0; int retcode = inflateInit2(m_request_zstream, MAX_WBITS); if (retcode == Z_OK) { retcode = inflateInit2(m_response_zstream, MAX_WBITS); if (retcode == Z_OK) { // Get the dictionary id m_dictionary_id = adler32(0L, Z_NULL, 0); m_dictionary_id = adler32(m_dictionary_id, (const Bytef *)SPDY_ZLIB_DICTIONARY, sizeof(SPDY_ZLIB_DICTIONARY)); } } } decompressor::~decompressor() { inflateEnd(m_request_zstream); inflateEnd(m_response_zstream); free(m_request_zstream); free(m_response_zstream); } char* decompressor::decompress(const char *compressed_data_ptr, boost::uint32_t stream_id, const spdy_control_frame_info& frame, boost::uint32_t header_block_length) { /// Get our decompressor. z_streamp decomp = NULL; if (stream_id % 2 == 0) { // Even streams are server-initiated and should never get a // client-initiated header block. Use reply decompressor. decomp = m_response_zstream; } else if (frame.type == SPDY_HEADERS) { // Odd streams are client-initiated, but may have HEADERS from either // side. Currently, no known clients send HEADERS so we assume they are // all from the server. decomp = m_response_zstream; } else if (frame.type == SPDY_SYN_STREAM) { decomp = m_request_zstream; } else if (frame.type == SPDY_SYN_REPLY) { decomp = m_response_zstream; } else { // Unhandled case. This should never happen. BOOST_ASSERT(false); } BOOST_ASSERT(decomp); // Decompress the data boost::uint32_t uncomp_length = 0; // Catch decompression failures. if (!spdy_decompress_header(compressed_data_ptr, decomp, header_block_length, uncomp_length)) { // Error in decompressing // This error is not catastrophic as many times we might get inconsistent // spdy header frames and we should just log error and continue. // No need to call SetError() return NULL; } return reinterpret_cast(m_uncompressed_header); } bool decompressor::spdy_decompress_header(const char *compressed_data_ptr, z_streamp decomp, boost::uint32_t length, boost::uint32_t& uncomp_length) { int retcode; const boost::uint8_t *hptr = (boost::uint8_t *)compressed_data_ptr; decomp->next_in = (Bytef *)hptr; decomp->avail_in = length; decomp->next_out = m_uncompressed_header; decomp->avail_out = MAX_UNCOMPRESSED_DATA_BUF_SIZE; retcode = inflate(decomp, Z_SYNC_FLUSH); if (retcode == Z_NEED_DICT) { if (decomp->adler != m_dictionary_id) { // Decompressor wants a different dictionary id } else { retcode = inflateSetDictionary(decomp, (const Bytef *)SPDY_ZLIB_DICTIONARY, sizeof(SPDY_ZLIB_DICTIONARY)); if (retcode == Z_OK) { retcode = inflate(decomp, Z_SYNC_FLUSH); } } } // Handle Errors. if (retcode != Z_OK) { // This error is not catastrophic as many times we might get inconsistent // spdy header frames and we should just log error and continue. // No need to call SetError() return false; } // Handle successful inflation. uncomp_length = MAX_UNCOMPRESSED_DATA_BUF_SIZE - decomp->avail_out; if (decomp->avail_in != 0) { // Error condition // This error is not catastrophic as many times we might get inconsistent // spdy header frames and we should just log error and continue. // No need to call SetError() return false; } return true; } } // end namespace spdy } // end namespace pion pion-5.0.7+dfsg.orig/src/http_plugin_server.cpp0000644000372000001440000002514312420270445021163 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // plugin_server member functions void plugin_server::add_service(const std::string& resource, http::plugin_service *service_ptr) { plugin_ptr plugin_ptr; const std::string clean_resource(strip_trailing_slash(resource)); service_ptr->set_resource(clean_resource); m_services.add(clean_resource, service_ptr); http::server::add_resource(clean_resource, boost::ref(*service_ptr)); PION_LOG_INFO(m_logger, "Loaded static web service for resource (" << clean_resource << ")"); } void plugin_server::load_service(const std::string& resource, const std::string& service_name) { const std::string clean_resource(strip_trailing_slash(resource)); http::plugin_service *service_ptr; service_ptr = m_services.load(clean_resource, service_name); http::server::add_resource(clean_resource, boost::ref(*service_ptr)); service_ptr->set_resource(clean_resource); PION_LOG_INFO(m_logger, "Loaded web service plug-in for resource (" << clean_resource << "): " << service_name); } void plugin_server::set_service_option(const std::string& resource, const std::string& name, const std::string& value) { const std::string clean_resource(strip_trailing_slash(resource)); m_services.run(clean_resource, boost::bind(&http::plugin_service::set_option, _1, name, value)); PION_LOG_INFO(m_logger, "Set web service option for resource (" << resource << "): " << name << '=' << value); } void plugin_server::load_service_config(const std::string& config_name) { std::string config_file; if (! plugin::find_config_file(config_file, config_name)) BOOST_THROW_EXCEPTION( error::file_not_found() << error::errinfo_file_name(config_name) ); // open the file for reading std::ifstream config_stream; config_stream.open(config_file.c_str(), std::ios::in); if (! config_stream.is_open()) BOOST_THROW_EXCEPTION( error::open_file() << error::errinfo_file_name(config_name) ); // parse the contents of the file http::auth_ptr my_auth_ptr; enum ParseState { PARSE_NEWLINE, PARSE_COMMAND, PARSE_RESOURCE, PARSE_VALUE, PARSE_COMMENT, PARSE_USERNAME } parse_state = PARSE_NEWLINE; std::string command_string; std::string resource_string; std::string username_string; std::string value_string; std::string option_name_string; std::string option_value_string; int c = config_stream.get(); // read the first character while (config_stream) { switch(parse_state) { case PARSE_NEWLINE: // parsing command portion (or beginning of line) if (c == '#') { // line is a comment parse_state = PARSE_COMMENT; } else if (isalpha(c)) { // first char in command parse_state = PARSE_COMMAND; // ignore case for commands command_string += tolower(c); } else if (c != '\r' && c != '\n') { // check for blank lines BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } break; case PARSE_COMMAND: // parsing command portion (or beginning of line) if (c == ' ' || c == '\t') { // command finished -> check if valid if (command_string=="path" || command_string=="auth" || command_string=="restrict") { value_string.clear(); parse_state = PARSE_VALUE; } else if (command_string=="service" || command_string=="option") { resource_string.clear(); parse_state = PARSE_RESOURCE; } else if (command_string=="user") { username_string.clear(); parse_state = PARSE_USERNAME; } else { BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } } else if (! isalpha(c)) { // commands may only contain alpha chars BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } else { // ignore case for commands command_string += tolower(c); } break; case PARSE_RESOURCE: // parsing resource portion (/hello) if (c == ' ' || c == '\t') { // check for leading whitespace if (! resource_string.empty()) { // resource finished value_string.clear(); parse_state = PARSE_VALUE; } } else if (c == '\r' || c == '\n') { // line truncated before value BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } else { // add char to resource resource_string += c; } break; case PARSE_USERNAME: // parsing username for user command if (c == ' ' || c == '\t') { // check for leading whitespace if (! username_string.empty()) { // username finished value_string.clear(); parse_state = PARSE_VALUE; } } else if (c == '\r' || c == '\n') { // line truncated before value (missing username) BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } else { // add char to username username_string += c; } break; case PARSE_VALUE: // parsing value portion if (c == '\r' || c == '\n') { // value is finished if (value_string.empty()) { // value must not be empty BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } else if (command_string == "path") { // finished path command try { plugin::add_plugin_directory(value_string); } catch (std::exception& e) { PION_LOG_WARN(m_logger, boost::diagnostic_information(e)); } } else if (command_string == "auth") { // finished auth command user_manager_ptr user_mgr(new user_manager); if (value_string == "basic"){ my_auth_ptr.reset(new http::basic_auth(user_mgr)); } else if (value_string == "cookie"){ my_auth_ptr.reset(new http::cookie_auth(user_mgr)); } else { // only basic and cookie authentications are supported BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); } } else if (command_string == "restrict") { // finished restrict command if (! my_auth_ptr) // Authentication type must be defined before restrict BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); else if (value_string.empty()) // No service defined for restrict parameter BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); my_auth_ptr->add_restrict(value_string); } else if (command_string == "user") { // finished user command if (! my_auth_ptr) // Authentication type must be defined before users BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); else if (value_string.empty()) // No password defined for user parameter BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); my_auth_ptr->add_user(username_string, value_string); } else if (command_string == "service") { // finished service command load_service(resource_string, value_string); } else if (command_string == "option") { // finished option command std::string::size_type pos = value_string.find('='); if (pos == std::string::npos) BOOST_THROW_EXCEPTION( error::bad_config() << error::errinfo_file_name(config_name) ); option_name_string = value_string.substr(0, pos); option_value_string = value_string.substr(pos + 1); set_service_option(resource_string, option_name_string, option_value_string); } command_string.clear(); parse_state = PARSE_NEWLINE; } else if (c == ' ' || c == '\t') { // only skip leading whitespace (value may contain spaces, etc) if (! value_string.empty()) value_string += c; } else { // add char to value value_string += c; } break; case PARSE_COMMENT: // skipping comment line if (c == '\r' || c == '\n') parse_state = PARSE_NEWLINE; break; } // read the next character c = config_stream.get(); } // update authentication configuration for the server set_authentication(my_auth_ptr); } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/http_cookie_auth.cpp0000644000372000001440000002646012420270445020574 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // static members of cookie_auth const unsigned int cookie_auth::CACHE_EXPIRATION = 3600; // 1 hour const unsigned int cookie_auth::RANDOM_COOKIE_BYTES = 20; const std::string cookie_auth::AUTH_COOKIE_NAME = "pion_session_id"; // cookie_auth member functions cookie_auth::cookie_auth(user_manager_ptr userManager, const std::string& login, const std::string& logout, const std::string& redirect) : http::auth(userManager), m_login(login), m_logout(logout), m_redirect(redirect), m_random_gen(), m_random_range(0, 255), m_random_die(m_random_gen, m_random_range), m_cache_cleanup_time(boost::posix_time::second_clock::universal_time()) { // set logger for this class set_logger(PION_GET_LOGGER("pion.http.cookie_auth")); // Seed random number generator with current time as time_t int value, cast to the required type. // (Note that boost::mt19937::result_type is boost::uint32_t, and casting to an unsigned n-bit integer is // defined by the standard to keep the lower n bits. Since ::time() returns seconds since Jan 1, 1970, // it will be a long time before we lose any entropy here, even if time_t is a 64-bit int.) m_random_gen.seed(static_cast(::time(NULL))); // generate some random numbers to increase entropy of the rng for (unsigned int n = 0; n < 100; ++n) m_random_die(); } bool cookie_auth::handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { if (process_login(http_request_ptr,tcp_conn)) { return false; // we processed login/logout request, no future processing for this request permitted } if (!need_authentication(http_request_ptr)) { return true; // this request does not require authentication } // check if it is redirection page.. If yes, then do not test its credentials ( as used for login) if (!m_redirect.empty() && m_redirect==http_request_ptr->get_resource()) { return true; // this request does not require authentication } // check cache for expiration boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time()); expire_cache(time_now); // if we are here, we need to check if access authorized... const std::string auth_cookie(http_request_ptr->get_cookie(AUTH_COOKIE_NAME)); if (! auth_cookie.empty()) { // check if this cookie is in user cache boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator user_cache_itr=m_user_cache.find(auth_cookie); if (user_cache_itr != m_user_cache.end()) { // we find those credential in our cache... // we can approve authorization now! http_request_ptr->set_user(user_cache_itr->second.second); // and update cache timeout user_cache_itr->second.first = time_now; return true; } } // user not found handle_unauthorized(http_request_ptr,tcp_conn); return false; } void cookie_auth::set_option(const std::string& name, const std::string& value) { if (name=="login") m_login = value; else if (name=="logout") m_logout = value; else if (name=="redirect") m_redirect = value; else BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } bool cookie_auth::process_login(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // strip off trailing slash if the request has one std::string resource(http::server::strip_trailing_slash(http_request_ptr->get_resource())); if (resource != m_login && resource != m_logout) { return false; // no login processing done } std::string redirect_url = http_request_ptr->get_query("url"); std::string new_cookie; bool delete_cookie = false; if (resource == m_login) { // process login // check username std::string username = http_request_ptr->get_query("user"); std::string password = http_request_ptr->get_query("pass"); // match username/password user_ptr user=m_user_manager->get_user(username,password); if (!user) { // authentication failed, process as in case of failed authentication... handle_unauthorized(http_request_ptr,tcp_conn); return true; } // ok we have a new user session, create a new cookie, add to cache // create random cookie std::string rand_binary; rand_binary.reserve(RANDOM_COOKIE_BYTES); for (unsigned int i=0; i(m_random_die()); } algorithm::base64_encode(rand_binary, new_cookie); // add new session to cache boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time()); boost::mutex::scoped_lock cache_lock(m_cache_mutex); m_user_cache.insert(std::make_pair(new_cookie,std::make_pair(time_now,user))); } else { // process logout sequence // if auth cookie presented - clean cache out const std::string auth_cookie(http_request_ptr->get_cookie(AUTH_COOKIE_NAME)); if (! auth_cookie.empty()) { boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator user_cache_itr=m_user_cache.find(auth_cookie); if (user_cache_itr!=m_user_cache.end()) { m_user_cache.erase(user_cache_itr); } } // and remove cookie from browser delete_cookie = true; } // if redirect defined - send redirect if (! redirect_url.empty()) { handle_redirection(http_request_ptr,tcp_conn,redirect_url,new_cookie,delete_cookie); } else { // otherwise - OK handle_ok(http_request_ptr,tcp_conn,new_cookie,delete_cookie); } // yes, we processed login/logout somehow return true; } void cookie_auth::handle_unauthorized(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // if redirection option is used, send redirect if (!m_redirect.empty()) { handle_redirection(http_request_ptr,tcp_conn,m_redirect,"",false); return; } // authentication failed, send 401..... static const std::string CONTENT = " " "" "" "Error" "" "" "

401 Unauthorized.

" " "; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_UNAUTHORIZED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_UNAUTHORIZED); writer->write_no_copy(CONTENT); writer->send(); } void cookie_auth::handle_redirection(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string &redirection_url, const std::string &new_cookie, bool delete_cookie ) { // authentication failed, send 302..... static const std::string CONTENT = " " "" "" "Redirect" "" "" "

302 Found.

" " "; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_FOUND); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_FOUND); writer->get_response().add_header(http::types::HEADER_LOCATION, redirection_url); // Note: use empty pass "" while setting cookies to workaround IE/FF difference // It is assumed that request url points to the root // ToDo: find a better workaround if (delete_cookie) { // remove cookie writer->get_response().delete_cookie(AUTH_COOKIE_NAME,""); } else if (!new_cookie.empty()) { // set up a new cookie writer->get_response().set_cookie(AUTH_COOKIE_NAME, new_cookie,""); } writer->write_no_copy(CONTENT); writer->send(); } void cookie_auth::handle_ok(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string &new_cookie, bool delete_cookie ) { // send 204 (No Content) response http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_NO_CONTENT); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NO_CONTENT); // Note: use empty pass "" while setting cookies to workaround IE/FF difference // It is assumed that request url points to the root // ToDo: find a better workaround if (delete_cookie) { // remove cookie writer->get_response().delete_cookie(AUTH_COOKIE_NAME,""); } else if(!new_cookie.empty()) { // set up a new cookie writer->get_response().set_cookie(AUTH_COOKIE_NAME, new_cookie,""); } writer->send(); } void cookie_auth::expire_cache(const boost::posix_time::ptime &time_now) { if (time_now > m_cache_cleanup_time + boost::posix_time::seconds(CACHE_EXPIRATION)) { // expire cache boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator i; user_cache_type::iterator next=m_user_cache.begin(); while (next!=m_user_cache.end()) { i=next; ++next; if (time_now > i->second.first + boost::posix_time::seconds(CACHE_EXPIRATION)) { // ok - this is an old record.. expire it now m_user_cache.erase(i); } } m_cache_cleanup_time = time_now; } } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/tcp_timer.cpp0000644000372000001440000000265312420270445017227 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include namespace pion { // begin namespace pion namespace tcp { // begin namespace tcp // timer member functions timer::timer(tcp::connection_ptr& conn_ptr) : m_conn_ptr(conn_ptr), m_timer(conn_ptr->get_io_service()), m_timer_active(false), m_was_cancelled(false) { } void timer::start(const boost::uint32_t seconds) { boost::mutex::scoped_lock timer_lock(m_mutex); m_timer_active = true; m_timer.expires_from_now(boost::posix_time::seconds(seconds)); m_timer.async_wait(boost::bind(&timer::timer_callback, shared_from_this(), _1)); } void timer::cancel(void) { boost::mutex::scoped_lock timer_lock(m_mutex); m_was_cancelled = true; if (m_timer_active) m_timer.cancel(); } void timer::timer_callback(const boost::system::error_code& ec) { boost::mutex::scoped_lock timer_lock(m_mutex); m_timer_active = false; if (! m_was_cancelled) m_conn_ptr->cancel(); } } // end namespace tcp } // end namespace pion pion-5.0.7+dfsg.orig/src/http_writer.cpp0000644000372000001440000000623112420270445017610 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // writer member functions void writer::prepare_write_buffers(http::message::write_buffers_t& write_buffers, const bool send_final_chunk) { // check if the HTTP headers have been sent yet if (! m_sent_headers) { // initialize write buffers for send operation prepare_buffers_for_send(write_buffers); // only send the headers once m_sent_headers = true; } // combine I/O write buffers (headers and content) so that everything // can be sent together; otherwise, we would have to send headers // and content separately, which would not be as efficient // don't send anything if there is no data in content buffers if (m_content_length > 0) { if (supports_chunked_messages() && sending_chunked_message()) { // prepare the next chunk of data to send // write chunk length in hex char cast_buf[35]; sprintf(cast_buf, "%lx", static_cast(m_content_length)); // add chunk length as a string at the back of the text cache m_text_cache.push_back(cast_buf); // append length of chunk to write_buffers write_buffers.push_back(boost::asio::buffer(m_text_cache.back())); // append an extra CRLF for chunk formatting write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF)); // append response content buffers write_buffers.insert(write_buffers.end(), m_content_buffers.begin(), m_content_buffers.end()); // append an extra CRLF for chunk formatting write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF)); } else { // append response content buffers write_buffers.insert(write_buffers.end(), m_content_buffers.begin(), m_content_buffers.end()); } } // prepare a zero-byte (final) chunk if (send_final_chunk && supports_chunked_messages() && sending_chunked_message()) { // add chunk length as a string at the back of the text cache m_text_cache.push_back("0"); // append length of chunk to write_buffers write_buffers.push_back(boost::asio::buffer(m_text_cache.back())); // append an extra CRLF for chunk formatting write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF)); write_buffers.push_back(boost::asio::buffer(http::types::STRING_CRLF)); } } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/algorithm.cpp0000644000372000001440000003417012420270445017226 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include // macro to shift bitmask by a single bit #define SHIFT_BITMASK(ptr, mask) if (mask & 0x01) { mask = 0x80; ++ptr; } else mask >>= 1; namespace pion { // begin namespace pion bool algorithm::base64_decode(const std::string &input, std::string &output) { static const char nop = -1; static const char decoding_data[] = { nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop, 62, nop,nop,nop, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,nop,nop, nop,nop,nop,nop, nop, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,nop, nop,nop,nop,nop, nop,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,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop, nop,nop,nop,nop }; unsigned int input_length=input.size(); const char * input_ptr = input.data(); // allocate space for output string output.clear(); output.reserve(((input_length+2)/3)*4); // for each 4-bytes sequence from the input, extract 4 6-bits sequences by droping first two bits // and regenerate into 3 8-bits sequence for (unsigned int i=0; i(input_ptr[i])]; if(base64code0==nop) // non base64 character return false; if(!(++i(input_ptr[i])]; if(base64code1==nop) // non base64 character return false; output += ((base64code0 << 2) | ((base64code1 >> 4) & 0x3)); if(++i(input_ptr[i])]; if(base64code2==nop) // non base64 character return false; output += ((base64code1 << 4) & 0xf0) | ((base64code2 >> 2) & 0x0f); } if(++i(input_ptr[i])]; if(base64code3==nop) // non base64 character return false; output += (((base64code2 << 6) & 0xc0) | base64code3 ); } } return true; } bool algorithm::base64_encode(const std::string &input, std::string &output) { static const char encoding_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned int input_length=input.size(); const char * input_ptr = input.data(); // allocate space for output string output.clear(); output.reserve(((input_length+2)/3)*4); // for each 3-bytes sequence from the input, extract 4 6-bits sequences and encode using // encoding_data lookup table. // if input do not contains enough chars to complete 3-byte sequence,use pad char '=' for (unsigned int i=0; i> 2) & 0x3f; // 1-byte 6 bits output += encoding_data[base64code0]; base64code1 = (input_ptr[i] << 4 ) & 0x3f; // 1-byte 2 bits + if (++i < input_length) { base64code1 |= (input_ptr[i] >> 4) & 0x0f; // 2-byte 4 bits output += encoding_data[base64code1]; base64code2 = (input_ptr[i] << 2) & 0x3f; // 2-byte 4 bits + if (++i < input_length) { base64code2 |= (input_ptr[i] >> 6) & 0x03; // 3-byte 2 bits base64code3 = input_ptr[i] & 0x3f; // 3-byte 6 bits output += encoding_data[base64code2]; output += encoding_data[base64code3]; } else { output += encoding_data[base64code2]; output += '='; } } else { output += encoding_data[base64code1]; output += '='; output += '='; } } return true; } std::string algorithm::url_decode(const std::string& str) { char decode_buf[3]; std::string result; result.reserve(str.size()); for (std::string::size_type pos = 0; pos < str.size(); ++pos) { switch(str[pos]) { case '+': // convert to space character result += ' '; break; case '%': // decode hexadecimal value if (pos + 2 < str.size()) { decode_buf[0] = str[++pos]; decode_buf[1] = str[++pos]; decode_buf[2] = '\0'; char decoded_char = static_cast( strtol(decode_buf, 0, 16) ); // decoded_char will be '\0' if strtol can't parse decode_buf as hex // (or if decode_buf == "00", which is also not valid). // In this case, recover from error by not decoding. if (decoded_char == '\0') { result += '%'; pos -= 2; } else result += decoded_char; } else { // recover from error by not decoding character result += '%'; } break; default: // character does not need to be escaped result += str[pos]; } }; return result; } std::string algorithm::url_encode(const std::string& str) { char encode_buf[4]; std::string result; encode_buf[0] = '%'; result.reserve(str.size()); // character selection for this algorithm is based on the following url: // http://www.blooberry.com/indexdot/html/topics/urlencoding.htm for (std::string::size_type pos = 0; pos < str.size(); ++pos) { switch(str[pos]) { default: if (str[pos] > 32 && str[pos] < 127) { // character does not need to be escaped result += str[pos]; break; } // else pass through to next case case ' ': case '$': case '&': case '+': case ',': case '/': case ':': case ';': case '=': case '?': case '@': case '"': case '<': case '>': case '#': case '%': case '{': case '}': case '|': case '\\': case '^': case '~': case '[': case ']': case '`': // the character needs to be encoded sprintf(encode_buf+1, "%.2X", (unsigned char)(str[pos])); result += encode_buf; break; } }; return result; } // TODO //std::string algorithm::xml_decode(const std::string& str) //{ //} std::string algorithm::xml_encode(const std::string& str) { std::string result; result.reserve(str.size() + 20); // Assume ~5 characters converted (length increases) const unsigned char *ptr = reinterpret_cast(str.c_str()); const unsigned char *end_ptr = ptr + str.size(); while (ptr < end_ptr) { // check byte ranges for valid UTF-8 // see http://en.wikipedia.org/wiki/UTF-8 // also, see http://www.w3.org/TR/REC-xml/#charsets // this implementation is the strictest subset of both if ((*ptr >= 0x20 && *ptr <= 0x7F) || *ptr == 0x9 || *ptr == 0xa || *ptr == 0xd) { // regular ASCII character switch(*ptr) { // Escape special XML characters. case '&': result += "&"; break; case '<': result += "<"; break; case '>': result += ">"; break; case '\"': result += """; break; case '\'': result += "'"; break; default: result += *ptr; } } else if (*ptr >= 0xC2 && *ptr <= 0xDF) { // two-byte sequence if (*(ptr+1) >= 0x80 && *(ptr+1) <= 0xBF) { result += *ptr; result += *(++ptr); } else { // insert replacement char result += 0xef; result += 0xbf; result += 0xbd; } } else if (*ptr >= 0xE0 && *ptr <= 0xEF) { // three-byte sequence if (*(ptr+1) >= 0x80 && *(ptr+1) <= 0xBF && *(ptr+2) >= 0x80 && *(ptr+2) <= 0xBF) { result += *ptr; result += *(++ptr); result += *(++ptr); } else { // insert replacement char result += 0xef; result += 0xbf; result += 0xbd; } } else if (*ptr >= 0xF0 && *ptr <= 0xF4) { // four-byte sequence if (*(ptr+1) >= 0x80 && *(ptr+1) <= 0xBF && *(ptr+2) >= 0x80 && *(ptr+2) <= 0xBF && *(ptr+3) >= 0x80 && *(ptr+3) <= 0xBF) { result += *ptr; result += *(++ptr); result += *(++ptr); result += *(++ptr); } else { // insert replacement char result += 0xef; result += 0xbf; result += 0xbd; } } else { // insert replacement char result += 0xef; result += 0xbf; result += 0xbd; } ++ptr; } return result; } void algorithm::float_from_bytes(long double& value, const unsigned char *ptr, size_t num_exp_bits, size_t num_fraction_bits) { // get sign of the number from the first bit const int value_sign = (*ptr & 0x80) ? -1 : 1; // build exponent value from bitstream unsigned char mask = 0x80; boost::int16_t exponent = 0; for (size_t n = 0; n < num_exp_bits; ++n) { SHIFT_BITMASK(ptr, mask); exponent *= 2; if (*ptr & mask) exponent += 1; } // build significand from bitstream long double significand = exponent ? 1.0 : 0.0; long double significand_value = 1.0; while (num_fraction_bits) { SHIFT_BITMASK(ptr, mask); significand_value /= 2; if (*ptr & mask) significand += significand_value; --num_fraction_bits; } // calculate final value exponent -= (::pow((long double)2, (int)(num_exp_bits - 1)) - 1); value = value_sign * significand * ::pow((long double)2, exponent); } void algorithm::float_to_bytes(long double value, unsigned char *buf, size_t num_exp_bits, size_t num_fraction_bits) { // first initialize output buffer to zeros unsigned char *ptr = buf; memset(ptr, 0x00, ::ceil(static_cast(num_exp_bits + num_fraction_bits + 1) / 8)); // initialize first byte starting with sign of number if (value < 0) { *ptr = 0x80; value *= -1; } // break down numbers >= 1.0 by incrementing the exponent & dividing by 2 boost::int16_t exponent = 0; while (value >= 1) { value /= 2; ++exponent; } // skip past exponent bits because we don't know the value yet unsigned char mask = 0x40; for (size_t n = num_exp_bits; n > 0; --n) { if (n >= 8) { ++ptr; n -= 7; } else { SHIFT_BITMASK(ptr, mask); } } // serialize fractional value < 1.0 bool got_exponent = false; boost::uint16_t num_bits = 0; while (value && num_bits < num_fraction_bits) { value *= 2; if (got_exponent) { if (value >= 1.0) { *ptr |= mask; value -= 1.0; } SHIFT_BITMASK(ptr, mask); ++num_bits; } else { --exponent; if (value >= 1.0) { value -= 1.0; got_exponent = true; } } } // normalize exponent. // note: we should have a zero exponent if value == 0 boost::int32_t high_bit = ::pow((long double)2, (int)(num_exp_bits - 1)); if (got_exponent) exponent += (high_bit - 1); else exponent = 0; // serialize exponent bits ptr = buf; mask = 0x80; for (size_t n = 0; n < num_exp_bits; ++n) { SHIFT_BITMASK(ptr, mask); if (exponent >= high_bit) { *ptr |= mask; exponent -= high_bit; } high_bit /= 2; } } } // end namespace pion pion-5.0.7+dfsg.orig/src/http_types.cpp0000644000372000001440000001501512420270445017440 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // generic strings used by HTTP const std::string types::STRING_EMPTY; const std::string types::STRING_CRLF("\x0D\x0A"); const std::string types::STRING_HTTP_VERSION("HTTP/"); const std::string types::HEADER_NAME_VALUE_DELIMITER(": "); const std::string types::COOKIE_NAME_VALUE_DELIMITER("="); // common HTTP header names const std::string types::HEADER_HOST("Host"); const std::string types::HEADER_COOKIE("Cookie"); const std::string types::HEADER_SET_COOKIE("Set-Cookie"); const std::string types::HEADER_CONNECTION("Connection"); const std::string types::HEADER_CONTENT_TYPE("Content-Type"); const std::string types::HEADER_CONTENT_LENGTH("Content-Length"); const std::string types::HEADER_CONTENT_LOCATION("Content-Location"); const std::string types::HEADER_CONTENT_ENCODING("Content-Encoding"); const std::string types::HEADER_CONTENT_DISPOSITION("Content-Disposition"); const std::string types::HEADER_LAST_MODIFIED("Last-Modified"); const std::string types::HEADER_IF_MODIFIED_SINCE("If-Modified-Since"); const std::string types::HEADER_TRANSFER_ENCODING("Transfer-Encoding"); const std::string types::HEADER_LOCATION("Location"); const std::string types::HEADER_AUTHORIZATION("Authorization"); const std::string types::HEADER_REFERER("Referer"); const std::string types::HEADER_USER_AGENT("User-Agent"); const std::string types::HEADER_X_FORWARDED_FOR("X-Forwarded-For"); const std::string types::HEADER_CLIENT_IP("Client-IP"); // common HTTP content types const std::string types::CONTENT_TYPE_HTML("text/html"); const std::string types::CONTENT_TYPE_TEXT("text/plain"); const std::string types::CONTENT_TYPE_XML("text/xml"); const std::string types::CONTENT_TYPE_URLENCODED("application/x-www-form-urlencoded"); const std::string types::CONTENT_TYPE_MULTIPART_FORM_DATA("multipart/form-data"); // common HTTP request methods const std::string types::REQUEST_METHOD_HEAD("HEAD"); const std::string types::REQUEST_METHOD_GET("GET"); const std::string types::REQUEST_METHOD_PUT("PUT"); const std::string types::REQUEST_METHOD_POST("POST"); const std::string types::REQUEST_METHOD_DELETE("DELETE"); // common HTTP response messages const std::string types::RESPONSE_MESSAGE_OK("OK"); const std::string types::RESPONSE_MESSAGE_CREATED("Created"); const std::string types::RESPONSE_MESSAGE_ACCEPTED("Accepted"); const std::string types::RESPONSE_MESSAGE_NO_CONTENT("No Content"); const std::string types::RESPONSE_MESSAGE_FOUND("Found"); const std::string types::RESPONSE_MESSAGE_UNAUTHORIZED("Unauthorized"); const std::string types::RESPONSE_MESSAGE_FORBIDDEN("Forbidden"); const std::string types::RESPONSE_MESSAGE_NOT_FOUND("Not Found"); const std::string types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED("Method Not Allowed"); const std::string types::RESPONSE_MESSAGE_NOT_MODIFIED("Not Modified"); const std::string types::RESPONSE_MESSAGE_BAD_REQUEST("Bad Request"); const std::string types::RESPONSE_MESSAGE_SERVER_ERROR("Server Error"); const std::string types::RESPONSE_MESSAGE_NOT_IMPLEMENTED("Not Implemented"); const std::string types::RESPONSE_MESSAGE_CONTINUE("Continue"); // common HTTP response codes const unsigned int types::RESPONSE_CODE_OK = 200; const unsigned int types::RESPONSE_CODE_CREATED = 201; const unsigned int types::RESPONSE_CODE_ACCEPTED = 202; const unsigned int types::RESPONSE_CODE_NO_CONTENT = 204; const unsigned int types::RESPONSE_CODE_FOUND = 302; const unsigned int types::RESPONSE_CODE_UNAUTHORIZED = 401; const unsigned int types::RESPONSE_CODE_FORBIDDEN = 403; const unsigned int types::RESPONSE_CODE_NOT_FOUND = 404; const unsigned int types::RESPONSE_CODE_METHOD_NOT_ALLOWED = 405; const unsigned int types::RESPONSE_CODE_NOT_MODIFIED = 304; const unsigned int types::RESPONSE_CODE_BAD_REQUEST = 400; const unsigned int types::RESPONSE_CODE_SERVER_ERROR = 500; const unsigned int types::RESPONSE_CODE_NOT_IMPLEMENTED = 501; const unsigned int types::RESPONSE_CODE_CONTINUE = 100; // static member functions std::string types::get_date_string(const time_t t) { // use mutex since time functions are normally not thread-safe static boost::mutex time_mutex; static const char *TIME_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"; static const unsigned int TIME_BUF_SIZE = 100; char time_buf[TIME_BUF_SIZE+1]; boost::mutex::scoped_lock time_lock(time_mutex); if (strftime(time_buf, TIME_BUF_SIZE, TIME_FORMAT, gmtime(&t)) == 0) time_buf[0] = '\0'; // failed; resulting buffer is indeterminate time_lock.unlock(); return std::string(time_buf); } std::string types::make_query_string(const ihash_multimap& query_params) { std::string query_string; for (ihash_multimap::const_iterator i = query_params.begin(); i != query_params.end(); ++i) { if (i != query_params.begin()) query_string += '&'; query_string += algorithm::url_encode(i->first); query_string += '='; query_string += algorithm::url_encode(i->second); } return query_string; } std::string types::make_set_cookie_header(const std::string& name, const std::string& value, const std::string& path, const bool has_max_age, const unsigned long max_age) { // note: according to RFC6265, attributes should not be quoted std::string set_cookie_header(name); set_cookie_header += "=\""; set_cookie_header += value; set_cookie_header += "\"; Version=1"; if (! path.empty()) { set_cookie_header += "; Path="; set_cookie_header += path; } if (has_max_age) { set_cookie_header += "; Max-Age="; set_cookie_header += boost::lexical_cast(max_age); } return set_cookie_header; } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/http_message.cpp0000644000372000001440000002066012420270445017722 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // static members of message const boost::regex message::REGEX_ICASE_CHUNKED(".*chunked.*", boost::regex::icase); // message member functions std::size_t message::send(tcp::connection& tcp_conn, boost::system::error_code& ec, bool headers_only) { // initialize write buffers for send operation using HTTP headers write_buffers_t write_buffers; prepare_buffers_for_send(write_buffers, tcp_conn.get_keep_alive(), false); // append payload content to write buffers (if there is any) if (!headers_only && get_content_length() > 0 && get_content() != NULL) write_buffers.push_back(boost::asio::buffer(get_content(), get_content_length())); // send the message and return the result return tcp_conn.write(write_buffers, ec); } std::size_t message::receive(tcp::connection& tcp_conn, boost::system::error_code& ec, parser& http_parser) { std::size_t last_bytes_read = 0; // make sure that we start out with an empty message clear(); if (tcp_conn.get_pipelined()) { // there are pipelined messages available in the connection's read buffer const char *read_ptr; const char *read_end_ptr; tcp_conn.load_read_pos(read_ptr, read_end_ptr); last_bytes_read = (read_end_ptr - read_ptr); http_parser.set_read_buffer(read_ptr, last_bytes_read); } else { // read buffer is empty (not pipelined) -> read some bytes from the connection last_bytes_read = tcp_conn.read_some(ec); if (ec) return 0; BOOST_ASSERT(last_bytes_read > 0); http_parser.set_read_buffer(tcp_conn.get_read_buffer().data(), last_bytes_read); } // incrementally read and parse bytes from the connection bool force_connection_closed = false; boost::tribool parse_result; while (true) { // parse bytes available in the read buffer parse_result = http_parser.parse(*this, ec); if (! boost::indeterminate(parse_result)) break; // read more bytes from the connection last_bytes_read = tcp_conn.read_some(ec); if (ec || last_bytes_read == 0) { if (http_parser.check_premature_eof(*this)) { // premature EOF encountered if (! ec) ec = make_error_code(boost::system::errc::io_error); return http_parser.get_total_bytes_read(); } else { // EOF reached when content length unknown // assume it is the correct end of content // and everything is OK force_connection_closed = true; parse_result = true; ec.clear(); break; } break; } // update the HTTP parser's read buffer http_parser.set_read_buffer(tcp_conn.get_read_buffer().data(), last_bytes_read); } if (parse_result == false) { // an error occurred while parsing the message headers return http_parser.get_total_bytes_read(); } // set the connection's lifecycle type if (!force_connection_closed && check_keep_alive()) { if ( http_parser.eof() ) { // the connection should be kept alive, but does not have pipelined messages tcp_conn.set_lifecycle(tcp::connection::LIFECYCLE_KEEPALIVE); } else { // the connection has pipelined messages tcp_conn.set_lifecycle(tcp::connection::LIFECYCLE_PIPELINED); // save the read position as a bookmark so that it can be retrieved // by a new HTTP parser, which will be created after the current // message has been handled const char *read_ptr; const char *read_end_ptr; http_parser.load_read_pos(read_ptr, read_end_ptr); tcp_conn.save_read_pos(read_ptr, read_end_ptr); } } else { // default to close the connection tcp_conn.set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // save the read position as a bookmark so that it can be retrieved // by a new HTTP parser if (http_parser.get_parse_headers_only()) { const char *read_ptr; const char *read_end_ptr; http_parser.load_read_pos(read_ptr, read_end_ptr); tcp_conn.save_read_pos(read_ptr, read_end_ptr); } } return (http_parser.get_total_bytes_read()); } std::size_t message::receive(tcp::connection& tcp_conn, boost::system::error_code& ec, bool headers_only, std::size_t max_content_length) { http::parser http_parser(dynamic_cast(this) != NULL); http_parser.parse_headers_only(headers_only); http_parser.set_max_content_length(max_content_length); return receive(tcp_conn, ec, http_parser); } std::size_t message::write(std::ostream& out, boost::system::error_code& ec, bool headers_only) { // reset error_code ec.clear(); // initialize write buffers for send operation using HTTP headers write_buffers_t write_buffers; prepare_buffers_for_send(write_buffers, true, false); // append payload content to write buffers (if there is any) if (!headers_only && get_content_length() > 0 && get_content() != NULL) write_buffers.push_back(boost::asio::buffer(get_content(), get_content_length())); // write message to the output stream std::size_t bytes_out = 0; for (write_buffers_t::const_iterator i=write_buffers.begin(); i!=write_buffers.end(); ++i) { const char *ptr = boost::asio::buffer_cast(*i); size_t len = boost::asio::buffer_size(*i); out.write(ptr, len); bytes_out += len; } return bytes_out; } std::size_t message::read(std::istream& in, boost::system::error_code& ec, parser& http_parser) { // make sure that we start out with an empty message & clear error_code clear(); ec.clear(); // parse data from file one byte at a time boost::tribool parse_result; char c; while (in) { in.read(&c, 1); if ( ! in ) { ec = make_error_code(boost::system::errc::io_error); break; } http_parser.set_read_buffer(&c, 1); parse_result = http_parser.parse(*this, ec); if (! boost::indeterminate(parse_result)) break; } if (boost::indeterminate(parse_result)) { if (http_parser.check_premature_eof(*this)) { // premature EOF encountered if (! ec) ec = make_error_code(boost::system::errc::io_error); } else { // EOF reached when content length unknown // assume it is the correct end of content // and everything is OK parse_result = true; ec.clear(); } } return (http_parser.get_total_bytes_read()); } std::size_t message::read(std::istream& in, boost::system::error_code& ec, bool headers_only, std::size_t max_content_length) { http::parser http_parser(dynamic_cast(this) != NULL); http_parser.parse_headers_only(headers_only); http_parser.set_max_content_length(max_content_length); return read(in, ec, http_parser); } void message::concatenate_chunks(void) { set_content_length(m_chunk_cache.size()); char *post_buffer = create_content_buffer(); if (m_chunk_cache.size() > 0) std::copy(m_chunk_cache.begin(), m_chunk_cache.end(), post_buffer); } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/pion.vcxproj.filters0000644000372000001440000001467712420270445020577 0ustar robertousers {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;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 Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files pion-5.0.7+dfsg.orig/src/tcp_server.cpp0000644000372000001440000002535512420270445017421 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include namespace pion { // begin namespace pion namespace tcp { // begin namespace tcp // tcp::server member functions server::server(scheduler& sched, const unsigned int tcp_port) : m_logger(PION_GET_LOGGER("pion.tcp.server")), m_active_scheduler(sched), m_tcp_acceptor(m_active_scheduler.get_io_service()), #ifdef PION_HAVE_SSL m_ssl_context(m_active_scheduler.get_io_service(), boost::asio::ssl::context::sslv23), #else m_ssl_context(0), #endif m_endpoint(boost::asio::ip::tcp::v4(), tcp_port), m_ssl_flag(false), m_is_listening(false) {} server::server(scheduler& sched, const boost::asio::ip::tcp::endpoint& endpoint) : m_logger(PION_GET_LOGGER("pion.tcp.server")), m_active_scheduler(sched), m_tcp_acceptor(m_active_scheduler.get_io_service()), #ifdef PION_HAVE_SSL m_ssl_context(m_active_scheduler.get_io_service(), boost::asio::ssl::context::sslv23), #else m_ssl_context(0), #endif m_endpoint(endpoint), m_ssl_flag(false), m_is_listening(false) {} server::server(const unsigned int tcp_port) : m_logger(PION_GET_LOGGER("pion.tcp.server")), m_default_scheduler(), m_active_scheduler(m_default_scheduler), m_tcp_acceptor(m_active_scheduler.get_io_service()), #ifdef PION_HAVE_SSL m_ssl_context(m_active_scheduler.get_io_service(), boost::asio::ssl::context::sslv23), #else m_ssl_context(0), #endif m_endpoint(boost::asio::ip::tcp::v4(), tcp_port), m_ssl_flag(false), m_is_listening(false) {} server::server(const boost::asio::ip::tcp::endpoint& endpoint) : m_logger(PION_GET_LOGGER("pion.tcp.server")), m_default_scheduler(), m_active_scheduler(m_default_scheduler), m_tcp_acceptor(m_active_scheduler.get_io_service()), #ifdef PION_HAVE_SSL m_ssl_context(m_active_scheduler.get_io_service(), boost::asio::ssl::context::sslv23), #else m_ssl_context(0), #endif m_endpoint(endpoint), m_ssl_flag(false), m_is_listening(false) {} void server::start(void) { // lock mutex for thread safety boost::mutex::scoped_lock server_lock(m_mutex); if (! m_is_listening) { PION_LOG_INFO(m_logger, "Starting server on port " << get_port()); before_starting(); // configure the acceptor service try { // get admin permissions in case we're binding to a privileged port pion::admin_rights use_admin_rights(get_port() > 0 && get_port() < 1024); m_tcp_acceptor.open(m_endpoint.protocol()); // allow the acceptor to reuse the address (i.e. SO_REUSEADDR) // ...except when running not on Windows - see http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx #ifndef _MSC_VER m_tcp_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); #endif m_tcp_acceptor.bind(m_endpoint); if (m_endpoint.port() == 0) { // update the endpoint to reflect the port chosen by bind m_endpoint = m_tcp_acceptor.local_endpoint(); } m_tcp_acceptor.listen(); } catch (std::exception& e) { PION_LOG_ERROR(m_logger, "Unable to bind to port " << get_port() << ": " << e.what()); throw; } m_is_listening = true; // unlock the mutex since listen() requires its own lock server_lock.unlock(); listen(); // notify the thread scheduler that we need it now m_active_scheduler.add_active_user(); } } void server::stop(bool wait_until_finished) { // lock mutex for thread safety boost::mutex::scoped_lock server_lock(m_mutex); if (m_is_listening) { PION_LOG_INFO(m_logger, "Shutting down server on port " << get_port()); m_is_listening = false; // this terminates any connections waiting to be accepted m_tcp_acceptor.close(); if (! wait_until_finished) { // this terminates any other open connections std::for_each(m_conn_pool.begin(), m_conn_pool.end(), boost::bind(&connection::close, _1)); } // wait for all pending connections to complete while (! m_conn_pool.empty()) { // try to prun connections that didn't finish cleanly if (prune_connections() == 0) break; // if no more left, then we can stop waiting // sleep for up to a quarter second to give open connections a chance to finish PION_LOG_INFO(m_logger, "Waiting for open connections to finish"); scheduler::sleep(m_no_more_connections, server_lock, 0, 250000000); } // notify the thread scheduler that we no longer need it m_active_scheduler.remove_active_user(); // all done! after_stopping(); m_server_has_stopped.notify_all(); } } void server::join(void) { boost::mutex::scoped_lock server_lock(m_mutex); while (m_is_listening) { // sleep until server_has_stopped condition is signaled m_server_has_stopped.wait(server_lock); } } void server::set_ssl_key_file(const std::string& pem_key_file) { // configure server for SSL set_ssl_flag(true); #ifdef PION_HAVE_SSL m_ssl_context.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use); m_ssl_context.use_certificate_file(pem_key_file, boost::asio::ssl::context::pem); m_ssl_context.use_private_key_file(pem_key_file, boost::asio::ssl::context::pem); #endif } void server::listen(void) { // lock mutex for thread safety boost::mutex::scoped_lock server_lock(m_mutex); if (m_is_listening) { // create a new TCP connection object tcp::connection_ptr new_connection(connection::create(get_io_service(), m_ssl_context, m_ssl_flag, boost::bind(&server::finish_connection, this, _1))); // prune connections that finished uncleanly prune_connections(); // keep track of the object in the server's connection pool m_conn_pool.insert(new_connection); // use the object to accept a new connection new_connection->async_accept(m_tcp_acceptor, boost::bind(&server::handle_accept, this, new_connection, boost::asio::placeholders::error)); } } void server::handle_accept(tcp::connection_ptr& tcp_conn, const boost::system::error_code& accept_error) { if (accept_error) { // an error occured while trying to a accept a new connection // this happens when the server is being shut down if (m_is_listening) { listen(); // schedule acceptance of another connection PION_LOG_WARN(m_logger, "Accept error on port " << get_port() << ": " << accept_error.message()); } finish_connection(tcp_conn); } else { // got a new TCP connection PION_LOG_DEBUG(m_logger, "New" << (tcp_conn->get_ssl_flag() ? " SSL " : " ") << "connection on port " << get_port()); // schedule the acceptance of another new connection // (this returns immediately since it schedules it as an event) if (m_is_listening) listen(); // handle the new connection #ifdef PION_HAVE_SSL if (tcp_conn->get_ssl_flag()) { tcp_conn->async_handshake_server(boost::bind(&server::handle_ssl_handshake, this, tcp_conn, boost::asio::placeholders::error)); } else #endif // not SSL -> call the handler immediately handle_connection(tcp_conn); } } void server::handle_ssl_handshake(tcp::connection_ptr& tcp_conn, const boost::system::error_code& handshake_error) { if (handshake_error) { // an error occured while trying to establish the SSL connection PION_LOG_WARN(m_logger, "SSL handshake failed on port " << get_port() << " (" << handshake_error.message() << ')'); finish_connection(tcp_conn); } else { // handle the new connection PION_LOG_DEBUG(m_logger, "SSL handshake succeeded on port " << get_port()); handle_connection(tcp_conn); } } void server::finish_connection(tcp::connection_ptr& tcp_conn) { boost::mutex::scoped_lock server_lock(m_mutex); if (m_is_listening && tcp_conn->get_keep_alive()) { // keep the connection alive handle_connection(tcp_conn); } else { PION_LOG_DEBUG(m_logger, "Closing connection on port " << get_port()); // remove the connection from the server's management pool ConnectionPool::iterator conn_itr = m_conn_pool.find(tcp_conn); if (conn_itr != m_conn_pool.end()) m_conn_pool.erase(conn_itr); // trigger the no more connections condition if we're waiting to stop if (!m_is_listening && m_conn_pool.empty()) m_no_more_connections.notify_all(); } } std::size_t server::prune_connections(void) { // assumes that a server lock has already been acquired ConnectionPool::iterator conn_itr = m_conn_pool.begin(); while (conn_itr != m_conn_pool.end()) { if (conn_itr->unique()) { PION_LOG_WARN(m_logger, "Closing orphaned connection on port " << get_port()); ConnectionPool::iterator erase_itr = conn_itr; ++conn_itr; (*erase_itr)->close(); m_conn_pool.erase(erase_itr); } else { ++conn_itr; } } // return the number of connections remaining return m_conn_pool.size(); } std::size_t server::get_connections(void) const { boost::mutex::scoped_lock server_lock(m_mutex); return (m_is_listening ? (m_conn_pool.size() - 1) : m_conn_pool.size()); } } // end namespace tcp } // end namespace pion pion-5.0.7+dfsg.orig/src/logger.cpp0000644000372000001440000000122212420270445016507 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include namespace pion { // begin namespace pion // static members of logger #if defined(PION_USE_OSTREAM_LOGGING) logger::log_priority_type logger::m_priority = logger::LOG_LEVEL_INFO; #endif } // end namespace pion pion-5.0.7+dfsg.orig/src/http_server.cpp0000644000372000001440000003342112420270445017603 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // static members of server const unsigned int server::MAX_REDIRECTS = 10; // server member functions void server::handle_connection(tcp::connection_ptr& tcp_conn) { request_reader_ptr my_reader_ptr; my_reader_ptr = request_reader::create(tcp_conn, boost::bind(&server::handle_request, this, _1, _2, _3)); my_reader_ptr->set_max_content_length(m_max_content_length); my_reader_ptr->receive(); } void server::handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const boost::system::error_code& ec) { if (ec || ! http_request_ptr->is_valid()) { tcp_conn->set_lifecycle(tcp::connection::LIFECYCLE_CLOSE); // make sure it will get closed if (tcp_conn->is_open() && (ec.category() == http::parser::get_error_category())) { // HTTP parser error PION_LOG_INFO(m_logger, "Invalid HTTP request (" << ec.message() << ")"); m_bad_request_handler(http_request_ptr, tcp_conn); } else { static const boost::system::error_condition ERRCOND_CANCELED(boost::system::errc::operation_canceled, boost::system::system_category()), ERRCOND_EOF(boost::asio::error::eof, boost::asio::error::misc_category); if (ec == ERRCOND_CANCELED || ec == ERRCOND_EOF) { // don't spam the log with common (non-)errors that happen during normal operation PION_LOG_DEBUG(m_logger, "Lost connection on port " << get_port() << " (" << ec.message() << ")"); } else { PION_LOG_INFO(m_logger, "Lost connection on port " << get_port() << " (" << ec.message() << ")"); } tcp_conn->finish(); } return; } PION_LOG_DEBUG(m_logger, "Received a valid HTTP request"); // strip off trailing slash if the request has one std::string resource_requested(strip_trailing_slash(http_request_ptr->get_resource())); // apply any redirection redirect_map_t::const_iterator it = m_redirects.find(resource_requested); unsigned int num_redirects = 0; while (it != m_redirects.end()) { if (++num_redirects > MAX_REDIRECTS) { PION_LOG_ERROR(m_logger, "Maximum number of redirects (server::MAX_REDIRECTS) exceeded for requested resource: " << http_request_ptr->get_original_resource()); m_server_error_handler(http_request_ptr, tcp_conn, "Maximum number of redirects (server::MAX_REDIRECTS) exceeded for requested resource"); return; } resource_requested = it->second; http_request_ptr->change_resource(resource_requested); it = m_redirects.find(resource_requested); } // if authentication activated, check current request if (m_auth_ptr) { // try to verify authentication if (! m_auth_ptr->handle_request(http_request_ptr, tcp_conn)) { // the HTTP 401 message has already been sent by the authentication object PION_LOG_DEBUG(m_logger, "Authentication required for HTTP resource: " << resource_requested); if (http_request_ptr->get_resource() != http_request_ptr->get_original_resource()) { PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request_ptr->get_original_resource()); } return; } } // search for a handler matching the resource requested request_handler_t request_handler; if (find_request_handler(resource_requested, request_handler)) { // try to handle the request try { request_handler(http_request_ptr, tcp_conn); PION_LOG_DEBUG(m_logger, "Found request handler for HTTP resource: " << resource_requested); if (http_request_ptr->get_resource() != http_request_ptr->get_original_resource()) { PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request_ptr->get_original_resource()); } } catch (std::bad_alloc&) { // propagate memory errors (FATAL) throw; } catch (std::exception& e) { // recover gracefully from other exceptions thrown by request handlers PION_LOG_ERROR(m_logger, "HTTP request handler: " << pion::diagnostic_information(e)); m_server_error_handler(http_request_ptr, tcp_conn, e.what()); } catch (boost::exception& e) { // recover gracefully from boost exceptions thrown by request handlers PION_LOG_ERROR(m_logger, "HTTP request handler: " << pion::diagnostic_information(e)); m_server_error_handler(http_request_ptr, tcp_conn, pion::diagnostic_information(e)); } } else { // no web services found that could handle the request PION_LOG_INFO(m_logger, "No HTTP request handlers found for resource: " << resource_requested); if (http_request_ptr->get_resource() != http_request_ptr->get_original_resource()) { PION_LOG_DEBUG(m_logger, "Original resource requested was: " << http_request_ptr->get_original_resource()); } m_not_found_handler(http_request_ptr, tcp_conn); } } bool server::find_request_handler(const std::string& resource, request_handler_t& request_handler) const { // first make sure that HTTP resources are registered boost::mutex::scoped_lock resource_lock(m_resource_mutex); if (m_resources.empty()) return false; // iterate through each resource entry that may match the resource resource_map_t::const_iterator i = m_resources.upper_bound(resource); while (i != m_resources.begin()) { --i; // check for a match if the first part of the strings match if (i->first.empty() || resource.compare(0, i->first.size(), i->first) == 0) { // only if the resource matches the plug-in's identifier // or if resource is followed first with a '/' character if (resource.size() == i->first.size() || resource[i->first.size()]=='/') { request_handler = i->second; return true; } } } return false; } void server::add_resource(const std::string& resource, request_handler_t request_handler) { boost::mutex::scoped_lock resource_lock(m_resource_mutex); const std::string clean_resource(strip_trailing_slash(resource)); m_resources.insert(std::make_pair(clean_resource, request_handler)); PION_LOG_INFO(m_logger, "Added request handler for HTTP resource: " << clean_resource); } void server::remove_resource(const std::string& resource) { boost::mutex::scoped_lock resource_lock(m_resource_mutex); const std::string clean_resource(strip_trailing_slash(resource)); m_resources.erase(clean_resource); PION_LOG_INFO(m_logger, "Removed request handler for HTTP resource: " << clean_resource); } void server::add_redirect(const std::string& requested_resource, const std::string& new_resource) { boost::mutex::scoped_lock resource_lock(m_resource_mutex); const std::string clean_requested_resource(strip_trailing_slash(requested_resource)); const std::string clean_new_resource(strip_trailing_slash(new_resource)); m_redirects.insert(std::make_pair(clean_requested_resource, clean_new_resource)); PION_LOG_INFO(m_logger, "Added redirection for HTTP resource " << clean_requested_resource << " to resource " << clean_new_resource); } void server::handle_bad_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string BAD_REQUEST_HTML = "\n" "400 Bad Request\n" "\n" "

Bad Request

\n" "

Your browser sent a request that this server could not understand.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_BAD_REQUEST); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_BAD_REQUEST); writer->write_no_copy(BAD_REQUEST_HTML); writer->send(); } void server::handle_not_found_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { static const std::string NOT_FOUND_HTML_START = "\n" "404 Not Found\n" "\n" "

Not Found

\n" "

The requested URL "; static const std::string NOT_FOUND_HTML_FINISH = " was not found on this server.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_NOT_FOUND); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_NOT_FOUND); writer->write_no_copy(NOT_FOUND_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(NOT_FOUND_HTML_FINISH); writer->send(); } void server::handle_server_error(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& error_msg) { static const std::string SERVER_ERROR_HTML_START = "\n" "500 Server Error\n" "\n" "

Internal Server Error

\n" "

The server encountered an internal error: "; static const std::string SERVER_ERROR_HTML_FINISH = "

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_SERVER_ERROR); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_SERVER_ERROR); writer->write_no_copy(SERVER_ERROR_HTML_START); writer << algorithm::xml_encode(error_msg); writer->write_no_copy(SERVER_ERROR_HTML_FINISH); writer->send(); } void server::handle_forbidden_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& error_msg) { static const std::string FORBIDDEN_HTML_START = "\n" "403 Forbidden\n" "\n" "

Forbidden

\n" "

User not authorized to access the requested URL "; static const std::string FORBIDDEN_HTML_MIDDLE = "

\n"; static const std::string FORBIDDEN_HTML_FINISH = "

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_FORBIDDEN); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_FORBIDDEN); writer->write_no_copy(FORBIDDEN_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_resource()); writer->write_no_copy(FORBIDDEN_HTML_MIDDLE); writer << error_msg; writer->write_no_copy(FORBIDDEN_HTML_FINISH); writer->send(); } void server::handle_method_not_allowed(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn, const std::string& allowed_methods) { static const std::string NOT_ALLOWED_HTML_START = "\n" "405 Method Not Allowed\n" "\n" "

Not Allowed

\n" "

The requested method "; static const std::string NOT_ALLOWED_HTML_FINISH = " is not allowed on this server.

\n" "\n"; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_METHOD_NOT_ALLOWED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED); if (! allowed_methods.empty()) writer->get_response().add_header("Allow", allowed_methods); writer->write_no_copy(NOT_ALLOWED_HTML_START); writer << algorithm::xml_encode(http_request_ptr->get_method()); writer->write_no_copy(NOT_ALLOWED_HTML_FINISH); writer->send(); } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/plugin.cpp0000644000372000001440000003631212420270445016536 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #ifdef PION_WIN32 #include #else #include #endif namespace pion { // begin namespace pion // static members of plugin const std::string plugin::PION_PLUGIN_CREATE("pion_create_"); const std::string plugin::PION_PLUGIN_DESTROY("pion_destroy_"); #ifdef PION_WIN32 const std::string plugin::PION_PLUGIN_EXTENSION(".dll"); #else const std::string plugin::PION_PLUGIN_EXTENSION(".so"); #endif const std::string plugin::PION_CONFIG_EXTENSION(".conf"); boost::once_flag plugin::m_instance_flag = BOOST_ONCE_INIT; plugin::config_type *plugin::m_config_ptr = NULL; // plugin member functions void plugin::create_plugin_config(void) { static config_type UNIQUE_PION_PLUGIN_CONFIG; m_config_ptr = &UNIQUE_PION_PLUGIN_CONFIG; } void plugin::check_cygwin_path(boost::filesystem::path& final_path, const std::string& start_path) { #if defined(PION_WIN32) && defined(PION_CYGWIN_DIRECTORY) // try prepending PION_CYGWIN_DIRECTORY if not complete if (! final_path.is_complete() && final_path.has_root_directory()) { final_path = boost::filesystem::path(std::string(PION_CYGWIN_DIRECTORY) + start_path); } #endif } void plugin::add_plugin_directory(const std::string& dir) { boost::filesystem::path plugin_path = boost::filesystem::system_complete(dir); check_cygwin_path(plugin_path, dir); if (! boost::filesystem::exists(plugin_path) ) BOOST_THROW_EXCEPTION( error::directory_not_found() << error::errinfo_dir_name(dir) ); config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 cfg.m_plugin_dirs.push_back(plugin_path.string()); #else cfg.m_plugin_dirs.push_back(plugin_path.directory_string()); #endif } void plugin::reset_plugin_directories(void) { config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); cfg.m_plugin_dirs.clear(); } void plugin::open(const std::string& plugin_name) { // check first if name matches an existing plugin name { config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); map_type::iterator itr = cfg.m_plugin_map.find(plugin_name); if (itr != cfg.m_plugin_map.end()) { release_data(); // make sure we're not already pointing to something m_plugin_data = itr->second; ++ m_plugin_data->m_references; return; } } // nope, look for shared library file std::string plugin_file; if (!find_plugin_file(plugin_file, plugin_name)) BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_name) ); open_file(plugin_file); } void plugin::open_file(const std::string& plugin_file) { release_data(); // make sure we're not already pointing to something // use a temporary object first since open_plugin() may throw data_type plugin_data(get_plugin_name(plugin_file)); // check to see if we already have a matching shared library config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); map_type::iterator itr = cfg.m_plugin_map.find(plugin_data.m_plugin_name); if (itr == cfg.m_plugin_map.end()) { // no plug-ins found with the same name // open up the shared library using our temporary data object open_plugin(plugin_file, plugin_data); // may throw // all is good -> insert it into the plug-in map m_plugin_data = new data_type(plugin_data); cfg.m_plugin_map.insert( std::make_pair(m_plugin_data->m_plugin_name, m_plugin_data) ); } else { // found an existing plug-in with the same name m_plugin_data = itr->second; } // increment the number of references ++ m_plugin_data->m_references; } void plugin::release_data(void) { if (m_plugin_data != NULL) { config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); // double-check after locking mutex if (m_plugin_data != NULL && --m_plugin_data->m_references == 0) { // no more references to the plug-in library // make sure it's not a static library if (m_plugin_data->m_lib_handle != NULL) { // release the shared object close_dynamic_library(m_plugin_data->m_lib_handle); // remove it from the plug-in map map_type::iterator itr = cfg.m_plugin_map.find(m_plugin_data->m_plugin_name); // check itr just to be safe (it SHOULD always find a match) if (itr != cfg.m_plugin_map.end()) cfg.m_plugin_map.erase(itr); // release the heap object delete m_plugin_data; } } m_plugin_data = NULL; } } void plugin::grab_data(const plugin& p) { release_data(); // make sure we're not already pointing to something config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); m_plugin_data = const_cast(p.m_plugin_data); if (m_plugin_data != NULL) { ++ m_plugin_data->m_references; } } bool plugin::find_file(std::string& path_to_file, const std::string& name, const std::string& extension) { // first, try the name as-is if (check_for_file(path_to_file, name, "", extension)) return true; // nope, check search paths config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); for (std::vector::iterator i = cfg.m_plugin_dirs.begin(); i != cfg.m_plugin_dirs.end(); ++i) { if (check_for_file(path_to_file, *i, name, extension)) return true; } // no plug-in file found return false; } bool plugin::check_for_file(std::string& final_path, const std::string& start_path, const std::string& name, const std::string& extension) { // check for cygwin path oddities boost::filesystem::path cygwin_safe_path(start_path); check_cygwin_path(cygwin_safe_path, start_path); boost::filesystem::path test_path(cygwin_safe_path); // if a name is specified, append it to the test path if (! name.empty()) test_path /= name; // check for existence of file (without extension) try { // is_regular may throw if directory is not readable if (boost::filesystem::is_regular(test_path)) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 final_path = test_path.string(); #else final_path = test_path.file_string(); #endif return true; } } catch (...) {} // next, try appending the extension if (name.empty()) { // no "name" specified -> append it directly to start_path test_path = boost::filesystem::path(start_path + extension); // in this case, we need to re-check for the cygwin oddities check_cygwin_path(test_path, start_path + extension); } else { // name is specified, so we can just re-use cygwin_safe_path test_path = cygwin_safe_path / boost::filesystem::path(name + extension); } // re-check for existence of file (after adding extension) try { // is_regular may throw if directory is not readable if (boost::filesystem::is_regular(test_path)) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 final_path = test_path.string(); #else final_path = test_path.file_string(); #endif return true; } } catch (...) {} // no plug-in file found return false; } void plugin::open_plugin(const std::string& plugin_file, data_type& plugin_data) { // get the name of the plugin (for create/destroy symbol names) plugin_data.m_plugin_name = get_plugin_name(plugin_file); // attempt to open the plugin; note that this tries all search paths // and also tries a variety of platform-specific extensions plugin_data.m_lib_handle = load_dynamic_library(plugin_file.c_str()); if (plugin_data.m_lib_handle == NULL) { #ifndef PION_WIN32 const char *error_msg = dlerror(); if (error_msg != NULL) { std::string error_str(plugin_file); error_str += " ("; error_str += error_msg; error_str += ')'; BOOST_THROW_EXCEPTION( error::open_plugin() << error::errinfo_plugin_name(plugin_data.m_plugin_name) << error::errinfo_message(error_str) ); } else #endif BOOST_THROW_EXCEPTION( error::open_plugin() << error::errinfo_plugin_name(plugin_data.m_plugin_name) ); } // find the function used to create new plugin objects plugin_data.m_create_func = get_library_symbol(plugin_data.m_lib_handle, PION_PLUGIN_CREATE + plugin_data.m_plugin_name); if (plugin_data.m_create_func == NULL) { close_dynamic_library(plugin_data.m_lib_handle); BOOST_THROW_EXCEPTION( error::plugin_missing_symbol() << error::errinfo_plugin_name(plugin_data.m_plugin_name) << error::errinfo_symbol_name(PION_PLUGIN_CREATE + plugin_data.m_plugin_name) ); } // find the function used to destroy existing plugin objects plugin_data.m_destroy_func = get_library_symbol(plugin_data.m_lib_handle, PION_PLUGIN_DESTROY + plugin_data.m_plugin_name); if (plugin_data.m_destroy_func == NULL) { close_dynamic_library(plugin_data.m_lib_handle); BOOST_THROW_EXCEPTION( error::plugin_missing_symbol() << error::errinfo_plugin_name(plugin_data.m_plugin_name) << error::errinfo_symbol_name(PION_PLUGIN_DESTROY + plugin_data.m_plugin_name) ); } } std::string plugin::get_plugin_name(const std::string& plugin_file) { return boost::filesystem::basename(boost::filesystem::path(plugin_file)); } void plugin::get_all_plugin_names(std::vector& plugin_names) { // Iterate through all the Plugin directories. std::vector::iterator it; config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); for (it = cfg.m_plugin_dirs.begin(); it != cfg.m_plugin_dirs.end(); ++it) { // Find all shared libraries in the directory and add them to the list of Plugin names. boost::filesystem::directory_iterator end; for (boost::filesystem::directory_iterator it2(*it); it2 != end; ++it2) { if (boost::filesystem::is_regular(*it2)) { if (boost::filesystem::extension(it2->path()) == plugin::PION_PLUGIN_EXTENSION) { # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 plugin_names.push_back(plugin::get_plugin_name(it2->path().filename().string())); #else plugin_names.push_back(plugin::get_plugin_name(it2->path().leaf())); #endif } } } } // Append static-linked libraries for (map_type::const_iterator itr = cfg.m_plugin_map.begin(); itr != cfg.m_plugin_map.end(); ++itr) { const data_type& plugin_data = *(itr->second); if (plugin_data.m_lib_handle == NULL) { plugin_names.push_back(plugin_data.m_plugin_name); } } } void *plugin::load_dynamic_library(const std::string& plugin_file) { #ifdef PION_WIN32 #ifdef _MSC_VER return LoadLibraryA(plugin_file.c_str()); #else return LoadLibrary(plugin_file.c_str()); #endif #else // convert into a full/absolute/complete path since dlopen() // does not always search the CWD on some operating systems # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 const boost::filesystem::path full_path = boost::filesystem::absolute(plugin_file); #else const boost::filesystem::path full_path = boost::filesystem::complete(plugin_file); #endif // NOTE: you must load shared libraries using RTLD_GLOBAL on Unix platforms // due to a bug in GCC (or Boost::any, depending on which crowd you want to believe). // see: http://svn.boost.org/trac/boost/ticket/754 # if defined(BOOST_FILESYSTEM_VERSION) && BOOST_FILESYSTEM_VERSION >= 3 return dlopen(full_path.string().c_str(), RTLD_LAZY | RTLD_GLOBAL); #else return dlopen(full_path.file_string().c_str(), RTLD_LAZY | RTLD_GLOBAL); #endif #endif } void plugin::close_dynamic_library(void *lib_handle) { #ifdef PION_WIN32 // Apparently, FreeLibrary sometimes causes crashes when running // unit tests under Windows. // It's hard to pin down, because many things can suppress the crashes, // such as enabling logging or setting breakpoints (i.e. things that // might help pin it down.) Also, it's very intermittent, and can be // strongly affected by other processes that are running. // So, please don't call FreeLibrary here unless you've been able to // reproduce and fix the crashing of the unit tests. //FreeLibrary((HINSTANCE) lib_handle); #else dlclose(lib_handle); #endif } void *plugin::get_library_symbol(void *lib_handle, const std::string& symbol) { #ifdef PION_WIN32 return (void*)GetProcAddress((HINSTANCE) lib_handle, symbol.c_str()); #else return dlsym(lib_handle, symbol.c_str()); #endif } void plugin::add_static_entry_point(const std::string& plugin_name, void *create_func, void *destroy_func) { // check for duplicate config_type& cfg = get_plugin_config(); boost::mutex::scoped_lock plugin_lock(cfg.m_plugin_mutex); map_type::iterator itr = cfg.m_plugin_map.find(plugin_name); if (itr == cfg.m_plugin_map.end()) { // no plug-ins found with the same name // all is good -> insert it into the plug-in map data_type *plugin_data = new data_type(plugin_name); plugin_data->m_lib_handle = NULL; // this will indicate that we are using statically linked plug-in plugin_data->m_create_func = create_func; plugin_data->m_destroy_func = destroy_func; cfg.m_plugin_map.insert(std::make_pair(plugin_name, plugin_data)); } } } // end namespace pion pion-5.0.7+dfsg.orig/src/scheduler.cpp0000644000372000001440000001377212420270445017223 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include namespace pion { // begin namespace pion // static members of scheduler const boost::uint32_t scheduler::DEFAULT_NUM_THREADS = 8; const boost::uint32_t scheduler::NSEC_IN_SECOND = 1000000000; // (10^9) const boost::uint32_t scheduler::MICROSEC_IN_SECOND = 1000000; // (10^6) const boost::uint32_t scheduler::KEEP_RUNNING_TIMER_SECONDS = 5; // scheduler member functions void scheduler::shutdown(void) { // lock mutex for thread safety boost::mutex::scoped_lock scheduler_lock(m_mutex); if (m_is_running) { PION_LOG_INFO(m_logger, "Shutting down the thread scheduler"); while (m_active_users > 0) { // first, wait for any active users to exit PION_LOG_INFO(m_logger, "Waiting for " << m_active_users << " scheduler users to finish"); m_no_more_active_users.wait(scheduler_lock); } // shut everything down m_is_running = false; stop_services(); stop_threads(); finish_services(); finish_threads(); PION_LOG_INFO(m_logger, "The thread scheduler has shutdown"); // Make sure anyone waiting on shutdown gets notified m_scheduler_has_stopped.notify_all(); } else { // stop and finish everything to be certain that no events are pending stop_services(); stop_threads(); finish_services(); finish_threads(); // Make sure anyone waiting on shutdown gets notified // even if the scheduler did not startup successfully m_scheduler_has_stopped.notify_all(); } } void scheduler::join(void) { boost::mutex::scoped_lock scheduler_lock(m_mutex); while (m_is_running) { // sleep until scheduler_has_stopped condition is signaled m_scheduler_has_stopped.wait(scheduler_lock); } } void scheduler::keep_running(boost::asio::io_service& my_service, boost::asio::deadline_timer& my_timer) { if (m_is_running) { // schedule this again to make sure the service doesn't complete my_timer.expires_from_now(boost::posix_time::seconds(KEEP_RUNNING_TIMER_SECONDS)); my_timer.async_wait(boost::bind(&scheduler::keep_running, this, boost::ref(my_service), boost::ref(my_timer))); } } void scheduler::add_active_user(void) { if (!m_is_running) startup(); boost::mutex::scoped_lock scheduler_lock(m_mutex); ++m_active_users; } void scheduler::remove_active_user(void) { boost::mutex::scoped_lock scheduler_lock(m_mutex); if (--m_active_users == 0) m_no_more_active_users.notify_all(); } boost::system_time scheduler::get_wakeup_time(boost::uint32_t sleep_sec, boost::uint32_t sleep_nsec) { return boost::get_system_time() + boost::posix_time::seconds(sleep_sec) + boost::posix_time::microseconds(sleep_nsec / 1000); } void scheduler::process_service_work(boost::asio::io_service& service) { while (m_is_running) { try { service.run(); } catch (std::exception& e) { PION_LOG_ERROR(m_logger, boost::diagnostic_information(e)); } catch (...) { PION_LOG_ERROR(m_logger, "caught unrecognized exception"); } } } // single_service_scheduler member functions void single_service_scheduler::startup(void) { // lock mutex for thread safety boost::mutex::scoped_lock scheduler_lock(m_mutex); if (! m_is_running) { PION_LOG_INFO(m_logger, "Starting thread scheduler"); m_is_running = true; // schedule a work item to make sure that the service doesn't complete m_service.reset(); keep_running(m_service, m_timer); // start multiple threads to handle async tasks for (boost::uint32_t n = 0; n < m_num_threads; ++n) { boost::shared_ptr new_thread(new boost::thread( boost::bind(&scheduler::process_service_work, this, boost::ref(m_service)) )); m_thread_pool.push_back(new_thread); } } } // one_to_one_scheduler member functions void one_to_one_scheduler::startup(void) { // lock mutex for thread safety boost::mutex::scoped_lock scheduler_lock(m_mutex); if (! m_is_running) { PION_LOG_INFO(m_logger, "Starting thread scheduler"); m_is_running = true; // make sure there are enough services initialized while (m_service_pool.size() < m_num_threads) { boost::shared_ptr service_ptr(new service_pair_type()); m_service_pool.push_back(service_ptr); } // schedule a work item for each service to make sure that it doesn't complete for (service_pool_type::iterator i = m_service_pool.begin(); i != m_service_pool.end(); ++i) { keep_running((*i)->first, (*i)->second); } // start multiple threads to handle async tasks for (boost::uint32_t n = 0; n < m_num_threads; ++n) { boost::shared_ptr new_thread(new boost::thread( boost::bind(&scheduler::process_service_work, this, boost::ref(m_service_pool[n]->first)) )); m_thread_pool.push_back(new_thread); } } } } // end namespace pion pion-5.0.7+dfsg.orig/src/http_parser.cpp0000644000372000001440000020033712420270445017573 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // static members of parser const boost::uint32_t parser::STATUS_MESSAGE_MAX = 1024; // 1 KB const boost::uint32_t parser::METHOD_MAX = 1024; // 1 KB const boost::uint32_t parser::RESOURCE_MAX = 256 * 1024; // 256 KB const boost::uint32_t parser::QUERY_STRING_MAX = 1024 * 1024; // 1 MB const boost::uint32_t parser::HEADER_NAME_MAX = 1024; // 1 KB const boost::uint32_t parser::HEADER_VALUE_MAX = 1024 * 1024; // 1 MB const boost::uint32_t parser::QUERY_NAME_MAX = 1024; // 1 KB const boost::uint32_t parser::QUERY_VALUE_MAX = 1024 * 1024; // 1 MB const boost::uint32_t parser::COOKIE_NAME_MAX = 1024; // 1 KB const boost::uint32_t parser::COOKIE_VALUE_MAX = 1024 * 1024; // 1 MB const std::size_t parser::DEFAULT_CONTENT_MAX = 1024 * 1024; // 1 MB parser::error_category_t * parser::m_error_category_ptr = NULL; boost::once_flag parser::m_instance_flag = BOOST_ONCE_INIT; // parser member functions boost::tribool parser::parse(http::message& http_msg, boost::system::error_code& ec) { BOOST_ASSERT(! eof() ); boost::tribool rc = boost::indeterminate; std::size_t total_bytes_parsed = 0; if(http_msg.has_missing_packets()) { http_msg.set_data_after_missing_packet(true); } do { switch (m_message_parse_state) { // just started parsing the HTTP message case PARSE_START: m_message_parse_state = PARSE_HEADERS; // step through to PARSE_HEADERS // parsing the HTTP headers case PARSE_HEADERS: case PARSE_FOOTERS: rc = parse_headers(http_msg, ec); total_bytes_parsed += m_bytes_last_read; // check if we have finished parsing HTTP headers if (rc == true && m_message_parse_state == PARSE_HEADERS) { // finish_header_parsing() updates m_message_parse_state // We only call this for Headers and not Footers rc = finish_header_parsing(http_msg, ec); } break; // parsing chunked payload content case PARSE_CHUNKS: rc = parse_chunks(http_msg.get_chunk_cache(), ec); total_bytes_parsed += m_bytes_last_read; // check if we have finished parsing all chunks if (rc == true && !m_payload_handler) { http_msg.concatenate_chunks(); // Handle footers if present rc = ((m_message_parse_state == PARSE_FOOTERS) ? boost::indeterminate : (boost::tribool)true); } break; // parsing regular payload content with a known length case PARSE_CONTENT: rc = consume_content(http_msg, ec); total_bytes_parsed += m_bytes_last_read; break; // parsing payload content with no length (until EOF) case PARSE_CONTENT_NO_LENGTH: consume_content_as_next_chunk(http_msg.get_chunk_cache()); total_bytes_parsed += m_bytes_last_read; break; // finished parsing the HTTP message case PARSE_END: rc = true; break; } } while ( boost::indeterminate(rc) && ! eof() ); // check if we've finished parsing the HTTP message if (rc == true) { m_message_parse_state = PARSE_END; finish(http_msg); } else if(rc == false) { compute_msg_status(http_msg, false); } // update bytes last read (aggregate individual operations for caller) m_bytes_last_read = total_bytes_parsed; return rc; } boost::tribool parser::parse_missing_data(http::message& http_msg, std::size_t len, boost::system::error_code& ec) { static const char MISSING_DATA_CHAR = 'X'; boost::tribool rc = boost::indeterminate; http_msg.set_missing_packets(true); switch (m_message_parse_state) { // cannot recover from missing data while parsing HTTP headers case PARSE_START: case PARSE_HEADERS: case PARSE_FOOTERS: set_error(ec, ERROR_MISSING_HEADER_DATA); rc = false; break; // parsing chunked payload content case PARSE_CHUNKS: // parsing chunk data -> we can only recover if data fits into current chunk if (m_chunked_content_parse_state == PARSE_CHUNK && m_bytes_read_in_current_chunk < m_size_of_current_chunk && (m_size_of_current_chunk - m_bytes_read_in_current_chunk) >= len) { // use dummy content for missing data if (m_payload_handler) { for (std::size_t n = 0; n < len; ++n) m_payload_handler(&MISSING_DATA_CHAR, 1); } else { for (std::size_t n = 0; n < len && http_msg.get_chunk_cache().size() < m_max_content_length; ++n) http_msg.get_chunk_cache().push_back(MISSING_DATA_CHAR); } m_bytes_read_in_current_chunk += len; m_bytes_last_read = len; m_bytes_total_read += len; m_bytes_content_read += len; if (m_bytes_read_in_current_chunk == m_size_of_current_chunk) { m_chunked_content_parse_state = PARSE_EXPECTING_CR_AFTER_CHUNK; } } else { // cannot recover from missing data set_error(ec, ERROR_MISSING_CHUNK_DATA); rc = false; } break; // parsing regular payload content with a known length case PARSE_CONTENT: // parsing content (with length) -> we can only recover if data fits into content if (m_bytes_content_remaining == 0) { // we have all of the remaining payload content rc = true; } else if (m_bytes_content_remaining < len) { // cannot recover from missing data set_error(ec, ERROR_MISSING_TOO_MUCH_CONTENT); rc = false; } else { // make sure content buffer is not already full if (m_payload_handler) { for (std::size_t n = 0; n < len; ++n) m_payload_handler(&MISSING_DATA_CHAR, 1); } else if ( (m_bytes_content_read+len) <= m_max_content_length) { // use dummy content for missing data for (std::size_t n = 0; n < len; ++n) http_msg.get_content()[m_bytes_content_read++] = MISSING_DATA_CHAR; } else { m_bytes_content_read += len; } m_bytes_content_remaining -= len; m_bytes_total_read += len; m_bytes_last_read = len; if (m_bytes_content_remaining == 0) rc = true; } break; // parsing payload content with no length (until EOF) case PARSE_CONTENT_NO_LENGTH: // use dummy content for missing data if (m_payload_handler) { for (std::size_t n = 0; n < len; ++n) m_payload_handler(&MISSING_DATA_CHAR, 1); } else { for (std::size_t n = 0; n < len && http_msg.get_chunk_cache().size() < m_max_content_length; ++n) http_msg.get_chunk_cache().push_back(MISSING_DATA_CHAR); } m_bytes_last_read = len; m_bytes_total_read += len; m_bytes_content_read += len; break; // finished parsing the HTTP message case PARSE_END: rc = true; break; } // check if we've finished parsing the HTTP message if (rc == true) { m_message_parse_state = PARSE_END; finish(http_msg); } else if(rc == false) { compute_msg_status(http_msg, false); } return rc; } boost::tribool parser::parse_headers(http::message& http_msg, boost::system::error_code& ec) { // // note that boost::tribool may have one of THREE states: // // false: encountered an error while parsing HTTP headers // true: finished successfully parsing the HTTP headers // indeterminate: parsed bytes, but the HTTP headers are not yet finished // const char *read_start_ptr = m_read_ptr; m_bytes_last_read = 0; while (m_read_ptr < m_read_end_ptr) { if (m_save_raw_headers) m_raw_headers += *m_read_ptr; switch (m_headers_parse_state) { case PARSE_METHOD_START: // we have not yet started parsing the HTTP method string if (*m_read_ptr != ' ' && *m_read_ptr!='\r' && *m_read_ptr!='\n') { // ignore leading whitespace if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_METHOD_CHAR); return false; } m_headers_parse_state = PARSE_METHOD; m_method.erase(); m_method.push_back(*m_read_ptr); } break; case PARSE_METHOD: // we have started parsing the HTTP method string if (*m_read_ptr == ' ') { m_resource.erase(); m_headers_parse_state = PARSE_URI_STEM; } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_METHOD_CHAR); return false; } else if (m_method.size() >= METHOD_MAX) { set_error(ec, ERROR_METHOD_SIZE); return false; } else { m_method.push_back(*m_read_ptr); } break; case PARSE_URI_STEM: // we have started parsing the URI stem (or resource name) if (*m_read_ptr == ' ') { m_headers_parse_state = PARSE_HTTP_VERSION_H; } else if (*m_read_ptr == '?') { m_query_string.erase(); m_headers_parse_state = PARSE_URI_QUERY; } else if (*m_read_ptr == '\r') { http_msg.set_version_major(0); http_msg.set_version_minor(0); m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { http_msg.set_version_major(0); http_msg.set_version_minor(0); m_headers_parse_state = PARSE_EXPECTING_CR; } else if (is_control(*m_read_ptr)) { set_error(ec, ERROR_URI_CHAR); return false; } else if (m_resource.size() >= RESOURCE_MAX) { set_error(ec, ERROR_URI_SIZE); return false; } else { m_resource.push_back(*m_read_ptr); } break; case PARSE_URI_QUERY: // we have started parsing the URI query string if (*m_read_ptr == ' ') { m_headers_parse_state = PARSE_HTTP_VERSION_H; } else if (*m_read_ptr == '\r') { http_msg.set_version_major(0); http_msg.set_version_minor(0); m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { http_msg.set_version_major(0); http_msg.set_version_minor(0); m_headers_parse_state = PARSE_EXPECTING_CR; } else if (is_control(*m_read_ptr)) { set_error(ec, ERROR_QUERY_CHAR); return false; } else if (m_query_string.size() >= QUERY_STRING_MAX) { set_error(ec, ERROR_QUERY_SIZE); return false; } else { m_query_string.push_back(*m_read_ptr); } break; case PARSE_HTTP_VERSION_H: // parsing "HTTP" if (*m_read_ptr == '\r') { // should only happen for requests (no HTTP/VERSION specified) if (! m_is_request) { set_error(ec, ERROR_VERSION_EMPTY); return false; } http_msg.set_version_major(0); http_msg.set_version_minor(0); m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { // should only happen for requests (no HTTP/VERSION specified) if (! m_is_request) { set_error(ec, ERROR_VERSION_EMPTY); return false; } http_msg.set_version_major(0); http_msg.set_version_minor(0); m_headers_parse_state = PARSE_EXPECTING_CR; } else if (*m_read_ptr != 'H') { set_error(ec, ERROR_VERSION_CHAR); return false; } m_headers_parse_state = PARSE_HTTP_VERSION_T_1; break; case PARSE_HTTP_VERSION_T_1: // parsing "HTTP" if (*m_read_ptr != 'T') { set_error(ec, ERROR_VERSION_CHAR); return false; } m_headers_parse_state = PARSE_HTTP_VERSION_T_2; break; case PARSE_HTTP_VERSION_T_2: // parsing "HTTP" if (*m_read_ptr != 'T') { set_error(ec, ERROR_VERSION_CHAR); return false; } m_headers_parse_state = PARSE_HTTP_VERSION_P; break; case PARSE_HTTP_VERSION_P: // parsing "HTTP" if (*m_read_ptr != 'P') { set_error(ec, ERROR_VERSION_CHAR); return false; } m_headers_parse_state = PARSE_HTTP_VERSION_SLASH; break; case PARSE_HTTP_VERSION_SLASH: // parsing slash after "HTTP" if (*m_read_ptr != '/') { set_error(ec, ERROR_VERSION_CHAR); return false; } m_headers_parse_state = PARSE_HTTP_VERSION_MAJOR_START; break; case PARSE_HTTP_VERSION_MAJOR_START: // parsing the first digit of the major version number if (!is_digit(*m_read_ptr)) { set_error(ec, ERROR_VERSION_CHAR); return false; } http_msg.set_version_major(*m_read_ptr - '0'); m_headers_parse_state = PARSE_HTTP_VERSION_MAJOR; break; case PARSE_HTTP_VERSION_MAJOR: // parsing the major version number (not first digit) if (*m_read_ptr == '.') { m_headers_parse_state = PARSE_HTTP_VERSION_MINOR_START; } else if (is_digit(*m_read_ptr)) { http_msg.set_version_major( (http_msg.get_version_major() * 10) + (*m_read_ptr - '0') ); } else { set_error(ec, ERROR_VERSION_CHAR); return false; } break; case PARSE_HTTP_VERSION_MINOR_START: // parsing the first digit of the minor version number if (!is_digit(*m_read_ptr)) { set_error(ec, ERROR_VERSION_CHAR); return false; } http_msg.set_version_minor(*m_read_ptr - '0'); m_headers_parse_state = PARSE_HTTP_VERSION_MINOR; break; case PARSE_HTTP_VERSION_MINOR: // parsing the major version number (not first digit) if (*m_read_ptr == ' ') { // ignore trailing spaces after version in request if (! m_is_request) { m_headers_parse_state = PARSE_STATUS_CODE_START; } } else if (*m_read_ptr == '\r') { // should only happen for requests if (! m_is_request) { set_error(ec, ERROR_STATUS_EMPTY); return false; } m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { // should only happen for requests if (! m_is_request) { set_error(ec, ERROR_STATUS_EMPTY); return false; } m_headers_parse_state = PARSE_EXPECTING_CR; } else if (is_digit(*m_read_ptr)) { http_msg.set_version_minor( (http_msg.get_version_minor() * 10) + (*m_read_ptr - '0') ); } else { set_error(ec, ERROR_VERSION_CHAR); return false; } break; case PARSE_STATUS_CODE_START: // parsing the first digit of the response status code if (!is_digit(*m_read_ptr)) { set_error(ec, ERROR_STATUS_CHAR); return false; } m_status_code = (*m_read_ptr - '0'); m_headers_parse_state = PARSE_STATUS_CODE; break; case PARSE_STATUS_CODE: // parsing the response status code (not first digit) if (*m_read_ptr == ' ') { m_status_message.erase(); m_headers_parse_state = PARSE_STATUS_MESSAGE; } else if (is_digit(*m_read_ptr)) { m_status_code = ( (m_status_code * 10) + (*m_read_ptr - '0') ); } else if (*m_read_ptr == '\r') { // recover from status message not sent m_status_message.erase(); m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { // recover from status message not sent m_status_message.erase(); m_headers_parse_state = PARSE_EXPECTING_CR; } else { set_error(ec, ERROR_STATUS_CHAR); return false; } break; case PARSE_STATUS_MESSAGE: // parsing the response status message if (*m_read_ptr == '\r') { m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { m_headers_parse_state = PARSE_EXPECTING_CR; } else if (is_control(*m_read_ptr)) { set_error(ec, ERROR_STATUS_CHAR); return false; } else if (m_status_message.size() >= STATUS_MESSAGE_MAX) { set_error(ec, ERROR_STATUS_CHAR); return false; } else { m_status_message.push_back(*m_read_ptr); } break; case PARSE_EXPECTING_NEWLINE: // we received a CR; expecting a newline to follow if (*m_read_ptr == '\n') { // check if this is a HTTP 0.9 "Simple Request" if (m_is_request && http_msg.get_version_major() == 0) { PION_LOG_DEBUG(m_logger, "HTTP 0.9 Simple-Request found"); ++m_read_ptr; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; return true; } else { m_headers_parse_state = PARSE_HEADER_START; } } else if (*m_read_ptr == '\r') { // we received two CR's in a row // assume CR only is (incorrectly) being used for line termination // therefore, the message is finished ++m_read_ptr; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; return true; } else if (*m_read_ptr == '\t' || *m_read_ptr == ' ') { m_headers_parse_state = PARSE_HEADER_WHITESPACE; } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_HEADER_CHAR); return false; } else { // assume it is the first character for the name of a header m_header_name.erase(); m_header_name.push_back(*m_read_ptr); m_headers_parse_state = PARSE_HEADER_NAME; } break; case PARSE_EXPECTING_CR: // we received a newline without a CR if (*m_read_ptr == '\r') { m_headers_parse_state = PARSE_HEADER_START; } else if (*m_read_ptr == '\n') { // we received two newlines in a row // assume newline only is (incorrectly) being used for line termination // therefore, the message is finished ++m_read_ptr; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; return true; } else if (*m_read_ptr == '\t' || *m_read_ptr == ' ') { m_headers_parse_state = PARSE_HEADER_WHITESPACE; } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_HEADER_CHAR); return false; } else { // assume it is the first character for the name of a header m_header_name.erase(); m_header_name.push_back(*m_read_ptr); m_headers_parse_state = PARSE_HEADER_NAME; } break; case PARSE_HEADER_WHITESPACE: // parsing whitespace before a header name if (*m_read_ptr == '\r') { m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { m_headers_parse_state = PARSE_EXPECTING_CR; } else if (*m_read_ptr != '\t' && *m_read_ptr != ' ') { if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_HEADER_CHAR); return false; } // assume it is the first character for the name of a header m_header_name.erase(); m_header_name.push_back(*m_read_ptr); m_headers_parse_state = PARSE_HEADER_NAME; } break; case PARSE_HEADER_START: // parsing the start of a new header if (*m_read_ptr == '\r') { m_headers_parse_state = PARSE_EXPECTING_FINAL_NEWLINE; } else if (*m_read_ptr == '\n') { m_headers_parse_state = PARSE_EXPECTING_FINAL_CR; } else if (*m_read_ptr == '\t' || *m_read_ptr == ' ') { m_headers_parse_state = PARSE_HEADER_WHITESPACE; } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_HEADER_CHAR); return false; } else { // first character for the name of a header m_header_name.erase(); m_header_name.push_back(*m_read_ptr); m_headers_parse_state = PARSE_HEADER_NAME; } break; case PARSE_HEADER_NAME: // parsing the name of a header if (*m_read_ptr == ':') { m_header_value.erase(); m_headers_parse_state = PARSE_SPACE_BEFORE_HEADER_VALUE; } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_HEADER_CHAR); return false; } else if (m_header_name.size() >= HEADER_NAME_MAX) { set_error(ec, ERROR_HEADER_NAME_SIZE); return false; } else { // character (not first) for the name of a header m_header_name.push_back(*m_read_ptr); } break; case PARSE_SPACE_BEFORE_HEADER_VALUE: // parsing space character before a header's value if (*m_read_ptr == ' ') { m_headers_parse_state = PARSE_HEADER_VALUE; } else if (*m_read_ptr == '\r') { http_msg.add_header(m_header_name, m_header_value); m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { http_msg.add_header(m_header_name, m_header_value); m_headers_parse_state = PARSE_EXPECTING_CR; } else if (!is_char(*m_read_ptr) || is_control(*m_read_ptr) || is_special(*m_read_ptr)) { set_error(ec, ERROR_HEADER_CHAR); return false; } else { // assume it is the first character for the value of a header m_header_value.push_back(*m_read_ptr); m_headers_parse_state = PARSE_HEADER_VALUE; } break; case PARSE_HEADER_VALUE: // parsing the value of a header if (*m_read_ptr == '\r') { http_msg.add_header(m_header_name, m_header_value); m_headers_parse_state = PARSE_EXPECTING_NEWLINE; } else if (*m_read_ptr == '\n') { http_msg.add_header(m_header_name, m_header_value); m_headers_parse_state = PARSE_EXPECTING_CR; } else if (*m_read_ptr != '\t' && is_control(*m_read_ptr)) { // RFC 2616, 2.2 basic Rules. // TEXT = // LWS = [CRLF] 1*( SP | HT ) // // TODO: parsing of folding LWS in multiple lines headers // doesn't work properly still set_error(ec, ERROR_HEADER_CHAR); return false; } else if (m_header_value.size() >= HEADER_VALUE_MAX) { set_error(ec, ERROR_HEADER_VALUE_SIZE); return false; } else { // character (not first) for the value of a header m_header_value.push_back(*m_read_ptr); } break; case PARSE_EXPECTING_FINAL_NEWLINE: if (*m_read_ptr == '\n') ++m_read_ptr; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; return true; case PARSE_EXPECTING_FINAL_CR: if (*m_read_ptr == '\r') ++m_read_ptr; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; return true; } ++m_read_ptr; } m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; return boost::indeterminate; } void parser::update_message_with_header_data(http::message& http_msg) const { if (is_parsing_request()) { // finish an HTTP request message http::request& http_request(dynamic_cast(http_msg)); http_request.set_method(m_method); http_request.set_resource(m_resource); http_request.set_query_string(m_query_string); // parse query pairs from the URI query string if (! m_query_string.empty()) { if (! parse_url_encoded(http_request.get_queries(), m_query_string.c_str(), m_query_string.size())) PION_LOG_WARN(m_logger, "Request query string parsing failed (URI)"); } // parse "Cookie" headers in request std::pair cookie_pair = http_request.get_headers().equal_range(http::types::HEADER_COOKIE); for (ihash_multimap::const_iterator cookie_iterator = cookie_pair.first; cookie_iterator != http_request.get_headers().end() && cookie_iterator != cookie_pair.second; ++cookie_iterator) { if (! parse_cookie_header(http_request.get_cookies(), cookie_iterator->second, false) ) PION_LOG_WARN(m_logger, "Cookie header parsing failed"); } } else { // finish an HTTP response message http::response& http_response(dynamic_cast(http_msg)); http_response.set_status_code(m_status_code); http_response.set_status_message(m_status_message); // parse "Set-Cookie" headers in response std::pair cookie_pair = http_response.get_headers().equal_range(http::types::HEADER_SET_COOKIE); for (ihash_multimap::const_iterator cookie_iterator = cookie_pair.first; cookie_iterator != http_response.get_headers().end() && cookie_iterator != cookie_pair.second; ++cookie_iterator) { if (! parse_cookie_header(http_response.get_cookies(), cookie_iterator->second, true) ) PION_LOG_WARN(m_logger, "Set-Cookie header parsing failed"); } } } boost::tribool parser::finish_header_parsing(http::message& http_msg, boost::system::error_code& ec) { boost::tribool rc = boost::indeterminate; m_bytes_content_remaining = m_bytes_content_read = 0; http_msg.set_content_length(0); http_msg.update_transfer_encoding_using_header(); update_message_with_header_data(http_msg); if (http_msg.is_chunked()) { // content is encoded using chunks m_message_parse_state = PARSE_CHUNKS; // return true if parsing headers only if (m_parse_headers_only) rc = true; } else if (http_msg.is_content_length_implied()) { // content length is implied to be zero m_message_parse_state = PARSE_END; rc = true; } else { // content length should be specified in the headers if (http_msg.has_header(http::types::HEADER_CONTENT_LENGTH)) { // message has a content-length header try { http_msg.update_content_length_using_header(); } catch (...) { PION_LOG_ERROR(m_logger, "Unable to update content length"); set_error(ec, ERROR_INVALID_CONTENT_LENGTH); return false; } // check if content-length header == 0 if (http_msg.get_content_length() == 0) { m_message_parse_state = PARSE_END; rc = true; } else { m_message_parse_state = PARSE_CONTENT; m_bytes_content_remaining = http_msg.get_content_length(); // check if content-length exceeds maximum allowed if (m_bytes_content_remaining > m_max_content_length) http_msg.set_content_length(m_max_content_length); if (m_parse_headers_only) { // return true if parsing headers only rc = true; } else { // allocate a buffer for payload content (may be zero-size) http_msg.create_content_buffer(); } } } else { // no content-length specified, and the content length cannot // otherwise be determined // only if not a request, read through the close of the connection if (! m_is_request) { // clear the chunk buffers before we start http_msg.get_chunk_cache().clear(); // continue reading content until there is no more data m_message_parse_state = PARSE_CONTENT_NO_LENGTH; // return true if parsing headers only if (m_parse_headers_only) rc = true; } else { m_message_parse_state = PARSE_END; rc = true; } } } finished_parsing_headers(ec); return rc; } bool parser::parse_uri(const std::string& uri, std::string& proto, std::string& host, boost::uint16_t& port, std::string& path, std::string& query) { size_t proto_end = uri.find("://"); size_t proto_len = 0; if(proto_end != std::string::npos) { proto = uri.substr(0, proto_end); proto_len = proto_end + 3; // add :// } else { proto.clear(); } // find a first slash charact // that indicates the end of the : part size_t server_port_end = uri.find('/', proto_len); if (server_port_end == std::string::npos) { // no path -> use just / path = "/"; server_port_end = uri.size(); } // copy : into temp string std::string t; t = uri.substr(proto_len, server_port_end - proto_len); size_t port_pos = t.find(':', 0); // assign output host and port parameters host = t.substr(0, port_pos); // if port_pos == npos, copy whole string if(host.length() == 0) { return false; } // parse the port, if it's not empty if(port_pos != std::string::npos) { try { port = boost::lexical_cast(t.substr(port_pos+1)); } catch (boost::bad_lexical_cast &) { return false; } } else if (proto == "http" || proto == "HTTP") { port = 80; } else if (proto == "https" || proto == "HTTPS") { port = 443; } else { port = 0; } if (server_port_end < uri.size()) { // copy the rest of the URI into path part path = uri.substr(server_port_end); // split the path and the query string parts size_t query_pos = path.find('?', 0); if(query_pos != std::string::npos) { query = path.substr(query_pos + 1, path.length() - query_pos - 1); path = path.substr(0, query_pos); } else { query.clear(); } } return true; } bool parser::parse_url_encoded(ihash_multimap& dict, const char *ptr, const size_t len) { // sanity check if (ptr == NULL || len == 0) return true; // used to track whether we are parsing the name or value enum QueryParseState { QUERY_PARSE_NAME, QUERY_PARSE_VALUE } parse_state = QUERY_PARSE_NAME; // misc other variables used for parsing const char * const end = ptr + len; std::string query_name; std::string query_value; // iterate through each encoded character while (ptr < end) { switch (parse_state) { case QUERY_PARSE_NAME: // parsing query name if (*ptr == '=') { // end of name found (OK if empty) parse_state = QUERY_PARSE_VALUE; } else if (*ptr == '&') { // if query name is empty, just skip it (i.e. "&&") if (! query_name.empty()) { // assume that "=" is missing -- it's OK if the value is empty dict.insert( std::make_pair(algorithm::url_decode(query_name), algorithm::url_decode(query_value)) ); query_name.erase(); } } else if (*ptr == '\r' || *ptr == '\n' || *ptr == '\t') { // ignore linefeeds, carriage return and tabs (normally within POST content) } else if (is_control(*ptr) || query_name.size() >= QUERY_NAME_MAX) { // control character detected, or max sized exceeded return false; } else { // character is part of the name query_name.push_back(*ptr); } break; case QUERY_PARSE_VALUE: // parsing query value if (*ptr == '&') { // end of value found (OK if empty) if (! query_name.empty()) { dict.insert( std::make_pair(algorithm::url_decode(query_name), algorithm::url_decode(query_value)) ); query_name.erase(); } query_value.erase(); parse_state = QUERY_PARSE_NAME; } else if (*ptr == ',') { // end of value found in multi-value list (OK if empty) if (! query_name.empty()) dict.insert( std::make_pair(algorithm::url_decode(query_name), algorithm::url_decode(query_value)) ); query_value.erase(); } else if (*ptr == '\r' || *ptr == '\n' || *ptr == '\t') { // ignore linefeeds, carriage return and tabs (normally within POST content) } else if (is_control(*ptr) || query_value.size() >= QUERY_VALUE_MAX) { // control character detected, or max sized exceeded return false; } else { // character is part of the value query_value.push_back(*ptr); } break; } ++ptr; } // handle last pair in string if (! query_name.empty()) dict.insert( std::make_pair(algorithm::url_decode(query_name), algorithm::url_decode(query_value)) ); return true; } bool parser::parse_multipart_form_data(ihash_multimap& dict, const std::string& content_type, const char *ptr, const size_t len) { // sanity check if (ptr == NULL || len == 0) return true; // parse field boundary std::size_t pos = content_type.find("boundary="); if (pos == std::string::npos) return false; const std::string boundary = std::string("--") + content_type.substr(pos+9); // used to track what we are parsing enum MultiPartParseState { MP_PARSE_START, MP_PARSE_HEADER_CR, MP_PARSE_HEADER_LF, MP_PARSE_HEADER_NAME, MP_PARSE_HEADER_SPACE, MP_PARSE_HEADER_VALUE, MP_PARSE_HEADER_LAST_LF, MP_PARSE_FIELD_DATA } parse_state = MP_PARSE_START; // a few variables used for parsing std::string header_name; std::string header_value; std::string field_name; std::string field_value; bool found_parameter = false; bool save_current_field = true; const char * const end_ptr = ptr + len; ptr = std::search(ptr, end_ptr, boundary.begin(), boundary.end()); while (ptr != NULL && ptr < end_ptr) { switch (parse_state) { case MP_PARSE_START: // start parsing a new field header_name.clear(); header_value.clear(); field_name.clear(); field_value.clear(); save_current_field = true; ptr += boundary.size() - 1; parse_state = MP_PARSE_HEADER_CR; break; case MP_PARSE_HEADER_CR: // expecting CR while parsing headers if (*ptr == '\r') { // got it -> look for linefeed parse_state = MP_PARSE_HEADER_LF; } else if (*ptr == '\n') { // got a linefeed? try to ignore and start parsing header parse_state = MP_PARSE_HEADER_NAME; } else if (*ptr == '-' && ptr+1 < end_ptr && ptr[1] == '-') { // end of multipart content return true; } else return false; break; case MP_PARSE_HEADER_LF: // expecting LF while parsing headers if (*ptr == '\n') { // got it -> start parsing header name parse_state = MP_PARSE_HEADER_NAME; } else return false; break; case MP_PARSE_HEADER_NAME: // parsing the name of a header if (*ptr == '\r' || *ptr == '\n') { if (header_name.empty()) { // got CR or LF at beginning; skip to data parse_state = (*ptr == '\r' ? MP_PARSE_HEADER_LAST_LF : MP_PARSE_FIELD_DATA); } else { // premature CR or LF -> just ignore and start parsing next header parse_state = (*ptr == '\r' ? MP_PARSE_HEADER_LF : MP_PARSE_HEADER_NAME); } } else if (*ptr == ':') { // done parsing header name -> consume space next parse_state = MP_PARSE_HEADER_SPACE; } else { // one more byte for header name header_name += *ptr; } break; case MP_PARSE_HEADER_SPACE: // expecting a space before header value if (*ptr == '\r') { // premature CR -> just ignore and start parsing next header parse_state = MP_PARSE_HEADER_LF; } else if (*ptr == '\n') { // premature LF -> just ignore and start parsing next header parse_state = MP_PARSE_HEADER_NAME; } else if (*ptr != ' ') { // not a space -> assume it's a value char header_value += *ptr; parse_state = MP_PARSE_HEADER_VALUE; } // otherwise just ignore the space(s) break; case MP_PARSE_HEADER_VALUE: // parsing the value of a header if (*ptr == '\r' || *ptr == '\n') { // reached the end of the value -> check if it's important if (boost::algorithm::iequals(header_name, types::HEADER_CONTENT_TYPE)) { // only keep fields that have a text type or no type save_current_field = boost::algorithm::iequals(header_value.substr(0, 5), "text/"); } else if (boost::algorithm::iequals(header_name, types::HEADER_CONTENT_DISPOSITION)) { // get current field from content-disposition header std::size_t name_pos = header_value.find("name=\""); if (name_pos != std::string::npos) { for (name_pos += 6; name_pos < header_value.size() && header_value[name_pos] != '\"'; ++name_pos) { field_name += header_value[name_pos]; } } } // clear values and start parsing next header header_name.clear(); header_value.clear(); parse_state = (*ptr == '\r' ? MP_PARSE_HEADER_LF : MP_PARSE_HEADER_NAME); } else { // one more byte for header value header_value += *ptr; } break; case MP_PARSE_HEADER_LAST_LF: // expecting final linefeed to terminate headers and begin field data if (*ptr == '\n') { // got it if (save_current_field && !field_name.empty()) { // parse the field if we care & know enough about it parse_state = MP_PARSE_FIELD_DATA; } else { // otherwise skip ahead to next field parse_state = MP_PARSE_START; ptr = std::search(ptr, end_ptr, boundary.begin(), boundary.end()); } } else return false; break; case MP_PARSE_FIELD_DATA: // parsing the value of a field -> find the end of it const char *field_end_ptr = end_ptr; const char *next_ptr = std::search(ptr, end_ptr, boundary.begin(), boundary.end()); if (next_ptr) { // don't include CRLF before next boundary const char *temp_ptr = next_ptr - 2; if (temp_ptr[0] == '\r' && temp_ptr[1] == '\n') field_end_ptr = temp_ptr; else field_end_ptr = next_ptr; } field_value.assign(ptr, field_end_ptr - ptr); // add the field to the query dictionary dict.insert( std::make_pair(field_name, field_value) ); found_parameter = true; // skip ahead to next field parse_state = MP_PARSE_START; ptr = next_ptr; break; } // we've already bumped position if MP_PARSE_START if (parse_state != MP_PARSE_START) ++ptr; } return found_parameter; } bool parser::parse_cookie_header(ihash_multimap& dict, const char *ptr, const size_t len, bool set_cookie_header) { // BASED ON RFC 2109 // http://www.ietf.org/rfc/rfc2109.txt // // The current implementation ignores cookie attributes which begin with '$' // (i.e. $Path=/, $Domain=, etc.) // used to track what we are parsing enum CookieParseState { COOKIE_PARSE_NAME, COOKIE_PARSE_VALUE, COOKIE_PARSE_IGNORE } parse_state = COOKIE_PARSE_NAME; // misc other variables used for parsing const char * const end = ptr + len; std::string cookie_name; std::string cookie_value; char value_quote_character = '\0'; // iterate through each character while (ptr < end) { switch (parse_state) { case COOKIE_PARSE_NAME: // parsing cookie name if (*ptr == '=') { // end of name found (OK if empty) value_quote_character = '\0'; parse_state = COOKIE_PARSE_VALUE; } else if (*ptr == ';' || *ptr == ',') { // ignore empty cookie names since this may occur naturally // when quoted values are encountered if (! cookie_name.empty()) { // value is empty (OK) if (! is_cookie_attribute(cookie_name, set_cookie_header)) dict.insert( std::make_pair(cookie_name, cookie_value) ); cookie_name.erase(); } } else if (*ptr != ' ') { // ignore whitespace // check if control character detected, or max sized exceeded if (is_control(*ptr) || cookie_name.size() >= COOKIE_NAME_MAX) return false; // character is part of the name cookie_name.push_back(*ptr); } break; case COOKIE_PARSE_VALUE: // parsing cookie value if (value_quote_character == '\0') { // value is not (yet) quoted if (*ptr == ';' || *ptr == ',') { // end of value found (OK if empty) if (! is_cookie_attribute(cookie_name, set_cookie_header)) dict.insert( std::make_pair(cookie_name, cookie_value) ); cookie_name.erase(); cookie_value.erase(); parse_state = COOKIE_PARSE_NAME; } else if (*ptr == '\'' || *ptr == '"') { if (cookie_value.empty()) { // begin quoted value value_quote_character = *ptr; } else if (cookie_value.size() >= COOKIE_VALUE_MAX) { // max size exceeded return false; } else { // assume character is part of the (unquoted) value cookie_value.push_back(*ptr); } } else if (*ptr != ' ' || !cookie_value.empty()) { // ignore leading unquoted whitespace // check if control character detected, or max sized exceeded if (is_control(*ptr) || cookie_value.size() >= COOKIE_VALUE_MAX) return false; // character is part of the (unquoted) value cookie_value.push_back(*ptr); } } else { // value is quoted if (*ptr == value_quote_character) { // end of value found (OK if empty) if (! is_cookie_attribute(cookie_name, set_cookie_header)) dict.insert( std::make_pair(cookie_name, cookie_value) ); cookie_name.erase(); cookie_value.erase(); parse_state = COOKIE_PARSE_IGNORE; } else if (cookie_value.size() >= COOKIE_VALUE_MAX) { // max size exceeded return false; } else { // character is part of the (quoted) value cookie_value.push_back(*ptr); } } break; case COOKIE_PARSE_IGNORE: // ignore everything until we reach a comma "," or semicolon ";" if (*ptr == ';' || *ptr == ',') parse_state = COOKIE_PARSE_NAME; break; } ++ptr; } // handle last cookie in string if (! is_cookie_attribute(cookie_name, set_cookie_header)) dict.insert( std::make_pair(cookie_name, cookie_value) ); return true; } boost::tribool parser::parse_chunks(http::message::chunk_cache_t& chunks, boost::system::error_code& ec) { // // note that boost::tribool may have one of THREE states: // // false: encountered an error while parsing message // true: finished successfully parsing the message // indeterminate: parsed bytes, but the message is not yet finished // const char *read_start_ptr = m_read_ptr; m_bytes_last_read = 0; while (m_read_ptr < m_read_end_ptr) { switch (m_chunked_content_parse_state) { case PARSE_CHUNK_SIZE_START: // we have not yet started parsing the next chunk size if (is_hex_digit(*m_read_ptr)) { m_chunk_size_str.erase(); m_chunk_size_str.push_back(*m_read_ptr); m_chunked_content_parse_state = PARSE_CHUNK_SIZE; } else if (*m_read_ptr == ' ' || *m_read_ptr == '\x09' || *m_read_ptr == '\x0D' || *m_read_ptr == '\x0A') { // Ignore leading whitespace. Technically, the standard probably doesn't allow white space here, // but we'll be flexible, since there's no ambiguity. break; } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } break; case PARSE_CHUNK_SIZE: if (is_hex_digit(*m_read_ptr)) { m_chunk_size_str.push_back(*m_read_ptr); } else if (*m_read_ptr == '\x0D') { m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE; } else if (*m_read_ptr == ' ' || *m_read_ptr == '\x09') { // Ignore trailing tabs or spaces. Technically, the standard probably doesn't allow this, // but we'll be flexible, since there's no ambiguity. m_chunked_content_parse_state = PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE; } else if (*m_read_ptr == ';') { // Following the semicolon we have text which will be ignored till we encounter // a CRLF m_chunked_content_parse_state = PARSE_EXPECTING_IGNORED_TEXT_AFTER_CHUNK_SIZE; } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } break; case PARSE_EXPECTING_IGNORED_TEXT_AFTER_CHUNK_SIZE: if (*m_read_ptr == '\x0D') { m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE; } break; case PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE: if (*m_read_ptr == '\x0D') { m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE; } else if (*m_read_ptr == ' ' || *m_read_ptr == '\x09') { // Ignore trailing tabs or spaces. Technically, the standard probably doesn't allow this, // but we'll be flexible, since there's no ambiguity. break; } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } break; case PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE: // We received a CR; expecting LF to follow. We can't be flexible here because // if we see anything other than LF, we can't be certain where the chunk starts. if (*m_read_ptr == '\x0A') { m_bytes_read_in_current_chunk = 0; m_size_of_current_chunk = strtol(m_chunk_size_str.c_str(), 0, 16); if (m_size_of_current_chunk == 0) { m_chunked_content_parse_state = PARSE_EXPECTING_FINAL_CR_OR_FOOTERS_AFTER_LAST_CHUNK; } else { m_chunked_content_parse_state = PARSE_CHUNK; } } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } break; case PARSE_CHUNK: if (m_bytes_read_in_current_chunk < m_size_of_current_chunk) { if (m_payload_handler) { const std::size_t bytes_avail = bytes_available(); const std::size_t bytes_in_chunk = m_size_of_current_chunk - m_bytes_read_in_current_chunk; const std::size_t len = (bytes_in_chunk > bytes_avail) ? bytes_avail : bytes_in_chunk; m_payload_handler(m_read_ptr, len); m_bytes_read_in_current_chunk += len; if (len > 1) m_read_ptr += (len - 1); } else if (chunks.size() < m_max_content_length) { chunks.push_back(*m_read_ptr); m_bytes_read_in_current_chunk++; } } if (m_bytes_read_in_current_chunk == m_size_of_current_chunk) { m_chunked_content_parse_state = PARSE_EXPECTING_CR_AFTER_CHUNK; } break; case PARSE_EXPECTING_CR_AFTER_CHUNK: // we've read exactly m_size_of_current_chunk bytes since starting the current chunk if (*m_read_ptr == '\x0D') { m_chunked_content_parse_state = PARSE_EXPECTING_LF_AFTER_CHUNK; } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } break; case PARSE_EXPECTING_LF_AFTER_CHUNK: // we received a CR; expecting LF to follow if (*m_read_ptr == '\x0A') { m_chunked_content_parse_state = PARSE_CHUNK_SIZE_START; } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } break; case PARSE_EXPECTING_FINAL_CR_OR_FOOTERS_AFTER_LAST_CHUNK: // we've read the final chunk; expecting final CRLF if (*m_read_ptr == '\x0D') { m_chunked_content_parse_state = PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK; } else { // Packet contains footers; Chunk parsing is commplete // Footer data contains name value pairs to be added to HTTP Message m_message_parse_state = PARSE_FOOTERS; m_headers_parse_state = PARSE_HEADER_START; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; m_bytes_content_read += m_bytes_last_read; PION_LOG_DEBUG(m_logger, "Parsed " << m_bytes_last_read << " chunked payload content bytes; chunked content complete."); return true; } break; case PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK: // we received the final CR; expecting LF to follow if (*m_read_ptr == '\x0A') { ++m_read_ptr; m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; m_bytes_content_read += m_bytes_last_read; PION_LOG_DEBUG(m_logger, "Parsed " << m_bytes_last_read << " chunked payload content bytes; chunked content complete."); return true; } else { set_error(ec, ERROR_CHUNK_CHAR); return false; } } ++m_read_ptr; } m_bytes_last_read = (m_read_ptr - read_start_ptr); m_bytes_total_read += m_bytes_last_read; m_bytes_content_read += m_bytes_last_read; return boost::indeterminate; } boost::tribool parser::consume_content(http::message& http_msg, boost::system::error_code& ec) { size_t content_bytes_to_read; size_t content_bytes_available = bytes_available(); boost::tribool rc = boost::indeterminate; if (m_bytes_content_remaining == 0) { // we have all of the remaining payload content return true; } else { if (content_bytes_available >= m_bytes_content_remaining) { // we have all of the remaining payload content rc = true; content_bytes_to_read = m_bytes_content_remaining; } else { // only some of the payload content is available content_bytes_to_read = content_bytes_available; } m_bytes_content_remaining -= content_bytes_to_read; } // make sure content buffer is not already full if (m_payload_handler) { m_payload_handler(m_read_ptr, content_bytes_to_read); } else if (m_bytes_content_read < m_max_content_length) { if (m_bytes_content_read + content_bytes_to_read > m_max_content_length) { // read would exceed maximum size for content buffer // copy only enough bytes to fill up the content buffer memcpy(http_msg.get_content() + m_bytes_content_read, m_read_ptr, m_max_content_length - m_bytes_content_read); } else { // copy all bytes available memcpy(http_msg.get_content() + m_bytes_content_read, m_read_ptr, content_bytes_to_read); } } m_read_ptr += content_bytes_to_read; m_bytes_content_read += content_bytes_to_read; m_bytes_total_read += content_bytes_to_read; m_bytes_last_read = content_bytes_to_read; return rc; } std::size_t parser::consume_content_as_next_chunk(http::message::chunk_cache_t& chunks) { if (bytes_available() == 0) { m_bytes_last_read = 0; } else { // note: m_bytes_last_read must be > 0 because of bytes_available() check m_bytes_last_read = (m_read_end_ptr - m_read_ptr); if (m_payload_handler) { m_payload_handler(m_read_ptr, m_bytes_last_read); m_read_ptr += m_bytes_last_read; } else { while (m_read_ptr < m_read_end_ptr) { if (chunks.size() < m_max_content_length) chunks.push_back(*m_read_ptr); ++m_read_ptr; } } m_bytes_total_read += m_bytes_last_read; m_bytes_content_read += m_bytes_last_read; } return m_bytes_last_read; } void parser::finish(http::message& http_msg) const { switch (m_message_parse_state) { case PARSE_START: http_msg.set_is_valid(false); http_msg.set_content_length(0); http_msg.create_content_buffer(); return; case PARSE_END: http_msg.set_is_valid(true); break; case PARSE_HEADERS: case PARSE_FOOTERS: http_msg.set_is_valid(false); update_message_with_header_data(http_msg); http_msg.set_content_length(0); http_msg.create_content_buffer(); break; case PARSE_CONTENT: http_msg.set_is_valid(false); if (get_content_bytes_read() < m_max_content_length) // NOTE: we can read more than we have allocated/stored http_msg.set_content_length(get_content_bytes_read()); break; case PARSE_CHUNKS: http_msg.set_is_valid(m_chunked_content_parse_state==PARSE_CHUNK_SIZE_START); if (!m_payload_handler) http_msg.concatenate_chunks(); break; case PARSE_CONTENT_NO_LENGTH: http_msg.set_is_valid(true); if (!m_payload_handler) http_msg.concatenate_chunks(); break; } compute_msg_status(http_msg, http_msg.is_valid()); if (is_parsing_request() && !m_payload_handler && !m_parse_headers_only) { // Parse query pairs from post content if content type is x-www-form-urlencoded. // Type could be followed by parameters (as defined in section 3.6 of RFC 2616) // e.g. Content-Type: application/x-www-form-urlencoded; charset=UTF-8 http::request& http_request(dynamic_cast(http_msg)); const std::string& content_type_header = http_request.get_header(http::types::HEADER_CONTENT_TYPE); if (content_type_header.compare(0, http::types::CONTENT_TYPE_URLENCODED.length(), http::types::CONTENT_TYPE_URLENCODED) == 0) { if (! parse_url_encoded(http_request.get_queries(), http_request.get_content(), http_request.get_content_length())) PION_LOG_WARN(m_logger, "Request form data parsing failed (POST urlencoded)"); } else if (content_type_header.compare(0, http::types::CONTENT_TYPE_MULTIPART_FORM_DATA.length(), http::types::CONTENT_TYPE_MULTIPART_FORM_DATA) == 0) { if (! parse_multipart_form_data(http_request.get_queries(), content_type_header, http_request.get_content(), http_request.get_content_length())) PION_LOG_WARN(m_logger, "Request form data parsing failed (POST multipart)"); } } } void parser::compute_msg_status(http::message& http_msg, bool msg_parsed_ok ) { http::message::data_status_t st = http::message::STATUS_NONE; if(http_msg.has_missing_packets()) { st = http_msg.has_data_after_missing_packets() ? http::message::STATUS_PARTIAL : http::message::STATUS_TRUNCATED; } else { st = msg_parsed_ok ? http::message::STATUS_OK : http::message::STATUS_TRUNCATED; } http_msg.set_status(st); } void parser::create_error_category(void) { static error_category_t UNIQUE_ERROR_CATEGORY; m_error_category_ptr = &UNIQUE_ERROR_CATEGORY; } bool parser::parse_forwarded_for(const std::string& header, std::string& public_ip) { // static regex's used to check for ipv4 address static const boost::regex IPV4_ADDR_RX("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"); /// static regex used to check for private/local networks: /// 10.* /// 127.* /// 192.168.* /// 172.16-31.* static const boost::regex PRIVATE_NET_RX("(10\\.[0-9]{1,3}|127\\.[0-9]{1,3}|192\\.168|172\\.1[6-9]|172\\.2[0-9]|172\\.3[0-1])\\.[0-9]{1,3}\\.[0-9]{1,3}"); // sanity check if (header.empty()) return false; // local variables re-used by while loop boost::match_results m; std::string::const_iterator start_it = header.begin(); // search for next ip address within the header while (boost::regex_search(start_it, header.end(), m, IPV4_ADDR_RX)) { // get ip that matched std::string ip_str(m[0].first, m[0].second); // check if public network ip address if (! boost::regex_match(ip_str, PRIVATE_NET_RX) ) { // match found! public_ip = ip_str; return true; } // update search starting position start_it = m[0].second; } // no matches found return false; } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/spdy_parser.cpp0000644000372000001440000004242612420270445017576 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include #include namespace pion { // begin namespace pion namespace spdy { // begin namespace spdy /// RST stream status string from code, return NULL for unknown status code static char const* rst_stream_status(boost::uint32_t rst_stream_status_code) { switch (rst_stream_status_code) { case 1: return "PROTOCOL_ERROR"; case 2: return "INVALID_STREAM"; case 3: return "REFUSED_STREAM"; case 4: return "UNSUPPORTED_VERSION"; case 5: return "CANCEL"; case 6: return "INTERNAL_ERROR"; case 7: return "FLOW_CONTROL_ERROR"; case 8: return "STREAM_IN_USE"; case 9: return "STREAM_ALREADY_CLOSED"; case 10: return "INVALID_CREDENTIALS"; case 11: return "FRAME_TOO_LARGE"; case 12: return "INVALID"; default: return NULL; } } parser::error_category_t * parser::m_error_category_ptr = NULL; boost::once_flag parser::m_instance_flag = BOOST_ONCE_INIT; // parser member functions parser::parser() : m_read_ptr(NULL), m_uncompressed_ptr(NULL), m_current_data_chunk_ptr(NULL), m_last_data_chunk_ptr(NULL), m_logger(PION_GET_LOGGER("pion.spdy.parser")) {} boost::tribool parser::parse(http_protocol_info& http_info, boost::system::error_code& ec, decompressor_ptr& decompressor, const char *packet_ptr, boost::uint32_t& length_packet, boost::uint32_t current_stream_count) { // initialize read position set_read_ptr(packet_ptr); // Parse the frame return parse_spdy_frame(ec, decompressor, http_info, length_packet, current_stream_count); } bool parser::is_spdy_control_frame(const char *ptr) { // Parse further for higher accuracy // Get the control bit boost::uint8_t control_bit; boost::uint16_t version, type; boost::uint16_t byte_value = algorithm::to_uint16(ptr); control_bit = byte_value >> (sizeof(short) * CHAR_BIT - 1); if (!control_bit) return false; // Control bit is set; This is a control frame // Get the version number boost::uint16_t two_bytes = algorithm::to_uint16(ptr); version = two_bytes & 0x7FFF; if(version < 1 || version > 3){ // SPDY does not have a version higher than 3 and lower than 1 at the moment return false; } // Increment the read pointer ptr += 2; type = algorithm::to_uint16(ptr); if (type >= SPDY_INVALID) { // Not among the recognized SPDY types return false; } return true; } spdy_frame_type parser::get_spdy_frame_type(const char *ptr) { // Determine if this a SPDY frame BOOST_ASSERT(ptr); /* * The first byte of a SPDY frame must be either 0 or * 0x80. If it's not, assume that this is not SPDY. * (In theory, a data frame could have a stream ID * >= 2^24, in which case it won't have 0 for a first * byte, but this is a pretty reliable heuristic for * now.) */ spdy_frame_type spdy_frame; boost::uint8_t first_byte = *((unsigned char *)ptr); if(first_byte == 0x80){ spdy_frame = spdy_control_frame; }else if(first_byte == 0x0){ spdy_frame = spdy_data_frame; }else{ spdy_frame = spdy_invalid_frame; } return spdy_frame; } boost::uint32_t parser::get_control_frame_stream_id(const char *ptr) { // The stream ID for control frames is at a 8 bit offser from start ptr += 8; boost::uint32_t four_bytes = algorithm::to_uint32(ptr); return four_bytes & 0x7FFFFFFF; } boost::tribool parser::parse_spdy_frame(boost::system::error_code& ec, decompressor_ptr& decompressor, http_protocol_info& http_info, boost::uint32_t& length_packet, boost::uint32_t current_stream_count) { boost::tribool rc = true; // Verify that this is a spdy frame BOOST_ASSERT(m_read_ptr); boost::uint8_t first_byte = (boost::uint8_t)*m_read_ptr; if (first_byte != 0x80 && first_byte != 0x0) { // This is not a SPDY frame, throw an error PION_LOG_ERROR(m_logger, "Invalid SPDY Frame"); set_error(ec, ERROR_INVALID_SPDY_FRAME); return false; } boost::uint8_t control_bit; spdy_control_frame_info frame; boost::uint32_t stream_id = 0; ec.clear(); // Populate the frame bool populate_frame_result = populate_frame(ec, frame, length_packet, stream_id, http_info); if(!populate_frame_result){ /// There was an error; No need to further parse. return false; } BOOST_ASSERT(stream_id != 0); control_bit = (boost::uint8_t)frame.control_bit; // There is a possibility that there are more than one SPDY frames in one TCP frame if(length_packet > frame.length){ m_current_data_chunk_ptr = m_read_ptr + frame.length; length_packet -= frame.length; rc = boost::indeterminate; } if (!control_bit) { // Parse the data packet parse_spdy_data(ec, frame, stream_id, http_info); } /* Abort here if the version is too low. */ if (frame.version > MIN_SPDY_VERSION) { // Version less that min SPDY version, throw an error PION_LOG_ERROR(m_logger, "Invalid SPDY Version Number"); set_error(ec, ERROR_INVALID_SPDY_VERSION); return false; } if(frame.type == SPDY_SYN_STREAM){ http_info.http_type = HTTP_REQUEST; }else if (frame.type == SPDY_SYN_REPLY){ http_info.http_type = HTTP_RESPONSE; }else if (frame.type == SPDY_DATA){ http_info.http_type = HTTP_DATA; } switch (frame.type) { case SPDY_SYN_STREAM: case SPDY_SYN_REPLY: case SPDY_HEADERS: parse_header_payload(ec, decompressor, frame, http_info, current_stream_count); break; case SPDY_RST_STREAM: parse_spdy_rst_stream(ec, frame); http_info.http_type = SPDY_CONTROL; break; case SPDY_SETTINGS: parse_spdy_settings_frame(ec, frame); http_info.http_type = SPDY_CONTROL; break; case SPDY_PING: parse_spdy_ping_frame(ec, frame); http_info.http_type = SPDY_CONTROL; break; case SPDY_GOAWAY: parse_spdy_goaway_frame(ec, frame); http_info.http_type = SPDY_CONTROL; break; case SPDY_WINDOW_UPDATE: parse_spdy_window_update_frame(ec, frame); http_info.http_type = SPDY_CONTROL; break; case SPDY_CREDENTIAL: // We dont need to parse this for now http_info.http_type = SPDY_CONTROL; break; default: break; } if (ec) return false; m_last_data_chunk_ptr = m_read_ptr; m_read_ptr = m_current_data_chunk_ptr; return rc; } void parser::create_error_category(void) { static error_category_t UNIQUE_ERROR_CATEGORY; m_error_category_ptr = &UNIQUE_ERROR_CATEGORY; } bool parser::populate_frame(boost::system::error_code& ec, spdy_control_frame_info& frame, boost::uint32_t& length_packet, boost::uint32_t& stream_id, http_protocol_info& http_info) { // Get the control bit boost::uint8_t control_bit; boost::uint16_t byte_value = algorithm::to_uint16(m_read_ptr); control_bit = byte_value >> (sizeof(short) * CHAR_BIT - 1); frame.control_bit = (control_bit != 0); if(control_bit){ // Control bit is set; This is a control frame // Get the version number boost::uint16_t two_bytes = algorithm::to_uint16(m_read_ptr); frame.version = two_bytes & 0x7FFF; // Increment the read pointer m_read_ptr += 2; length_packet -= 2; http_info.data_offset +=2; // Get the type frame.type = algorithm::to_uint16(m_read_ptr); if (frame.type >= SPDY_INVALID) { // SPDY Frame is invalid // This is not a SPDY frame, throw an error PION_LOG_ERROR(m_logger, "Invalid SPDY Frame"); set_error(ec, ERROR_INVALID_SPDY_FRAME); return false; } }else { // Control bit is not set; This is a data frame frame.type = SPDY_DATA; frame.version = 0; /* Version doesn't apply to DATA. */ // Get the stream id boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr); stream_id = four_bytes & 0x7FFFFFFF; http_info.stream_id = stream_id; m_read_ptr +=2; http_info.data_offset +=2; length_packet -= 2; } // Increment the read pointer m_read_ptr += 2; length_packet -= 2; http_info.data_offset +=2; // Get the flags frame.flags = (boost::uint8_t)*m_read_ptr; // Increment the read pointer // Get the length boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr); frame.length = four_bytes & 0xFFFFFF; // Increment the read pointer m_read_ptr += 4; length_packet -= 4; http_info.data_offset +=4; http_info.data_size = frame.length; if(control_bit){ four_bytes = algorithm::to_uint32(m_read_ptr); stream_id = four_bytes & 0x7FFFFFFF; } return true; } void parser::parse_header_payload(boost::system::error_code &ec, decompressor_ptr& decompressor, const spdy_control_frame_info& frame, http_protocol_info& http_info, boost::uint32_t current_stream_count) { boost::uint32_t stream_id = 0; boost::uint32_t associated_stream_id; boost::uint32_t header_block_length = frame.length; // Get the 31 bit stream id boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr); stream_id = four_bytes & 0x7FFFFFFF; m_read_ptr += 4; http_info.stream_id = stream_id; // Get SYN_STREAM-only fields. if (frame.type == SPDY_SYN_STREAM) { // Get associated stream ID. boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr); associated_stream_id = four_bytes & 0x7FFFFFFF; m_read_ptr += 4; // The next bits are priority, unused, and slot. // Disregard these for now as we dont need them m_read_ptr +=2 ; } else if( frame.type == SPDY_SYN_REPLY || frame.type == SPDY_HEADERS ) { // Unused bits m_read_ptr +=2 ; } // Get our header block length. switch (frame.type) { case SPDY_SYN_STREAM: header_block_length -= 10; break; case SPDY_SYN_REPLY: case SPDY_HEADERS: // This is a very important distinction. // It should be 6 bytes for SPDYv2 and 4 bytes for SPDYv3. header_block_length -= 6; break; default: // Unhandled case. This should never happen. PION_LOG_ERROR(m_logger, "Invalid SPDY Frame Type"); set_error(ec, ERROR_INVALID_SPDY_FRAME); return; } // Decompress header block as necessary. m_uncompressed_ptr = decompressor->decompress(m_read_ptr, stream_id, frame, header_block_length); if (!m_uncompressed_ptr) { set_error(ec, ERROR_DECOMPRESSION); return; } // Now parse the name/value pairs // The number of name/value pairs is 16 bit SPDYv2 // and it is 32 bit in SPDYv3 // TBD : Add support for SPDYv3 boost::uint16_t num_name_val_pairs = algorithm::to_uint16(m_uncompressed_ptr); m_uncompressed_ptr += 2; std::string content_type = ""; std::string content_encoding = ""; for(boost::uint16_t count = 0; count < num_name_val_pairs; ++count){ // Get the length of the name boost::uint16_t length_name = algorithm::to_uint16(m_uncompressed_ptr); std::string name = ""; m_uncompressed_ptr += 2; { for(boost::uint16_t count = 0; count < length_name; ++count){ name.push_back(*(m_uncompressed_ptr+count)); } m_uncompressed_ptr += length_name; } // Get the length of the value boost::uint16_t length_value = algorithm::to_uint16(m_uncompressed_ptr); std::string value = ""; m_uncompressed_ptr += 2; { for(boost::uint16_t count = 0; count < length_value; ++count){ value.push_back(*(m_uncompressed_ptr+count)); } m_uncompressed_ptr += length_value; } // Save these headers http_info.http_headers.insert(std::make_pair(name, value)); } } void parser::parse_spdy_data(boost::system::error_code &ec, const spdy_control_frame_info& frame, boost::uint32_t stream_id, http_protocol_info& http_info) { // This marks the finish flag if (frame.flags & SPDY_FLAG_FIN){ http_info.last_chunk = true; } } void parser::parse_spdy_rst_stream(boost::system::error_code &ec, const spdy_control_frame_info& frame) { boost::uint32_t stream_id = 0; boost::uint32_t status_code = 0; // First complete the check for size and flag // The flag for RST frame should be 0, The length should be 8 if(frame.flags != 0 || frame.length != 8 ){ return; } // Get the 31 bit stream id boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr); stream_id = four_bytes & 0x7FFFFFFF; m_read_ptr += 4; // Get the status code status_code = algorithm::to_uint32(m_read_ptr); char const* const status_code_str = rst_stream_status(status_code); if(status_code_str){ PION_LOG_INFO(m_logger, "SPDY Status Code is : " << status_code_str); }else{ PION_LOG_INFO(m_logger, "SPDY RST Invalid status code : " << status_code); } } void parser::parse_spdy_ping_frame(boost::system::error_code &ec, const spdy_control_frame_info& frame) { // First complete the check for size // The length should be 4 always if(frame.length != 4){ return; } boost::uint32_t ping_id = 0; // Get the 32 bit ping id ping_id = algorithm::to_uint32(m_read_ptr); m_read_ptr += 4; PION_LOG_INFO(m_logger, "SPDY " << "Ping ID is : " << ping_id); } void parser::parse_spdy_settings_frame(boost::system::error_code &ec, const spdy_control_frame_info& frame) { // Can ignore this frame for our purposes } void parser::parse_spdy_goaway_frame(boost::system::error_code &ec, const spdy_control_frame_info& frame) { // First complete the check for size // The length should be 4 always if(frame.length != 4){ return; } boost::uint32_t last_good_stream_id = 0; boost::uint32_t status_code = 0; // Get the 31 bit stream id boost::uint32_t four_bytes = algorithm::to_uint32(m_read_ptr); last_good_stream_id = four_bytes & 0x7FFFFFFF; m_read_ptr += 4; // Get the status code status_code = algorithm::to_uint32(m_read_ptr); // Chek if there was an error if(status_code == 1){ PION_LOG_ERROR(m_logger, "There was a Protocol Error"); set_error(ec, ERROR_PROTOCOL_ERROR); return; }else if (status_code == 11) { PION_LOG_ERROR(m_logger, "There was an Internal Error"); set_error(ec, ERROR_INTERNAL_SPDY_ERROR); return; } PION_LOG_INFO(m_logger, "SPDY " << "Status Code is : " << status_code); } void parser::parse_spdy_window_update_frame(boost::system::error_code &ec, const spdy_control_frame_info& frame) { // TBD : Do we really need this for our purpose } } // end namespace spdy } // end namespace pion pion-5.0.7+dfsg.orig/src/CMakeLists.txt0000644000372000001440000000354412420270445017275 0ustar robertousers# --------------------------------------------------------------------- # pion: a Boost C++ framework for building lightweight HTTP interfaces # --------------------------------------------------------------------- # Copyright (C) 2013 Splunk Inc. (https://github.com/splunk/pion) # # Distributed under the Boost Software License, Version 1.0. # See http://www.boost.org/LICENSE_1_0.txt # --------------------------------------------------------------------- cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR) set(PROJECT_NAME pion) project(${PROJECT_NAME} CXX) # get all *.cpp files from src to build target file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp) file(GLOB_RECURSE HDR_FILES ${PROJECT_WIDE_INCLUDE}/*.hpp) if (NOT BUILD_SPDY) list(REMOVE_ITEM SRC_FILES ${PROJECT_SOURCE_DIR}/spdy_decompressor.cpp) list(REMOVE_ITEM SRC_FILES ${PROJECT_SOURCE_DIR}/spdy_parser.cpp) list(REMOVE_ITEM HDR_FILES ${PROJECT_WIDE_INCLUDE}/pion/spdy/decompressor.hpp) list(REMOVE_ITEM HDR_FILES ${PROJECT_WIDE_INCLUDE}/pion/spdy/parser.hpp) list(REMOVE_ITEM HDR_FILES ${PROJECT_WIDE_INCLUDE}/pion/spdy/types.hpp) endif() if(MSVC) if(BUILD_SHARED_LIBS) add_definitions(-DPION_EXPORTS -D_USRDLL) else() add_definitions(-D_LIB) endif() endif() # build target add_library(${PROJECT_NAME} ${SRC_FILES} ${HDR_FILES}) target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES}) if (ZLIB_FOUND) target_link_libraries(${PROJECT_NAME} ${ZLIB_LIBRARIES}) endif() if (BZIP2_FOUND ) target_link_libraries(${PROJECT_NAME} ${BZIP2_LIBRARIES}) endif() if (OPENSSL_FOUND ) target_link_libraries(${PROJECT_NAME} ${OPENSSL_LIBRARIES}) endif() if (LOG4CPLUS_FOUND ) target_link_libraries(${PROJECT_NAME} ${LOG4CPLUS_LIBRARIES}) endif() install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) pion-5.0.7+dfsg.orig/src/admin_rights.cpp0000644000372000001440000001015112420270445017701 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #ifndef _MSC_VER #include #include #include #include #include #include #include #endif namespace pion { // begin namespace pion // static members of admin_rights const boost::int16_t admin_rights::ADMIN_USER_ID = 0; boost::mutex admin_rights::m_mutex; // admin_rights member functions #ifdef _MSC_VER admin_rights::admin_rights(bool use_log) : m_logger(PION_GET_LOGGER("pion.admin_rights")), m_lock(m_mutex), m_user_id(-1), m_has_rights(false), m_use_log(use_log) {} void admin_rights::release(void) {} long admin_rights::run_as_user(const std::string& user_name) { return -1; } long admin_rights::run_as_group(const std::string& group_name) { return -1; } long admin_rights::find_system_id(const std::string& name, const std::string& file) { return -1; } #else // NOT #ifdef _MSC_VER admin_rights::admin_rights(bool use_log) : m_logger(PION_GET_LOGGER("pion.admin_rights")), m_lock(m_mutex), m_user_id(-1), m_has_rights(false), m_use_log(use_log) { m_user_id = geteuid(); if ( seteuid(ADMIN_USER_ID) != 0 ) { if (m_use_log) PION_LOG_ERROR(m_logger, "Unable to upgrade to administrative rights"); m_lock.unlock(); return; } else { m_has_rights = true; if (m_use_log) PION_LOG_DEBUG(m_logger, "Upgraded to administrative rights"); } } void admin_rights::release(void) { if (m_has_rights) { if ( seteuid(m_user_id) == 0 ) { if (m_use_log) PION_LOG_DEBUG(m_logger, "Released administrative rights"); } else { if (m_use_log) PION_LOG_ERROR(m_logger, "Unable to release administrative rights"); } m_has_rights = false; m_lock.unlock(); } } long admin_rights::run_as_user(const std::string& user_name) { long user_id = find_system_id(user_name, "/etc/passwd"); if (user_id != -1) { if ( seteuid(user_id) != 0 ) user_id = -1; } else { user_id = geteuid(); } return user_id; } long admin_rights::run_as_group(const std::string& group_name) { long group_id = find_system_id(group_name, "/etc/group"); if (group_id != -1) { if ( setegid(group_id) != 0 ) group_id = -1; } else { group_id = getegid(); } return group_id; } long admin_rights::find_system_id(const std::string& name, const std::string& file) { // check if name is the system id const boost::regex just_numbers("\\d+"); if (boost::regex_match(name, just_numbers)) { return boost::lexical_cast(name); } // open system file std::ifstream system_file(file.c_str()); if (! system_file.is_open()) { return -1; } // find id in system file typedef boost::tokenizer > Tok; boost::char_separator sep(":"); std::string line; boost::int32_t system_id = -1; while (std::getline(system_file, line, '\n')) { Tok tokens(line, sep); Tok::const_iterator token_it = tokens.begin(); if (token_it != tokens.end() && *token_it == name) { // found line matching name if (++token_it != tokens.end() && ++token_it != tokens.end() && boost::regex_match(*token_it, just_numbers)) { // found id as third parameter system_id = boost::lexical_cast(*token_it); } break; } } return system_id; } #endif // #ifdef _MSC_VER } // end namespace pion pion-5.0.7+dfsg.orig/src/Makefile.am0000644000372000001440000000124312420270445016563 0ustar robertousers# -------------------------------- # pion automake configuration file # -------------------------------- AM_CPPFLAGS = -I../include lib_LTLIBRARIES = libpion.la libpion_la_SOURCES = \ admin_rights.cpp algorithm.cpp logger.cpp plugin.cpp process.cpp scheduler.cpp \ spdy_decompressor.cpp spdy_parser.cpp \ tcp_server.cpp tcp_timer.cpp \ http_auth.cpp http_basic_auth.cpp http_cookie_auth.cpp http_message.cpp \ http_parser.cpp http_plugin_server.cpp http_reader.cpp http_server.cpp \ http_types.cpp http_writer.cpp libpion_la_LDFLAGS = -no-undefined -release $(PION_LIBRARY_VERSION) libpion_la_LIBADD = @PION_EXTERNAL_LIBS@ EXTRA_DIST = *.vcxproj *.vcxproj.filters pion-5.0.7+dfsg.orig/src/http_auth.cpp0000644000372000001440000000566612420270445017250 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // auth member functions void auth::add_restrict(const std::string& resource) { boost::mutex::scoped_lock resource_lock(m_resource_mutex); const std::string clean_resource(http::server::strip_trailing_slash(resource)); m_restrict_list.insert(clean_resource); PION_LOG_INFO(m_logger, "Set authentication restrictions for HTTP resource: " << clean_resource); } void auth::add_permit(const std::string& resource) { boost::mutex::scoped_lock resource_lock(m_resource_mutex); const std::string clean_resource(http::server::strip_trailing_slash(resource)); m_white_list.insert(clean_resource); PION_LOG_INFO(m_logger, "Set authentication permission for HTTP resource: " << clean_resource); } bool auth::need_authentication(const http::request_ptr& http_request_ptr) const { // if no users are defined, authentication is never required if (m_user_manager->empty()) return false; // strip off trailing slash if the request has one std::string resource(http::server::strip_trailing_slash(http_request_ptr->get_resource())); boost::mutex::scoped_lock resource_lock(m_resource_mutex); // just return false if restricted list is empty if (m_restrict_list.empty()) return false; // try to find resource in restricted list if (find_resource(m_restrict_list, resource)) { // return true if white list is empty if (m_white_list.empty()) return true; // return false if found in white list, or true if not found return ( ! find_resource(m_white_list, resource) ); } // resource not found in restricted list return false; } bool auth::find_resource(const resource_set_type& resource_set, const std::string& resource) const { resource_set_type::const_iterator i = resource_set.upper_bound(resource); while (i != resource_set.begin()) { --i; // check for a match if the first part of the strings match if (i->empty() || resource.compare(0, i->size(), *i) == 0) { // only if the resource matches exactly // or if resource is followed first with a '/' character if (resource.size() == i->size() || resource[i->size()]=='/') { return true; } } } return false; } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/src/pion.vcxproj0000644000372000001440000004462412420270445017123 0ustar robertousers Debug_DLL_full Win32 Debug_DLL_full x64 Debug_static Win32 Debug_static x64 Release_DLL_full Win32 Release_DLL_full x64 Release_static Win32 Release_static x64 {61F4B4D5-3608-4264-9F4B-B0DA3E3FDF62} pion-net Win32Proj DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 DynamicLibrary v120 DynamicLibrary v120 StaticLibrary v120 StaticLibrary v120 <_ProjectFileVersion>10.0.40219.1 AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset AllRules.ruleset Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp _LIB;%(PreprocessorDefinitions) Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp X64 _LIB;%(PreprocessorDefinitions) ProgramDatabase Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp _LIB;%(PreprocessorDefinitions) MultiThreadedDLL Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp X64 _LIB;%(PreprocessorDefinitions) MultiThreadedDLL Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp PION_EXPORTS;PION_FULL;_USRDLL;%(PreprocessorDefinitions) false zdll.lib;%(AdditionalDependencies) Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp X64 PION_EXPORTS;PION_FULL;_USRDLL;%(PreprocessorDefinitions) ProgramDatabase false MachineX64 zdll.lib;%(AdditionalDependencies) Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp PION_EXPORTS;PION_FULL;_USRDLL;%(PreprocessorDefinitions) false zdll.lib;%(AdditionalDependencies) Copying config.hpp.win ->config.hpp copy /Y $(SolutionDir)include\pion\config.hpp.win $(SolutionDir)include\pion\config.hpp X64 PION_EXPORTS;PION_FULL;_USRDLL;%(PreprocessorDefinitions) false MachineX64 zdll.lib;%(AdditionalDependencies) pion-5.0.7+dfsg.orig/src/http_basic_auth.cpp0000644000372000001440000001333012420270445020374 0ustar robertousers// --------------------------------------------------------------------- // pion: a Boost C++ framework for building lightweight HTTP interfaces // --------------------------------------------------------------------- // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) // // Distributed under the Boost Software License, Version 1.0. // See http://www.boost.org/LICENSE_1_0.txt // #include #include #include #include #include namespace pion { // begin namespace pion namespace http { // begin namespace http // static members of basic_auth const unsigned int basic_auth::CACHE_EXPIRATION = 300; // 5 minutes // basic_auth member functions basic_auth::basic_auth(user_manager_ptr userManager, const std::string& realm) : http::auth(userManager), m_realm(realm), m_cache_cleanup_time(boost::posix_time::second_clock::universal_time()) { set_logger(PION_GET_LOGGER("pion.http.basic_auth")); } bool basic_auth::handle_request(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { if (!need_authentication(http_request_ptr)) { return true; // this request does not require authentication } boost::posix_time::ptime time_now(boost::posix_time::second_clock::universal_time()); if (time_now > m_cache_cleanup_time + boost::posix_time::seconds(CACHE_EXPIRATION)) { // expire cache boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator i; user_cache_type::iterator next=m_user_cache.begin(); while (next!=m_user_cache.end()) { i=next; ++next; if (time_now > i->second.first + boost::posix_time::seconds(CACHE_EXPIRATION)) { // ok - this is an old record.. expire it now m_user_cache.erase(i); } } m_cache_cleanup_time = time_now; } // if we are here, we need to check if access authorized... std::string authorization = http_request_ptr->get_header(http::types::HEADER_AUTHORIZATION); if (!authorization.empty()) { std::string credentials; if (parse_authorization(authorization, credentials)) { // to do - use fast cache to match with active credentials boost::mutex::scoped_lock cache_lock(m_cache_mutex); user_cache_type::iterator user_cache_ptr=m_user_cache.find(credentials); if (user_cache_ptr!=m_user_cache.end()) { // we found the credentials in our cache... // we can approve authorization now! http_request_ptr->set_user(user_cache_ptr->second.second); user_cache_ptr->second.first = time_now; return true; } std::string username; std::string password; if (parse_credentials(credentials, username, password)) { // match username/password user_ptr user=m_user_manager->get_user(username, password); if (user) { // add user to the cache m_user_cache.insert(std::make_pair(credentials, std::make_pair(time_now, user))); // add user credentials to the request object http_request_ptr->set_user(user); return true; } } } } // user not found handle_unauthorized(http_request_ptr, tcp_conn); return false; } void basic_auth::set_option(const std::string& name, const std::string& value) { if (name=="realm") m_realm = value; else BOOST_THROW_EXCEPTION( error::bad_arg() << error::errinfo_arg_name(name) ); } bool basic_auth::parse_authorization(const std::string& authorization, std::string &credentials) { if (!boost::algorithm::starts_with(authorization, "Basic ")) return false; credentials = authorization.substr(6); if (credentials.empty()) return false; return true; } bool basic_auth::parse_credentials(const std::string &credentials, std::string &username, std::string &password) { std::string user_password; if (! algorithm::base64_decode(credentials, user_password)) return false; // find ':' symbol std::string::size_type i = user_password.find(':'); if (i==0 || i==std::string::npos) return false; username = user_password.substr(0, i); password = user_password.substr(i+1); return true; } void basic_auth::handle_unauthorized(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) { // authentication failed, send 401..... static const std::string CONTENT = " " "" "" "Error" "" "" "

401 Unauthorized.

" " "; http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, boost::bind(&tcp::connection::finish, tcp_conn))); writer->get_response().set_status_code(http::types::RESPONSE_CODE_UNAUTHORIZED); writer->get_response().set_status_message(http::types::RESPONSE_MESSAGE_UNAUTHORIZED); writer->get_response().add_header("WWW-Authenticate", "Basic realm=\"" + m_realm + "\""); writer->write_no_copy(CONTENT); writer->send(); } } // end namespace http } // end namespace pion pion-5.0.7+dfsg.orig/index.html0000644000372000001440000000077612420270445015747 0ustar robertousers Boost.Name Documentation Automatic redirection failed, please go to doc/html/index.html pion-5.0.7+dfsg.orig/README.md0000644000372000001440000000454612420270445015230 0ustar robertousersPion Network Library ==================== C++ framework for building lightweight HTTP interfaces **Project Home:** https://github.com/splunk/pion Retrieving the code ------------------- git clone git@github.com:splunk/pion.git cd pion Building the code ----------------- *For XCode:* use `pion.xcodeproj` *For Visual Studio:* use `pion.sln` On Unix platforms (including Linux, OSX, etc.) you can run ./autogen.sh ./configure to generate Makefiles using GNU autotools, followed by make to build everything except the unit tests. You can build and run all the unit tests with make check Generate build using CMake --------------------------- [CMake](http://www.cmake.org) is cross-platform build generator. Pion required cmake version 2.8.10+ To generate build call cmake [-G ] [-D