From 9ac6831aba6bbfed4d99479ba0961dcb781eda57 Mon Sep 17 00:00:00 2001 From: lopsi <40902730+Lpsd@users.noreply.github.com> Date: Wed, 10 Jun 2026 20:30:32 +0100 Subject: [PATCH 01/13] Remove ehs vendor --- vendor/ehs/AUTHORS | 9 - vendor/ehs/COPYING | 504 ------- vendor/ehs/CPollFdSet.h | 59 - vendor/ehs/ChangeLog | 398 ------ vendor/ehs/INSTALL | 182 --- vendor/ehs/Makefile.am | 11 - vendor/ehs/NEWS | 2 - vendor/ehs/README | 12 - vendor/ehs/TODO | 28 - vendor/ehs/building_for_windows.txt | 44 - vendor/ehs/contentdisposition.h | 46 - vendor/ehs/datum.cpp | 99 -- vendor/ehs/datum.h | 79 -- vendor/ehs/dynamicssllocking.cpp | 93 -- vendor/ehs/dynamicssllocking.h | 76 -- vendor/ehs/ehs | 1 - vendor/ehs/ehs-stress.pl | 113 -- vendor/ehs/ehs.cpp | 1714 ------------------------ vendor/ehs/ehs.h | 555 -------- vendor/ehs/ehs_development_guide.txt | 390 ------ vendor/ehs/ehstypes.h | 60 - vendor/ehs/formvalue.h | 69 - vendor/ehs/httprequest.cpp | 722 ---------- vendor/ehs/httprequest.h | 162 --- vendor/ehs/httpresponse.cpp | 158 --- vendor/ehs/httpresponse.h | 124 -- vendor/ehs/networkabstraction.h | 89 -- vendor/ehs/premake5.lua | 34 - vendor/ehs/samples/ehs_formtest.cpp | 164 --- vendor/ehs/samples/ehs_https.cpp | 34 - vendor/ehs/samples/ehs_mirror.cpp | 66 - vendor/ehs/samples/ehs_simple.cpp | 57 - vendor/ehs/samples/ehs_test.cpp | 200 --- vendor/ehs/samples/ehs_testharness.cpp | 103 -- vendor/ehs/samples/ehs_uploader.cpp | 151 --- vendor/ehs/securesocket.cpp | 461 ------- vendor/ehs/securesocket.h | 198 --- vendor/ehs/socket.cpp | 369 ----- vendor/ehs/socket.h | 145 -- vendor/ehs/sslerror.cpp | 74 - vendor/ehs/sslerror.h | 60 - vendor/ehs/staticssllocking.cpp | 103 -- vendor/ehs/staticssllocking.h | 70 - vendor/ehs/stats.h | 9 - vendor/ehs/threadabstractionlayer.h | 59 - 45 files changed, 8156 deletions(-) delete mode 100644 vendor/ehs/AUTHORS delete mode 100644 vendor/ehs/COPYING delete mode 100644 vendor/ehs/CPollFdSet.h delete mode 100644 vendor/ehs/ChangeLog delete mode 100644 vendor/ehs/INSTALL delete mode 100644 vendor/ehs/Makefile.am delete mode 100644 vendor/ehs/NEWS delete mode 100644 vendor/ehs/README delete mode 100644 vendor/ehs/TODO delete mode 100644 vendor/ehs/building_for_windows.txt delete mode 100644 vendor/ehs/contentdisposition.h delete mode 100644 vendor/ehs/datum.cpp delete mode 100644 vendor/ehs/datum.h delete mode 100644 vendor/ehs/dynamicssllocking.cpp delete mode 100644 vendor/ehs/dynamicssllocking.h delete mode 120000 vendor/ehs/ehs delete mode 100644 vendor/ehs/ehs-stress.pl delete mode 100644 vendor/ehs/ehs.cpp delete mode 100644 vendor/ehs/ehs.h delete mode 100644 vendor/ehs/ehs_development_guide.txt delete mode 100644 vendor/ehs/ehstypes.h delete mode 100644 vendor/ehs/formvalue.h delete mode 100644 vendor/ehs/httprequest.cpp delete mode 100644 vendor/ehs/httprequest.h delete mode 100644 vendor/ehs/httpresponse.cpp delete mode 100644 vendor/ehs/httpresponse.h delete mode 100644 vendor/ehs/networkabstraction.h delete mode 100644 vendor/ehs/premake5.lua delete mode 100644 vendor/ehs/samples/ehs_formtest.cpp delete mode 100644 vendor/ehs/samples/ehs_https.cpp delete mode 100644 vendor/ehs/samples/ehs_mirror.cpp delete mode 100644 vendor/ehs/samples/ehs_simple.cpp delete mode 100644 vendor/ehs/samples/ehs_test.cpp delete mode 100644 vendor/ehs/samples/ehs_testharness.cpp delete mode 100644 vendor/ehs/samples/ehs_uploader.cpp delete mode 100644 vendor/ehs/securesocket.cpp delete mode 100644 vendor/ehs/securesocket.h delete mode 100644 vendor/ehs/socket.cpp delete mode 100644 vendor/ehs/socket.h delete mode 100644 vendor/ehs/sslerror.cpp delete mode 100644 vendor/ehs/sslerror.h delete mode 100644 vendor/ehs/staticssllocking.cpp delete mode 100644 vendor/ehs/staticssllocking.h delete mode 100644 vendor/ehs/stats.h delete mode 100644 vendor/ehs/threadabstractionlayer.h diff --git a/vendor/ehs/AUTHORS b/vendor/ehs/AUTHORS deleted file mode 100644 index 79c63f4f992..00000000000 --- a/vendor/ehs/AUTHORS +++ /dev/null @@ -1,9 +0,0 @@ - -EHS was written and is maintained by: - -Zac Hansen xaxxon@slackworks.com - - -Patches and stuff by: - -Fillod Stephane \ No newline at end of file diff --git a/vendor/ehs/COPYING b/vendor/ehs/COPYING deleted file mode 100644 index cbee875ba6d..00000000000 --- a/vendor/ehs/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/vendor/ehs/CPollFdSet.h b/vendor/ehs/CPollFdSet.h deleted file mode 100644 index e1976558283..00000000000 --- a/vendor/ehs/CPollFdSet.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// CPollFdSet.h -// -// Array of file descriptors for poll() -// - -class CPollFdSet -{ -public: - // FD_ZERO - void Reset( void ) - { - m_uiFdCount = 0; - } - - // FD_SET - // Assumes the fd has not been added already - void Add( int fd, short events ) - { - unsigned int i = m_uiFdCount; - if ( i < FD_ARRAY_LENGTH ) - { - m_FdArray[i].fd = fd; - m_FdArray[i].events = events; - m_FdArray[i].revents = 0; - m_uiFdCount = i + 1; - } - } - - // FD_ISSET - // Check if event has been triggered for the fd - bool IsSet( int fd, short events ) const - { - for( unsigned int i = 0 ; i < m_uiFdCount ; i++ ) - { - if ( m_FdArray[i].fd == fd && - (m_FdArray[i].events & events) != 0 ) - { - return true; - } - } - return false; - } - - unsigned int GetFdCount( void ) const - { - return m_uiFdCount; - } - - pollfd* GetFdArray( void ) - { - return m_FdArray; - } - -protected: - const static int FD_ARRAY_LENGTH = 2048; - unsigned int m_uiFdCount; - pollfd m_FdArray[FD_ARRAY_LENGTH]; -}; diff --git a/vendor/ehs/ChangeLog b/vendor/ehs/ChangeLog deleted file mode 100644 index dacd1db9848..00000000000 --- a/vendor/ehs/ChangeLog +++ /dev/null @@ -1,398 +0,0 @@ -2003-10-28 xaxxon@banshee - - * README: - lame readme file. need to look at a well-done one and fix mine - - * StaticSslLocking.h, ThreadAbstractionLayer.h, COPYING, DynamicSslLocking.cpp, DynamicSslLocking.h, EHS.cpp, EHS.h, NetworkAbstraction.h, SecureSocket.cpp, SecureSocket.h, Socket.cpp, Socket.h, SslError.cpp, SslError.h, StaticSslLocking.cpp: - Added LGPL stuff to each of the source files and updated COPYING to - include the LGPL - - * EHS.cpp, Makefile.am, Samples/EHS_FormTest.cpp, SecureSocket.cpp, SecureSocket.h: - pre-1.1. HTTPS is working, but I'm still hammering out all the - certificate stuff. Changed some wording in EHS_FormTest I didn't like. - -2003-10-27 xaxxon@banshee - - * ThreadAbstractionLayer.h: - macros for doing thread stuff compatibly between windows and UNIX - - * Makefile, Makefile.am: Deleted Makefile and added Makefile.am - - * EHS.cpp, EHS.h, Makefile, NetworkAbstraction.h, SecureSocket.cpp, SecureSocket.h, Socket.cpp, Socket.h, StaticSslLocking.h: - More stuff on the path to getting things ready for 1.1. HTTPS still - doesn't work (I'm assuming), but it compiles. Testing comes later. - - * AUTHORS, COPYING, ChangeLog, DynamicSslLocking.cpp, DynamicSslLocking.h, EHS.cpp, EHS.h, INSTALL, NEWS, README, SecureSocket.cpp, Socket.cpp, SslError.cpp, SslError.h, StaticSslLocking.cpp, StaticSslLocking.h, config.h.in, configure.ac: - Bunch of new changes for version 1.1. Includes autotools support and - preliminary HTTPS support. HTTPS support is not yet functional. - ./configure --with-debug --with-memory for debugging and memory tracking - info - -2003-07-22 xaxxon@banshee - - * ehs_development_guide.rtf, ehs_development_guide.txt: - deleted out of date rtf file. Added updated txt file for 1.1.x series EHS - - * EHS.cpp, EHS.h, Samples/ehs_testharness.cpp: - bunch of changes. Removed a ton of char* pointer manipulation. Fixed - up the Regex PCRE wrapper usage. Cleaned up a TON of code. Fixed some - comments.. - -2003-07-15 xaxxon@banshee - - * EHS.cpp, EHS.h: temp checkin to get this elsewhere - -2003-07-14 xaxxon@banshee - - * EHS.cpp: partial implementation of new split function - -2003-07-10 xaxxon@banshee - - * EHS.cpp, EHS.h: updated to have doxygen-compatible comments - -2003-06-29 xaxxon@banshee - - * EHS.cpp: just a smidgen.. got rid of some unused vars - - * EHS.cpp, test.pl: - re-updated. It now passes my regression tests that I didn't test - against before. - -2003-06-28 xaxxon@banshee - - * EHS.cpp, EHS.h, Makefile: - moved to using my Regex class that wraps PCRE. Simplified a LOT of stuff - it's so much nicer :) Though it requires you get the wrapper too.. - but I'll include it in the new version of EHS under the same license - so it's no big deal - -2003-06-22 xaxxon@banshee - - * EHS.cpp: - updated an assert for 64-bit clean build. Updated socket code to - set SO_REUSEADDR for immediate re-binding of ports after the - program exits - -2003-06-14 xaxxon@banshee - - * ehs_development_guide.rtf: no more .doc and updated for EHS 1.0 - -2003-06-06 xaxxon@banshee - - * EHS.cpp, test.pl: final final 1.0 checkin. Here we go :) :) :D :) - - * Test/test4.data, Test/test4.result: test data - - * test.pl: test script for EHS - - * EHS.cpp, EHS.h, Samples/ehs_testharness.cpp, Test/test1.result, Test/test3.result: - Final 1.0 checkin - -2003-06-04 xaxxon@banshee - - * Test/test1.data, Test/test1.result, Test/test2.data, Test/test2.result, Test/test3.data, Test/test3.result: - working towards 1.0 -- creating test cases - - * EHS.h, Makefile, Samples/ehs_testharness.cpp: - working towards 1.0. Adding test cases. - -2003-06-01 xaxxon@banshee - - * Samples/ehs_testharness.cpp: initial commit (??) - -2003-05-28 xaxxon@banshee - - * EHS.h, EHS.cpp: - 0.9.9 -- so very very close to the esteemed 1.0 release. This release checks a bunch of stuff to - make sure there's no memory leaking. Between prints that occur on object creation and a hand-check - of all procedural heap allocations, I'm fairly confident it doesn't leak. - -2003-05-27 xaxxon@banshee - - * EHS.cpp: - completed code review. Next step is to do a check to see if things are properly handled on error - and that memory is cleared up properly. - - * EHS.cpp: - major cleanups and EHS_DEBUG prints. 75% through a total code review - - * EHS.cpp, EHS.h: small fix for vc++ 6 - - * EHS.cpp: little crap - - * EHS.cpp, EHS.h: - put in a new EHS_DEBUG flag that prints out error messages when requests fail. Also cleaned up the server behavior to be more compliant to spec. It errors much more correctly on incorrect input. More to come. - -2003-05-26 xaxxon@banshee - - * exectest: it was just a test... removing it now - - * exectest: test file - - * Makefile: oops. Fixed some makefile foo - - * EHS.cpp: - removed a bunch of print statements used for debugging while changing to PCRE - - * EHS.cpp, Samples/ehs_uploader.cpp: - updated to work with new regex stuff and fixed up some stuff to make ehs_uploader more sane - -2003-05-25 xaxxon@banshee - - * EHS.h, Makefile, Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp, Samples/ehs_uploader.cpp, EHS.cpp: - Booyah. No more boost. Not 100% sure on the multipart form attachments, but everything else is good. PCRE is now the regex engine of choice. This reduces memory usage, increases readability and simplicity of the library code, and makes it a lot easier to build, as PCRE is very straight forward. - -2003-04-11 xaxxon@banshee - - * EHS.cpp: fix for Tru64 - -2002-11-13 xaxxon@banshee - - * EHS.cpp, EHS.h: - sort of works -- perl doesn't crash all the time, but I have to re-create - the interpreter each time. It won't reuse it. - -2002-11-11 xaxxon@banshee - - * EHS.h: timeval issue resolved by including sys/time.h - -2002-10-27 xaxxon@banshee - - * EHS.h: - took out an unused object -- if it's needed I'll put it back in, but it - wasn't compiling properly and I couldn't find where it was needed.. - - * Makefile: - Whoops, last makefile didn't quite work. This one should :) - - * EHS.cpp: fixed deprecated fstream.h => fstream thing. - -2002-05-22 xaxxon@banshee - - * EHS.cpp: - changed how it grabs pieces of a url from std::string stuff to boost::regex - stuff. seems to actually work now :) - - * EHS.h: added a new regex for grabbing the parts out of a path - -2002-05-01 xaxxon@banshee - - * EHS.cpp, EHS.h: - removed dependency on stringstreams because it didn't work reliably across - different platforms - -2002-04-19 xaxxon@banshee - - * Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp, Samples/ehs_uploader.cpp: - big update.. getting closer to having the win client actually playing the game again (after so, so long) - -2002-04-17 xaxxon@banshee - - * EHS.cpp: reordered in the *correct* order this time.. - - * EHS.cpp: changed order of init's for httpresponse constructor - - * EHS.cpp, EHS.h: - bug fixes.. wasn't storing http response code properly and it was causing bad things - - * EHS.cpp: fixed send length problem - -2002-04-17 m - - * Samples/Windows/SimpleDlg/EHSTest.dsp: - Updated project settings to use correct path to boost libs for ALL configurations, oops. - - * Samples/Windows/SimpleDlg/EHSTest.dsp: - Updated location of boost libs, now relative to sample and maintained in the project file, wahoo! - -2002-04-17 xaxxon@banshee - - * Samples/Windows/SimpleDlg/EHSTestDlg.cpp, Samples/Windows/SimpleDlg/EHSTestDlg.h: - fixed for new api - -2002-04-17 m - - * EHS.h: Needed a const on EHSLessThanStrings operator(). - - * EHS.h: - Pragma'ed away an annoying MS warning that names are truncated to 255 char's. There's nothing we can do about it anyway... - -2002-04-16 xaxxon@banshee - - * EHS.cpp, EHS.h: small changes to make windows work - - * EHS.cpp: syntax error while commenting stuff out.. oopsies - -2002-04-15 xaxxon@banshee - - * Samples/EHS_TEST.cpp: - had to slightly change sample code because api for SetBody changed - - * EHS.h: - chagned API slightly -- no need to set return code in SetBody, because - it has to be returned from HandleRequest.. it was redundant - - * EHS.cpp: took out a bunch of debugging prints and the like.. - -2002-04-14 xaxxon@banshee - - * EHS.h: just a couple last second comment changes - - * Makefile: pre-built libs for boost regex - - * Makefile, Samples/EHS_FormTest.cpp, Samples/ehs_uploader.cpp: - new version that actually supports uploading files. ehs_uploader is a test - program for handling uploaded files and dumping them out to local files. - updated formtest, as well, to the new API - - * EHS.h: - finally a working version with file upload support.. this may be - a release version.. - - * EHS.cpp: finally a working version with file uploading capabilities.. - this may be a release, not sure - -2002-03-12 xaxxon@banshee - - * EHS.cpp: about to rip a chunk out, so this is a backup checkin - -2002-03-09 xaxxon@banshee - - * EHS.cpp: - about to make substantial changes to the buffer processing.. backup checkin - -2002-03-08 m - - * EHS.cpp, EHS.h, Samples/Windows/SimpleDlg/EHSTest.dsp: - Added a few "std::" as needed by VC. - Removed SGI_STL include path requirement from test project. - Added boost include path to test project. - -2002-03-08 xaxxon@banshee - - * EHS.cpp, EHS.h: - merged in myron's changes/fixes.. oops.. forgot to build .. oh well - - * Samples/ehs_formtest.dsp, Samples/ehs_test.dsp: - myron's .dsp files for building the unix samples under windows - - * Makefile: fixed where boost regex lib is - - * Makefile: modified to build the boost regex lib - - * EHS.h, Makefile, Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp: - modified for the new system.. using the boost stuff and not using the - SGI STL - - * EHS.cpp: - Added the boost regex library and cut out 300 lines of code. But it now - requires the boost regex library.. - -2002-02-20 xaxxon@banshee - - * Samples/EHS_TEST.cpp: - yet another backup commit.. stuff is still broken. Working on getting keystroke messages down to the right objects.. not hard, just boring - -2002-01-30 xaxxon@banshee - - * EHS.cpp: - fixed a couple errors introduced to the linux build while fixing the windows - build. - -2002-01-30 m - - * EHS.cpp, EHS.h, Samples/Windows/SimpleDlg/EHSTest.dsp, Samples/Windows/SimpleDlg/EHSTestDlg.cpp: - Updated sample code to use new EHSServer abstraction. - Added HandleData() chain. - NOTE: It looks like there is a memory leak in a string allocated in the EHS() constructor. - -2002-01-30 xaxxon@banshee - - * EHS.cpp, EHS.h, Makefile, Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp: - Fairly major modifications to the basic structure. Got rid of EHSInterface - and added EHSServer. Just better modularization.. and updated the test - programs to use the new interface - -2002-01-17 m - - * Samples/EHS_TEST.cpp: Added /a/b/ to test server, whooopteedoo. - -2002-01-17 xaxxon@banshee - - * Makefile: Kinda need this. - - * Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp: - Updated samples to match new EHS changes. - -2002-01-17 m - - * Samples/Windows/SimpleDlg/EHSTest.dsp, Samples/Windows/SimpleDlg/EHSTestDlg.cpp, Samples/Windows/SimpleDlg/EHSTestDlg.h: - Updated Windows sample to match latest EHS changes. Builds and runs without errors. - - * EHS.cpp, EHS.h: - Added EHS-specific utilities to EHS.h, including assert, trace, verify, and pragma message helpers. - -2002-01-17 xaxxon@banshee - - * EHS.h: grr.. sorry (again) - - * EHS.cpp: - sorry.. here's a couple bug fixes and syntax fixes I forgot to check in.. - - oopsies :( - -2002-01-17 m - - * Samples/Windows/SimpleDlg/EHSTest.cpp, Samples/Windows/SimpleDlg/EHSTest.dsp, Samples/Windows/SimpleDlg/EHSTest.dsw, Samples/Windows/SimpleDlg/EHSTest.h, Samples/Windows/SimpleDlg/EHSTest.rc, Samples/Windows/SimpleDlg/EHSTestDlg.cpp, Samples/Windows/SimpleDlg/EHSTestDlg.h, Samples/Windows/SimpleDlg/StdAfx.cpp, Samples/Windows/SimpleDlg/StdAfx.h, Samples/Windows/SimpleDlg/res/EHSTest.ico, Samples/Windows/SimpleDlg/res/EHSTest.rc2, Samples/Windows/SimpleDlg/resource.h: - Adding sample code that creates a simple dialog. The text in the dialog will be served up using EHS. - -2002-01-15 xaxxon@banshee - - * EHS.cpp, EHS.h, Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp: - Linux works now. Not sure about windows, but I didn't do much in the - way of platform specific stuff. Added no-caching html header. Added - EHSInterface class to allow classes to have a HandleRequest member without - each having to have a socket and thread associated with them. - -2002-01-13 xaxxon@banshee - - * EHS.cpp, EHS.h: - Preliminary support for windows in both threaded and unthreaded modes. Seems to work for windows, need to re-test for linux. - -2002-01-06 xaxxon@banshee - - * EHS.cpp, EHS.h, Samples/EHS_FormTest.cpp, Samples/EHS_TEST.cpp: - finished with first revision of EHS (finally). EHS.cpp and EHS.h are the - library files and are done at revision 0.1. EHS_TEST.cpp and EHS_FormTest.cpp - are example/test programs for the EHS library and this is their initial check - in. - -2002-01-03 xaxxon@banshee - - * EHS.cpp, EHS.h: - hey! look at that. All I have to do is write one more function - (EHSConnection::SendHttpResponse()) and it'll be ready for testing.. - the code is still pretty ugly, but I think it'll actually be ready for - use.. - -2002-01-01 xaxxon@banshee - - * EHS.cpp, EHS.h: - still working on EHS.. but it's coming along well. I already got the code - done for taking care of the request line, and I just typed in the code for - dealing with request headers.. and it compiles (but I have no idea - if any of it works..). Now, all that's left is to read in the body and pass - it off to the virtual function.. oh.. and some testing. And some better - error handling.. right now there's a few spots that just explode if you - send a bad HTTP request.. that's probably not good for building a stable game - engine, since if EHS crashes, it will bring down everything.. - -2001-12-30 xaxxon@banshee - - * EHS.cpp, EHS.h: - EHS - Embedded HTTP Server. Used for embedding an HTTP server within - a c++ program. I tried to find something like this already written, but - couldn't.. - - - diff --git a/vendor/ehs/INSTALL b/vendor/ehs/INSTALL deleted file mode 100644 index 60387b27d68..00000000000 --- a/vendor/ehs/INSTALL +++ /dev/null @@ -1,182 +0,0 @@ -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. diff --git a/vendor/ehs/Makefile.am b/vendor/ehs/Makefile.am deleted file mode 100644 index 4c380bda724..00000000000 --- a/vendor/ehs/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -# Build EHS library -noinst_LTLIBRARIES=libehs.la - -# Sources for building EHS library -libehs_la_SOURCES=ehs.cpp dynamicssllocking.cpp securesocket.cpp socket.cpp\ -sslerror.cpp staticssllocking.cpp datum.cpp httpresponse.cpp httprequest.cpp -libehs_la_CXXFLAGS=-I$(srcdir)/../pme -I$(srcdir)/../../Shared/sdk -libehs_la_LIBADD=$(top_builddir)/vendor/pme/libpme.la - -# add includes for pcre which is what pme needs -libehs_la_CXXFLAGS+=$(PCRE_CFLAGS) diff --git a/vendor/ehs/NEWS b/vendor/ehs/NEWS deleted file mode 100644 index 35166acc6f0..00000000000 --- a/vendor/ehs/NEWS +++ /dev/null @@ -1,2 +0,0 @@ - -1.1 - Introduced HTTPS support and autotools ./configure support diff --git a/vendor/ehs/README b/vendor/ehs/README deleted file mode 100644 index d06f3921b6b..00000000000 --- a/vendor/ehs/README +++ /dev/null @@ -1,12 +0,0 @@ - - -This isn't really done yet. - -EHS is distributed under version 2.1 of the LGPL as described in COPYING. - -Check out INSTALL for installation notes. - -check out ehs_development_guide.txt for how to develop using EHS. - -check out building_for_windows.txt to see how to build for Visual Studio 6 (and -probably a decent idea for how to do it for newer versions) diff --git a/vendor/ehs/TODO b/vendor/ehs/TODO deleted file mode 100644 index 9bc458b2d80..00000000000 --- a/vendor/ehs/TODO +++ /dev/null @@ -1,28 +0,0 @@ - - -List of things to do in EHS: ------------------------------ - -Security: -Max request size shouldn't be compile-time option - - - - -HTTP/1.1: - - - - - - -Monitoring: -Logging should be much more customizalbe - -- logging to a seperate file - -- logging to a seperate process - - -Locking: -Create visualization tool for lock utilization - -- shows when locks are open/closed/under contention - -- uses logs/direct file write diff --git a/vendor/ehs/building_for_windows.txt b/vendor/ehs/building_for_windows.txt deleted file mode 100644 index 6ecf384e37b..00000000000 --- a/vendor/ehs/building_for_windows.txt +++ /dev/null @@ -1,44 +0,0 @@ -Building EHS for Visual Studio 6.0 - -PLATFORM SDK - -Platform SDK must be installed in order for any of the network code to work. Note that this may take quite a while and requires that you go to the following URL in Internet Explorer 5.0 or later. - -Platform SDK -http://www.microsoft.com/msdownload/platformsdk/sdkupdate/ - -Click on "Core SDK" on the left, then "Install this SDK" on the right. It will look around on your system for a while, then give you options. Only the Core SDK need be installed. This step is 167.6MB (at the time of this writing). Click the Continue button, accept the license, then click Install Now. Click ok to the warning dialogue that pops up, and the download will begin. Then you have to update the directory settings in visual studio. Microsoft provides the following directions: - -Directions -http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdkintro/sdkintro/installing_the_platform_sdk_with_visual_studio.asp - - -PTHREADS - -pthreads for windows - make sure to get all of the .h files in the include directory and all of the .dll, .lib, and .a files from the lib directory (for completeness). - - -ftp://sources.redhat.com/pub/pthreads-win32/dll-latest/ - -PCRE - -Regular expressions library - -http://gnuwin32.sourceforge.net/packages/pcre.htm -- you want "developer files" - - - -PME - -Windows - grab the latest version. There will be a vs6 directory. Open this in visual studio. Go into project->settings, hit the C/C++ tab, Category: preprocessor, and add/change the directory in "Additional include paths" to the PCRE include file - likely c:\program files\gnuwin32\include. Build it. - -http://xaxxon.slackworks.com/pme/ - - -EHS - -HTTP server - -Windows - grab the latest version. There will be a vs6 directory. Open the workspace in Visual Studio. Project->Settings, C/C++ tab, Category: Preprocessor. Additional include paths: path to pcre include directory, same as in PME step previously. Also, add the directory to the PME header files that were installed previously. You must also add the path to the pthread library installed previously. Seperate directories with semicolons. Build it. - -http://xaxxon.slackworks.com/ehs/ diff --git a/vendor/ehs/contentdisposition.h b/vendor/ehs/contentdisposition.h deleted file mode 100644 index 43009d63679..00000000000 --- a/vendor/ehs/contentdisposition.h +++ /dev/null @@ -1,46 +0,0 @@ - -#ifndef CONTENTDISPOSITION_H -#define CONTENTDISPOSITION_H - -#include - -#include "ehstypes.h" - -/// This stores the content disposition of a subbody -/** - * This stores the content disposition of a subbody. This is used for - * multi-part form data. - */ -class ContentDisposition { - - public: - - /// constructor - ContentDisposition ( ) { -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: ContentDisposition\n" ); -#endif - } - - /// destructor - ~ContentDisposition ( ) { -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: ContentDisposition\n" ); -#endif - } - -#ifdef EHS_MEMORY - /// this is only for watching memory allocation - ContentDisposition ( const ContentDisposition & iroContentDisposition ) { - *this = iroContentDisposition; - fprintf ( stderr, "[EHS_MEMORY] Allocated: ContentDisposition (Copy Constructor)\n" ); - } -#endif - - StringMap oContentDispositionHeaders; ///< map of headers for this content disposition - std::string sContentDisposition; ///< content disposition string for this object - -}; - - -#endif // CONTENTDISPOSITION_H diff --git a/vendor/ehs/datum.cpp b/vendor/ehs/datum.cpp deleted file mode 100644 index f2bb06f9520..00000000000 --- a/vendor/ehs/datum.cpp +++ /dev/null @@ -1,99 +0,0 @@ - -#include "datum.h" -#include -#include -#include - -#define DATUM_BUFFER_SIZE 350 - -#ifdef _WIN32 -#define strcasecmp stricmp -#endif - - - -Datum & Datum::operator= ( long inLong ) -{ - char psBuffer [ 100 ]; - sprintf ( psBuffer, "%ld", inLong ); - sDatum = psBuffer; - return *this; -} -Datum & Datum::operator= ( int inInt ) -{ - char psBuffer [ 100 ]; - sprintf ( psBuffer, "%d", inInt ); - sDatum = psBuffer; - return *this; -} -Datum & Datum::operator= ( double inDouble ) -{ - char psBuffer [ DATUM_BUFFER_SIZE ]; - snprintf ( psBuffer, DATUM_BUFFER_SIZE, "%lf", inDouble ); - sDatum = psBuffer; - return *this; -} -Datum & Datum::operator= ( std::string isString ) -{ - sDatum = isString; - return *this; -} - -Datum & Datum::operator= ( char * ipsString ) -{ - sDatum = ipsString; - return *this; -} -Datum & Datum::operator= ( const char * ipsString ) -{ - sDatum = ipsString; - return *this; -} - -Datum & Datum::operator= ( void * ipVoid ) -{ - pDatum = ipVoid; - return *this; -} - -bool Datum::operator== ( const char * ipsString ) -{ - - return sDatum == ipsString; - -} - -Datum::operator long ( ) -{ - return atol ( sDatum.c_str ( ) ); -} - -Datum::operator int ( ) -{ - return atoi ( sDatum.c_str ( ) ); -} - -Datum::operator double ( ) -{ - return atof ( sDatum.c_str ( ) ); -} - -Datum::operator std::string ( ) -{ - return sDatum; -} - -Datum::operator const char * ( ) -{ - return sDatum.c_str ( ); -} - -bool Datum::operator!= ( int inCompare ) -{ - return ((int)*this) != inCompare; -} - -bool Datum::operator != ( const char * ipsCompare ) -{ - return strcasecmp ( (const char*)*this, ipsCompare ); -} diff --git a/vendor/ehs/datum.h b/vendor/ehs/datum.h deleted file mode 100644 index 1faf1f2e0d7..00000000000 --- a/vendor/ehs/datum.h +++ /dev/null @@ -1,79 +0,0 @@ - -#ifndef DATUM_H -#define DATUM_H - -#include - - -/// class that makes it easy to go between numbers and strings -/** - * class that can take data in string or number form and can return it - * in either form. Very similar to a perl scalar (without references) - */ -class Datum { - - protected: - - /// holds the data in string form - std::string sDatum; - - /// holds the data in pointer form - void * pDatum; - - public: - - /// assignment operator for longs - Datum & operator= ( long inLong ); - - /// assignment operator for ints - Datum & operator= ( int inInt ); - - /// assignment operator for doubles - Datum & operator= ( double inDouble ); - - /// assignment operator for std::strings - Datum & operator= ( std::string isString ); - - /// assignment operator for char * strings - Datum & operator= ( char * ipsString ); - - /// assignment operator for const char * strings - Datum & operator= ( const char * ipsString ); - - /// assignment operator for void * - Datum & operator= ( void * ipVoid ); - - /// equality operator for const char * string - bool operator== ( const char * ipsString ); - - /// conversion operaor to return an in - operator int ( ); - - /// explicit accessor for int - int GetInt() { return (int)(*this); } - - /// conversion operator for long - operator long ( ); - - /// conversion operator for double - operator double ( ); - - /// conversion operator for std::string - operator std::string ( ); - - /// conversion operator for const char * - operator const char * ( ); - - /// explicit accessor for const char * - const char * GetCharString ( ) { return (const char*)(*this); } - - - /// inequality operator to test against int - bool operator!= ( int ); - - /// inequality operator to test against const char * - bool operator!= ( const char * ); - -}; - -#endif // DATUM_H diff --git a/vendor/ehs/dynamicssllocking.cpp b/vendor/ehs/dynamicssllocking.cpp deleted file mode 100644 index e94fb0f8c9b..00000000000 --- a/vendor/ehs/dynamicssllocking.cpp +++ /dev/null @@ -1,93 +0,0 @@ - -/* - -EHS is a library for adding web server support to a C++ application -Copyright (C) 2001, 2002 Zac Hansen - -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; version 2 -of the License only. - -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. -or see http://www.gnu.org/licenses/gpl.html - -Zac Hansen ( xaxxon@slackworks.com ) - -*/ - -// must be outside COMPILE_WITH_SSL check -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef COMPILE_WITH_SSL - -#include "dynamicssllocking.h" - - - -CRYPTO_dynlock_value * DynamicSslLocking::DynamicLockCreateCallback ( const char * ipsFile, - int inLine ) -{ - - CRYPTO_dynlock_value * poDynlock = new CRYPTO_dynlock_value; - - assert ( poDynlock != NULL ); - - MUTEX_SETUP ( poDynlock->oMutex ); - return poDynlock; - -} - -void DynamicSslLocking::DynamicLockCallback ( int inMode, - CRYPTO_dynlock_value * ipoDynlock, - const char * ipsFile, - int inLine ) -{ - - if ( inMode & CRYPTO_LOCK ) { - MUTEX_LOCK ( ipoDynlock->oMutex ); - } else { - MUTEX_UNLOCK ( ipoDynlock->oMutex ); - } - -} - -void DynamicSslLocking::DynamicLockCleanupCallback ( struct CRYPTO_dynlock_value * ipoDynlock, - const char * ipsFile, - int inLine ) -{ - - MUTEX_CLEANUP ( ipoDynlock->oMutex ); - delete ipoDynlock; - -} - - -DynamicSslLocking::DynamicSslLocking ( ) -{ - - CRYPTO_set_dynlock_create_callback ( DynamicLockCreateCallback ); - CRYPTO_set_dynlock_lock_callback ( DynamicLockCallback ); - CRYPTO_set_dynlock_destroy_callback ( DynamicLockCleanupCallback ); - -} - -DynamicSslLocking::~DynamicSslLocking ( ) -{ - - CRYPTO_set_dynlock_create_callback ( NULL ); - CRYPTO_set_dynlock_lock_callback ( NULL ); - CRYPTO_set_dynlock_destroy_callback ( NULL ); - -} - -#endif // COMPILE WITH SSL diff --git a/vendor/ehs/dynamicssllocking.h b/vendor/ehs/dynamicssllocking.h deleted file mode 100644 index 7dc3cf42171..00000000000 --- a/vendor/ehs/dynamicssllocking.h +++ /dev/null @@ -1,76 +0,0 @@ - -/* - -EHS is a library for adding web server support to a C++ application -Copyright (C) 2001, 2002 Zac Hansen - -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; version 2 -of the License only. - -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. -or see http://www.gnu.org/licenses/gpl.html - -Zac Hansen ( xaxxon@slackworks.com ) - -*/ - -#ifndef DYNAMIC_SSL_LOCKING -#define DYNAMIC_SSL_LOCKING - -#include -#include -#include - -#include "threadabstractionlayer.h" - -/// used for dynamic locking callback -struct CRYPTO_dynlock_value -{ - - MUTEX_TYPE oMutex; - -}; - - -/// dynamic locking mechanism for OpenSSL. Created as needed. -class DynamicSslLocking -{ - - public: - - /// default constructor - DynamicSslLocking ( ); - - /// destructor - ~DynamicSslLocking ( ); - - - protected: - - /// callback for creating a CRYPTO_dynlock_value object for later use - static CRYPTO_dynlock_value * DynamicLockCreateCallback ( const char * ipsFile, - int inLine ); - - /// callback for locking/unlocking CRYPTO_dynlock_value - static void DynamicLockCallback ( int inMode, - CRYPTO_dynlock_value * ipoDynlock, - const char * ipsFile, - int inLine ); - - /// callback for freeing CRYPTO_dynlock_value - static void DynamicLockCleanupCallback ( struct CRYPTO_dynlock_value * ipoDynlock, - const char * ipsFile, - int inLine ); - -}; - -#endif diff --git a/vendor/ehs/ehs b/vendor/ehs/ehs deleted file mode 120000 index 945c9b46d68..00000000000 --- a/vendor/ehs/ehs +++ /dev/null @@ -1 +0,0 @@ -. \ No newline at end of file diff --git a/vendor/ehs/ehs-stress.pl b/vendor/ehs/ehs-stress.pl deleted file mode 100644 index e94573b4c52..00000000000 --- a/vendor/ehs/ehs-stress.pl +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/perl - -# -# ehs-stress.pl was written by Michal Pleban -# - - -use LWP::UserAgent; -use HTTP::Request; - -if ( @ARGV < 1 ) { - PrintHelp ( ); - exit; -} - -my %UserAgentOptions; -$SERVER = shift @ARGV; -$PROCESSES = 10; -$HITS = 10; -while ( my $arg = shift @ARGV ) { - - if ( $arg eq "-p" ) { - - PrintHelp ( ) and exit if @ARGV == 0; - $PROCESSES = shift @ARGV; - - } elsif ( $arg eq "-c" ) { - - PrintHelp ( ) and exit if @ARGV == 0; - $HITS = shift @ARGV; - - } elsif ( $arg eq "-k" ) { - - $UserAgentOptions { keep_alive } = 1; - - } - -} - - -print "Starting $0 against $SERVER with $PROCESSES processes each performing $HITS queries\n"; - -$start_time = time; - -for($i = 0; $i < $PROCESSES; $i++) -{ -# print "Starting process " . ($i + 1) . "\n" if $i % 10 == 9; - print "Starting process " . ($i + 1) . "\n"; - if(!($kidpid = fork())) - { - $ua = LWP::UserAgent->new ( %UserAgentOptions ); - $ua->agent("ehs-stress_" . $kidpid); - - $failed = 0; - $requestsperformed = 0; - for($j = 0; $j < $HITS || $HITS == -1; $j++) - { - $l = int rand 16384; - print "Sending request " . ($j + 1) . " from process $i\n" if ($j + 1) % 100 == 0; -# $r = HTTP::Request->new("GET", "http://" . $SERVER . "/" . $l . "/hit;" . $l . ",b"); - $r = HTTP::Request->new("GET", "http://" . $SERVER . "/" ); - $response = $ua->request($r); - - # if not date header, assume failure and exit - $failed = 1 and last if !$response->header('Date'); - -# print "Request: $foo Date: " . $response->header('Date'). "\n" if ++$foo % 100 == 99; - $requestsperformed++; - } - `echo $requestsperformed >/tmp/$$`; - exit ( $failed ); - } else { - $kids{$kidpid}++; - } -} - -$totalrequests = 0; - -for($i = 0; $i < $PROCESSES; $i++) -{ - $Pid = wait(); - - if ( $? == 0 ) { - printf "PID $Pid exited successfully\n"; - } else { - printf "PID $Pid failed\n"; - } - - # load number of requests from /tmp - $totalrequests += `cat /tmp/$Pid`; - - `rm /tmp/$Pid`; - -} - -print "performed $totalrequests total requests\n"; - -$end_time = time; - -$total_time = $end_time - $start_time; -$avg_time = $totalrequests != 0 ? $total_time / $totalrequests : 0; -print "It took $total_time seconds to run $totalrequests queries for an avg o $avg_time second / request\n"; - - - - -sub PrintHelp -{ - - print "Usage: $0 : [-p ] [-c ] [-k]\n\t-p: number of processes to spawn (default 10)\n\t-c: request count per process (default 10)\n\t-k: if specified, persistent connections are used\n"; - - -} diff --git a/vendor/ehs/ehs.cpp b/vendor/ehs/ehs.cpp deleted file mode 100644 index af034829759..00000000000 --- a/vendor/ehs/ehs.cpp +++ /dev/null @@ -1,1714 +0,0 @@ - -/* - -EHS is a library for embedding HTTP(S) support into a C++ application -Copyright (C) 2004 Zachary J. Hansen - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License version 2.1 as published by the Free Software Foundation; - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -This can be found in the 'COPYING' file. - -*/ - - - -#include "ehs.h" -#include -#include - -long long ms_HttpTotalBytesSent = 0; -SAllocationStats ms_AllocationStats = { 0 }; -CCriticalSection ms_StatsCS; - -// Returns true if lock succeeded -static bool MUTEX_TRY_LOCK( MUTEX_TYPE& x ) -{ - return ( pthread_mutex_trylock( &x ) != EBUSY ); -} - -int EHSServer::CreateFdSet ( ) -{ - MUTEX_LOCK ( m_oMutex ); - - m_oReadFds.Reset(); - - // add the accepting FD - m_oReadFds.Add( m_poNetworkAbstraction->GetFd(), POLLIN ); - - int nHighestFd = m_poNetworkAbstraction->GetFd ( ); - - for ( EHSConnectionList::iterator oCurrentConnection = m_oEHSConnectionList.begin ( ); - !( oCurrentConnection == m_oEHSConnectionList.end ( ) ); - oCurrentConnection++ ) { - - /// skip this one if it's already been used - if ( (*oCurrentConnection)->StillReading ( ) ) { - - int nCurrentFd = - ( * oCurrentConnection )->GetNetworkAbstraction ( )->GetFd ( ); - - EHS_TRACE ( "Adding %d to FD SET\n", nCurrentFd ); - - m_oReadFds.Add( nCurrentFd, POLLIN ); - - // store the highest FD in the set to return it - if ( nCurrentFd > nHighestFd ) { - - nHighestFd = nCurrentFd; - - } - - } else { - - EHS_TRACE ( "FD %d isn't reading anymore\n", - ( * oCurrentConnection )->GetNetworkAbstraction ( )->GetFd ( ) ); - - } - } - - MUTEX_UNLOCK ( m_oMutex ); - - return nHighestFd; - -} - - - -int EHSServer::ClearIdleConnections ( ) -{ - - // don't lock mutex, as it is only called rom within locked sections - - int nIdleConnections = 0; - - for ( EHSConnectionList::iterator i = m_oEHSConnectionList.begin ( ); - i != m_oEHSConnectionList.end ( ); - i++ ) { - - if ( MUTEX_TRY_LOCK ( (*i)->m_oConnectionMutex ) == false ) - continue; - - // if it's been more than N seconds since a response has been - // sent and there are no pending requests - if ( (*i)->StillReading ( ) && - ( time ( NULL ) - (*i)->LastActivity ( ) > m_nIdleTimeout || (*i)->m_iStopASAP ) && - !(*i)->RequestsPending ( ) - ) { - - EHS_TRACE ( "Done reading because of idle timeout\n" ); - - (*i)->DoneReading ( false ); - - nIdleConnections++; - - } - - MUTEX_UNLOCK ( (*i)->m_oConnectionMutex ); - - } - - - if ( nIdleConnections > 0 ) { - EHS_TRACE ( "Cleared %d connections\n", nIdleConnections ); - } - - - RemoveFinishedConnections ( ); - - return nIdleConnections; - -} - - -int EHSServer::RemoveFinishedConnections ( ) { - - // don't lock mutex, as it is only called rom within locked sections - - for ( EHSConnectionList::iterator i = m_oEHSConnectionList.begin ( ); - i != m_oEHSConnectionList.end ( ); - /* no third part */ ) { - - if ( (*i)->CheckDone ( ) ) { - - RemoveEHSConnection ( *i ); - i = m_oEHSConnectionList.begin ( ); - - } else { - - i++; - - } - - } - - return 0; - -} - - -EHSConnection::EHSConnection ( NetworkAbstraction * ipoNetworkAbstraction, - EHSServer * ipoEHSServer ) : - m_nDoneReading ( 0 ), - m_nDisconnected ( 0 ), - m_nRequests ( 0 ), - m_nResponses ( 0 ), - m_poNetworkAbstraction ( ipoNetworkAbstraction ), - m_poCurrentHttpRequest ( NULL ), - m_poEHSServer ( ipoEHSServer ), - m_iStopASAP ( 0 ) -{ - m_UnusedSyncId = 0; - UpdateLastActivity ( ); - - // initialize mutex for this object - MUTEX_SETUP ( m_oConnectionMutex ); - - // get the address and port of the new connection - m_sAddress = ipoNetworkAbstraction->GetAddress ( ); - m_nPort = ipoNetworkAbstraction->GetPort ( ); - - // make sure the buffer is clear - m_sBuffer = ""; - - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: EHSConnection\n" ); -#endif -} - - -EHSConnection::~EHSConnection ( ) -{ -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: EHSConnection\n" ); -#endif - MUTEX_CLEANUP ( m_oConnectionMutex ); - if ( m_poCurrentHttpRequest ) - delete m_poCurrentHttpRequest; - delete m_poNetworkAbstraction; - -} - - -NetworkAbstraction * EHSConnection::GetNetworkAbstraction ( ) -{ - - return m_poNetworkAbstraction; - -} - - -// adds data to the current buffer for this connection -EHSConnection::AddBufferResult -EHSConnection::AddBuffer ( char * ipsData, ///< new data to be added - int inSize ///< size of new data - ) -{ - // Mutex is locked - - // make sure we actually got some data - if ( inSize <= 0 ) { - return ADDBUFFER_INVALID; - } - - // this is binary safe -- only the single argument char* constructor looks for NULL - m_sBuffer += std::string ( ipsData, inSize ); - - // make sure the buffer hasn't grown too big - if ( m_sBuffer.length ( ) > MAX_BUFFER_SIZE_BEFORE_BOOT ) { - return ADDBUFFER_TOOBIG; - } - - // need to run through our buffer until we don't get a full result out - do { -// fprintf ( stderr, "##### Top of do loop\n" ); - // if we need to make a new request object, do that now - if ( m_poCurrentHttpRequest == NULL || - m_poCurrentHttpRequest->nCurrentHttpParseState == HttpRequest::HTTPPARSESTATE_COMPLETEREQUEST ) { -// fprintf ( stderr, "##### Making new http request object\n" ); - // if we have one already, toss it on the list - if ( m_poCurrentHttpRequest != NULL ) { - - m_oHttpRequestList.push_back ( m_poCurrentHttpRequest ); - m_poEHSServer->IncrementRequestsPending ( ); - - // wake up everyone - pthread_cond_broadcast ( & m_poEHSServer->m_oDoneAccepting ); - - - if ( m_poEHSServer->m_nServerRunningStatus == EHSServer::SERVERRUNNING_ONETHREADPERREQUEST ) { - - - static int nThreadsCreated = 0; - - // create a thread if necessary - pthread_t oThread; - - MUTEX_UNLOCK ( m_oConnectionMutex ); - pthread_create ( & oThread, - NULL, - EHSServer::PthreadHandleData_ThreadedStub, - (void *) m_poEHSServer ); - pthread_detach ( oThread ); - MUTEX_LOCK ( m_oConnectionMutex ); - - -// fprintf ( stderr, "##### Created new thread %d - %d\n", ++nThreadsCreated, oThread ); - } - - } else { - //fprintf ( stderr, "not moving old request\n" ); - } - - - - - // create the initial request - m_poCurrentHttpRequest = new HttpRequest ( ++m_nRequests, this ); - m_poCurrentHttpRequest->nSecure = m_poNetworkAbstraction->IsSecure ( ); - - } - - // parse through the current data -// fprintf ( stderr, "##### Calling ParseData()\n" ); - m_poCurrentHttpRequest->ParseData ( m_sBuffer ); -// fprintf ( stderr, "##### Done calling ParseData()\n" ); - - } while ( m_poCurrentHttpRequest->nCurrentHttpParseState == - HttpRequest::HTTPPARSESTATE_COMPLETEREQUEST ); - - - AddBufferResult nReturnValue; - - // return either invalid request or ok - if ( m_poCurrentHttpRequest->nCurrentHttpParseState == HttpRequest::HTTPPARSESTATE_INVALIDREQUEST ) { - - nReturnValue = ADDBUFFER_INVALIDREQUEST; - - } else { - - nReturnValue = ADDBUFFER_OK; - - } - - return nReturnValue; - -} - -/// call when no more reads will be performed on this object. inDisconnected is true when client has disconnected -void EHSConnection::DoneReading ( int inDisconnected ) -{ - // Mutex is locked - m_nDoneReading = 1; - m_nDisconnected = inDisconnected; -} - - -HttpRequest * EHSConnection::GetNextRequest ( ) -{ - - HttpRequest * poHttpRequest = NULL; - - if ( MUTEX_TRY_LOCK ( m_oConnectionMutex ) == false ) - return NULL; - - if ( m_oHttpRequestList.empty ( ) ) { - - poHttpRequest = NULL; - - } else { - - poHttpRequest = m_oHttpRequestList.front ( ); - - m_oHttpRequestList.pop_front ( ); - - } - - MUTEX_UNLOCK ( m_oConnectionMutex ); - - return poHttpRequest; - -} - - -int EHSConnection::CheckDone ( ) -{ - - // if we're not still reading, we may want to drop this connection - if ( !StillReading ( ) ) { - - // if we're done with all our responses (-1 because the next (unused) request is already created) - if ( m_nRequests - 1 <= m_nResponses ) { - - // if we haven't disconnected, do that now - if ( !m_nDisconnected) { - - m_poNetworkAbstraction->Close ( ); - - } - - return 1; - - } - - } - - return 0; - -} - - -//////////////////////////////////////////////////////////////////// -// EHS SERVER -//////////////////////////////////////////////////////////////////// - -EHSServer::EHSServer ( EHS * ipoTopLevelEHS ///< pointer to top-level EHS for request routing - ) : - m_nServerRunningStatus ( SERVERRUNNING_NOTRUNNING ), - m_poTopLevelEHS ( ipoTopLevelEHS ), - m_nRequestsPending ( 0 ), - m_nIdleTimeout ( 15 ) -{ - // you HAVE to specify a top-level EHS object - // compare against NULL for 64-bit systems - assert ( m_poTopLevelEHS != NULL ); - - - MUTEX_SETUP ( m_oMutex ); - pthread_cond_init ( & m_oDoneAccepting, NULL ); - - m_nAccepting = 0; - m_iActiveThreadCount = 0; - - // grab out the parameters for less typing later on - EHSServerParameters & roEHSServerParameters = - ipoTopLevelEHS->m_oEHSServerParameters; - - // whether to run with https support - int nHttps = roEHSServerParameters [ "https" ]; - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: EHSServer\n" ); -#endif - - - if ( nHttps ) { - EHS_TRACE ( "EHSServer running in HTTPS mode\n"); - } else { - EHS_TRACE ( "EHSServer running in plain-text mode (no HTTPS)\n"); - } - - - - // are we using secure sockets? - if ( !nHttps ) { - m_poNetworkAbstraction = new Socket ( ); - } else { - -#ifdef COMPILE_WITH_SSL - - - EHS_TRACE ( "Trying to create secure socket with certificate='%s' and passphrase='%s'\n", - (const char*)roEHSServerParameters [ "certificate" ], - (const char*)roEHSServerParameters [ "passphrase" ] ); - - - SecureSocket * poSecureSocket = - new SecureSocket ( roEHSServerParameters [ "certificate" ], - roEHSServerParameters [ "passphrase" ] ); - - // HIGHLY EXPERIMENTAL - // scary shit - EHS_TRACE ( "Thinking about loading callback - '%s'\n", - roEHSServerParameters [ "passphrasecallback" ]. - GetCharString ( ) ); - - - if ( roEHSServerParameters [ "passphrasecallback" ] != "" && - dlsym ( RTLD_DEFAULT, - roEHSServerParameters [ "passphrasecallback" ] ) == - NULL ) { - - EHS_TRACE ( "Couldn't load symbol for '%s' -- make sure you extern \"C\" the function\n", - roEHSServerParameters [ "passphrasecallback" ]. - GetCharString ( ) ); - } - - - - EHS_TRACE ( "done thinking about loading callback\n" ); - - - - - poSecureSocket->SetPassphraseCallback ( (int ( * ) ( char *, int, int, void * )) - dlsym ( RTLD_DEFAULT, - roEHSServerParameters [ "passphrasecallback" ] ) ); - // END EXPERIMENTAL - - m_poNetworkAbstraction = poSecureSocket; -#else // COMPILE_WITH_SSL - fprintf ( stderr, "EHS not compiled with SSL support. Cannot create HTTPS server. Aborting\n" ); - exit ( 1 ); -#endif // COMPILE_WITH_SSL - - - - } - - - // initialize the socket - assert ( m_poNetworkAbstraction != NULL ); - int nResult = m_poNetworkAbstraction->Init ( roEHSServerParameters [ "bindip" ], roEHSServerParameters [ "port" ] ); // initialize socket stuff - - - - - if ( nResult != NetworkAbstraction::INITSOCKET_SUCCESS ) { - - EHS_TRACE ( "Error: Failed to initialize sockets\n" ); - - return; - } - - - if ( roEHSServerParameters [ "mode" ] == "threadpool" ) { - - // need to set this here because the thread will check this to make - // sure it's supposed to keep running - m_nServerRunningStatus = SERVERRUNNING_THREADPOOL; - - // create a pthread - int nResult = -1; - - EHS_TRACE ( "Starting %d threads\n", roEHSServerParameters [ "threadcount" ].GetInt ( ) ); - - - int nThreadsToStart = roEHSServerParameters [ "threadcount" ].GetInt ( ); - if ( nThreadsToStart == 0 ) { - nThreadsToStart = 1; - } - - for ( int i = 0; i < nThreadsToStart; i++ ) { - - EHS_TRACE ( "creating thread with %x, NULL, %x, %x\n", - &m_nAcceptThreadId, - EHSServer::PthreadHandleData_ThreadedStub, - (void *) this ); - - // create new thread and detach so we don't have to join on it - nResult = - pthread_create ( &m_nAcceptThreadId, - NULL, - EHSServer::PthreadHandleData_ThreadedStub, - (void *) this ); - pthread_detach ( m_nAcceptThreadId ); - - } - - if ( nResult != 0 ) { - m_nServerRunningStatus = SERVERRUNNING_NOTRUNNING; - } - - - } else if ( roEHSServerParameters [ "mode" ] == "onethreadperrequest" ) { - - m_nServerRunningStatus = SERVERRUNNING_ONETHREADPERREQUEST; - - // spawn off one thread just to deal with basic stuff - nResult = pthread_create ( &m_nAcceptThreadId, - NULL, - EHSServer::PthreadHandleData_ThreadedStub, - (void *) this ); - pthread_detach ( m_nAcceptThreadId ); - - // check to make sure the thread was created properly - if ( nResult != 0 ) { - m_nServerRunningStatus = SERVERRUNNING_NOTRUNNING; - } - - } else if ( roEHSServerParameters [ "mode" ] == "singlethreaded" ) { - - // we're single threaded - m_nServerRunningStatus = SERVERRUNNING_SINGLETHREADED; - - } else { - - EHS_TRACE ( "INVALID 'mode' SPECIFIED.\ntMust be 'singlethreaded', 'threadpool', or 'onethreadperrequest'\n" ); - - assert ( 0 ); - } - - - if ( m_nServerRunningStatus == SERVERRUNNING_THREADPOOL ) { - EHS_TRACE ( "Info: EHS Server running in dedicated thread mode with '%s' threads\n", - roEHSServerParameters [ "threadcount" ] == "" ? - roEHSServerParameters [ "threadcount" ].GetCharString ( ) : "1" ); - } else if ( m_nServerRunningStatus == SERVERRUNNING_ONETHREADPERREQUEST ) { - EHS_TRACE ( "Info: EHS Server running with one thread per request\n" ); - } else if ( m_nServerRunningStatus == SERVERRUNNING_SINGLETHREADED ) { - EHS_TRACE ( "Info: EHS Server running in non-dedicated thread mode\n" ); - } else { - EHS_TRACE ( "Error: EHS Server not running. Server initialization failed\n" ); - } - - return; - - -} - - -EHSServer::~EHSServer ( ) -{ - if ( m_poNetworkAbstraction ) - { - m_poNetworkAbstraction->Close (); - delete m_poNetworkAbstraction; - m_poNetworkAbstraction = NULL; - } - MUTEX_CLEANUP ( m_oMutex ); - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: EHSServer\n" ); -#endif - -} - -HttpRequest * EHSServer::GetNextRequest ( ) -{ - - // don't lock because it's only called from within locked sections - - HttpRequest * poNextRequest = NULL; - - // pick a random connection if the list isn't empty - if ( ! m_oEHSConnectionList.empty ( ) ) { - - // pick a random connection, so no one takes too much time - int nWhich = (int) ( ( (double) m_oEHSConnectionList.size ( ) ) * rand ( ) / ( RAND_MAX + 1.0 ) ); - - // go to that element - EHSConnectionList::iterator i = m_oEHSConnectionList.begin ( ); - int nCounter = 0; - - for ( nCounter = 0; nCounter < nWhich; nCounter++ ) { - i++; - } - - // now get the next available request treating the list as circular - - EHSConnectionList::iterator iStartPoint = i; - int nFirstTime = 1; - while ( poNextRequest == NULL && - !( iStartPoint == i && nFirstTime == 0 ) ) { - - // check this one to see if it has anything - poNextRequest = (*i)->GetNextRequest ( ); - - - i++; - - if ( i == m_oEHSConnectionList.end ( ) ) { - i = m_oEHSConnectionList.begin ( ); - } - - nFirstTime = 0; - - // decrement the number of pending requests - if ( poNextRequest != NULL ) { - - m_nRequestsPending--; - - } - - } - - } - - - if ( poNextRequest == NULL ) { -// EHS_TRACE ( "No request found\n" ); - } else { - EHS_TRACE ( "Found request\n" ); - } - - - return poNextRequest; - -} - -int EHSServer::RemoveEHSConnection ( EHSConnection * ipoEHSConnection ) -{ - - // don't lock as it's only called from within locked sections - assert ( ipoEHSConnection != NULL ); - int nDeletedOneAlready = 0; - - - EHS_TRACE ( "%d elements to look for somethign to delete\n", - m_oEHSConnectionList.size ( ) ); - - - // go through the list and find all occurances of ipoEHSConnection - for ( EHSConnectionList::iterator i = m_oEHSConnectionList.begin ( ); - i != m_oEHSConnectionList.end ( ); - /* no third part */ ) { - - if ( *i == ipoEHSConnection ) { - if ( nDeletedOneAlready ) { - EHS_TRACE ( "FATAL ERROR: Deleting a second element in RemoveEHSConnection - EXITING\n" ); - exit ( 2 ); - } - nDeletedOneAlready = 1; - - - // close the FD - EHSConnection * poEHSConnection = *i; - - NetworkAbstraction * poNetworkAbstraction = poEHSConnection->GetNetworkAbstraction ( ); - - poNetworkAbstraction->Close ( ); -#if STOP_MEMORY_LEAKS // Needs testing - delete poEHSConnection; -#endif - - // start back over at the beginning of the list - m_oEHSConnectionList.erase ( i ); - i = m_oEHSConnectionList.begin ( ); - - // Mark as unused - poEHSConnection->m_UnusedSyncId = m_ThreadsSyncPoint.GetSyncId (); - m_oEHSConnectionUnusedList.push_back ( poEHSConnection ); - } else { - i++; - } - - } - - return nDeletedOneAlready; - -} - - - -EHS::StartServerResult -EHS::StartServer ( EHSServerParameters & iroEHSServerParameters ) -{ - StartServerResult nResult = STARTSERVER_INVALID; - - m_oEHSServerParameters = iroEHSServerParameters; - - if ( poEHSServer != NULL ) { - - EHS_TRACE ( "Warning: Tried to start server that was already running\n" ); - - - nResult = STARTSERVER_ALREADYRUNNING; - - } else { - - // associate a EHSServer object to this EHS object - poEHSServer = new EHSServer ( this ); - - if ( poEHSServer->m_nServerRunningStatus == EHSServer::SERVERRUNNING_NOTRUNNING ) { - - - EHS_TRACE ( "Error: Failed to start server\n" ); - - - - return STARTSERVER_FAILED; - - } - } - - return STARTSERVER_SUCCESS; - -} - - - -// this is the function specified to pthread_create under UNIX -// because you can't start a thread directly into a class method -void * EHSServer::PthreadHandleData_ThreadedStub ( void * ipParam ///< EHSServer object cast to a void pointer - ) -{ - - EHSServer * poThis = (EHSServer *) ipParam; - - poThis->HandleData_Threaded ( ); - - return NULL; - -} - - - -void EHS::StopServer ( ) -{ - - // make sure we're in a sane state - assert ( ( poParent == NULL && poEHSServer != NULL ) || - ( poParent != NULL && poEHSServer == NULL ) ); - - if ( poParent ) { - poParent->StopServer ( ); - } else { - poEHSServer->m_nServerRunningStatus = EHSServer::SERVERRUNNING_NOTRUNNING; - - // Allow 10 seconds for threads to stop - for( int i = 0; i < 100 && poEHSServer->m_iActiveThreadCount; i++ ) - { - pthread_cond_broadcast ( & poEHSServer->m_oDoneAccepting ); - Sleep(100); - } - } - -} - - - - -void EHSServer::HandleData_Threaded ( ) -{ - -#define HANDLEDATA_THREADEDSELECTTIMEOUTMILLISECONDS 1000 - - - pthread_t nMyThreadId = pthread_self ( ); - - MUTEX_LOCK ( m_oMutex ); - int ThreadIndex = m_ThreadsSyncPoint.GetNewThreadIndex (); - m_iActiveThreadCount++; - MUTEX_UNLOCK ( m_oMutex ); - - do { - - //fprintf ( stderr, "##### [%d] Thread HandleData\n", nMyThreadId ); - HandleData ( HANDLEDATA_THREADEDSELECTTIMEOUTMILLISECONDS, - nMyThreadId ); - - MUTEX_LOCK ( m_oMutex ); - m_ThreadsSyncPoint.SyncThreadIndex ( ThreadIndex ); - MUTEX_UNLOCK ( m_oMutex ); - - } while ( m_nServerRunningStatus != SERVERRUNNING_NOTRUNNING && - ( m_nServerRunningStatus == SERVERRUNNING_THREADPOOL || - pthread_equal(nMyThreadId,m_nAcceptThreadId) ) ); - - //fprintf ( stderr, "##### [%d] Thread exiting\n", nMyThreadId ); - MUTEX_LOCK ( m_oMutex ); - m_iActiveThreadCount--; - MUTEX_UNLOCK ( m_oMutex ); - - -} - - - - -void EHSServer::HandleData ( int inTimeoutMilliseconds, ///< milliseconds for timeout on select - pthread_t inThreadId ///< numeric ID for this thread to help debug - ) -{ - - //fprintf ( stderr, "##### [%d] Trying to lock server mutex\n", inThreadId ); - - MUTEX_LOCK ( m_oMutex ); - - //fprintf ( stderr, "##### [%d] Got lock on server mutex\n", inThreadId ); - - // determine if there are any jobs waiting if this thread should -- - // if we're running one-thread-per-request and this is the accept thread - // we don't look for requests - HttpRequest * poHttpRequest = NULL; - if ( m_nServerRunningStatus != SERVERRUNNING_ONETHREADPERREQUEST || - !pthread_equal(inThreadId,m_nAcceptThreadId) ) { - - poHttpRequest = GetNextRequest ( ); - - } - - // if we got a request to handle - if ( poHttpRequest != NULL ) { - - //fprintf ( stderr, "##### [%d] Got a request to handle\n", inThreadId ); - - // handle the request and post it back to the connection object - MUTEX_UNLOCK ( m_oMutex ); - - // route the request - HttpResponse * poHttpResponse = - m_poTopLevelEHS->RouteRequest ( poHttpRequest ); - - // add the response to the appropriate connection's response list - poHttpResponse->m_poEHSConnection->AddResponse ( poHttpResponse ); - - delete poHttpRequest; - - } - // otherwise, no requests are pending - else { - - // if something is already accepting, sleep - if ( m_nAccepting ) { - - // wait until something happens - // it's ok to not recheck our condition here, as we'll come back in the same way and recheck then - //fprintf ( stderr, "##### [%d] Sleeping because no requests and someone else is accepting\n", inThreadId ); - - pthread_cond_wait ( & m_oDoneAccepting, - & m_oMutex ); - - MUTEX_UNLOCK ( m_oMutex ); - - } - // if no one is accepting, we accept - else { - - m_nAcceptedNewConnection = 0; - - - - //fprintf ( stderr, "Accepting\n" ); - - // we're now accepting - m_nAccepting = 1; - - MUTEX_UNLOCK ( m_oMutex ); - - // create the FD set for poll - CreateFdSet(); - int nSocketCount = poll( m_oReadFds.GetFdArray(), m_oReadFds.GetFdCount(), inTimeoutMilliseconds ); - - // handle select error -#ifdef _WIN32 - if ( nSocketCount == SOCKET_ERROR ) -#else // NOT _WIN32 - if ( nSocketCount == -1 ) -#endif // _WIN32 - { - - EHS_TRACE ( "[%d] Critical Error: select() failed. Aborting\n", inThreadId ); - - // Idea! Remove stupid idea - //exit ( 0 ); - } - - - - // if no sockets have data to read, clear accepting flag and return - if ( nSocketCount > 0 ) { - - // Check the accept socket for a new connection - CheckAcceptSocket ( ); - - // check client sockets for data - CheckClientSockets ( ); - - } - - MUTEX_LOCK ( m_oMutex ); - ClearIdleConnections ( ); - m_nAccepting = 0; - MUTEX_UNLOCK ( m_oMutex ); - - // Occasional pulse for updating of things - m_poTopLevelEHS->HttpPulse (); - - } // END ACCEPTING - - } // END NO REQUESTS PENDING - - - MUTEX_LOCK ( m_oMutex ); - - // Delete unused connections after all threads have been synced - EHSConnectionList :: iterator iter = m_oEHSConnectionUnusedList.begin (); - while ( iter != m_oEHSConnectionUnusedList.end () ) - { - EHSConnection* pConnection = *iter; - // Delete it after all threads are past syncing point - if ( pConnection->m_UnusedSyncId < m_ThreadsSyncPoint.GetSyncId () - 1 ) - { - iter = m_oEHSConnectionUnusedList.erase ( iter ); - delete pConnection; - } - else - iter++; - } - - MUTEX_UNLOCK ( m_oMutex ); - -} - -void EHSServer::CheckAcceptSocket ( ) -{ - - // see if we got data on this socket - if ( m_oReadFds.IsSet( m_poNetworkAbstraction->GetFd(), POLLIN ) ) { - - - //printf ( "Accept new connection\n"); - // THIS SHOULD BE NON-BLOCKING OR ELSE A HANG CAN OCCUR IF THEY DISCONNECT BETWEEN WHEN - // POLL SEES THE CONNECTION AND WHEN WE ACTUALLY CALL ACCEPT - NetworkAbstraction * poNewClient = - m_poNetworkAbstraction->Accept ( ); - - - - // not sure what would cause this - if ( poNewClient == NULL ) { - return; - } - - // Flood detection - if ( !m_poTopLevelEHS->ShouldAllowConnection ( poNewClient->GetAddress ().c_str () ) ) - { - - MUTEX_LOCK ( m_oMutex ); - // Stop all other connections using this address - for ( EHSConnectionList::iterator i = m_oEHSConnectionList.begin ( ); - i != m_oEHSConnectionList.end ( ); - i++ ) { - - if ( (*i)->GetNetworkAbstraction ( )->GetAddress ( ) == poNewClient->GetAddress () ) - { - (*i)->m_iStopASAP = true; - } - } - MUTEX_UNLOCK ( m_oMutex ); - - // Reject connection - delete poNewClient; - return; - } - - // create a new EHSConnection object and initialize it - EHSConnection * poEHSConnection = - new EHSConnection ( poNewClient, this ); - - MUTEX_LOCK ( m_oMutex ); - m_oEHSConnectionList.push_back ( poEHSConnection ); - m_nAcceptedNewConnection = 1; - MUTEX_UNLOCK ( m_oMutex ); - - } // end FD_ISSET ( ) - -} - -void EHSServer::CheckClientSockets ( ) -{ - MUTEX_LOCK ( m_oMutex ); - - // go through all the sockets from which we're still reading - for ( EHSConnectionList::iterator i = m_oEHSConnectionList.begin ( ); - i != m_oEHSConnectionList.end ( ); - i++ ) { - - if ( m_oReadFds.IsSet( (*i)->GetNetworkAbstraction()->GetFd(), POLLIN ) ) { - - if ( MUTEX_TRY_LOCK ( (*i)->m_oConnectionMutex ) == false ) - continue; - - EHS_TRACE ( "$$$$$ Got data on client connection\n" ); - - - // prepare a buffer for the read - static const int BYTES_TO_READ_AT_A_TIME = 10240; - char psReadBuffer [ BYTES_TO_READ_AT_A_TIME + 1 ]; - memset ( psReadBuffer, 0, BYTES_TO_READ_AT_A_TIME + 1 ); - - // do the actual read - int nBytesReceived = - (*i)->GetNetworkAbstraction ( )->Read ( psReadBuffer, - BYTES_TO_READ_AT_A_TIME ); - - if ( nBytesReceived == SOCKET_ERROR ) - { - int err = GetLastSocketError (); - if ( err == E_WOULDBLOCK ) - { - MUTEX_UNLOCK ( (*i)->m_oConnectionMutex ); - continue; - } - } - // if we received a disconnect - if ( nBytesReceived <= 0 ) { - - // we're done reading and we received a disconnect - (*i)->DoneReading ( true ); - - } - // otherwise we got data - else { - - // take the data we got and append to the connection's buffer - EHSConnection::AddBufferResult nAddBufferResult = - (*i)->AddBuffer ( psReadBuffer, nBytesReceived ); - - // if add buffer failed, don't read from this connection anymore - if ( nAddBufferResult == EHSConnection::ADDBUFFER_INVALIDREQUEST || - nAddBufferResult == EHSConnection::ADDBUFFER_TOOBIG ) { - - // done reading but did not receieve disconnect - EHS_TRACE ( "Done reading because we got a bad request\n" ); - (*i)->DoneReading ( false ); - - } // end error with AddBuffer - - } // end nBytesReceived - - MUTEX_UNLOCK ( (*i)->m_oConnectionMutex ); - } // FD_ISSET - - } // for loop through connections - MUTEX_UNLOCK ( m_oMutex ); - -} - - -const char* GetHttpStatusReasonPhrase(int statusCode) -{ - if (statusCode >= 100 && statusCode <= 199) - { - switch (statusCode) - { - case HTTP_STATUS_CODE_100_CONTINUE: - return "Continue"; - case HTTP_STATUS_CODE_101_SWITCHING_PROTOCOLS: - return "Switching Protocols"; - default: - return "Informational"; - } - } - - if (statusCode >= 200 && statusCode <= 299) - { - switch (statusCode) - { - case HTTP_STATUS_CODE_200_OK: - return "OK"; - case HTTP_STATUS_CODE_201_CREATED: - return "Created"; - case HTTP_STATUS_CODE_202_ACCEPTED: - return "Accepted"; - case HTTP_STATUS_CODE_203_NON_AUTHORITATIVE_INFO: - return "Non-Authoritative Information"; - case HTTP_STATUS_CODE_204_NO_CONTENT: - return "No Content"; - case HTTP_STATUS_CODE_205_RESET_CONTENT: - return "Reset Content"; - case HTTP_STATUS_CODE_206_PARTIAL_CONTENT: - return "Partial Content"; - default: - return "Success"; - } - } - - if (statusCode >= 300 && statusCode <= 399) - { - switch (statusCode) - { - case HTTP_STATUS_CODE_300_MULTIPLE_CHOICES: - return "Multiple Choices"; - case HTTP_STATUS_CODE_301_MOVED_PERMANENTLY: - return "Moved Permanently"; - case HTTP_STATUS_CODE_302_FOUND: - return "Found"; - case HTTP_STATUS_CODE_303_SEE_OTHER: - return "See Other"; - case HTTP_STATUS_CODE_304_NOT_MODIFIED: - return "Not Modified"; - case HTTP_STATUS_CODE_305_USE_PROXY: - return "Use Proxy"; - case HTTP_STATUS_CODE_307_TEMPORARY_REDIRECT: - return "Temporary Redirect"; - default: - return "Redirection"; - } - } - - if (statusCode >= 400 && statusCode <= 499) - { - switch (statusCode) - { - case HTTP_STATUS_CODE_400_BAD_REQUEST: - return "Bad Request"; - case HTTP_STATUS_CODE_401_UNAUTHORIZED: - return "Unauthorized"; - case HTTP_STATUS_CODE_402_PAYMENT_REQUIRED: - return "Payment Required"; - case HTTP_STATUS_CODE_403_FORBIDDEN: - return "Forbidden"; - case HTTP_STATUS_CODE_404_NOT_FOUND: - return "Not Found"; - case HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED: - return "Method Not Allowed"; - case HTTP_STATUS_CODE_406_NOT_ACCEPTABLE: - return "Not Acceptable"; - case HTTP_STATUS_CODE_407_PROXY_AUTH_REQUIRED: - return "Proxy Authentication Required"; - case HTTP_STATUS_CODE_408_REQUEST_TIMEOUT: - return "Request Time-out"; - case HTTP_STATUS_CODE_409_CONFLICT: - return "Conflict"; - case HTTP_STATUS_CODE_410_GONE: - return "Gone"; - case HTTP_STATUS_CODE_411_LENGTH_REQUIRED: - return "Length Required"; - case HTTP_STATUS_CODE_412_PRECONDITION_FAILED: - return "Precondition Failed"; - case HTTP_STATUS_CODE_413_REQUEST_ENTITY_TOO_LARGE: - return "Request Entity Too Large"; - case HTTP_STATUS_CODE_414_URI_TOO_LARGE: - return "Request-URI Too Large"; - case HTTP_STATUS_CODE_415_UNSUPPORTED_MEDIA_TYPE: - return "Unsupported Media Type"; - case HTTP_STATUS_CODE_416_RANGE_NOT_SATISFIABLE: - return "Requested range not satisfiable"; - case HTTP_STATUS_CODE_417_EXPECTATION_FAILED: - return "Expectation Failed"; - default: - return "Client Error"; - } - } - - if (statusCode >= 500 && statusCode <= 599) - { - switch (statusCode) - { - case HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR: - return "Internal Server Error"; - case HTTP_STATUS_CODE_501_NOT_IMPLEMENTED: - return "Not Implemented"; - case HTTP_STATUS_CODE_502_BAD_GATEWAY: - return "Bad Gateway"; - case HTTP_STATUS_CODE_503_SERVICE_UNAVAILABLE: - return "Service Unavailable"; - case HTTP_STATUS_CODE_504_GATEWAY_TIMEOUT: - return "Gateway Time-out"; - case HTTP_STATUS_CODE_505_VERSION_NOT_SUPPORTED: - return "HTTP Version not supported"; - default: - return "Server Error"; - } - } - - return "Unknown"; -} - - -void EHSConnection::AddResponse ( HttpResponse * ipoHttpResponse ) -{ - - MUTEX_LOCK ( m_oConnectionMutex ); - - // push the object on to the list - m_oHttpResponseMap [ ipoHttpResponse->m_nResponseId ] = ipoHttpResponse; - - // go through the list until we can't find the next response to send - int nFoundNextResponse = 0; - do { - - nFoundNextResponse = 0; - - if ( m_oHttpResponseMap.find ( m_nResponses + 1 ) != m_oHttpResponseMap.end ( ) ) { - - nFoundNextResponse = 1; - - HttpResponseMap::iterator i = m_oHttpResponseMap.find ( m_nResponses + 1 ); - - SendHttpResponse ( i->second ); - - delete i->second; - - m_oHttpResponseMap.erase ( i ); - - m_nResponses++; - - // set last activity to the current time for idle purposes - UpdateLastActivity ( ); - - // if we're done with this connection, get rid of it - if ( CheckDone ( ) ) { - EHS_TRACE( "add response found something to delete\n" ); - - // careful with mutexes around here.. Don't want to hold both - MUTEX_UNLOCK ( m_oConnectionMutex ); - MUTEX_LOCK ( m_poEHSServer->m_oMutex ); - m_poEHSServer->RemoveEHSConnection ( this ); - MUTEX_UNLOCK ( m_poEHSServer->m_oMutex ); - return; - - } - - - EHS_TRACE ( "Sending response %d to %x\n", m_nResponses, this ); - - - } - - } while ( nFoundNextResponse == 1 ); - - MUTEX_UNLOCK ( m_oConnectionMutex ); - -} - -void EHSConnection::SendHttpResponse ( HttpResponse * ipoHttpResponse ) -{ - - // only send it if the client isn't disconnected - if ( Disconnected ( ) ) { - - return; - - } - - std::string sOutput; - - char psSmallBuffer [ 20 ]; - - sOutput = "HTTP/1.1 "; - - // add in the response code - sprintf ( psSmallBuffer, "%d", ipoHttpResponse->m_nResponseCode ); - sOutput += psSmallBuffer; - - sOutput += " "; - sOutput += GetHttpStatusReasonPhrase ( ipoHttpResponse->m_nResponseCode ); - sOutput += "\r\n"; - - - // now go through all the entries in the responseheaders string map - for ( StringMap::iterator oCurrentHeader = ipoHttpResponse->oResponseHeaders.begin ( ); - oCurrentHeader != ipoHttpResponse->oResponseHeaders.end ( ); - oCurrentHeader++ ) { - - sOutput += (*oCurrentHeader).first; - sOutput += ": "; - sOutput += (*oCurrentHeader).second; - sOutput += "\r\n"; - - } - - // now push out all the cookies - for ( StringList::iterator i = ipoHttpResponse->oCookieList.begin ( ); - i != ipoHttpResponse->oCookieList.end ( ); - i++ ) { - sOutput += "Set-Cookie: "; - sOutput += *i; - sOutput += "\r\n"; - } - - // extra line break signalling end of headers - sOutput += "\r\n"; - - int ret = TrySend ( sOutput.c_str (), sOutput.length() ); - - if ( ret == -1 ) - return; - - // now send the body - TrySend ( ipoHttpResponse->GetBody ( ), - atoi ( ipoHttpResponse->oResponseHeaders [ "content-length" ].c_str ( ) ) ); - -} - -int EHSConnection::TrySend ( const char * ipMessage, size_t inLength, int inFlags ) -{ - - int iWouldBlockCount = 0; -lp1: - { - int iCount = 0; - UpdateLastActivity ( ); - while( !m_poNetworkAbstraction->IsWritable(1000) && !m_poNetworkAbstraction->IsAtError(0) ) - { - iCount++; - if ( iCount == 10 ) - { - break; - } - } - } - - int ret = m_poNetworkAbstraction->Send ( ipMessage, inLength, inFlags ); - - if ( ret == SOCKET_ERROR ) - { - int err = GetLastSocketError (); - if ( err == E_WOULDBLOCK ) - { - Sleep(20); - iWouldBlockCount++; - if ( iWouldBlockCount < 2 ) - goto lp1; - m_poNetworkAbstraction->Close(); - } - } - else - if ( ret != inLength ) - { - ipMessage += ret; - inLength -= ret; - Sleep(1); - goto lp1; - } - - return ret; -} - - -void EHSServer::EndServerThread ( char * ipsReason ///< reason for ending the thread - ) -{ - - MUTEX_LOCK ( m_oMutex ); - - m_sShutdownReason = ipsReason; - m_nServerRunningStatus = SERVERRUNNING_NOTRUNNING; - - MUTEX_UNLOCK ( m_oMutex ); - -} - -EHS::EHS ( EHS * ipoParent, ///< parent EHS object for routing purposes - std::string isRegisteredAs ///< path string for routing purposes - ) : - poParent ( NULL ), - poEHSServer ( NULL ), - m_poSourceEHS ( NULL ) -{ - - if ( ipoParent != NULL ) { - SetParent ( ipoParent, isRegisteredAs ); - } - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: EHS\n" ); -#endif - -} - -EHS::~EHS ( ) -{ - // needs to clean up all its registered interfaces - if ( poParent ) { - poParent->UnregisterEHS ( sRegisteredAs.c_str ( ) ); - } - - delete poEHSServer; - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: EHS\n" ); -#endif - -} - -void EHS::SetParent ( EHS * ipoParent, ///< this is the new parent - std::string isRegisteredAs ///< path for routing - ) -{ - poParent = ipoParent; - sRegisteredAs = isRegisteredAs; -} - -EHS::RegisterEHSResult -EHS::RegisterEHS ( EHS * ipoEHS, ///< new sibling - const char * ipsRegisterPath ///< path for routing - ) -{ - - ipoEHS->SetParent ( this, ipsRegisterPath ); - - if ( oEHSMap [ ipsRegisterPath ] ) { - return REGISTEREHSINTERFACE_ALREADYEXISTS; - } - - oEHSMap [ ipsRegisterPath ] = ipoEHS; - - return REGISTEREHSINTERFACE_SUCCESS; - -} - - -EHS::UnregisterEHSResult -EHS::UnregisterEHS ( const char * ipsRegisterPath ///< remove object at this path - ) -{ - - if ( !oEHSMap [ ipsRegisterPath ] ) { - return UNREGISTEREHSINTERFACE_NOTREGISTERED; - } - - oEHSMap.erase ( ipsRegisterPath ); - - return UNREGISTEREHSINTERFACE_SUCCESS; - -} - - -void EHS::HandleData ( int inTimeoutMilliseconds ///< milliseconds for select timeout - ) -{ - // make sure we're in a sane state - assert ( ( poParent == NULL && poEHSServer != NULL ) || - ( poParent != NULL && poEHSServer == NULL ) ); - - if ( poParent ) { - - poParent->HandleData( inTimeoutMilliseconds ); - - } else { - - // if we're in single threaded mode, handle data until there are no more jobs left - if ( poEHSServer->m_nServerRunningStatus == - EHSServer::SERVERRUNNING_SINGLETHREADED ) { - - int nChecksInARow=0; - - do { - -/* fprintf ( stderr, "Doing %d requests in a row - %d - %d\n", ++nChecksInARow, - poEHSServer->RequestsPending ( ), - poEHSServer->m_nAcceptedNewConnection ); -*/ - pthread_t dummy; -memset(&dummy,0,sizeof(pthread_t)); -// dummy.p = NULL; - poEHSServer->HandleData( inTimeoutMilliseconds, dummy ); - - } while ( poEHSServer->RequestsPending ( ) || - poEHSServer->m_nAcceptedNewConnection ); - - } - - } - -// fprintf ( stderr, "##### Done checking this time through\n" ); - -} - - - -std::string GetNextPathPart ( std::string & irsUri ///< URI to look for next path part in - ) -{ - - - PME oNextPathPartRegex ( "^[/]{0,1}([^/]+)/(.*)$" ); - - if ( oNextPathPartRegex.match ( irsUri ) ) { - - std::string sReturnValue = oNextPathPartRegex [ 1 ]; - std::string sNewUri = oNextPathPartRegex [ 2 ]; - - irsUri = sNewUri; - return sReturnValue; - - } else { - - return ""; - - } - -} - -HttpResponse * -EHS::RouteRequest ( HttpRequest * ipoHttpRequest ///< request info for service - ) -{ - - // get the next path from the URI - std::string sNextPathPart = GetNextPathPart ( ipoHttpRequest->sUri ); - - - EHS_TRACE ( "Info: Trying to route: '%s'\n", sNextPathPart.c_str ( ) ); - - - // if there is no more path, call HandleRequest on this EHS object with - // whatever's left - or if we're not routing - if ( sNextPathPart.empty ( ) || - m_oEHSServerParameters.find ( "norouterequest" ) != - m_oEHSServerParameters.end ( ) ) { - - // create an HttpRespose object for the client - HttpResponse * poHttpResponse = - new HttpResponse ( ipoHttpRequest->m_nRequestId, - ipoHttpRequest->m_poSourceEHSConnection ); - - // get the actual response and return code - poHttpResponse->m_nResponseCode = - HandleRequest ( ipoHttpRequest, poHttpResponse ); - - return poHttpResponse; - - } - - // if the path exists, check it against the map of EHSs - if ( oEHSMap [ sNextPathPart ] ) { - - // if it exists, call RouteRequest with that EHS and the - // new shortened path - - return oEHSMap [ sNextPathPart ]->RouteRequest ( ipoHttpRequest ); - - } - // if it doesn't exist, send an error back up saying resource doesn't exist - else { - - - EHS_TRACE ( "Info: Routing failed. Most likely caused by an invalid URL, not internal error\n" ); - - - // send back a 404 response - HttpResponse * poHttpResponse = new HttpResponse ( ipoHttpRequest->m_nRequestId, - ipoHttpRequest->m_poSourceEHSConnection ); - - poHttpResponse->m_nResponseCode = HTTP_STATUS_CODE_404_NOT_FOUND; - poHttpResponse->SetBody ( "404 - Not Found", strlen ( "404 - Not Found" ) ); - - return poHttpResponse; - - } - -} - -// default handle request does nothing -HttpStatusCode EHS::HandleRequest ( HttpRequest * ipoHttpRequest, - HttpResponse * ipoHttpResponse) -{ - - // if we have a source EHS specified, use it - if ( m_poSourceEHS != NULL ) { - return m_poSourceEHS->HandleRequest ( ipoHttpRequest, ipoHttpResponse ); - } - - // otherwise, just send back the current time - char psTime [ 20 ]; - sprintf ( psTime, "%lld", time ( NULL ) ); - ipoHttpResponse->SetBody ( psTime, strlen ( psTime ) ); - return HTTP_STATUS_CODE_200_OK; - -} - -void EHS::SetSourceEHS ( EHS & iroSourceEHS ) -{ - - m_poSourceEHS = &iroSourceEHS; - -} - - -void EHS::SetCertificateFile ( std::string & irsCertificateFile ) -{ - - assert ( 0 ); - -} - -/// set certificate passphrase -void EHS::SetCertificatePassphrase ( std::string & irsCertificatePassphrase ) -{ - - assert ( 0 ); - -} - -/// sets a new passphrase callback function -void EHS::SetPassphraseCallback ( int ( * m_ipfOverridePassphraseCallback ) ( char *, int, int, void * ) ) -{ - - assert ( 0 ); - -} - - -#ifdef COMPILE_WITH_SSL -// secure socket static class variables -DynamicSslLocking * SecureSocket::poDynamicSslLocking = NULL; -StaticSslLocking * SecureSocket::poStaticSslLocking = NULL; -SslError * SecureSocket::poSslError = NULL; - -SSL_CTX * SecureSocket::poCtx; - -#endif // COMPILE_WITH_SSL - -long long EHS::StaticGetTotalBytesSent ( void ) -{ - ms_StatsCS.Lock(); - long long llResult = ms_HttpTotalBytesSent; - ms_StatsCS.Unlock(); - return llResult; -} - -void EHS::StaticGetAllocationStats ( SAllocationStats& outAllocationStats ) -{ - ms_StatsCS.Lock(); - outAllocationStats = ms_AllocationStats; - ms_StatsCS.Unlock(); -} - -void StatsAddTotalBytesSent( size_t inLength ) -{ - ms_StatsCS.Lock(); - ms_HttpTotalBytesSent += inLength; - ms_StatsCS.Unlock(); -} - -void StatsNumRequestsInc( void ) -{ - ms_StatsCS.Lock(); - ms_AllocationStats.uiTotalNumRequests++; - ms_AllocationStats.uiActiveNumRequests++; - ms_StatsCS.Unlock(); -} - -void StatsNumRequestsDec( void ) -{ - ms_StatsCS.Lock(); - ms_AllocationStats.uiActiveNumRequests--; - ms_StatsCS.Unlock(); -} - -void StatsNumResponsesInc( void ) -{ - ms_StatsCS.Lock(); - ms_AllocationStats.uiTotalNumResponses++; - ms_AllocationStats.uiActiveNumResponses++; - ms_StatsCS.Unlock(); -} - -void StatsNumResponsesDec( void ) -{ - ms_StatsCS.Lock(); - ms_AllocationStats.uiActiveNumResponses--; - ms_StatsCS.Unlock(); -} - -void StatsBytesAllocated( int nBodyLength ) -{ - ms_StatsCS.Lock(); - ms_AllocationStats.uiTotalKBAllocated += nBodyLength / 1024; - ms_AllocationStats.uiActiveKBAllocated += nBodyLength / 1024; - ms_StatsCS.Unlock(); -} - -void StatsBytesDeallocated( int nBodyLength ) -{ - ms_StatsCS.Lock(); - ms_AllocationStats.uiActiveKBAllocated -= nBodyLength / 1024; - ms_StatsCS.Unlock(); -} diff --git a/vendor/ehs/ehs.h b/vendor/ehs/ehs.h deleted file mode 100644 index 35e12cfa6c0..00000000000 --- a/vendor/ehs/ehs.h +++ /dev/null @@ -1,555 +0,0 @@ - -/** \mainpage EHS 1.1.3 - - - EHS is a library for embedding HTTP(S) support into a C++ application - Copyright (C) 2004 Zachary J. Hansen - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation; - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - This can be found in the 'COPYING' file. - -*/ - -#ifndef EHS_H -#define EHS_H - -/////////////////////// -#ifdef HAVE_CONFIG_H // -/////////////////////// - -// load up the autoheader-generated config file if it exists (UNIX only) -#include - -///////////////////// -#endif // -///////////////////// - - - -/////////////////////////////////// -#ifdef _WIN32 // windows headers // -/////////////////////////////////// - - -// Pragma'ing away nasty MS 255-char-name problem. Otherwise -// you will get warnings on many template names that -// "identifier was truncated to '255' characters in the debug information". -#pragma warning(disable : 4786) - -// to use winsock2.h instead of winsock.h -#include -#include - -#include - -// make stricmp sound like strcasecmp -#define strcasecmp stricmp - -// make windows sleep act like UNIX sleep -#define sleep(seconds) (Sleep(seconds * 1000)) - -/////////////////////////////////// -#else // unix headers go here // -/////////////////////////////////// - -#include -#include -#include -#include - -/////////////////////////////////// -#endif // end platform headers // -/////////////////////////////////// - -// STL headers -#include -#include -#include -#include -#include -#include -#include -#include - -// C headers -#include -#include -#include -#include -#include - - -// other library headers -#include -#include - -// EHS headers -#include "ehstypes.h" -#include "datum.h" -#include "networkabstraction.h" -#include "socket.h" -#include "securesocket.h" -#include "httpresponse.h" -#include "httprequest.h" -#include "threadabstractionlayer.h" - -class EHSServer; - -/// EHSConnection abstracts the concept of a connection to an EHS application -/** - * EHSConnection abstracts the concept of a connection to an EHS application. - * It stores file descriptor information, unhandled data, and the current - * state of the request - */ -class EHSConnection { - - protected: - - int m_nDoneReading; ///< we're never reading from this again - int m_nDisconnected; ///< client has closed connection on us - - HttpRequest * m_poCurrentHttpRequest; ///< request we're currently parsing - - EHSServer * m_poEHSServer; ///< server with which this is associated - - time_t m_nLastActivity; ///< time at which the last activity occured - - int m_nRequests; ///< holds id of last request received - - int m_nResponses; ///< holds id of last response sent - - - - /// file descriptor associated with this client - NetworkAbstraction * m_poNetworkAbstraction; - - /// raw data received from client that doesn't comprise a full request - std::string m_sBuffer; - - /// holds out-of-order httpresponses that aren't ready to go out yet - HttpResponseMap m_oHttpResponseMap; - - /// holds pending requests - HttpRequestList m_oHttpRequestList; - - /// address from which the connection originated - std::string m_sAddress; - - /// remote port from which the connection originated - int m_nPort; - - public: - int m_iStopASAP; - - /// Constructor - EHSConnection ( NetworkAbstraction * ipoNetworkAbstraction, - EHSServer * ipoEHSServer ); - - /// destructor - ~EHSConnection ( ); - - MUTEX_TYPE m_oConnectionMutex; ///< mutex protecting entire object - - long long m_UnusedSyncId; // Value of SyncId when the connection was first unused - - /// updates the last activity to the current time - void UpdateLastActivity ( ) { m_nLastActivity = time ( NULL ); } - - /// returns the time of last activity - time_t LastActivity ( ) { return m_nLastActivity; } - - /// returns whether we're still reading from this socket -- mutex must be locked - int StillReading ( ) { return !m_nDoneReading; } - - /// returns whether the client has disconnected from us -- mutex must be locked - int Disconnected ( ) { return m_nDisconnected; } - - /// call when no more reads will be performed on this object. inDisconnected is true when client has disconnected - void DoneReading ( int inDisconnected ); - - /// gets the next request object - HttpRequest * GetNextRequest ( ); - - /// returns true if object should be deleted - int CheckDone ( ); - - /// Enumeration result for AddBuffer - enum AddBufferResult { ADDBUFFER_INVALID = 0, - ADDBUFFER_OK, - ADDBUFFER_INVALIDREQUEST, - ADDBUFFER_TOOBIG }; - - /// this is to protect from people being malicious or really stupid - #define MAX_BUFFER_SIZE_BEFORE_BOOT 102400 - - /// adds new data to psBuffer - AddBufferResult AddBuffer ( char * ipsData, int inSize ); - - /// sends the actual data back to the client - void SendHttpResponse ( HttpResponse * ipoHttpResponse); - - /// adds a response to the response list and sends as many responses as are ready -- takes over the memory in ipoHttpResponse - void AddResponse ( HttpResponse * ipoHttpResponse ); - - /// returns address of connection - std::string GetAddress ( ) { return m_sAddress; } - - /// returns client port of connection - int GetPort ( ) { return m_nPort; } - - /// returns true of httprequestlist is not empty - int RequestsPending ( ) { return !m_oHttpRequestList.empty ( ); } - - /// returns underlying network abstraction - NetworkAbstraction * GetNetworkAbstraction ( ); - - // Send with retries - int TrySend ( const char * ipMessage, size_t inLength, int inFlags = 0 ); - -}; - - - -// predeclare because of circular reference between EHSServer and EHS -class EHSServer; - - -/// EHS provides HTTP server functionality to a child class -/** - * EHS provides HTTP server functionality to a child class. The child class - * must inherit from it and then override HandleRequest ( ). - */ -class EHS { - - protected: - - /// stores path => EHSConnection pairs for path/tree traversal - EHSMap oEHSMap; - - /// points to the EHS object this object was registered with, NULL if top level - EHS * poParent; - - /// the string that this EHS object is regestered as - std::string sRegisteredAs; - - /// EHSServer object associated with this EHS object - EHSServer * poEHSServer; - - /// source EHS object to route requests to for data instead of processing it ourselves - EHS * m_poSourceEHS; - - - public: - - /// default constructor that can set a parrent and a path name - EHS ( EHS * ipoParent = NULL, std::string isRegisteredAs = "" ); - - /// destructor - virtual ~EHS ( ); - - /// set the certificate file for use in HTTPS transactions - void SetCertificateFile ( std::string & irsCertificateFile ); - - /// set certificate passphrase - void SetCertificatePassphrase ( std::string & irsCertificatePassphrase ); - - /// sets a new passphrase callback function - void SetPassphraseCallback ( int ( * m_ipfOverridePassphraseCallback ) ( char *, int, int, void * ) ); - - /// sets the poParent member of this class to the specified EHS. This is how an EHS object can unregister itself on destruction - void SetParent ( EHS * ipoParent, std::string isRegisteredAs ); - - - /// Enumeration for error results for RegisterEHSResult - enum RegisterEHSResult { REGISTEREHSINTERFACE_INVALID = 0, - REGISTEREHSINTERFACE_ALREADYEXISTS, - REGISTEREHSINTERFACE_SUCCESS }; - - /// this associates an EHS object with this EHS object under the path ipsRegisterPath - RegisterEHSResult - RegisterEHS ( EHS * ipoEHS, - const char * ipsRegisterPath ); - - /// Enumeration for error results for UnregisterEHSResult - enum UnregisterEHSResult { UNREGISTEREHSINTERFACE_INVALID = 0, - UNREGISTEREHSINTERFACE_NOTREGISTERED, - UNREGISTEREHSINTERFACE_SUCCESS }; - - /// Unregister an EHS object from the specified path - UnregisterEHSResult - UnregisterEHS ( const char * ipsRegisterPath ); - - /// this is responsible for routing a request through the EHS tree and sending the request to the final destination. It returns the HttpResponse object to be sent back to the client - virtual HttpResponse * RouteRequest ( HttpRequest * ipoHttpRequest ); - - /// This function should be defined by the subclass - virtual HttpStatusCode HandleRequest(HttpRequest* ipoHttpRequest, - HttpResponse * ipoHttpResponse ); - - /// This function should be defined by the subclass - virtual void HttpPulse ( void ) {}; - - /// This function should be defined by the subclass - virtual bool ShouldAllowConnection ( const char * szAddress ) { return true; } - - /// makes this EHS object get its data from another EHS -- useful for having secure and normal connections share same data - void SetSourceEHS ( EHS & iroSourceEHS ); - - - /// result codes for StartServer and StartSErver_Threaded - enum StartServerResult { STARTSERVER_INVALID = 0, - STARTSERVER_SUCCESS, - STARTSERVER_NODATASPECIFIED, - STARTSERVER_ALREADYRUNNING, - STARTSERVER_SOCKETSNOTINITIALIZED, - STARTSERVER_THREADCREATIONFAILED, - STARTSERVER_FAILED }; - - - - /// stores a map with server parameters - EHSServerParameters m_oEHSServerParameters; - - - /// do everything needed to start server - StartServerResult StartServer ( EHSServerParameters & iroEHSServerParameters ); - - - /// brings down socket stuff. If StartServer_Threaded() was called it also stops that by setting the nServerStopped variable - void StopServer ( ); - - /// This looks for incoming connections in EHSServer. - void HandleData ( int inTimeoutMilliseconds = 0 ); - - static long long StaticGetTotalBytesSent ( void ); // For stats - static void StaticGetAllocationStats ( SAllocationStats& outAllocationStats ); -}; - - -class CThreadsSyncPoint -{ - int m_iHighestThreadIndex; - long long m_SyncId; - std::map m_SyncList; -public: - - CThreadsSyncPoint () - { - m_iHighestThreadIndex = -1; - m_SyncId = 0; - } - - long long GetSyncId () const - { - return m_SyncId; - } - - int GetNewThreadIndex () - { - return ++m_iHighestThreadIndex; - } - - void SyncThreadIndex( int iThreadIndex ) - { - m_SyncList[ iThreadIndex ] = 1; - if ( (int)m_SyncList.size() == m_iHighestThreadIndex ) - { - m_SyncId++; - m_SyncList.clear (); - } - } -}; - -/// EHSServer contains all the network functionality for EHS -/** - * EHSServer has all the network related services for EHS. It is responsible - * for accepting new connections and getting EHSConnection objects set up - */ -class EHSServer { - - public: - - /// consturctor for an EHSServer -- takes parameters out of ipoTopLevelEHS->m_oEHSServerParameters; - EHSServer ( EHS * ipoTopLevelEHS ); - virtual ~EHSServer ( ); - - /// removes the specified EHSConnection object, returns true if it actually found something to remove - int RemoveEHSConnection ( EHSConnection * ipoEHSConnection ); - - /// disconnects idle connections - int ClearIdleConnections ( ); - - /// removes all connections from the server that are no longer active - int RemoveFinishedConnections ( ); - - /// sets default http response headers, such as date, and content type - void InitHttpResponse ( HttpResponse * ipoHttpResponse ); - - /// stops the server - void EndServerThread ( char * ipsReason ); - - /// main function that deals with client connections and getting data - void HandleData ( int inTimeoutMilliseconds, pthread_t inThreadId ); - - /// check clients that are already connected - void CheckClientSockets ( ); - - /// check the listen socket for a new connection - void CheckAcceptSocket ( ); - - /// Enumeration on the current running status of the EHSServer - enum ServerRunningStatus { SERVERRUNNING_INVALID = 0, - SERVERRUNNING_NOTRUNNING, - SERVERRUNNING_SINGLETHREADED, - SERVERRUNNING_THREADPOOL, - SERVERRUNNING_ONETHREADPERREQUEST - }; - - /// Current running status of the EHSServer - ServerRunningStatus m_nServerRunningStatus; - - /// reason for shutting down - std::string m_sShutdownReason; - - /// this runs in a loop until told to stop by StopServer() -- runs off it's own thread created by StartServer_Threaded - void HandleData_Threaded ( ); - - /// pointer back up to top-most level EHS object - EHS * m_poTopLevelEHS; - - /// gets a pending request - HttpRequest * GetNextRequest ( ); - - /// whether we accepted a new connection last time through - int m_nAcceptedNewConnection; - - /// returns number of requests pending - int RequestsPending ( ) { return m_nRequestsPending; } - - /// increments the number of pending requests - void IncrementRequestsPending ( ) { m_nRequestsPending++; } - - /// mutex for controlling who is accepting or processing jobs - pthread_mutex_t m_oMutex; - - /// condition for when a thread is done accepting and there may be more jobs to process - pthread_cond_t m_oDoneAccepting; - - // Used to ensure all threads are past a certain point - CThreadsSyncPoint m_ThreadsSyncPoint; - - // Count of active threads - int m_iActiveThreadCount; - - /// static method for starting threaded mode -- pthreads can't start a thread on a normal member function, only static - static void * PthreadHandleData_ThreadedStub ( void * ipData ); - - - - protected: - - /// number of requests waiting to be processed - int m_nRequestsPending; - - - /// number of threads currently accepting (0 or 1) - int m_nAccepting; - - /// this is the server name sent out in the response headers - std::string sServerName; - - /// creates the poll array with the accept socket and any connections present - int CreateFdSet ( ); - - /// this is the read set for sending to select(2) - CPollFdSet m_oReadFds; - - /// List of all connections currently attached to the server - EHSConnectionList m_oEHSConnectionList; - - // List of all connections that are no longer used - EHSConnectionList m_oEHSConnectionUnusedList; - - /// the network abstraction this server is listening on - NetworkAbstraction * m_poNetworkAbstraction; - - /// pthread identifier for the accept thread -- only used when started in threaded mode - pthread_t m_nAcceptThreadId; - - /// number of seconds a connection can be idle before disconnect - int m_nIdleTimeout; - -}; - - - -// EHS_ASSERT() -// EHS_VERIFY() -// EHS_TRACE() - -// looks for needle in haystack -char * EHSMemMem ( const char * ipsHaystack, int inHaystackLength, - const char * ipsNeedle, int inNeedleLength ); - - -#ifdef _WIN32 -#define strcasecmp stricmp -#endif - -#define EHS_ASSERT assert - -#ifdef EHS_DEBUG -#define EHS_VERIFY(test) EHS_ASSERT(test) -#else -#define EHS_VERIFY(test) test -#endif - -#undef EHS_DEBUG -//#define EHS_DEBUG -inline void EHS_TRACE( const char* szFormat ... ) -{ -#ifdef EHS_DEBUG - - const int bufsize = 100000; - char buf [ bufsize ] ; - va_list VarList; - va_start( VarList, szFormat ); - int len = vsprintf(buf, szFormat, VarList ) ; - assert( len > 0 && len < bufsize ) ; - va_end ( VarList ) ; - //fprintf ( stderr, buf ) ; -#ifdef WIN32 - //OutputDebugString(buf) ; -// This would also work but requires more includes -// _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG ); -// _CrtDbgReport( _CRT_WARN, NULL, NULL, NULL, "%s", buf ); -#endif -#endif -} - - - -#define _STR(x) #x -#define EHS_TODO (_message) message (" *** TODO: " ##_message "\t\t\t\t" __FILE__ ":" _STR(__LINE__) ) -#define EHS_FUTURE (_message) message (" *** FUTURE: " ##_message "\t\t\t\t" __FILE__ ":" _STR(__LINE__) ) -#define EHS_TODOCUMENT (_message) message (" *** TODOCUMENT: " ##_message "\t\t\t\t" __FILE__ ":" _STR(__LINE__) ) -#define EHS_DEBUGCODE (_message) message (" *** DEBUG CODE (REMOVE!): " ##_message "\t\t\t\t" __FILE__ ":" _STR(__LINE__) ) - - - - -#endif // EHS_H - - diff --git a/vendor/ehs/ehs_development_guide.txt b/vendor/ehs/ehs_development_guide.txt deleted file mode 100644 index 6384e844d16..00000000000 --- a/vendor/ehs/ehs_development_guide.txt +++ /dev/null @@ -1,390 +0,0 @@ -Writing an EHS application ---------------------------- - - -Overview: ----------- - -EHS stands for Embedded HTTP Server and allows you to easily extend an existing -C++ class to have HTTP (web) server capabilities. - - -How to build EHS (for UNIX): ------------------- -./configure --with-ssl --with-debug --with-memory - ---with-ssl: compile with HTTPS support. Requires OpenSSL library installed. ---with-debug: prints out many debugging statements. Recommended when you first - build a new application, but rather spammy. ---with-memory: prints out internal memory tracking information. Mostly only - used for EHS internal development. - - -Requirements: --------------- -PCRE (Perl Compatible Regular Expressions) can be found at http://www.pcre.org. -EHS 1.1 was designed to work with version 4.3. Earlier and later versions -may work as well, but have not been tested. Later versions should be fine. - -PME (PCRE Made Easy) can be found at http://xaxxon.slackworks.com/pme - -OpenSSL is required for HTTPS support (./configure --with-ssl). It can be -found at http://www.openssl.org. - - -Writing a new program using EHS (or extending an existing one to use EHS) ----------------------------------------------------------------------------- - -The sample programs are probably your best bet for figuring out how to write an -EHS program. They can be found in the Samples subdirectory. - -ehs_simple.cpp: about the simplest program you can write. Shows how to use EHS -either single-threaded or multi-threaded. - -ehs_test.cpp: Example of writing a small program with each of the three -operation modes: singlethreaded, threadpool, onethreadperrequest. Presents one -line at a time from the file specified on the command line and stores the word -as a cookie in the browser to be shown on the next page loaded. Also sets up a -path hierarchy. - -ehs_https.cpp: same as ehs_simple, but creates an https connection. Only built -if configured with the --with-ssl option. - -ehs_testharness.cpp: shows how to return a custom response to the client. Also -used for unit testing EHS. - -ehs_formtest.cpp: shows how to get form data out of the HttpRequest object. -Runs in either HTTP or HTTPS mode based on command line arguments. - -ehs_mirror.cpp: shows how to bind more than one port to the same EHS object -using SetSourceEHS(). This example creates a custom EHS subclass and binds it -to an HTTP port, then it creates a normal EHS object, sets the custom EHS -subclass as its source, but binds to an HTTPS port. The returned page reports -whether or not the request was made over a secure connection. - -ehs_uploader.cpp: shows how to use multi-part form attachments to upload a file -from the client to the server. Useful for uploading configuration files to a -server or pictures to a web page. - - - - -* * Basics: ------------- - -Create an EHS object either statically or dynamically: -EHS oEHS; -EHS * poEHS = new EHS; - -Create a parameter list for the server: -EHSServerParameters oSP; -oSP [ "port" ] = 4000; -oSP [ "https" ] = [1]; (if the https parameter is not specified, it defaults to - off) -oSP [ "certificate" ] = "server.pem"; (only if you set https and you must - generate your own certificate. See the - CERTIFICATES section of this document - for help on generating your own - certificates) -oSP [ "passphrase" ] = "my_passphrase"; (only for https. Passphrase for your - server certificate) - -One of the following three must be specified (see Samples/ehs_test.cpp for -examples on using each of the three modes) - -oSP [ "mode" ] = "singethreaded" -- no dedicated thread for processing. Main - process must call EHS::HandleData() in - order for web requests to be processed. - -oSP [ "mode" ] = "threadpool" -- a set of dedicated threads will be set up for - handling web requests. oSP [ "threadcount" ]= - may be specified to set - the number of threads in the pool. The - default is 1. Note that setting this number - too high (>100?) may result in poor - performance. - -oSP [ "mode" ] = "onethreadperrequest" -- each time a request comes in, a new - thread is created. When the request - has been processed, the thread is - destroyed. This is *not* a good mode - for dealing with lots of small - requests. If you have bursts of - requests that can take a long time - (more than a few seconds), this may - be a good mode. (I recommend being - very careful with this. If you get - hit hard, it may bring your entire - system to a crawl with lots of - threads being spawned.) - -oSP [ "norouterequest" ] = "1" -- means to disregard trying to route requests - through different EHS objects based on path. - All requests will go to the EHS object that - had StartServer called on it. You can still - call RegisterEHS ( ) to set up a hierarchy, - but child EHS objects will never be called. - - -Start your server: -oEHS.StartServer ( oSP ); -poEHS->StartServer ( oSP ); - -Now whenever you point a web browser at your specified port (4000 in above example), it will display the current time since the epoch. - - -Returning Custom Pages -------------------------------- - -To return a custom page, you must subclass the EHS object and override -HandleRequest(...). - -class MyEHS : public EHS { - - HttpResponse HandleRequest ( HttpRequest * ipoHttpRequest, - HttpResponse * ipoHttpResponse ) { - - HttpResponse->SetBody ( "Hello, HTTP World!", - strlen ( "Hello, HTTP World!" ) ); - return HTTPRESPONSECODE_200_OK; - - } - -} - -The preceeding code will send the string "Hello, HTTP World!" with a 200 (OK) -response code to the client. - -The full list of response codes is in httpresponse.h. - - -Creating a virtual directory structure: ----------------------------------------- - -See Samples/ehs_test.cpp for an example of this. - -NOTE: If the "norouterequest" option is sent to the server, the following - code will NOT behave as described below. In this case, no matter what - the requested path, the A object will handle the request. The following - is the default behavior. - -With EHS you can create class hierarchies that EHS automatically traverses -based on the URL requested. To do this, create multiple objects of classes -that inherit from EHS. Say they are variables A, B, and C. To set up B as a -child of A with a path name of "childb", and then C as a child of B with a path -name of "childc", do - -the following: - -MyEhsClass A, B, C; - -A->RegisterEHS ( &B, "childb" ); -B->RegisterEHS ( &C, "childc" ); - -To have a request sent automatically to the B object, create a URL similar to -the following: - -http://myserver.com/childb/ - -To have a request sent automatically to the C object, create a URL similar to -the following: - -http://myserver.com/childb/childc/ - -Note that the trailing / is required, as otherwise it doesn't denote a -directory, it denotes a file. - - -Multi-part form attachments: ------------------------------ - -See Samples/ehs_uploader.cpp for an example of how to use this feature. - - -Cookies ( as specified in RFC-2109 ): --------------------- - -See: ehs_test.cpp for an example on using cookies. - -Incoming: -EHS will break out cookies for you into the HttpRequest object's oCookieMap -member. The key of the map is the name of the cookie and the value of the map -is the value of the cookie. Pretty simple. - -Outgoing: -To set a cookie into a user's browser, set a CookieParameter object with the -following fields: - -The following fields are valid (required as noted): -Name (required): Name of the cookie -Value (required): Value of the cookie -Comment: Comment on the cookie. For client-side use only -CommentURL: URL specifying a comment on the cookie. -Discard: Discard unconditionally when the user-agent terminates -Domain: Domain for which the cookie is valid -Max-Age: lifetime of the cookie in seconds (time from now, not since epoch) -Path: subset of URLs to which this cookie applies -Port: specifies teh port for which the cookie may be returned. Requires quotes - around the port list, but that will be added if not specified. -Secure: Has no value -- if specified, cookie should only be sent over secure - connection. Client decides what is secure or not. -Version (required, but set to 1 if not specified): what version of state - management specification to which the cookie conforms. - 1 is the current. - -For example: - -CookieParameters oCP; -oCP["name"]="mycookie"; -oCP["value"]="myvalue"; -oCP["max-age"]=60; // makes the cookie last a minute from now - -Then call HttpResponse::SetCookie ( CookieParameters & ); - -as in: - -ipoHttpResponse->SetCookie ( oCP ); - -For an actual example, see Samples/ehs_test.cpp. - - - -HTTPS: ------------- - -See Samples/ehs_https.cpp for an example of how to use this feature and see the -section in this document called "Certificates" for information on how to create -a certificate for HTTPS. A certificate is REQUIRED for running an HTTPS -server. - - -Certificates: --------------- -In order to use HTTPS, you must first have a server certificate to send to the -client. This is how the server process that it is who it says it is and starts -the cryptography. - -Generating a server certificate is not a quick process and involves a number of -steps. The following is an example of how to make a server certificate that -will allow an HTTPS connection to be established. - -NOTE: I am not a certificate or crypto expert. These steps work for me but I -don't promise that it's the right way to do it. - -Creating a root CA: -A CA is a Certificate Authority. Verisign is an example of a CA. This is the -base certificate that is used to verify all levels beneath it. This -certificate should ideally be distributed securely to the clients. This is -commonly done with the browser, but we don't have that option. When you -initially connect the browser to your HTTPS server, it will loudly complain -that the certificate cannot be verified. If you pay for a Versign (or other -standard certificate authority) to sign your certificate, this won't happen. - -> openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out rootreq.pem -This generates a new certificate request and a new private key. - -newkey rsa:1024 creates a 1024-bit private key - -sha1 specifies the message digest with which to sign the request - -keyout rootkey.pem specifies the filename to write the private key to - -out rootreq.pem specifies the file to write output to (the certificate - request) - -Answer all the questions it gives you. - -> openssl x509 -req -in rootreq.pem -sha1 -extensions v3_ca -signkey - rootkey.pem -out rootcert.pem - - -req says a certificate request instead of an actual certificate will be - provided (what we created in the previous step) - -in rootreq.pem specifies the input filename from which to read a certificate - request - -sha1 specifies the digest to use. - -extensions v3_ca is required for self-signed CA certificates - -signkey rootkey.pem says to sign this certificate using our previously - generated private key - -out rootcert.pem writes our certificate out to rootcert.pem - -> cat rootcert.pem rootkey.pem > root.pem - -This puts the new certificate along with our encrypted private key into a -single file. - - -Creating a server CA and signing it with our root CA: -Now that we have a root CA, we need a server CA. I don't know why/if you have -to do this, but if you do this, it will work. Basically we're going to do the -same thing we just did, but with some different filenames. - -> openssl req -newkey rsa:1024 -sha1 -keyout serverCAkey.pem -out - serverCAreq.pem -Answer all the same questions again. - -> openssl x509 -req -in serverCAreq.pem -sha1 -extensions v3_ca -CA root.pem - -CAkey root.pem -CAcreateserial -out serverCAcert.pem - - -CA root.pem specifies the CA certificate to be used for signing. x509 - behaves like a 'mini CA' - -CAkey root.pem specifies the CA private key to sign the certificate with. - (not necessary?) - -CAcreateserial creates CA serial number file if it does not exist. - -> cat serverCAcert.pem serverCAkey.pem rootcert.pem > serverCA.pem - - -Now we actually create the server's certificate and sign it with the server CA. -This is the certificate we will actually load into EHS to send to the client. -Again, it looks an awful lot like the stuff we've done before. - -> openssl req -newkey rsa:1024 -sha1 -keyout serverkey.pem -out serverreq.pem - -> openssl x509 -req -in serverreq.pem -sha1 -extensions usr_cert -CA - serverCA.pem -CAkey serverCA.pem -CAcreateserial -out servercert.pem - -Note that we're using a different extension here: usr_cert. - -> cat servercert.pem serverkey.pem serverCAcert.pem rootcert.pem > server.pem - -The file, 'server.pem', is what we send to EHS in the 'certificate' parameter. -The passphrase set for in this last step will be the passphrase you will pass -into EHS. - - -ehs-stress.pl --------------- - -ehs-stress is a tool contributed by Michal Pleban for creating many -simulataneous HTTP requests. It creates multiple processes, each of which -stream multiple HTTP requests to a web server (EHS or other). It can either -connect once per request, or use the same connection for all requests from -each process (-k option). - -Note: Apache bench (ab) does similar things, but I've never been able to make - it work properly. ab 2.0.40 doesn't seem to like the reply from EHS, - but it also hangs against my Apache server, as well, so I don't put - much faith in it. Any input here would be appreciated, especially - if EHS's behaviour is incorrect in some way. - -Usage: ehs-stress.pl hostname:port [-p ] [-c ] [-k] - -p: specifies number of processes to run. Each does requests - Default: 10 - -c: specifies how many requests each process should do. Default: 10 - -k: keep-alive. Use persistent connections. Default: No - - -ehs-stress was contributed by Michal Pleban. It requires you to install some -perl modules. This is most easily accomplished as root. It can be done as a -normal user, but I don't know how, so I'll just describe how to do it as root: -Note: You may have these installed. Just try running it. If it works, you - already have them and should skip the install described below. - -su - -perl -MCPAN -e shell - - -install LWP::UserAgent - - - - -And that should do it. \ No newline at end of file diff --git a/vendor/ehs/ehstypes.h b/vendor/ehs/ehstypes.h deleted file mode 100644 index cae4fb3822f..00000000000 --- a/vendor/ehs/ehstypes.h +++ /dev/null @@ -1,60 +0,0 @@ - -#ifndef EHSTYPES_H -#define EHSTYPES_H - -#include -#include -#include - -#ifndef DEFINED_SHARED_UTIL - #include "SharedUtil.h" -#endif -class EHSConnection; -class EHS; -class Datum; -class FormValue; -class HttpResponse; -class HttpRequest; - -/// generic std::string => std::string map used by many things -typedef std::map < std::string, std::string > StringMap; - -/// generic list of std::strings -typedef std::list < std::string > StringList; - -/// Define a list of EHSConnection objects to handle all current connections -typedef std::list < EHSConnection * > EHSConnectionList; - -// map for registered EHS objects on a path -typedef std::map < std::string, EHS * > EHSMap; - -/// map type for storing EHSServer parameters -typedef std::map < std::string, Datum > EHSServerParameters; - -/// cookies that come in from the client, mapped by name -typedef std::map < std::string, std::string > CookieMap; - -/// describes a form value that came in from a client -typedef std::map < std::string, FormValue > FormValueMap; - -/// describes a cookie to be sent back to the client -typedef std::map < std::string, Datum > CookieParameters; - -/// holds respose objects not yet ready to send -typedef std::map < int, HttpResponse * > HttpResponseMap; - -/// holds a list of pending requests -typedef std::list < HttpRequest * > HttpRequestList; - - -struct SAllocationStats -{ - unsigned int uiActiveNumRequests; - unsigned int uiActiveNumResponses; - unsigned int uiActiveKBAllocated; - unsigned int uiTotalNumRequests; - unsigned int uiTotalNumResponses; - unsigned int uiTotalKBAllocated; -}; - -#endif diff --git a/vendor/ehs/formvalue.h b/vendor/ehs/formvalue.h deleted file mode 100644 index 731c00504ec..00000000000 --- a/vendor/ehs/formvalue.h +++ /dev/null @@ -1,69 +0,0 @@ - -#ifndef FORMVALUE_H -#define FORMVALUE_H - -#include -#include - -#include "contentdisposition.h" - -/// This is how data is passed in from the client has to be more complicated because of metadata associated with MIME-style attachments -/** - * This is how data is passed in from the client has to be more complicated because of metadata - * associated with MIME-style attachments. Each element of a form is put into a ContentDisposition - * object which can be looked at in HandleRequest to see what data might have been sent in. - */ -class FormValue { - - public: - - /// for MIME attachments only, normal header information like content-type -- everything except content-disposition, which is in oContentDisposition - StringMap oFormHeaders; - - /// everything in the content disposition line - ContentDisposition oContentDisposition; - - /// the body of the value. For non-MIME-style attachments, this is the only part used. - std::string sBody; - - /// Default constructor - FormValue ( ) { -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: FormValue\n" ); -#endif - } - - /// Constructor - FormValue ( std::string & irsBody, ///< body for the form value - ContentDisposition & ioContentDisposition ///< content disposition type string - ) : - oContentDisposition ( ioContentDisposition ), - sBody ( irsBody ) { -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: FormValue\n" ); -#endif - } - - /// Constructor - explicit FormValue(std::string_view body) : sBody{body} - { - } - -#ifdef EHS_MEMORY - /// This is only for watching memory allocation - FormValue ( const FormValue & iroFormValue ) { - *this = iroFormValue; - fprintf ( stderr, "[EHS_MEMORY] Allocated: FormValue (Copy Constructor)\n" ); - } -#endif - - /// destructor - virtual ~FormValue ( ) { -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: FormValue\n" ); -#endif - } - -}; - -#endif // FORMVALUE_H diff --git a/vendor/ehs/httprequest.cpp b/vendor/ehs/httprequest.cpp deleted file mode 100644 index fd7075a2f7d..00000000000 --- a/vendor/ehs/httprequest.cpp +++ /dev/null @@ -1,722 +0,0 @@ - -#include "httprequest.h" -#include "stats.h" - -#include - -void HttpRequest::ParseRequestURI(std::string_view uri) -{ - if (uri.empty()) - return; - - // See: https://www.rfc-editor.org/rfc/rfc3986#section-3.4 - if (size_t queryDelimiter = uri.find_first_of("?&"); queryDelimiter != std::string_view::npos) - { - // Skip repeating '?' (question mark) and '&' (ampersand) characters after the first one. - if (queryDelimiter = uri.find_first_not_of("?&", queryDelimiter + 1); queryDelimiter == std::string_view::npos) - return; - - std::string_view parameters = uri.substr(queryDelimiter); - - // Discard any trailing fragment. - if (size_t fragmentDelimiter = parameters.find('#'); fragmentDelimiter != std::string_view::npos) - { - parameters = parameters.substr(0, fragmentDelimiter); - } - - // Limit request uri parameters to 4096 bytes. - if (parameters.length() > 4096) - { - parameters = parameters.substr(0, 4096); - } - - // According to the RFC, query can be anything, but this web server implementation only supports "key=value" pairs, - // which are parsable as form data. - ParseFormData(parameters, true); - } -} - -void HttpRequest::ParseFormData(std::string_view formData, bool isQueryData) -{ - size_t counter = 0; - - // Limit the maximum acceptable form data fields to 256. - while (!formData.empty() && counter < 256) - { - std::string_view parameter; - - if (size_t delimiter = formData.find('&'); delimiter != std::string_view::npos) - { - parameter = formData.substr(0, delimiter); - - // Skip repeating '&' (ampersand) characters after the first one. - if (delimiter = formData.find_first_not_of('&', delimiter + 1); delimiter != std::string_view::npos) - { - formData = formData.substr(delimiter); - } - else - { - formData = {}; - } - } - else - { - parameter = formData; - formData = {}; - } - - if (!parameter.empty()) - { - std::string_view key, value; - - if (size_t delimiter = parameter.find('='); delimiter != std::string_view::npos) - { - key = parameter.substr(0, delimiter); - - // Skip repeating '=' (equals) characters after the first one. - if (delimiter = parameter.find_first_not_of('=', delimiter + 1); delimiter != std::string_view::npos) - { - value = parameter.substr(delimiter); - } - } - else - { - key = parameter; - // NOTE: value is empty. - } - - if (!key.empty()) - { - oFormValueMap[std::string{key}] = FormValue{value}; - - if (isQueryData) - { - oQueryValueMap[std::string{key}] = FormValue{value}; - } - } - } - - counter += 1; - } -} - -// this parses a single piece of a multipart form body -// here are two examples -- first is an uploaded file, second is a -// standard text box html form -/* - -----------------------------7d2248207500d4 - Content-Disposition: form-data; name="DFWFilename2"; filename="C:\Documents and Settings\administrator\Desktop\contacts.dat" - Content-Type: application/octet-stream - - Default Screen Name - -----------------------------7d2248207500d4 - - - -----------------------------7d2248207500d4 - Content-Disposition: form-data; name="foo" - - asdfasdf - -----------------------------7d2248207500d4 -*/ - - -HttpRequest::ParseSubbodyResult HttpRequest::ParseSubbody ( std::string isSubbody ///< string in which to look for subbody stuff - ) -{ - - // find the spot after the headers in the body - std::string::size_type nBlankLinePosition = isSubbody.find ( "\r\n\r\n" ); - - // if there's no double blank line, then this isn't a valid subbody - if ( nBlankLinePosition == std::string::npos ) { - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEUBG] Invalix subbody, couldn't find double blank line\n" ); -#endif - return PARSESUBBODY_INVALIDSUBBODY; - - } - - // create a string from the beginning to the blank line -- OFF BY ONE? - std::string sHeaders ( isSubbody, 0, nBlankLinePosition - 1 ); - - - // first line MUST be the content-disposition header line, so that - // we know what the name of the field is.. otherwise, we're in trouble - - - - int nMatchResult = 0; - PME oContentDispositionRegex ( "Content-Disposition:[ ]?([^;]+);[ ]?(.*)" ); - - nMatchResult = oContentDispositionRegex.match ( sHeaders ); - - - if ( nMatchResult == 3 ) { - - - std::string sContentDisposition ( oContentDispositionRegex [ 1 ] ); - std::string sNameValuePairs ( oContentDispositionRegex [ 2 ] ); - -/* fprintf ( stderr, "cont. disp. '%s', name/value pairs '%s'\n", - sContentDisposition.c_str ( ), - sNameValuePairs.c_str ( ) ); -*/ - StringMap oStringMap; - - - - PME oContentDispositionNameValueRegex ( "[ ]?([^= ]+)=\"([^\"]+)\"[;]?", "g" ); - - - // go through the sNameValuePairs string and grab out the pieces - nMatchResult = 3; - - while ( nMatchResult == 3 ) { - - nMatchResult = oContentDispositionNameValueRegex.match ( sNameValuePairs ); - if ( nMatchResult == 3 ) { - - std::string sName = oContentDispositionNameValueRegex [ 1 ]; - std::string sValue = oContentDispositionNameValueRegex [ 2 ]; - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Info: Subbody header found: '%s' => '%s' with %d matches\n", - sName.c_str ( ), - sValue.c_str ( ), - nMatchResult ); -#endif - - oStringMap [ sName ] = sValue; - - } else if ( nMatchResult == 0 ) { - ; // this is okay -- just done with name value pairs - } else { - //fprintf ( stderr, "Unexpected number of matches, '%d' != 3\n", nMatchResult ); - assert ( 0 ); - } - - //fprintf ( stderr, "nMatchResult = %d\n", nMatchResult ); - - - } - -// fprintf ( stderr, "done looking for headers\n" ); - - // take oStringMap and actually fill the right object with its data - FormValue & roFormValue = oFormValueMap [ oStringMap [ "name" ] ]; - - // copy the headers in now that we know the name - roFormValue.oContentDisposition.oContentDispositionHeaders = oStringMap; - - // grab out the body - roFormValue.sBody = isSubbody.substr ( nBlankLinePosition + 4); - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Info: Subbody body (in binary):\n---\n" ); - fwrite ( roFormValue.sBody.c_str ( ), 1, roFormValue.sBody.length ( ), stderr ); - fprintf ( stderr, "\n---\n" ); -#endif - - } - // couldn't find content-disposition line -- FATAL ERROR - else { - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Error: Couldn't find content-disposition line\n" ); -#endif - return PARSESUBBODY_INVALIDSUBBODY; - - } - - - - - return PARSESUBBODY_SUCCESS; - -} - - - - - -HttpRequest::ParseMultipartFormDataResult -HttpRequest::ParseMultipartFormData ( ) -{ - - assert ( !oRequestHeaders [ "content-type" ].empty ( ) ); - - - // find the boundary string - int nMatchResult = 0; - - PME oMultipartFormDataContentTypeValueRegex ( "multipart/[^;]+;[ ]*boundary=([^\"]+)$" ); - -#ifdef EHS_DEBUG - fprintf ( stderr, "looking for boundary in '%s'\n",oRequestHeaders [ "content-type" ].c_str ( ) ); -#endif - - if ( ( nMatchResult = oMultipartFormDataContentTypeValueRegex.match ( oRequestHeaders [ "content-type" ] ) ) ) { - - - assert ( nMatchResult == 2 ); - - std::string sBoundaryString = oMultipartFormDataContentTypeValueRegex [ 1 ]; - - - // the actual boundary has two dashes prepended to it - std::string sActualBoundary = std::string ("--") + sBoundaryString; - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Info: Found boundary of '%s'\n", sBoundaryString.c_str ( ) ); - fprintf ( stderr, "[EHS_DEBUG] Info: Looking for boundary to match (%d) '%s'\n", sBody.length ( ), - sBody.substr ( 0, sActualBoundary.length ( ) ).c_str ( ) ); -#endif - - - // check to make sure we started at the boundary - if ( sBody.substr ( 0, sActualBoundary.length ( ) ) != sActualBoundary ) { -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Error: Misparsed multi-part form data for unknown reason - first bytes weren't the boundary string\n" ); -#endif - return PARSEMULTIPARTFORMDATA_FAILED; - - } - - - // go past the initial boundary - std::string sRemainingBody = sBody.substr ( sActualBoundary.length ( ) ); - - // while we're at a boundary after we grab a part, keep going - std::string::size_type nNextPartPosition; - - - while ( ( nNextPartPosition = sRemainingBody.find ( std::string ( "\r\n" ) + sActualBoundary ) ) != - std::string::npos ) { - - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Info: Found subbody from pos %d to %d\n", - 0, nNextPartPosition ); -#endif - - assert ( (unsigned int) sRemainingBody.length ( ) >= sActualBoundary.length ( ) ); - - ParseSubbody ( sRemainingBody.substr ( 0, nNextPartPosition ) ); - - // skip past the boundary at the end and look for the next one - nNextPartPosition += sActualBoundary.length ( ); - - sRemainingBody = sRemainingBody.substr ( nNextPartPosition ); - - } - - } else { - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Error: Couldn't find boundary specification in content-type header\n" ); -#endif - return PARSEMULTIPARTFORMDATA_FAILED; - } - - return PARSEMULTIPARTFORMDATA_SUCCESS; - -} - -// A cookie header looks like: Cookie: username=xaxxon; password=comoesta -// everything after the : gets passed in in irsData -int HttpRequest::ParseCookieData ( std::string & irsData ) -{ - -#ifdef EHS_DEBUG - fprintf ( stderr, "looking for cookies in '%s'\n", irsData.c_str ( ) ); -#endif - - PME oCookieRegex ( "\\s*([^=]+)=([^;]+)(;|$)*", "g" ); - - int nNameValuePairsFound = 0; - - while ( oCookieRegex.match ( irsData ) ) { - -/* fprintf ( stderr, "mapping cookie data: %s => %s\n", - oCookieRegex [ 1 ].c_str ( ), - oCookieRegex [ 2 ].c_str ( ) ); -*/ - oCookieMap [ oCookieRegex [ 1 ] ] = oCookieRegex [ 2 ]; - nNameValuePairsFound++; - - } - - return nNameValuePairsFound; - -} - - - -// takes data and tries to figure out what it is. it will loop through -// irsData as many times as it can as long as it gets a full line each time. -// Depending on how much data it's gotten already, it will handle a line -// differently.. -HttpRequest::HttpParseStates HttpRequest::ParseData ( std::string & irsData ///< buffer to look in for more data - ) -{ - - - std::string sLine; - - int nDoneWithCurrentData = 0; - - PME oHeaderRegex ( "^([^:]*):\\s+(.*)\\r\\n$" ); - - while ( ! nDoneWithCurrentData && - nCurrentHttpParseState != HTTPPARSESTATE_INVALIDREQUEST && - nCurrentHttpParseState != HTTPPARSESTATE_COMPLETEREQUEST && - nCurrentHttpParseState != HTTPPARSESTATE_INVALID ) { - - switch ( nCurrentHttpParseState ) { - - case HTTPPARSESTATE_REQUEST: - - // get the request line - GetNextLine ( sLine, irsData ); - - // if we got a line, parse out the data.. - if ( sLine.length ( ) == 0 ) { - - nDoneWithCurrentData = 1; - - } - // if we got a line, look for a request line - else { - - // everything must be uppercase according to rfc2616 - PME oRequestLineRegex ( "^(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH) ([^ ]*) HTTP/([^ ]+)\\r\\n$" ); - - if ( oRequestLineRegex.match ( sLine ) ) { - - // get the info from the request line - nRequestMethod = GetRequestMethodFromString ( oRequestLineRegex [ 1 ] ); - sUri = oRequestLineRegex [ 2 ]; - sOriginalUri = oRequestLineRegex [ 2 ]; - sHttpVersionNumber = oRequestLineRegex [ 3 ]; - - - // check to see if the uri appeared to have form data in it - ParseRequestURI(sUri); - - // on to the headers - nCurrentHttpParseState = HTTPPARSESTATE_HEADERS; - - } - // if the regex failed - else { - - nCurrentHttpParseState = HTTPPARSESTATE_INVALIDREQUEST; - - } // end match on request line - - } // end whether we got a line - - break; - - case HTTPPARSESTATE_HEADERS: - - // get the next line - GetNextLine ( sLine, irsData ); - - // if we didn't get a full line of data - if ( sLine.length ( ) == 0 ) { - - nDoneWithCurrentData = 1; - - } - // check to see if we're done with headers - else if ( sLine == "\r\n" ) { - - // if content length is found - if ( oRequestHeaders.find ( "content-length" ) != - oRequestHeaders.end ( ) ) { - - nCurrentHttpParseState = HTTPPARSESTATE_BODY; - - } else { - - - nCurrentHttpParseState = HTTPPARSESTATE_COMPLETEREQUEST; - - } - - // if this is an HTTP/1.1 request, then it had better have a Host: header - if ( sHttpVersionNumber == "1.1" && - oRequestHeaders [ "host" ].length ( ) == 0 ) { - - nCurrentHttpParseState = HTTPPARSESTATE_INVALIDREQUEST; - - } - - } - // else if there is still data - else if ( oHeaderRegex.match ( sLine ) ) { - - std::string sName = oHeaderRegex [ 1 ]; - std::string sValue = oHeaderRegex [ 2 ]; - - if ( sName == "Transfer-Encoding" && - sValue == "chunked" ) { - -#ifdef EHS_DEBUG - fprintf ( stderr, "EHS DOES NOT SUPPORT CHUNKED ENCODING. Send an email to xaxxon@slackworks.com and tell him you want chunked encoding (or send a patch)\n" ); -#endif - nCurrentHttpParseState = HTTPPARSESTATE_INVALIDREQUEST; - - } - - sName = mytolower ( sName ); - - if ( sName == "cookie" ) { - - ParseCookieData ( sValue ); - - } - - oRequestHeaders [ sName ] = sValue; - - - - } - // else we had some sort of error -- bail out - else { - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Error: Invalid header line: '%s'\n", - sLine.c_str ( ) ); -#endif - - nCurrentHttpParseState = HTTPPARSESTATE_INVALIDREQUEST; - nDoneWithCurrentData = 1; - - } - - break; - - - case HTTPPARSESTATE_BODY: - { - - // if a content length wasn't specified, we can't be here (we - // don't know chunked encoding) - if ( oRequestHeaders.find ( "content-length" ) == - oRequestHeaders.end ( ) ) { - - nCurrentHttpParseState = HTTPPARSESTATE_INVALIDREQUEST; - continue; - - } - - // get the content length - unsigned int nContentLength = - atoi ( oRequestHeaders [ "content-length" ].c_str ( ) ); - - // else if we haven't gotten all the data we're looking for, - // just hold off and try again when we get more - if ( irsData.length ( ) < nContentLength ) { - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Info: Not enough data yet -- %d < %d\n", - irsData.length ( ), nContentLength ); -#endif - nDoneWithCurrentData = 1; - - } - // otherwise, we've gotten enough data from the client, handle it now - else { - - // grab out the actual body from the request and leave the rest - sBody = irsData.substr ( 0, nContentLength ); - - irsData = irsData.substr ( nContentLength ); - - - // if we're dealing with multi-part form attachments - if ( oRequestHeaders [ "content-type" ].substr ( 0, 9 ) == - "multipart" ) { - - // handle the body as if it's multipart form data - if ( ParseMultipartFormData ( ) == - PARSEMULTIPARTFORMDATA_SUCCESS ) { - - nCurrentHttpParseState = HTTPPARSESTATE_COMPLETEREQUEST; - - } else { - -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Error: Mishandled multi-part form data for unknown reason\n" ); -#endif - nCurrentHttpParseState = HTTPPARSESTATE_INVALIDREQUEST; - - } - - - } - // else the body is just one piece - else { - // check for any form data - ParseFormData(sBody, false); - -#ifdef EHS_DEBUG - fprintf ( stderr, "Done with body, done with entire request\n" ); -#endif - - nCurrentHttpParseState = HTTPPARSESTATE_COMPLETEREQUEST; - } - - } - - nDoneWithCurrentData = 1; - - } - - break; - - - case HTTPPARSESTATE_INVALID: - default: -#ifdef EHS_DEBUG - fprintf ( stderr, "[EHS_DEBUG] Critical error: Invalid internal state: %d. Aborting\n", nCurrentHttpParseState ); -#endif - assert ( 0 ); - break; - } - } - - return nCurrentHttpParseState; - -} - - - - - -//////////////////////////////////////////////////////////////////// -// HTTP REQUEST -// -//////////////////////////////////////////////////////////////////// - - -HttpRequest::HttpRequest ( int inRequestId, - EHSConnection * ipoSourceEHSConnection ) : - nCurrentHttpParseState ( HTTPPARSESTATE_REQUEST ), - nRequestMethod ( REQUESTMETHOD_UNKNOWN ), - sUri ( "" ), - sHttpVersionNumber ( "" ), - m_nRequestId ( inRequestId ), - m_poSourceEHSConnection ( ipoSourceEHSConnection ) -{ - StatsNumRequestsInc(); - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: HttpRequest\n" ); -#endif - if ( m_poSourceEHSConnection == NULL ) { -#ifdef EHS_DEBUG - fprintf ( stderr, "Not allowed to have null source connection\n" ); -#endif - exit ( 2 ); - } -} - -HttpRequest::~HttpRequest ( ) -{ -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: HttpRequest\n" ); -#endif - StatsNumRequestsDec(); -} - - -// HELPER FUNCTIONS - -// Takes a char* buffer and grabs a line off it, puts the new line in irsLine -// and shrinks the buffer by the size of the line and sets ipnBufferLength to -// the new size - -// returns 1 if it got a line, 0 otherwise -int GetNextLine ( std::string & irsLine, ///< line removed from *ippsBuffer - std::string & irsBuffer ///< buffer from which to remove a line - ) -{ - - int nResult = 0; - - // can't use split, because we lose our \r\n - PME oLineRegex ( "^([^\\r]*\\r\\n)(.*)$", "sm" ); - - if ( oLineRegex.match ( irsBuffer ) == 3 ) { - - irsLine = oLineRegex [ 1 ]; - irsBuffer = oLineRegex [ 2 ]; - - } else { - - irsLine = ""; - - } - - return nResult; - -} - - -/// List of possible HTTP request methods -const char * RequestMethodStrings [] = { "OPTIONS", "GET", "HEAD", "POST", - "PUT", "DELETE", "TRACE", "CONNECT", "PATCH", "*"}; - - -RequestMethod GetRequestMethodFromString ( const std::string & isRequestMethod ///< determine the request type enumeration from the request string - ) -{ - - int i = 0; - - for ( i = 0; i < REQUESTMETHOD_LAST; i++ ) { - - if ( isRequestMethod == RequestMethodStrings [ i ] ) { - - break; - - } - - } - - return ( RequestMethod ) i; - -} - -std::string & mytolower (std::string & s ///< string to make lowercase - ) -{ - std::transform ( s.begin(), s.end(), s.begin(), [](char c) { return std::tolower(c); }); - return s; - -} - - -std::string HttpRequest::GetAddress ( ) -{ - - return m_poSourceEHSConnection->GetAddress ( ); - -} - -int HttpRequest::GetPort ( ) -{ - - return m_poSourceEHSConnection->GetPort ( ); - -} - - -int HttpRequest::ClientDisconnected ( ) -{ - return m_poSourceEHSConnection->Disconnected ( ); -} diff --git a/vendor/ehs/httprequest.h b/vendor/ehs/httprequest.h deleted file mode 100644 index b1fa53248b7..00000000000 --- a/vendor/ehs/httprequest.h +++ /dev/null @@ -1,162 +0,0 @@ - -#ifndef HTTPREQUEST_H -#define HTTPREQUEST_H - - -#ifdef _WIN32 -#pragma warning(disable : 4786) -#endif - -#include -#include - -#include - -#include "ehs.h" -#include "ehstypes.h" -#include "formvalue.h" - - -/// UNKNOWN must be the last one, as these must match up with RequestMethodStrings *exactly* -enum RequestMethod { REQUESTMETHOD_OPTIONS, /* not implemented */ - REQUESTMETHOD_GET, - REQUESTMETHOD_HEAD, - REQUESTMETHOD_POST, - REQUESTMETHOD_PUT, ///< not implemented - REQUESTMETHOD_DELETE, ///< not implemented - REQUESTMETHOD_TRACE, ///< not implemented - REQUESTMETHOD_CONNECT, ///< not implemented - REQUESTMETHOD_PATCH, ///< not implemented - REQUESTMETHOD_LAST, ///< must be the last valid entry - REQUESTMETHOD_UNKNOWN, ///< used until we find the method - REQUESTMETHOD_INVALID ///< must be the last entry -}; - -/// this holds a list of strings corresponding to the order of the RequestMethod enumeration -extern const char * RequestMethodStrings []; - -/// This is what the client sent in a more organized form -/** - * This is what the client sent in a more organized form. It has any form - * data, header information, the request type - */ -class HttpRequest { - - public: - - /// constructor - HttpRequest ( int inRequestId, - EHSConnection * ipoSourceEHSConnection ); - - /// destructor - virtual ~HttpRequest ( ); - - /// Enumeration for the state of the current HTTP parsing - enum HttpParseStates { HTTPPARSESTATE_INVALID = 0, - HTTPPARSESTATE_REQUEST, - HTTPPARSESTATE_HEADERS, - HTTPPARSESTATE_BODY, - HTTPPARSESTATE_COMPLETEREQUEST, - HTTPPARSESTATE_INVALIDREQUEST, -}; - - /// Enumeration of error codes for ParseMultipartFormDataResult - enum ParseMultipartFormDataResult { - PARSEMULTIPARTFORMDATA_INVALID = 0, - PARSEMULTIPARTFORMDATA_SUCCESS, - PARSEMULTIPARTFORMDATA_FAILED - }; - - /// treats the body as if it's a multipart form data as specified in RFC not sure what the number is and I'll probably forget to look it up - ParseMultipartFormDataResult ParseMultipartFormData ( ); - - /// Enumeration of error codes for ParseSubbody - enum ParseSubbodyResult { - PARSESUBBODY_INVALID = 0, - PARSESUBBODY_SUCCESS, - PARSESUBBODY_INVALIDSUBBODY, // no blank line? - PARSESUBBODY_FAILED // other reason - - }; - - /// goes through a subbody and parses out elements - ParseSubbodyResult ParseSubbody ( std::string sSubBody ); - - - /// this function is given data that is read from the client and it deals with it - HttpParseStates ParseData ( std::string & irsData ); - - /// takes the cookie header and breaks it down into usable chunks -- returns number of name/value pairs found - int ParseCookieData ( std::string & irsData ); - - /// parses the request uri, extracts the query segment and puts its key=value pairs into oFormElements - void ParseRequestURI(std::string_view uri); - - /// parses the form data as if it's key=value pairs and puts them into oFormElements - void ParseFormData(std::string_view formData, bool isQueryData); - - /// the current parse state -- where we are in looking at the data from the client - HttpParseStates nCurrentHttpParseState; - - /// this is the request method from the client - RequestMethod nRequestMethod; - - /// the clients requested URI - std::string sUri; - - /// holds the original requested URI, not changed by any path routing - std::string sOriginalUri; - - - /// the HTTP version of the request - std::string sHttpVersionNumber; - - /// Binary data, not NULL terminated - std::string sBody; - - /// whether or not this came over secure channels - int nSecure; - - /// headers from the client request - StringMap oRequestHeaders; - - /// Data specified by the client. The 'name' field is mapped to a FormValue object which has the value and any metadata - FormValueMap oFormValueMap; - - /// Data specified by the client in the query string. - FormValueMap oQueryValueMap; - - /// cookies that come in from the client - CookieMap oCookieMap; - - /// request id for this connection - int m_nRequestId; - - /// connection object from which this request came - EHSConnection * m_poSourceEHSConnection; - - /// returns the address this request came from - std::string GetAddress ( ); - - /// returns the port this request came from - int GetPort ( ); - - /// returns true if the client is disconnected - int ClientDisconnected ( ); - -}; - - -// HELPER FUNCTIONS - -/// removes the next line from irsBuffer and returns it in irsLine -int GetNextLine ( std::string & irsLine, std::string & irsBuffer ); - -/// gets the RequestMethod enumeration based on isRequestMethod -RequestMethod GetRequestMethodFromString ( const std::string & isRequestMethod ); - -/// makes the string lowercase -std::string & mytolower (std::string & s ); - - -#endif // HTTPREQUEST_H diff --git a/vendor/ehs/httpresponse.cpp b/vendor/ehs/httpresponse.cpp deleted file mode 100644 index 3725782af0b..00000000000 --- a/vendor/ehs/httpresponse.cpp +++ /dev/null @@ -1,158 +0,0 @@ - -#include -#include "httpresponse.h" -#include -#include "stats.h" - - -const char * DaysOfWeek [] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -const char * Months [] = { - - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - -}; - -char * CreateHttpTime ( ) -{ - // 30 is a magic number that is the length of the http - // time format + 1 for NULL terminator - - time_t nTime = time ( NULL ); - char * psTime = new char [ 30 ]; - tm * oTm = gmtime ( &nTime ); // get the time info - sprintf ( psTime, "%s, %02d %s %04d %02d:%02d:%02d GMT", - DaysOfWeek [ oTm->tm_wday ], - oTm->tm_mday, - Months [ oTm->tm_mon ], - oTm->tm_year + 1900, - oTm->tm_hour, - oTm->tm_min, - oTm->tm_sec ); - - return psTime; - -} - - - - -//////////////////////////////////////////////////////////////////// -// HTTP RESPONSE -// -//////////////////////////////////////////////////////////////////// - -HttpResponse::HttpResponse ( int inResponseId, - EHSConnection * ipoEHSConnection ) : - m_nResponseCode ( HTTP_STATUS_CODE_INVALID ), - psBody ( NULL ), - nBodyLength ( 0 ), - m_nResponseId ( inResponseId ), - m_poEHSConnection ( ipoEHSConnection ) - -{ - StatsNumResponsesInc(); - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Allocated: HttpResponse\n" ); -#endif - - char * psHttpTime = CreateHttpTime ( ); - - // General Header Fields (HTTP 1.1 Section 4.5) - oResponseHeaders [ "date" ] = psHttpTime; - oResponseHeaders [ "cache-control" ] = "no-cache"; - - - oResponseHeaders [ "last-modified" ] = psHttpTime; - oResponseHeaders [ "content-type" ] = "text/html"; - - delete [] psHttpTime; - -} - - - -HttpResponse::~HttpResponse ( ) -{ - -#ifdef EHS_MEMORY - fprintf ( stderr, "[EHS_MEMORY] Deallocated: HttpResponse\n" ); -#endif - - delete [] psBody; - StatsNumResponsesDec(); - StatsBytesDeallocated( nBodyLength ); -} - - -// sets informatino regarding the body of the HTTP response -// sent back to the client -void HttpResponse::SetBody ( const char * ipsBody, ///< body to return to user - int inBodyLength ///< length of the body - ) - -{ - nBodyLength = inBodyLength; - StatsBytesAllocated( nBodyLength ); - - assert ( psBody == NULL ); - - psBody = new char [ inBodyLength + 1 ]; - assert ( psBody != NULL ); - memset ( psBody, 0, inBodyLength + 1 ); - memcpy ( psBody, ipsBody, inBodyLength ); - - - char psContentLength [ 100 ]; - sprintf ( psContentLength, "%d", inBodyLength ); - - oResponseHeaders [ "content-length" ] = psContentLength; - -} - - -// this will send stuff if it's not valid.. -void HttpResponse::SetCookie ( CookieParameters & iroCookieParameters ) -{ - - // name and value must be set - if ( iroCookieParameters [ "name" ] != "" && - iroCookieParameters [ "value" ] != "" ) { - - std::stringstream ssBuffer; - - ssBuffer << iroCookieParameters["name"].GetCharString ( ) << - "=" << iroCookieParameters["value"].GetCharString ( ); - - // Version should have capital V according to RFC 2109 - if ( iroCookieParameters [ "Version" ] == "" ) { - iroCookieParameters [ "Version" ] = "1"; - } - - for ( CookieParameters::iterator i = iroCookieParameters.begin ( ); - i != iroCookieParameters.end ( ); - i++ ) { - - if ( (*i).first != "name" && - (*i).first != "value" ) { - - ssBuffer << "; " << (*i).first.c_str ( ) << - "=" << (*i).second.GetCharString ( ); - - } - - } - - oCookieList.push_back ( ssBuffer.str ( ) ); - - } else { - -#ifdef EHS_DEBUG - fprintf ( stderr, "Cookie set with insufficient data -- requires name and value\n" ); -#endif - } - -} diff --git a/vendor/ehs/httpresponse.h b/vendor/ehs/httpresponse.h deleted file mode 100644 index 98d567c6842..00000000000 --- a/vendor/ehs/httpresponse.h +++ /dev/null @@ -1,124 +0,0 @@ - -#ifndef HTTPRESPONSE_H -#define HTTPRESPONSE_H - -#ifdef _WIN32 -#include -#pragma warning(disable : 4786) -#endif - -#include -#include -#include -#include -#include - -#include "ehstypes.h" -#include "datum.h" - -enum HttpStatusCode -{ - HTTP_STATUS_CODE_INVALID = 0, - HTTP_STATUS_CODE_100_CONTINUE = 100, ///< Continue - HTTP_STATUS_CODE_101_SWITCHING_PROTOCOLS = 101, ///< Switching Protocols - HTTP_STATUS_CODE_200_OK = 200, ///< OK - HTTP_STATUS_CODE_201_CREATED = 201, ///< Created - HTTP_STATUS_CODE_202_ACCEPTED = 202, ///< Accepted - HTTP_STATUS_CODE_203_NON_AUTHORITATIVE_INFO = 203, ///< Non-Authoritative Information - HTTP_STATUS_CODE_204_NO_CONTENT = 204, ///< No Content - HTTP_STATUS_CODE_205_RESET_CONTENT = 205, ///< Reset Content - HTTP_STATUS_CODE_206_PARTIAL_CONTENT = 206, ///< Partial Content - HTTP_STATUS_CODE_300_MULTIPLE_CHOICES = 300, ///< Multiple Choices - HTTP_STATUS_CODE_301_MOVED_PERMANENTLY = 301, ///< Moved Permanently - HTTP_STATUS_CODE_302_FOUND = 302, ///< Found - HTTP_STATUS_CODE_303_SEE_OTHER = 303, ///< See Other - HTTP_STATUS_CODE_304_NOT_MODIFIED = 304, ///< Not Modified - HTTP_STATUS_CODE_305_USE_PROXY = 305, ///< Use Proxy - HTTP_STATUS_CODE_307_TEMPORARY_REDIRECT = 307, ///< Temporary Redirect - HTTP_STATUS_CODE_400_BAD_REQUEST = 400, ///< Bad Request - HTTP_STATUS_CODE_401_UNAUTHORIZED = 401, ///< Unauthorized - HTTP_STATUS_CODE_402_PAYMENT_REQUIRED = 402, ///< Payment Required - HTTP_STATUS_CODE_403_FORBIDDEN = 403, ///< Forbidden - HTTP_STATUS_CODE_404_NOT_FOUND = 404, ///< Not Found - HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED = 405, ///< Method Not Allowed - HTTP_STATUS_CODE_406_NOT_ACCEPTABLE = 406, ///< Not Acceptable - HTTP_STATUS_CODE_407_PROXY_AUTH_REQUIRED = 407, ///< Proxy Authentication Required - HTTP_STATUS_CODE_408_REQUEST_TIMEOUT = 408, ///< Request Time-out - HTTP_STATUS_CODE_409_CONFLICT = 409, ///< Conflict - HTTP_STATUS_CODE_410_GONE = 410, ///< Gone - HTTP_STATUS_CODE_411_LENGTH_REQUIRED = 411, ///< Length Required - HTTP_STATUS_CODE_412_PRECONDITION_FAILED = 412, ///< Precondition Failed - HTTP_STATUS_CODE_413_REQUEST_ENTITY_TOO_LARGE = 413, ///< Request Entity Too Large - HTTP_STATUS_CODE_414_URI_TOO_LARGE = 414, ///< Request-URI Too Large - HTTP_STATUS_CODE_415_UNSUPPORTED_MEDIA_TYPE = 415, ///< Unsupported Media Type - HTTP_STATUS_CODE_416_RANGE_NOT_SATISFIABLE = 416, ///< Requested range not satisfiable - HTTP_STATUS_CODE_417_EXPECTATION_FAILED = 417, ///< Expectation Failed - HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR = 500, ///< Internal Server Error - HTTP_STATUS_CODE_501_NOT_IMPLEMENTED = 501, ///< Not Implemented - HTTP_STATUS_CODE_502_BAD_GATEWAY = 502, ///< Bad Gateway - HTTP_STATUS_CODE_503_SERVICE_UNAVAILABLE = 503, ///< Service Unavailable - HTTP_STATUS_CODE_504_GATEWAY_TIMEOUT = 504, ///< Gateway Time-out - HTTP_STATUS_CODE_505_VERSION_NOT_SUPPORTED = 505, ///< HTTP Version not supported -}; - -extern const char* GetHttpStatusReasonPhrase(int statusCode); - -/// This defines what is sent back to the client -/** - * This defines what is sent back to the client. It contains the actual body, any - * headers specified, and the response code. - */ -class HttpResponse { - - public: - - /// constructor - HttpResponse ( int inResponseId, EHSConnection * ipoEHSConnection ); - - /// destructor - ~HttpResponse ( ); - - /// sets information about the body of the response being sent back to the client. - void SetBody ( const char * ipsBody, ///< body to be sent to client - int inBodyLength ///< length of body to be sent to client - ); - - /// sets cookies for the response - void SetCookie ( CookieParameters & iroCookieParameters ); - - - /// Returns the body of the response - char * GetBody ( ) { return psBody; }; - - /// the response code to be sent back - HttpStatusCode m_nResponseCode; - - /// these are the headers sent back to the client in the http response. Things like content-type and content-length - StringMap oResponseHeaders; - - /// cookies waiting to be sent - StringList oCookieList; - - /// ehs connection object this response goes back on - EHSConnection * m_poEHSConnection; - - /// response id for making sure we send responses in the right order - int m_nResponseId; - - - protected: - - /// request id for this request's connection object - int m_nRequestId; - - /// the actual body to be sent back -- set by SetBody - char * psBody; - - /// the size of the body to be sent back -- set by SetBody - int nBodyLength; - - -}; - - -#endif // HTTPRESPONSE_H diff --git a/vendor/ehs/networkabstraction.h b/vendor/ehs/networkabstraction.h deleted file mode 100644 index 1b6a1e1156d..00000000000 --- a/vendor/ehs/networkabstraction.h +++ /dev/null @@ -1,89 +0,0 @@ - -/* - -EHS is a library for adding web server support to a C++ application -Copyright (C) 2001, 2002 Zac Hansen - -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; version 2 -of the License only. - -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. -or see http://www.gnu.org/licenses/gpl.html - -Zac Hansen ( xaxxon@slackworks.com ) - -*/ - -#ifndef NETWORK_ABSTRACTION_H -#define NETWORK_ABSTRACTION_H - -#include -#include - -/// Abstracts different socket types -/** - * this abstracts the differences between normal sockets and ssl sockets - * Socket is the standard socket class and SecureSocket is the SSL - * implementation - */ -class NetworkAbstraction { - - public: - - /// returns the address of the connection - virtual std::string GetAddress ( ) = 0; - - /// returns the port of the connection - virtual int GetPort ( ) = 0; - - /// Enumeration of error results for InitSocketsResults - enum InitResult { INITSOCKET_INVALID, - INITSOCKET_SOCKETFAILED, - INITSOCKET_BINDFAILED, - INITSOCKET_LISTENFAILED, - INITSOCKET_FAILED, - INITSOCKET_CERTIFICATE, - INITSOCKET_SUCCESS }; - - /// Iniitalize sockets - virtual InitResult Init ( int iPort, int inPort ) = 0; - - /// destructor - virtual ~NetworkAbstraction ( ) {}; - - /// returns the FD/Socket for the socket on which we're listening - virtual int GetFd ( ) = 0; - - /// pure virtual read function to be overloaded in child classes - virtual int Read ( void * ipBuffer, int ipBufferLength ) = 0; - - /// pure virtual send function to be overloaded in child class - virtual int Send ( const void * ipMessage, size_t inLength, int inFlags = 0 ) = 0; - - /// pure virtual close function to be overloaded in child class - virtual void Close ( ) = 0; - - /// pure virtual accept function to be overloaded in child class - virtual NetworkAbstraction * Accept ( ) = 0; - - /// returns whether the child class connection is considered secure - virtual int IsSecure ( ) = 0; - - // Check status - virtual bool IsReadable( int inTimeoutMilliseconds ) = 0; - virtual bool IsWritable( int inTimeoutMilliseconds ) = 0; - virtual bool IsAtError( int inTimeoutMilliseconds ) = 0; - -}; - - -#endif // NETWORK_ABSTRACTION_H diff --git a/vendor/ehs/premake5.lua b/vendor/ehs/premake5.lua deleted file mode 100644 index 9fae08e95b6..00000000000 --- a/vendor/ehs/premake5.lua +++ /dev/null @@ -1,34 +0,0 @@ -project "ehs" - language "C++" - kind "StaticLib" - targetname "ehs" - warnings "Off" - - includedirs { - "../../Shared/sdk", - "../pcre", - "../pme", - } - - defines { "WIN32_LEAN_AND_MEAN", "_LIB" } - - vpaths { - ["Headers/*"] = "**.h", - ["Sources/*"] = "*.cpp", - ["*"] = "premake5.lua" - } - - files { - "premake5.lua", - "*.h", - - "datum.cpp", - "ehs.cpp", - "httprequest.cpp", - "httpresponse.cpp", - "socket.cpp" - } - - filter "system:windows" - includedirs { "../pthreads/include" } - disablewarnings { "4800" } diff --git a/vendor/ehs/samples/ehs_formtest.cpp b/vendor/ehs/samples/ehs_formtest.cpp deleted file mode 100644 index aecc7824b69..00000000000 --- a/vendor/ehs/samples/ehs_formtest.cpp +++ /dev/null @@ -1,164 +0,0 @@ - -/* - - EHS is a library for adding web server support to a C++ application - Copyright (C) 2001, 2002 Zac Hansen - - 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; version 2 - of the License only. - - 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. - - Zac Hansen ( xaxxon@slackworks.com ) - -*/ - - -#include -#include - -#include "../ehs.h" - -typedef std::list < std::string > StringList; - -class FormTester : public EHS { - -public: - - FormTester ( ) {} - - ResponseCode HandleRequest ( HttpRequest * ipoHttpRequest, - HttpResponse * ipoHttpResponse ); - - StringList oNameList; - - -}; - - -// creates a page based on user input -- either displays data from -// form or presents a form for users to submit data. -ResponseCode FormTester::HandleRequest ( HttpRequest * ipoHttpRequest, - HttpResponse * ipoHttpResponse ) -{ - char psHtml[ 5000 ]; - - - // if we got data from the user, show it - if ( ipoHttpRequest->oFormValueMap [ "user" ].sBody.length ( ) || - ipoHttpRequest->oFormValueMap [ "existinguser" ].sBody.length ( ) ) { - - std::string sName; - - sName = ipoHttpRequest->oFormValueMap [ "existinguser" ].sBody; - if ( ipoHttpRequest->oFormValueMap [ "user" ].sBody.length() ) { - sName = ipoHttpRequest->oFormValueMap [ "user" ].sBody; - } - - fprintf ( stderr, "Got name of %s\n", sName.c_str ( ) ); - - char * psHtml = new char [ 5000 ]; - sprintf ( psHtml, "StringList\nHi %s", sName.c_str ( ) ); - oNameList.push_back ( sName ); - - ipoHttpResponse->SetBody( psHtml, strlen( psHtml ) ); - return HTTPRESPONSECODE_200_OK; - - } else { - - // otherwise, present the form to the user to fill in - fprintf ( stderr, "Got no form data\n" ); - - // create the options for the dropdown box - char * psOptions; - if ( oNameList.size ( ) > 0 ) - psOptions = new char [ oNameList.size ( ) * 200 ]; - else - psOptions = new char [1]; - - psOptions [ 0 ] = '\0'; - - for ( StringList::iterator oCurrentName = oNameList.begin(); - oCurrentName != oNameList.end ( ); - oCurrentName++ ) { - - char psOption [ 200 ]; - sprintf ( psOption, "