]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
libhtp: remove libhtp from repo
authorVictor Julien <victor@inliniac.net>
Mon, 15 Jul 2013 10:20:46 +0000 (12:20 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 15 Jul 2013 10:20:46 +0000 (12:20 +0200)
61 files changed:
libhtp/AUTHORS [deleted file]
libhtp/COPYING [deleted file]
libhtp/ChangeLog [deleted file]
libhtp/LIBHTP_LICENSING_EXCEPTION [deleted file]
libhtp/LICENSE [deleted file]
libhtp/Makefile.am [deleted file]
libhtp/NEWS [deleted file]
libhtp/README [deleted file]
libhtp/configure.ac [deleted file]
libhtp/docs/QUICK_START [deleted file]
libhtp/docs/doxygen.conf [deleted file]
libhtp/htp.pc.in [deleted file]
libhtp/htp/Makefile.am [deleted file]
libhtp/htp/bstr.c [deleted file]
libhtp/htp/bstr.h [deleted file]
libhtp/htp/dslib.c [deleted file]
libhtp/htp/dslib.h [deleted file]
libhtp/htp/hooks.c [deleted file]
libhtp/htp/hooks.h [deleted file]
libhtp/htp/htp.c [deleted file]
libhtp/htp/htp.h [deleted file]
libhtp/htp/htp_config.c [deleted file]
libhtp/htp/htp_connection.c [deleted file]
libhtp/htp/htp_connection_parser.c [deleted file]
libhtp/htp/htp_decompressors.c [deleted file]
libhtp/htp/htp_decompressors.h [deleted file]
libhtp/htp/htp_parsers.c [deleted file]
libhtp/htp/htp_request.c [deleted file]
libhtp/htp/htp_request_apache_2_2.c [deleted file]
libhtp/htp/htp_request_generic.c [deleted file]
libhtp/htp/htp_request_parsers.c [deleted file]
libhtp/htp/htp_response.c [deleted file]
libhtp/htp/htp_response_generic.c [deleted file]
libhtp/htp/htp_transaction.c [deleted file]
libhtp/htp/htp_util.c [deleted file]
libhtp/htp/utf8_decoder.c [deleted file]
libhtp/htp/utf8_decoder.h [deleted file]
libhtp/m4/.keep [deleted file]
libhtp/test/Makefile.am [deleted file]
libhtp/test/files/01-get.t [deleted file]
libhtp/test/files/02-header-test-apache2.t [deleted file]
libhtp/test/files/03-post-urlencoded.t [deleted file]
libhtp/test/files/04-post-urlencoded-chunked.t [deleted file]
libhtp/test/files/05-expect.t [deleted file]
libhtp/test/files/06-uri-normal.t [deleted file]
libhtp/test/files/07-pipelined-connection.t [deleted file]
libhtp/test/files/08-not-pipelined-connection.t [deleted file]
libhtp/test/files/09-multi-packet-request-head.t [deleted file]
libhtp/test/files/10-host-in-headers.t [deleted file]
libhtp/test/files/11-response-stream-closure.t [deleted file]
libhtp/test/files/12-connect-request.t [deleted file]
libhtp/test/files/13-compressed-response-gzip-ct.t [deleted file]
libhtp/test/files/14-compressed-response-gzip-chunked.t [deleted file]
libhtp/test/files/15-connect-complete.t [deleted file]
libhtp/test/files/16-connect-extra.t [deleted file]
libhtp/test/files/anchor.empty [deleted file]
libhtp/test/files/misc.t [deleted file]
libhtp/test/main.c [deleted file]
libhtp/test/test-tcpick.c [deleted file]
libhtp/test/test.c [deleted file]
libhtp/test/test.h [deleted file]

diff --git a/libhtp/AUTHORS b/libhtp/AUTHORS
deleted file mode 100644 (file)
index 769b9a2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Ivan Ristic <ivanr@webkreator.com>
diff --git a/libhtp/COPYING b/libhtp/COPYING
deleted file mode 100644 (file)
index 64bc050..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
\ No newline at end of file
diff --git a/libhtp/ChangeLog b/libhtp/ChangeLog
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/libhtp/LIBHTP_LICENSING_EXCEPTION b/libhtp/LIBHTP_LICENSING_EXCEPTION
deleted file mode 100644 (file)
index 815af7b..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-
-LIBHTP LICENSING EXCEPTION
-===============================
-
-Version 1.0, 6 January 2010
-
-As a special exception ("Exception") to the terms and conditions of version 2
-of the GPL, Ivan Ristic hereby grants you the rights described below, provided
-you agree to the terms and conditions in this Exception, including its
-obligations and restrictions on use.
-
-
-Exception Intent
-================
-
-We want specified Free/Libre and Open Source Software ("FLOSS") programs to be
-able to use LibHTP (the "Program") despite the fact that not all FLOSS
-licenses are compatible with version 2 of the GNU General Public License (the
-"GPLv2").
-
-
-Legal Terms and Conditions
-==========================
-
-You are free to distribute a Derivative Work that is formed entirely from the
-Program and one or more works (each, a "FLOSS Work") licensed under one or
-more of the licenses listed below in section 1, as long as all of the
-following conditions are met:
-
-  1. You obey the GPLv2 in all respects for the Program and the Derivative
-     Work, except for identifiable sections of the Derivative Work which are
-     
-     1. not derived from the Program, and
-     
-     2. are not designed to interact with the Program, and
-     
-     3. which can reasonably be considered independent and separate works in
-        themselves.
-        
-  2. All such identifiable sections of the Derivative Work are
-  
-     1. distributed subject to one of the FLOSS licenses listed below, and
-     
-     2. the object code or executable form of those sections are accompanied
-        by the complete corresponding machine-readable source code for those
-        sections on the same medium and under the same FLOSS license as the
-        corresponding object code or executable forms of those sections.
-        
-  3. Any works which are aggregated with the Program or with a Derivative Work
-     on a volume of a storage or distribution medium in accordance with the
-     GPLv2, can reasonably be considered independent and separate works in
-     themselves which are not derivatives of either the Program, a Derivative
-     Work or a FLOSS Work, and are not designed to interact with the Program.
-     
-If the above conditions are not met, then the Program may only be copied,
-modified, distributed or used under the terms and conditions of the GPLv2
-or another valid licensing option from Ivan Ristic.
-
-
-FLOSS License List
-==================
-
-License name                                   Version(s)/Copyright Date
------------------------------------------------------------------------
-Academic Free License                                  2.0
-Apache Software License                                1.0/1.1/2.0
-Apple Public Source License                            2.0
-Artistic license                                       From Perl 5.8.0
-BSD license                                            "July 22 1999"
-Common Development and Distribution License (CDDL)     1.0
-Common Public License                                  1.0
-Eclipse Public License                                 1.0
-GNU Library or "Lesser" General Public License (LGPL)  2.0/2.1/3.0
-Jabber Open Source License                             1.0
-MIT License (As listed in file MIT-License.txt)        -
-Mozilla Public License (MPL)                           1.0/1.1
-Open Software License                                  2.0
-OpenSSL license (with original SSLeay license)         "2003" ("1998")
-PHP License                                            3.0
-Python license (CNRI Python License)                   -
-Python Software Foundation License                     2.1.1
-Sleepycat License                                      "1999"
-University of Illinois/NCSA Open Source License        -
-W3C License                                            "2001"
-X11 License                                            "2001"
-Zlib/libpng License                                    -
-Zope Public License                                    2.0
-
-Due to the many variants of some of the above licenses, we require that for
-any version of the listed FLOSS licenses to qualify under this exception, it
-must follow the 2003 version of the Free Software Foundation's Free Software
-Definition (http://www.gnu.org/philosophy/free-sw.html) or version 1.9 of the
-Open Source Definition by the Open Source Initiative
-(http://www.opensource.org/docs/definition.php).
-
-
-Definitions
-===========
-
-1. Terms used, but not defined, herein shall have the meaning provided in the
-   version 2 of the GPL.
-   
-2. Derivative Work means a derivative work under copyright law.
-
-
-Applicability
-=============
-
-This Exception applies to all Programs that contain a notice placed by Ivan
-Ristic saying that the Program may be distributed under the terms of
-this Exception. If you create or distribute a work which is a Derivative Work
-of both the Program and any other work licensed under the GPL, then this FLOSS
-Exception is not available for that work; thus, you must remove the FLOSS
-Exception notice from that work and comply with the GPL in all respects,
-including by retaining all GPL notices.
-
-You may choose to redistribute a copy of the Program exclusively under the
-terms of the GPLv2 by removing the Exception notice from that copy of the
-Program, provided that the copy has never been modified by you or any third
-party.
diff --git a/libhtp/LICENSE b/libhtp/LICENSE
deleted file mode 100644 (file)
index 0cd26d5..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1989, 1991 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.
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, 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 or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-\f
-                   GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-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 give any other recipients of the Program a copy of this License
-along with the Program.
-
-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 Program or any portion
-of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-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 Program, 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 Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) 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; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, 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 executable.  However, as a
-special exception, the source code 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.
-
-If distribution of executable or 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 counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program 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.
-
-  5. 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 Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program 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 to
-this License.
-
-  7. 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 Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program 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 Program.
-
-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.
-\f
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program 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.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the 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 Program
-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 Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, 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
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-
diff --git a/libhtp/Makefile.am b/libhtp/Makefile.am
deleted file mode 100644 (file)
index 8ff13fa..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-SUBDIRS= $(GENERIC_LIBRARY_NAME) test
-
-DIST_SUBDIRS = $(GENERIC_LIBRARY_NAME) test
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = htp.pc
-
diff --git a/libhtp/NEWS b/libhtp/NEWS
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/libhtp/README b/libhtp/README
deleted file mode 100644 (file)
index cbde65e..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-
-LibHTP (http://www.libhtp.org)
-Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
-======================================================
-
-LibHTP is a security-aware parser for the HTTP protocol and the related bits
-and pieces. The goals of the project, in the order of importance, are as
-follows:
-
- 1. Completeness of coverage; LibHTP must be able to parse virtually all
-    traffic that is found in practice.
-
- 2. Permissive parsing; LibHTP must never fail to parse a stream that would
-    be parsed by some other web server.
-
- 3. Awareness of evasion techniques; LibHTP must be able to detect and
-    effectively deal with various evasion techniques, producing, where
-    practical, identical or practically identical results as the web
-    server processing the same traffic stream.
-
- 4. Performance; The performance must be adequate for the desired tasks.
-    Completeness and security are often detremental to performance. Our
-    idea of handling the conflicting requirements is to put the library
-    user in control, allowing him to choose the most desired library
-    characteristic.
-
- | IMPORTANT   LIBHTP IS NOT YET CONSIDERED STABLE. USE AT YOUR OWN RISK. DO NOT
- |             USE IN PRODUCTION. WORK IS CURRENTLY UNDER WAY TO ENSURE THAT
- |             LIBHTP IS SECURE AND THAT IT PERFORMS WELL.
-
- | STATUS      LIBHTP IS VERY YOUNG AT THIS POINT. IT WILL BE SOME TIME BEFORE
- |             IT CAN BE CONSIDER COMPLETE. AT THE MOMENT, THE FOCUS OF DEVELOPMENT
- |             IS ON ACHIEVING THE FIRST TWO GOALS.
-
-LibHTP is an open source product, released under terms of the General Public Licence
-version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
-of the license.
-
-In addition, there is a special exception that allows LibHTP to be freely
-used with any OSI-approved open source licence. Please refer to the file
-LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
-
-
-INSTALLATION
-------------
-
-The installation process should be as simple as:
-
-  $ ./configure
-  $ make
-  # make install
-
- | NOTE    If you already have an early 0.2.x version installed, you must
- |         uninstall it before proceeding. Initially /usr was used for the
- |         installation, but /usr/local is used now. If you forgot to uninstall,
- |         clean all traces of LibHTP from /usr/lib/libhtp* and /usr/include/htp/*.
-
-If you want to use a repository version of LibHTP, do the following:
-
- 1. Use svn export to retrieve the sources of the version you wish to use
-
- 2. Run ./update_version, which will update htp.c with the latest Subversion
-    revision used
-
- 3. You may wish to also update htp.pc.in and configure.ac with the correct version
-
- 4. Run autoconf -i --force, which will prepare the library for installation
-
- 5. Run doxygen to generate the API documentation
-
- 6. Continue to install as described above
-
-
-DOCUMENTATION
--------------
-
-The best documentation at this time is the code itself and the Doxygen output (which
-should be all right). There's also a quick start guide in the doc/ folder, which
-should give you enough information to get going.
-
-
-NO WARRANTY
------------
-
-  BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
diff --git a/libhtp/configure.ac b/libhtp/configure.ac
deleted file mode 100644 (file)
index 8519fef..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-
-dnl ----------------------
-dnl Initialization macros
-dnl ----------------------
-
-AC_INIT(htp/htp.h)
-AC_CONFIG_HEADERS([config.h])
-
-
-dnl -----------------------------------------------
-dnl Package name and version number (user defined)
-dnl -----------------------------------------------
-
-GENERIC_LIBRARY_NAME=htp
-
-GENERIC_MAJOR_VERSION=0
-GENERIC_MINOR_VERSION=2
-GENERIC_MICRO_VERSION=12
-
-# API version (often = GENERIC_MAJOR_VERSION.GENERIC_MINOR_VERSION)
-GENERIC_API_VERSION=1.0
-AC_SUBST(GENERIC_API_VERSION)
-
-# Shared library versioning
-GENERIC_LIBRARY_VERSION=1:2:0
-#                       | | |
-#                +------+ | +---+
-#                |        |     |
-#             current:revision:age
-#                |        |     |
-#                |        |     +- increment if interfaces have been added
-#                |        |        set to zero if interfaces have been removed
-#                                  or changed
-#                |        +- increment if source code has changed
-#                |           set to zero if current is incremented
-#                +- increment if interfaces have been added, removed or changed
-
-
-dnl --------------------------------
-dnl Package name and version number
-dnl --------------------------------
-
-AC_SUBST(GENERIC_LIBRARY_VERSION)
-
-PACKAGE=$GENERIC_LIBRARY_NAME
-AC_SUBST(GENERIC_LIBRARY_NAME)
-
-GENERIC_VERSION=$GENERIC_MAJOR_VERSION.$GENERIC_MINOR_VERSION.$GENERIC_MICRO_VERSION
-GENERIC_RELEASE=$GENERIC_MAJOR_VERSION.$GENERIC_MINOR_VERSION
-AC_SUBST(GENERIC_RELEASE)
-AC_SUBST(GENERIC_VERSION)
-
-VERSION=$GENERIC_VERSION
-
-AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
-
-AC_CONFIG_MACRO_DIR([m4])
-
-AC_ARG_ENABLE(htp-debug, [ --enable-htp-debug  Enable debug output], [ enable_htp_debug=yes ])
-if test "$enable_htp_debug" = "yes"; then
-    CFLAGS="${CFLAGS} -DHTP_DEBUG"
-    echo "Debug mode enabled"
-fi
-
-dnl -----------------------------------------------
-dnl Checks for programs.
-dnl -----------------------------------------------
-
-AC_PROG_CC
-AM_PROG_LIBTOOL
-AM_SANITY_CHECK
-
-dnl -----------------------------------------------
-dnl Checks for libs.
-dnl -----------------------------------------------
-AC_CHECK_HEADER(zlib.h,,[AC_ERROR(zlib.h not found ...)])
-ZLIB=""
-AC_CHECK_LIB(z, inflate,, ZLIB="no")
-if test "$ZLIB" = "no"; then
-    echo
-    echo "   ERROR! zlib library not found"
-    echo
-    exit 1
-fi
-
-dnl -----------------------------------------------
-dnl provides a read-only relocation table area in the final ELF
-dnl -----------------------------------------------
-AC_MSG_CHECKING(for -z relro)
-TMPLDFLAGS="${LDFLAGS}"
-LDFLAGS="${LDFLAGS} -z relro"
-AC_TRY_LINK(,,SECLDFLAGS="${SECLDFLAGS} -z relro"
-AC_MSG_RESULT(yes),
-AC_MSG_RESULT(no))
-LDFLAGS="${TMPLDFLAGS}"
-
-
-#check for os
-AC_MSG_CHECKING([host os])
-
-# If no host os was detected, try with uname
-if test -z "$host" ; then
-        host="`uname`"
-fi
-case "$host" in
-       *-*-openbsd*)
-                CFLAGS="${CFLAGS} -fgnu89-inline"
-       ;;
-esac
-AC_MSG_RESULT(ok)
-
-
-dnl -----------------------------------------------
-dnl forces all relocations to be resolved at run-time
-dnl -----------------------------------------------
-AC_MSG_CHECKING(for -z now)
-TMPLDFLAGS="${LDFLAGS}"
-LDFLAGS="${LDFLAGS} -z now"
-AC_TRY_LINK(,,SECLDFLAGS="${SECLDFLAGS} -z now"
-AC_MSG_RESULT(yes),
-AC_MSG_RESULT(no))
-LDFLAGS="${TMPLDFLAGS}"
-
-CFLAGS="${CFLAGS} ${SECCFLAGS}"
-LDFLAGS="${LDFLAGS} ${SECLDFLAGS}"
-
-dnl -----------------------------------------------
-dnl Generates Makefile's, configuration files and scripts
-dnl -----------------------------------------------
-
-AC_PREFIX_DEFAULT(/usr/local)
-
-AC_OUTPUT(Makefile \
-          htp.pc \
-          htp/Makefile \
-          test/Makefile
-)
diff --git a/libhtp/docs/QUICK_START b/libhtp/docs/QUICK_START
deleted file mode 100644 (file)
index 57dcec7..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-
-QUICK START
------------
-
-LibHTP is envisioned to be many things, but the only scenario in which it has been tested
-so far is that when you need to parse a duplex HTTP stream which you have obtained by
-passively intercepting a communication channel. The assumption is that you have raw TCP data
-(after SSL, if SSL is used).
-
-Every parsing operation needs to follow these steps:
-
-  1. Configure-time:
-
-     1.1. Create one or more parser configuration structures.
-
-     1.2. Tweak the configuration of each parser to match the behaviour of
-          the server you're intercepting the communication of (htp_config_set_* functions).
-
-     1.3. Register the parser callbacks you'll need. You will need to use parser callbacks
-          if you want to monitor parsing events as they occur, and gain access to partial
-          transaction information. If you are processing data in batch (off-line) you may
-          simply parse entire streams at a time and only analyze complete transaction data
-          after the fact.
-
-          If you need to gain access to request and response bodies, your only option at
-          this time is to use the callbacks, because the parser will not preserve that
-          information.
-
-          For callback registration, look up the htp_config_register_* functions.
-
-          If your program operates in real-time then it may be desirable to dispose of
-          the used resources after each transaction is parsed. To do that, you are allowed
-          to call htp_tx_destroy() at the end of the RESPONSE callback.
-
-  2. Run-time:
-
-     2.1. Create a parser instance for every TCP stream you want to process.
-
-     2.2. Feed the parser inbound and outbound data.
-
-          The parser will typically always consume complete data chunks and return
-          STREAM_STATE_DATA, which means that you can continue to feed it more data
-          when you have it. If you have a queue of data chunks, always send the
-          parsed all the request chunks you have. That will ensure that the parser
-          never encounters a response for which it had not seen a request.
-
-          If you get STREAM_STATE_ERROR, the parser has encountered a fatal error and
-          is unable to continue to parse the stream. An error should never happen for
-          a valid HTTP stream. If you encounter such an error please send me the pcap
-          file for analysis.
-
-          There is one situation when the parser will not be able to consume a complete
-          request data chunk, in which case it will return STREAM_STATE_DATA_OTHER. You
-          will then need to do the following:
-
-          2.2.1. Remember how many bytes of data were consumed (using
-                 htp_connp_req_data_consumed()).
-
-          2.2.2. Suspend request parsing until you get some response data.
-
-          2.2.3. Feed some response data to the parser.
-
-                 Note that it is now possible to receive STREAM_STATE_DATA_OTHER
-                 from the response parser. If that happens, you will need to
-                 remember how many bytes were consumed using
-                 htp_connp_res_data_consumed().
-
-          2.2.4. After each chunk of response data fed to the parser, attempt
-                 to resume request stream parsing.
-
-          2.2.5. If you again receive STREAM_STATE_DATA_OTHER go back to 2.2.3.
-
-          2.2.6. At this point you should feed the parser all the request data
-                 you have accumulated before giving it any response data. This is
-                 necessary to prevent the case of the parser seeing more responses
-                 than requests (which would inevitably result with an error).
-
-          2.2.7. Send unprocessed response data from 2.2.3 (if any).
-
-          2.2.8. Continue sending request/response data as normal.
-
-          The above situation should occur very rarely.
-
-     2.3. Analyze transaction data in callbacks (if any).
-
-     2.4. Analyze transaction data after an entire TCP stream has been processed.
-
-     2.4. Destroy parser instance to free up the allocated resources.
-
-
-USER DATA
----------
-
-If you're using the callbacks and you need to keep state between invocations, you have two
-options:
-
-  1. Associate one opaque structure with a parser instance, using htp_connp_set_user_data().
-
-  2. Associate one opaque structure with a transaction instance, using htp_tx_set_user_data().
-     The best place to do this is in a TRANSACTION_START callback. Don't forget to free up
-     any resources you allocate on per-transaction basis, before you delete each transaction.
-
diff --git a/libhtp/docs/doxygen.conf b/libhtp/docs/doxygen.conf
deleted file mode 100644 (file)
index 5493cae..0000000
+++ /dev/null
@@ -1,1356 +0,0 @@
-# Doxyfile 1.5.5
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file 
-# that follow. The default is UTF-8 which is also the encoding used for all 
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
-# iconv built into libc) for the transcoding. See 
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = HTP
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 0.1
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = doxygen/
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS         = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
-# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
-# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
-# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
-# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, 
-# and Ukrainian.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF       = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB  = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH        = 
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like regular Qt-style comments 
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF      = NO
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
-# interpret the first line (until the first dot) of a Qt-style 
-# comment as the brief description. If set to NO, the comments 
-# will behave just like regular Qt-style comments (thus requiring 
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF           = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP         = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 8
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Java. For instance, namespaces will be presented as packages, qualified 
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
-# sources only. Doxygen will then generate output that is more tailored for 
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
-# sources. Doxygen will then generate output that is tailored for 
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
-# to include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also make the inheritance and collaboration 
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT    = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
-# Doxygen will parse them like normal C++ but will assume all classes use public 
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT            = NO
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING            = YES
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
-# is documented as struct, union, or enum with the name of the typedef. So 
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
-# with name TypeT. When disabled the typedef will appear as a member of a file, 
-# namespace, or class. And the struct will be named TypeS. This can typically 
-# be useful for C code in case the coding convention dictates that all compound 
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be 
-# extracted and appear in the documentation as a namespace called 
-# 'anonymous_namespace{file}', where file will be replaced with the base 
-# name of the file that contains the anonymous namespace. By default 
-# anonymous namespace are hidden.
-
-EXTRACT_ANON_NSPACES   = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES       = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
-# hierarchy of group names into alphabetical order. If set to NO (the default) 
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES       = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from 
-# the version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
-# documentation.
-
-WARN_NO_PARAMDOC       = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-INPUT                  = ../htp
-
-# This tag can be used to specify the character encoding of the source files 
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
-# also the default input encoding. Doxygen uses libiconv (or the iconv built 
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
-# the list of possible encodings.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-
-FILE_PATTERNS          = *.c *.h
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix filesystem feature) are excluded 
-# from the input.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = 
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
-# (namespaces, classes, functions, etc.) that should be excluded from the 
-# output. The symbol name can be a fully qualified name, a word, or if the 
-# wildcard * is used, a substring. Examples: ANamespace, AClass, 
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS        = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER           = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
-# is applied to all files.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = NO
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
-# will need version 4.8.6 or higher.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = ./
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET        = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files 
-# will be generated that can be used as input for Apple's Xcode 3 
-# integrated development environment, introduced with OSX 10.5 (Leopard). 
-# To create a documentation set, doxygen will generate a Makefile in the 
-# HTML output directory. Running make will produce the docset in that 
-# directory and running "make install" will install the docset in 
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
-# it at startup.
-
-GENERATE_DOCSET        = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
-# feed. A documentation feed provides an umbrella under which multiple 
-# documentation sets from a single provider (such as a company or product suite) 
-# can be grouped.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
-# should uniquely identify the documentation set bundle. This should be a 
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
-# documentation will contain sections that can be hidden and shown after the 
-# page has loaded. For this to work a browser that supports 
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE               = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION           = 
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES     = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT             = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA             = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD                = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF     = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED             = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse 
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS        = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option is superseded by the HAVE_DOT option below. This is only a 
-# fallback. It is recommended to install and use dot, since it yields more 
-# powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# You can define message sequence charts within doxygen comments using the \msc 
-# command. Doxygen will then run the mscgen tool (see 
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
-# the mscgen tool resides. If left empty the tool is assumed to be found in the 
-# default search path.
-
-MSCGEN_PATH            = 
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK               = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
-# doxygen will generate a call dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable call graphs 
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
-# doxygen will generate a caller dependency graph for every global function 
-# or class method. Note that enabling this option will significantly increase 
-# the time of a run. So in most cases it will be better to enable caller 
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT       = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
-# nodes that will be shown in the graph. If the number of nodes in a graph 
-# becomes larger than this value, doxygen will truncate the graph, which is 
-# visualized by representing a node as a red box. Note that doxygen if the 
-# number of direct children of the root node in a graph is already larger than 
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that the size of a graph can be further restricted by 
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is enabled by default, which results in a transparent 
-# background. Warning: Depending on the platform used, enabling this option 
-# may lead to badly anti-aliased labels on the edges of a graph (i.e. they 
-# become hard to read).
-
-DOT_TRANSPARENT        = YES
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
diff --git a/libhtp/htp.pc.in b/libhtp/htp.pc.in
deleted file mode 100644 (file)
index 754851e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=/usr
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib
-includedir=${prefix}/include
-
-Name: HTP
-Description: HTTP parser
-Version: 0.2.12
-Libs: -L${libdir} -lhtp
-Cflags: -I${includedir}/htp -I${libdir}/htp/include
-
diff --git a/libhtp/htp/Makefile.am b/libhtp/htp/Makefile.am
deleted file mode 100644 (file)
index ce4a9d3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-h_sources = bstr.h dslib.h hooks.h htp.h utf8_decoder.h htp_decompressors.h
-c_sources = bstr.c hooks.c htp_config.c htp_connection_parser.c htp_request_apache_2_2.c htp_request_generic.c htp_request_parsers.c htp_response_generic.c htp_util.c dslib.c htp.c htp_connection.c htp_parsers.c htp_request.c htp_response.c htp_transaction.c utf8_decoder.c htp_decompressors.c
-
-library_includedir = $(includedir)/$(GENERIC_LIBRARY_NAME)
-library_include_HEADERS = $(h_sources)
-
-INCLUDES = -I$(top_srcdir)
-AM_CFLAGS = -D_GNU_SOURCE -g -O2 -Wall -Wextra -std=gnu99 -pedantic
-
-lib_LTLIBRARIES= libhtp.la
-libhtp_la_SOURCES= $(h_sources) $(c_sources)
-libhtp_la_LDFLAGS= -version-info $(GENERIC_LIBRARY_VERSION) -release $(GENERIC_RELEASE)
-
diff --git a/libhtp/htp/bstr.c b/libhtp/htp/bstr.c
deleted file mode 100644 (file)
index 9cf330c..0000000
+++ /dev/null
@@ -1,657 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "bstr.h"
-#include <ctype.h>
-
-/**
- * Allocate a zero-length bstring, but reserving space for at least len bytes.
- *
- * @param len
- * @return New string
- */
-bstr *bstr_alloc(size_t len) {
-    unsigned char *s = malloc(sizeof (bstr_t) + len);
-    if (s == NULL) return NULL;
-
-    bstr_t *b = (bstr_t *) s;
-    b->len = 0;
-    b->size = len;
-    b->ptr = NULL;
-
-    return (bstr *) s;
-}
-
-/**
- * Deallocate a bstring. Allows a NULL bstring on input.
- *
- * @param b
- */
-void bstr_free(bstr *b) {
-    if (b == NULL) return;
-    free(b);
-}
-
-/**
- * Append source bstring to destination bstring, growing
- * destination if necessary.
- *
- * @param destination
- * @param source
- * @return destination, at a potentially different memory location
- */
-bstr *bstr_add_str(bstr *destination, bstr *source) {
-    return bstr_add_mem(destination, bstr_ptr(source), bstr_len(source));
-}
-
-/**
- * Append a NUL-terminated source to destination, growing
- * destination if necessary.
- *
- * @param destination
- * @param source
- * @return destination, at a potentially different memory location
- */
-bstr *bstr_add_cstr(bstr *destination, char *source) {
-    return bstr_add_mem(destination, source, strlen(source));
-}
-
-/**
- * Append a memory region to destination, growing destination
- * if necessary.
- *
- * @param destination
- * @param data
- * @param len
- * @return destination, at a potentially different memory location
- */
-bstr *bstr_add_mem(bstr *destination, char *data, size_t len) {    
-    if (bstr_size(destination) < bstr_len(destination) + len) {        
-        destination = bstr_expand(destination, bstr_len(destination) + len);
-        if (destination == NULL) return NULL;        
-    }    
-
-    bstr_t *b = (bstr_t *) destination;
-    memcpy(bstr_ptr(destination) + b->len, data, len);
-    b->len = b->len + len;   
-
-    return destination;
-}
-
-/**
- * Append source bstring to destination bstring, growing
- * destination if necessary.
- *
- * @param destination
- * @param source
- * @return destination, at a potentially different memory location
- */
-bstr *bstr_add_str_noex(bstr *destination, bstr *source) {
-    return bstr_add_mem_noex(destination, bstr_ptr(source), bstr_len(source));
-}
-
-/**
- * Append a NUL-terminated source to destination, growing
- * destination if necessary.
- *
- * @param destination
- * @param source
- * @return destination, at a potentially different memory location
- */
-bstr *bstr_add_cstr_noex(bstr *destination, char *source) {
-    return bstr_add_mem_noex(destination, source, strlen(source));
-}
-
-/**
- * Append a memory region to destination, growing destination
- * if necessary.
- *
- * @param destination
- * @param data
- * @param len
- * @return destination, at a potentially different memory location
- */
-bstr *bstr_add_mem_noex(bstr *destination, char *data, size_t len) {
-    size_t copylen = len;
-
-    if (bstr_size(destination) < bstr_len(destination) + copylen) {
-        copylen = bstr_size(destination) - bstr_len(destination);
-        if (copylen <= 0) return destination;
-    }
-
-    bstr_t *b = (bstr_t *) destination;
-    memcpy(bstr_ptr(destination) + b->len, data, copylen);
-    b->len = b->len + copylen;
-
-    return destination;
-}
-
-/**
- * Expand a string to support at least newsize bytes. The input bstring
- * is not changed if it is big enough to accommodate the desired size. If
- * the input bstring is smaller, however, it is expanded. The pointer to
- * the bstring may change. If the expansion fails, the original bstring
- * is left untouched (it is not freed).
- *
- * @param s
- * @param newsize
- * @return new bstring, or NULL if memory allocation failed
- */
-bstr *bstr_expand(bstr *s, size_t newsize) {
-    if (((bstr_t *) s)->ptr != NULL) {
-        void * newblock = realloc(((bstr_t *) s)->ptr, newsize);
-        if (newblock == NULL) {
-            return NULL;
-        } else {
-            ((bstr_t *) s)->ptr = newblock;
-        }
-    } else {
-        void *newblock = realloc(s, sizeof (bstr_t) + newsize);
-        if (newblock == NULL) {
-            return NULL;
-        } else {
-            s = newblock;
-        }
-    }
-
-    ((bstr_t *) s)->size = newsize;
-
-    return s;
-}
-
-/**
- * Create a new bstring by copying the provided NUL-terminated string.
- *
- * @param data
- * @return new bstring
- */
-bstr *bstr_cstrdup(char *data) {
-    return bstr_memdup(data, strlen(data));
-}
-
-/**
- * Create a new bstring by copying the provided memory region.
- *
- * @param data
- * @param len
- * @return new bstring
- */
-bstr *bstr_memdup(char *data, size_t len) {
-    bstr *b = bstr_alloc(len);
-    if (b == NULL) return NULL;
-    memcpy(bstr_ptr(b), data, len);
-    ((bstr_t *) b)->len = len;
-    return b;
-}
-
-/**
- * Create a new bstring by copying the provided bstring.
- *
- * @param b
- * @return new bstring
- */
-bstr *bstr_strdup(bstr *b) {
-    return bstr_strdup_ex(b, 0, bstr_len(b));
-}
-
-/**
- * Create a new bstring by copying a part of the provided
- * bstring.
- *
- * @param b
- * @param offset
- * @param len
- * @return new bstring
- */
-bstr *bstr_strdup_ex(bstr *b, size_t offset, size_t len) {
-    bstr *bnew = bstr_alloc(len);
-    if (bnew == NULL) return NULL;
-    memcpy(bstr_ptr(bnew), bstr_ptr(b) + offset, len);
-    ((bstr_t *) bnew)->len = len;
-    return bnew;
-}
-
-/**
- * Take the provided memory region and construct a NUL-terminated
- * string, replacing NUL bytes with "\0".
- *
- * @param data
- * @param len
- * @return new NUL-terminated string
- */
-char *bstr_memtocstr(char *data, size_t len) {
-    // Count how many NUL bytes we have in the string.
-    size_t i, nulls = 0;
-    for (i = 0; i < len; i++) {
-        if (data[i] == '\0') {
-            nulls++;
-        }
-    }
-
-    // Now copy the string into a NUL-terminated buffer.
-    char *r, *t;
-    r = t = malloc(len + nulls + 1);
-    if (t == NULL) return NULL;
-
-    while (len--) {
-        // Escape NUL bytes, but just copy everything else.
-        if (*data == '\0') {
-            data++;
-            *t++ = '\\';
-            *t++ = '0';
-        } else {
-            *t++ = *data++;
-        }
-    }
-
-    // Terminate string.
-    *t = '\0';
-
-    return r;
-}
-
-/**
- * Create a new NUL-terminated string out of the provided bstring.
- *
- * @param b
- * @return new NUL-terminated string
- */
-char *bstr_tocstr(bstr *b) {
-    if (b == NULL) return NULL;
-    return bstr_memtocstr(bstr_ptr(b), bstr_len(b));
-}
-
-/**
- * Return the first position of the provided character (byte).
- *
- * @param b
- * @param c
- * @return the first position of the character, or -1 if it could not be found
- */
-int bstr_chr(bstr *b, int c) {
-    char *data = bstr_ptr(b);
-    size_t len = bstr_len(b);
-
-    size_t i = 0;
-    while (i < len) {
-        if (data[i] == c) {
-            return i;
-        }
-
-        i++;
-    }
-
-    return -1;
-}
-
-/**
- * Return the last position of a character (byte).
- *
- * @param b
- * @param c
- * @return the last position of the character, or -1 if it could not be found
- */
-int bstr_rchr(bstr *b, int c) {
-    char *data = bstr_ptr(b);
-    size_t len = bstr_len(b);
-
-    int i = len;
-    while (i >= 0) {
-        if (data[i] == c) {
-            return i;
-        }
-
-        i--;
-    }
-
-    return -1;
-}
-
-/**
- * Compare two memory regions.
- *
- * @param s1
- * @param l1
- * @param s2
- * @param l2
- * @return 0 if the memory regions are identical, -1 or +1 if they're not
- */
-int bstr_cmp_ex(char *s1, size_t l1, char *s2, size_t l2) {
-    size_t p1 = 0, p2 = 0;
-
-    while ((p1 < l1) && (p2 < l2)) {
-        if (s1[p1] != s2[p2]) {
-            // Difference
-            return (s1[p1] < s2[p2]) ? -1 : 1;
-        }
-
-        p1++;
-        p2++;
-    }
-
-    if ((p1 == l2) && (p2 == l1)) {
-        // They're identical
-        return 0;
-    } else {
-        // One string is shorter
-        if (p1 == l1) return -1;
-        else return 1;
-    }
-}
-
-/**
- * Case-insensitive comparison of two memory regions.
- *
- * @param s1
- * @param l1
- * @param s2
- * @param l2
- * @return 0 if the memory regions are identical, -1 or +1 if they're not
- */
-int bstr_cmp_nocase_ex(char *s1, size_t l1, char *s2, size_t l2) {
-    size_t p1 = 0, p2 = 0;
-
-    while ((p1 < l1) && (p2 < l2)) {
-        if (tolower((int)s1[p1]) != tolower((int)s2[p2])) {
-            // Difference
-            return (tolower((int)s1[p1]) < tolower((int)s2[p2])) ? -1 : 1;
-        }
-
-        p1++;
-        p2++;
-    }
-
-    if ((p1 == l2) && (p2 == l1)) {
-        // They're identical
-        return 0;
-    } else {
-        // One string is shorter
-        if (p1 == l1) return -1;
-        else return 1;
-    }
-}
-
-/**
- * Compare a bstring with a NUL-terminated string.
- *
- * @param b
- * @param c
- * @return 0, -1 or +1
- */
-int bstr_cmpc(bstr *b, char *c) {
-    return bstr_cmp_ex(bstr_ptr(b), bstr_len(b), c, strlen(c));
-}
-
-/**
- * Compare two bstrings.
- *
- * @param b1
- * @param b2
- * @return 0, -1 or +1
- */
-int bstr_cmp(bstr *b1, bstr *b2) {
-    return bstr_cmp_ex(bstr_ptr(b1), bstr_len(b1), bstr_ptr(b2), bstr_len(b2));
-}
-
-/**
- * Case-insensitive comparison two bstrings.
- *
- * @param b1
- * @param b2
- * @return 0, -1 or +1
- */
-int bstr_cmp_nocase(bstr *b1, bstr *b2) {
-    return bstr_cmp_nocase_ex(bstr_ptr(b1), bstr_len(b1), bstr_ptr(b2), bstr_len(b2));
-}
-
-/**
- * Convert bstring to lowercase.
- *
- * @param b
- * @return b
- */
-bstr *bstr_tolowercase(bstr *b) {
-    if (b == NULL) return NULL;
-
-    unsigned char *data = (unsigned char *)bstr_ptr(b);
-    size_t len = bstr_len(b);
-
-    size_t i = 0;
-    while (i < len) {
-        data[i] = tolower(data[i]);
-        i++;
-    }
-
-    return b;
-}
-
-/**
- * Create a copy of the provided bstring, then convert it to lowercase.
- *
- * @param b
- * @return bstring copy
- */
-bstr *bstr_dup_lower(bstr *b) {
-    return bstr_tolowercase(bstr_strdup(b));
-}
-
-/**
- *
- */
-int bstr_util_memtoip(char *data, size_t len, int base, size_t *lastlen) {
-    int rval = 0, tval = 0, tflag = 0;
-
-    size_t i = *lastlen = 0;
-    for (i = 0; i < len; i++) {
-        int d = data[i];
-
-        *lastlen = i;
-
-        // Convert character to digit.
-        if ((d >= '0') && (d <= '9')) {
-            d -= '0';
-        } else if ((d >= 'a') && (d <= 'z')) {
-            d -= 'a' - 10;
-        } else if ((d >= 'A') && (d <= 'Z')) {
-            d -= 'A' - 10;
-        } else {
-            d = -1;
-        }
-
-        // Check that the digit makes sense with the base
-        // we are using.
-        if ((d == -1) || (d >= base)) {
-            if (tflag) {
-                // Return what we have so far; lastlen points
-                // to the first non-digit position.
-                return rval;
-            } else {
-                // We didn't see a single digit.
-                return -1;
-            }
-        }
-
-        if (tflag) {
-            rval *= base;
-
-            if (tval > rval) {
-                // Overflow
-                return -2;
-            }
-
-            rval += d;
-
-            if (tval > rval) {
-                // Overflow
-                return -2;
-            }
-
-            tval = rval;
-        } else {
-            tval = rval = d;
-            tflag = 1;
-        }
-    }
-
-    *lastlen = i + 1;
-
-    return rval;
-}
-
-/**
- * Find needle in a haystack.
- *
- * @param haystack
- * @param needle
- * @return
- */
-int bstr_indexof(bstr *haystack, bstr *needle) {
-    return bstr_indexofmem(haystack, bstr_ptr(needle), bstr_len(needle));
-}
-
-/**
- * Find index in the haystack, with the needle being a NUL-terminated string.
- *
- * @param haystack
- * @param needle
- * @return
- */
-int bstr_indexofc(bstr *haystack, char *needle) {
-    return bstr_indexofmem(haystack, needle, strlen(needle));
-}
-
-/**
- * Find index in the haystack. Ignore case differences.
- *
- * @param haystack
- * @param needle
- * @return
- */
-int bstr_indexof_nocase(bstr *haystack, bstr *needle) {
-    return bstr_indexofmem_nocase(haystack, bstr_ptr(needle), bstr_len(needle));
-}
-
-/**
- * Find index in the haystack, with the needle being a NUL-terminated string.
- * Ignore case differences.
- *
- * @param haystack
- * @param needle
- * @return
- */
-int bstr_indexofc_nocase(bstr *haystack, char *needle) {
-    return bstr_indexofmem_nocase(haystack, needle, strlen(needle));
-}
-
-/**
- * Find index in the haystack, with the needle being a memory region.
- *
- * @param haystack
- * @param data2
- * @param len2
- * @return
- */
-int bstr_indexofmem(bstr *haystack, char *data2, size_t len2) {
-    unsigned char *data = (unsigned char *)bstr_ptr(haystack);
-    size_t len = bstr_len(haystack);
-    size_t i, j;
-
-    // TODO Is an optimisation here justified?
-    //      http://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm
-    
-    for (i = 0; i < len; i++) {
-        size_t k = i;
-
-        for (j = 0; ((j < len2) && (k < len)); j++) {
-            if (data[k++] != data2[j]) break;
-        }
-
-        if ((k - i) == len2) {
-            return i;
-        }
-    }
-
-    return -1;
-}
-
-/**
- * Find index in the haystack, with the needle being a memory region.
- * Ignore case differences.
- *
- * @param haystack
- * @param data2
- * @param len2
- * @return
- */
-int bstr_indexofmem_nocase(bstr *haystack, char *data2, size_t len2) {
-    unsigned char *data = (unsigned char *)bstr_ptr(haystack);
-    size_t len = bstr_len(haystack);
-    size_t i, j;
-
-    // TODO No need to inspect the last len2 - 1 bytes
-    for (i = 0; i < len; i++) {
-        size_t k = i;
-
-        for (j = 0; ((j < len2) && (k < len)); j++) {
-            if (toupper(data[k++]) != toupper((unsigned char)data2[j])) break;
-        }
-
-        if ((k - i) == len2) {
-            return i;
-        }
-    }
-
-    return -1;
-}
-
-/**
- * Remove one byte from the end of the string.
- *
- * @param s
- */
-void bstr_chop(bstr *s) {
-    bstr_t *b = (bstr_t *) s;
-    if (b->len > 0) {
-        b->len--;
-    }
-}
-
-/**
- * Adjust bstring length. You will need to use this method whenever
- * you work directly with the string contents, and you end up changing
- * its length.
- *
- * @param s
- * @param newlen
- */
-void bstr_len_adjust(bstr *s, size_t newlen) {
-    bstr_t *b = (bstr_t *) s;
-    b->len = newlen;
-}
-
-/**
- * Return the character (byte) at the given position.
- *
- * @param s
- * @param pos
- * @return the character, or -1 if the bstring is too short
- */
-char bstr_char_at(bstr *s, size_t pos) {
-    unsigned char *data = (unsigned char *)bstr_ptr(s);
-    size_t len = bstr_len(s);
-
-    if (pos > len) return -1;
-    return data[pos];
-}
-
diff --git a/libhtp/htp/bstr.h b/libhtp/htp/bstr.h
deleted file mode 100644 (file)
index 9122249..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _BSTR_H
-#define        _BSTR_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// IMPORTANT This binary string library is used internally by the parser and you should
-//           not rely on it in your code. The implementation may change.
-//
-// TODO
-//           - Add a function that wraps an existing data
-//           - Support Unicode bstrings
-
-typedef void * bstr;
-
-bstr *bstr_alloc(size_t newsize);
-void  bstr_free(bstr *s);
-bstr *bstr_expand(bstr *s, size_t newsize);
-bstr *bstr_cstrdup(char *);
-bstr *bstr_memdup(char *data, size_t len);
-bstr *bstr_strdup(bstr *b);
-bstr *bstr_strdup_ex(bstr *b, size_t offset, size_t len);
-char *bstr_tocstr(bstr *);
-
-int bstr_chr(bstr *, int);
-int bstr_rchr(bstr *, int);
-
-int bstr_cmpc(bstr *, char *);
-int bstr_cmp(bstr *, bstr *);
-int bstr_cmp_nocase(bstr *, bstr *);
-
-bstr *bstr_dup_lower(bstr *);
-bstr *bstr_tolowercase(bstr *);
-
-bstr *bstr_add_mem(bstr *, char *, size_t);
-bstr *bstr_add_str(bstr *, bstr *);
-bstr *bstr_add_cstr(bstr *, char *);
-
-bstr *bstr_add_mem_noex(bstr *, char *, size_t);
-bstr *bstr_add_str_noex(bstr *, bstr *);
-bstr *bstr_add_cstr_noex(bstr *, char *);
-
-int bstr_util_memtoip(char *data, size_t len, int base, size_t *lastlen);
-char *bstr_memtocstr(char *data, size_t len);
-
-int bstr_indexof(bstr *haystack, bstr *needle);
-int bstr_indexofc(bstr *haystack, char *needle);
-int bstr_indexof_nocase(bstr *haystack, bstr *needle);
-int bstr_indexofc_nocase(bstr *haystack, char *needle);
-int bstr_indexofmem(bstr *haystack, char *data, size_t len);
-int bstr_indexofmem_nocase(bstr *haystack, char *data, size_t len);
-
-void bstr_chop(bstr *b);
-void bstr_len_adjust(bstr *s, size_t newlen);
-
-char bstr_char_at(bstr *s, size_t pos);
-typedef struct bstr_t bstr_t;
-
-struct bstr_t {
-    /** The length of the string stored in the buffer. */
-    size_t len;
-      
-    /** The current size of the buffer. If the buffer is bigger than the
-     *  string then it will be able to expand without having to reallocate.
-     */
-    size_t size;
-
-    /** Optional buffer pointer. If this pointer is NUL (as it currently is
-     *  in virtually all cases, the string buffer will immediatelly follow
-     *  this structure. If the pointer is not NUL, it points to the actual
-     *  buffer used, and there's no data following this structure.
-     */
-    char *ptr;
-};
-
-#define bstr_len(X) ((*(bstr_t *)(X)).len)
-#define bstr_size(X) ((*(bstr_t *)(X)).size)
-#define bstr_ptr(X) ( ((*(bstr_t *)(X)).ptr == NULL) ? (char *)((char *)(X) + sizeof(bstr_t)) : (char *)(*(bstr_t *)(X)).ptr )
-
-#endif /* _BSTR_H */
-
diff --git a/libhtp/htp/dslib.c b/libhtp/htp/dslib.c
deleted file mode 100644 (file)
index 507094b..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "dslib.h"
-
-
-// -- Queue List --
-
-/**
- * Add element to list.
- *
- * @param list
- * @param element
- * @return 1 on success, -1 on error (memory allocation failure)
- */
-static int list_linked_push(list_t *_q, void *element) {
-    list_linked_t *q = (list_linked_t *) _q;
-    list_linked_element_t *qe = calloc(1, sizeof (list_linked_element_t));
-    if (qe == NULL) return -1;
-
-    // Rememeber the element
-    qe->data = element;
-
-    // If the queue is empty, make this element first
-    if (!q->first) {
-        q->first = qe;
-    }
-
-    if (q->last) {
-        q->last->next = qe;
-    }
-
-    q->last = qe;
-
-    return 1;
-}
-
-/**
- * Remove one element from the beginning of the list.
- *
- * @param list
- * @return a pointer to the removed element, or NULL if the list is empty.
- */
-static void *list_linked_pop(list_t *_q) {
-    list_linked_t *q = (list_linked_t *) _q;
-    void *r = NULL;
-
-    if (!q->first) {
-        return NULL;
-    }
-
-    list_linked_element_t *qe = q->first;
-    q->first = qe->next;
-    r = qe->data;
-
-    if (!q->first) {
-        q->last = NULL;
-    }
-
-    free(qe);
-
-    return r;
-}
-
-/**
- * Is the list empty?
- *
- * @param list
- * @return 1 if the list is empty, 0 if it is not
- */
-static int list_linked_empty(list_t *_q) {
-    list_linked_t *q = (list_linked_t *) _q;
-
-    if (!q->first) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-/**
- * Destroy list. This function will not destroy any of the
- * data stored in it. You'll have to do that manually beforehand.
- *
- * @param l
- */
-void list_linked_destroy(list_linked_t *l) {
-    // Free the list structures
-    list_linked_element_t *temp = l->first;
-    list_linked_element_t *prev = NULL;
-    while (temp != NULL) {
-        free(temp->data);
-        prev = temp;
-        temp = temp->next;
-        free(prev);
-    }
-
-    // Free the list itself
-    free(l);
-}
-
-/**
- * Create a new linked list.
- *
- * @return a pointer to the newly creted list (list_t), or NULL on memory allocation failure
- */
-list_t *list_linked_create(void) {
-    list_linked_t *q = calloc(1, sizeof (list_linked_t));
-    if (q == NULL) return NULL;
-
-    q->push = list_linked_push;
-    q->pop = list_linked_pop;
-    q->empty = list_linked_empty;
-    q->destroy = (void (*)(list_t *))list_linked_destroy;
-
-    return (list_t *) q;
-}
-
-// -- Queue Array --
-
-/**
- * Add new element to the end of the list, expanding the list
- * as necessary.
- *
- * @param list
- * @param element
- *
- * @return 1 on success or -1 on failure (memory allocation)
- */
-static int list_array_push(list_t *_q, void *element) {
-    list_array_t *q = (list_array_t *) _q;
-
-    // Check if we're full
-    if (q->current_size >= q->max_size) {
-        int new_size = q->max_size * 2;
-        void *newblock = NULL;
-        
-        if (q->first == 0) {
-            // The simple case of expansion is when the first
-            // element in the list resides in the first slot. In
-            // that case we just add some new space to the end,
-            // adjust the max_size and that's that.
-            newblock = realloc(q->elements, new_size * sizeof (void *));
-            if (newblock == NULL) return -1;
-        } else {
-            // When the first element is not in the first
-            // memory slot, we need to rearrange the order
-            // of the elements in order to expand the storage area.
-            newblock = malloc(new_size * sizeof (void *));
-            if (newblock == NULL) return -1;
-
-            // Copy the beginning of the list to the beginning of the new memory block
-            memcpy(newblock, (char *)q->elements + q->first * sizeof (void *), (q->max_size - q->first) * sizeof (void *));
-            // Append the second part of the list to the end
-            memcpy((char *)newblock + (q->max_size - q->first) * sizeof (void *), q->elements, q->first * sizeof (void *));
-            
-            free(q->elements);
-        }
-        
-        q->first = 0;
-        q->last = q->current_size;
-        q->max_size = new_size;
-        q->elements = newblock;
-    }
-
-    q->elements[q->last] = element;
-    q->current_size++;
-    
-    q->last++;
-    if (q->last == q->max_size) {
-        q->last = 0;
-    }
-
-    return 1;
-}
-
-/**
- * Remove one element from the beginning of the list.
- *
- * @param list
- * @return the removed element, or NULL if the list is empty
- */
-static void *list_array_pop(list_t *_q) {
-    list_array_t *q = (list_array_t *) _q;
-    void *r = NULL;
-
-    if (q->current_size == 0) {
-        return NULL;
-    }
-
-    r = q->elements[q->first];
-    q->first++;
-    if (q->first == q->max_size) {
-        q->first = 0;
-    }
-
-    q->current_size--;
-
-    return r;
-}
-
-/**
- * Returns the size of the list.
- *
- * @param list
- */
-static size_t list_array_size(list_t *_l) {
-    return ((list_array_t *) _l)->current_size;
-}
-
-/**
- * Return the element at the given index.
- *
- * @param list
- * @param index
- * @return the desired element, or NULL if the list is too small, or
- *         if the element at that position carries a NULL
- */
-static void *list_array_get(list_t *_l, size_t idx) {
-    list_array_t *l = (list_array_t *) _l;
-    void *r = NULL;
-
-    if (idx + 1 > l->current_size) return NULL;
-
-    size_t i = l->first;
-    r = l->elements[l->first];
-
-    while (idx--) {
-        if (++i == l->max_size) {
-            i = 0;
-        }
-
-        r = l->elements[i];
-    }
-
-    return r;
-}
-
-/**
- * Replace the element at the given index with the provided element.
- *
- * @param list
- * @param index
- * @param element
- *
- * @return 1 if the element was replaced, or 0 if the list is too small
- */
-static int list_array_replace(list_t *_l, size_t idx, void *element) {
-    list_array_t *l = (list_array_t *) _l;    
-
-    if (idx + 1 > l->current_size) return 0;
-
-    size_t i = l->first;
-
-    while (idx--) {
-        if (++i == l->max_size) {
-            i = 0;
-        }
-    }
-
-    l->elements[i] = element;
-
-    return 1;
-}
-
-/**
- * Reset the list iterator.
- *
- * @param l
- */
-void list_array_iterator_reset(list_array_t *l) {
-    l->iterator_index = 0;
-}
-
-/**
- * Advance to the next list value.
- *
- * @param l
- * @return the next list value, or NULL if there aren't more elements
- *         left to iterate over or if the element itself is NULL
- */
-void *list_array_iterator_next(list_array_t *l) {
-    void *r = NULL;
-
-    if (l->iterator_index < l->current_size) {
-        r = list_get(l, l->iterator_index);
-        l->iterator_index++;
-    }
-
-    return r;
-}
-
-/**
- * Free the memory occupied by this list. This function assumes
- * the data elements were freed beforehand.
- *
- * @param l
- */
-void list_array_destroy(list_array_t *l) {
-    free(l->elements);
-    free(l);
-}
-
-/**
- * Create new array-based list.
- *
- * @param size
- * @return newly allocated list (list_t)
- */
-list_t *list_array_create(size_t size) {
-    // Allocate the list structure
-    list_array_t *q = calloc(1, sizeof (list_array_t));
-    if (q == NULL) return NULL;
-
-    // Allocate the initial batch of elements
-    q->elements = malloc(size * sizeof (void *));
-    if (q->elements == NULL) {
-        free(q);
-        return NULL;
-    }
-
-    // Initialise structure
-    q->first = 0;
-    q->last = 0;
-    q->max_size = size;
-    q->push = list_array_push;
-    q->pop = list_array_pop;
-    q->get = list_array_get;
-    q->replace = list_array_replace;
-    q->size = list_array_size;
-    q->iterator_reset = (void (*)(list_t *))list_array_iterator_reset;
-    q->iterator_next = (void *(*)(list_t *))list_array_iterator_next;
-    q->destroy = (void (*)(list_t *))list_array_destroy;
-
-    return (list_t *) q;
-}
-
-
-// -- Table --
-
-/**
- * Create a new table structure.
- *
- * @param size
- * @return newly created table_t
- */
-table_t *table_create(size_t size) {
-    table_t *t = calloc(1, sizeof (table_t));
-    if (t == NULL) return NULL;
-
-    // Use a list behind the scenes
-    t->list = list_array_create(size * 2);
-    if (t->list == NULL) {
-        free(t);
-        return NULL;
-    }
-    
-    return t;
-}
-
-/**
- * Destroy a table.
- *
- * @param table
- */
-void table_destroy(table_t * table) {
-    // Free keys only
-    int counter = 0;
-    void *data = NULL;
-
-    list_iterator_reset(table->list);
-
-    while ((data = list_iterator_next(table->list)) != NULL) {
-        // Free key
-        if ((counter % 2) == 0) {
-            free(data);
-        }
-
-        counter++;
-    }
-
-    list_destroy(table->list);
-
-    free(table);
-}
-
-/**
- * Add a new table element. This function currently makes a copy of
- * the key, which is inefficient.
- *
- * @param table
- * @param key
- * @param element
- */
-int table_add(table_t *table, bstr *key, void *element) {
-    // Lowercase key
-    bstr *lkey = bstr_dup_lower(key);
-    if (lkey == NULL) {
-        return -1;
-    }   
-
-    // Add key
-    if (list_add(table->list, lkey) != 1) {
-        free(lkey);
-        return -1;
-    }
-
-    // Add element
-    if (list_add(table->list, element) != 1) {
-        list_pop(table->list);
-        free(lkey);
-        return -1;
-    }
-
-    return 1;
-}
-
-/**
- * @param table
- * @param key
- */
-static void *table_get_internal(table_t *table, bstr *key) {
-    // Iterate through the list, comparing
-    // keys with the parameter, return data if found.
-    bstr *ts = NULL;
-    list_iterator_reset(table->list);
-    while ((ts = list_iterator_next(table->list)) != NULL) {
-        void *data = list_iterator_next(table->list);
-        if (bstr_cmp(ts, key) == 0) {
-            return data;
-        }
-    }
-
-    return NULL;
-}
-
-/**
- * Retrieve the first element in the table with the given
- * key (as a NUL-terminated string).
- *
- * @param table
- * @param cstr
- * @return table element, or NULL if not found
- */
-void *table_getc(table_t *table, char *cstr) {
-    if (table == NULL||cstr == NULL)
-        return NULL;
-    // TODO This is very inefficient
-    bstr *key = bstr_cstrdup(cstr);
-    if (key == NULL)
-        return NULL;
-    bstr_tolowercase(key);
-    void *data = table_get_internal(table, key);
-    free(key);
-    return data;
-}
-
-/**
- * Retrieve the first element in the table with the given key.
- *
- * @param table
- * @param key
- * @return table element, or NULL if not found
- */
-void *table_get(table_t *table, bstr *key) {
-    if (table == NULL||key == NULL)
-        return NULL;
-    // TODO This is very inefficient
-    bstr *lkey = bstr_dup_lower(key);
-    if (lkey == NULL)
-        return NULL;
-    void *data = table_get_internal(table, lkey);
-    free(lkey);
-    return data;
-}
-
-/**
- * Reset the table iterator.
- *
- * @param table
- */
-void table_iterator_reset(table_t *table) {
-    list_iterator_reset(table->list);
-}
-
-/**
- * Advance to the next table element.
- *
- * @param t
- * @param data
- * @return pointer to the key and the element if there is a next element, NULL otherwise
- */
-bstr *table_iterator_next(table_t *t, void **data) {
-    bstr *s = list_iterator_next(t->list);
-    if (s != NULL) {
-        *data = list_iterator_next(t->list);
-    }
-
-    return s;
-}
-
-/**
- * Returns the size of the table.
- *
- * @param table
- * @return table size
- */
-size_t table_size(table_t *table) {
-    return list_size(table->list) / 2;
-}
-
-/**
- * Remove all elements from the table.
- *
- * @param table
- */
-void table_clear(table_t *table) {    
-    // TODO Clear table by removing the existing elements
-    if (table == NULL)
-        return;
-    size_t size = list_size(table->list);
-
-    list_destroy(table->list);
-    
-    // Use a list behind the scenes
-    table->list = list_array_create(size == 0 ? 10 : size);
-    if (table->list == NULL) {
-        free(table);        
-    }    
-}
-
-#if 0
-
-int main(int argc, char **argv) {
-    list_t *q = list_linked_create();
-
-    list_push(q, "1");
-    list_push(q, "2");
-    list_push(q, "3");
-    list_push(q, "4");
-
-    char *s = NULL;
-    while ((s = (char *) list_pop(q)) != NULL) {
-        printf("Got: %s\n", s);
-    }
-
-    free(q);
-}
-#endif
diff --git a/libhtp/htp/dslib.h b/libhtp/htp/dslib.h
deleted file mode 100644 (file)
index 1cc2b6c..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _DSLIB_H
-#define        _DSLIB_H
-
-#include "bstr.h"
-
-// IMPORTANT This library is used internally by the parser and you should
-//           not rely on it in your code. The implementation may change at
-//           some point in the future.
-
-// What we have here is two implementations of a list structure (array- and link-list-based),
-// and one implementation of a table (case-insensitive keys; multiple key values are allowed).
-// The lists can be used as a stack.
-//
-// TODO The table element retrieval if very inefficient at the moment.
-
-#define list_push(L, E) (L)->push(L, E)
-#define list_pop(L) (L)->pop(L)
-#define list_empty(L) (L)->empty(L)
-#define list_get(L, N) (L)->get((list_t *)L, N)
-#define list_replace(L, N, E) (L)->replace((list_t *)L, N, E)
-#define list_add(L, N) (L)->push(L, N)
-#define list_size(L) (L)->size(L)
-#define list_iterator_reset(L) (L)->iterator_reset(L)
-#define list_iterator_next(L) (L)->iterator_next(L)
-#define list_destroy(L) (L)->destroy(L)
-
-#define LIST_COMMON \
-    int (*push)(list_t *, void *); \
-    void *(*pop)(list_t *); \
-    int (*empty)(list_t *); \
-    void *(*get)(list_t *, size_t index); \
-    int (*replace)(list_t *, size_t index, void *); \
-    size_t (*size)(list_t *); \
-    void (*iterator_reset)(list_t *); \
-    void *(*iterator_next)(list_t *); \
-    void (*destroy)(list_t *)
-
-typedef struct list_t list_t;
-typedef struct list_array_t list_array_t;
-typedef struct list_linked_element_t list_linked_element_t;
-typedef struct list_linked_t list_linked_t;
-
-typedef struct table_t table_t;
-
-struct list_t {
-    LIST_COMMON;
-};
-
-struct list_linked_element_t {
-    void *data;
-    list_linked_element_t *next;
-};
-
-struct list_linked_t {
-    LIST_COMMON;
-
-    list_linked_element_t *first;
-    list_linked_element_t *last;
-};
-
-struct list_array_t {
-    LIST_COMMON;
-
-    size_t first;
-    size_t last;
-    size_t max_size;
-    size_t current_size;
-    void **elements;
-
-    size_t iterator_index;
-};
-
-list_t *list_linked_create(void);
-list_t *list_array_create(size_t size);
-
-struct table_t {
-    list_t *list;
-};
-
-table_t *table_create(size_t size);
-     int table_add(table_t *, bstr *, void *);
-    void table_set(table_t *, bstr *, void *);
-   void *table_get(table_t *, bstr *);
-   void *table_getc(table_t *, char *);
-    void table_iterator_reset(table_t *);
-   bstr *table_iterator_next(table_t *, void **);
-  size_t table_size(table_t *t);
-    void table_destroy(table_t *);
-    void table_clear(table_t *);
-
-#endif /* _DSLIB_H */
-
diff --git a/libhtp/htp/hooks.c b/libhtp/htp/hooks.c
deleted file mode 100644 (file)
index 37fd2c9..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "hooks.h"
-
-/**
- * Creates a new hook.
- *
- * @return New htp_hook_t structure on success, NULL on failure
- */
-htp_hook_t *hook_create() {
-    htp_hook_t *hook = calloc(1, sizeof (htp_hook_t));
-    if (hook == NULL) return NULL;
-
-    hook->callbacks = list_array_create(4);
-    if (hook->callbacks == NULL) {
-        free(hook);
-        return NULL;
-    }   
-
-    return hook;
-}
-
-/**
- * Creates a copy of the provided hook. The hook is allowed to be NULL,
- * in which case this function simply returns a NULL.
- *
- * @param hook
- * @return A copy of the hook, or NULL (if the provided hook was NULL
- *         or, if it wasn't, if there was a memory allocation problem while
- *         constructing a copy).
- */
-htp_hook_t * hook_copy(htp_hook_t *hook) {
-    if (hook == NULL) return NULL;
-
-    htp_hook_t *copy = hook_create();
-    if (copy == NULL) return NULL;
-
-    htp_callback_t *callback = NULL;
-    list_iterator_reset(hook->callbacks);
-    while ((callback = list_iterator_next(hook->callbacks)) != NULL) {
-        if (hook_register(&copy, callback->fn) < 0) {
-            hook_destroy(copy);
-            return NULL;
-        }
-    }
-
-    return copy;
-}
-
-/**
- * Destroys an existing hook. It is all right to send a NULL
- * to this method because it will simply return straight away.
- *
- * @param hook
- */
-void hook_destroy(htp_hook_t *hook) {
-    if (hook == NULL) return;
-
-    htp_callback_t *callback = NULL;
-    list_iterator_reset(hook->callbacks);
-    while ((callback = list_iterator_next(hook->callbacks)) != NULL) {
-        free(callback);
-    }
-
-    list_destroy(hook->callbacks);
-    
-    free(hook);
-}
-
-/**
- * Registers a new callback with the hook.
- *
- * @param hook
- * @param callback_fn
- * @return 1 on success, -1 on memory allocation error
- */
-int hook_register(htp_hook_t **hook, int (*callback_fn)()) {
-    int hook_created = 0;
-    htp_callback_t *callback = calloc(1, sizeof (htp_callback_t));
-    if (callback == NULL) return -1;
-
-    callback->fn = callback_fn;
-
-    // Create a new hook if one does not exist
-    if (*hook == NULL) {
-        *hook = hook_create();
-        if (*hook == NULL) {
-            free(callback);
-            return -1;
-        }
-
-        hook_created = 1;
-    }
-
-    // Add callback 
-    if (list_add((*hook)->callbacks, callback) < 0) {
-        if (hook_created) {
-            free(*hook);
-        }
-        
-        free(callback);
-        return -1;
-    }
-
-    return 1;
-}
-
-/**
- * Runs all the callbacks associated with a given hook. Only stops if
- * one of the callbacks returns an error (HOOK_ERROR). 
- *
- * @param hook
- * @param data
- * @return HOOK_OK or HOOK_ERROR
- */
-int hook_run_all(htp_hook_t *hook, void *data) {
-    if (hook == NULL) {
-        return HOOK_OK;
-    }
-
-    /* HACK https://redmine.openinfosecfoundation.org/issues/601 */
-    size_t i = 0;
-    for (i = 0; i < ((list_array_t *)hook->callbacks)->current_size; i++) {
-        void *r = ((list_array_t *)hook->callbacks)->elements[i];
-        if (r == NULL)
-            continue;
-
-        htp_callback_t *callback = r;
-        if (callback->fn(data) == HOOK_ERROR) {
-            return HOOK_ERROR;
-        }
-    }
-#if 0
-    htp_callback_t *callback = NULL;
-    list_iterator_reset(hook->callbacks);
-    while ((callback = list_iterator_next(hook->callbacks)) != NULL) {
-        if (callback->fn(data) == HOOK_ERROR) {
-            return HOOK_ERROR;
-        }
-    }
-#endif
-    return HOOK_OK;
-}
-
-/**
- * Run callbacks until one of them accepts to service the hook.
- *
- * @param hook
- * @param data
- * @return HOOK_OK on success, HOOK_DECLINED if no callback wanted to run and HOOK_ERROR on error.
- */
-int hook_run_one(htp_hook_t *hook, void *data) {
-    if (hook == NULL) {
-        return HOOK_DECLINED;
-    }
-
-    /* HACK https://redmine.openinfosecfoundation.org/issues/601 */
-    size_t i = 0;
-    for (i = 0; i < ((list_array_t *)hook->callbacks)->current_size; i++) {
-        void *r = ((list_array_t *)hook->callbacks)->elements[i];
-        if (r == NULL)
-            continue;
-
-        htp_callback_t *callback = r;
-        int status = callback->fn(data);
-        if (status != HOOK_DECLINED) {
-            return status;
-        }
-    }
-#if 0
-    htp_callback_t *callback = NULL;
-    list_iterator_reset(hook->callbacks);
-    while ((callback = list_iterator_next(hook->callbacks)) != NULL) {
-        int status = callback->fn(data);
-        // Both HOOK_OK and HOOK_ERROR will stop hook processing
-        if (status != HOOK_DECLINED) {
-            return status;
-        }
-    }
-#endif
-    return HOOK_DECLINED;
-}
diff --git a/libhtp/htp/hooks.h b/libhtp/htp/hooks.h
deleted file mode 100644 (file)
index 80ced94..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _HOOKS_H
-#define        _HOOKS_H
-
-#include "dslib.h"
-
-#ifdef _HTP_H
-#define HOOK_ERROR      HTP_ERROR
-#define HOOK_OK         HTP_OK
-#define HOOK_DECLINED   HTP_DECLINED
-#else
-#define HOOK_ERROR      -1
-#define HOOK_OK          0
-#define HOOK_DECLINED    1
-#endif
-
-typedef struct htp_hook_t htp_hook_t;
-typedef struct htp_callback_t htp_callback_t;
-
-struct htp_hook_t {
-    list_t *callbacks;
-};
-
-struct htp_callback_t {
-    int (*fn)();        
-};
-
- int hook_register(htp_hook_t **hook, int (*callback_fn)());
- int hook_run_one(htp_hook_t *hook, void *data);
- int hook_run_all(htp_hook_t *hook, void *data);
-
-htp_hook_t *hook_create();
-htp_hook_t *hook_copy(htp_hook_t *hook);
-       void hook_destroy(htp_hook_t *hook);
-
-
-#endif /* _HOOKS_H */
-
diff --git a/libhtp/htp/htp.c b/libhtp/htp/htp.c
deleted file mode 100644 (file)
index 4fc92d7..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <stdlib.h>
-#include "htp.h"
-
-/**
- * Returns the library version.
- */
-const char *htp_get_version() {    
-    return HTP_BASE_VERSION_TEXT;
-}
-
-
-
-
diff --git a/libhtp/htp/htp.h b/libhtp/htp/htp.h
deleted file mode 100644 (file)
index 01465fa..0000000
+++ /dev/null
@@ -1,1168 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _HTP_H
-#define        _HTP_H
-
-typedef struct htp_cfg_t htp_cfg_t;
-typedef struct htp_conn_t htp_conn_t;
-typedef struct htp_connp_t htp_connp_t;
-typedef struct htp_header_t htp_header_t;
-typedef struct htp_header_line_t htp_header_line_t;
-typedef struct htp_log_t htp_log_t;
-typedef struct htp_tx_data_t htp_tx_data_t;
-typedef struct htp_tx_t htp_tx_t;
-typedef struct htp_uri_t htp_uri_t;
-typedef struct htp_urldecoder_t htp_urldecoder_t;
-
-#include <ctype.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "bstr.h"
-#include "dslib.h"
-#include "hooks.h"
-#include "htp_decompressors.h"
-
-// -- Defines -------------------------------------------------------------------------------------
-
-#define HTP_BASE_VERSION_TEXT  "0.2.12"
-
-#define HTP_ERROR              -1
-#define HTP_OK                  0
-#define HTP_DATA                1
-#define HTP_DATA_OTHER          2
-#define HTP_DECLINED            3
-
-#define PROTOCOL_UNKNOWN        -1
-#define HTTP_0_9                9
-#define HTTP_1_0                100
-#define HTTP_1_1                101
-
-#define COMPRESSION_NONE        0
-#define COMPRESSION_GZIP        1
-#define COMPRESSION_COMPRESS    2 // Not implemented
-#define COMPRESSION_DEFLATE     3 // Not implemented
-
-#define HTP_LOG_MARK                __FILE__,__LINE__
-
-#define HTP_LOG_ERROR               1
-#define HTP_LOG_WARNING             2
-#define HTP_LOG_NOTICE              3
-#define HTP_LOG_INFO                4
-#define HTP_LOG_DEBUG               5
-#define HTP_LOG_DEBUG2              6
-
-#define HTP_HEADER_MISSING_COLON            1
-#define HTP_HEADER_INVALID_NAME             2
-#define HTP_HEADER_LWS_AFTER_FIELD_NAME     3
-#define HTP_LINE_TOO_LONG_HARD              4
-#define HTP_LINE_TOO_LONG_SOFT              5
-
-#define HTP_HEADER_LIMIT_HARD               18000
-#define HTP_HEADER_LIMIT_SOFT               9000
-
-#define LOG_NO_CODE             0
-
-#define CR '\r'
-#define LF '\n'
-
-#define M_UNKNOWN              -1
-
-// The following request method are defined in Apache 2.2.13, in httpd.h.
-#define M_GET                   0
-#define M_PUT                   1
-#define M_POST                  2
-#define M_DELETE                3
-#define M_CONNECT               4
-#define M_OPTIONS               5
-#define M_TRACE                 6
-#define M_PATCH                 7
-#define M_PROPFIND              8
-#define M_PROPPATCH             9
-#define M_MKCOL                 10
-#define M_COPY                  11
-#define M_MOVE                  12
-#define M_LOCK                  13
-#define M_UNLOCK                14
-#define M_VERSION_CONTROL       15
-#define M_CHECKOUT              16
-#define M_UNCHECKOUT            17
-#define M_CHECKIN               18
-#define M_UPDATE                19
-#define M_LABEL                 20
-#define M_REPORT                21
-#define M_MKWORKSPACE           22
-#define M_MKACTIVITY            23
-#define M_BASELINE_CONTROL      24
-#define M_MERGE                 25
-#define M_INVALID               26
-
-// Interestingly, Apache does not define M_HEAD
-#define M_HEAD                  1000
-
-#define HTP_FIELD_UNPARSEABLE           0x000001
-#define HTP_FIELD_INVALID               0x000002
-#define HTP_FIELD_FOLDED                0x000004
-#define HTP_FIELD_REPEATED              0x000008
-#define HTP_FIELD_LONG                  0x000010
-#define HTP_FIELD_NUL_BYTE              0x000020
-#define HTP_REQUEST_SMUGGLING           0x000040
-#define HTP_INVALID_FOLDING             0x000080
-#define HTP_INVALID_CHUNKING            0x000100
-#define HTP_MULTI_PACKET_HEAD           0x000200
-#define HTP_HOST_MISSING                0x000400
-#define HTP_AMBIGUOUS_HOST              0x000800
-#define HTP_PATH_ENCODED_NUL            0x001000
-#define HTP_PATH_INVALID_ENCODING       0x002000
-#define HTP_PATH_INVALID                0x004000
-#define HTP_PATH_OVERLONG_U             0x008000
-#define HTP_PATH_ENCODED_SEPARATOR      0x010000
-
-#define HTP_PATH_UTF8_VALID             0x020000 /* At least one valid UTF-8 character and no invalid ones */
-#define HTP_PATH_UTF8_INVALID           0x040000
-#define HTP_PATH_UTF8_OVERLONG          0x080000
-#define HTP_PATH_FULLWIDTH_EVASION      0x100000 /* Range U+FF00 - U+FFFF detected */
-
-#define PIPELINED_CONNECTION        1
-
-#define HTP_SERVER_MINIMAL          0
-#define HTP_SERVER_GENERIC          1
-#define HTP_SERVER_IDS              2
-#define HTP_SERVER_IIS_4_0          4   /* Windows NT 4.0 */
-#define HTP_SERVER_IIS_5_0          5   /* Windows 2000 */
-#define HTP_SERVER_IIS_5_1          6   /* Windows XP Professional */
-#define HTP_SERVER_IIS_6_0          7   /* Windows 2003 */
-#define HTP_SERVER_IIS_7_0          8   /* Windows 2008 */
-#define HTP_SERVER_IIS_7_5          9   /* Windows 7 */
-#define HTP_SERVER_TOMCAT_6_0       10  /* Unused */
-#define HTP_SERVER_APACHE           11
-#define HTP_SERVER_APACHE_2_2       12
-
-#define NONE                        0
-#define IDENTITY                    1
-#define CHUNKED                     2
-
-#define TX_PROGRESS_NEW             0
-#define TX_PROGRESS_REQ_LINE        1
-#define TX_PROGRESS_REQ_HEADERS     2
-#define TX_PROGRESS_REQ_BODY        3
-#define TX_PROGRESS_REQ_TRAILER     4
-#define TX_PROGRESS_WAIT            5
-#define TX_PROGRESS_RES_LINE        6
-#define TX_PROGRESS_RES_HEADERS     7
-#define TX_PROGRESS_RES_BODY        8
-#define TX_PROGRESS_RES_TRAILER     9
-#define TX_PROGRESS_DONE            10
-
-#define STREAM_STATE_NEW            0
-#define STREAM_STATE_OPEN           1
-#define STREAM_STATE_CLOSED         2
-#define STREAM_STATE_ERROR          3
-#define STREAM_STATE_TUNNEL         4
-#define STREAM_STATE_DATA_OTHER     5
-#define STREAM_STATE_DATA           9
-
-#define URL_DECODER_PRESERVE_PERCENT            0
-#define URL_DECODER_REMOVE_PERCENT              1
-#define URL_DECODER_DECODE_INVALID              2
-#define URL_DECODER_STATUS_400                  400
-
-#define NONE        0
-#define NO          0
-#define BESTFIT     0
-#define YES         1
-#define TERMINATE   1
-#define STATUS_400  400
-#define STATUS_404  401
-
-#define IN_TEST_NEXT_BYTE_OR_RETURN(X) \
-if ((X)->in_current_offset >= (X)->in_current_len) { \
-    return HTP_DATA; \
-}
-
-#define IN_NEXT_BYTE(X) \
-if ((X)->in_current_offset < (X)->in_current_len) { \
-    (X)->in_next_byte = (X)->in_current_data[(X)->in_current_offset]; \
-    (X)->in_current_offset++; \
-    (X)->in_stream_offset++; \
-} else { \
-    (X)->in_next_byte = -1; \
-}
-
-#define IN_NEXT_BYTE_OR_RETURN(X) \
-if ((X)->in_current_offset < (X)->in_current_len) { \
-    (X)->in_next_byte = (X)->in_current_data[(X)->in_current_offset]; \
-    (X)->in_current_offset++; \
-    (X)->in_stream_offset++; \
-} else { \
-    return HTP_DATA; \
-}
-
-#define IN_COPY_BYTE_OR_RETURN(X) \
-if ((X)->in_current_offset < (X)->in_current_len) { \
-    (X)->in_next_byte = (X)->in_current_data[(X)->in_current_offset]; \
-    (X)->in_current_offset++; \
-    (X)->in_stream_offset++; \
-} else { \
-    return HTP_DATA; \
-} \
-\
-if ((X)->in_line_len < (X)->in_line_size) { \
-    (X)->in_line[(X)->in_line_len] = (X)->in_next_byte; \
-    (X)->in_line_len++; \
-    if (((X)->in_line_len == HTP_HEADER_LIMIT_SOFT)&&(!((X)->in_tx->flags & HTP_FIELD_LONG))) { \
-        (X)->in_tx->flags |= HTP_FIELD_LONG; \
-        htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_SOFT, "Request field over soft limit"); \
-    } \
-} else { \
-    htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_HARD, "Request field over hard limit"); \
-    return HTP_ERROR; \
-}
-
-#define OUT_TEST_NEXT_BYTE_OR_RETURN(X) \
-if ((X)->out_current_offset >= (X)->out_current_len) { \
-    return HTP_DATA; \
-}
-
-#define OUT_NEXT_BYTE(X) \
-if ((X)->out_current_offset < (X)->out_current_len) { \
-    (X)->out_next_byte = (X)->out_current_data[(X)->out_current_offset]; \
-    (X)->out_current_offset++; \
-    (X)->out_stream_offset++; \
-} else { \
-    (X)->out_next_byte = -1; \
-}
-
-#define OUT_NEXT_BYTE_OR_RETURN(X) \
-if ((X)->out_current_offset < (X)->out_current_len) { \
-    (X)->out_next_byte = (X)->out_current_data[(X)->out_current_offset]; \
-    (X)->out_current_offset++; \
-    (X)->out_stream_offset++; \
-} else { \
-    return HTP_DATA; \
-}
-
-#define OUT_COPY_BYTE_OR_RETURN(X) \
-if ((X)->out_current_offset < (X)->out_current_len) { \
-    (X)->out_next_byte = (X)->out_current_data[(X)->out_current_offset]; \
-    (X)->out_current_offset++; \
-    (X)->out_stream_offset++; \
-} else { \
-    return HTP_DATA; \
-} \
-\
-if ((X)->out_line_len < (X)->out_line_size) { \
-    (X)->out_line[(X)->out_line_len] = (X)->out_next_byte; \
-    (X)->out_line_len++; \
-    if (((X)->out_line_len == HTP_HEADER_LIMIT_SOFT)&&(!((X)->out_tx->flags & HTP_FIELD_LONG))) { \
-        (X)->out_tx->flags |= HTP_FIELD_LONG; \
-        htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_SOFT, "Response field over soft limit"); \
-    } \
-} else { \
-    htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_HARD, "Response field over hard limit"); \
-    return HTP_ERROR; \
-}
-
-typedef uint32_t htp_time_t;
-
-// -- Data structures -----------------------------------------------------------------------------
-
-struct htp_cfg_t {
-    /** Hard field limit length. If the parser encounters a line that's longer
-     *  than this value it will give up parsing. Do note that the line limit
-     *  is not the same thing as header length limit. Because of header folding,
-     *  a header can end up being longer than the line limit.
-     */
-    size_t field_limit_hard;
-    
-    /** Soft field limit length. If this limit is reached the parser will issue
-     *  a warning but continue to run.
-     */
-    size_t field_limit_soft;              
-
-    /** Log level, which will be used when deciding whether to store or
-     *  ignore the messages issued by the parser.
-     */
-    int log_level;   
-
-    /**
-     * Server personality ID.
-     */
-    int spersonality;
-
-    /** The function used for request line parsing. Depends on the personality. */
-    int (*parse_request_line)(htp_connp_t *connp);
-
-    /** The function used for response line parsing. Depends on the personality. */
-    int (*parse_response_line)(htp_connp_t *connp);
-
-    /** The function used for request header parsing. Depends on the personality. */
-    int (*process_request_header)(htp_connp_t *connp);
-
-    /** The function used for response header parsing. Depends on the personality. */
-    int (*process_response_header)(htp_connp_t *connp);
-
-    
-    // Path handling
-
-    /** Should we treat backslash characters as path segment separators? */
-    int path_backslash_separators;
-    int query_backslash_separators;
-    
-    /** Should we treat paths as case insensitive? */
-    int path_case_insensitive;
-    int query_case_insensitive;
-
-    /** Should we compress multiple path segment separators into one? */
-    int path_compress_separators;
-    int query_compress_separators;
-
-    /** This parameter is used to predict how a server will react when control
-     *  characters are present in a request path, but does not affect path
-     *  normalization.
-     */
-    int path_control_char_handling;
-    int query_control_char_handling;
-
-    /** Should the parser convert UTF-8 into a single-byte stream, using
-     *  best-fit?
-     */
-    int path_convert_utf8;
-
-    /** Should we URL-decode encoded path segment separators? */
-    int path_decode_separators;
-    int query_decode_separators;
-
-    /** Should we decode %u-encoded characters? */
-    int path_decode_u_encoding;
-    int query_decode_u_encoding;
-
-    /** How do handle invalid encodings: URL_DECODER_LEAVE_PERCENT,
-     *  URL_DECODER_REMOVE_PERCENT or URL_DECODER_DECODE_INVALID.
-     */
-    int path_invalid_encoding_handling;
-    int query_invalid_encoding_handling;
-
-    /** Controls how invalid UTF-8 characters are handled. */
-    int path_invalid_utf8_handling;
-
-    /** Controls how encoded NUL bytes are handled. */
-    int path_nul_encoded_handling;
-    int query_nul_encoded_handling;
-
-    /** Controls how raw NUL bytes are handled. */
-    int path_nul_raw_handling;
-    int query_nul_raw_handling;
-
-    /** The replacement character used when there is no best-fit mapping. */
-    unsigned char path_replacement_char;
-
-    /** How will the server handle UCS-2 characters? */
-    int path_unicode_mapping;      
-
-    /** XXX Unused */
-    int path_utf8_overlong_handling;
-
-    /** The best-fit map to use to decode %u-encoded characters. */
-    unsigned char *path_u_bestfit_map;
-
-    /** Whether to generate the request_uri_normalized field. */
-    int generate_request_uri_normalized;
-
-
-    // Hooks
-
-    /** Transaction start hook, invoked when the parser receives the first
-     *  byte of a new transaction.
-     */
-    htp_hook_t *hook_transaction_start;
-
-    /** Request line hook, invoked after a request line has been parsed. */
-    htp_hook_t *hook_request_line;
-
-    /** Request URI normalization hook, for overriding default normalization of URI. */
-    htp_hook_t *hook_request_uri_normalize;
-
-    /** Request headers hook, invoked after all request headers are seen. */
-    htp_hook_t *hook_request_headers;
-
-    /** Request body data hook, invoked every time body data is available. Chunked data
-     *  will be dechunked and compressed data will be decompressed (not implemented at present)
-     *  before the data is passed to this hook.
-     */
-    htp_hook_t *hook_request_body_data;
-
-    /** Request trailer hook, invoked after all trailer headers are seen,
-     *  and if they are seen (not invoked otherwise).
-     */
-    htp_hook_t *hook_request_trailer;
-
-    /** Request hook, invoked after a complete request is seen. */
-    htp_hook_t *hook_request;
-
-    /** Response line hook, invoked after a response line has been parsed. */
-    htp_hook_t *hook_response_line;
-
-    /** Response headers book, invoked after all response headers have been seen. */
-    htp_hook_t *hook_response_headers;
-
-    /** Response body data hook, invoked whenever a chunk of response data is available. Chunked
-     *  data will be dechunked and compressed data will be decompressed (not implemented
-     *  at present) before the data is passed to this hook.*/
-    htp_hook_t *hook_response_body_data;
-
-    /** Response trailer hook, invoked after all trailer headers have been processed,
-     *  and only if the trailer exists.
-     */
-    htp_hook_t *hook_response_trailer;
-
-    /** Response hook, invoked after a response has been seen. There isn't a separate
-     *  transaction hook, use this hook to do something whenever a transaction is
-     *  complete.
-     */
-    htp_hook_t *hook_response;
-
-    /**
-     * Log hook, invoked every time the library wants to log.
-     */
-    htp_hook_t *hook_log;
-
-    /** Opaque user data associated with this configuration structure. */
-    void *user_data;
-};
-
-struct htp_conn_t {
-    /** Connection parser associated with this connection. */
-    htp_connp_t *connp;
-
-    /** Remote IP address. */
-    char *remote_addr;
-
-    /** Remote port. */
-    int remote_port;
-
-    /** Local IP address. */
-    char *local_addr;
-
-    /** Local port. */
-    int local_port;
-
-    /** Transactions carried out on this connection. The list may contain
-     *  NULL elements when some of the transactions are deleted (and then
-     *  removed from a connection by calling htp_conn_remove_tx().
-     */
-    list_t *transactions;
-
-    /** Log messages associated with this connection. */
-    list_t *messages;   
-
-    /** Parsing flags: PIPELINED_CONNECTION. */
-    unsigned int flags;   
-
-    /** When was this connection opened? */
-    htp_time_t open_timestamp;
-
-    /** When was this connection closed? */
-    htp_time_t close_timestamp;
-    
-    /** Inbound data counter. */
-    size_t in_data_counter;
-
-    /** Outbound data counter. */
-    size_t out_data_counter;
-
-    /** Inbound packet counter. */
-    size_t in_packet_counter;
-
-    /** Outbound packet counter. */
-    size_t out_packet_counter;
-};
-
-struct htp_connp_t {
-    // General fields
-    
-    /** Current parser configuration structure. */
-    htp_cfg_t *cfg;
-
-    /** Is the configuration structure only used with this connection
-     *  parser? If it is, then it can be changed as parsing goes on,
-     *  and destroyed along with the parser in the end.
-     */
-    int is_cfg_private;
-
-    /** The connection structure associated with this parser. */
-    htp_conn_t *conn;
-
-    /** Opaque user data associated with this parser. */
-    void *user_data;   
-
-    /** On parser failure, this field will contain the error information. Do note, however,
-     *  that the value in this field will only be valid immediately after an error condition,
-     *  but it is not guaranteed to remain valid if the parser is invoked again.
-     */
-    htp_log_t *last_error;
-
-    // Request parser fields
-
-    /** Parser inbound status. Starts as HTP_OK, but may turn into HTP_ERROR. */
-    unsigned int in_status;
-
-    /** Parser output status. Starts as HTP_OK, but may turn into HTP_ERROR. */
-    unsigned int out_status;
-
-    /** The time when the last request data chunk was received. */
-    htp_time_t in_timestamp;
-
-    /** Pointer to the current request data chunk. */
-    unsigned char *in_current_data;
-
-    /** The length of the current request data chunk. */
-    int64_t in_current_len;
-
-    /** The offset of the next byte in the request data chunk to consume. */
-    int64_t in_current_offset;
-
-    /** How many data chunks does the inbound connection stream consist of? */
-    size_t in_chunk_count;
-
-    /** The index of the first chunk used in the current request. */
-    size_t in_chunk_request_index;
-
-    /** The offset, in the entire connection stream, of the next request byte. */
-    int64_t in_stream_offset;
-
-    /** The value of the request byte currently being processed. */
-    int in_next_byte;
-
-    /** Pointer to the request line buffer. */
-    unsigned char *in_line;
-
-    /** Size of the request line buffer. */
-    size_t in_line_size;
-
-    /** Lenght of the current request line. */
-    size_t in_line_len;    
-
-    /** Ongoing inbound transaction. */
-    htp_tx_t *in_tx;   
-
-    /** The request header line currently being processed. */
-    htp_header_line_t *in_header_line;
-
-    /** The index, in the structure holding all request header lines, of the
-     *  line with which the current header begins. The header lines are
-     *  kept in the transaction structure.
-     */
-    int in_header_line_index;
-
-    /** How many lines are there in the current request header? */
-    int in_header_line_counter;
-
-    /**
-     * The request body length declared in a valid request headers. The key here
-     * is "valid". This field will not be populated if a request contains both
-     * a Transfer-Encoding header and a Content-Lenght header.
-     */
-    int64_t in_content_length;
-
-    /** Holds the remaining request body length that we expect to read. This
-     *  field will be available only when the length of a request body is known
-     *  in advance, i.e. when request headers contain a Content-Length header.
-     */
-    int64_t in_body_data_left;
-
-    /** Holds the amount of data that needs to be read from the
-     *  current data chunk. Only used with chunked request bodies.
-     */
-    int in_chunked_length;
-
-    /** Current request parser state. */
-    int (*in_state)(htp_connp_t *);
-
-    // Response parser fields
-
-    /** Response counter, incremented with every new response. This field is
-     *  used to match responses to requests. The expectation is that for every
-     *  response there will already be a transaction (request) waiting.
-     */
-    size_t out_next_tx_index;
-
-    /** The time when the last response data chunk was received. */
-    htp_time_t out_timestamp;
-
-    /** Pointer to the current response data chunk. */
-    unsigned char *out_current_data;
-
-    /** The length of the current response data chunk. */
-    int64_t out_current_len;
-
-    /** The offset of the next byte in the response data chunk to consume. */
-    int64_t out_current_offset;
-
-    /** The offset, in the entire connection stream, of the next response byte. */
-    int64_t out_stream_offset;
-
-    /** The value of the response byte currently being processed. */
-    int out_next_byte;
-
-    /** Pointer to the response line buffer. */
-    unsigned char *out_line;
-
-    /** Size of the response line buffer. */
-    size_t out_line_size;
-
-    /** Lenght of the current response line. */
-    size_t out_line_len;       
-        
-    /** Ongoing outbound transaction */
-    htp_tx_t *out_tx;
-
-    /** The response header line currently being processed. */
-    htp_header_line_t *out_header_line;
-
-    /** The index, in the structure holding all response header lines, of the
-     *  line with which the current header begins. The header lines are
-     *  kept in the transaction structure.
-     */
-    int out_header_line_index;
-
-    /** How many lines are there in the current response header? */
-    int out_header_line_counter;
-
-    /**
-     * The length of the current response body as presented in the
-     * Content-Length response header.
-     */
-    int64_t out_content_length;
-
-    /** The remaining length of the current response body, if known. */
-    int64_t out_body_data_left;
-
-    /** Holds the amount of data that needs to be read from the
-     *  current response data chunk. Only used with chunked response bodies.
-     */
-    int out_chunked_length;
-
-    /** Current response parser state. */
-    int (*out_state)(htp_connp_t *);
-
-    /** Response decompressor used to decompress response body data. */
-    htp_decompressor_t *out_decompressor;
-};
-
-struct htp_log_t {
-    /** The connection parser associated with this log message. */
-    htp_connp_t *connp;
-
-    /** The transaction associated with this log message, if any. */
-    htp_tx_t *tx;
-
-    /** Log message. */
-    const char *msg;
-
-    /** Message level. */
-    int level;
-
-    /** Message code. */
-    int code;
-
-    /** File in which the code that emitted the message resides. */
-    const char *file;
-
-    /** Line number on which the code that emitted the message resides. */
-    unsigned int line;
-};
-
-struct htp_header_line_t {
-    /** Header line data. */
-    bstr *line;
-
-    /** Offset at which header name begins, if applicable. */
-    size_t name_offset;
-
-    /** Header name length, if applicable. */
-    size_t name_len;
-
-    /** Offset at which header value begins, if applicable. */
-    size_t value_offset;
-
-    /** Value length, if applicable. */
-    size_t value_len;
-
-    /** How many NUL bytes are there on this header line? */
-    unsigned int has_nulls;
-
-    /** The offset of the first NUL byte, or -1. */
-    int first_nul_offset;
-
-    /** Parsing flags: HTP_FIELD_INVALID_NOT_FATAL, HTP_FIELD_INVALID_FATAL, HTP_FIELD_LONG */
-    unsigned int flags;
-
-    /** terminator characters, if NULL assume RFC compliant 0d 0a */
-    bstr *terminators;
-
-    /** Header that uses this line. */
-    htp_header_t *header;
-};
-
-struct htp_header_t {
-    /** Header name. */
-    bstr *name;
-
-    /** Header value. */
-    bstr *value;   
-
-    /** Parsing flags: HTP_FIELD_INVALID_NOT_FATAL, HTP_FIELD_FOLDED, HTP_FIELD_REPEATED */
-    unsigned int flags;
-};
-
-struct htp_tx_t {
-    /** The connection parsed associated with this transaction. */
-    htp_connp_t *connp;
-
-    /** The connection to which this transaction belongs. */
-    htp_conn_t *conn;
-
-    /** The configuration structure associated with this transaction. */
-    htp_cfg_t *cfg;
-
-    /** Is the configuration structure shared with other transactions or connections? As
-     *  a rule of thumb transactions will initially share their configuration structure, but
-     *  copy-on-write may be used when an attempt to modify configuration is detected.
-     */
-    int is_cfg_shared;
-
-    /** The user data associated with this transaction. */
-    void *user_data;
-    
-    // Request
-    unsigned int request_ignored_lines;
-
-    /** The first line of this request. */
-    bstr *request_line;
-
-    /** How many NUL bytes are there in the request line? */
-    int request_line_nul;
-
-    /** The offset of the first NUL byte. */
-    int request_line_nul_offset;
-
-    /** Request method. */
-    bstr *request_method;
-
-    /** Request method, as number. Available only if we were able to recognize the request method. */
-    int request_method_number;
-
-    /** Request URI, raw, as given to us on the request line. */
-    bstr *request_uri;
-
-    /**
-     * Normalized request URI as a single string. The availability of this
-     * field depends on configuration. Use htp_config_set_generate_request_uri_normalized()
-     * to ask for the field to be generated.
-     */
-    bstr *request_uri_normalized;
-
-    /** Request protocol, as text. */
-    bstr *request_protocol;
-
-    /** Protocol version as a number: -1 means unknown, 9 (HTTP_0_9) means 0.9,
-     *  100 (HTTP_1_0) means 1.0 and 101 (HTTP_1_1) means 1.1.
-     */
-    int request_protocol_number;
-
-    /** Is this request using a short-style HTTP/0.9 request? */
-    int protocol_is_simple;   
-
-    /** This structure holds a parsed request_uri, with the missing information
-     *  added (e.g., adding port number from the TCP information) and the fields
-     *  normalized. This structure should be used to make decisions about a request.
-     *  To inspect raw data, either use request_uri, or parsed_uri_incomplete.
-     */
-    htp_uri_t *parsed_uri;
-
-    /** This structure holds the individual components parsed out of the request URI. No
-     *  attempt is made to normalize the contents or replace the missing pieces with
-     *  defaults. The purpose of this field is to allow you to look at the data as it
-     *  was supplied. Use parsed_uri when you need to act on data. Note that this field
-     *  will never have the port as a number.
-     */
-    htp_uri_t *parsed_uri_incomplete;
-
-    /** The actual message length (the length _after_ transformations
-     *  have been applied). This field will change as a request body is being
-     *  received, with the final value available once the entire body has
-     *  been received.
-     */
-    size_t request_message_len;
-
-    /** The actual entity length (the length _before_ transformations
-     *  have been applied). This field will change as a request body is being
-     *  received, with the final value available once the entire body has
-     *  been received.
-     */
-    size_t request_entity_len;
-
-    /** TODO The length of the data transmitted in a request body, minus the length
-     *  of the files (if any). At worst, this field will be equal to the entity
-     *  length if the entity encoding is not recognized. If we recognise the encoding
-     *  (e.g., if it is application/x-www-form-urlencoded or multipart/form-data), the
-     *  decoder may be able to separate the data from everything else, in which case
-     *  the value in this field will be lower.
-     */
-    size_t request_nonfiledata_len;
-
-    /** TODO The length of the files uploaded using multipart/form-data, or in a
-     *  request that uses PUT (in which case this field will be equal to the
-     *  entity length field). This field will be zero in all other cases.
-     */
-    size_t request_filedata_len;        
-
-    /** Original request header lines. This list stores instances of htp_header_line_t. */
-    list_t *request_header_lines;
-
-    /** Parsed request headers. */
-    table_t *request_headers;
-
-    /** Contains raw request headers. This field is generated on demand, use
-     *  htp_tx_get_request_headers_raw() to get it.
-     */
-    bstr *request_headers_raw;
-
-    /** How many request header lines have been included in the raw
-     *  buffer (above).
-     */
-    size_t request_headers_raw_lines;
-
-
-    /** Request transfer coding: IDENTITY or CHUNKED. Only available on requests that have bodies. */
-    int request_transfer_coding;
-
-    /** Compression; currently COMPRESSION_NONE or COMPRESSION_GZIP. */
-    int request_content_encoding;
-
-    // Response
-
-    /** How many empty lines did we ignore before reaching the status line? */
-    unsigned int response_ignored_lines;
-
-    /** Response line. */
-    bstr *response_line;
-
-    /** Response protocol, as text. */
-    bstr *response_protocol;
-
-    /** Response protocol as number. Only available if we were
-     *  able to parse the protocol version.
-     */
-    int response_protocol_number;
-
-    /** Response status code, as text. */
-    bstr *response_status;
-
-    /** Reponse status code, available only if we were able to parse it. */
-    int response_status_number;
-
-    /** This field is set by the protocol decoder with it thinks that the
-     *  backend server will reject a request with a particular status code.
-     */
-    int response_status_expected_number;
-
-    /** The message associated with the response status code. */
-    bstr *response_message;
-
-    /** Have we seen the server respond with a 100 response? */
-    int seen_100continue;   
-
-    /** Original response header lines. */
-    list_t *response_header_lines;
-
-    /** Parsed response headers. */
-    table_t *response_headers;
-
-    /** Contains raw response headers. This field is generated on demand, use
-     *  htp_tx_get_response_headers_raw() to get it.
-     */
-    bstr *response_headers_raw;
-
-    /** How many response header lines have been included in the raw
-     *  buffer (above).
-     */
-    size_t response_headers_raw_lines;
-
-    /** The actual message length (the length _after_ transformations
-     *  have been applied). This field will change as a request body is being
-     *  received, with the final value available once the entire body has
-     *  been received.
-     */
-    size_t response_message_len;
-
-    /** The actual entity length (the length _before_ transformations
-     *  have been applied). This field will change as a request body is being
-     *  received, with the final value available once the entire body has
-     *  been received.
-     */
-    size_t response_entity_len;
-
-    /** Response transfer coding: IDENTITY or CHUNKED. Only available on responses that have bodies. */
-    int response_transfer_coding;
-
-    /** Compression; currently COMPRESSION_NONE or COMPRESSION_GZIP. */
-    int response_content_encoding;   
-    
-    // Common
-
-    /** Parsing flags: HTP_INVALID_CHUNKING, HTP_INVALID_FOLDING,
-     *  HTP_REQUEST_SMUGGLING, HTP_MULTI_PACKET_HEAD.
-     */
-    unsigned int flags;
-
-    /** Transaction progress. Look for the TX_PROGRESS_* constants for more information. */
-    unsigned int progress[2];
-};
-
-/** This structure is used to pass transaction data to callbacks. */
-struct htp_tx_data_t {
-    /** Transaction pointer. */
-    htp_tx_t *tx;
-
-    /** Pointer to the data buffer. */
-    unsigned char *data;
-
-    /** Buffer length. */
-    size_t len;
-};
-
-/** URI structure. Each of the fields provides access to a single
- *  URI element. A typical URI will look like this:
- *  http://username:password@hostname.com:8080/path?query#fragment.
- */
-struct htp_uri_t {
-    /** Scheme */
-    bstr *scheme;
-
-    /** Username */
-    bstr *username;
-
-    /** Password */
-    bstr *password;
-
-    /** Hostname */
-    bstr *hostname;
-
-    /** Port, as string */
-    bstr *port;
-
-    /** Port, as number, but only if the port is valid. */
-      int port_number;
-
-    /** The path part of this URI */
-    bstr *path;
-
-    /** Query string */
-    bstr *query;
-
-    /** Fragment identifier */
-    bstr *fragment;
-};
-
-// -- Functions -----------------------------------------------------------------------------------
-
-const char *htp_get_version();
-
-htp_cfg_t *htp_config_copy(htp_cfg_t *cfg);
-htp_cfg_t *htp_config_create();
-      void htp_config_destroy(htp_cfg_t *cfg); 
-
-void htp_config_register_transaction_start(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_request_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_request_uri_normalize(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_request_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_request_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *));
-void htp_config_register_request_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_request(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-
-void htp_config_register_response_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_response_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_response_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *));
-void htp_config_register_response_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-void htp_config_register_response(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *));
-
-void htp_config_register_log(htp_cfg_t *cfg, int (*callback_fn)(htp_log_t *));
-
- int htp_config_set_server_personality(htp_cfg_t *cfg, int personality);
-
-void htp_config_set_bestfit_map(htp_cfg_t *cfg, unsigned char *map);
-void htp_config_set_path_backslash_separators(htp_cfg_t *cfg, int backslash_separators);
-void htp_config_set_query_backslash_separators(htp_cfg_t *cfg, int backslash_separators);
-void htp_config_set_path_case_insensitive(htp_cfg_t *cfg, int path_case_insensitive);
-void htp_config_set_query_case_insensitive(htp_cfg_t *cfg, int case_insensitive);
-void htp_config_set_path_compress_separators(htp_cfg_t *cfg, int compress_separators);
-void htp_config_set_query_compress_separators(htp_cfg_t *cfg, int compress_separators);
-void htp_config_set_path_control_char_handling(htp_cfg_t *cfg, int control_char_handling);
-void htp_config_set_query_control_char_handling(htp_cfg_t *cfg, int control_char_handling);
-void htp_config_set_path_convert_utf8(htp_cfg_t *cfg, int convert_utf8);
-void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int backslash_separators);
-void htp_config_set_query_decode_separators(htp_cfg_t *cfg, int decode_separators);
-void htp_config_set_path_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding);
-void htp_config_set_query_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding);
-void htp_config_set_path_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling);
-void htp_config_set_query_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling);
-void htp_config_set_path_invalid_utf8_handling(htp_cfg_t *cfg, int invalid_utf8_handling);
-void htp_config_set_path_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling);
-void htp_config_set_query_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling);
-void htp_config_set_path_nul_raw_handling(htp_cfg_t *cfg, int nul_raw_handling);
-void htp_config_set_query_nul_raw_handling(htp_cfg_t *cfg, int nul_raw_handling);
-void htp_config_set_path_replacement_char(htp_cfg_t *cfg, int replacement_char);
-void htp_config_set_path_unicode_mapping(htp_cfg_t *cfg, int unicode_mapping);
-
-void htp_config_set_generate_request_uri_normalized(htp_cfg_t *cfg, int generate);
-
-
-htp_connp_t *htp_connp_create(htp_cfg_t *cfg);
-htp_connp_t *htp_connp_create_copycfg(htp_cfg_t *cfg);
-void htp_connp_open(htp_connp_t *connp, const char *remote_addr, int remote_port, const char *local_addr, int local_port, htp_time_t timestamp);
-void htp_connp_close(htp_connp_t *connp, htp_time_t timestamp);
-void htp_connp_destroy(htp_connp_t *connp);
-void htp_connp_destroy_all(htp_connp_t *connp);
-
- void htp_connp_set_user_data(htp_connp_t *connp, void *user_data);
-void *htp_connp_get_user_data(htp_connp_t *connp);
-
-htp_conn_t *htp_conn_create(htp_connp_t *connp);
-       void htp_conn_destroy(htp_conn_t *conn);
-        int htp_conn_remove_tx(htp_conn_t *conn, htp_tx_t *tx);
-
-   int htp_connp_req_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char *data, size_t len);
-size_t htp_connp_req_data_consumed(htp_connp_t *connp);
-   int htp_connp_res_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char *data, size_t len);
-size_t htp_connp_res_data_consumed(htp_connp_t *connp);
-
-      void htp_connp_clear_error(htp_connp_t *connp);
-htp_log_t *htp_connp_get_last_error(htp_connp_t *connp);
-
-htp_header_t *htp_connp_header_parse(htp_connp_t *, unsigned char *, size_t);
-
-#define CFG_NOT_SHARED  0
-#define CFG_SHARED      1
-
-htp_tx_t *htp_tx_create(htp_cfg_t *cfg, int is_cfg_shared, htp_conn_t *conn);
-     void htp_tx_destroy(htp_tx_t *tx);
-     void htp_tx_set_config(htp_tx_t *tx, htp_cfg_t *cfg, int is_cfg_shared);
-
-     void htp_tx_set_user_data(htp_tx_t *tx, void *user_data);
-    void *htp_tx_get_user_data(htp_tx_t *tx);
-
-    bstr *htp_tx_get_request_uri_normalized(htp_tx_t *tx);
-
-// Parsing functions
-
-int htp_parse_request_line_generic(htp_connp_t *connp);
-int htp_parse_request_header_generic(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len);
-int htp_process_request_header_generic(htp_connp_t *);
-
-int htp_parse_request_header_apache_2_2(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len);
-int htp_parse_request_line_apache_2_2(htp_connp_t *connp);
-int htp_process_request_header_apache_2_2(htp_connp_t *);
-
-int htp_parse_response_line_generic(htp_connp_t *connp);
-int htp_process_response_header_generic(htp_connp_t *connp);
-
-// Parser states
-
-int htp_connp_REQ_IDLE(htp_connp_t *connp);
-int htp_connp_REQ_LINE(htp_connp_t *connp);
-int htp_connp_REQ_PROTOCOL(htp_connp_t *connp);
-int htp_connp_REQ_HEADERS(htp_connp_t *connp);
-int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp);
-int htp_connp_REQ_BODY_IDENTITY(htp_connp_t *connp);
-int htp_connp_REQ_BODY_CHUNKED_LENGTH(htp_connp_t *connp);
-int htp_connp_REQ_BODY_CHUNKED_DATA(htp_connp_t *connp);
-int htp_connp_REQ_BODY_CHUNKED_DATA_END(htp_connp_t *connp);
-
-int htp_connp_REQ_CONNECT_CHECK(htp_connp_t *connp);
-int htp_connp_REQ_CONNECT_WAIT_RESPONSE(htp_connp_t *connp);
-
-int htp_connp_RES_IDLE(htp_connp_t *connp);
-int htp_connp_RES_LINE(htp_connp_t *connp);
-int htp_connp_RES_HEADERS(htp_connp_t *connp);
-int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp);
-int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp);
-int htp_connp_RES_BODY_CHUNKED_LENGTH(htp_connp_t *connp);
-int htp_connp_RES_BODY_CHUNKED_DATA(htp_connp_t *connp);
-int htp_connp_RES_BODY_CHUNKED_DATA_END(htp_connp_t *connp);
-
-// Utility functions
-
-int htp_convert_method_to_number(bstr *);
-int htp_is_lws(int c);
-int htp_is_separator(int c);
-int htp_is_text(int c);
-int htp_is_token(int c);
-int htp_chomp(unsigned char *data, size_t *len);
-int htp_is_space(int c);
-
-int htp_parse_protocol(bstr *protocol);
-
-int htp_is_line_empty(unsigned char *data, size_t len);
-int htp_is_line_whitespace(unsigned char *data, size_t len);
-
-int htp_connp_is_line_folded(unsigned char *data, size_t len);
-int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len);
-int htp_connp_is_line_ignorable(htp_connp_t *connp, unsigned char *data, size_t len);
-
-int htp_parse_uri(bstr *input, htp_uri_t **uri);
-int htp_parse_authority(htp_connp_t *connp, bstr *input, htp_uri_t **uri);
-int htp_normalize_parsed_uri(htp_connp_t *connp, htp_uri_t *parsed_uri_incomplete, htp_uri_t *parsed_uri);
-bstr *htp_normalize_hostname_inplace(bstr *input);
-void htp_replace_hostname(htp_connp_t *connp, htp_uri_t *parsed_uri, bstr *hostname);
-
-int htp_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path);
-int htp_decode_query_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path);
-
-void htp_uriencoding_normalize_inplace(bstr *s);
-
- int htp_prenormalize_uri_path_inplace(bstr *s, int *flags, int case_insensitive, int backslash, int decode_separators, int remove_consecutive);
-void htp_normalize_uri_path_inplace(bstr *s);
-
-void htp_utf8_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path);
-void htp_utf8_validate_path(htp_tx_t *tx, bstr *path);
-
-int htp_parse_content_length(bstr *b);
-int htp_parse_chunked_length(unsigned char *data, size_t len);
-int htp_parse_positive_integer_whitespace(unsigned char *data, size_t len, int base);
-int htp_parse_status(bstr *status);
-
-void htp_log(htp_connp_t *connp, const char *file, int line, int level, int code, const char *fmt, ...);
-void htp_print_log(FILE *stream, htp_log_t *log);
-
-void fprint_raw_data(FILE *stream, const char *name, unsigned char *data, size_t len);
-
-char *htp_connp_in_state_as_string(htp_connp_t *connp);
-char *htp_connp_out_state_as_string(htp_connp_t *connp);
-char *htp_tx_progress_as_string(htp_tx_t *tx, int direction);
-
-bstr *htp_unparse_uri_noencode(htp_uri_t *uri);
-
-bstr *htp_tx_get_request_headers_raw(htp_tx_t *tx);
-bstr *htp_tx_get_response_headers_raw(htp_tx_t *tx);
-
-#endif /* _HTP_H */
-
-
diff --git a/libhtp/htp/htp_config.c b/libhtp/htp/htp_config.c
deleted file mode 100644 (file)
index bceba1f..0000000
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * This map is used by default for best-fit mapping from the Unicode
- * values U+0100-FFFF.
- */
-static unsigned char bestfit_1252[] =
-{ 0x01, 0x00, 0x41, 0x01, 0x01, 0x61, 0x01, 0x02, 0x41, 0x01, 0x03, 0x61,
-  0x01, 0x04, 0x41, 0x01, 0x05, 0x61, 0x01, 0x06, 0x43, 0x01, 0x07, 0x63,
-  0x01, 0x08, 0x43, 0x01, 0x09, 0x63, 0x01, 0x0a, 0x43, 0x01, 0x0b, 0x63,
-  0x01, 0x0c, 0x43, 0x01, 0x0d, 0x63, 0x01, 0x0e, 0x44, 0x01, 0x0f, 0x64,
-  0x01, 0x11, 0x64, 0x01, 0x12, 0x45, 0x01, 0x13, 0x65, 0x01, 0x14, 0x45,
-  0x01, 0x15, 0x65, 0x01, 0x16, 0x45, 0x01, 0x17, 0x65, 0x01, 0x18, 0x45,
-  0x01, 0x19, 0x65, 0x01, 0x1a, 0x45, 0x01, 0x1b, 0x65, 0x01, 0x1c, 0x47,
-  0x01, 0x1d, 0x67, 0x01, 0x1e, 0x47, 0x01, 0x1f, 0x67, 0x01, 0x20, 0x47,
-  0x01, 0x21, 0x67, 0x01, 0x22, 0x47, 0x01, 0x23, 0x67, 0x01, 0x24, 0x48,
-  0x01, 0x25, 0x68, 0x01, 0x26, 0x48, 0x01, 0x27, 0x68, 0x01, 0x28, 0x49,
-  0x01, 0x29, 0x69, 0x01, 0x2a, 0x49, 0x01, 0x2b, 0x69, 0x01, 0x2c, 0x49,
-  0x01, 0x2d, 0x69, 0x01, 0x2e, 0x49, 0x01, 0x2f, 0x69, 0x01, 0x30, 0x49,
-  0x01, 0x31, 0x69, 0x01, 0x34, 0x4a, 0x01, 0x35, 0x6a, 0x01, 0x36, 0x4b,
-  0x01, 0x37, 0x6b, 0x01, 0x39, 0x4c, 0x01, 0x3a, 0x6c, 0x01, 0x3b, 0x4c,
-  0x01, 0x3c, 0x6c, 0x01, 0x3d, 0x4c, 0x01, 0x3e, 0x6c, 0x01, 0x41, 0x4c,
-  0x01, 0x42, 0x6c, 0x01, 0x43, 0x4e, 0x01, 0x44, 0x6e, 0x01, 0x45, 0x4e,
-  0x01, 0x46, 0x6e, 0x01, 0x47, 0x4e, 0x01, 0x48, 0x6e, 0x01, 0x4c, 0x4f,
-  0x01, 0x4d, 0x6f, 0x01, 0x4e, 0x4f, 0x01, 0x4f, 0x6f, 0x01, 0x50, 0x4f,
-  0x01, 0x51, 0x6f, 0x01, 0x54, 0x52, 0x01, 0x55, 0x72, 0x01, 0x56, 0x52,
-  0x01, 0x57, 0x72, 0x01, 0x58, 0x52, 0x01, 0x59, 0x72, 0x01, 0x5a, 0x53,
-  0x01, 0x5b, 0x73, 0x01, 0x5c, 0x53, 0x01, 0x5d, 0x73, 0x01, 0x5e, 0x53,
-  0x01, 0x5f, 0x73, 0x01, 0x62, 0x54, 0x01, 0x63, 0x74, 0x01, 0x64, 0x54,
-  0x01, 0x65, 0x74, 0x01, 0x66, 0x54, 0x01, 0x67, 0x74, 0x01, 0x68, 0x55,
-  0x01, 0x69, 0x75, 0x01, 0x6a, 0x55, 0x01, 0x6b, 0x75, 0x01, 0x6c, 0x55,
-  0x01, 0x6d, 0x75, 0x01, 0x6e, 0x55, 0x01, 0x6f, 0x75, 0x01, 0x70, 0x55,
-  0x01, 0x71, 0x75, 0x01, 0x72, 0x55, 0x01, 0x73, 0x75, 0x01, 0x74, 0x57,
-  0x01, 0x75, 0x77, 0x01, 0x76, 0x59, 0x01, 0x77, 0x79, 0x01, 0x79, 0x5a,
-  0x01, 0x7b, 0x5a, 0x01, 0x7c, 0x7a, 0x01, 0x80, 0x62, 0x01, 0x97, 0x49,
-  0x01, 0x9a, 0x6c, 0x01, 0x9f, 0x4f, 0x01, 0xa0, 0x4f, 0x01, 0xa1, 0x6f,
-  0x01, 0xab, 0x74, 0x01, 0xae, 0x54, 0x01, 0xaf, 0x55, 0x01, 0xb0, 0x75,
-  0x01, 0xb6, 0x7a, 0x01, 0xc0, 0x7c, 0x01, 0xc3, 0x21, 0x01, 0xcd, 0x41,
-  0x01, 0xce, 0x61, 0x01, 0xcf, 0x49, 0x01, 0xd0, 0x69, 0x01, 0xd1, 0x4f,
-  0x01, 0xd2, 0x6f, 0x01, 0xd3, 0x55, 0x01, 0xd4, 0x75, 0x01, 0xd5, 0x55,
-  0x01, 0xd6, 0x75, 0x01, 0xd7, 0x55, 0x01, 0xd8, 0x75, 0x01, 0xd9, 0x55,
-  0x01, 0xda, 0x75, 0x01, 0xdb, 0x55, 0x01, 0xdc, 0x75, 0x01, 0xde, 0x41,
-  0x01, 0xdf, 0x61, 0x01, 0xe4, 0x47, 0x01, 0xe5, 0x67, 0x01, 0xe6, 0x47,
-  0x01, 0xe7, 0x67, 0x01, 0xe8, 0x4b, 0x01, 0xe9, 0x6b, 0x01, 0xea, 0x4f,
-  0x01, 0xeb, 0x6f, 0x01, 0xec, 0x4f, 0x01, 0xed, 0x6f, 0x01, 0xf0, 0x6a,
-  0x02, 0x61, 0x67, 0x02, 0xb9, 0x27, 0x02, 0xba, 0x22, 0x02, 0xbc, 0x27,
-  0x02, 0xc4, 0x5e, 0x02, 0xc8, 0x27, 0x02, 0xcb, 0x60, 0x02, 0xcd, 0x5f,
-  0x03, 0x00, 0x60, 0x03, 0x02, 0x5e, 0x03, 0x03, 0x7e, 0x03, 0x0e, 0x22,
-  0x03, 0x31, 0x5f, 0x03, 0x32, 0x5f, 0x03, 0x7e, 0x3b, 0x03, 0x93, 0x47,
-  0x03, 0x98, 0x54, 0x03, 0xa3, 0x53, 0x03, 0xa6, 0x46, 0x03, 0xa9, 0x4f,
-  0x03, 0xb1, 0x61, 0x03, 0xb4, 0x64, 0x03, 0xb5, 0x65, 0x03, 0xc0, 0x70,
-  0x03, 0xc3, 0x73, 0x03, 0xc4, 0x74, 0x03, 0xc6, 0x66, 0x04, 0xbb, 0x68,
-  0x05, 0x89, 0x3a, 0x06, 0x6a, 0x25, 0x20, 0x00, 0x20, 0x20, 0x01, 0x20,
-  0x20, 0x02, 0x20, 0x20, 0x03, 0x20, 0x20, 0x04, 0x20, 0x20, 0x05, 0x20,
-  0x20, 0x06, 0x20, 0x20, 0x10, 0x2d, 0x20, 0x11, 0x2d, 0x20, 0x17, 0x3d,
-  0x20, 0x32, 0x27, 0x20, 0x35, 0x60, 0x20, 0x44, 0x2f, 0x20, 0x74, 0x34,
-  0x20, 0x75, 0x35, 0x20, 0x76, 0x36, 0x20, 0x77, 0x37, 0x20, 0x78, 0x38,
-  0x20, 0x7f, 0x6e, 0x20, 0x80, 0x30, 0x20, 0x81, 0x31, 0x20, 0x82, 0x32,
-  0x20, 0x83, 0x33, 0x20, 0x84, 0x34, 0x20, 0x85, 0x35, 0x20, 0x86, 0x36,
-  0x20, 0x87, 0x37, 0x20, 0x88, 0x38, 0x20, 0x89, 0x39, 0x20, 0xa7, 0x50,
-  0x21, 0x02, 0x43, 0x21, 0x07, 0x45, 0x21, 0x0a, 0x67, 0x21, 0x0b, 0x48,
-  0x21, 0x0c, 0x48, 0x21, 0x0d, 0x48, 0x21, 0x0e, 0x68, 0x21, 0x10, 0x49,
-  0x21, 0x11, 0x49, 0x21, 0x12, 0x4c, 0x21, 0x13, 0x6c, 0x21, 0x15, 0x4e,
-  0x21, 0x18, 0x50, 0x21, 0x19, 0x50, 0x21, 0x1a, 0x51, 0x21, 0x1b, 0x52,
-  0x21, 0x1c, 0x52, 0x21, 0x1d, 0x52, 0x21, 0x24, 0x5a, 0x21, 0x28, 0x5a,
-  0x21, 0x2a, 0x4b, 0x21, 0x2c, 0x42, 0x21, 0x2d, 0x43, 0x21, 0x2e, 0x65,
-  0x21, 0x2f, 0x65, 0x21, 0x30, 0x45, 0x21, 0x31, 0x46, 0x21, 0x33, 0x4d,
-  0x21, 0x34, 0x6f, 0x22, 0x12, 0x2d, 0x22, 0x15, 0x2f, 0x22, 0x16, 0x5c,
-  0x22, 0x17, 0x2a, 0x22, 0x1a, 0x76, 0x22, 0x1e, 0x38, 0x22, 0x23, 0x7c,
-  0x22, 0x29, 0x6e, 0x22, 0x36, 0x3a, 0x22, 0x3c, 0x7e, 0x22, 0x61, 0x3d,
-  0x22, 0x64, 0x3d, 0x22, 0x65, 0x3d, 0x23, 0x03, 0x5e, 0x23, 0x20, 0x28,
-  0x23, 0x21, 0x29, 0x23, 0x29, 0x3c, 0x23, 0x2a, 0x3e, 0x25, 0x00, 0x2d,
-  0x25, 0x0c, 0x2b, 0x25, 0x10, 0x2b, 0x25, 0x14, 0x2b, 0x25, 0x18, 0x2b,
-  0x25, 0x1c, 0x2b, 0x25, 0x2c, 0x2d, 0x25, 0x34, 0x2d, 0x25, 0x3c, 0x2b,
-  0x25, 0x50, 0x2d, 0x25, 0x52, 0x2b, 0x25, 0x53, 0x2b, 0x25, 0x54, 0x2b,
-  0x25, 0x55, 0x2b, 0x25, 0x56, 0x2b, 0x25, 0x57, 0x2b, 0x25, 0x58, 0x2b,
-  0x25, 0x59, 0x2b, 0x25, 0x5a, 0x2b, 0x25, 0x5b, 0x2b, 0x25, 0x5c, 0x2b,
-  0x25, 0x5d, 0x2b, 0x25, 0x64, 0x2d, 0x25, 0x65, 0x2d, 0x25, 0x66, 0x2d,
-  0x25, 0x67, 0x2d, 0x25, 0x68, 0x2d, 0x25, 0x69, 0x2d, 0x25, 0x6a, 0x2b,
-  0x25, 0x6b, 0x2b, 0x25, 0x6c, 0x2b, 0x25, 0x84, 0x5f, 0x27, 0x58, 0x7c,
-  0x30, 0x00, 0x20, 0x30, 0x08, 0x3c, 0x30, 0x09, 0x3e, 0x30, 0x1a, 0x5b,
-  0x30, 0x1b, 0x5d, 0xff, 0x01, 0x21, 0xff, 0x02, 0x22, 0xff, 0x03, 0x23,
-  0xff, 0x04, 0x24, 0xff, 0x05, 0x25, 0xff, 0x06, 0x26, 0xff, 0x07, 0x27,
-  0xff, 0x08, 0x28, 0xff, 0x09, 0x29, 0xff, 0x0a, 0x2a, 0xff, 0x0b, 0x2b,
-  0xff, 0x0c, 0x2c, 0xff, 0x0d, 0x2d, 0xff, 0x0e, 0x2e, 0xff, 0x0f, 0x2f,
-  0xff, 0x10, 0x30, 0xff, 0x11, 0x31, 0xff, 0x12, 0x32, 0xff, 0x13, 0x33,
-  0xff, 0x14, 0x34, 0xff, 0x15, 0x35, 0xff, 0x16, 0x36, 0xff, 0x17, 0x37,
-  0xff, 0x18, 0x38, 0xff, 0x19, 0x39, 0xff, 0x1a, 0x3a, 0xff, 0x1b, 0x3b,
-  0xff, 0x1c, 0x3c, 0xff, 0x1d, 0x3d, 0xff, 0x1e, 0x3e, 0xff, 0x20, 0x40,
-  0xff, 0x21, 0x41, 0xff, 0x22, 0x42, 0xff, 0x23, 0x43, 0xff, 0x24, 0x44,
-  0xff, 0x25, 0x45, 0xff, 0x26, 0x46, 0xff, 0x27, 0x47, 0xff, 0x28, 0x48,
-  0xff, 0x29, 0x49, 0xff, 0x2a, 0x4a, 0xff, 0x2b, 0x4b, 0xff, 0x2c, 0x4c,
-  0xff, 0x2d, 0x4d, 0xff, 0x2e, 0x4e, 0xff, 0x2f, 0x4f, 0xff, 0x30, 0x50,
-  0xff, 0x31, 0x51, 0xff, 0x32, 0x52, 0xff, 0x33, 0x53, 0xff, 0x34, 0x54,
-  0xff, 0x35, 0x55, 0xff, 0x36, 0x56, 0xff, 0x37, 0x57, 0xff, 0x38, 0x58,
-  0xff, 0x39, 0x59, 0xff, 0x3a, 0x5a, 0xff, 0x3b, 0x5b, 0xff, 0x3c, 0x5c,
-  0xff, 0x3d, 0x5d, 0xff, 0x3e, 0x5e, 0xff, 0x3f, 0x5f, 0xff, 0x40, 0x60,
-  0xff, 0x41, 0x61, 0xff, 0x42, 0x62, 0xff, 0x43, 0x63, 0xff, 0x44, 0x64,
-  0xff, 0x45, 0x65, 0xff, 0x46, 0x66, 0xff, 0x47, 0x67, 0xff, 0x48, 0x68,
-  0xff, 0x49, 0x69, 0xff, 0x4a, 0x6a, 0xff, 0x4b, 0x6b, 0xff, 0x4c, 0x6c,
-  0xff, 0x4d, 0x6d, 0xff, 0x4e, 0x6e, 0xff, 0x4f, 0x6f, 0xff, 0x50, 0x70,
-  0xff, 0x51, 0x71, 0xff, 0x52, 0x72, 0xff, 0x53, 0x73, 0xff, 0x54, 0x74,
-  0xff, 0x55, 0x75, 0xff, 0x56, 0x76, 0xff, 0x57, 0x77, 0xff, 0x58, 0x78,
-  0xff, 0x59, 0x79, 0xff, 0x5a, 0x7a, 0xff, 0x5b, 0x7b, 0xff, 0x5c, 0x7c,
-  0xff, 0x5d, 0x7d, 0xff, 0x5e, 0x7e, 0x00, 0x00, 0x00
-};
-
-/**
- * Creates a new configuration structure. Configuration structures created at
- * configuration time must not be changed afterwards in order to support lock-less
- * copying.
- *
- * @return New configuration structure.
- */
-htp_cfg_t *htp_config_create() {
-    htp_cfg_t *cfg = calloc(1, sizeof(htp_cfg_t));
-    if (cfg == NULL) return NULL;
-
-    cfg->field_limit_hard = HTP_HEADER_LIMIT_HARD;
-    cfg->field_limit_soft = HTP_HEADER_LIMIT_SOFT;
-    cfg->log_level = HTP_LOG_NOTICE;
-
-    cfg->path_u_bestfit_map = bestfit_1252;
-    cfg->path_replacement_char = '?';
-
-    // No need to create hooks here; they will be created on-demand,
-    // during callback registration
-
-    // Set the default personality before we return
-    htp_config_set_server_personality(cfg, HTP_SERVER_MINIMAL);
-
-    return cfg;
-}
-
-/**
- * Creates a copy of the supplied configuration structure. The idea is to create
- * one or more configuration objects at configuration-time, but to use this
- * function to create per-connection copies. That way it will be possible to
- * adjust per-connection configuration as necessary, without affecting the
- * global configuration. Make sure no other thread changes the configuration
- * object while this function is operating.
- *
- * @param cfg
- * @return A copy of the configuration structure.
- */
-htp_cfg_t *htp_config_copy(htp_cfg_t *cfg) {
-    htp_cfg_t *copy = malloc(sizeof(htp_cfg_t));
-    if (copy == NULL) return NULL;
-
-    *copy = *cfg;
-
-    // Create copies of the hooks' structures
-    if (cfg->hook_transaction_start != NULL) {
-        copy->hook_transaction_start = hook_copy(cfg->hook_transaction_start);
-        if (copy->hook_transaction_start == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_request_line != NULL) {
-        copy->hook_request_line = hook_copy(cfg->hook_request_line);
-        if (copy->hook_request_line == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_request_uri_normalize != NULL) {
-        copy->hook_request_uri_normalize = hook_copy(cfg->hook_request_uri_normalize);
-        if (copy->hook_request_uri_normalize == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_request_headers != NULL) {
-        copy->hook_request_headers = hook_copy(cfg->hook_request_headers);
-        if (copy->hook_request_headers == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_request_body_data != NULL) {
-        copy->hook_request_body_data = hook_copy(cfg->hook_request_body_data);
-        if (copy->hook_request_body_data == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_request_trailer != NULL) {
-        copy->hook_request_trailer = hook_copy(cfg->hook_request_trailer);
-        if (copy->hook_request_trailer == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_request != NULL) {
-        copy->hook_request = hook_copy(cfg->hook_request);
-        if (copy->hook_request == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-    
-    if (cfg->hook_response_line != NULL) {
-        copy->hook_response_line = hook_copy(cfg->hook_response_line);
-        if (copy->hook_response_line == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_response_headers != NULL) {
-        copy->hook_response_headers = hook_copy(cfg->hook_response_headers);
-        if (copy->hook_response_headers == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_response_body_data != NULL) {
-        copy->hook_response_body_data = hook_copy(cfg->hook_response_body_data);
-        if (copy->hook_response_body_data == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_response_trailer != NULL) {
-        copy->hook_response_trailer = hook_copy(cfg->hook_response_trailer);
-        if (copy->hook_response_trailer == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_response != NULL) {
-        copy->hook_response = hook_copy(cfg->hook_response);
-        if (copy->hook_response == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    if (cfg->hook_log != NULL) {
-        copy->hook_log = hook_copy(cfg->hook_log);
-        if (copy->hook_log == NULL) {
-            free(copy);
-            return NULL;
-        }
-    }
-
-    return copy;
-}
-
-/**
- * Destroy a configuration structure.
- * 
- * @param cfg
- */
-void htp_config_destroy(htp_cfg_t *cfg) {
-    // Destroy the hooks
-    hook_destroy(cfg->hook_transaction_start);
-    hook_destroy(cfg->hook_request_line);
-    hook_destroy(cfg->hook_request_uri_normalize);
-    hook_destroy(cfg->hook_request_headers);
-    hook_destroy(cfg->hook_request_body_data);
-    hook_destroy(cfg->hook_request_trailer);
-    hook_destroy(cfg->hook_request);
-    hook_destroy(cfg->hook_response_line);
-    hook_destroy(cfg->hook_response_headers);
-    hook_destroy(cfg->hook_response_body_data);
-    hook_destroy(cfg->hook_response_trailer);
-    hook_destroy(cfg->hook_response);
-    hook_destroy(cfg->hook_log);
-
-    // Free the structure itself
-    free(cfg);
-}
-
-/**
- * Registers a transaction_start callback.
- * 
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_transaction_start(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_transaction_start, callback_fn);
-}
-
-/**
- * Registers a request_line callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_request_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_request_line, callback_fn);
-}
-
-/**
- * Registers a request_uri_normalize callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_request_uri_normalize(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_request_uri_normalize, callback_fn);
-}
-
-/**
- * Registers a request_headers callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_request_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_request_headers, callback_fn);
-}
-
-/**
- * Registers a request_trailer callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_request_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_request_trailer, callback_fn);
-}
-
-/**
- * Registers a request_body_data callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_request_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *)) {
-    hook_register(&cfg->hook_request_body_data, callback_fn);
-}
-
-/**
- * Registers a request callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_request(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_request, callback_fn);
-}
-
-/**
- * Registers a request_line callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_response_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_response_line, callback_fn);
-}
-
-/**
- * Registers a request_headers callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_response_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_response_headers, callback_fn);
-}
-
-/**
- * Registers a request_trailer callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_response_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_response_trailer, callback_fn);
-}
-
-/**
- * Registers a request_body_data callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_response_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *)) {
-    hook_register(&cfg->hook_response_body_data, callback_fn);
-}
-
-/**
- * Registers a request callback.
- *
- * @param cfg
- * @param callback_fn 
- */
-void htp_config_register_response(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
-    hook_register(&cfg->hook_response, callback_fn);
-}
-
-/**
- * Registers a callback that is invoked every time there is a log message.
- *
- * @param cfg
- * @param callback_fn
- */
-void htp_config_register_log(htp_cfg_t *cfg, int (*callback_fn)(htp_log_t *)) {
-    hook_register(&cfg->hook_log, callback_fn);
-}
-
-/**
- * Update the best-fit map, which is used to convert UCS-2 characters into
- * single-byte characters. By default a Windows 1252 best-fit map is used. The map
- * is an list of triplets, the first 2 bytes being an UCS-2 character to map from,
- * and the third byte being the single byte to map to. Make sure that your map contains
- * the mappings to cover the fullwidth form characters (U+FF00-FFEF).
- *
- * @param cfg
- * @param map
- */
-void htp_config_set_bestfit_map(htp_cfg_t *cfg, unsigned char *map) {
-    cfg->path_u_bestfit_map = map;
-}
-
-/**
- * Whether to generate the request_uri_normalized field.
- *
- * @param cfg
- * @param generate
- */
-void htp_config_set_generate_request_uri_normalized(htp_cfg_t *cfg, int generate) {
-    cfg->generate_request_uri_normalized = generate;
-}
-
-/**
- * Configures whether backslash characters are treated as path segment separators. They
- * are not on Unix systems, but are on Windows systems. If this setting is enabled, a path
- * such as "/one\two/three" will be converted to "/one/two/three".
- *
- * @param cfg
- * @param backslash_separators
- */
-void htp_config_set_path_backslash_separators(htp_cfg_t *cfg, int backslash_separators) {
-    cfg->path_backslash_separators = backslash_separators;
-}
-
-/**
- * Configures whether backslash characters are treated as query segment separators. They
- * are not on Unix systems, but are on Windows systems. If this setting is enabled, a query
- * such as "/one\two/three" will be converted to "/one/two/three".
- *
- * @param cfg
- * @param backslash_separators
- */
-void htp_config_set_query_backslash_separators(htp_cfg_t *cfg, int backslash_separators) {
-    cfg->query_backslash_separators = backslash_separators;
-}
-
-/**
- * Configures filesystem sensitivity. This setting affects
- * how URL paths are normalized. There are no path modifications by default, but
- * on a case-insensitive systems path will be converted to lowercase.
- *
- * @param cfg
- * @param case_insensitive
- */
-void htp_config_set_path_case_insensitive(htp_cfg_t *cfg, int case_insensitive) {
-    cfg->path_case_insensitive = case_insensitive;
-}
-
-/**
- * Configures filesystem sensitivity. This setting affects
- * how URL querys are normalized. There are no query modifications by default, but
- * on a case-insensitive systems query will be converted to lowercase.
- *
- * @param cfg
- * @param case_insensitive
- */
-void htp_config_set_query_case_insensitive(htp_cfg_t *cfg, int case_insensitive) {
-    cfg->query_case_insensitive = case_insensitive;
-}
-
-/**
- * Configures whether consecutive path segment separators will be compressed. When
- * enabled, a path such as "/one//two" will be normalized to "/one/two". The backslash_separators
- * and decode_separators parameters are used before compression takes place. For example, if
- * backshasl_deparators and decode_separators are both enabled, the path "/one\\/two\/%5cthree/%2f//four"
- * will be converted to "/one/two/three/four".
- *
- * @param cfg
- * @param compress_separators
- */
-void htp_config_set_path_compress_separators(htp_cfg_t *cfg, int compress_separators) {
-    cfg->path_compress_separators = compress_separators;
-}
-
-/**
- * Configures whether consecutive query segment separators will be compressed. When
- * enabled, a query such as "/one//two" will be normalized to "/one/two". The backslash_separators
- * and decode_separators parameters are used before compression takes place. For example, if
- * backshasl_deparators and decode_separators are both enabled, the query "/one\\/two\/%5cthree/%2f//four"
- * will be converted to "/one/two/three/four".
- *
- * @param cfg
- * @param compress_separators
- */
-void htp_config_set_query_compress_separators(htp_cfg_t *cfg, int compress_separators) {
-    cfg->query_compress_separators = compress_separators;
-}
-
-/**
- * This parameter is used to predict how a server will react when control
- * characters are present in a request path, but does not affect path
- * normalization.
- *
- * @param cfg
- * @param control_char_handling Use NONE with servers that ignore control characters in
- *                              request path, and STATUS_400 with servers that respond
- *                              with 400.
- */
-void htp_config_set_path_control_char_handling(htp_cfg_t *cfg, int control_char_handling) {
-    cfg->path_control_char_handling = control_char_handling;
-}
-
-/**
- * This parameter is used to predict how a server will react when control
- * characters are present in a request query, but does not affect query
- * normalization.
- *
- * @param cfg
- * @param control_char_handling Use NONE with servers that ignore control characters in
- *                              request query, and STATUS_400 with servers that respond
- *                              with 400.
- */
-void htp_config_set_query_control_char_handling(htp_cfg_t *cfg, int control_char_handling) {
-    cfg->query_control_char_handling = control_char_handling;
-}
-
-/**
- * Controls the UTF-8 treatment of request paths. One option is to only validate
- * path as UTF-8. In this case, the UTF-8 flags will be raised as appropriate, and
- * the path will remain in UTF-8 (if it was UTF-8in the first place). The other option
- * is to convert a UTF-8 path into a single byte stream using best-fit mapping.
- *
- * @param cfg
- * @param convert_utf8
- */
-void htp_config_set_path_convert_utf8(htp_cfg_t *cfg, int convert_utf8) {
-    cfg->path_convert_utf8 = convert_utf8;
-}
-
-/**
- * Configures whether encoded path segment separators will be decoded. Apache does
- * not do this, but IIS does. If enabled, a path such as "/one%2ftwo" will be normalized
- * to "/one/two". If the backslash_separators option is also enabled, encoded backslash
- * characters will be converted too (and subseqently normalized to forward slashes).
- *
- * @param cfg
- * @param decode_separators
- */
-void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int decode_separators) {
-    cfg->path_decode_separators = decode_separators;
-}
-
-/**
- * Configures whether encoded query segment separators will be decoded. Apache does
- * not do this, but IIS does. If enabled, a query such as "/one%2ftwo" will be normalized
- * to "/one/two". If the backslash_separators option is also enabled, encoded backslash
- * characters will be converted too (and subseqently normalized to forward slashes).
- *
- * @param cfg
- * @param decode_separators
- */
-void htp_config_set_query_decode_separators(htp_cfg_t *cfg, int decode_separators) {
-    cfg->query_decode_separators = decode_separators;
-}
-
-/**
- * Configures whether %u-encoded sequences in path will be decoded. Such sequences
- * will be treated as invalid URL encoding if decoding is not desireable. 
- *
- * @param cfg
- * @param decode_u_encoding
- */
-void htp_config_set_path_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding) {
-    cfg->path_decode_u_encoding = decode_u_encoding;
-}
-
-/**
- * Configures whether %u-encoded sequences in query will be decoded. Such sequences
- * will be treated as invalid URL encoding if decoding is not desireable.
- *
- * @param cfg
- * @param decode_u_encoding
- */
-void htp_config_set_query_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding) {
-    cfg->query_decode_u_encoding = decode_u_encoding;
-}
-
-/**
- * Configures how server reacts to invalid encoding in path.
- *
- * @param cfg
- * @param invalid_encoding_handling The available options are: URL_DECODER_PRESERVE_PERCENT,
- *                                  URL_DECODER_REMOVE_PERCENT, URL_DECODER_DECODE_INVALID
- *                                  and URL_DECODER_STATUS_400.
- */
-void htp_config_set_path_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling) {
-    cfg->path_invalid_encoding_handling = invalid_encoding_handling;
-}
-
-/**
- * Configures how server reacts to invalid encoding in query.
- *
- * @param cfg
- * @param invalid_encoding_handling The available options are: URL_DECODER_PRESERVE_PERCENT,
- *                                  URL_DECODER_REMOVE_PERCENT, URL_DECODER_DECODE_INVALID
- *                                  and URL_DECODER_STATUS_400.
- */
-void htp_config_set_query_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling) {
-    cfg->query_invalid_encoding_handling = invalid_encoding_handling;
-}
-
-
-/**
- * Configures how server reacts to invalid UTF-8 characters in path. This setting will
- * not affect path normalization; it only controls what response status we expect for
- * a request that contains invalid UTF-8 characters.
- *
- * @param cfg
- * @param invalid_utf8_handling Possible values: NONE or STATUS_400.
- */
-void htp_config_set_path_invalid_utf8_handling(htp_cfg_t *cfg, int invalid_utf8_handling) {
-    cfg->path_invalid_utf8_handling = invalid_utf8_handling;
-}
-
-/**
- * Configures how server reacts to encoded NUL bytes. Some servers will terminate
- * path at NUL, while some will respond with 400 or 404. When the termination option
- * is not used, the NUL byte will remain in the path.
- *
- * @param cfg
- * @param nul_encoded_handling Possible values: TERMINATE, STATUS_400, STATUS_404
- */
-void htp_config_set_path_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling) {
-    cfg->path_nul_encoded_handling = nul_encoded_handling;
-}
-
-/**
- * Configures how server reacts to encoded NUL bytes. Some servers will terminate
- * query at NUL, while some will respond with 400 or 404. When the termination option
- * is not used, the NUL byte will remain in the query.
- *
- * @param cfg
- * @param nul_encoded_handling Possible values: TERMINATE, STATUS_400, STATUS_404
- */
-void htp_config_set_query_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling) {
-    cfg->query_nul_encoded_handling = nul_encoded_handling;
-}
-
-/**
- * Configures how server reacts to raw NUL bytes. Some servers will terminate
- * path at NUL, while some will respond with 400 or 404. When the termination option
- * is not used, the NUL byte will remain in the path.
- *
- * @param cfg
- * @param nul_raw_handling Possible values: TERMINATE, STATUS_400, STATUS_404
- */
-void htp_config_set_path_nul_raw_handling(htp_cfg_t *cfg, int nul_raw_handling) {
-    cfg->path_nul_raw_handling = nul_raw_handling;
-}
-
-/**
- * Configures how server reacts to raw NUL bytes. Some servers will terminate
- * query at NUL, while some will respond with 400 or 404. When the termination option
- * is not used, the NUL byte will remain in the query.
- *
- * @param cfg
- * @param nul_raw_handling Possible values: TERMINATE, STATUS_400, STATUS_404
- */
-void htp_config_set_query_nul_raw_handling(htp_cfg_t *cfg, int nul_raw_handling) {
-    cfg->query_nul_raw_handling = nul_raw_handling;
-}
-
-/**
- * Sets the replacement characater that will be used to in the lossy best-fit
- * mapping from Unicode characters into single-byte streams. The question mark
- * is the default replacement character.
- *
- * @param cfg
- * @param replacement_char
- */
-void htp_config_set_path_replacement_char(htp_cfg_t *cfg, int replacement_char) {
-    cfg->path_replacement_char = replacement_char;
-}
-
-/**
- * Controls what the library does when it encounters an Unicode character where
- * only a single-byte would do (e.g., the %u-encoded characters). Conversion always
- * takes place; this parameter is used to correctly predict the status code used
- * in response. In the future there will probably be an option to convert such
- * characters to UCS-2 or UTF-8.
- *
- * @param cfg
- * @param unicode_mapping Possible values: BESTFIT, STATUS_400, STATUS_404.
- */
-void htp_config_set_path_unicode_mapping(htp_cfg_t *cfg, int unicode_mapping) {
-    cfg->path_unicode_mapping = unicode_mapping;
-}
-
-/**
- * Controls how server reacts to overlong UTF-8 characters.
- * XXX Not used at the moment.
- *
- * @param cfg
- * @param utf8_overlong_handling
- */
-void htp_config_set_path_utf8_overlong_handling(htp_cfg_t *cfg, int utf8_overlong_handling) {
-    cfg->path_utf8_overlong_handling = utf8_overlong_handling;
-}
-
-/**
- * Configure desired server personality.
- *
- * @param cfg
- * @param personality
- * @return HTP_OK if the personality is supported, HTP_ERROR if it isn't.
- */
-int htp_config_set_server_personality(htp_cfg_t *cfg, int personality) {
-    switch (personality) {
-        case HTP_SERVER_MINIMAL:
-            cfg->parse_request_line = htp_parse_request_line_generic;
-            cfg->process_request_header = htp_process_request_header_generic;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-            break;
-
-        case HTP_SERVER_GENERIC:
-            cfg->parse_request_line = htp_parse_request_line_generic;
-            cfg->process_request_header = htp_process_request_header_generic;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-
-            cfg->path_backslash_separators = YES;
-            cfg->path_decode_separators = YES;
-            cfg->path_compress_separators = YES;
-
-//            cfg->query_backslash_separators = YES;
-            cfg->query_decode_separators = YES;
-//            cfg->query_compress_separators = YES;
-            break;
-
-        case HTP_SERVER_IDS:
-            cfg->parse_request_line = htp_parse_request_line_generic;
-            cfg->process_request_header = htp_process_request_header_generic;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-
-            cfg->path_backslash_separators = YES;
-            cfg->path_case_insensitive = YES;
-            cfg->path_decode_separators = YES;
-            cfg->path_compress_separators = YES;
-            cfg->path_decode_u_encoding = YES;
-            cfg->path_unicode_mapping = BESTFIT;
-            cfg->path_convert_utf8 = YES;
-
-//            cfg->query_backslash_separators = YES;
-            cfg->query_case_insensitive = YES;
-            cfg->query_decode_separators = YES;
-//            cfg->query_compress_separators = YES;
-            cfg->query_decode_u_encoding = YES;
-            break;
-
-        case HTP_SERVER_APACHE :
-        case HTP_SERVER_APACHE_2_2:
-            cfg->parse_request_line = htp_parse_request_line_apache_2_2;
-            cfg->process_request_header = htp_process_request_header_apache_2_2;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-            
-            cfg->path_backslash_separators = NO;
-            cfg->path_decode_separators = NO;
-            cfg->path_compress_separators = YES;
-            cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;            
-            cfg->path_control_char_handling = NONE;
-
-//            cfg->query_backslash_separators = NO;
-            cfg->query_decode_separators = NO;
-//            cfg->query_compress_separators = YES;
-            cfg->query_invalid_encoding_handling = URL_DECODER_STATUS_400;
-            cfg->query_control_char_handling = NONE;
-            break;
-
-        case HTP_SERVER_IIS_5_1:
-            cfg->parse_request_line = htp_parse_request_line_generic;
-            cfg->process_request_header = htp_process_request_header_generic;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-
-            cfg->path_backslash_separators = YES;
-            cfg->path_decode_separators = NO;
-            cfg->path_compress_separators = YES;
-            cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-            cfg->path_decode_u_encoding = YES;
-            cfg->path_unicode_mapping = BESTFIT;
-            cfg->path_control_char_handling = NONE;
-
-//            cfg->query_backslash_separators = YES;
-            cfg->query_decode_separators = NO;
-//            cfg->query_compress_separators = YES;
-            cfg->query_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-            cfg->query_decode_u_encoding = YES;
-//            cfg->query_unicode_mapping = BESTFIT;
-            cfg->query_control_char_handling = NONE;
-            break;
-
-        case HTP_SERVER_IIS_6_0:
-            cfg->parse_request_line = htp_parse_request_line_generic;
-            cfg->process_request_header = htp_process_request_header_generic;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-
-            cfg->path_backslash_separators = YES;
-            cfg->path_decode_separators = YES;
-            cfg->path_compress_separators = YES;
-            cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
-            cfg->path_decode_u_encoding = YES;
-            cfg->path_unicode_mapping = STATUS_400;
-            cfg->path_control_char_handling = STATUS_400;
-
-//            cfg->query_backslash_separators = YES;
-            cfg->query_decode_separators = YES;
-//            cfg->query_compress_separators = YES;
-            cfg->query_invalid_encoding_handling = URL_DECODER_STATUS_400;
-            cfg->query_decode_u_encoding = YES;
-//            cfg->query_unicode_mapping = STATUS_400;
-            cfg->query_control_char_handling = STATUS_400;
-            break;
-
-        case HTP_SERVER_IIS_7_0:
-        case HTP_SERVER_IIS_7_5:
-            cfg->parse_request_line = htp_parse_request_line_generic;
-            cfg->process_request_header = htp_process_request_header_generic;
-            cfg->parse_response_line = htp_parse_response_line_generic;
-            cfg->process_response_header = htp_process_response_header_generic;
-
-            cfg->path_backslash_separators = YES;
-            cfg->path_decode_separators = YES;
-            cfg->path_compress_separators = YES;
-            cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
-            cfg->path_control_char_handling = STATUS_400;
-
-//            cfg->query_backslash_separators = YES;
-            cfg->query_decode_separators = YES;
-//            cfg->query_compress_separators = YES;
-            cfg->query_invalid_encoding_handling = URL_DECODER_STATUS_400;
-            cfg->query_control_char_handling = STATUS_400;
-            break;
-            
-        default:
-            return HTP_ERROR;
-    }
-
-    // Remember the personality
-    cfg->spersonality = personality;   
-
-    return HTP_OK;
-}
diff --git a/libhtp/htp/htp_connection.c b/libhtp/htp/htp_connection.c
deleted file mode 100644 (file)
index cd2a9a6..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * Creates a new connection structure.
- *
- * @param connp
- * @return A new htp_connp_t structure on success, NULL on memory allocation failure.
- */
-htp_conn_t *htp_conn_create(htp_connp_t *connp) {
-    htp_conn_t *conn = calloc(1, sizeof (htp_conn_t));
-    if (conn == NULL) return NULL;
-
-    conn->connp = connp;
-
-    conn->transactions = list_array_create(16);
-    if (conn->transactions == NULL) {
-        free(conn);
-        return NULL;
-    }
-
-    conn->messages = list_array_create(8);
-    if (conn->messages == NULL) {
-        list_destroy(conn->transactions);
-        free(conn);
-        return NULL;
-    }
-
-    return conn;
-}
-
-/**
- * Destroys a connection, as well as all the transactions it contains. It is
- * not possible to destroy a connection structure yet leave any of its
- * transactions intact. This is because transactions need its connection and
- * connection structures hold little data anyway. The opposite is true, though
- * it is possible to delete a transaction but leave its connection alive.
- *
- * @param conn
- */
-void htp_conn_destroy(htp_conn_t *conn) {
-    if (conn == NULL) return;
-    
-    // Destroy individual transactions. Do note that iterating
-    // using the iterator does not work here because some of the
-    // list element may be NULL (and with the iterator it is impossible
-    // to distinguish a NULL element from the end of the list).
-    if (conn->transactions != NULL) {
-        size_t i;
-        for (i = 0; i < list_size(conn->transactions); i++) {
-            htp_tx_t *tx = (htp_tx_t *)list_get(conn->transactions, i);
-            if (tx != NULL) {
-                htp_tx_destroy(tx);
-            }
-        }
-
-        list_destroy(conn->transactions);
-    }
-
-    // Destroy individual messages
-    if (conn->messages != NULL) {
-        htp_log_t *l = NULL;
-        list_iterator_reset(conn->messages);
-        while ((l = list_iterator_next(conn->messages)) != NULL) {
-            free((void *)l->msg);
-            free(l);
-        }
-
-        list_destroy(conn->messages);
-    }
-
-    if (conn->local_addr != NULL) {
-        free(conn->local_addr);
-    }
-
-    if (conn->remote_addr != NULL) {
-        free(conn->remote_addr);
-    }
-   
-    // Finally, destroy the connection
-    // structure itself.
-    free(conn);
-}
-
-/**
- * Removes the given transaction structure, which makes it possible to
- * safely destroy it. It is safe to destroy transactions in this way
- * because the index of the transactions (in a connection) is preserved.
- *
- * @param conn
- * @param tx
- * @return 1 if transaction was removed or 0 if it wasn't found
- */
-int htp_conn_remove_tx(htp_conn_t *conn, htp_tx_t *tx) {
-    if ((tx == NULL)||(conn == NULL)||(conn->transactions == NULL)) return 0;
-
-    unsigned int i = 0;
-    for (i = 0; i < list_size(conn->transactions); i++) {
-        htp_tx_t *etx = list_get(conn->transactions, i);
-        if (tx == etx) {
-            list_replace(conn->transactions, i, NULL);
-            return 1;
-        }
-    }
-
-    return 0;
-}
diff --git a/libhtp/htp/htp_connection_parser.c b/libhtp/htp/htp_connection_parser.c
deleted file mode 100644 (file)
index f8b995b..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-// NOTE The parser contains a lot of duplicated code. That is on purpose.
-//
-//      Within the request parser alone there are several states in which
-//      bytes are copied into the line buffer and lines are processed one at a time.
-//      This code could be made more elegant by adding a new line-reading state along
-//      with a what-fn-to-invoke-to-handle-line pointer.
-//
-//      Furthermore, the entire request parser is terribly similar to the response parser.
-//      It is imaginable that a single parser could handle both.
-//
-//      After some thought, I decided not to make any changes (at least not for the time
-//      being). State-based parsers are sometimes difficult to understand. I remember trying
-//      to figure one once and I had a hard time following the logic because each function
-//      was small and did exactly one thing. There was jumping all around. You could probably
-//      say that it was elegant, but I saw it as difficult to understand, verify and maintain.
-//
-//      Thus, I am keeping this inelegant but quite straightforward parser with duplicated code,
-//      mostly for the sake of maintenance.
-//
-//      For the time being, anyway. I will review at a later time.
-
-/**
- * Clears an existing parser error, if any.
- *
- * @param connp
- */
-void htp_connp_clear_error(htp_connp_t *connp) {
-    connp->last_error = NULL;
-}
-
-/**
- * Closes the connection associated with the supplied parser.
- *
- * @param connp
- * @param timestamp
- */
-void htp_connp_close(htp_connp_t *connp, htp_time_t timestamp) {
-    // Update internal information
-    connp->conn->close_timestamp = timestamp;
-    connp->in_status = STREAM_STATE_CLOSED;
-    connp->out_status = STREAM_STATE_CLOSED;
-
-    // Call the parsers one last time, which will allow them
-    // to process the events that depend on stream closure
-    htp_connp_req_data(connp, timestamp, NULL, 0);
-    htp_connp_res_data(connp, timestamp, NULL, 0);
-}
-
-/**
- * Creates a new connection parser using the provided configuration. Because
- * the configuration structure is used directly, in a multithreaded environment
- * you are not allowed to change the structure, ever. If you have a need to
- * change configuration on per-connection basis, make a copy of the configuration
- * structure to go along with every connection parser.
- *
- * @param cfg
- * @return A pointer to a newly created htp_connp_t instance.
- */
-htp_connp_t *htp_connp_create(htp_cfg_t *cfg) {
-    htp_connp_t *connp = calloc(1, sizeof (htp_connp_t));
-    if (connp == NULL) return NULL;
-
-    // Use the supplied configuration structure
-    connp->cfg = cfg;
-
-    // Create a new connection object
-    connp->conn = htp_conn_create(connp);
-    if (connp->conn == NULL) {
-        free(connp);
-        return NULL;
-    }
-
-    connp->in_status = HTP_OK;
-
-    // Request parsing
-
-    connp->in_line_size = cfg->field_limit_hard;
-    connp->in_line_len = 0;
-    connp->in_line = malloc(connp->in_line_size);
-    if (connp->in_line == NULL) {
-        htp_conn_destroy(connp->conn);
-        free(connp);
-        return NULL;
-    }
-
-    connp->in_header_line_index = -1;
-    connp->in_state = htp_connp_REQ_IDLE;
-
-    // Response parsing
-
-    connp->out_line_size = cfg->field_limit_hard;
-    connp->out_line_len = 0;
-    connp->out_line = malloc(connp->out_line_size);
-    if (connp->out_line == NULL) {
-        free(connp->in_line);
-        htp_conn_destroy(connp->conn);
-        free(connp);
-        return NULL;
-    }
-
-    connp->out_header_line_index = -1;
-    connp->out_state = htp_connp_RES_IDLE;
-
-    connp->in_status = STREAM_STATE_NEW;
-    connp->out_status = STREAM_STATE_NEW;
-
-    return connp;
-}
-
-/**
- * Creates a new configuration parser, making a copy of the supplied
- * configuration structure.
- *
- * @param cfg
- * @return A pointer to a newly created htp_connp_t instance.
- */
-htp_connp_t *htp_connp_create_copycfg(htp_cfg_t *cfg) {
-    htp_connp_t *connp = htp_connp_create(cfg);
-    if (connp == NULL) return NULL;
-
-    connp->cfg = htp_config_copy(cfg);
-    if (connp->cfg == NULL) {
-        htp_connp_destroy(connp);
-        return NULL;
-    }
-
-    connp->is_cfg_private = 1;
-
-    return connp;
-}
-
-/**
- * Destroys the connection parser and its data structures, leaving
- * the connection data intact.
- *
- * @param connp
- */
-void htp_connp_destroy(htp_connp_t *connp) {
-    if (connp == NULL)
-        return;
-
-    if (connp->out_decompressor != NULL) {
-        connp->out_decompressor->destroy(connp->out_decompressor);
-        connp->out_decompressor = NULL;
-    }
-
-    if (connp->in_header_line != NULL) {
-        if (connp->in_header_line->line != NULL) {
-            free(connp->in_header_line->line);
-        }
-
-        free(connp->in_header_line);
-    }
-
-    if (connp->in_line != NULL)
-        free(connp->in_line);
-
-    if (connp->out_header_line != NULL) {
-        if (connp->out_header_line->line != NULL) {
-            free(connp->out_header_line->line);
-        }
-
-        free(connp->out_header_line);
-    }
-
-    if (connp->out_line != NULL)
-        free(connp->out_line);
-
-    // Destroy the configuration structure, but only
-    // if it is our private copy
-    if ((connp->is_cfg_private) && (connp->cfg != NULL)) {
-        htp_config_destroy(connp->cfg);
-    }
-
-    free(connp);
-}
-
-/**
- * Destroys the connection parser, its data structures, as well
- * as the connection and its transactions.
- *
- * @param connp
- */
-void htp_connp_destroy_all(htp_connp_t *connp) {
-    if (connp == NULL)
-        return;
-
-    if (connp->conn != NULL) {
-        // Destroy connection
-        htp_conn_destroy(connp->conn);
-        connp->conn = NULL;
-    }
-
-    // Destroy everything else
-    htp_connp_destroy(connp);
-}
-
-/**
- * Retrieve the user data associated with this connection parser.
- * 
- * @param connp
- * @return User data, or NULL if there isn't any.
- */
-void *htp_connp_get_data(htp_connp_t *connp) {
-    return connp->user_data;
-}
-
-/**
- * Returns the last error that occured with this connection parser. Do note, however,
- * that the value in this field will only be valid immediately after an error condition,
- * but it is not guaranteed to remain valid if the parser is invoked again.
- *
- * @param connp
- * @return A pointer to an htp_log_t instance if there is an error, or NULL
- *         if there isn't.
- */
-htp_log_t *htp_connp_get_last_error(htp_connp_t *connp) {
-    return connp->last_error;
-}
-
-/**
- * Opens connection.
- *
- * @param connp
- * @param remote_addr Remote address
- * @param remote_port Remote port
- * @param local_addr Local address
- * @param local_port Local port
- * @param timestamp
- */
-void htp_connp_open(htp_connp_t *connp, const char *remote_addr, int remote_port, const char *local_addr, int local_port, htp_time_t timestamp) {
-    if ((connp->in_status != STREAM_STATE_NEW) || (connp->out_status != STREAM_STATE_NEW)) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Connection is already open");
-        return;
-    }
-
-    if (remote_addr != NULL) {
-        connp->conn->remote_addr = strdup(remote_addr);
-        if (connp->conn->remote_addr == NULL) return;
-    }
-
-    connp->conn->remote_port = remote_port;
-
-    if (local_addr != NULL) {
-        connp->conn->local_addr = strdup(local_addr);
-        if (connp->conn->local_addr == NULL) {
-            if (connp->conn->remote_addr != NULL) {
-                free(connp->conn->remote_addr);
-            }
-            return;
-        }
-    }
-
-    connp->conn->local_port = local_port;
-    connp->conn->open_timestamp = timestamp;
-    connp->in_status = STREAM_STATE_OPEN;
-    connp->out_status = STREAM_STATE_OPEN;
-}
-
-/**
- * Associate user data with the supplied parser.
- *
- * @param connp
- * @param user_data
- */
-void htp_connp_set_user_data(htp_connp_t *connp, void *user_data) {
-    connp->user_data = user_data;
-}
-
-void *htp_connp_get_user_data(htp_connp_t *connp) {
-    return(connp->user_data);
-}
diff --git a/libhtp/htp/htp_decompressors.c b/libhtp/htp/htp_decompressors.c
deleted file mode 100644 (file)
index d9a0c0d..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-#include "htp_decompressors.h"
-
-/**
- * Decompress a chunk of gzip-compressed data.
- *
- * @param drec
- * @param d
- */
-static int htp_gzip_decompressor_decompress(htp_decompressor_gzip_t *drec, htp_tx_data_t *d) {
-    size_t consumed = 0;
-
-    // Return if we've previously had an error
-    if (drec->initialized < 0) {
-        return drec->initialized;
-    }
-
-    // Do we need to initialize?
-    if (drec->initialized == 0) {
-        // Check the header
-        if ((drec->header_len == 0) && (d->len >= 10)) {
-            // We have received enough data initialize; use the input buffer directly
-            if ((d->data[0] != DEFLATE_MAGIC_1) || (d->data[1] != DEFLATE_MAGIC_2)) {
-                htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                    "GZip decompressor: Magic bytes mismatch");
-                drec->initialized = -1;
-                return -1;
-            }
-
-            if (d->data[3] == 0) {
-                drec->initialized = 1;
-                consumed = 10;
-            } else if ((d->data[3] & (1 << 3)) || (d->data[3] & (1 << 4))) {
-                /* skip past
-                 * - FNAME extension, which is a name ended in a NUL terminator
-                 * or
-                 * - FCOMMENT extension, which is a commend ended in a NULL terminator
-                 */
-
-                size_t len;
-                for (len = 10; len < d->len && d->data[len] != '\0'; len++);
-
-                drec->initialized = 1;
-                consumed = len + 1;
-            } else {
-                htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                    "GZip decompressor: Unable to handle flags: %d", d->data[3]);
-                drec->initialized = -1;
-                return -1;
-            }
-        } else {
-            // We do not (or did not) have enough bytes, so we have
-            // to copy some data into our internal header buffer.
-
-            // How many bytes do we need?
-            size_t copylen = 10 - drec->header_len;
-
-            // Is there enough in input?
-            if (copylen > d->len) copylen = d->len;
-
-            // Copy the bytes
-            memcpy(drec->header + drec->header_len, d->data, copylen);
-            drec->header_len += copylen;
-            consumed = copylen;
-
-            // Do we have enough now?
-            if (drec->header_len == 10) {
-                // We do!
-                if ((drec->header[0] != DEFLATE_MAGIC_1) || (drec->header[1] != DEFLATE_MAGIC_2)) {
-                    htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                        "GZip decompressor: Magic bytes mismatch");
-                    drec->initialized = -1;
-                    return -1;
-                }
-
-                if (drec->header[3] != 0) {
-                    htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                        "GZip decompressor: Unable to handle flags: %d", d->data[3]);
-                    drec->initialized = -1;
-                    return -1;
-                }
-
-                drec->initialized = 1;
-            } else {
-                // Need more data
-                return 1;
-            }
-        }
-    }
-
-    // Decompress data
-    int rc = 0;
-    drec->stream.next_in = d->data + consumed;
-    drec->stream.avail_in = d->len - consumed;
-
-    while (drec->stream.avail_in != 0) {
-        // If there's no more data left in the
-        // buffer, send that information out
-        if (drec->stream.avail_out == 0) {
-            drec->crc = crc32(drec->crc, drec->buffer, GZIP_BUF_SIZE);
-
-            // Prepare data for callback
-            htp_tx_data_t d2;
-            d2.tx = d->tx;
-            d2.data = drec->buffer;
-            d2.len = GZIP_BUF_SIZE;
-
-            // Send decompressed data to callback
-            if (drec->super.callback(&d2) < 0) {
-                inflateEnd(&drec->stream);
-                drec->zlib_initialized = 0;
-                return -1;
-            }
-
-            drec->stream.next_out = drec->buffer;
-            drec->stream.avail_out = GZIP_BUF_SIZE;
-        }
-
-        rc = inflate(&drec->stream, Z_NO_FLUSH);
-
-        if (rc == Z_STREAM_END) {
-            // How many bytes do we have?
-            size_t len = GZIP_BUF_SIZE - drec->stream.avail_out;
-
-            // Update CRC
-            drec->crc = crc32(drec->crc, drec->buffer, len);
-
-            // Prepare data for callback
-            htp_tx_data_t d2;
-            d2.tx = d->tx;
-            d2.data = drec->buffer;
-            d2.len = len;
-            
-            // Send decompressed data to callback
-            if (drec->super.callback(&d2) < 0) {
-                inflateEnd(&drec->stream);
-                drec->zlib_initialized = 0;
-                return -1;
-            }
-
-            // TODO Handle trailer           
-
-            return 1;
-        }
-
-        if (rc != Z_OK) {
-            htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                    "GZip decompressor: inflate failed with %d", rc);
-
-            inflateEnd(&drec->stream);
-            drec->zlib_initialized = 0;
-
-            return -1;
-        }
-    }
-
-    return 1;
-}
-
-/**
- * Shut down gzip decompressor.
- *
- * @param drec
- */
-static void htp_gzip_decompressor_destroy(htp_decompressor_gzip_t * drec) {
-    if (drec == NULL) return;
-
-    if (drec->zlib_initialized) {
-        inflateEnd(&drec->stream);
-        drec->zlib_initialized = 0;
-    }
-
-    free(drec->buffer);
-    free(drec);
-}
-
-/**
- * Initialize gzip decompressor.
- *
- * @param connp
- */
-htp_decompressor_t * htp_gzip_decompressor_create(htp_connp_t *connp) {
-    htp_decompressor_gzip_t *drec = calloc(1, sizeof (htp_decompressor_gzip_t));
-    if (drec == NULL) return NULL;
-
-    drec->super.decompress = (int (*)(htp_decompressor_t *, htp_tx_data_t *)) htp_gzip_decompressor_decompress;
-    drec->super.destroy = (void (*)(htp_decompressor_t *))htp_gzip_decompressor_destroy;
-
-    drec->buffer = malloc(GZIP_BUF_SIZE);
-    if (drec->buffer == NULL) {
-        free(drec);
-        return NULL;
-    }
-
-    int rc = inflateInit2(&drec->stream, GZIP_WINDOW_SIZE);
-    if (rc != Z_OK) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-            "GZip decompressor: inflateInit2 failed with code %d", rc);
-
-        inflateEnd(&drec->stream);
-        free(drec->buffer);
-        free(drec);
-
-        return NULL;
-    }
-
-    drec->zlib_initialized = 1;
-    drec->stream.avail_out = GZIP_BUF_SIZE;
-    drec->stream.next_out = drec->buffer;
-
-    return (htp_decompressor_t *) drec;
-}
diff --git a/libhtp/htp/htp_decompressors.h b/libhtp/htp/htp_decompressors.h
deleted file mode 100644 (file)
index 1782797..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _HTP_DECOMPRESSORS_H
-#define        _HTP_DECOMPRESSORS_H
-
-typedef struct htp_decompressor_gzip_t htp_decompressor_gzip_t;
-typedef struct htp_decompressor_t htp_decompressor_t;
-
-#include "zlib.h"
-
-#define GZIP_BUF_SIZE       8192
-#define GZIP_WINDOW_SIZE    -15
-
-#define DEFLATE_MAGIC_1     0x1f
-#define DEFLATE_MAGIC_2     0x8b
-
-struct htp_decompressor_t {
-    int (*decompress)(htp_decompressor_t *, htp_tx_data_t *);
-    int (*callback)(htp_tx_data_t *);
-    void (*destroy)(htp_decompressor_t *);
-};
-
-struct htp_decompressor_gzip_t {
-    htp_decompressor_t super;
-    int initialized;
-    int zlib_initialized;
-    uint8_t header[10];
-    uint8_t header_len;
-    z_stream stream;
-    unsigned char *buffer;
-    unsigned long crc;    
-};
-
-htp_decompressor_t * htp_gzip_decompressor_create(htp_connp_t *connp);
-
-#endif /* _HTP_DECOMPRESSORS_H */
-
diff --git a/libhtp/htp/htp_parsers.c b/libhtp/htp/htp_parsers.c
deleted file mode 100644 (file)
index 5d9bdc8..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * Determines protocol number from a textual representation (i.e., "HTTP/1.1"). This
- * function will only understand a properly formatted protocol information. It does
- * not try to be flexible.
- * 
- * @param protocol
- * @return Protocol version or PROTOCOL_UKNOWN.
- */
-int htp_parse_protocol(bstr *protocol) {
-    if (protocol != NULL && bstr_len(protocol) == 8) {
-        char *ptr = bstr_ptr(protocol);
-        if ((ptr[0] == 'H') && (ptr[1] == 'T') && (ptr[2] == 'T') && (ptr[3] == 'P')
-            && (ptr[4] == '/') && (ptr[6] == '.')) {
-            // Check the version numbers
-            if (ptr[5] == '0') {
-                if (ptr[7] == '9') {
-                    return HTTP_0_9;
-                }
-            } else if (ptr[5] == '1') {
-                if (ptr[7] == '0') {
-                    return HTTP_1_0;
-                } else if (ptr[7] == '1') {
-                    return HTTP_1_1;
-                }
-            }
-        }
-    }
-
-    return PROTOCOL_UNKNOWN;
-}
-
-/**
- * Determines the numerical value of a response status given as a string.
- *
- * @param status
- * @return Status code on success, or -1 on error.
- */
-int htp_parse_status(bstr *status) {
-    return htp_parse_positive_integer_whitespace((unsigned char *)bstr_ptr(status), bstr_len(status), 10);
-}
diff --git a/libhtp/htp/htp_request.c b/libhtp/htp/htp_request.c
deleted file mode 100644 (file)
index f7d3d89..0000000
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <stdlib.h>
-
-#include "htp.h"
-
-/**
- * Performs check for a CONNECT transaction to decide whether inbound
- * parsing needs to be suspended.
- *
- * @param connp
- * @return HTP_OK if the request does not use CONNECT, HTP_DATA_OTHER if
- *          inbound parsing needs to be suspended until we hear from the
- *          other side
- */
-int htp_connp_REQ_CONNECT_CHECK(htp_connp_t *connp) {
-    // If the request uses the CONNECT method, then there will
-    // not be a request body, but first we need to wait to see the
-    // response in order to determine if the tunneling request
-    // was a success.
-    if (connp->in_tx->request_method_number == M_CONNECT) {
-        connp->in_state = htp_connp_REQ_CONNECT_WAIT_RESPONSE;
-        connp->in_status = STREAM_STATE_DATA_OTHER;
-        connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
-
-        return HTP_DATA_OTHER;
-    }
-
-    // Continue to the next step to determine the presence
-    // of the request body
-    connp->in_state = htp_connp_REQ_BODY_DETERMINE;
-
-    return HTP_OK;
-}
-
-/**
- * Determines whether inbound parsing, which was suspended after
- * encountering a CONNECT transaction, can proceed (after receiving
- * the response).
- *
- * @param connp
- * @return HTP_OK if the parser can resume parsing, HTP_DATA_OTHER if
- *         it needs to continue waiting.
- */
-int htp_connp_REQ_CONNECT_WAIT_RESPONSE(htp_connp_t *connp) {
-    // Check that we saw the response line of the current
-    // inbound transaction.
-    if (connp->in_tx->progress[0] <= TX_PROGRESS_RES_LINE) {
-        return HTP_DATA_OTHER;
-    }
-
-    // A 2xx response means a tunnel was established. Anything
-    // else means we continue to follow the HTTP stream.
-    if ((connp->in_tx->response_status_number >= 200) && (connp->in_tx->response_status_number <= 299)) {
-        // TODO Check that the server did not accept a connection
-        //      to itself.
-
-        // The requested tunnel was established: we are going
-        // to ignore the remaining data on this stream
-        connp->in_status = STREAM_STATE_TUNNEL;
-        connp->in_state = htp_connp_REQ_IDLE;
-    } else {
-        // No tunnel; continue to the next transaction
-        connp->in_state = htp_connp_REQ_IDLE;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Consumes bytes until the end of the current line.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_BODY_CHUNKED_DATA_END(htp_connp_t *connp) {
-    // TODO We shouldn't really see anything apart from CR and LF,
-    // so we should warn about anything else.
-
-    for (;;) {
-        IN_NEXT_BYTE_OR_RETURN(connp);
-
-        connp->in_tx->request_message_len++;
-
-        if (connp->in_next_byte == LF) {
-            connp->in_state = htp_connp_REQ_BODY_CHUNKED_LENGTH;
-            return HTP_OK;
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Processes a chunk of data.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_BODY_CHUNKED_DATA(htp_connp_t *connp) {
-    htp_tx_data_t d;
-
-    d.tx = connp->in_tx;
-    d.data = &connp->in_current_data[connp->in_current_offset];
-    d.len = 0;
-
-    for (;;) {
-        IN_NEXT_BYTE(connp);
-
-        if (connp->in_next_byte == -1) {
-            // Send data to callbacks
-            int rc = hook_run_all(connp->cfg->hook_request_body_data, &d);
-            if (rc != HOOK_OK) {
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                    "Request body data callback returned error (%d)", rc);
-                return HTP_ERROR;
-            }
-
-            // Ask for more data
-            return HTP_DATA;
-        } else {
-            connp->in_tx->request_message_len++;
-            connp->in_tx->request_entity_len++;
-            connp->in_chunked_length--;
-            d.len++;
-
-            if (connp->in_chunked_length == 0) {
-                // End of data chunk
-
-                // Send data to callbacks
-                int rc = hook_run_all(connp->cfg->hook_request_body_data, &d);
-                if (rc != HOOK_OK) {
-                    htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                        "Request body data callback returned error (%d)", rc);
-                    return HTP_ERROR;
-                }
-
-                connp->in_state = htp_connp_REQ_BODY_CHUNKED_DATA_END;
-
-                return HTP_OK;
-            }
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Extracts chunk length.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_BODY_CHUNKED_LENGTH(htp_connp_t *connp) {
-    for (;;) {
-        IN_COPY_BYTE_OR_RETURN(connp);
-
-        connp->in_tx->request_message_len++;
-
-        // Have we reached the end of the line?
-        if (connp->in_next_byte == LF) {
-            htp_chomp(connp->in_line, &connp->in_line_len);
-
-            // Extract chunk length
-            connp->in_chunked_length = htp_parse_chunked_length(connp->in_line, connp->in_line_len);
-
-            // Cleanup for the next line
-            connp->in_line_len = 0;
-
-            // Handle chunk length
-            if (connp->in_chunked_length > 0) {
-                // More data available
-                // TODO Add a check for chunk length
-                connp->in_state = htp_connp_REQ_BODY_CHUNKED_DATA;
-            } else if (connp->in_chunked_length == 0) {
-                // End of data
-                connp->in_state = htp_connp_REQ_HEADERS;
-                connp->in_tx->progress[0] = TX_PROGRESS_REQ_TRAILER;
-            } else {
-                // Invalid chunk length
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                    "Request chunk encoding: Invalid chunk length");
-                return HTP_ERROR;
-            }
-
-            return HTP_OK;
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Processes identity request body.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_BODY_IDENTITY(htp_connp_t *connp) {
-    htp_tx_data_t d;
-
-    d.tx = connp->in_tx;
-    d.data = &connp->in_current_data[connp->in_current_offset];
-    d.len = 0;
-
-    for (;;) {
-        IN_NEXT_BYTE(connp);
-
-        if (connp->in_next_byte == -1) {
-            // End of chunk
-
-            if (d.len != 0) {
-                int rc = hook_run_all(connp->cfg->hook_request_body_data, &d);
-                if (rc != HOOK_OK) {
-                    htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                        "Request body data callback returned error (%d)", rc);
-                    return HTP_ERROR;
-                }
-            }
-
-            // Ask for more data
-            return HTP_DATA;
-        } else {
-            connp->in_tx->request_message_len++;
-            connp->in_tx->request_entity_len++;
-            connp->in_body_data_left--;
-            d.len++;
-
-            if (connp->in_body_data_left == 0) {
-                // End of body
-
-                if (d.len != 0) {
-                    int rc = hook_run_all(connp->cfg->hook_request_body_data, &d);
-                    if (rc != HOOK_OK) {
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                            "Request body data callback returned error (%d)", rc);
-                        return HTP_ERROR;
-                    }
-                }
-
-                // Done
-                connp->in_state = htp_connp_REQ_IDLE;
-                connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
-
-                return HTP_OK;
-            }
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Determines presence (and encoding) of a request body.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp) {
-    htp_header_t *cl = table_getc(connp->in_tx->request_headers, "content-length");
-    htp_header_t *te = table_getc(connp->in_tx->request_headers, "transfer-encoding");
-
-    // Check for the Transfer-Encoding header, which
-    // would indicate a chunked request body
-    if (te != NULL && te->value != NULL) {
-        // Make sure it contains "chunked" only
-        if (bstr_cmpc(te->value, "chunked") != 0) {
-            // Invalid T-E header value
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Invalid T-E value in request");
-        }
-
-        // Chunked encoding is a HTTP/1.1 feature. Check
-        // that some other protocol is not used. The flag will
-        // also be set if the protocol could not be parsed.
-        //
-        // TODO IIS 7.0, for example, would ignore the T-E header when it
-        //      it is used with a protocol below HTTP 1.1.
-        if (connp->in_tx->request_protocol_number < HTTP_1_1) {
-            connp->in_tx->flags |= HTP_INVALID_CHUNKING;
-            // TODO Log
-        }
-
-        // If the T-E header is present we are going to use it.
-        connp->in_tx->request_transfer_coding = CHUNKED;
-
-        // We are still going to check for the presence of C-L
-        if (cl != NULL) {
-            // This is a violation of the RFC
-            connp->in_tx->flags |= HTP_REQUEST_SMUGGLING;
-            // TODO Log
-        }
-
-        connp->in_state = htp_connp_REQ_BODY_CHUNKED_LENGTH;
-        connp->in_tx->progress[0] = TX_PROGRESS_REQ_BODY;
-    } else
-        // Next check for the presence of the Content-Length header
-        if (cl != NULL && cl->value != NULL) {
-        // It seems that we have a request body.
-        connp->in_tx->request_transfer_coding = IDENTITY;
-
-        // Check for a folded C-L header
-        if (cl->flags & HTP_FIELD_FOLDED) {
-            connp->in_tx->flags |= HTP_REQUEST_SMUGGLING;
-            // TODO Log
-        }
-
-        // Check for multiple C-L headers
-        if (cl->flags & HTP_FIELD_REPEATED) {
-            connp->in_tx->flags |= HTP_REQUEST_SMUGGLING;
-            // TODO Log
-        }
-
-        // Get body length
-        int i = htp_parse_content_length(cl->value);
-        if (i < 0) {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid C-L field in request");
-            return HTP_ERROR;
-        } else {
-            connp->in_content_length = i;
-            connp->in_body_data_left = connp->in_content_length;
-
-            if (connp->in_content_length != 0) {
-                connp->in_state = htp_connp_REQ_BODY_IDENTITY;
-                connp->in_tx->progress[0] = TX_PROGRESS_REQ_BODY;
-            } else {
-                connp->in_state = htp_connp_REQ_IDLE;
-                connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
-            }
-        }
-    } else {
-        // This request does not have a body, which
-        // means that we're done with it
-        connp->in_state = htp_connp_REQ_IDLE;
-        connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
-    }
-
-    // Host resolution    
-    htp_header_t *h = table_getc(connp->in_tx->request_headers, "host");
-    if (h == NULL) {
-        // No host information in the headers
-
-        // HTTP/1.1 requires host information in the headers
-        if (connp->in_tx->request_protocol_number >= HTTP_1_1) {
-            connp->in_tx->flags |= HTP_HOST_MISSING;
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                "Host information in request headers required by HTTP/1.1");
-        }
-    } else {
-        // Host information available in the headers
-
-        // Is there host information in the URI?
-        if (connp->in_tx->parsed_uri->hostname == NULL) {
-            // There is no host information in the URI. Place the
-            // hostname from the headers into the parsed_uri structure.
-            htp_replace_hostname(connp, connp->in_tx->parsed_uri, h->value);
-        } else if (bstr_cmp_nocase(h->value, connp->in_tx->parsed_uri->hostname) != 0) {
-            // The host information is different in the
-            // headers and the URI. The HTTP RFC states that
-            // we should ignore the headers copy.
-            connp->in_tx->flags |= HTP_AMBIGUOUS_HOST;
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Host information ambiguous");
-        }
-    }
-
-    // Run hook REQUEST_HEADERS
-    int rc = hook_run_all(connp->cfg->hook_request_headers, connp);
-    if (rc != HOOK_OK) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-            "Request headers callback returned error (%d)", rc);
-        return HTP_ERROR;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Parses request headers.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
-    for (;;) {
-        IN_COPY_BYTE_OR_RETURN(connp);
-
-        if (connp->in_header_line == NULL) {
-            connp->in_header_line = calloc(1, sizeof (htp_header_line_t));
-            if (connp->in_header_line == NULL) return HTP_ERROR;
-            connp->in_header_line->first_nul_offset = -1;
-        }
-
-        // Keep track of NUL bytes
-        if (connp->in_next_byte == 0) {
-            // Store the offset of the first NUL
-            if (connp->in_header_line->has_nulls == 0) {
-                connp->in_header_line->first_nul_offset = connp->in_line_len;
-            }
-
-            // Remember how many NULs there were
-            connp->in_header_line->flags |= HTP_FIELD_NUL_BYTE;
-            connp->in_header_line->has_nulls++;
-        }
-
-        // Have we reached the end of the line?
-        if (connp->in_next_byte == LF) {
-            #ifdef HTP_DEBUG
-            fprint_raw_data(stderr, __FUNCTION__, connp->in_line, connp->in_line_len);
-            #endif
-
-            // Should we terminate headers?
-            if (htp_connp_is_line_terminator(connp, connp->in_line, connp->in_line_len)) {
-                // Terminator line
-
-                // Parse previous header, if any
-                if (connp->in_header_line_index != -1) {
-                    if (connp->cfg->process_request_header(connp) != HTP_OK) {
-                        // Note: downstream responsible for error logging
-                        return HTP_ERROR;
-                    }
-
-                    // Reset index
-                    connp->in_header_line_index = -1;
-                }
-
-                // Cleanup
-                free(connp->in_header_line);
-                connp->in_line_len = 0;
-                connp->in_header_line = NULL;                
-
-                // We've seen all request headers
-                if (connp->in_chunk_count != connp->in_chunk_request_index) {
-                    connp->in_tx->flags |= HTP_MULTI_PACKET_HEAD;
-                }
-
-                // Move onto the next processing phase
-                if (connp->in_tx->progress[0] == TX_PROGRESS_REQ_HEADERS) {
-                    // Determine if this request has a body
-                    //connp->in_state = htp_connp_REQ_BODY_DETERMINE;
-                    connp->in_state = htp_connp_REQ_CONNECT_CHECK;
-                } else {
-                    // Run hook REQUEST_TRAILER
-                    int rc = hook_run_all(connp->cfg->hook_request_trailer, connp);
-                    if (rc != HOOK_OK) {
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                            "Request trailer callback returned error (%d)", rc);
-                        return HTP_ERROR;
-                    }
-
-                    // We've completed parsing this request
-                    connp->in_state = htp_connp_REQ_IDLE;
-                    connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
-                }
-
-                return HTP_OK;
-            }
-
-            // Prepare line for consumption
-            size_t raw_in_line_len = connp->in_line_len;
-            htp_chomp(connp->in_line, &connp->in_line_len);
-
-            // Check for header folding
-            if (htp_connp_is_line_folded(connp->in_line, connp->in_line_len) == 0) {
-                // New header line
-
-                // Parse previous header, if any
-                if (connp->in_header_line_index != -1) {
-                    if (connp->cfg->process_request_header(connp) != HTP_OK) {
-                        // Note: downstream responsible for error logging
-                        return HTP_ERROR;
-                    }
-
-                    // Reset index
-                    connp->in_header_line_index = -1;
-                }
-
-                // Remember the index of the fist header line
-                connp->in_header_line_index = connp->in_header_line_counter;
-            } else {
-                // Folding; check that there's a previous header line to add to
-                if (connp->in_header_line_index == -1) {
-                    if (!(connp->in_tx->flags & HTP_INVALID_FOLDING)) {
-                        connp->in_tx->flags |= HTP_INVALID_FOLDING;
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0,
-                            "Invalid request field folding");
-                    }
-                }
-            }
-
-            // Add the raw header line to the list
-            if (raw_in_line_len > connp->in_line_len) {
-                if (raw_in_line_len - connp->in_line_len == 2 &&
-                        connp->in_line[connp->in_line_len] == 0x0d &&
-                        connp->in_line[connp->in_line_len + 1] == 0x0a) {
-                    connp->in_header_line->terminators = NULL;
-                } else {
-                    connp->in_header_line->terminators =
-                        bstr_memdup((char *) connp->in_line + connp->in_line_len,
-                                raw_in_line_len - connp->in_line_len);
-                    if (connp->in_header_line->terminators == NULL) {
-                        return HTP_ERROR;
-                    }
-                }
-            } else {
-                connp->in_header_line->terminators = NULL;
-            }
-
-            connp->in_header_line->line = bstr_memdup((char *) connp->in_line, connp->in_line_len);
-            if (connp->in_header_line->line == NULL) {
-                return HTP_ERROR;
-            }
-            list_add(connp->in_tx->request_header_lines, connp->in_header_line);
-            connp->in_header_line = NULL;
-
-            // Cleanup for the next line
-            connp->in_line_len = 0;
-            if (connp->in_header_line_index == -1) {
-                connp->in_header_line_index = connp->in_header_line_counter;
-            }
-
-            connp->in_header_line_counter++;
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Determines request protocol.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_PROTOCOL(htp_connp_t *connp) {
-    // Is this a short-style HTTP/0.9 request? If it is,
-    // we will not want to parse request headers.
-    if (connp->in_tx->protocol_is_simple == 0) {
-        // Switch to request header parsing.
-        connp->in_state = htp_connp_REQ_HEADERS;
-        connp->in_tx->progress[0] = TX_PROGRESS_REQ_HEADERS;
-    } else {
-        // We're done with this request.
-        connp->in_state = htp_connp_REQ_IDLE;
-        connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Parses request line.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_LINE(htp_connp_t *connp) {
-    for (;;) {
-        // Get one byte
-        IN_COPY_BYTE_OR_RETURN(connp);
-
-        // Keep track of NUL bytes
-        if (connp->in_next_byte == 0) {
-            // Remember how many NULs there were
-            connp->in_tx->request_line_nul++;
-
-            // Store the offset of the first NUL byte
-            if (connp->in_tx->request_line_nul_offset == -1) {
-                connp->in_tx->request_line_nul_offset = connp->in_line_len;
-            }
-        }
-
-        // Have we reached the end of the line?
-        if (connp->in_next_byte == LF) {
-            #ifdef HTP_DEBUG
-            fprint_raw_data(stderr, __FUNCTION__, connp->in_line, connp->in_line_len);
-            #endif
-
-            // Is this a line that should be ignored?
-            if (htp_connp_is_line_ignorable(connp, connp->in_line, connp->in_line_len)) {
-                // We have an empty/whitespace line, which we'll note, ignore and move on
-                connp->in_tx->request_ignored_lines++;
-
-                // TODO How many empty lines are we willing to accept?
-
-                // Start again
-                connp->in_line_len = 0;
-
-                return HTP_OK;
-            }
-
-            // Process request line
-
-            htp_chomp(connp->in_line, &connp->in_line_len);
-            connp->in_tx->request_line = bstr_memdup((char *) connp->in_line, connp->in_line_len);
-            if (connp->in_tx->request_line == NULL) {
-                return HTP_ERROR;
-            }
-
-            // Parse request line
-            if (connp->cfg->parse_request_line(connp) != HTP_OK) {
-                // Note: downstream responsible for error logging
-                return HTP_ERROR;
-            }
-
-            if (connp->in_tx->request_method_number == M_CONNECT) {
-                // Parse authority
-                if (htp_parse_authority(connp, connp->in_tx->request_uri, &(connp->in_tx->parsed_uri_incomplete)) != HTP_OK) {
-                    // Note: downstream responsible for error logging
-                    return HTP_ERROR;
-                }
-            } else {
-                // Parse the request URI
-                if (htp_parse_uri(connp->in_tx->request_uri, &(connp->in_tx->parsed_uri_incomplete)) != HTP_OK) {
-                    // Note: downstream responsible for error logging
-                    return HTP_ERROR;
-                }               
-
-                // Keep the original URI components, but
-                // create a copy which we can normalize and use internally
-                if (htp_normalize_parsed_uri(connp, connp->in_tx->parsed_uri_incomplete, connp->in_tx->parsed_uri)) {
-                    // Note: downstream responsible for error logging
-                    return HTP_ERROR;
-                }               
-
-                // Run hook REQUEST_URI_NORMALIZE
-                int rc = hook_run_all(connp->cfg->hook_request_uri_normalize, connp);
-                if (rc != HOOK_OK) {
-                    htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                            "Request URI normalize callback returned error (%d)", rc);
-                    return HTP_ERROR;
-                }
-
-                // Now is a good time to generate request_uri_normalized, before we finalize
-                // parsed_uri (and lose the information which parts were provided in the request and
-                // which parts we added).
-                if (connp->cfg->generate_request_uri_normalized) {                 
-                    connp->in_tx->request_uri_normalized = htp_unparse_uri_noencode(connp->in_tx->parsed_uri);                   
-
-                    if (connp->in_tx->request_uri_normalized == NULL) {
-                        // There's no sense in logging anything on a memory allocation failure
-                        return HTP_ERROR;
-                    }                   
-
-                    #ifdef HTP_DEBUG
-                    fprint_raw_data(stderr, "request_uri_normalized",
-                        (unsigned char *) bstr_ptr(connp->in_tx->request_uri_normalized),
-                        bstr_len(connp->in_tx->request_uri_normalized));
-                    #endif
-                }               
-
-                // Finalize parsed_uri
-
-                // Scheme
-                if (connp->in_tx->parsed_uri->scheme != NULL) {
-                    if (bstr_cmpc(connp->in_tx->parsed_uri->scheme, "http") != 0) {
-                        // TODO Invalid scheme
-                    }
-                } else {
-                    connp->in_tx->parsed_uri->scheme = bstr_cstrdup("http");
-                    if (connp->in_tx->parsed_uri->scheme == NULL) {
-                        return HTP_ERROR;
-                    }
-                }
-
-                // Port
-                if (connp->in_tx->parsed_uri->port != NULL) {
-                    if (connp->in_tx->parsed_uri->port_number != -1) {
-                        // Check that the port in the URI is the same
-                        // as the port on which the client is talking
-                        // to the server
-                        if (connp->in_tx->parsed_uri->port_number != connp->conn->local_port) {
-                            // Incorrect port; use the real port instead
-                            connp->in_tx->parsed_uri->port_number = connp->conn->local_port;
-                            // TODO Log
-                        }
-                    } else {
-                        // Invalid port; use the real port instead
-                        connp->in_tx->parsed_uri->port_number = connp->conn->local_port;
-                        // TODO Log
-                    }
-                } else {
-                    connp->in_tx->parsed_uri->port_number = connp->conn->local_port;
-                }
-
-                // Path
-                if (connp->in_tx->parsed_uri->path == NULL) {
-                    connp->in_tx->parsed_uri->path = bstr_cstrdup("/");
-                    if (connp->in_tx->parsed_uri->path == NULL) {
-                        return HTP_ERROR;
-                    }
-                }               
-            }
-
-            // Run hook REQUEST_LINE
-            int rc = hook_run_all(connp->cfg->hook_request_line, connp);
-            if (rc != HOOK_OK) {
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                    "Request line callback returned error (%d)", rc);
-                return HTP_ERROR;
-            }
-
-            // Clean up.
-            connp->in_line_len = 0;
-
-            // Move on to the next phase.
-            connp->in_state = htp_connp_REQ_PROTOCOL;
-
-            return HTP_OK;
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * The idle state is invoked before and after every transaction. Consequently,
- * it will start a new transaction when data is available and finalise a transaction
- * which has been processed.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_REQ_IDLE(htp_connp_t * connp) {
-    // If we're here and a transaction object exists that
-    // means we've just completed parsing a request. We need
-    // to run the final hook and start over.
-    if (connp->in_tx != NULL) {
-        // Run hook REQUEST
-        int rc = hook_run_all(connp->cfg->hook_request, connp);
-        if (rc != HOOK_OK) {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Request callback returned error (%d)", rc);
-            return HTP_ERROR;
-        }
-
-        // Start afresh
-        connp->in_tx = NULL;
-    }
-
-    // We want to start parsing the next request (and change
-    // the state from IDLE) only if there's at least one
-    // byte of data available. Otherwise we could be creating
-    // new structures even if there's no more data on the
-    // connection.
-    IN_TEST_NEXT_BYTE_OR_RETURN(connp);
-
-    // Detect pipelining
-    if (list_size(connp->conn->transactions) > connp->out_next_tx_index) {
-        connp->conn->flags |= PIPELINED_CONNECTION;
-    }
-
-    // Parsing a new request
-    connp->in_tx = htp_tx_create(connp->cfg, CFG_SHARED, connp->conn);
-    if (connp->in_tx == NULL) return HTP_ERROR;
-
-    connp->in_tx->connp = connp;
-
-    list_add(connp->conn->transactions, connp->in_tx);
-
-    connp->in_content_length = -1;
-    connp->in_body_data_left = -1;
-    connp->in_header_line_index = -1;
-    connp->in_header_line_counter = 0;
-    connp->in_chunk_request_index = connp->in_chunk_count;
-
-    // Run hook TRANSACTION_START
-    int rc = hook_run_all(connp->cfg->hook_transaction_start, connp);
-    if (rc != HOOK_OK) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-            "Transaction start callback returned error (%d)", rc);
-        return HTP_ERROR;
-    }
-
-    // Change state into request line parsing
-    connp->in_state = htp_connp_REQ_LINE;
-    connp->in_tx->progress[0] = TX_PROGRESS_REQ_LINE;
-
-    return HTP_OK;
-}
-
-size_t htp_connp_req_data_consumed(htp_connp_t *connp) {
-    return connp->in_current_offset;
-}
-
-/**
- * Process a chunk of inbound (client or request) data.
- * 
- * @param connp
- * @param timestamp
- * @param data
- * @param len
- * @return HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_req_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char *data, size_t len) {
-    #ifdef HTP_DEBUG
-    fprintf(stderr, "htp_connp_req_data(connp->in_status %x)\n", connp->in_status);
-    fprint_raw_data(stderr, __FUNCTION__, data, len);
-    #endif
-
-    // Return if the connection has had a fatal error
-    if (connp->in_status == STREAM_STATE_ERROR) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Inbound parser is in STREAM_STATE_ERROR");
-
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA (previous error)\n");
-        #endif
-
-        return STREAM_STATE_ERROR;
-    }
-
-    // If the length of the supplied data chunk is zero, proceed
-    // only if the stream has been closed. We do not allow zero-sized
-    // chunks in the API, but we use it internally to force the parsers
-    // to finalize parsing.
-    if ((len == 0) && (connp->in_status != STREAM_STATE_CLOSED)) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Zero-length data chunks are not allowed");
-
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA (zero-length chunk)\n");
-        #endif
-
-        return STREAM_STATE_ERROR;
-    }
-
-    // Store the current chunk information
-    connp->in_timestamp = timestamp;
-    connp->in_current_data = data;
-    connp->in_current_len = len;
-    connp->in_current_offset = 0;
-    connp->in_chunk_count++;
-    connp->conn->in_data_counter += len;
-    connp->conn->in_packet_counter++;
-
-    // Return without processing any data if the stream is in tunneling
-    // mode (which it would be after an initial CONNECT transaction).
-    if (connp->in_status == STREAM_STATE_TUNNEL) {
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_TUNNEL\n");
-        #endif
-        return STREAM_STATE_TUNNEL;
-    }
-
-    // Invoke a processor, in a loop, until an error
-    // occurs or until we run out of data. Many processors
-    // will process a request, each pointing to the next
-    // processor that needs to run.
-    for (;;) {
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_req_data: in state=%s, progress=%s\n",
-            htp_connp_in_state_as_string(connp),
-            htp_tx_progress_as_string(connp->in_tx, 0));
-        #endif
-
-        // Return if there's been an error
-        // or if we've run out of data. We are relying
-        // on processors to add error messages, so we'll
-        // keep quiet here.
-        int rc = connp->in_state(connp);
-        if (rc == HTP_OK) {
-            if (connp->in_status == STREAM_STATE_TUNNEL) {
-                #ifdef HTP_DEBUG
-                fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_TUNNEL\n");
-                #endif
-
-                return STREAM_STATE_TUNNEL;
-            }
-        } else {
-            // Do we need more data?
-            if (rc == HTP_DATA) {
-                #ifdef HTP_DEBUG
-                fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA\n");
-                #endif
-
-                return STREAM_STATE_DATA;
-            }
-
-            // Check for suspended parsing
-            if (rc == HTP_DATA_OTHER) {
-                // We might have actually consumed the entire data chunk?
-                if (connp->in_current_offset >= connp->in_current_len) {
-                    // Do not send STREAM_DATE_DATA_OTHER if we've
-                    // consumed the entire chunk
-                    #ifdef HTP_DEBUG
-                    fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA (suspended parsing)\n");
-                    #endif
-                    return STREAM_STATE_DATA;
-                } else {
-                    // Partial chunk consumption
-                    #ifdef HTP_DEBUG
-                    fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA_OTHER\n");
-                    #endif
-                    return STREAM_STATE_DATA_OTHER;
-                }
-            }
-
-            // Remember that we've had an error. Errors are
-            // (at least at present) not possible to recover from.
-            connp->in_status = STREAM_STATE_ERROR;
-
-            #ifdef HTP_DEBUG
-            fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_ERROR (state response)\n");
-            #endif
-
-            return STREAM_STATE_ERROR;
-        }
-    }
-    return HTP_ERROR;
-}
-
diff --git a/libhtp/htp/htp_request_apache_2_2.c b/libhtp/htp/htp_request_apache_2_2.c
deleted file mode 100644 (file)
index e8e0f30..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * Extract one request header. A header can span multiple lines, in
- * which case they will be folded into one before parsing is attempted.
- *
- * @param connp
- * @return HTP_OK or HTP_ERROR
- */
-int htp_process_request_header_apache_2_2(htp_connp_t *connp) {
-    bstr *tempstr = NULL;
-    unsigned char *data = NULL;
-    size_t len = 0;
-
-    // Create new header structure
-    htp_header_t *h = calloc(1, sizeof (htp_header_t));
-    if (h == NULL) return HTP_ERROR;
-
-    // Ensure we have the necessary header data in a single buffer
-    if (connp->in_header_line_index + 1 == connp->in_header_line_counter) {
-        // Single line
-        htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines,
-            connp->in_header_line_index);
-        if (hl == NULL) {
-            // Internal error
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Process request header (Apache 2.2): Internal error");
-            free(h);
-            return HTP_ERROR;
-        }
-
-        data = (unsigned char *) bstr_ptr(hl->line);
-        len = bstr_len(hl->line);
-        hl->header = h;
-    } else {
-        // Multiple lines (folded)
-        int i = 0;
-
-        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
-            htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines, i);
-            if (hl == NULL) {
-                // Internal error
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                        "Process request header (Apache 2.2): Internal error");
-                free(h);
-                return HTP_ERROR;
-            }
-            len += bstr_len(hl->line);
-        }
-
-        tempstr = bstr_alloc(len);
-        if (tempstr == NULL) {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Process request header (Apache 2.2): Failed to allocate bstring of %d bytes", len);
-            free(h);
-            return HTP_ERROR;
-        }
-
-        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
-            htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines, i);
-            if (hl == NULL) {
-                // Internal error
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                        "Process request header (Apache 2.2): Internal error");
-                bstr_free(tempstr);
-                free(h);
-                return HTP_ERROR;
-            }
-            char *data = bstr_ptr(hl->line);
-            size_t len = bstr_len(hl->line);
-            htp_chomp((unsigned char *)data, &len);
-            bstr_add_mem_noex(tempstr, data, len);
-            hl->header = h;
-        }
-
-        data = (unsigned char *) bstr_ptr(tempstr);
-    }
-
-    // Now try to parse the header
-    if (htp_parse_request_header_apache_2_2(connp, h, data, len) != HTP_OK) {
-        // Note: downstream responsible for error logging
-        if (tempstr != NULL) {
-            free(tempstr);
-        }
-        free(h);
-        return HTP_ERROR;
-    }
-
-    // Do we already have a header with the same name?
-    htp_header_t *h_existing = table_get(connp->in_tx->request_headers, h->name);
-    if (h_existing != NULL) {
-        // TODO Do we want to keep a list of the headers that are
-        //      allowed to be combined in this way?
-
-        // Add to existing header
-        h_existing->value = bstr_expand(h_existing->value, bstr_len(h_existing->value)
-            + 2 + bstr_len(h->value));
-        bstr_add_mem_noex(h_existing->value, ", ", 2);
-        bstr_add_str_noex(h_existing->value, h->value);
-
-        // The header is no longer needed
-        if (h->name != NULL)
-            free(h->name);
-        if (h->value != NULL)
-            free(h->value);
-        free(h);
-
-        // Keep track of same-name headers        
-        h_existing->flags |= HTP_FIELD_REPEATED;
-    } else {
-        // Add as a new header
-        table_add(connp->in_tx->request_headers, h->name, h);
-    }
-
-    if (tempstr != NULL) {
-        free(tempstr);
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Parses a message header line as Apache 2.2 does.
- *
- * @param connp
- * @param h
- * @param data
- * @param len
- * @return HTP_OK or HTP_ERROR
- */
-int htp_parse_request_header_apache_2_2(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len) {
-    size_t name_start, name_end;
-    size_t value_start, value_end;
-
-    htp_chomp(data, &len);
-
-    name_start = 0;
-
-    // Look for the colon
-    size_t colon_pos = 0;
-    while ((colon_pos < len) && (data[colon_pos] != '\0') && (data[colon_pos] != ':')) colon_pos++;
-
-    if ((colon_pos == len) || (data[colon_pos] == '\0')) {
-        // Missing colon
-        h->flags |= HTP_FIELD_UNPARSEABLE;
-
-        if (!(connp->in_tx->flags & HTP_FIELD_UNPARSEABLE)) {
-            connp->in_tx->flags |= HTP_FIELD_UNPARSEABLE;
-            // Only log once per transaction
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Request field invalid: colon missing");
-        }
-
-        return HTP_ERROR;
-    }
-
-    if (colon_pos == 0) {
-        // Empty header name
-        h->flags |= HTP_FIELD_INVALID;
-
-        if (!(connp->in_tx->flags & HTP_FIELD_INVALID)) {
-            connp->in_tx->flags |= HTP_FIELD_INVALID;
-            // Only log once per transaction
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request field invalid: empty name");
-        }
-    }
-
-    name_end = colon_pos;
-
-    // Ignore LWS after field-name
-    size_t prev = name_end - 1;
-    while ((prev > name_start) && (htp_is_lws(data[prev]))) {
-        prev--;
-        name_end--;
-
-        h->flags |= HTP_FIELD_INVALID;
-
-        if (!(connp->in_tx->flags & HTP_FIELD_INVALID)) {
-            connp->in_tx->flags |= HTP_FIELD_INVALID;
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request field invalid: LWS after name");
-        }
-    }
-
-    // Value
-
-    value_start = colon_pos;
-
-    // Go over the colon
-    if (value_start < len) {
-        value_start++;
-    }
-
-    // Ignore LWS before field-content
-    while ((value_start < len) && (htp_is_lws(data[value_start]))) {
-        value_start++;
-    }
-
-    // Look for the end of field-content
-    value_end = value_start;
-    while ((value_end < len) && (data[value_end] != '\0')) value_end++;
-
-    // Ignore LWS after field-content
-    prev = value_end - 1;
-    while ((prev > value_start) && (htp_is_lws(data[prev]))) {
-        prev--;
-        value_end--;
-    }
-
-    // Check that the header name is a token
-    size_t i = name_start;
-    while (i < name_end) {
-        if (!htp_is_token(data[i])) {
-            h->flags |= HTP_FIELD_INVALID;
-
-            if (!(connp->in_tx->flags & HTP_FIELD_INVALID)) {
-                connp->in_tx->flags |= HTP_FIELD_INVALID;
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request header name is not a token");
-            }
-
-            break;
-        }
-
-        i++;
-    }
-
-    // Now extract the name and the value
-    h->name = bstr_memdup((char *) data + name_start, name_end - name_start);
-    if (h->name == NULL)
-        return HTP_ERROR;
-    h->value = bstr_memdup((char *) data + value_start, value_end - value_start);
-    if (h->value == NULL) {
-        bstr_free(h->name);
-        return HTP_ERROR;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Parse request line as Apache 2.2 does.
- *
- * @param connp
- * @return HTP_OK or HTP_ERROR
- */
-int htp_parse_request_line_apache_2_2(htp_connp_t *connp) {
-    htp_tx_t *tx = connp->in_tx;
-    unsigned char *data = (unsigned char *) bstr_ptr(tx->request_line);
-    size_t len = bstr_len(tx->request_line);
-    size_t pos = 0;
-
-    // In this implementation we assume the
-    // line ends with the first NUL byte.
-    if (tx->request_line_nul_offset != -1) {
-        len = tx->request_line_nul_offset - 1;
-    }
-
-    // The request method starts at the beginning of the
-    // line and ends with the first whitespace character.
-    while ((pos < len) && (!htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    // No, we don't care if the method is empty.
-
-    tx->request_method = bstr_memdup((char *) data, pos);
-    if (tx->request_method == NULL) {
-        return HTP_ERROR;
-    }
-
-#ifdef HTP_DEBUG
-    fprint_raw_data(stderr, __FUNCTION__, (unsigned char *)bstr_ptr(tx->request_method), bstr_len(tx->request_method));
-#endif
-
-    tx->request_method_number = htp_convert_method_to_number(tx->request_method);
-
-    // Ignore whitespace after request method. The RFC allows
-    // for only one SP, but then suggests any number of SP and HT
-    // should be permitted. Apache uses isspace(), which is even
-    // more permitting, so that's what we use here.
-    while ((pos < len) && (isspace(data[pos]))) {
-        pos++;
-    }
-
-    size_t start = pos;
-
-    // The URI ends with the first whitespace.
-    while ((pos < len) && (!htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    tx->request_uri = bstr_memdup((char *) data + start, pos - start);
-    if (tx->request_uri == NULL) {
-        return HTP_ERROR;
-    }
-
-#ifdef HTP_DEBUG
-    fprint_raw_data(stderr, __FUNCTION__, (unsigned char *)bstr_ptr(tx->request_uri), bstr_len(tx->request_uri));
-#endif
-
-    // Ignore whitespace after URI
-    while ((pos < len) && (htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    // Is there protocol information available?
-    if (pos == len) {
-        // No, this looks like a HTTP/0.9 request.
-        tx->protocol_is_simple = 1;
-        return HTP_OK;
-    }
-
-    // The protocol information spreads until the end of the line.
-    tx->request_protocol = bstr_memdup((char *) data + pos, len - pos);
-    if (tx->request_protocol == NULL)
-        return HTP_ERROR;
-    tx->request_protocol_number = htp_parse_protocol(tx->request_protocol);
-
-#ifdef HTP_DEBUG
-    fprint_raw_data(stderr, __FUNCTION__, (unsigned char *)bstr_ptr(tx->request_protocol), bstr_len(tx->request_protocol));
-#endif
-
-    return HTP_OK;
-}
diff --git a/libhtp/htp/htp_request_generic.c b/libhtp/htp/htp_request_generic.c
deleted file mode 100644 (file)
index 56ad6ff..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION fo the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * Extract one request header. A header can span multiple lines, in
- * which case they will be folded into one before parsing is attempted.
- *
- * @param connp
- * @return HTP_OK or HTP_ERROR
- */
-int htp_process_request_header_generic(htp_connp_t *connp) {
-    bstr *tempstr = NULL;
-    unsigned char *data = NULL;
-    size_t len = 0;
-
-    // Create new header structure
-    htp_header_t *h = calloc(1, sizeof (htp_header_t));
-    if (h == NULL) {
-        // TODO
-        return HTP_ERROR;
-    }
-
-    // Ensure we have the necessary header data in a single buffer
-    if (connp->in_header_line_index + 1 == connp->in_header_line_counter) {
-        // Single line
-        htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines,
-            connp->in_header_line_index);
-        if (hl == NULL) {
-            // Internal error
-            // TODO
-            free(h);
-            return HTP_ERROR;
-        }
-
-        data = (unsigned char *)bstr_ptr(hl->line);
-        if (data == NULL) {
-            free(h);
-            return HTP_ERROR;
-        }
-        len = bstr_len(hl->line);
-        hl->header = h;
-    } else {
-        // Multiple lines (folded)
-        int i = 0;
-
-        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
-            htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines, i);
-            len += bstr_len(hl->line);
-        }
-
-        tempstr = bstr_alloc(len);
-        if (tempstr == NULL) {
-            // TODO
-            free(h);
-            return HTP_ERROR;
-        }
-
-        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
-            htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines, i);
-            char *data = bstr_ptr(hl->line);
-            size_t len = bstr_len(hl->line);
-            htp_chomp((unsigned char *)data, &len);
-            bstr_add_mem_noex(tempstr, data, len);
-            hl->header = h;
-        }
-
-        data = (unsigned char *)bstr_ptr(tempstr);
-    }
-
-    // Now try to oparse the header
-    if (htp_parse_request_header_generic(connp, h, data, len) != HTP_OK) {
-        if (tempstr != NULL) {
-            free(tempstr);
-        }
-
-        free(h);
-
-        return HTP_ERROR;
-    }
-
-    // Do we already have a header with the same name?
-    htp_header_t *h_existing = table_get(connp->in_tx->request_headers, h->name);
-    if (h_existing != NULL) {
-        // TODO Do we want to keep a list of the headers that are
-        //      allowed to be combined in this way?
-
-        // Add to existing header
-        h_existing->value = bstr_expand(h_existing->value, bstr_len(h_existing->value)
-            + 2 + bstr_len(h->value));
-        bstr_add_mem_noex(h_existing->value, ", ", 2);
-        bstr_add_str_noex(h_existing->value, h->value);
-
-        // The header is no longer needed
-        free(h->name);
-        free(h->value);
-        free(h);
-
-        // Keep track of same-name headers        
-        h_existing->flags |= HTP_FIELD_REPEATED;
-    } else {
-        // Add as a new header
-        table_add(connp->in_tx->request_headers, h->name, h);
-    }
-
-    if (tempstr != NULL) {
-        free(tempstr);
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Generic request header parser.
- *
- * @param connp
- * @param h
- * @param data
- * @param len
- * @return HTP_OK or HTP_ERROR
- */
-int htp_parse_request_header_generic(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len) {
-    size_t name_start, name_end;
-    size_t value_start, value_end;
-
-    htp_chomp(data, &len);   
-
-    name_start = 0;
-
-    // Look for the colon
-    size_t colon_pos = 0;
-    
-    while ((colon_pos < len) && (data[colon_pos] != ':')) colon_pos++;
-    
-    if (colon_pos == len) {
-        // Missing colon
-        h->flags |= HTP_FIELD_UNPARSEABLE;
-
-        if (!(connp->in_tx->flags & HTP_FIELD_UNPARSEABLE)) {
-            connp->in_tx->flags |= HTP_FIELD_UNPARSEABLE;
-            // Only log once per transaction
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Request field invalid: colon missing");
-        }
-
-        return HTP_ERROR;
-    }
-
-    if (colon_pos == 0) {
-        // Empty header name
-        h->flags |= HTP_FIELD_INVALID;
-
-        if (!(connp->in_tx->flags & HTP_FIELD_INVALID)) {
-            connp->in_tx->flags |= HTP_FIELD_INVALID;
-            // Only log once per transaction
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request field invalid: empty name");
-        }
-    }
-
-    name_end = colon_pos;
-
-    // Ignore LWS after field-name
-    size_t prev = name_end - 1;
-    while ((prev > name_start) && (htp_is_lws(data[prev]))) {
-        prev--;
-        name_end--;
-
-        h->flags |= HTP_FIELD_INVALID;
-
-        if (!(connp->in_tx->flags & HTP_FIELD_INVALID)) {
-            connp->in_tx->flags |= HTP_FIELD_INVALID;
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request field invalid: LWS after name");
-        }
-    }
-
-    // Value
-
-    value_start = colon_pos;
-
-    // Go over the colon
-    if (value_start < len) {
-        value_start++;
-    }
-
-    // Ignore LWS before field-content
-    while ((value_start < len) && (htp_is_lws(data[value_start]))) {
-        value_start++;
-    }
-
-    // Look for the end of field-content
-    value_end = value_start;
-    
-    while (value_end < len) value_end++;
-
-    // Ignore LWS after field-content
-    prev = value_end - 1;
-    while ((prev > value_start) && (htp_is_lws(data[prev]))) {
-        prev--;
-        value_end--;
-    }
-
-    // Check that the header name is a token
-    size_t i = name_start;
-    while (i < name_end) {
-        if (!htp_is_token(data[i])) {
-            h->flags |= HTP_FIELD_INVALID;
-
-            if (!(connp->in_tx->flags & HTP_FIELD_INVALID)) {
-                connp->in_tx->flags |= HTP_FIELD_INVALID;
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Request header name is not a token");
-            }
-
-            break;
-        }
-
-        i++;
-    }
-
-    // Now extract the name and the value
-    h->name = bstr_memdup((char *)data + name_start, name_end - name_start);
-    if (h->name == NULL) {
-        return HTP_ERROR;
-    }
-    h->value = bstr_memdup((char *)data + value_start, value_end - value_start);
-    if (h->name == NULL) {
-        return HTP_ERROR;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Generic request line parser.
- *
- * @param connp
- * @return HTP_OK or HTP_ERROR
- */
-int htp_parse_request_line_generic(htp_connp_t *connp) {
-    htp_tx_t *tx = connp->in_tx;
-    unsigned char *data = (unsigned char *)bstr_ptr(tx->request_line);
-    size_t len = bstr_len(tx->request_line);
-    size_t pos = 0;
-
-    // The request method starts at the beginning of the
-    // line and ends with the first whitespace character.
-    while ((pos < len) && (!htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    // No, we don't care if the method is empty.
-
-    tx->request_method = bstr_memdup((char *)data, pos);
-    if (tx->request_method == NULL) {
-        return HTP_ERROR;
-    }
-    tx->request_method_number = htp_convert_method_to_number(tx->request_method);
-
-    // Ignore whitespace after request method. The RFC allows
-    // for only one SP, but then suggests any number of SP and HT
-    // should be permitted.
-    while ((pos < len) && (isspace(data[pos]))) {
-        pos++;
-    }
-
-    size_t start = pos;
-
-    // The URI ends with the first whitespace.
-    while ((pos < len) && (!htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    tx->request_uri = bstr_memdup((char *)data + start, pos - start);
-    if (tx->request_uri == NULL) {
-        return HTP_ERROR;
-    }
-
-    // Ignore whitespace after URI
-    while ((pos < len) && (htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    // Is there protocol information available?
-    if (pos == len) {
-        // No, this looks like a HTTP/0.9 request.
-        tx->protocol_is_simple = 1;
-        return HTP_OK;
-    }
-
-    // The protocol information spreads until the end of the line.
-    tx->request_protocol = bstr_memdup((char *)data + pos, len - pos);
-    if (tx->request_protocol == NULL) {
-        return HTP_ERROR;
-    }
-    tx->request_protocol_number = htp_parse_protocol(tx->request_protocol);
-
-    return HTP_OK;
-}
-
diff --git a/libhtp/htp/htp_request_parsers.c b/libhtp/htp/htp_request_parsers.c
deleted file mode 100644 (file)
index 33080bc..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-#if 0
-
-/**
- *
- */
-int htp_header_parse_internal_strict(unsigned char *data, size_t len, htp_header_t *h) {
-    size_t name_start, name_end;
-    size_t value_start, value_end;
-
-    // Deal with the name first
-    name_start = name_end = 0;
-
-    // Find where the header name ends
-    while (name_end < len) {
-        if (htp_is_lws(data[name_end]) || data[name_end] == ':') break;
-        name_end++;
-    }
-
-    if (name_end == 0) {
-        // Empty header name
-        return -1;
-    }
-
-    if (name_end == len) {
-        // TODO
-        return -1;
-    }
-
-    // Is there any LWS before colon?
-    size_t pos = name_end;
-    while (pos < len) {
-        if (!htp_is_lws(data[pos])) break;
-        pos++;
-        // TODO
-        // return -1;
-    }
-
-    if (pos == len) {
-        // TODO
-        return -1;
-    }
-
-    // The next character must be a colon
-    if (data[pos] != ':') {
-        // TODO
-        return -1;
-    }
-
-    // Move over the colon
-    pos++;
-
-    // Again, ignore any LWS
-    while (pos < len) {
-        if (!htp_is_lws(data[pos])) break;
-        pos++;
-    }
-
-    if (pos == len) {
-        // TODO
-        return -1;
-    }
-
-    value_start = value_end = pos;
-
-    while (value_end < len) {
-        if (htp_is_lws(data[value_end])) break;
-        value_end++;
-    }
-
-    h->name_offset = name_start;
-    h->name_len = name_end - name_start;
-    h->value_offset = value_start;
-    h->value_len = value_end - value_start;
-
-    return 1;
-}
- */
-
-/**
- *
- */
-htp_header_t *htp_connp_header_parse(htp_connp_t *reqp, unsigned char *data, size_t len) {
-    htp_header_t *h = calloc(1, sizeof (htp_header_t));
-    if (h == NULL) return NULL;
-
-    // Parse the header line    
-    if (reqp->impl_header_parse(data, len, h) < 0) {
-        // Invalid header line
-        h->is_parsed = 0;
-        h->name = bstr_memdup(data, len);
-
-        return h;
-    }
-
-    // Now extract the name and the value
-    h->name = bstr_memdup(data + h->name_offset, h->name_len);
-    h->value = bstr_memdup(data + h->value_offset, h->value_len);
-    h->is_parsed = 1;
-
-    // Because header names are case-insensitive, we will convert
-    // the name to lowercase to use it as a lookup key.
-    h->name_lowercase = bstr_tolowercase(h->name);
-
-    return h;
-}
-
-#endif
diff --git a/libhtp/htp/htp_response.c b/libhtp/htp/htp_response.c
deleted file mode 100644 (file)
index 3a0a244..0000000
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <stdlib.h>
-#include "htp.h"
-
-/**
- * Invoked whenever decompressed response body data becomes available.
- *
- * @param d
- * @return HTP_OK on state change, HTP_ERROR on error.
- */
-static int htp_connp_RES_BODY_DECOMPRESSOR_CALLBACK(htp_tx_data_t *d) {
-    // Invoke all callbacks
-    int rc = hook_run_all(d->tx->connp->cfg->hook_response_body_data, d);
-    if (rc != HTP_OK) {
-        htp_log(d->tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-            "Response body data callback returned error (%d)", rc);
-        return HTP_ERROR;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Consumes bytes until the end of the current line.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_BODY_CHUNKED_DATA_END(htp_connp_t *connp) {
-    // TODO We shouldn't really see anything apart from CR and LF,
-    // so we should warn about anything else.
-
-    for (;;) {
-        OUT_NEXT_BYTE_OR_RETURN(connp);
-
-        connp->out_tx->request_message_len++;
-
-        if (connp->out_next_byte == LF) {
-            connp->out_state = htp_connp_RES_BODY_CHUNKED_LENGTH;
-
-            return HTP_OK;
-        }
-    }
-
-    return HTP_ERROR;
-}
-
-/**
- * Processes a chunk of data.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_BODY_CHUNKED_DATA(htp_connp_t *connp) {
-    htp_tx_data_t d;
-
-    d.tx = connp->out_tx;
-    d.data = &connp->out_current_data[connp->out_current_offset];
-    d.len = 0;
-
-    for (;;) {
-        OUT_NEXT_BYTE(connp);
-
-        if (connp->out_next_byte == -1) {            
-            if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {
-                connp->out_decompressor->decompress(connp->out_decompressor, &d);
-            } else {
-                // Send data to callbacks
-                int rc = hook_run_all(connp->cfg->hook_response_body_data, &d);
-                if (rc != HOOK_OK) {
-                    htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                        "Response body data callback returned error (%d)", rc);
-                    return HTP_ERROR;
-                }
-            }
-
-            // Ask for more data
-            return HTP_DATA;
-        } else {
-            connp->out_tx->response_message_len++;
-            connp->out_tx->response_entity_len++;
-            connp->out_chunked_length--;
-            d.len++;
-
-            if (connp->out_chunked_length == 0) {
-                // End of data chunk
-                
-                if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {
-                    connp->out_decompressor->decompress(connp->out_decompressor, &d);
-                } else {
-                    // Send data to callbacks
-                    int rc = hook_run_all(connp->cfg->hook_response_body_data, &d);
-                    if (rc != HOOK_OK) {
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                            "Response body data callback returned error (%d)", rc);
-                        return HTP_ERROR;
-                    }
-                }
-
-                connp->out_state = htp_connp_RES_BODY_CHUNKED_DATA_END;
-
-                return HTP_OK;
-            }
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Extracts chunk length.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_BODY_CHUNKED_LENGTH(htp_connp_t *connp) {
-    for (;;) {
-        OUT_COPY_BYTE_OR_RETURN(connp);
-
-        connp->out_tx->response_message_len++;
-
-        // Have we reached the end of the line?
-        if (connp->out_next_byte == LF) {
-            htp_chomp(connp->out_line, &connp->out_line_len);
-
-            // Extract chunk length
-            connp->out_chunked_length = htp_parse_chunked_length(connp->out_line, connp->out_line_len);
-
-            // Cleanup for the next line
-            connp->out_line_len = 0;
-
-            // Handle chunk length
-            if (connp->out_chunked_length > 0) {
-                // More data available
-                // TODO Add a check for chunk length
-                connp->out_state = htp_connp_RES_BODY_CHUNKED_DATA;
-            } else if (connp->out_chunked_length == 0) {
-                // End of data
-                connp->out_state = htp_connp_RES_HEADERS;
-                connp->out_tx->progress[1] = TX_PROGRESS_RES_TRAILER;
-            } else {
-                // Invalid chunk length
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                    "Response chunk encoding: Invalid chunk length: %d", connp->out_chunked_length);
-                return HTP_ERROR;
-            }
-
-            return HTP_OK;
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Processes identity response body.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp) {
-    htp_tx_data_t d;
-
-    d.tx = connp->out_tx;
-    d.data = &connp->out_current_data[connp->out_current_offset];
-    d.len = 0;
-
-    for (;;) {
-        OUT_NEXT_BYTE(connp);
-
-        if (connp->out_next_byte == -1) {
-            // End of chunk
-
-            // Send data to callbacks
-            if (d.len != 0) {
-                if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {                    
-                    connp->out_decompressor->decompress(connp->out_decompressor, &d);
-                } else {
-                    int rc = hook_run_all(connp->cfg->hook_response_body_data, &d);
-                    if (rc != HOOK_OK) {
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                            "Response body data callback returned error (%d)", rc);
-                        return HTP_ERROR;
-                    }
-                }                
-            }
-
-            // If we don't know the length, then we must check
-            // to see if the stream closed; that would signal the
-            // end of the response body (and the end of the transaction).
-            if ((connp->out_content_length == -1) && (connp->out_status == STREAM_STATE_CLOSED)) {
-                connp->out_state = htp_connp_RES_IDLE;
-                connp->out_tx->progress[1] = TX_PROGRESS_DONE;
-
-                return HTP_OK;
-            } else {
-                // Ask for more data
-                return HTP_DATA;
-            }
-        } else {
-            connp->out_tx->response_message_len++;
-            connp->out_tx->response_entity_len++;
-
-            if (connp->out_body_data_left > 0) {
-                // We know the length of response body
-
-                connp->out_body_data_left--;
-                d.len++;
-
-                if (connp->out_body_data_left == 0) {
-                    // End of body
-
-                    // Send data to callbacks
-                    if (d.len != 0) {
-                        if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {                            
-                            connp->out_decompressor->decompress(connp->out_decompressor, &d);
-                        } else {
-                            int rc = hook_run_all(connp->cfg->hook_response_body_data, &d);
-                            if (rc != HOOK_OK) {
-                                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                                    "Response body data callback returned error (%d)", rc);
-                                return HTP_ERROR;
-                            }
-                        }
-                    }
-
-                    // Done
-                    connp->out_state = htp_connp_RES_IDLE;
-                    connp->out_tx->progress[1] = TX_PROGRESS_DONE;
-
-                    return HTP_OK;
-                }
-            } else {
-                d.len++;
-                // We don't know the length of the response body, which means
-                // that the body will consume all data until the connection
-                // is closed.
-                //
-                // We don't need to do anything here.
-            }
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Determines presence (and encoding) of a response body.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
-    // If the request uses the CONNECT method, then not only are we
-    // to assume there's no body, but we need to ignore all
-    // subsequent data in the stream.
-    if ((connp->out_tx->request_method_number == M_CONNECT)
-        &&(connp->out_tx->response_status_number >= 200)
-        &&(connp->out_tx->response_status_number <= 299))
-    {
-        connp->out_status = STREAM_STATE_TUNNEL;
-        connp->out_state = htp_connp_RES_IDLE;
-        connp->out_tx->progress[1] = TX_PROGRESS_DONE;
-
-        return HTP_OK;
-    }
-
-    // Check for an interim "100 Continue"
-    // response. Ignore it if found, and revert back to RES_FIRST_LINE.
-    if (connp->out_tx->response_status_number == 100) {
-        if (connp->out_tx->seen_100continue != 0) {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Already seen 100-Continue");
-            return HTP_ERROR;
-        }
-
-        // Ignore any response headers set
-        table_clear(connp->out_tx->response_headers);
-
-        connp->out_state = htp_connp_RES_LINE;
-        connp->out_tx->progress[1] = TX_PROGRESS_RES_LINE;
-        connp->out_tx->seen_100continue++;
-
-        return HTP_OK;
-    }
-
-    // Check for compression
-    htp_header_t *ce = table_getc(connp->out_tx->response_headers, "content-encoding");
-    if (ce != NULL) {
-        // TODO Improve detection
-        // TODO How would a Content-Range header affect us?
-        if ((bstr_cmpc(ce->value, "gzip") == 0) || (bstr_cmpc(ce->value, "x-gzip") == 0)) {
-            connp->out_decompressor = (htp_decompressor_t *) htp_gzip_decompressor_create(connp);
-            if (connp->out_decompressor != NULL) {
-                connp->out_tx->response_content_encoding = COMPRESSION_GZIP;
-                connp->out_decompressor->callback = htp_connp_RES_BODY_DECOMPRESSOR_CALLBACK;
-            } else {
-                // No need to do anything; the error will have already
-                // been reported by the failed decompressor.
-            }
-        }
-    }
-
-    // 1. Any response message which MUST NOT include a message-body
-    //  (such as the 1xx, 204, and 304 responses and any response to a HEAD
-    //  request) is always terminated by the first empty line after the
-    //  header fields, regardless of the entity-header fields present in the
-    //  message.
-    if (((connp->out_tx->response_status_number >= 100) && (connp->out_tx->response_status_number <= 199))
-        || (connp->out_tx->response_status_number == 204) || (connp->out_tx->response_status_number == 304)
-        || (connp->out_tx->request_method_number == M_HEAD)) {
-        // There's no response body        
-        connp->out_state = htp_connp_RES_IDLE;
-    } else {
-        // We have a response body
-
-        htp_header_t *cl = table_getc(connp->out_tx->response_headers, "content-length");
-        htp_header_t *te = table_getc(connp->out_tx->response_headers, "transfer-encoding");
-
-        // 2. If a Transfer-Encoding header field (section 14.40) is present and
-        //   indicates that the "chunked" transfer coding has been applied, then
-        //   the length is defined by the chunked encoding (section 3.6).
-        if (te != NULL) {
-            if (bstr_cmpc(te->value, "chunked") != 0) {
-                // Invalid T-E header value
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                    "Invalid T-E value in response");
-            }
-
-            // If the T-E header is present we are going to use it.
-            connp->out_tx->response_transfer_coding = CHUNKED;
-
-            // We are still going to check for the presence of C-L
-            if (cl != NULL) {
-                // This is a violation of the RFC
-                connp->out_tx->flags |= HTP_REQUEST_SMUGGLING;
-                // TODO
-            }
-
-            connp->out_state = htp_connp_RES_BODY_CHUNKED_LENGTH;
-            connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
-        }// 3. If a Content-Length header field (section 14.14) is present, its
-            //   value in bytes represents the length of the message-body.
-        else if (cl != NULL) {
-            // We know the exact length
-            connp->out_tx->response_transfer_coding = IDENTITY;
-
-            // Check for multiple C-L headers
-            if (cl->flags & HTP_FIELD_REPEATED) {
-                connp->out_tx->flags |= HTP_REQUEST_SMUGGLING;
-                // TODO Log
-            }
-
-            // Get body length
-            int i = htp_parse_content_length(cl->value);
-            if (i < 0) {
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid C-L field in response");
-                return HTP_ERROR;
-            } else {
-                connp->out_content_length = i;
-                connp->out_body_data_left = connp->out_content_length;
-
-                if (connp->out_content_length != 0) {
-                    connp->out_state = htp_connp_RES_BODY_IDENTITY;
-                    connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
-                } else {
-                    connp->out_state = htp_connp_RES_IDLE;
-                    connp->out_tx->progress[1] = TX_PROGRESS_DONE;
-                }
-            }
-        } else {
-            // 4. If the message uses the media type "multipart/byteranges", which is
-            //   self-delimiting, then that defines the length. This media type MUST
-            //   NOT be used unless the sender knows that the recipient can parse it;
-            //   the presence in a request of a Range header with multiple byte-range
-            //   specifiers implies that the client can parse multipart/byteranges
-            //   responses.
-            htp_header_t *ct = table_getc(connp->out_tx->response_headers, "content-type");
-            if (ct != NULL) {
-                // TODO Handle multipart/byteranges
-
-                if (bstr_indexofc_nocase(ct->value, "multipart/byteranges") != -1) {
-                    htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                        "C-T multipart/byteranges in responses not supported");
-                    return HTP_ERROR;
-                }
-            }
-
-            // 5. By the server closing the connection. (Closing the connection
-            //   cannot be used to indicate the end of a request body, since that
-            //   would leave no possibility for the server to send back a response.)
-            connp->out_state = htp_connp_RES_BODY_IDENTITY;
-            connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
-        }
-    }
-
-    // NOTE We do not need to check for short-style HTTP/0.9 requests here because
-    //      that is done earlier, before response line parsing begins
-
-    // Run hook RESPONSE_HEADERS_COMPLETE
-    int rc = hook_run_all(connp->cfg->hook_response_headers, connp);
-    if (rc != HOOK_OK) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-            "Response headers callback returned error (%d)", rc);
-        return HTP_ERROR;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Parses response headers.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_HEADERS(htp_connp_t *connp) {
-    for (;;) {
-        OUT_COPY_BYTE_OR_RETURN(connp);
-
-        if (connp->out_header_line == NULL) {
-            connp->out_header_line = calloc(1, sizeof (htp_header_line_t));
-            if (connp->out_header_line == NULL) return HTP_ERROR;
-            connp->out_header_line->first_nul_offset = -1;
-        }
-
-        // Keep track of NUL bytes
-        if (connp->out_next_byte == 0) {
-            // Store the offset of the first NUL
-            if (connp->out_header_line->has_nulls == 0) {
-                connp->out_header_line->first_nul_offset = connp->out_line_len;
-            }
-
-            // Remember how many NULs there were
-            connp->out_header_line->flags |= HTP_FIELD_NUL_BYTE;
-            connp->out_header_line->has_nulls++;
-        }
-
-        // Have we reached the end of the line?
-        if (connp->out_next_byte == LF) {
-            #ifdef HTP_DEBUG
-            fprint_raw_data(stderr, __FUNCTION__, connp->out_line, connp->out_line_len);
-            #endif
-
-            // Should we terminate headers?
-            if (htp_connp_is_line_terminator(connp, connp->out_line, connp->out_line_len)) {
-                // Terminator line
-
-                // Parse previous header, if any
-                if (connp->out_header_line_index != -1) {
-                    if (connp->cfg->process_response_header(connp) != HTP_OK) {
-                        // Note: downstream responsible for error logging
-                        return HTP_ERROR;
-                    }
-
-                    // Reset index
-                    connp->out_header_line_index = -1;
-                }
-
-                // Cleanup
-                free(connp->out_header_line);
-                connp->out_line_len = 0;
-                connp->out_header_line = NULL;                
-
-                // We've seen all response headers
-                if (connp->out_tx->progress[1] == TX_PROGRESS_RES_HEADERS) {
-                    // Determine if this response has a body
-                    connp->out_state = htp_connp_RES_BODY_DETERMINE;
-                } else {
-                    // Run hook response_TRAILER
-                    int rc = hook_run_all(connp->cfg->hook_response_trailer, connp);
-                    if (rc != HOOK_OK) {
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                            "Response trailer callback returned error (%d)", rc);
-                        return HTP_ERROR;
-                    }
-
-                    // We've completed parsing this response
-                    connp->out_state = htp_connp_RES_IDLE;
-                }
-
-                return HTP_OK;
-            }
-
-            // Prepare line for consumption
-            size_t raw_out_line_len = connp->out_line_len;
-            htp_chomp(connp->out_line, &connp->out_line_len);
-
-            // Check for header folding
-            if (htp_connp_is_line_folded(connp->out_line, connp->out_line_len) == 0) {
-                // New header line               
-
-                // Parse previous header, if any
-                if (connp->out_header_line_index != -1) {
-                    if (connp->cfg->process_response_header(connp) != HTP_OK) {
-                        // Note: downstream responsible for error logging
-                        return HTP_ERROR;
-                    }
-
-                    // Reset index
-                    connp->out_header_line_index = -1;
-                }
-
-                // Remember the index of the fist header line
-                connp->out_header_line_index = connp->out_header_line_counter;
-            } else {
-                // Folding; check that there's a previous header line to add to
-                if (connp->out_header_line_index == -1) {
-                    if (!(connp->out_tx->flags & HTP_INVALID_FOLDING)) {
-                        connp->out_tx->flags |= HTP_INVALID_FOLDING;
-                        htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Invalid response field folding");
-                    }
-                }
-            }
-
-            // Add the raw header line to the list
-
-            if (raw_out_line_len > connp->out_line_len) {
-                if (raw_out_line_len - connp->out_line_len == 2 &&
-                        connp->out_line[connp->out_line_len] == 0x0d &&
-                        connp->out_line[connp->out_line_len + 1] == 0x0a) {
-                    connp->out_header_line->terminators = NULL;
-                } else {
-                    connp->out_header_line->terminators =
-                        bstr_memdup((char *) connp->out_line + connp->out_line_len,
-                                raw_out_line_len - connp->out_line_len);
-                    if (connp->out_header_line->terminators == NULL) {
-                        return HTP_ERROR;
-                    }
-                }
-            } else {
-                connp->out_header_line->terminators = NULL;
-            }
-
-            connp->out_header_line->line = bstr_memdup((char *) connp->out_line, connp->out_line_len);
-            if (connp->out_header_line->line == NULL) {
-                return HTP_ERROR;
-            }
-            list_add(connp->out_tx->response_header_lines, connp->out_header_line);
-            connp->out_header_line = NULL;
-
-            // Cleanup for the next line
-            connp->out_line_len = 0;
-            if (connp->out_header_line_index == -1) {
-                connp->out_header_line_index = connp->out_header_line_counter;
-            }
-
-            connp->out_header_line_counter++;
-        }
-    }
-    return HTP_ERROR;
-}
-
-/**
- * Parses response line.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_LINE(htp_connp_t *connp) {
-    for (;;) {
-        // Get one byte
-        OUT_COPY_BYTE_OR_RETURN(connp);
-
-        // Have we reached the end of the line?
-        if (connp->out_next_byte == LF) {
-            #ifdef HTP_DEBUG
-            fprint_raw_data(stderr, __FUNCTION__, connp->out_line, connp->out_line_len);
-            #endif
-
-            // Is this a line that should be ignored?
-            if (htp_connp_is_line_ignorable(connp, connp->out_line, connp->out_line_len)) {
-                // We have an empty/whitespace line, which we'll note, ignore and move on
-                connp->out_tx->response_ignored_lines++;
-
-                // TODO How many lines are we willing to accept?
-
-                // Start again
-                connp->out_line_len = 0;
-
-                return HTP_OK;
-            }
-
-            // Process response line
-
-            htp_chomp(connp->out_line, &connp->out_line_len);
-
-            // Deallocate previous response line allocations, which we woud have on a 100 response
-            // TODO Consider moving elsewhere; no need to make these checks on every response
-            if (connp->out_tx->response_line != NULL) {
-                bstr_free(connp->out_tx->response_line);
-            }
-
-            if (connp->out_tx->response_protocol != NULL) {
-                bstr_free(connp->out_tx->response_protocol);
-            }
-
-            if (connp->out_tx->response_status != NULL) {
-                bstr_free(connp->out_tx->response_status);
-            }
-
-            if (connp->out_tx->response_message != NULL) {
-                bstr_free(connp->out_tx->response_message);
-            }
-
-            connp->out_tx->response_line = bstr_memdup((char *) connp->out_line, connp->out_line_len);
-            if (connp->out_tx->response_line == NULL) {
-                return HTP_ERROR;
-            }
-
-            // Parse response line
-            if (connp->cfg->parse_response_line(connp) != HTP_OK) {
-                // Note: downstream responsible for error logging
-                return HTP_ERROR;
-            }
-
-            // Run hook RESPONSE_LINE
-            int rc = hook_run_all(connp->cfg->hook_response_line, connp);
-            if (rc != HOOK_OK) {
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                    "Response line callback returned error (%d)", rc);
-                return HTP_ERROR;
-            }
-
-            // Clean up.
-            connp->out_line_len = 0;
-
-            // Move on to the next phase.
-            connp->out_state = htp_connp_RES_HEADERS;
-            connp->out_tx->progress[1] = TX_PROGRESS_RES_HEADERS;
-
-            return HTP_OK;
-        }
-    }
-    return HTP_ERROR;
-}
-
-size_t htp_connp_res_data_consumed(htp_connp_t *connp) {
-    return connp->out_current_offset;
-}
-
-/**
- * The response idle state will initialize response processing, as well as
- * finalize each transactions after we are done with it.
- *
- * @param connp
- * @returns HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed.
- */
-int htp_connp_RES_IDLE(htp_connp_t * connp) {
-    // If we're here and an outgoing transaction object exists that
-    // means we've just completed parsing a response. We need
-    // to run the final hook in a transaction and start over.
-    if (connp->out_tx != NULL) {
-        // Shut down the decompressor, if we've used one
-        if (connp->out_decompressor != NULL) {
-            connp->out_decompressor->destroy(connp->out_decompressor);
-            connp->out_decompressor = NULL;
-        }
-
-        connp->out_tx->progress[1] = TX_PROGRESS_DONE;
-
-        // Run hook RESPONSE
-        int rc = hook_run_all(connp->cfg->hook_response, connp);
-        if (rc != HTP_OK) {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Response callback returned error (%d)", rc);
-            return HTP_ERROR;
-        }
-
-        // Check if the inbound parser is waiting on us. If it is that means that
-        // there might be request data that the inbound parser hasn't consumed yet.
-        // If we don't stop parsing we might encounter a response without a
-        // request.
-        if ((connp->in_status == STREAM_STATE_DATA_OTHER) && (connp->in_tx == connp->out_tx)) {
-            connp->out_tx = NULL;
-            return HTP_DATA_OTHER;
-        }
-
-        // Start afresh
-        connp->out_tx = NULL;
-    }
-
-    // We want to start parsing the next response (and change
-    // the state from IDLE) only if there's at least one
-    // byte of data available. Otherwise we could be creating
-    // new structures even if there's no more data on the
-    // connection.
-    OUT_TEST_NEXT_BYTE_OR_RETURN(connp);
-
-    // Parsing a new response
-
-    // Find the next outgoing transaction    
-    connp->out_tx = list_get(connp->conn->transactions, connp->out_next_tx_index);
-    if (connp->out_tx == NULL) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-            "Unable to match response to request");
-        return HTP_ERROR;
-    }
-
-    // We've used one transaction
-    connp->out_next_tx_index++;
-
-    // TODO Detect state mismatch
-
-    connp->out_content_length = -1;
-    connp->out_body_data_left = -1;
-    connp->out_header_line_index = -1;
-    connp->out_header_line_counter = 0;
-
-    // Change state into response line parsing, except if we're following
-    // a short HTTP/0.9 request, because such requests to not have a
-    // response line and headers.
-    if (connp->out_tx->protocol_is_simple) {
-        connp->out_tx->response_transfer_coding = IDENTITY;
-        connp->out_state = htp_connp_RES_BODY_IDENTITY;
-        connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
-    } else {
-        connp->out_state = htp_connp_RES_LINE;
-        connp->out_tx->progress[1] = TX_PROGRESS_RES_LINE;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Process a chunk of outbound (server or response) data.
- *
- * @param connp
- * @param timestamp
- * @param data
- * @param len
- * @return HTP_OK on state change, HTTP_ERROR on error, or HTP_DATA when more data is needed
- */
-int htp_connp_res_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char *data, size_t len) {
-    #ifdef HTP_DEBUG
-    fprintf(stderr, "htp_connp_res_data(connp->out_status %x)\n", connp->out_status);
-    fprint_raw_data(stderr, __FUNCTION__, data, len);
-    #endif
-
-    // Return if the connection has had a fatal error
-    if (connp->out_status == STREAM_STATE_ERROR) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Outbound parser is in STREAM_STATE_ERROR");
-
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_DATA (previous error)\n");
-        #endif
-
-        return STREAM_STATE_ERROR;
-    }
-
-    // If the length of the supplied data chunk is zero, proceed
-    // only if the stream has been closed. We do not allow zero-sized
-    // chunks in the API, but we use it internally to force the parsers
-    // to finalize parsing.
-    if ((len == 0) && (connp->out_status != STREAM_STATE_CLOSED)) {
-        htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Zero-length data chunks are not allowed");
-
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_DATA (zero-length chunk)\n");
-        #endif
-
-        return STREAM_STATE_ERROR;
-    }
-
-    // Store the current chunk information
-    connp->out_timestamp = timestamp;
-    connp->out_current_data = data;
-    connp->out_current_len = len;
-    connp->out_current_offset = 0;
-    connp->conn->out_data_counter += len;
-    connp->conn->out_packet_counter++;
-
-    // Return without processing any data if the stream is in tunneling
-    // mode (which it would be after an initial CONNECT transaction.
-    if (connp->out_status == STREAM_STATE_TUNNEL) {
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_TUNNEL\n");
-        #endif
-        return STREAM_STATE_TUNNEL;
-    }
-
-    // Invoke a processor, in a loop, until an error
-    // occurs or until we run out of data. Many processors
-    // will process a request, each pointing to the next
-    // processor that needs to run.
-    for (;;) {
-        #ifdef HTP_DEBUG
-        fprintf(stderr, "htp_connp_res_data: out state=%s, progress=%s\n",
-            htp_connp_out_state_as_string(connp),
-            htp_tx_progress_as_string(connp->out_tx, 1));
-        #endif
-        // Return if there's been an error
-        // or if we've run out of data. We are relying
-        // on processors to add error messages, so we'll
-        // keep quiet here.
-        int rc = connp->out_state(connp);
-        if (rc == HTP_OK) {
-            if (connp->out_status == STREAM_STATE_TUNNEL) {
-                #ifdef HTP_DEBUG
-                fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_TUNNEL\n");
-                #endif
-
-                return STREAM_STATE_TUNNEL;
-            }
-        } else { 
-            // Do we need more data?
-            if (rc == HTP_DATA) {
-                return STREAM_STATE_DATA;
-            }
-
-            // Check for suspended parsing
-            if (rc == HTP_DATA_OTHER) {
-                // We might have actually consumed the entire data chunk?
-                if (connp->out_current_offset >= connp->out_current_len) {
-                    // Do not send STREAM_DATE_DATA_OTHER if we've
-                    // consumed the entire chunk
-                    #ifdef HTP_DEBUG
-                    fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_DATA (suspended parsing)\n");
-                    #endif
-                    return STREAM_STATE_DATA;
-                } else {
-                    // Partial chunk consumption
-                    #ifdef HTP_DEBUG
-                    fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA_OTHER\n");
-                    #endif
-                    return STREAM_STATE_DATA_OTHER;
-                }
-            }
-
-            // Remember that we've had an error. Errors are
-            // not possible to recover from.
-            connp->out_status = STREAM_STATE_ERROR;
-
-            return STREAM_STATE_ERROR;
-        }
-    }
-    return HTP_ERROR;
-}
-
diff --git a/libhtp/htp/htp_response_generic.c b/libhtp/htp/htp_response_generic.c
deleted file mode 100644 (file)
index 1399295..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * Generic response line parser.
- * 
- * @param connp
- * @return HTP status
- */
-int htp_parse_response_line_generic(htp_connp_t *connp) {
-    htp_tx_t *tx = connp->out_tx;
-    unsigned char *data = (unsigned char *)bstr_ptr(tx->response_line);
-    size_t len = bstr_len(tx->response_line);
-    size_t pos = 0;
-
-    // The request method starts at the beginning of the
-    // line and ends with the first whitespace character.
-    while ((pos < len) && (!htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    tx->response_protocol = bstr_memdup((char *)data, pos);
-    if (tx->response_protocol == NULL) {
-        return HTP_ERROR;
-    }
-    tx->response_protocol_number = htp_parse_protocol(tx->response_protocol);
-
-#ifdef HTP_DEBUG
-    fprint_raw_data(stderr, __FUNCTION__, (unsigned char *)bstr_ptr(tx->response_protocol), bstr_len(tx->response_protocol));
-#endif
-
-    // Ignore whitespace after response protocol
-    while ((pos < len) && (isspace(data[pos]))) {
-        pos++;
-    }
-
-    size_t start = pos;
-
-    // Find the next whitespace character
-    while ((pos < len) && (!htp_is_space(data[pos]))) {
-        pos++;
-    }
-
-    tx->response_status = bstr_memdup((char *)data + start, pos - start);
-    if (tx->response_status == NULL) {
-        return HTP_ERROR;
-    }
-    tx->response_status_number = htp_parse_status(tx->response_status);
-
-#ifdef HTP_DEBUG
-    fprint_raw_data(stderr, __FUNCTION__, (unsigned char *)bstr_ptr(tx->response_status), bstr_len(tx->response_status));
-#endif
-
-    // Ignore whitespace that follows
-    while ((pos < len) && (isspace(data[pos]))) {
-        pos++;
-    }
-
-    tx->response_message = bstr_memdup((char *)data + pos, len - pos);
-    if (tx->response_message == NULL) {
-        return HTP_ERROR;
-    }
-
-#ifdef HTP_DEBUG
-    fprint_raw_data(stderr, __FUNCTION__, (unsigned char *)bstr_ptr(tx->response_message), bstr_len(tx->response_message));
-#endif
-    
-    return HTP_OK;
-}
-
-/**
- * Generic response header parser.
- * 
- * @param connp
- * @param h
- * @param data
- * @param len
- * @return HTP status
- */
-int htp_parse_response_header_generic(htp_connp_t *connp, htp_header_t *h, char *data, size_t len) {
-    size_t name_start, name_end;
-    size_t value_start, value_end;
-
-    name_start = 0;
-
-    // Look for the colon
-    size_t colon_pos = 0;
-    while ((colon_pos < len) && (data[colon_pos] != ':')) colon_pos++;
-
-    if (colon_pos == len) {
-        // Missing colon
-        h->flags |= HTP_FIELD_UNPARSEABLE;
-
-        if (!(connp->out_tx->flags & HTP_FIELD_UNPARSEABLE)) {
-            connp->out_tx->flags |= HTP_FIELD_UNPARSEABLE;
-            // Only log once per transaction
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Response field invalid: colon missing");
-        }
-
-        return HTP_ERROR;
-    }
-
-    if (colon_pos == 0) {
-        // Empty header name
-        h->flags |= HTP_FIELD_INVALID;
-
-        if (!(connp->out_tx->flags & HTP_FIELD_INVALID)) {
-            connp->out_tx->flags |= HTP_FIELD_INVALID;
-            // Only log once per transaction
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Response field invalid: empty name");
-        }
-    }
-
-    name_end = colon_pos;
-
-    // Ignore LWS after field-name
-    size_t prev = name_end - 1;
-    while ((prev > name_start) && (htp_is_lws(data[prev]))) {
-        prev--;
-        name_end--;
-
-        h->flags |= HTP_FIELD_INVALID;
-
-        if (!(connp->out_tx->flags & HTP_FIELD_INVALID)) {
-            connp->out_tx->flags |= HTP_FIELD_INVALID;
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Response field invalid: LWS after name");
-        }
-    }
-
-    // Value
-
-    value_start = colon_pos;
-
-    // Go over the colon
-    if (value_start < len) {
-        value_start++;
-    }
-
-    // Ignore LWS before field-content
-    while ((value_start < len) && (htp_is_lws(data[value_start]))) {
-        value_start++;
-    }
-
-    // Look for the end of field-content
-    value_end = value_start;
-    while (value_end < len) value_end++;
-
-    // Ignore LWS after field-content
-    prev = value_end - 1;
-    while ((prev > value_start) && (htp_is_lws(data[prev]))) {
-        prev--;
-        value_end--;
-    }
-
-    // Check that the header name is a token
-    size_t i = name_start;
-    while (i < name_end) {
-        if (!htp_is_token(data[i])) {
-            h->flags |= HTP_FIELD_INVALID;
-
-            if (!(connp->out_tx->flags & HTP_FIELD_INVALID)) {
-                connp->out_tx->flags |= HTP_FIELD_INVALID;
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_WARNING, 0, "Response header name is not a token");
-            }
-
-            break;
-        }
-
-        i++;
-    }
-
-    // Now extract the name and the value
-    h->name = bstr_memdup(data + name_start, name_end - name_start);
-    if (h->name == NULL) {
-        return HTP_ERROR;
-    }
-    h->value = bstr_memdup(data + value_start, value_end - value_start);
-    if (h->value == NULL) {
-        return HTP_ERROR;
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Generic response header line(s) processor, which assembles folded lines
- * into a single buffer before invoking the parsing function.
- * 
- * @param connp
- * @return HTP status
- */
-int htp_process_response_header_generic(htp_connp_t *connp) {
-    bstr *tempstr = NULL;
-    char *data = NULL;
-    size_t len = 0;
-
-    // Parse header
-    htp_header_t *h = calloc(1, sizeof (htp_header_t));
-    if (h == NULL) return HTP_ERROR;    
-
-    // Ensure we have the necessary header data in a single buffer
-    if (connp->out_header_line_index + 1 == connp->out_header_line_counter) {
-        // Single line
-        htp_header_line_t *hl = list_get(connp->out_tx->response_header_lines,
-            connp->out_header_line_index);
-        if (hl == NULL) {
-            // Internal error
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Process response header (generic): Internal error");
-            free(h);
-            return HTP_ERROR;
-        }
-
-        data = bstr_ptr(hl->line);
-        len = bstr_len(hl->line);
-        hl->header = h;
-    } else {
-        // Multiple lines (folded)
-        int i = 0;
-
-        for (i = connp->out_header_line_index; i < connp->out_header_line_counter; i++) {
-            htp_header_line_t *hl = list_get(connp->out_tx->response_header_lines, i);
-            len += bstr_len(hl->line);
-        }
-
-        tempstr = bstr_alloc(len);
-        if (tempstr == NULL) {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
-                "Process reqsponse header (generic): Failed to allocate bstring of %d bytes", len);
-            free(h);
-            return HTP_ERROR;
-        }
-
-        for (i = connp->out_header_line_index; i < connp->out_header_line_counter; i++) {
-            htp_header_line_t *hl = list_get(connp->out_tx->response_header_lines, i);
-            bstr_add_str_noex(tempstr, hl->line);
-            hl->header = h;
-        }
-
-        data = bstr_ptr(tempstr);
-    }
-
-    if (htp_parse_response_header_generic(connp, h, data, len) != HTP_OK) {
-        // Note: downstream responsible for error logging
-        if (tempstr != NULL) {
-            free(tempstr);
-        }
-        free(h);
-        return HTP_ERROR;
-    }
-
-    // Do we already have a header with the same name?
-    htp_header_t *h_existing = table_get(connp->out_tx->response_headers, h->name);
-    if (h_existing != NULL) {
-        // TODO Do we want to keep a list of the headers that are
-        //      allowed to be combined in this way?
-
-        // Add to existing header
-        h_existing->value = bstr_expand(h_existing->value, bstr_len(h_existing->value)
-            + 2 + bstr_len(h->value));
-        bstr_add_mem_noex(h_existing->value, ", ", 2);
-        bstr_add_str_noex(h_existing->value, h->value);
-
-        // The header is no longer needed
-        free(h->name);
-        free(h->value);
-        free(h);
-
-        // Keep track of same-name headers
-        h_existing->flags |= HTP_FIELD_REPEATED;
-    } else {
-        // Add as a new header
-        table_add(connp->out_tx->response_headers, h->name, h);
-    }
-
-    if (tempstr != NULL) {
-        free(tempstr);
-    }
-
-    return HTP_OK;
-}
diff --git a/libhtp/htp/htp_transaction.c b/libhtp/htp/htp_transaction.c
deleted file mode 100644 (file)
index 3b33891..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-
-/**
- * Creates a new transaction structure.
- *
- * @param cfg
- * @param is_cfg_shared
- * @param conn
- * @return The newly created transaction, or NULL on memory allocation failure.
- */
-htp_tx_t *htp_tx_create(htp_cfg_t *cfg, int is_cfg_shared, htp_conn_t *conn) {
-    htp_tx_t *tx = calloc(1, sizeof (htp_tx_t));
-    if (tx == NULL) return NULL;
-
-    tx->conn = conn;
-    tx->cfg = cfg;
-    tx->is_cfg_shared = is_cfg_shared;
-
-    tx->conn = conn;
-
-    tx->request_header_lines = list_array_create(32);
-    tx->request_headers = table_create(32);
-    tx->request_line_nul_offset = -1;
-    tx->parsed_uri = calloc(1, sizeof (htp_uri_t));
-    tx->parsed_uri_incomplete = calloc(1, sizeof (htp_uri_t));
-
-    tx->response_header_lines = list_array_create(32);
-    tx->response_headers = table_create(32);
-
-    tx->request_protocol_number = -1;
-
-    return tx;
-}
-
-/**
- * Destroys the supplied transaction.
- *
- * @param tx
- */
-void htp_tx_destroy(htp_tx_t *tx) {
-    bstr_free(tx->request_line);
-    bstr_free(tx->request_method);
-    bstr_free(tx->request_uri);
-    bstr_free(tx->request_uri_normalized);
-    bstr_free(tx->request_protocol);
-
-    if (tx->parsed_uri != NULL) {
-        bstr_free(tx->parsed_uri->scheme);
-        bstr_free(tx->parsed_uri->username);
-        bstr_free(tx->parsed_uri->password);
-        bstr_free(tx->parsed_uri->hostname);
-        bstr_free(tx->parsed_uri->port);
-        bstr_free(tx->parsed_uri->path);
-        bstr_free(tx->parsed_uri->query);
-        bstr_free(tx->parsed_uri->fragment);
-
-        free(tx->parsed_uri);
-    }
-
-    if (tx->parsed_uri_incomplete != NULL) {
-        bstr_free(tx->parsed_uri_incomplete->scheme);
-        bstr_free(tx->parsed_uri_incomplete->username);
-        bstr_free(tx->parsed_uri_incomplete->password);
-        bstr_free(tx->parsed_uri_incomplete->hostname);
-        bstr_free(tx->parsed_uri_incomplete->port);
-        bstr_free(tx->parsed_uri_incomplete->path);
-        bstr_free(tx->parsed_uri_incomplete->query);
-        bstr_free(tx->parsed_uri_incomplete->fragment);
-
-        free(tx->parsed_uri_incomplete);
-    }
-
-    // Destroy request_header_lines
-    htp_header_line_t *hl = NULL;
-    if (tx->request_header_lines != NULL) {
-        list_iterator_reset(tx->request_header_lines);
-        while ((hl = list_iterator_next(tx->request_header_lines)) != NULL) {
-            bstr_free(hl->line);
-            bstr_free(hl->terminators);
-            // No need to destroy hl->header because
-            // htp_header_line_t does not own it.
-            free(hl);
-        }
-
-        list_destroy(tx->request_header_lines);
-    }
-
-    // Destroy request_headers    
-    htp_header_t *h = NULL;
-    if (tx->request_headers != NULL) {
-        table_iterator_reset(tx->request_headers);
-        while (table_iterator_next(tx->request_headers, (void **) & h) != NULL) {
-            bstr_free(h->name);
-            bstr_free(h->value);
-            free(h);
-        }
-
-        table_destroy(tx->request_headers);
-    }
-
-    if (tx->request_headers_raw != NULL) {
-        bstr_free(tx->request_headers_raw);
-    }
-
-    bstr_free(tx->response_line);
-    bstr_free(tx->response_protocol);
-    bstr_free(tx->response_status);
-    bstr_free(tx->response_message);
-
-    // Destroy response_header_lines
-    hl = NULL;
-    if (tx->response_header_lines != NULL) {
-        list_iterator_reset(tx->response_header_lines);
-        while ((hl = list_iterator_next(tx->response_header_lines)) != NULL) {
-            bstr_free(hl->line);
-            bstr_free(hl->terminators);
-            // No need to destroy hl->header because
-            // htp_header_line_t does not own it.
-            free(hl);
-        }
-        list_destroy(tx->response_header_lines);
-    }
-
-    // Destroy response headers    
-    h = NULL;
-    if (tx->response_headers) {
-        table_iterator_reset(tx->response_headers);
-        while (table_iterator_next(tx->response_headers, (void **) & h) != NULL) {
-            bstr_free(h->name);
-            bstr_free(h->value);
-            free(h);
-        }
-        table_destroy(tx->response_headers);
-    }
-
-    // Tell the connection to remove this transaction
-    // from the list
-    htp_conn_remove_tx(tx->conn, tx);
-
-    // Invalidate the pointer to this transactions held
-    // by the connection parser. This is to allow a transaction
-    // to be destroyed from within the final response callback.
-    if (tx->connp != NULL) {
-        if (tx->connp->out_tx == tx) {
-            tx->connp->out_tx = NULL;
-        }
-    }
-
-    free(tx);
-}
-
-/**
- * Returns the user data associated with this transaction. 
- *
- * @param tx
- * @return A pointer to user data or NULL
- */
-void *htp_tx_get_user_data(htp_tx_t *tx) {
-    return tx->user_data;
-}
-
-/**
- * Sets the configuration that is to be used for this transaction.
- *
- * @param tx
- * @param cfg
- * @param is_cfg_shared
- */
-void htp_tx_set_config(htp_tx_t *tx, htp_cfg_t *cfg, int is_cfg_shared) {
-    tx->cfg = cfg;
-    tx->is_cfg_shared = is_cfg_shared;
-}
-
-/**
- * Associates user data with this transaction.
- *
- * @param tx
- * @param user_data
- */
-void htp_tx_set_user_data(htp_tx_t *tx, void *user_data) {
-    tx->user_data = user_data;    
-}
diff --git a/libhtp/htp/htp_util.c b/libhtp/htp/htp_util.c
deleted file mode 100644 (file)
index 6c6acd4..0000000
+++ /dev/null
@@ -1,2260 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include "htp.h"
-#include "utf8_decoder.h"
-
-/**
- * Is character a linear white space character?
- *
- * @param c
- * @return 0 or 1
- */
-int htp_is_lws(int c) {
-    if ((c == ' ') || (c == '\t')) return 1;
-    else return 0;
-}
-
-/**
- * Is character a separator character?
- *
- * @param c
- * @return 0 or 1
- */
-int htp_is_separator(int c) {
-    /* separators = "(" | ")" | "<" | ">" | "@"
-                  | "," | ";" | ":" | "\" | <">
-                  | "/" | "[" | "]" | "?" | "="
-                  | "{" | "}" | SP | HT         */
-    switch (c) {
-        case '(':
-        case ')':
-        case '<':
-        case '>':
-        case '@':
-        case ',':
-        case ';':
-        case ':':
-        case '\\':
-        case '"':
-        case '/':
-        case '[':
-        case ']':
-        case '?':
-        case '=':
-        case '{':
-        case '}':
-        case ' ':
-        case '\t':
-            return 1;
-            break;
-        default:
-            return 0;
-    }
-}
-
-/**
- * Is character a text character?
- *
- * @param c
- * @return 0 or 1
- */
-int htp_is_text(int c) {
-    if (c == '\t') return 1;
-    if (c < 32) return 0;
-    return 1;
-}
-
-/**
- * Is character a token character?
- *
- * @param c
- * @return 0 or 1
- */
-int htp_is_token(int c) {
-    /* token = 1*<any CHAR except CTLs or separators> */
-    /* CHAR  = <any US-ASCII character (octets 0 - 127)> */
-    if ((c < 32) || (c > 126)) return 0;
-    if (htp_is_separator(c)) return 0;
-    return 1;
-}
-
-/**
- * Remove one or more line terminators (LF or CRLF) from
- * the end of the line provided as input.
- *
- * @return 0 if nothing was removed, 1 if one or more LF characters were removed, or
- *         2 if one or more CR and/or LF characters were removed.
- */
-int htp_chomp(unsigned char *data, size_t *len) {
-    int r = 0;
-
-    // Loop until there's no more stuff in the buffer
-    while (*len > 0) {
-        // Try one LF first
-        if (data[*len - 1] == LF) {
-            (*len)--;
-            r = 1;
-
-            if (*len == 0) return r;
-
-            // A CR is allowed before LF
-            if (data[*len - 1] == CR) {
-                (*len)--;
-                r = 2;
-            }
-        } else return r;
-    }
-
-    return r;
-}
-
-/**
- * Is character a white space character?
- *
- * @param c
- * @return 0 or 1
- */
-int htp_is_space(int c) {
-    switch (c) {
-        case ' ':
-        case '\f':
-        case '\v':
-        case '\t':
-        case '\r':
-        case '\n':
-            return 1;
-        default:
-            return 0;
-    }
-}
-
-/**
- * Converts request method, given as a string, into a number.
- *
- * @param method
- * @return Method number of M_UNKNOWN
- */
-int htp_convert_method_to_number(bstr *method) {
-    if (method == NULL) return M_UNKNOWN;
-    // TODO Optimize using parallel matching, or something
-    if (bstr_cmpc(method, "GET") == 0) return M_GET;
-    if (bstr_cmpc(method, "PUT") == 0) return M_PUT;
-    if (bstr_cmpc(method, "POST") == 0) return M_POST;
-    if (bstr_cmpc(method, "DELETE") == 0) return M_DELETE;
-    if (bstr_cmpc(method, "CONNECT") == 0) return M_CONNECT;
-    if (bstr_cmpc(method, "OPTIONS") == 0) return M_OPTIONS;
-    if (bstr_cmpc(method, "TRACE") == 0) return M_TRACE;
-    if (bstr_cmpc(method, "PATCH") == 0) return M_PATCH;
-    if (bstr_cmpc(method, "PROPFIND") == 0) return M_PROPFIND;
-    if (bstr_cmpc(method, "PROPPATCH") == 0) return M_PROPPATCH;
-    if (bstr_cmpc(method, "MKCOL") == 0) return M_MKCOL;
-    if (bstr_cmpc(method, "COPY") == 0) return M_COPY;
-    if (bstr_cmpc(method, "MOVE") == 0) return M_MOVE;
-    if (bstr_cmpc(method, "LOCK") == 0) return M_LOCK;
-    if (bstr_cmpc(method, "UNLOCK") == 0) return M_UNLOCK;
-    if (bstr_cmpc(method, "VERSION_CONTROL") == 0) return M_VERSION_CONTROL;
-    if (bstr_cmpc(method, "CHECKOUT") == 0) return M_CHECKOUT;
-    if (bstr_cmpc(method, "UNCHECKOUT") == 0) return M_UNCHECKOUT;
-    if (bstr_cmpc(method, "CHECKIN") == 0) return M_CHECKIN;
-    if (bstr_cmpc(method, "UPDATE") == 0) return M_UPDATE;
-    if (bstr_cmpc(method, "LABEL") == 0) return M_LABEL;
-    if (bstr_cmpc(method, "REPORT") == 0) return M_REPORT;
-    if (bstr_cmpc(method, "MKWORKSPACE") == 0) return M_MKWORKSPACE;
-    if (bstr_cmpc(method, "MKACTIVITY") == 0) return M_MKACTIVITY;
-    if (bstr_cmpc(method, "BASELINE_CONTROL") == 0) return M_BASELINE_CONTROL;
-    if (bstr_cmpc(method, "MERGE") == 0) return M_MERGE;
-    if (bstr_cmpc(method, "INVALID") == 0) return M_INVALID;
-    if (bstr_cmpc(method, "HEAD") == 0) return M_HEAD;
-
-    return M_UNKNOWN;
-}
-
-/**
- * Is the given line empty? This function expects the line to have
- * a terminating LF.
- *
- * @param data
- * @param len
- * @return 0 or 1
- */
-int htp_is_line_empty(unsigned char *data, size_t len) {
-    if ((len == 1) || ((len == 2) && (data[0] == CR))) {
-        return 1;
-    }
-
-    return 0;
-}
-
-/**
- * Does line consist entirely of whitespace characters?
- * 
- * @param data
- * @param len
- * @return 0 or 1
- */
-int htp_is_line_whitespace(unsigned char *data, size_t len) {
-    size_t i;
-
-    for (i = 0; i < len; i++) {
-        if (!isspace(data[i])) {
-            return 0;
-        }
-    }
-
-    return 1;
-}
-
-/**
- * Parses Content-Length string (positive decimal number).
- * White space is allowed before and after the number.
- *
- * @param b
- * @return Content-Length as a number, or -1 on error.
- */
-int htp_parse_content_length(bstr *b) {
-    return htp_parse_positive_integer_whitespace((unsigned char *) bstr_ptr(b), bstr_len(b), 10);
-}
-
-/**
- * Parses chunk length (positive hexadecimal number).
- * White space is allowed before and after the number.
- *
- * @param data
- * @param len
- * @return Chunk length, or -1 on error.
- */
-int htp_parse_chunked_length(unsigned char *data, size_t len) {
-    return htp_parse_positive_integer_whitespace(data, len, 16);
-}
-
-/**
- * A forgiving parser for a positive integer in a given base.
- * White space is allowed before and after the number.
- * 
- * @param data
- * @param len
- * @param base
- * @return The parsed number, or -1 on error.
- */
-int htp_parse_positive_integer_whitespace(unsigned char *data, size_t len, int base) {
-    size_t pos = 0;
-
-    // Ignore LWS before
-    while ((pos < len) && (htp_is_lws(data[pos]))) pos++;
-    if (pos == len) return -1001;
-
-    int r = bstr_util_memtoip((char *) data + pos, len - pos, base, &pos);
-    if (r < 0) return r;
-
-    // Ignore LWS after
-    while (pos < len) {
-        if (!htp_is_lws(data[pos])) {
-            return -1002;
-        }
-
-        pos++;
-    }
-
-    return r;
-}
-
-/**
- * Prints one log message to stderr.
- * 
- * @param log
- */
-void htp_print_log(FILE *stream, htp_log_t *log) {
-    if (log->code != 0) {
-        fprintf(stream, "[%d][code %d][file %s][line %d] %s\n", log->level,
-            log->code, log->file, log->line, log->msg);
-    } else {
-        fprintf(stream, "[%d][file %s][line %d] %s\n", log->level,
-            log->file, log->line, log->msg);
-    }
-}
-
-/**
- * Records one log message.
- * 
- * @param connp
- * @param file
- * @param line
- * @param level
- * @param code
- * @param fmt
- */
-void htp_log(htp_connp_t *connp, const char *file, int line, int level, int code, const char *fmt, ...) {
-    char buf[1024];
-    va_list args;
-
-    // Ignore messages below our log level
-    if (connp->cfg->log_level < level) {
-        return;
-    }
-
-    va_start(args, fmt);
-
-    int r = vsnprintf(buf, 1023, fmt, args);
-
-    va_end(args);
-
-    if (r < 0) {
-        // TODO Will vsnprintf ever return an error?
-        snprintf(buf, 1024, "[vnsprintf returned error %d]", r);
-    }
-
-    // Indicate overflow with a '+' at the end
-    if (r > 1023) {
-        buf[1022] = '+';
-        buf[1023] = '\0';
-    }
-
-    // Create a new log entry...
-    htp_log_t *log = calloc(1, sizeof (htp_log_t));
-    if (log == NULL) return;
-
-    log->connp = connp;
-    log->file = file;
-    log->line = line;
-    log->level = level;
-    log->code = code;
-    log->msg = strdup(buf);
-
-    list_add(connp->conn->messages, log);
-
-    if (level == HTP_LOG_ERROR) {
-        connp->last_error = log;
-    }
-
-    hook_run_all(connp->cfg->hook_log, log);
-}
-
-/**
- * Determines if the given line is a continuation (of some previous line).
- *
- * @param connp
- * @param data
- * @param len
- * @return 0 or 1
- */
-int htp_connp_is_line_folded(unsigned char *data, size_t len) {
-    // Is there a line?
-    if (len == 0) {
-        return -1;
-    }
-
-    if (htp_is_lws(data[0])) return 1;
-    else return 0;
-}
-
-/**
- * Determines if the given line is a request terminator.
- *
- * @param connp
- * @param data
- * @param len
- * @return 0 or 1
- */
-int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len) {
-    // Is this the end of request headers?
-    switch (connp->cfg->spersonality) {
-        case HTP_SERVER_IIS_5_1:
-            // IIS 5 will accept a whitespace line as a terminator
-            if (htp_is_line_whitespace(data, len)) {
-                return 1;
-            }
-
-            // Fall through
-        default:
-            // Treat an empty line as terminator
-            if (htp_is_line_empty(data, len)) {
-                return 1;
-            }
-            break;
-    }
-
-    return 0;
-}
-
-/**
- * Determines if the given line can be ignored when it appears before a request.
- *
- * @param connp
- * @param data
- * @param len
- * @return 0 or 1
- */
-int htp_connp_is_line_ignorable(htp_connp_t *connp, unsigned char *data, size_t len) {
-    return htp_connp_is_line_terminator(connp, data, len);
-}
-
-/**
- * Parses request URI, making no attempt to validate the contents.
- *
- * @param connp
- * @param authority
- * @param uri
- * @return HTP_ERROR on memory allocation failure, HTP_OK otherwise
- */
-int htp_parse_authority(htp_connp_t *connp, bstr *authority, htp_uri_t **uri) {
-    int colon = bstr_chr(authority, ':');
-    if (colon == -1) {
-        // Hostname alone
-        (*uri)->hostname = bstr_strdup(authority);
-        htp_normalize_hostname_inplace((*uri)->hostname);
-    } else {
-        // Hostname and port
-
-        // Hostname
-        (*uri)->hostname = bstr_strdup_ex(authority, 0, colon);
-        // TODO Handle whitespace around hostname
-        htp_normalize_hostname_inplace((*uri)->hostname);
-
-        // Port
-        int port = htp_parse_positive_integer_whitespace((unsigned char *) bstr_ptr(authority)
-            + colon + 1, bstr_len(authority) - colon - 1, 10);
-        if (port < 0) {
-            // Failed to parse port
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid server port information in request");
-        } else if ((port > 0) && (port < 65536)) {
-            // Valid port            
-            (*uri)->port_number = port;
-        } else {
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid authority port");
-        }
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Parses request URI, making no attempt to validate the contents.
- * 
- * @param input
- * @param uri
- * @return HTP_ERROR on memory allocation failure, HTP_OK otherwise
- */
-int htp_parse_uri(bstr *input, htp_uri_t **uri) {
-    if (input == NULL)
-        return HTP_ERROR;
-    char *data = bstr_ptr(input);
-    size_t len = bstr_len(input);
-    size_t start, pos;
-
-    // Allow a htp_uri_t structure to be provided on input,
-    // but allocate a new one if there isn't one
-    if (*uri == NULL) {
-        *uri = calloc(1, sizeof (htp_uri_t));
-        if (*uri == NULL) return HTP_ERROR;
-    }
-
-    if (len == 0) {
-        // Empty string
-        return HTP_OK;
-    }
-
-    pos = 0;
-
-    // Scheme test: if it doesn't start with a forward slash character (which it must
-    // for the contents to be a path or an authority, then it must be the scheme part
-    if (data[0] != '/') {
-        // Parse scheme        
-
-        // Find the colon, which marks the end of the scheme part
-        start = pos;
-        while ((pos < len) && (data[pos] != ':')) pos++;
-
-        if (pos >= len) {
-            // We haven't found a colon, which means that the URI
-            // is invalid. Apache will ignore this problem and assume
-            // the URI contains an invalid path so, for the time being,
-            // we are going to do the same.
-            pos = 0;
-        } else {
-            // Make a copy of the scheme
-            (*uri)->scheme = bstr_memdup(data + start, pos - start);
-
-            // Go over the colon
-            pos++;
-        }
-    }
-
-    // Authority test: two forward slash characters and it's an authority.
-    // One, three or more slash characters, and it's a path. We, however,
-    // only attempt to parse authority if we've seen a scheme.
-    if ((*uri)->scheme != NULL)
-        if ((pos + 2 < len) && (data[pos] == '/') && (data[pos + 1] == '/') && (data[pos + 2] != '/')) {
-            // Parse authority
-
-            // Go over the two slash characters
-            start = pos = pos + 2;
-
-            // Authority ends with a question mark, forward slash or hash
-            while ((pos < len) && (data[pos] != '?') && (data[pos] != '/') && (data[pos] != '#')) pos++;
-
-            char *hostname_start;
-            size_t hostname_len;
-
-            // Are the credentials included in the authority?
-            char *m = memchr(data + start, '@', pos - start);
-            if (m != NULL) {
-                // Credentials present
-                char *credentials_start = data + start;
-                size_t credentials_len = m - data - start;
-
-                // Figure out just the hostname part
-                hostname_start = data + start + credentials_len + 1;
-                hostname_len = pos - start - credentials_len - 1;
-
-                // Extract the username and the password
-                m = memchr(credentials_start, ':', credentials_len);
-                if (m != NULL) {
-                    // Username and password
-                    (*uri)->username = bstr_memdup(credentials_start, m - credentials_start);
-                    (*uri)->password = bstr_memdup(m + 1, credentials_len - (m - credentials_start) - 1);
-                } else {
-                    // Username alone
-                    (*uri)->username = bstr_memdup(credentials_start, credentials_len);
-                }
-            } else {
-                // No credentials
-                hostname_start = data + start;
-                hostname_len = pos - start;
-            }
-
-            // Still parsing authority; is there a port provided?
-            m = memchr(hostname_start, ':', hostname_len);
-            if (m != NULL) {
-                size_t port_len = hostname_len - (m - hostname_start) - 1;
-                hostname_len = hostname_len - port_len - 1;
-
-                // Port string
-                (*uri)->port = bstr_memdup(m + 1, port_len);
-
-                // We deliberately don't want to try to convert the port
-                // string as a number. That will be done later, during
-                // the normalization and validation process.
-            }
-
-            // Hostname
-            (*uri)->hostname = bstr_memdup(hostname_start, hostname_len);
-        }
-
-    // Path
-    start = pos;
-
-    // The path part will end with a question mark or a hash character, which
-    // mark the beginning of the query part or the fragment part, respectively.
-    while ((pos < len) && (data[pos] != '?') && (data[pos] != '#')) pos++;
-
-    // Path
-    (*uri)->path = bstr_memdup(data + start, pos - start);
-
-    if (pos == len) return HTP_OK;
-
-    // Query
-    if (data[pos] == '?') {
-        // Step over the question mark
-        start = pos + 1;
-
-        // The query part will end with the end of the input
-        // or the beginning of the fragment part
-        while ((pos < len) && (data[pos] != '#')) pos++;
-
-        // Query string
-        (*uri)->query = bstr_memdup(data + start, pos - start);
-
-        if (pos == len) return HTP_OK;
-    }
-
-    // Fragment
-    if (data[pos] == '#') {
-        // Step over the hash character
-        start = pos + 1;
-
-        // Fragment; ends with the end of the input
-        (*uri)->fragment = bstr_memdup(data + start, len - start);
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Convert two input bytes, pointed to by the pointer parameter,
- * into a single byte by assuming the input consists of hexadecimal
- * characters. This function will happily convert invalid input.
- *
- * @param what
- * @return hex-decoded byte
- */
-unsigned char x2c(unsigned char *what) {
-    register unsigned char digit;
-
-    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
-    digit *= 16;
-    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
-
-    return digit;
-}
-
-/**
- * Convert a Unicode codepoint into a single-byte, using best-fit
- * mapping (as specified in the provided configuration structure).
- *
- * @param cfg
- * @param codepoint
- * @return converted single byte
- */
-uint8_t bestfit_codepoint(htp_cfg_t *cfg, uint32_t codepoint) {
-    // Is it a single-byte codepoint?
-    if (codepoint < 0x100) {
-        return (uint8_t) codepoint;
-    }
-
-    // Our current implementation only converts the 2-byte codepoints
-    if (codepoint > 0xffff) {
-        return cfg->path_replacement_char;
-    }
-
-    uint8_t *p = cfg->path_u_bestfit_map;
-
-    // TODO Optimize lookup
-
-    for (;;) {
-        uint32_t x = (p[0] << 8) + p[1];
-
-        if (x == 0) {
-            return cfg->path_replacement_char;
-        }
-
-        if (x == codepoint) {
-            return p[2];
-            break;
-        }
-
-        // Move to the next triplet
-        p += 3;
-    }
-    return cfg->path_replacement_char;
-}
-
-/**
- * Decode a UTF-8 encoded path. Overlong characters will be decoded, invalid
- * chararacters will be left as-is. Best-fit mapping will be used to convert
- * UTF-8 into a single-byte stream.
- *
- * @param cfg
- * @param tx
- * @param path
- */
-void htp_utf8_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path) {
-    if (path == NULL)
-        return;
-
-    uint8_t *data = (unsigned char *) bstr_ptr(path);
-    size_t len = bstr_len(path);
-    size_t rpos = 0;
-    size_t wpos = 0;
-    size_t charpos = 0;
-    uint32_t codepoint = 0;
-    uint32_t state = UTF8_ACCEPT;
-    uint32_t counter = 0;
-    uint8_t seen_valid = 0;
-
-    while (rpos < len) {
-        counter++;
-
-        switch (utf8_decode_allow_overlong(&state, &codepoint, data[rpos])) {
-            case UTF8_ACCEPT:
-                if (counter == 1) {
-                    // ASCII character
-                    data[wpos++] = (uint8_t) codepoint;
-                } else {
-                    // A valid UTF-8 character
-                    seen_valid = 1;
-
-                    // Check for overlong characters and set the
-                    // flag accordingly
-                    switch (counter) {
-                        case 2:
-                            if (codepoint < 0x80) {
-                                tx->flags |= HTP_PATH_UTF8_OVERLONG;
-                            }
-                            break;
-                        case 3:
-                            if (codepoint < 0x800) {
-                                tx->flags |= HTP_PATH_UTF8_OVERLONG;
-                            }
-                            break;
-                        case 4:
-                            if (codepoint < 0x10000) {
-                                tx->flags |= HTP_PATH_UTF8_OVERLONG;
-                            }
-                            break;
-                    }
-
-                    // Special flag for fullwidth form evasion
-                    if ((codepoint > 0xfeff) && (codepoint < 0x010000)) {
-                        tx->flags |= HTP_PATH_FULLWIDTH_EVASION;
-                    }
-
-                    // Use best-fit mapping to convert to a single byte
-                    data[wpos++] = bestfit_codepoint(cfg, codepoint);
-                }
-
-                // Advance over the consumed byte
-                rpos++;
-
-                // Prepare for the next character
-                counter = 0;
-                charpos = rpos;
-
-                break;
-
-            case UTF8_REJECT:
-                // Invalid UTF-8 character
-                tx->flags |= HTP_PATH_UTF8_INVALID;
-
-                // Is the server expected to respond with 400?
-                if (cfg->path_invalid_utf8_handling == STATUS_400) {
-                    tx->response_status_expected_number = 400;
-                }
-
-                // Override the state in the UTF-8 decoder because
-                // we want to ignore invalid characters
-                state = UTF8_ACCEPT;
-
-                // Copy the invalid bytes into the output stream
-                while (charpos <= rpos) {
-                    data[wpos++] = data[charpos++];
-                }
-
-                // Advance over the consumed byte
-                rpos++;
-
-                // Prepare for the next character
-                counter = 0;
-                charpos = rpos;
-
-                break;
-
-            default:
-                // Keep going; the character is not yet formed
-                rpos++;
-                break;
-        }
-    }
-
-    // Did the input stream seem like a valid UTF-8 string?
-    if ((seen_valid) && (!(tx->flags & HTP_PATH_UTF8_INVALID))) {
-        tx->flags |= HTP_PATH_UTF8_VALID;
-    }
-
-    // Adjust the length of the string, because
-    // we're doing in-place decoding.
-    bstr_len_adjust(path, wpos);
-}
-
-/**
- * Validate a path that is quite possibly UTF-8 encoded.
- *
- * @param cfg
- * @param tx
- * @param path
- */
-void htp_utf8_validate_path(htp_tx_t *tx, bstr *path) {
-    unsigned char *data = (unsigned char *) bstr_ptr(path);
-    size_t len = bstr_len(path);
-    size_t rpos = 0;
-    uint32_t codepoint = 0;
-    uint32_t state = UTF8_ACCEPT;
-    uint32_t counter = 0;
-    uint8_t seen_valid = 0;
-
-    while (rpos < len) {
-        counter++;
-
-        switch (utf8_decode_allow_overlong(&state, &codepoint, data[rpos])) {
-            case UTF8_ACCEPT:
-                // ASCII character
-
-                if (counter > 1) {
-                    // A valid UTF-8 character
-                    seen_valid = 1;
-
-                    // Check for overlong characters and set the
-                    // flag accordingly
-                    switch (counter) {
-                        case 2:
-                            if (codepoint < 0x80) {
-                                tx->flags |= HTP_PATH_UTF8_OVERLONG;
-                            }
-                            break;
-                        case 3:
-                            if (codepoint < 0x800) {
-                                tx->flags |= HTP_PATH_UTF8_OVERLONG;
-                            }
-                            break;
-                        case 4:
-                            if (codepoint < 0x10000) {
-                                tx->flags |= HTP_PATH_UTF8_OVERLONG;
-                            }
-                            break;
-                    }
-                }
-
-                // Special flag for fullwidth form evasion
-                if ((codepoint > 0xfeff) && (codepoint < 0x010000)) {
-                    tx->flags |= HTP_PATH_FULLWIDTH_EVASION;
-                }
-
-                // Advance over the consumed byte
-                rpos++;
-
-                // Prepare for the next character
-                counter = 0;
-
-                break;
-
-            case UTF8_REJECT:
-                // Invalid UTF-8 character
-                tx->flags |= HTP_PATH_UTF8_INVALID;
-
-                // Override the state in the UTF-8 decoder because
-                // we want to ignore invalid characters
-                state = UTF8_ACCEPT;
-
-                // Advance over the consumed byte
-                rpos++;
-
-                // Prepare for the next character
-                counter = 0;
-
-                break;
-
-            default:
-                // Keep going; the character is not yet formed
-                rpos++;
-                break;
-        }
-    }
-
-    // Did the input stream seem like a valid UTF-8 string?
-    if ((seen_valid) && (!(tx->flags & HTP_PATH_UTF8_INVALID))) {
-        tx->flags |= HTP_PATH_UTF8_VALID;
-    }
-}
-
-/**
- * Decode a %u-encoded character, using best-fit mapping as necessary.
- *
- * @param cfg
- * @param tx
- * @param data
- * @return decoded byte
- */
-int decode_u_encoding(htp_cfg_t *cfg, htp_tx_t *tx, unsigned char *data) {
-    unsigned int c1 = x2c(data);
-    unsigned int c2 = x2c(data + 2);
-    int r = cfg->path_replacement_char;
-
-    if (c1 == 0x00) {
-        r = c2;
-        tx->flags |= HTP_PATH_OVERLONG_U;
-    } else {
-        // Check for fullwidth form evasion
-        if (c1 == 0xff) {
-            tx->flags |= HTP_PATH_FULLWIDTH_EVASION;
-        }
-
-        switch (cfg->path_unicode_mapping) {
-            case STATUS_400:
-                tx->response_status_expected_number = 400;
-                break;
-            case STATUS_404:
-                tx->response_status_expected_number = 404;
-                break;
-        }
-
-        // Use best-fit mapping
-        unsigned char *p = cfg->path_u_bestfit_map;
-
-        // TODO Optimize lookup
-
-        for (;;) {
-            // Have we reached the end of the map?
-            if ((p[0] == 0) && (p[1] == 0)) {
-                break;
-            }
-
-            // Have we found the mapping we're looking for?
-            if ((p[0] == c1) && (p[1] == c2)) {
-                r = p[2];
-                break;
-            }
-
-            // Move to the next triplet
-            p += 3;
-        }
-    }
-
-    // Check for encoded path separators
-    if ((r == '/') || ((cfg->path_backslash_separators) && (r == '\\'))) {
-        tx->flags |= HTP_PATH_ENCODED_SEPARATOR;
-    }
-
-    return r;
-}
-
-/**
- * Decode a request query according to the settings in the
- * provided configuration structure.
- *
- * @param cfg
- * @param tx
- * @param query
- */
-int htp_decode_query_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *query) {
-    if (query == NULL)
-        return -1;
-
-    unsigned char *data = (unsigned char *) bstr_ptr(query);
-    if (data == NULL) {
-        return -1;
-    }
-    size_t len = bstr_len(query);
-
-    // TODO I don't like this function. It's too complex.
-
-    size_t rpos = 0;
-    size_t wpos = 0;
-    int previous_was_separator = 0;
-
-    while (rpos < len) {
-        int c = data[rpos];
-
-        // Decode encoded characters
-        if (c == '%') {
-            if (rpos + 2 < len) {
-                int handled = 0;
-
-                if (cfg->query_decode_u_encoding) {
-                    // Check for the %u encoding
-                    if ((data[rpos + 1] == 'u') || (data[rpos + 1] == 'U')) {
-                        handled = 1;
-
-                        if (cfg->query_decode_u_encoding == STATUS_400) {
-                            tx->response_status_expected_number = 400;
-                        }
-
-                        if (rpos + 5 < len) {
-                            if (isxdigit(data[rpos + 2]) && (isxdigit(data[rpos + 3]))
-                                && isxdigit(data[rpos + 4]) && (isxdigit(data[rpos + 5]))) {
-                                // Decode a valid %u encoding
-                                c = decode_u_encoding(cfg, tx, &data[rpos + 2]);
-                                rpos += 6;
-
-                                if (c == 0) {
-                                    tx->flags |= HTP_PATH_ENCODED_NUL;
-
-                                    if (cfg->query_nul_encoded_handling == STATUS_400) {
-                                        tx->response_status_expected_number = 400;
-                                    } else if (cfg->query_nul_encoded_handling == STATUS_404) {
-                                        tx->response_status_expected_number = 404;
-                                    }
-                                }
-                            } else {
-                                // Invalid %u encoding
-                                tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                                switch (cfg->query_invalid_encoding_handling) {
-                                    case URL_DECODER_REMOVE_PERCENT:
-                                        // Do not place anything in output; eat
-                                        // the percent character
-                                        rpos++;
-                                        continue;
-                                        break;
-                                    case URL_DECODER_PRESERVE_PERCENT:
-                                        // Leave the percent character in output
-                                        rpos++;
-                                        break;
-                                    case URL_DECODER_DECODE_INVALID:
-                                        // Decode invalid %u encoding
-                                        c = decode_u_encoding(cfg, tx, &data[rpos + 2]);
-                                        rpos += 6;
-                                        break;
-                                    case URL_DECODER_STATUS_400:
-                                        // Set expected status to 400
-                                        tx->response_status_expected_number = 400;
-
-                                        // Decode invalid %u encoding
-                                        c = decode_u_encoding(cfg, tx, &data[rpos + 2]);
-                                        rpos += 6;
-                                        break;
-                                        break;
-                                    default:
-                                        // Unknown setting
-                                        return -1;
-                                        break;
-                                }
-                            }
-                        } else {
-                            // Invalid %u encoding (not enough data)
-                            tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                            if (cfg->query_invalid_encoding_handling == URL_DECODER_REMOVE_PERCENT) {
-                                // Remove the percent character from output
-                                rpos++;
-                                continue;
-                            } else {
-                                rpos++;
-                            }
-                        }
-                    }
-                }
-
-                // Handle standard URL encoding
-                if (!handled) {
-                    if ((isxdigit(data[rpos + 1])) && (isxdigit(data[rpos + 2]))) {
-                        c = x2c(&data[rpos + 1]);
-
-                        if (c == 0) {
-                            tx->flags |= HTP_PATH_ENCODED_NUL;
-
-                            switch (cfg->query_nul_encoded_handling) {
-                                case TERMINATE:
-                                    bstr_len_adjust(query, wpos);
-                                    return 1;
-                                    break;
-                                case STATUS_400:
-                                    tx->response_status_expected_number = 400;
-                                    break;
-                                case STATUS_404:
-                                    tx->response_status_expected_number = 404;
-                                    break;
-                            }
-                        }
-
-                        if ((c == '/') || ((cfg->query_backslash_separators) && (c == '\\'))) {
-                            tx->flags |= HTP_PATH_ENCODED_SEPARATOR;
-
-                            switch (cfg->query_decode_separators) {
-                                case STATUS_404:
-                                    tx->response_status_expected_number = 404;
-                                    // Fall-through
-                                case NO:
-                                    // Leave encoded
-                                    c = '%';
-                                    rpos++;
-                                    break;
-                                case YES:
-                                    // Decode
-                                    rpos += 3;
-                                    break;
-                            }
-                        } else {
-                            // Decode
-                            rpos += 3;
-                        }
-                    } else {
-                        // Invalid encoding
-                        tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                        switch (cfg->query_invalid_encoding_handling) {
-                            case URL_DECODER_REMOVE_PERCENT:
-                                // Do not place anything in output; eat
-                                // the percent character
-                                rpos++;
-                                continue;
-                                break;
-                            case URL_DECODER_PRESERVE_PERCENT:
-                                // Leave the percent character in output
-                                rpos++;
-                                break;
-                            case URL_DECODER_DECODE_INVALID:
-                                // Decode
-                                c = x2c(&data[rpos + 1]);
-                                rpos += 3;
-                                // Note: What if an invalid encoding decodes into a path
-                                //       separator? This is theoretical at the moment, because
-                                //       the only platform we know doesn't convert separators is
-                                //       Apache, who will also respond with 400 if invalid encoding
-                                //       is encountered. Thus no check for a separator here.
-                                break;
-                            case URL_DECODER_STATUS_400:
-                                // Backend will reject request with 400, which means
-                                // that it does not matter what we do.
-                                tx->response_status_expected_number = 400;
-
-                                // Preserve the percent character
-                                rpos++;
-                                break;
-                            default:
-                                // Unknown setting
-                                return -1;
-                                break;
-                        }
-                    }
-                }
-            } else {
-                // Invalid encoding (not enough data)
-                tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                if (cfg->query_invalid_encoding_handling == URL_DECODER_REMOVE_PERCENT) {
-                    // Do not place the percent character in output
-                    rpos++;
-                    continue;
-                } else {
-                    rpos++;
-                }
-            }
-        } else {
-            // One non-encoded character
-
-            // Is it a NUL byte?
-            if (c == 0) {
-                switch (cfg->query_nul_raw_handling) {
-                    case TERMINATE:
-                        // Terminate path with a raw NUL byte
-                        bstr_len_adjust(query, wpos);
-                        return 1;
-                        break;
-                    case STATUS_400:
-                        // Leave the NUL byte, but set the expected status
-                        tx->response_status_expected_number = 400;
-                        break;
-                    case STATUS_404:
-                        // Leave the NUL byte, but set the expected status
-                        tx->response_status_expected_number = 404;
-                        break;
-                }
-            }
-
-            rpos++;
-        }
-
-        // Place the character into output
-
-        // Check for control characters
-        if (c < 0x20) {
-            if (cfg->query_control_char_handling == STATUS_400) {
-                tx->response_status_expected_number = 400;
-            }
-        }
-
-        // Convert backslashes to forward slashes, if necessary
-        if ((c == '\\') && (cfg->query_backslash_separators)) {
-            c = '/';
-        }
-
-        // Lowercase characters, if necessary
-        if (cfg->query_case_insensitive) {
-            c = tolower(c);
-        }
-
-        // If we're compressing separators then we need
-        // to track if the previous character was a separator
-        if (cfg->query_compress_separators) {
-            if (c == '/') {
-                if (!previous_was_separator) {
-                    data[wpos++] = c;
-                    previous_was_separator = 1;
-                } else {
-                    // Do nothing; we don't want
-                    // another separator in output
-                }
-            } else {
-                data[wpos++] = c;
-                previous_was_separator = 0;
-            }
-        } else {
-            data[wpos++] = c;
-        }
-    }
-
-    bstr_len_adjust(query, wpos);
-
-    return 1;
-}
-
-/**
- * Decode a request path according to the settings in the
- * provided configuration structure.
- *
- * @param cfg
- * @param tx
- * @param path
- */
-int htp_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path) {
-    if (path == NULL)
-        return -1;
-
-    unsigned char *data = (unsigned char *) bstr_ptr(path);
-    if (data == NULL) {
-        return -1;
-    }
-    size_t len = bstr_len(path);
-
-    // TODO I don't like this function. It's too complex.
-
-    size_t rpos = 0;
-    size_t wpos = 0;
-    int previous_was_separator = 0;
-
-    while (rpos < len) {
-        int c = data[rpos];
-
-        // Decode encoded characters
-        if (c == '%') {
-            if (rpos + 2 < len) {
-                int handled = 0;
-
-                if (cfg->path_decode_u_encoding) {
-                    // Check for the %u encoding
-                    if ((data[rpos + 1] == 'u') || (data[rpos + 1] == 'U')) {
-                        handled = 1;
-
-                        if (cfg->path_decode_u_encoding == STATUS_400) {
-                            tx->response_status_expected_number = 400;
-                        }
-
-                        if (rpos + 5 < len) {
-                            if (isxdigit(data[rpos + 2]) && (isxdigit(data[rpos + 3]))
-                                && isxdigit(data[rpos + 4]) && (isxdigit(data[rpos + 5]))) {
-                                // Decode a valid %u encoding
-                                c = decode_u_encoding(cfg, tx, &data[rpos + 2]);
-                                rpos += 6;
-
-                                if (c == 0) {
-                                    tx->flags |= HTP_PATH_ENCODED_NUL;
-
-                                    if (cfg->path_nul_encoded_handling == STATUS_400) {
-                                        tx->response_status_expected_number = 400;
-                                    } else if (cfg->path_nul_encoded_handling == STATUS_404) {
-                                        tx->response_status_expected_number = 404;
-                                    }
-                                }
-                            } else {
-                                // Invalid %u encoding
-                                tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                                switch (cfg->path_invalid_encoding_handling) {
-                                    case URL_DECODER_REMOVE_PERCENT:
-                                        // Do not place anything in output; eat
-                                        // the percent character
-                                        rpos++;
-                                        continue;
-                                        break;
-                                    case URL_DECODER_PRESERVE_PERCENT:
-                                        // Leave the percent character in output
-                                        rpos++;
-                                        break;
-                                    case URL_DECODER_DECODE_INVALID:
-                                        // Decode invalid %u encoding
-                                        c = decode_u_encoding(cfg, tx, &data[rpos + 2]);
-                                        rpos += 6;
-                                        break;
-                                    case URL_DECODER_STATUS_400:
-                                        // Set expected status to 400
-                                        tx->response_status_expected_number = 400;
-
-                                        // Decode invalid %u encoding
-                                        c = decode_u_encoding(cfg, tx, &data[rpos + 2]);
-                                        rpos += 6;
-                                        break;
-                                        break;
-                                    default:
-                                        // Unknown setting
-                                        return -1;
-                                        break;
-                                }
-                            }
-                        } else {
-                            // Invalid %u encoding (not enough data)
-                            tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                            if (cfg->path_invalid_encoding_handling == URL_DECODER_REMOVE_PERCENT) {
-                                // Remove the percent character from output
-                                rpos++;
-                                continue;
-                            } else {
-                                rpos++;
-                            }
-                        }
-                    }
-                }
-
-                // Handle standard URL encoding
-                if (!handled) {
-                    if ((isxdigit(data[rpos + 1])) && (isxdigit(data[rpos + 2]))) {
-                        c = x2c(&data[rpos + 1]);
-
-                        if (c == 0) {
-                            tx->flags |= HTP_PATH_ENCODED_NUL;
-
-                            switch (cfg->path_nul_encoded_handling) {
-                                case TERMINATE:
-                                    bstr_len_adjust(path, wpos);
-                                    return 1;
-                                    break;
-                                case STATUS_400:
-                                    tx->response_status_expected_number = 400;
-                                    break;
-                                case STATUS_404:
-                                    tx->response_status_expected_number = 404;
-                                    break;
-                            }
-                        }
-
-                        if ((c == '/') || ((cfg->path_backslash_separators) && (c == '\\'))) {
-                            tx->flags |= HTP_PATH_ENCODED_SEPARATOR;
-
-                            switch (cfg->path_decode_separators) {
-                                case STATUS_404:
-                                    tx->response_status_expected_number = 404;
-                                    // Fall-through
-                                case NO:
-                                    // Leave encoded
-                                    c = '%';
-                                    rpos++;
-                                    break;
-                                case YES:
-                                    // Decode
-                                    rpos += 3;
-                                    break;
-                            }
-                        } else {
-                            // Decode
-                            rpos += 3;
-                        }
-                    } else {
-                        // Invalid encoding
-                        tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                        switch (cfg->path_invalid_encoding_handling) {
-                            case URL_DECODER_REMOVE_PERCENT:
-                                // Do not place anything in output; eat
-                                // the percent character
-                                rpos++;
-                                continue;
-                                break;
-                            case URL_DECODER_PRESERVE_PERCENT:
-                                // Leave the percent character in output
-                                rpos++;
-                                break;
-                            case URL_DECODER_DECODE_INVALID:
-                                // Decode
-                                c = x2c(&data[rpos + 1]);
-                                rpos += 3;
-                                // Note: What if an invalid encoding decodes into a path
-                                //       separator? This is theoretical at the moment, because
-                                //       the only platform we know doesn't convert separators is
-                                //       Apache, who will also respond with 400 if invalid encoding
-                                //       is encountered. Thus no check for a separator here.
-                                break;
-                            case URL_DECODER_STATUS_400:
-                                // Backend will reject request with 400, which means
-                                // that it does not matter what we do.
-                                tx->response_status_expected_number = 400;
-
-                                // Preserve the percent character
-                                rpos++;
-                                break;
-                            default:
-                                // Unknown setting
-                                return -1;
-                                break;
-                        }
-                    }
-                }
-            } else {
-                // Invalid encoding (not enough data)
-                tx->flags |= HTP_PATH_INVALID_ENCODING;
-
-                if (cfg->path_invalid_encoding_handling == URL_DECODER_REMOVE_PERCENT) {
-                    // Do not place the percent character in output
-                    rpos++;
-                    continue;
-                } else {
-                    rpos++;
-                }
-            }
-        } else {
-            // One non-encoded character
-
-            // Is it a NUL byte?
-            if (c == 0) {
-                switch (cfg->path_nul_raw_handling) {
-                    case TERMINATE:
-                        // Terminate path with a raw NUL byte
-                        bstr_len_adjust(path, wpos);
-                        return 1;
-                        break;
-                    case STATUS_400:
-                        // Leave the NUL byte, but set the expected status
-                        tx->response_status_expected_number = 400;
-                        break;
-                    case STATUS_404:
-                        // Leave the NUL byte, but set the expected status
-                        tx->response_status_expected_number = 404;
-                        break;
-                }
-            }
-
-            rpos++;
-        }
-
-        // Place the character into output
-
-        // Check for control characters
-        if (c < 0x20) {
-            if (cfg->path_control_char_handling == STATUS_400) {
-                tx->response_status_expected_number = 400;
-            }
-        }
-
-        // Convert backslashes to forward slashes, if necessary
-        if ((c == '\\') && (cfg->path_backslash_separators)) {
-            c = '/';
-        }
-
-        // Lowercase characters, if necessary
-        if (cfg->path_case_insensitive) {
-            c = tolower(c);
-        }
-
-        // If we're compressing separators then we need
-        // to track if the previous character was a separator
-        if (cfg->path_compress_separators) {
-            if (c == '/') {
-                if (!previous_was_separator) {
-                    data[wpos++] = c;
-                    previous_was_separator = 1;
-                } else {
-                    // Do nothing; we don't want
-                    // another separator in output
-                }
-            } else {
-                data[wpos++] = c;
-                previous_was_separator = 0;
-            }
-        } else {
-            data[wpos++] = c;
-        }
-    }
-
-    bstr_len_adjust(path, wpos);
-
-    return 1;
-}
-
-/**
- * Normalize a previously-parsed request URI.
- *
- * @param connp
- * @param incomplete
- * @param normalized
- * @return HTP_OK or HTP_ERROR
- */
-int htp_normalize_parsed_uri(htp_connp_t *connp, htp_uri_t *incomplete, htp_uri_t *normalized) {
-    // Scheme
-    if (incomplete->scheme != NULL) {
-        // Duplicate and convert to lowercase
-        normalized->scheme = bstr_dup_lower(incomplete->scheme);
-        if (normalized->scheme == NULL)
-            return HTP_ERROR;
-    }
-
-    // Username
-    if (incomplete->username != NULL) {
-        normalized->username = bstr_strdup(incomplete->username);
-        if (normalized->username == NULL)
-            return HTP_ERROR;
-        htp_uriencoding_normalize_inplace(normalized->username);
-    }
-
-    // Password
-    if (incomplete->password != NULL) {
-        normalized->password = bstr_strdup(incomplete->password);
-        if (normalized->password == NULL)
-            return HTP_ERROR;
-        htp_uriencoding_normalize_inplace(normalized->password);
-    }
-
-    // Hostname
-    if (incomplete->hostname != NULL) {
-        // We know that incomplete->hostname does not contain
-        // port information, so no need to check for it here
-        normalized->hostname = bstr_strdup(incomplete->hostname);
-        if (normalized->hostname == NULL)
-            return HTP_ERROR;
-        htp_uriencoding_normalize_inplace(normalized->hostname);
-        htp_normalize_hostname_inplace(normalized->hostname);
-    }
-
-    // Port
-    if (incomplete->port != NULL) {
-        // Parse provided port
-        normalized->port_number = htp_parse_positive_integer_whitespace((unsigned char *) bstr_ptr(incomplete->port),
-            bstr_len(incomplete->port), 10);
-        // We do not report failed port parsing, but leave
-        // to upstream to detect and act upon it.
-    }
-
-    // Path
-    if (incomplete->path != NULL) {
-        // Make a copy of the path, on which we can work on
-        normalized->path = bstr_strdup(incomplete->path);
-        if (normalized->path != NULL) {
-            // Decode URL-encoded (and %u-encoded) characters, as well as lowercase,
-            // compress separators and convert backslashes.
-            htp_decode_path_inplace(connp->cfg, connp->in_tx, normalized->path);
-
-            // Handle UTF-8 in path
-            if (connp->cfg->path_convert_utf8) {
-                // Decode Unicode characters into a single-byte stream, using best-fit mapping
-                htp_utf8_decode_path_inplace(connp->cfg, connp->in_tx, normalized->path);
-            } else {
-                // Only validate path as a UTF-8 stream
-                htp_utf8_validate_path(connp->in_tx, normalized->path);
-            }
-
-            // RFC normalization
-            htp_normalize_uri_path_inplace(normalized->path);
-        } else {
-            return HTP_ERROR;
-        }
-    }
-
-    // Query
-    if (incomplete->query != NULL) {
-        // We cannot URL-decode the query string here; it needs to be
-        // parsed into individual key-value pairs first.
-        normalized->query = bstr_strdup(incomplete->query);
-        if (normalized->query == NULL)
-            return HTP_ERROR;
-    }
-
-    // Fragment
-    if (incomplete->fragment != NULL) {
-        normalized->fragment = bstr_strdup(incomplete->fragment);
-        if (normalized->fragment == NULL)
-            return HTP_ERROR;
-        htp_uriencoding_normalize_inplace(normalized->fragment);
-    }
-
-    return HTP_OK;
-}
-
-/**
- * Normalize request hostname. Convert all characters to lowercase and
- * remove trailing dots from the end, if present.
- *
- * @param hostname
- * @return normalized hostnanme
- */
-bstr *htp_normalize_hostname_inplace(bstr *hostname) {
-    if (hostname == NULL)
-        return NULL;
-    bstr_tolowercase(hostname);
-
-    char *data = bstr_ptr(hostname);
-    size_t len = bstr_len(hostname);
-
-    while (len > 0) {
-        if (data[len - 1] != '.') return hostname;
-
-        bstr_chop(hostname);
-        len--;
-    }
-
-    return hostname;
-}
-
-/**
- * Replace the URI in the structure with the one provided as the parameter
- * to this function (which will typically be supplied in a Host header).
- *
- * @param connp
- * @param parsed_uri
- * @param hostname
- */
-void htp_replace_hostname(htp_connp_t *connp, htp_uri_t *parsed_uri, bstr *hostname) {
-    if (hostname == NULL)
-        return;
-    int colon = bstr_chr(hostname, ':');
-    if (colon == -1) {
-        // Hostname alone
-        parsed_uri->hostname = bstr_strdup(hostname);
-        htp_normalize_hostname_inplace(parsed_uri->hostname);
-    } else {
-        // Hostname
-        parsed_uri->hostname = bstr_strdup_ex(hostname, 0, colon);
-        // TODO Handle whitespace around hostname
-        htp_normalize_hostname_inplace(parsed_uri->hostname);
-
-        // Port
-        int port = htp_parse_positive_integer_whitespace((unsigned char *) bstr_ptr(hostname) + colon + 1,
-            bstr_len(hostname) - colon - 1, 10);
-        if (port < 0) {
-            // Failed to parse port
-            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid server port information in request");
-        } else if ((port > 0) && (port < 65536)) {
-            // Valid port
-            if (port != connp->conn->local_port) {
-                // Port is different from the TCP port
-                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Request server port number differs from the actual TCP port");
-            } else {
-                parsed_uri->port_number = port;
-            }
-        }
-    }
-}
-
-/**
- * Is URI character reserved?
- *
- * @param c
- * @return 1 if it is, 0 if it isn't
- */
-int htp_is_uri_unreserved(unsigned char c) {
-    if (((c >= 0x41) && (c <= 0x5a)) ||
-        ((c >= 0x61) && (c <= 0x7a)) ||
-        ((c >= 0x30) && (c <= 0x39)) ||
-        (c == 0x2d) || (c == 0x2e) ||
-        (c == 0x5f) || (c == 0x7e)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-/**
- * Decode a URL-encoded string, leaving the reserved
- * characters and invalid encodings alone.
- *
- * @param s
- */
-void htp_uriencoding_normalize_inplace(bstr *s) {
-    if (s == NULL) return;
-    unsigned char *data = (unsigned char *) bstr_ptr(s);
-    size_t len = bstr_len(s);
-
-    size_t rpos = 0;
-    size_t wpos = 0;
-
-    while (rpos < len) {
-        if (data[rpos] == '%') {
-            if (rpos + 2 < len) {
-                if (isxdigit(data[rpos + 1]) && (isxdigit(data[rpos + 2]))) {
-                    unsigned char c = x2c(&data[rpos + 1]);
-
-                    if (!htp_is_uri_unreserved(c)) {
-                        // Leave reserved characters encoded, but convert
-                        // the hexadecimal digits to uppercase
-                        data[wpos++] = data[rpos++];
-                        data[wpos++] = toupper(data[rpos++]);
-                        data[wpos++] = toupper(data[rpos++]);
-                    } else {
-                        // Decode unreserved character
-                        data[wpos++] = c;
-                        rpos += 3;
-                    }
-                } else {
-                    // Invalid URL encoding: invalid hex digits
-
-                    // Copy over what's there
-                    data[wpos++] = data[rpos++];
-                    data[wpos++] = toupper(data[rpos++]);
-                    data[wpos++] = toupper(data[rpos++]);
-                }
-            } else {
-                // Invalid URL encoding: string too short
-
-                // Copy over what's there
-                data[wpos++] = data[rpos++];
-                while (rpos < len) {
-                    data[wpos++] = toupper(data[rpos++]);
-                }
-            }
-        } else {
-            data[wpos++] = data[rpos++];
-        }
-    }
-
-    bstr_len_adjust(s, wpos);
-}
-
-#if 0
-
-/**
- *
- */
-int htp_prenormalize_uri_path_inplace(bstr *s, int *flags, int case_insensitive, int backslash, int decode_separators, int remove_consecutive) {
-    char *data = bstr_ptr(s);
-    size_t len = bstr_len(s);
-
-    size_t rpos = 0;
-    size_t wpos = 0;
-
-    while (rpos < len) {
-        char c = data[rpos];
-
-        // Convert backslash characters where necessary
-        if ((c == '/') || ((c == '\\') && (backslash))) {
-            if ((!remove_consecutive) || (wpos == 0) || (data[wpos - 1] != '/')) {
-                data[wpos++] = '/';
-            }
-
-            rpos++;
-        } else
-            if ((c == '%') && (decode_separators)) {
-            if (rpos + 2 < len) {
-                if (isxdigit(data[rpos + 1]) && (isxdigit(data[rpos + 2]))) {
-                    unsigned char x = x2c(&data[rpos + 1]);
-
-                    if (x == 0) {
-                        (*flags) |= HTP_PATH_ENCODED_NUL;
-                    }
-
-                    if ((x == '/') || ((backslash) && (x == '\\'))) {
-                        data[wpos++] = '/';
-                        rpos += 3;
-                        continue;
-                    }
-                } else {
-                    // Invalid URL encoding
-                    (*flags) |= HTP_PATH_INVALID_ENCODING;
-
-                    // Copy over all three bytes
-                    data[wpos++] = data[rpos++];
-                    data[wpos++] = data[rpos++];
-                    data[wpos++] = data[rpos++];
-                }
-            } else {
-                // Not enough characters
-                (*flags) |= HTP_PATH_INVALID_ENCODING;
-
-                // Copy over what's there
-                while (rpos < len) {
-                    data[wpos++] = data[rpos++];
-                }
-            }
-        } else {
-            // Just copy the character
-            if (case_insensitive) {
-                data[wpos++] = tolower(c);
-            } else {
-                data[wpos++] = c;
-            }
-
-            rpos++;
-        }
-    }
-
-    bstr_len_adjust(s, wpos);
-}
-#endif
-
-/**
- * Normalize URL path. This function implements the remove dot segments algorithm
- * speficied in RFC 3986, section 5.2.4.
- *
- * @param s
- */
-void htp_normalize_uri_path_inplace(bstr *s) {
-    if (s == NULL) return;
-    char *data = bstr_ptr(s);
-    size_t len = bstr_len(s);
-
-    size_t rpos = 0;
-    size_t wpos = 0;
-
-    int c = -1;
-    while (rpos < len) {
-        if (c == -1) {
-            c = data[rpos++];
-        }
-
-        // A. If the input buffer begins with a prefix of "../" or "./",
-        //    then remove that prefix from the input buffer; otherwise,
-        if (c == '.') {
-            if ((rpos + 1 < len) && (data[rpos] == '.') && (data[rpos + 1] == '/')) {
-                c = -1;
-                rpos += 2;
-                continue;
-            } else if ((rpos < len) && (data[rpos + 1] == '/')) {
-                c = -1;
-                rpos += 2;
-                continue;
-            }
-        }
-
-        if (c == '/') {
-            // B. if the input buffer begins with a prefix of "/./" or "/.",
-            //    where "." is a complete path segment, then replace that
-            //    prefix with "/" in the input buffer; otherwise,
-            if ((rpos + 1 < len) && (data[rpos] == '.') && (data[rpos + 1] == '/')) {
-                c = '/';
-                rpos += 2;
-                continue;
-            } else if ((rpos + 1 == len) && (data[rpos] == '.')) {
-                c = '/';
-                rpos += 1;
-                continue;
-            }
-
-            // C. if the input buffer begins with a prefix of "/../" or "/..",
-            //    where ".." is a complete path segment, then replace that
-            //    prefix with "/" in the input buffer and remove the last
-            //    segment and its preceding "/" (if any) from the output
-            //    buffer; otherwise,
-            if ((rpos + 2 < len) && (data[rpos] == '.') && (data[rpos + 1] == '.') && (data[rpos + 2] == '/')) {
-                c = '/';
-                rpos += 3;
-
-                // Remove the last segment
-                while ((wpos > 0) && (data[wpos - 1] != '/')) wpos--;
-                if (wpos > 0) wpos--;
-                continue;
-            } else if ((rpos + 2 == len) && (data[rpos] == '.') && (data[rpos + 1] == '.')) {
-                c = '/';
-                rpos += 2;
-
-                // Remove the last segment
-                while ((wpos > 0) && (data[wpos - 1] != '/')) wpos--;
-                if (wpos > 0) wpos--;
-                continue;
-            }
-        }
-
-        // D.  if the input buffer consists only of "." or "..", then remove
-        // that from the input buffer; otherwise,
-        if ((c == '.') && (rpos == len)) {
-            rpos++;
-            continue;
-        }
-
-        if ((c == '.') && (rpos + 1 == len) && (data[rpos] == '.')) {
-            rpos += 2;
-            continue;
-        }
-
-        // E.  move the first path segment in the input buffer to the end of
-        // the output buffer, including the initial "/" character (if
-        // any) and any subsequent characters up to, but not including,
-        // the next "/" character or the end of the input buffer.
-        data[wpos++] = c;
-
-        while ((rpos < len) && (data[rpos] != '/')) {
-            // data[wpos++] = data[rpos++];
-            int c2 = data[rpos++];
-            data[wpos++] = c2;
-        }
-
-        c = -1;
-    }
-
-    bstr_len_adjust(s, wpos);
-}
-
-/**
- *
- */
-void fprint_raw_data(FILE *stream, const char *name, unsigned char *data, size_t len) {
-    char buf[160];
-    size_t offset = 0;
-
-    fprintf(stream, "\n%s: data len %zd (0x%zx)\n", name, len, len);
-
-    while (offset < len) {
-        size_t i;
-
-        sprintf(buf, "%08zx", offset);
-        strcat(buf + strlen(buf), "  ");
-
-        i = 0;
-        while (i < 8) {
-            if (offset + i < len) {
-                sprintf(buf + strlen(buf), "%02x ", data[offset + i]);
-            } else {
-                strcat(buf + strlen(buf), "   ");
-            }
-
-            i++;
-        }
-
-        strcat(buf + strlen(buf), " ");
-
-        i = 8;
-        while (i < 16) {
-            if (offset + i < len) {
-                sprintf(buf + strlen(buf), "%02x ", data[offset + i]);
-            } else {
-                strcat(buf + strlen(buf), "   ");
-            }
-
-            i++;
-        }
-
-        strcat(buf + strlen(buf), " |");
-
-        i = 0;
-        char *p = buf + strlen(buf);
-        while ((offset + i < len) && (i < 16)) {
-            int c = data[offset + i];
-
-            if (isprint(c)) {
-                *p++ = c;
-            } else {
-                *p++ = '.';
-            }
-
-            i++;
-        }
-
-        *p++ = '|';
-        *p++ = '\n';
-        *p++ = '\0';
-
-        fprintf(stream, "%s", buf);
-        offset += 16;
-    }
-
-    fprintf(stream, "\n");
-}
-
-
-/*
-
- */
-
-/**
- *
- */
-char *htp_connp_in_state_as_string(htp_connp_t *connp) {
-    if (connp == NULL) return "NULL";
-
-    if (connp->in_state == htp_connp_REQ_IDLE) return "REQ_IDLE";
-    if (connp->in_state == htp_connp_REQ_LINE) return "REQ_FIRST_LINE";
-    if (connp->in_state == htp_connp_REQ_PROTOCOL) return "REQ_PROTOCOL";
-    if (connp->in_state == htp_connp_REQ_HEADERS) return "REQ_HEADERS";
-    if (connp->in_state == htp_connp_REQ_BODY_DETERMINE) return "REQ_BODY_DETERMINE";
-    if (connp->in_state == htp_connp_REQ_BODY_IDENTITY) return "REQ_BODY_IDENTITY";
-    if (connp->in_state == htp_connp_REQ_BODY_CHUNKED_LENGTH) return "REQ_BODY_CHUNKED_LENGTH";
-    if (connp->in_state == htp_connp_REQ_BODY_CHUNKED_DATA) return "REQ_BODY_CHUNKED_DATA";
-    if (connp->in_state == htp_connp_REQ_BODY_CHUNKED_DATA_END) return "REQ_BODY_CHUNKED_DATA_END";
-
-    if (connp->in_state == htp_connp_REQ_CONNECT_CHECK) return "htp_connp_REQ_CONNECT_CHECK";
-    if (connp->in_state == htp_connp_REQ_CONNECT_WAIT_RESPONSE) return "htp_connp_REQ_CONNECT_WAIT_RESPONSE";
-
-    return "UNKNOWN";
-}
-
-/**
- *
- */
-char *htp_connp_out_state_as_string(htp_connp_t *connp) {
-    if (connp == NULL) return "NULL";
-
-    if (connp->out_state == htp_connp_RES_IDLE) return "RES_IDLE";
-    if (connp->out_state == htp_connp_RES_LINE) return "RES_LINE";
-    if (connp->out_state == htp_connp_RES_HEADERS) return "RES_HEADERS";
-    if (connp->out_state == htp_connp_RES_BODY_DETERMINE) return "RES_BODY_DETERMINE";
-    if (connp->out_state == htp_connp_RES_BODY_IDENTITY) return "RES_BODY_IDENTITY";
-    if (connp->out_state == htp_connp_RES_BODY_CHUNKED_LENGTH) return "RES_BODY_CHUNKED_LENGTH";
-    if (connp->out_state == htp_connp_RES_BODY_CHUNKED_DATA) return "RES_BODY_CHUNKED_DATA";
-    if (connp->out_state == htp_connp_RES_BODY_CHUNKED_DATA_END) return "RES_BODY_CHUNKED_DATA_END";
-
-    return "UNKNOWN";
-}
-
-/**
- *
- */
-char *htp_tx_progress_as_string(htp_tx_t *tx, int direction) {
-    if (tx == NULL) return "NULL";
-
-    switch ((direction == 0) ? tx->progress[0] : tx->progress[1]) {
-        case TX_PROGRESS_NEW:
-            return "NEW";
-        case TX_PROGRESS_REQ_LINE:
-            return "REQ_LINE";
-        case TX_PROGRESS_REQ_HEADERS:
-            return "REQ_HEADERS";
-        case TX_PROGRESS_REQ_BODY:
-            return "REQ_BODY";
-        case TX_PROGRESS_REQ_TRAILER:
-            return "REQ_TRAILER";
-        case TX_PROGRESS_WAIT:
-            return "WAIT";
-        case TX_PROGRESS_RES_LINE:
-            return "RES_LINE";
-        case TX_PROGRESS_RES_HEADERS:
-            return "RES_HEADERS";
-        case TX_PROGRESS_RES_BODY:
-            return "RES_BODY";
-        case TX_PROGRESS_RES_TRAILER:
-            return "RES_TRAILER";
-        case TX_PROGRESS_DONE:
-            return "DONE";
-    }
-
-    return "UNKNOWN";
-}
-
-bstr *htp_unparse_uri_noencode(htp_uri_t *uri) {
-    if (uri == NULL) {
-        return NULL;
-    }   
-
-    // On the first pass determine the length of the final string
-    size_t len = 0;
-
-    if (uri->scheme != NULL) {
-        len += bstr_len(uri->scheme);
-        len += 3; // "://"
-    }
-
-    if ((uri->username != NULL) || (uri->password != NULL)) {
-        if (uri->username != NULL) {
-            len += bstr_len(uri->username);
-        }
-
-        len += 1; // ":"
-
-        if (uri->password != NULL) {
-            len += bstr_len(uri->password);
-        }
-
-        len += 1; // "@"
-    }   
-
-    if (uri->hostname != NULL) {
-        len += bstr_len(uri->hostname);
-    }   
-
-    if (uri->port != NULL) {
-        len += 1; // ":"
-        len += bstr_len(uri->port);
-    }
-
-    if (uri->path != NULL) {
-        len += bstr_len(uri->path);
-    }
-
-    if (uri->query != NULL) {
-        len += 1; // "?"
-        len += bstr_len(uri->query);
-    }
-
-    if (uri->fragment != NULL) {
-        len += 1; // "#"
-        len += bstr_len(uri->fragment);
-    }    
-
-    // On the second pass construct the string
-    bstr *r = bstr_alloc(len);
-    if (r == NULL) {
-        return NULL;
-    }   
-
-    if (uri->scheme != NULL) {
-        bstr_add_str_noex(r, uri->scheme);
-        bstr_add_cstr_noex(r, "://");
-    }   
-
-    if ((uri->username != NULL) || (uri->password != NULL)) {
-        if (uri->username != NULL) {
-            bstr_add_str_noex(r, uri->username);
-        }
-
-        bstr_add_cstr(r, ":");
-
-        if (uri->password != NULL) {
-            bstr_add_str_noex(r, uri->password);
-        }
-
-        bstr_add_cstr_noex(r, "@");
-    }   
-
-    if (uri->hostname != NULL) {
-        bstr_add_str_noex(r, uri->hostname);
-    }   
-
-    if (uri->port != NULL) {
-        bstr_add_cstr(r, ":");
-        bstr_add_str_noex(r, uri->port);
-    }   
-
-    if (uri->path != NULL) {
-        bstr_add_str_noex(r, uri->path);
-    }  
-
-    if (uri->query != NULL) {
-        bstr *query = bstr_strdup(uri->query);
-        htp_uriencoding_normalize_inplace(query);
-        bstr_add_cstr_noex(r, "?");
-        bstr_add_str_noex(r, query);
-        bstr_free(query);
-    }     
-
-    if (uri->fragment != NULL) {
-        bstr_add_cstr_noex(r, "#");
-        bstr_add_str_noex(r, uri->fragment);
-    }
-   
-    return r;
-}
-
-/**
- * Construct a bstr that contains the raw request headers.
- *
- * @param tx
- * @return
- */
-bstr *htp_tx_generate_request_headers_raw(htp_tx_t *tx) {
-    bstr *request_headers_raw = NULL;
-    size_t i, len = 0;
-
-    for (i = 0; i < list_size(tx->request_header_lines); i++) {
-        htp_header_line_t *hl = list_get(tx->request_header_lines, i);
-        len += bstr_len(hl->line);
-        if (hl->terminators)
-            len += bstr_len(hl->terminators);
-        else
-            len += 2; // 0d 0a
-    }
-
-    request_headers_raw = bstr_alloc(len);
-    if (request_headers_raw == NULL) {
-        htp_log(tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Failed to allocate bstring of %d bytes", len);
-        return NULL;
-    }
-
-    for (i = 0; i < list_size(tx->request_header_lines); i++) {
-        htp_header_line_t *hl = list_get(tx->request_header_lines, i);
-        bstr_add_str_noex(request_headers_raw, hl->line);
-        if (hl->terminators)
-            bstr_add_str_noex(request_headers_raw, hl->terminators);
-        else
-            bstr_add_cstr_noex(request_headers_raw, "\r\n");
-    }
-
-    return request_headers_raw;
-}
-
-/**
- * Get a bstr that contains the raw request headers. This method will always
- * return an up-to-date buffer, containing the last known headers. Thus, if
- * it is called once after REQUEST_HEADERS phase it will return one buffer, but
- * it may return a different buffer if called after REQUEST_TRAILERS phase (but
- * only if the request actually contains trailer headers). Do not retain the
- * bstr pointer, as the buffer may change. If there are no changes to the
- * request header structure, only one buffer will be contstructed and used. (Multiple
- * invocations of this method will not cause multiple buffers to be created.)
- *
- * @param tx
- * @return
- */
-bstr *htp_tx_get_request_headers_raw(htp_tx_t *tx) {
-    // Check that we are not called too early
-    if (tx->progress[0] < TX_PROGRESS_REQ_HEADERS) return NULL;
-
-    if (tx->request_headers_raw == NULL) {
-        tx->request_headers_raw = htp_tx_generate_request_headers_raw(tx);
-        tx->request_headers_raw_lines = list_size(tx->request_header_lines);
-    } else {
-        // Check that the buffer we have is not obsolete
-        if (tx->request_headers_raw_lines < list_size(tx->request_header_lines)) {
-            // Rebuild raw buffer
-            bstr_free(tx->request_headers_raw);
-            tx->request_headers_raw = htp_tx_generate_request_headers_raw(tx);
-            tx->request_headers_raw_lines = list_size(tx->request_header_lines);
-        }
-    }
-
-    return tx->request_headers_raw;
-}
-
-/**
- * Construct a bstr that contains the raw response headers.
- *
- * @param tx
- * @return
- */
-bstr *htp_tx_generate_response_headers_raw(htp_tx_t *tx) {
-    bstr *response_headers_raw = NULL;
-    size_t i, len = 0;
-
-    for (i = 0; i < list_size(tx->response_header_lines); i++) {
-        htp_header_line_t *hl = list_get(tx->response_header_lines, i);
-        len += bstr_len(hl->line);
-        if (hl->terminators)
-            len += bstr_len(hl->terminators);
-        else
-            len += 2; // 0d 0a
-    }
-
-    response_headers_raw = bstr_alloc(len);
-    if (response_headers_raw == NULL) {
-        htp_log(tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Failed to allocate bstring of %d bytes", len);
-        return NULL;
-    }
-
-    for (i = 0; i < list_size(tx->response_header_lines); i++) {
-        htp_header_line_t *hl = list_get(tx->response_header_lines, i);
-        bstr_add_str_noex(response_headers_raw, hl->line);
-        if (hl->terminators)
-            bstr_add_str_noex(response_headers_raw, hl->terminators);
-        else
-            bstr_add_cstr_noex(response_headers_raw, "\r\n");
-    }
-
-    return response_headers_raw;
-}
-
-/**
- * Get a bstr that contains the raw response headers. This method will always
- * return an up-to-date buffer, containing the last known headers. Thus, if
- * it is called once after RESPONSE_HEADERS phase it will return one buffer, but
- * it may return a different buffer if called after RESPONSE_TRAILERS phase (but
- * only if the response actually contains trailer headers). Do not retain the
- * bstr pointer, as the buffer may change. If there are no changes to the
- * response header structure, only one buffer will be contstructed and used. (Multiple
- * invocations of this method will not cause multiple buffers to be created.)
- *
- * @param tx
- * @return
- */
-bstr *htp_tx_get_response_headers_raw(htp_tx_t *tx) {
-    // Check that we are not called too early
-    if (tx->progress[1] < TX_PROGRESS_RES_HEADERS) return NULL;
-
-    if (tx->response_headers_raw == NULL) {
-        tx->response_headers_raw = htp_tx_generate_response_headers_raw(tx);
-        tx->response_headers_raw_lines = list_size(tx->response_header_lines);
-    } else {
-        // Check that the buffer we have is not obsolete
-        if (tx->response_headers_raw_lines < list_size(tx->response_header_lines)) {
-            // Rebuild raw buffer
-            bstr_free(tx->response_headers_raw);
-            tx->response_headers_raw = htp_tx_generate_response_headers_raw(tx);
-            tx->response_headers_raw_lines = list_size(tx->response_header_lines);
-        }
-    }
-
-    return tx->response_headers_raw;
-}
diff --git a/libhtp/htp/utf8_decoder.c b/libhtp/htp/utf8_decoder.c
deleted file mode 100644 (file)
index 35c6ae6..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-/*
-Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
-
-#include "utf8_decoder.h"
-
-static const uint8_t utf8d[] = {
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
-  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
-  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
-  8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
-  0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
-  0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
-  0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
-  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
-  1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
-  1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
-  1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
-};
-
-static const uint8_t utf8d_allow_overlong[] = {
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
-  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
-  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
-  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df; changed c0 and c1
-  0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef; changed e0
-  0x6,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff; changed f0
-  0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
-  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
-  1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
-  1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
-  1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
-};
-
-inline uint32_t utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
-  uint32_t type = utf8d[byte];
-
-  *codep = (*state != UTF8_ACCEPT) ?
-    (byte & 0x3fu) | (*codep << 6) :
-    (0xff >> type) & (byte);
-
-  *state = utf8d[256 + *state*16 + type];
-  return *state;
-}
-
-inline uint32_t utf8_decode_allow_overlong(uint32_t* state, uint32_t* codep, uint32_t byte) {
-  uint32_t type = utf8d_allow_overlong[byte];
-
-  *codep = (*state != UTF8_ACCEPT) ?
-    (byte & 0x3fu) | (*codep << 6) :
-    (0xff >> type) & (byte);
-
-  *state = utf8d[256 + *state*16 + type];
-  return *state;
-}
-
diff --git a/libhtp/htp/utf8_decoder.h b/libhtp/htp/utf8_decoder.h
deleted file mode 100644 (file)
index e682528..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _UTF8_DECODER_H
-#define        _UTF8_DECODER_H
-
-/* HTP changes:
- * 
- *     - Changed the name of the function from "decode" to "utf8_decode"
- *     - Created a separate header file
- *     - Copied the licence from the web page
- *     - Created a copy of the data and function "utf8_decode_allow_overlong", which
- *       does not treat overlong characters as invalid.
- */
-
-/*
-Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute,
-sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or
-substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
-NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include <stdint.h>
-
-#define UTF8_ACCEPT 0
-#define UTF8_REJECT 1
-
-uint32_t utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte);
-uint32_t utf8_decode_allow_overlong(uint32_t* state, uint32_t* codep, uint32_t byte);
-
-#endif /* _UTF8_DECODER_H */
-
diff --git a/libhtp/m4/.keep b/libhtp/m4/.keep
deleted file mode 100644 (file)
index ab93fd8..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-libhtp/m4 dir won't be created on CentOS 5.3 by autogen.sh, so work around that by having it in git
-
diff --git a/libhtp/test/Makefile.am b/libhtp/test/Makefile.am
deleted file mode 100644 (file)
index ddf2952..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-check_PROGRAMS = main
-main_SOURCES = main.c test.c test.h  test-tcpick.c
-
-LDADD = ../htp/.libs/libhtp.a -lz
-AM_CFLAGS = -g -O2
-
-
-#check: all
-#      ./main
-       
-       
diff --git a/libhtp/test/files/01-get.t b/libhtp/test/files/01-get.t
deleted file mode 100644 (file)
index 832f8e9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
->>>
-GET /?p=%20 HTTP/1.0
-User-Agent: Mozilla
-
-
-<<<
-HTTP/1.0 200 OK
-Date: Mon, 31 Aug 2009 20:25:50 GMT
-Server: Apache
-Connection: close
-Content-Type: text/html
-Content-Length: 12
-
-Hello World!
diff --git a/libhtp/test/files/02-header-test-apache2.t b/libhtp/test/files/02-header-test-apache2.t
deleted file mode 100644 (file)
index ee6652d..0000000
Binary files a/libhtp/test/files/02-header-test-apache2.t and /dev/null differ
diff --git a/libhtp/test/files/03-post-urlencoded.t b/libhtp/test/files/03-post-urlencoded.t
deleted file mode 100644 (file)
index e81076f..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
->>>
-POST / HTTP/1.0
-Content-Length: 12
-Content-Type: application/x-www-form-urlencoded
-User-Agent: Mozilla
-
-p=0123456789
-<<<
-HTTP/1.0 200 OK
-Date: Mon, 31 Aug 2009 20:25:50 GMT
-Server: Apache
-Connection: close
-Content-Type: text/html
-Content-Length: 12
-
-Hello World!
->>>
-GET / HTTP/1.0
-
-
-<<<
-HTTP/1.0 200 OK
-Date: Mon, 31 Aug 2009 20:25:50 GMT
-Server: Apache
-Connection: close
-Content-Type: text/html
-Transfer-Encoding: chunked
-
-9
-012345678
-1
-9
-0
-
diff --git a/libhtp/test/files/04-post-urlencoded-chunked.t b/libhtp/test/files/04-post-urlencoded-chunked.t
deleted file mode 100644 (file)
index d99bb03..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
->>>
-POST / HTTP/1.1
-Transfer-Encoding: chunked
-Content-Type: application/x-www-form-urlencoded
-User-Agent: Mozilla
-Cookie: 1
-
-9
-012345678
-1
-9
-0
-Cookie: 2
-
-
-<<<
-HTTP/1.0 200 OK
-Date: Mon, 31 Aug 2009 20:25:50 GMT
-Server: Apache
-Connection: close
-Content-Type: text/html
-Content-Length: 12
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/files/05-expect.t b/libhtp/test/files/05-expect.t
deleted file mode 100644 (file)
index d6d474f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
->>>
-POST / HTTP/1.1
-User-Agent: curl/7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.8 libssh2/0.18
-Accept: */*
-Content-Length: 216
-Expect: 100-continue
-Content-Type: multipart/form-data; boundary=----------------------------07869933ca1b
-
-
-<<<
-HTTP/1.1 100 Continue
-
-
->>>
-------------------------------07869933ca1b
-Content-Disposition: form-data; name="file"; filename="404.php"
-Content-Type: application/octet-stream
-
-
->>>
-<? echo "404"; ?>
->>>
-
-------------------------------07869933ca1b--
-
-<<<
-HTTP/1.1 200 OK
-Date: Tue, 03 Nov 2009 09:27:47 GMT
-Server: Apache
-Last-Modified: Thu, 30 Apr 2009 12:20:49 GMT
-ETag: "2dcada-2d-468c4b9ec6a40"
-Accept-Ranges: bytes
-Content-Length: 45
-Vary: Accept-Encoding
-Content-Type: text/html
-
-<html><body><h1>It works!</h1></body></html>
diff --git a/libhtp/test/files/06-uri-normal.t b/libhtp/test/files/06-uri-normal.t
deleted file mode 100644 (file)
index 0f83fc8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
->>>
-GET http://username:password@www.example.com:8080/sub/folder/file.jsp?p=q#f HTTP/1.0
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/files/07-pipelined-connection.t b/libhtp/test/files/07-pipelined-connection.t
deleted file mode 100644 (file)
index bcb602a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
->>>
-GET /first HTTP/1.1
-
-GET /second HTTP/1.1
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/files/08-not-pipelined-connection.t b/libhtp/test/files/08-not-pipelined-connection.t
deleted file mode 100644 (file)
index ae1eb99..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
->>>
-GET /first HTTP/1.1
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
->>>
-GET /second HTTP/1.1
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/files/09-multi-packet-request-head.t b/libhtp/test/files/09-multi-packet-request-head.t
deleted file mode 100644 (file)
index 28ee8e8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
->>>
-GET / HTTP/1.0
-
->>>
-Host: www.example.com
-
->>>
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/files/10-host-in-headers.t b/libhtp/test/files/10-host-in-headers.t
deleted file mode 100644 (file)
index ac7766c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
->>>
-GET / HTTP/1.1
-Host: www.example.com
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
-
-Hello World!
->>>
-GET / HTTP/1.1
-Host: www.example.com...
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
->>>
-GET / HTTP/1.1
-Host: WwW.ExamPle.cOm
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
->>>
-GET / HTTP/1.1
-Host: www.example.com:80
-
-
-<<<
-HTTP/1.0 200 OK
-Content-Length: 12
\ No newline at end of file
diff --git a/libhtp/test/files/11-response-stream-closure.t b/libhtp/test/files/11-response-stream-closure.t
deleted file mode 100644 (file)
index 2bc9d36..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
->>>
-GET / HTTP/1.0
-User-Agent: Mozilla
-
-
-<<<
-HTTP/1.0 200 OK
-Date: Mon, 31 Aug 2009 20:25:50 GMT
-Server: Apache
-Connection: close
-Content-Type: text/html
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/files/12-connect-request.t b/libhtp/test/files/12-connect-request.t
deleted file mode 100644 (file)
index e1fbe33..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
->>>
-CONNECT www.ssllabs.com:443 HTTP/1.0
-
-
-<<<
-HTTP/1.1 405 Method Not Allowed
-Date: Sat, 12 Dec 2009 05:08:45 GMT
-Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8g PHP/5.3.0
-Allow: GET,HEAD,POST,OPTIONS,TRACE
-Vary: Accept-Encoding
-Content-Length: 230
-Connection: close
-Content-Type: text/html; charset=iso-8859-1
-
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
-<html><head>
-<title>405 Method Not Allowed</title>
-</head><body>
-<h1>Method Not Allowed</h1>
-<p>The requested method CONNECT is not allowed for the URL /.</p>
-</body></html>
\ No newline at end of file
diff --git a/libhtp/test/files/13-compressed-response-gzip-ct.t b/libhtp/test/files/13-compressed-response-gzip-ct.t
deleted file mode 100644 (file)
index d5a2e31..0000000
Binary files a/libhtp/test/files/13-compressed-response-gzip-ct.t and /dev/null differ
diff --git a/libhtp/test/files/14-compressed-response-gzip-chunked.t b/libhtp/test/files/14-compressed-response-gzip-chunked.t
deleted file mode 100644 (file)
index bae8a2d..0000000
Binary files a/libhtp/test/files/14-compressed-response-gzip-chunked.t and /dev/null differ
diff --git a/libhtp/test/files/15-connect-complete.t b/libhtp/test/files/15-connect-complete.t
deleted file mode 100644 (file)
index 071d064..0000000
Binary files a/libhtp/test/files/15-connect-complete.t and /dev/null differ
diff --git a/libhtp/test/files/16-connect-extra.t b/libhtp/test/files/16-connect-extra.t
deleted file mode 100644 (file)
index da6b352..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
->>>
-CONNECT www.feistyduck.com:80 HTTP/1.1
-Host: www.feistyduck.com
-
-HEAD / HTTP/1.0
-
-
-<<<
-HTTP/1.1 301 Moved Permanently
-Date: Wed, 06 Jan 2010 17:41:34 GMT
-Server: Apache
-Location: https://www.feistyduck.com/
-Vary: Accept-Encoding
-Content-Length: 235
-Content-Type: text/html; charset=iso-8859-1
-
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
-<html><head>
-<title>301 Moved Permanently</title>
-</head><body>
-<h1>Moved Permanently</h1>
-<p>The document has moved <a href="https://www.feistyduck.com/">here</a>.</p>
-</body></html>
-
-HTTP/1.1 301 Moved Permanently
-Date: Wed, 06 Jan 2010 17:41:46 GMT
-Server: Apache
-Location: https://www.feistyduck.com/
-Vary: Accept-Encoding
-Connection: close
-Content-Type: text/html; charset=iso-8859-1
-
diff --git a/libhtp/test/files/anchor.empty b/libhtp/test/files/anchor.empty
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/libhtp/test/files/misc.t b/libhtp/test/files/misc.t
deleted file mode 100644 (file)
index 8ca3fce..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
->>>
-GET http://www.example%64.com/one/two/three.php?p=%64&q=%64#fff HTTP/1.0
-
-
-<<<
-HTTP/1.1 200 OK
-Content-Type: text/html
-Content-Length: 12
-
-Hello World!
\ No newline at end of file
diff --git a/libhtp/test/main.c b/libhtp/test/main.c
deleted file mode 100644 (file)
index 4a2abde..0000000
+++ /dev/null
@@ -1,1388 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include "../htp/bstr.h"
-#include "../htp/htp.h"
-#include "test.h"
-
-char *home = NULL;
-
-/**
- *
- */
-int test_get(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "01-get.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);    
-
-    return 1;
-}
-
-/**
- *
- */
-int test_post_urlencoded_chunked(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "04-post-urlencoded-chunked.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    bstr *key = NULL;
-    htp_header_t *h = NULL;
-    table_iterator_reset(tx->request_headers);
-    while ((key = table_iterator_next(tx->request_headers, (void **) & h)) != NULL) {
-        char *key = bstr_tocstr(h->name);
-        char *value = bstr_tocstr(h->value);
-        printf("--   HEADER [%s][%s]\n", key, value);
-        free(value);
-        free(key);
-    }
-
-    bstr *raw = htp_tx_get_request_headers_raw(tx);
-    fprint_raw_data(stdout, "REQUEST HEADERS RAW 2", bstr_ptr(raw), bstr_len(raw));
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_post_urlencoded(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "03-post-urlencoded.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_apache_header_parsing(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "02-header-test-apache2.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-    if (tx == NULL) return -1;
-
-    int count = 0;
-    bstr *key = NULL;
-    htp_header_t *h = NULL;
-    table_iterator_reset(tx->request_headers);
-    while ((key = table_iterator_next(tx->request_headers, (void **) & h)) != NULL) {
-        char *key = bstr_tocstr(h->name);
-        char *value = bstr_tocstr(h->value);
-        printf("--   HEADER [%s][%s]\n", key, value);
-        free(value);
-        free(key);
-    }
-
-    // There must be 9 headers
-    if (table_size(tx->request_headers) != 9) {
-        printf("Got %i headers, but expected 9\n", table_size(tx->request_headers));
-        htp_connp_destroy(connp);
-        return -1;
-    }
-
-    // Check every header
-    count = 0;
-    key = NULL;
-    h = NULL;
-    table_iterator_reset(tx->request_headers);
-    while ((key = table_iterator_next(tx->request_headers, (void **) & h)) != NULL) {
-
-        switch (count) {
-            case 0:
-                if (bstr_cmpc(h->name, " Invalid-Folding") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "1") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 1:
-                if (bstr_cmpc(h->name, "Valid-Folding") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "2 2") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 2:
-                if (bstr_cmpc(h->name, "Normal-Header") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "3") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 3:
-                if (bstr_cmpc(h->name, "Invalid Header Name") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "4") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 4:
-                if (bstr_cmpc(h->name, "Same-Name-Headers") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "5, 6") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 5:
-                if (bstr_cmpc(h->name, "Empty-Value-Header") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 6:
-                if (bstr_cmpc(h->name, "") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "8, ") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 7:
-                if (bstr_cmpc(h->name, "Header-With-LWS-After") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    return -1;
-                }
-                if (bstr_cmpc(h->value, "9") != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    return -1;
-                }
-                break;
-            case 8:
-            {
-                bstr *b = bstr_memdup("BEFORE", 6);
-                if (bstr_cmpc(h->name, "Header-With-NUL") != 0) {
-                    printf("Header %i incorrect name\n", count + 1);
-                    bstr_free(b);
-                    return -1;
-                }
-                if (bstr_cmp(h->value, b) != 0) {
-                    printf("Header %i incorrect value\n", count + 1);
-                    bstr_free(b);
-                    return -1;
-                }
-                bstr_free(b);
-            }
-                break;
-        }
-
-        count++;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_expect(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "05-expect.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_uri_normal(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "06-uri-normal.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_pipelined_connection(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "07-pipelined-connection.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) != 2) {
-        printf("Expected 2 transactions but found %i.", list_size(connp->conn->transactions));
-        return -1;
-    }
-
-    if (!(connp->conn->flags & PIPELINED_CONNECTION)) {
-        printf("The pipelined flag not set on a pipelined connection.");
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_not_pipelined_connection(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "08-not-pipelined-connection.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) != 2) {
-        printf("Expected 2 transactions but found %i.", list_size(connp->conn->transactions));
-        return -1;
-    }
-
-    if (connp->conn->flags & PIPELINED_CONNECTION) {
-        printf("The pipelined flag set on a connection that is not pipelined.");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->flags & HTP_MULTI_PACKET_HEAD) {
-        printf("The HTP_MULTI_PACKET_HEAD flag set on a single-packet transaction.");
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_multi_packet_request_head(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "09-multi-packet-request-head.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) != 1) {
-        printf("Expected 1 transaction but found %i.", list_size(connp->conn->transactions));
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (!(tx->flags & HTP_MULTI_PACKET_HEAD)) {
-        printf("The HTP_MULTI_PACKET_HEAD flag is not set on a multipacket transaction.");
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_misc(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "misc.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    printf("Parsed URI: %s\n", bstr_tocstr(tx->parsed_uri_incomplete->path));
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-/**
- *
- */
-int test_host_in_headers(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "10-host-in-headers.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) != 4) {
-        printf("Expected 4 transactions but found %i.", list_size(connp->conn->transactions));
-        return -1;
-    }
-
-    htp_tx_t *tx1 = list_get(connp->conn->transactions, 0);
-    htp_tx_t *tx2 = list_get(connp->conn->transactions, 1);
-    htp_tx_t *tx3 = list_get(connp->conn->transactions, 2);
-    htp_tx_t *tx4 = list_get(connp->conn->transactions, 3);
-
-    if ((tx1->parsed_uri->hostname == NULL) || (bstr_cmpc(tx1->parsed_uri->hostname, "www.example.com") != 0)) {
-        printf("1) Expected 'www.example.com' as hostname, but got: %s", tx1->parsed_uri->hostname);
-        return -1;
-    }
-
-    if ((tx2->parsed_uri->hostname == NULL) || (bstr_cmpc(tx2->parsed_uri->hostname, "www.example.com") != 0)) {
-        printf("2) Expected 'www.example.com' as hostname, but got: %s", tx2->parsed_uri->hostname);
-        return -1;
-    }
-
-    if ((tx3->parsed_uri->hostname == NULL) || (bstr_cmpc(tx3->parsed_uri->hostname, "www.example.com") != 0)) {
-        printf("3) Expected 'www.example.com' as hostname, but got: %s", tx3->parsed_uri->hostname);
-        return -1;
-    }
-
-    if ((tx4->parsed_uri->hostname == NULL) || (bstr_cmpc(tx4->parsed_uri->hostname, "www.example.com") != 0)) {
-        printf("4) Expected 'www.example.com' as hostname, but got: %s", tx4->parsed_uri->hostname);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_response_stream_closure(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "11-response-stream-closure.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->progress != TX_PROGRESS_DONE) {
-        printf("Expected the only transaction to be complete (but got %i).", tx->progress);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_connect(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "12-connect-request.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->progress != TX_PROGRESS_DONE) {
-        printf("Expected the only transaction to be complete (but got %i).", tx->progress);
-        return -1;
-    }
-
-    //printf("Parsed URI: %x\n", tx->parsed_uri);
-    // printf("Server: %s\n", bstr_len(tx->parsed_uri->hostname), bstr_ptr(tx->parsed_uri->hostname));
-    //printf("Port: %s\n", bstr_ptr(tx->parsed_uri->port));
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_connect_complete(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "15-connect-complete.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->progress != TX_PROGRESS_DONE) {
-        printf("Expected the only transaction to be complete (but got %i).", tx->progress);
-        return -1;
-    }   
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_connect_extra(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "16-connect-extra.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->progress != TX_PROGRESS_DONE) {
-        printf("Expected the only transaction to be complete (but got %i).", tx->progress);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_compressed_response_gzip_ct(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "13-compressed-response-gzip-ct.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->progress != TX_PROGRESS_DONE) {
-        printf("Expected the only transaction to be complete (but got %i).", tx->progress);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int test_compressed_response_gzip_chunked(htp_cfg_t *cfg) {
-    htp_connp_t *connp = NULL;
-
-    int rc = test_run(home, "14-compressed-response-gzip-chunked.t", cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) htp_connp_destroy_all(connp);
-        return -1;
-    }
-
-    if (list_size(connp->conn->transactions) == 0) {
-        printf("Expected at least one transaction");
-        return -1;
-    }
-
-    htp_tx_t *tx = list_get(connp->conn->transactions, 0);
-
-    if (tx->progress != TX_PROGRESS_DONE) {
-        printf("Expected the only transaction to be complete (but got %i).", tx->progress);
-        return -1;
-    }
-
-    htp_connp_destroy_all(connp);
-
-    return 1;
-}
-
-int callback_transaction_start(htp_connp_t *connp) {
-    printf("-- Callback: transaction_start\n");
-    return HOOK_OK;
-}
-
-int callback_request_line(htp_connp_t *connp) {
-    printf("-- Callback: request_line\n");
-    return HOOK_OK;
-}
-
-int callback_request_headers(htp_connp_t *connp) {
-    printf("-- Callback: request_headers\n");
-    return HOOK_OK;
-}
-
-int callback_request_body_data(htp_tx_data_t *d) {
-    printf("-- Callback: request_body_data\n");
-    fprint_raw_data(stdout, __FUNCTION__, d->data, d->len);
-    return HOOK_OK;
-}
-
-int callback_request_trailer(htp_connp_t *connp) {
-    printf("-- Callback: request_trailer\n");
-    return HOOK_OK;
-}
-
-int callback_request(htp_connp_t *connp) {
-    printf("-- Callback: request\n");
-    return HOOK_OK;
-}
-
-int callback_response_line(htp_connp_t *connp) {
-    printf("-- Callback: response_line\n");
-    return HOOK_OK;
-}
-
-int callback_response_headers(htp_connp_t *connp) {
-    printf("-- Callback: response_headers\n");
-    return HOOK_OK;
-}
-
-int callback_response_body_data(htp_tx_data_t *d) {
-    printf("-- Callback: response_body_data\n");
-    fprint_raw_data(stdout, __FUNCTION__, d->data, d->len);
-    return HOOK_OK;
-}
-
-int callback_response_trailer(htp_connp_t *connp) {
-    printf("-- Callback: response_trailer\n");
-    return HOOK_OK;
-}
-
-int callback_response(htp_connp_t *connp) {
-    printf("-- Callback: response\n");    
-    return HOOK_OK;
-}
-
-int callback_response_destroy(htp_connp_t *connp) {
-    htp_tx_destroy(connp->out_tx);
-    printf("-- Destroyed transaction\n");
-    return HOOK_OK;
-}
-
-int callback_log(htp_log_t *log) {    
-    htp_print_log(stdout, log);
-    return HOOK_OK;
-}
-
-static void print_tx(htp_connp_t *connp, htp_tx_t *tx) {
-    char *request_line = bstr_tocstr(tx->request_line);
-    htp_header_t *h_user_agent = table_getc(tx->request_headers, "user-agent");
-    htp_header_t *h_referer = table_getc(tx->request_headers, "referer");
-    char *referer, *user_agent;
-    char buf[256];
-
-    time_t t = time(NULL);
-    struct tm *tmp = localtime(&t);
-
-    strftime(buf, 255, "%d/%b/%Y:%T %z", tmp);
-
-    if (h_user_agent == NULL) user_agent = strdup("-");
-    else {
-        user_agent = bstr_tocstr(h_user_agent->value);
-    }
-
-    if (h_referer == NULL) referer = strdup("-");
-    else {
-        referer = bstr_tocstr(h_referer->value);
-    }
-
-    printf("%s - - [%s] \"%s\" %i %i \"%s\" \"%s\"\n", connp->conn->remote_addr, buf,
-        request_line, tx->response_status_number, tx->response_message_len,
-        referer, user_agent);
-
-    free(referer);
-    free(user_agent);
-    free(request_line);
-}
-
-static int run_directory(char *dirname, htp_cfg_t *cfg) {
-    struct dirent *entry;
-    char buf[1025];
-    DIR *d = opendir(dirname);
-    htp_connp_t *connp;
-
-    if (d == NULL) {
-        printf("Failed to open directory: %s\n", dirname);
-        return -1;
-    }
-
-    while ((entry = readdir(d)) != NULL) {
-        if (strncmp(entry->d_name, "stream", 6) == 0) {   
-            int rc = test_run(dirname, entry->d_name, cfg, &connp);
-
-            if (rc < 0) {
-                if (connp != NULL) {
-                    htp_log_t *last_error = htp_connp_get_last_error(connp);
-                    if (last_error != NULL) {
-                        printf(" -- failed: %s\n", last_error->msg);
-                    } else {
-                        printf(" -- failed: ERROR NOT AVAILABLE\n");
-                    }
-
-                    return 0;
-                } else {
-                    return -1;
-                }
-            } else {
-                printf(" -- %i transaction(s)\n", list_size(connp->conn->transactions));
-
-                htp_tx_t *tx = NULL;
-                list_iterator_reset(connp->conn->transactions);
-                while ((tx = list_iterator_next(connp->conn->transactions)) != NULL) {
-                    printf("    ");
-                    print_tx(connp, tx);
-                }
-
-                printf("\n");
-
-                htp_connp_destroy_all(connp);
-            }
-        }
-    }
-
-    closedir(d);
-
-    return 1;
-}
-
-int main_dir(int argc, char** argv) {
-    htp_cfg_t *cfg = htp_config_create();
-    htp_config_register_log(cfg, callback_log);
-    htp_config_register_response(cfg, callback_response_destroy);
-    
-    run_directory("C:\\http_traces\\run5", cfg);
-    //run_directory("/home/ivanr/work/traces/run3/", cfg);
-    
-    htp_config_destroy(cfg);
-    return (EXIT_SUCCESS);
-}
-
-#define RUN_TEST(X, Y) \
-    {\
-    tests++; \
-    printf("---------------------------------\n"); \
-    printf("Test: " #X "\n"); \
-    int rc = X(Y); \
-    if (rc < 0) { \
-        printf("    Failed with %i\n", rc); \
-        failures++; \
-    } \
-    printf("\n"); \
-    }
-
-/**
- * Entry point; runs a bunch of tests and exits.
- */
-int main(int argc, char** argv) {
-    char buf[1025];
-    int tests = 0, failures = 0;
-
-    home = NULL;
-
-    // Try the current working directory first
-    int fd = open("./files/anchor.empty", 0, O_RDONLY);
-    if (fd != -1) {
-        close(fd);
-        home = "./files";
-    } else {
-        // Try the directory in which the executable resides
-        strncpy(buf, argv[0], 1024);
-        strncat(buf, "/../files/anchor.empty", 1024 - strlen(buf));
-        fd = open(buf, 0, O_RDONLY);
-        if (fd != -1) {
-            close(fd);
-            strncpy(buf, argv[0], 1024);
-            strncat(buf, "/../files", 1024 - strlen(buf));
-            home = buf;
-        } else {
-            // Try the directory in which the executable resides
-            strncpy(buf, argv[0], 1024);
-            strncat(buf, "/../../files/anchor.empty", 1024 - strlen(buf));
-            fd = open(buf, 0, O_RDONLY);
-            if (fd != -1) {
-                close(fd);
-                strncpy(buf, argv[0], 1024);
-                strncat(buf, "/../../files", 1024 - strlen(buf));
-                home = buf;
-            }
-        }
-    }
-
-    if (home == NULL) {
-        printf("Failed to find test files.");
-        exit(-1);
-    }
-
-    htp_cfg_t *cfg = htp_config_create();
-    //htp_config_set_server_personality(cfg, HTP_SERVER_GENERIC);
-    htp_config_set_server_personality(cfg, HTP_SERVER_APACHE_2_2);
-
-    // Register hooks
-    htp_config_register_transaction_start(cfg, callback_transaction_start);
-
-    htp_config_register_request_line(cfg, callback_request_line);
-    htp_config_register_request_headers(cfg, callback_request_headers);
-    htp_config_register_request_body_data(cfg, callback_request_body_data);
-    htp_config_register_request_trailer(cfg, callback_request_trailer);
-    htp_config_register_request(cfg, callback_request);
-
-    htp_config_register_response_line(cfg, callback_response_line);
-    htp_config_register_response_headers(cfg, callback_response_headers);
-    htp_config_register_response_body_data(cfg, callback_response_body_data);
-    htp_config_register_response_trailer(cfg, callback_response_trailer);
-    htp_config_register_response(cfg, callback_response);
-
-    htp_config_register_log(cfg, callback_log);
-
-    htp_config_set_generate_request_uri_normalized(cfg, 1);
-    
-    RUN_TEST(test_get, cfg);
-    //RUN_TEST(test_apache_header_parsing, cfg);
-    //RUN_TEST(test_post_urlencoded, cfg);
-    //RUN_TEST(test_post_urlencoded_chunked, cfg);
-    //RUN_TEST(test_expect, cfg);
-    //RUN_TEST(test_uri_normal, cfg);
-    //RUN_TEST(test_pipelined_connection, cfg);
-    //RUN_TEST(test_not_pipelined_connection, cfg);
-    //RUN_TEST(test_multi_packet_request_head, cfg);
-    //RUN_TEST(test_response_stream_closure, cfg);
-    //RUN_TEST(test_host_in_headers, cfg);
-    //RUN_TEST(test_compressed_response_gzip_ct, cfg);
-    //RUN_TEST(test_compressed_response_gzip_chunked, cfg);
-    
-    //RUN_TEST(test_connect, cfg);
-    //RUN_TEST(test_connect_complete, cfg);
-    //RUN_TEST(test_connect_extra, cfg);    
-
-    //RUN_TEST(test_misc, cfg);
-    //RUN_TEST(test_post_urlencoded_chunked, cfg);
-
-    printf("Tests: %i\n", tests);
-    printf("Failures: %i\n", failures);
-
-    htp_config_destroy(cfg);
-
-    return (EXIT_SUCCESS);
-}
-
-int main_path_decoding_tests(int argc, char** argv) {
-    htp_cfg_t *cfg = htp_config_create();
-    htp_tx_t *tx = htp_tx_create(cfg, 0, NULL);
-
-    bstr *path = NULL;
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven");
-    cfg->path_case_insensitive = 1;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven");
-    cfg->path_case_insensitive = 1;
-    cfg->path_compress_separators = 1;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven");
-    cfg->path_case_insensitive = 1;
-    cfg->path_compress_separators = 1;
-    cfg->path_backslash_separators = 1;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven");
-    cfg->path_case_insensitive = 1;
-    cfg->path_compress_separators = 1;
-    cfg->path_backslash_separators = 1;
-    cfg->path_decode_separators = 1;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven");
-    cfg->path_case_insensitive = 1;
-    cfg->path_compress_separators = 1;
-    cfg->path_backslash_separators = 1;
-    cfg->path_decode_separators = 1;
-    cfg->path_invalid_encoding_handling = URL_DECODER_REMOVE_PERCENT;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven/%u0074");
-    cfg->path_case_insensitive = 1;
-    cfg->path_compress_separators = 1;
-    cfg->path_backslash_separators = 1;
-    cfg->path_decode_separators = 1;
-    cfg->path_invalid_encoding_handling = URL_DECODER_DECODE_INVALID;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    //
-    path = bstr_cstrdup("/One\\two///ThRee%2ffive%5csix/se%xxven/%u0074%u0100");
-    cfg->path_case_insensitive = 1;
-    cfg->path_compress_separators = 1;
-    cfg->path_backslash_separators = 1;
-    cfg->path_decode_separators = 1;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    cfg->path_decode_u_encoding = 1;
-
-    printf("Before: %s\n", bstr_tocstr(path));
-    htp_decode_path_inplace(cfg, tx, path);
-    printf("After: %s\n\n", bstr_tocstr(path));
-
-    return (EXIT_SUCCESS);
-}
-
-void encode_utf8_2(uint8_t *data, uint32_t i) {
-    i = i & 0x7ff;
-    data[0] = 0xc0 + (i >> 6);
-    data[1] = 0x80 + (i & 0x3f);
-}
-
-void encode_utf8_3(uint8_t *data, uint32_t i) {
-    i = i & 0xffff;
-    data[0] = 0xe0 + (i >> 12);
-    data[1] = 0x80 + ((i >> 6) & 0x3f);
-    data[2] = 0x80 + (i & 0x3f);
-}
-
-void encode_utf8_4(uint8_t *data, uint32_t i) {
-    i = i & 0x10ffff;
-    data[0] = 0xf0 + (i >> 18);
-    data[1] = 0x80 + ((i >> 12) & 0x3f);
-    data[2] = 0x80 + ((i >> 6) & 0x3f);
-    data[3] = 0x80 + (i & 0x3f);
-}
-
-int main_utf8_decoder_tests(int argc, char** argv) {
-    htp_cfg_t *cfg = htp_config_create();
-    htp_tx_t *tx = htp_tx_create(cfg, 0, NULL);
-
-    bstr *path = NULL;
-
-    path = bstr_cstrdup("//////////");
-    uint8_t *data = bstr_ptr(path);
-
-    int i = 0;
-
-    for (i = 0; i < 0x80; i++) {
-        memset(data, 0x2f, 10);
-        tx->flags = 0;
-        encode_utf8_2(data, i);
-        htp_utf8_validate_path(tx, path);
-        if (tx->flags != HTP_PATH_UTF8_OVERLONG) {
-            printf("#2 i %i data %x %x flags %x\n", i, (uint8_t) data[0], (uint8_t) data[1], tx->flags);
-        }
-    }
-
-    for (i = 0; i < 0x800; i++) {
-        memset(data, 0x2f, 10);
-        tx->flags = 0;
-        encode_utf8_3(data, i);
-        htp_utf8_validate_path(tx, path);
-        if (tx->flags != HTP_PATH_UTF8_OVERLONG) {
-            printf("#3 i %x data %x %x %x flags %x\n", i, (uint8_t) data[0], (uint8_t) data[1], (uint8_t) data[2], tx->flags);
-        }
-    }
-
-    for (i = 0; i < 0x10000; i++) {
-        memset(data, 0x2f, 10);
-        tx->flags = 0;
-        encode_utf8_4(data, i);
-        htp_utf8_validate_path(tx, path);
-        if ((i >= 0xff00) && (i <= 0xffff)) {
-            if (tx->flags != (HTP_PATH_UTF8_OVERLONG | HTP_PATH_FULLWIDTH_EVASION)) {
-                printf("#4 i %x data %x %x %x %x flags %x\n", i, (uint8_t) data[0], (uint8_t) data[1], (uint8_t) data[2], (uint8_t) data[3], tx->flags);
-            }
-        } else {
-            if (tx->flags != HTP_PATH_UTF8_OVERLONG) {
-                printf("#4 i %x data %x %x %x %x flags %x\n", i, (uint8_t) data[0], (uint8_t) data[1], (uint8_t) data[2], (uint8_t) data[3], tx->flags);
-            }
-        }
-    }
-    return (EXIT_SUCCESS);
-}
-
-#define PATH_DECODE_TEST_BEFORE(NAME) \
-    test_name = NAME; \
-    tests++; \
-    expected_status = 0; \
-    expected_flags = -1; \
-    success = 0; \
-    cfg = htp_config_create(); \
-    tx = htp_tx_create(cfg, 0, NULL);
-
-#define PATH_DECODE_TEST_AFTER() \
-    htp_decode_path_inplace(cfg, tx, input); \
-    htp_utf8_decode_path_inplace(cfg, tx, input); \
-    if (bstr_cmp(input, expected) == 0) success = 1; \
-    printf("[%2i] %s: %s\n", tests, (success == 1 ? "SUCCESS" : "FAILURE"), test_name); \
-    if ((success == 0)||((expected_status != 0)&&(expected_status != tx->response_status_expected_number))) { \
-        char *s1 = bstr_tocstr(input); \
-        char *s2 = bstr_tocstr(expected); \
-        printf("      Output: [%s]\n", s1); \
-        printf("    Expected: [%s]\n", s2); \
-        if (expected_status != 0) { \
-            printf("    Expected status %i; got %i\n", expected_status, tx->response_status_expected_number); \
-        } \
-        if (expected_flags != -1) { \
-            printf("    Expected flags 0x%x; got 0x%x\n", expected_flags, tx->flags); \
-        } \
-        free(s2); \
-        free(s1); \
-        failures++; \
-    } \
-    htp_tx_destroy(tx); \
-    htp_config_destroy(cfg); \
-    bstr_free(expected); \
-    bstr_free(input);
-
-
-int main_path_tests(int argc, char** argv) {
-    htp_cfg_t *cfg = NULL;
-    htp_tx_t *tx = NULL;
-    bstr *input = NULL;
-    bstr *expected = NULL;
-    int success = 0;
-    int tests = 0;
-    int failures = 0;        
-    int expected_status = 0;
-    int expected_flags = 0;
-    char *test_name = NULL;
-    
-    PATH_DECODE_TEST_BEFORE("URL-decoding");
-    input = bstr_cstrdup("/%64est");
-    expected = bstr_cstrdup("/dest");    
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid URL-encoded, preserve %");
-    input = bstr_cstrdup("/%xxest");
-    expected = bstr_cstrdup("/%xxest");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid URL-encoded, remove %");
-    input = bstr_cstrdup("/%xxest");
-    expected = bstr_cstrdup("/xxest");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_invalid_encoding_handling = URL_DECODER_REMOVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid URL-encoded (end of string, test 1), preserve %");
-    input = bstr_cstrdup("/test/%2");
-    expected = bstr_cstrdup("/test/%2");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid URL-encoded (end of string, test 2), preserve %");
-    input = bstr_cstrdup("/test/%");
-    expected = bstr_cstrdup("/test/%");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid URL-encoded, preserve % and 400");
-    input = bstr_cstrdup("/%xxest");
-    expected = bstr_cstrdup("/%xxest");
-    expected_status = 400;
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;    
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("%u decoding (expected not to decode; 400)");
-    input = bstr_cstrdup("/%u0064");
-    expected = bstr_cstrdup("/%u0064");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    expected_status = 400;
-    cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("%u decoding (decode; 400)");
-    input = bstr_cstrdup("/%u0064");
-    expected = bstr_cstrdup("/d");
-    expected_status = 400;
-    expected_flags = HTP_PATH_OVERLONG_U;
-    cfg->path_decode_u_encoding = STATUS_400;    
-    PATH_DECODE_TEST_AFTER();   
-
-    PATH_DECODE_TEST_BEFORE("%u decoding (also overlong)");
-    input = bstr_cstrdup("/%u0064");
-    expected = bstr_cstrdup("/d");
-    expected_flags = HTP_PATH_OVERLONG_U;
-    cfg->path_decode_u_encoding = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid %u decoding, leave; preserve percent");
-    input = bstr_cstrdup("/%uXXXX---");
-    expected = bstr_cstrdup("/%uXXXX---");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid %u decoding, decode invalid; preserve percent");
-    input = bstr_cstrdup("/%uXXXX---");
-    expected = bstr_cstrdup("/?---");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_invalid_encoding_handling = URL_DECODER_DECODE_INVALID;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid %u decoding, decode invalid; preserve percent; 400");
-    input = bstr_cstrdup("/%uXXXX---");
-    expected = bstr_cstrdup("/?---");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    expected_status = 400;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid %u decoding (not enough data 1), preserve percent");
-    input = bstr_cstrdup("/%u123");
-    expected = bstr_cstrdup("/%u123");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid %u decoding (not enough data 2), preserve percent");
-    input = bstr_cstrdup("/%u12");
-    expected = bstr_cstrdup("/%u12");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid %u decoding (not enough data 3), preserve percent");
-    input = bstr_cstrdup("/%u1");
-    expected = bstr_cstrdup("/%u1");
-    expected_flags = HTP_PATH_INVALID_ENCODING;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
-    PATH_DECODE_TEST_AFTER();  
-
-    PATH_DECODE_TEST_BEFORE("%u decoding, best-fit mapping");
-    input = bstr_cstrdup("/%u0107");
-    expected = bstr_cstrdup("/c");    
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_unicode_mapping = BESTFIT;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("%u decoding, 404 to UCS-2 characters");
-    input = bstr_cstrdup("/%u0107");
-    expected = bstr_cstrdup("/c");
-    expected_status = 404;
-    cfg->path_decode_u_encoding = YES;
-    cfg->path_unicode_mapping = STATUS_404;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Forward slash (URL-encoded), not expect to decode");
-    input = bstr_cstrdup("/one%2ftwo");
-    expected = bstr_cstrdup("/one%2ftwo");
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Forward slash (URL-encoded), expect to decode");
-    input = bstr_cstrdup("/one%2ftwo");
-    expected = bstr_cstrdup("/one/two");
-    cfg->path_decode_separators = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Forward slash (URL-encoded), expect not do decode and 404");
-    input = bstr_cstrdup("/one%2ftwo");
-    expected = bstr_cstrdup("/one%2ftwo");
-    expected_status = 404;
-    cfg->path_decode_separators = STATUS_404;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Forward slash (%u-encoded), expect to decode");
-    input = bstr_cstrdup("/one%u002ftwo");
-    expected = bstr_cstrdup("/one/two");    
-    cfg->path_decode_separators = YES;
-    cfg->path_decode_u_encoding = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Forward slash (%u-encoded, fullwidth), expect to decode");
-    input = bstr_cstrdup("/one%uff0ftwo");
-    expected = bstr_cstrdup("/one/two");
-    cfg->path_decode_separators = YES;
-    cfg->path_decode_u_encoding = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Backslash (URL-encoded), not a separator; expect to decode");
-    input = bstr_cstrdup("/one%5ctwo");
-    expected = bstr_cstrdup("/one\\two");
-    cfg->path_decode_separators = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Backslash (URL-encoded), as path segment separator");
-    input = bstr_cstrdup("/one%5ctwo");
-    expected = bstr_cstrdup("/one/two");
-    cfg->path_decode_separators = YES;
-    cfg->path_backslash_separators = 1;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Backslash (not encoded), as path segment separator");
-    input = bstr_cstrdup("/one\\two");
-    expected = bstr_cstrdup("/one/two");    
-    cfg->path_backslash_separators = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Backslash (%u-encoded), as path segment separator");
-    input = bstr_cstrdup("/one%u005ctwo");
-    expected = bstr_cstrdup("/one/two");
-    cfg->path_decode_separators = YES;
-    cfg->path_backslash_separators = YES;
-    cfg->path_decode_u_encoding = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Backslash (%u-encoded, fullwidth), as path segment separator");
-    input = bstr_cstrdup("/one%uff3ctwo");
-    expected = bstr_cstrdup("/one/two");
-    cfg->path_decode_separators = YES;
-    cfg->path_backslash_separators = 1;
-    cfg->path_decode_u_encoding = YES;
-    PATH_DECODE_TEST_AFTER();    
-
-    PATH_DECODE_TEST_BEFORE("Invalid UTF-8 encoding, encoded");
-    input = bstr_cstrdup("/%f7test");
-    expected = bstr_cstrdup("/\xf7test");
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Invalid UTF-8 encoding, encoded (400)");
-    input = bstr_cstrdup("/%f7test");
-    expected = bstr_cstrdup("/\xf7test");
-    expected_status = 400;
-    expected_flags = HTP_PATH_UTF8_INVALID;
-    cfg->path_invalid_utf8_handling = STATUS_400;
-    PATH_DECODE_TEST_AFTER();   
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (raw) in path; leave");
-    input = bstr_memdup("/test\0text", 10);
-    expected = bstr_memdup("/test\0text", 10);
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (raw) in path; terminate path");
-    input = bstr_memdup("/test\0text", 10);
-    expected = bstr_cstrdup("/test");
-    cfg->path_nul_raw_handling = TERMINATE;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (raw) in path; 400");
-    input = bstr_memdup("/test\0text", 10);
-    expected = bstr_memdup("/test\0text", 10);
-    cfg->path_nul_raw_handling = STATUS_400;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (URL-encoded) in path; leave");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_memdup("/test\0text", 10);
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (URL-encoded) in path; terminate path");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_cstrdup("/test");
-    cfg->path_nul_encoded_handling = TERMINATE;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (URL-encoded) in path; 400");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_memdup("/test\0text", 10);
-    cfg->path_nul_encoded_handling = STATUS_400;
-    expected_status = 400;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (URL-encoded) in path; 404");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_memdup("/test\0text", 10);
-    cfg->path_nul_encoded_handling = STATUS_404;
-    expected_status = 404;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (%u-encoded) in path; terminate path");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_cstrdup("/test");
-    cfg->path_nul_encoded_handling = TERMINATE;
-    cfg->path_decode_u_encoding = YES;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (%u-encoded) in path; 400");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_memdup("/test\0text", 10);
-    cfg->path_nul_encoded_handling = STATUS_400;
-    cfg->path_decode_u_encoding = YES;
-    expected_status = 400;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("NUL byte (%u-encoded) in path; 404");
-    input = bstr_cstrdup("/test%00text");
-    expected = bstr_memdup("/test\0text", 10);
-    cfg->path_nul_encoded_handling = STATUS_404;
-    cfg->path_decode_u_encoding = YES;
-    expected_status = 404;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Control char in path, encoded (no effect)");
-    input = bstr_cstrdup("/%01test");
-    expected = bstr_cstrdup("/\x01test");
-    cfg->path_control_char_handling = NONE;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Control char in path, raw (no effect)");
-    input = bstr_cstrdup("/\x01test");
-    expected = bstr_cstrdup("/\x01test");
-    cfg->path_control_char_handling = NONE;
-    PATH_DECODE_TEST_AFTER();
-    
-    PATH_DECODE_TEST_BEFORE("Control char in path, encoded (400)");
-    input = bstr_cstrdup("/%01test");
-    expected = bstr_cstrdup("/\x01test");
-    expected_status = 400;
-    cfg->path_control_char_handling = STATUS_400;    
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("Control char in path, raw (400)");
-    input = bstr_cstrdup("/\x01test");
-    expected = bstr_cstrdup("/\x01test");
-    expected_status = 400;
-    cfg->path_control_char_handling = STATUS_400;
-    PATH_DECODE_TEST_AFTER();    
-
-    PATH_DECODE_TEST_BEFORE("UTF-8; overlong 2-byte sequence");
-    input = bstr_cstrdup("/%c1%b4est");
-    expected = bstr_cstrdup("/test");
-    expected_flags = HTP_PATH_UTF8_OVERLONG;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("UTF-8; overlong 3-byte sequence");
-    input = bstr_cstrdup("/%e0%81%b4est");
-    expected = bstr_cstrdup("/test");
-    expected_flags = HTP_PATH_UTF8_OVERLONG;
-    PATH_DECODE_TEST_AFTER();
-
-    PATH_DECODE_TEST_BEFORE("UTF-8; overlong 4-byte sequence");
-    input = bstr_cstrdup("/%f0%80%81%b4est");
-    expected = bstr_cstrdup("/test");
-    expected_flags = HTP_PATH_UTF8_OVERLONG;
-    PATH_DECODE_TEST_AFTER();
-
-    printf("\n");
-    printf("Total tests: %i, %i failure(s).\n", tests, failures);
-
-    return (EXIT_SUCCESS);
-}
diff --git a/libhtp/test/test-tcpick.c b/libhtp/test/test-tcpick.c
deleted file mode 100644 (file)
index f14312a..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <dirent.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include "../htp/htp.h"
-
-#define CLIENT 1
-#define SERVER 2
-
-static int parse_filename(const char *filename, char **remote_addr, char **local_addr) {
-    char *copy = strdup(filename);
-    char *p, *saveptr;
-
-    char *start = copy;
-    char *q = strrchr(copy, '/');
-    if (q != NULL) start = q;
-
-    q = strrchr(start, '\\');
-    if (q != NULL) start = q;
-
-    int count = 0;
-    p = strtok_r(start, "_", &saveptr);
-    while (p != NULL) {
-        count++;
-        // printf("%i %s\n", count, p);
-
-        switch (count) {
-            case 3:
-                *remote_addr = strdup(p);
-                break;
-            case 4:
-                *local_addr = strdup(p);
-                break;
-        }
-
-        p = strtok_r(NULL, "_", &saveptr);
-    }
-
-    free(copy);
-
-    return 0;
-}
-
-static int parse_chunk_info(char *buf, size_t *response_offset, size_t *response_len) {
-    char *p = buf;
-    size_t lastlen;
-
-    while ((*p != ']') && (p != '\0')) p++;
-    if (*p == '\0') return -1;
-    p++;
-
-    while (isspace(*p)) p++;
-
-    *response_offset = bstr_util_memtoip(p, strlen(p), 10, &lastlen);
-
-    p += lastlen;
-
-    while ((*p != '(') && (p != '\0')) p++;
-    if (*p == '\0') return -1;
-    p++;
-
-    *response_len = bstr_util_memtoip(p, strlen(p), 10, &lastlen);
-
-    return 1;
-}
-
-static int tcpick_run_file(const char *filename, htp_cfg_t *cfg, htp_connp_t **connp) {
-    struct timeval tv;
-    char buf[1025];
-    int first = -1, current = -1;
-    char *remote_addr, *local_addr;
-
-    char *request_last_chunk = NULL;
-    char *response_last_chunk = NULL;
-    size_t request_offset, request_len;
-    size_t request_last_offset = 0, request_last_len = 0;
-    size_t response_offset, response_len;
-    size_t response_last_offset = 0, response_last_len = 0;
-
-    if (parse_filename(filename, &remote_addr, &local_addr) < 0) {
-        printf("Failed to parse filename: %s\n", filename);
-        return -1;
-    }
-
-    FILE *f = fopen(filename, "rb");
-    if (f == NULL) {
-        printf("Unable to open file: %s\n", filename);
-        return -1;
-    }
-
-    gettimeofday(&tv, NULL);
-
-    // Create parser
-    *connp = htp_connp_create(cfg);
-
-    // Find all chunks and feed them to the parser
-    while (fgets(buf, 1024, f) != NULL) {
-        // Ignore empty lines
-        if (buf[0] == LF) {
-            continue;
-        }
-
-        if (strncmp(buf, "[server", 7) == 0) {
-            current = SERVER;
-        } else {
-            current = CLIENT;
-        }
-
-        if (first == -1) {
-            first = current;
-
-            if (first == SERVER) {
-                htp_connp_open(*connp, local_addr, 80, remote_addr, 80, tv.tv_usec);
-            } else {
-                htp_connp_open(*connp, remote_addr, 80, local_addr, 80, tv.tv_usec);
-            }
-        }
-
-        int len = 0;
-
-        if (first == current) {
-            if (parse_chunk_info(buf, &request_offset, &request_len) < 0) {
-                printf("Invalid line: %s", buf);
-                fclose(f);
-                htp_connp_destroy_all(*connp);
-                *connp = NULL;
-                return -1;
-            }
-
-            len = request_len;
-
-            // printf("# Request offset %i len %i\n", request_offset, request_len);
-        } else {
-            if (parse_chunk_info(buf, &response_offset, &response_len) < 0) {
-                printf("Invalid line: %s", buf);
-                fclose(f);
-                htp_connp_destroy_all(*connp);
-                *connp = NULL;
-                return -1;
-            }
-
-            len = response_len;
-
-            // printf("# Response offset %i len %i\n", response_offset, response_len);
-        }
-
-        // printf("Len: %i\n", len);
-
-        if (len <= 0) {
-            printf("Invalid length: %i\n", len);
-            fclose(f);
-            htp_connp_destroy_all(*connp);
-            *connp = NULL;
-            return -1;
-        }
-
-        char *data = malloc(len);
-        if (data == NULL) {
-            printf("Failed to allocate %i bytes\n", len);
-            fclose(f);
-            htp_connp_destroy_all(*connp);
-            *connp = NULL;
-            return -1;
-        }
-
-        int read = fread(data, 1, len, f);
-        if (read != len) {
-            // printf("Failed to read %i bytes (got %i)\n", len, read);
-            fclose(f);
-            htp_connp_destroy_all(*connp);
-            *connp = NULL;
-            return -1;
-        }
-
-        if (first == current) {
-            if ((request_last_chunk == NULL) || (request_len != request_last_len) || (memcmp(data, request_last_chunk, request_len) != 0)) {
-                // printf("# Parse request data: %i byte(s)\n", len);
-                if (htp_connp_req_data(*connp, tv.tv_usec, data, len) == HTP_ERROR) {
-                    fclose(f);
-                    return -1;
-                }
-            }
-
-            request_last_offset = request_offset;
-            request_last_len = request_len;
-            if (request_last_chunk != NULL) {
-                free(request_last_chunk);
-            }
-            request_last_chunk = data;
-        } else {
-            if ((response_last_chunk == NULL) || (response_len != response_last_len) || (memcmp(data, response_last_chunk, response_len) != 0)) {
-                // printf("# Parse response data: %i byte(s)\n", len);
-                if (htp_connp_res_data(*connp, tv.tv_usec, data, len) == HTP_ERROR) {
-                    fclose(f);
-                    return -1;
-                }
-            }
-
-            response_last_offset = response_offset;
-            response_last_len = response_len;
-            if (response_last_chunk != NULL) {
-                free(response_last_chunk);
-            }
-            response_last_chunk = data;
-        }
-    }
-
-    fclose(f);
-
-    htp_connp_close(*connp, tv.tv_usec);
-
-    return 1;
-}
-
-static void print_tx(htp_connp_t *connp, htp_tx_t *tx) {
-    char *request_line = bstr_tocstr(tx->request_line);
-    htp_header_t *h_user_agent = table_getc(tx->request_headers, "user-agent");
-    htp_header_t *h_referer = table_getc(tx->request_headers, "referer");
-    char *referer, *user_agent;
-    char buf[256];
-
-    time_t t = time(NULL);
-    struct tm *tmp = localtime(&t);
-
-    strftime(buf, 255, "%d/%b/%Y:%T %z", tmp);
-
-    if (h_user_agent == NULL) user_agent = strdup("-");
-    else {
-        user_agent = bstr_tocstr(h_user_agent->value);
-    }
-
-    if (h_referer == NULL) referer = strdup("-");
-    else {
-        referer = bstr_tocstr(h_referer->value);
-    }
-
-    printf("%s - - [%s] \"%s\" %i %i \"%s\" \"%s\"\n", connp->conn->remote_addr, buf,
-        request_line, tx->response_status_number, tx->response_message_len,
-        referer, user_agent);
-
-    free(referer);
-    free(user_agent);
-    free(request_line);
-}
-
-static int run_file(char *filename, htp_cfg_t *cfg) {
-    htp_connp_t *connp;
-
-    fprintf(stdout, "Running file %s", filename);
-
-    int rc = tcpick_run_file(filename, cfg, &connp);
-    if (rc < 0) {
-        if (connp != NULL) {
-            htp_log_t *last_error = htp_connp_get_last_error(connp);
-            if (last_error != NULL) {
-                printf(" -- failed: %s\n", last_error->msg);
-            } else {
-                printf(" -- failed: ERROR NOT AVAILABLE\n");
-            }
-
-            return 0;
-        } else {
-            return -1;
-        }
-    } else {
-        printf(" -- %i transaction(s)\n", list_size(connp->conn->transactions));
-
-        htp_tx_t *tx = NULL;
-        list_iterator_reset(connp->conn->transactions);
-        while ((tx = list_iterator_next(connp->conn->transactions)) != NULL) {
-            printf("    ");
-            print_tx(connp, tx);
-        }
-
-        printf("\n");
-
-        htp_connp_destroy_all(connp);
-
-        return 1;
-    }
-}
-
-static int run_directory(char *dirname, htp_cfg_t *cfg) {
-    struct dirent *entry;
-    char buf[1025];
-    DIR *d = opendir(dirname);
-
-    if (d == NULL) {
-        printf("Failed to open directory: %s\n", dirname);
-        return -1;
-    }
-
-    while ((entry = readdir(d)) != NULL) {
-        if (strncmp(entry->d_name, "tcpick", 6) == 0) {
-            strncpy(buf, dirname, 1024);
-            strncat(buf, "/", 1024 - strlen(buf));
-            strncat(buf, entry->d_name, 1024 - strlen(buf));
-
-            // fprintf(stderr, "Filename: %s\n", buf);
-            run_file(buf, cfg);
-            //if (run_file(buf, cfg) <= 0) {
-            //    closedir(d);
-            //    return 0;
-            //}
-        }
-    }
-
-    closedir(d);
-
-    return 1;
-}
-
-int main_xxx(int argc, char** argv) {
-    htp_cfg_t *cfg = htp_config_create();
-
-    //run_file("c:/http_traces/run1//tcpick_000015_192.168.1.67_66.249.80.118_www.both.dat", cfg);
-    run_directory("c:/http_traces/run1/", cfg);
-
-    return 0;
-}
diff --git a/libhtp/test/test.c b/libhtp/test/test.c
deleted file mode 100644 (file)
index 16aeef3..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include "../htp/htp.h"
-#include "test.h"
-
-/**
- * Destroys a test.
- *
- * @param test
- */
-static void test_destroy(test_t *test) {
-    if (test->buf != NULL) {
-        free(test->buf);
-        test->buf = NULL;
-    }
-}
-
-/**
- * Checks if there's a chunk boundary at the given position.
- *
- * @param test
- * @param pos
- * @return Zero if there is no boundary, SERVER or CLIENT if a boundary
- *         was found, and a negative value on error (e.g., not enough data
- *         to determine if a boundary is present).
- */
-static int test_is_boundary(test_t *test, int pos) {
-    // Check that there's enough room
-    if (pos + 3 >= test->len) return -1;
-
-    if ((test->buf[pos] == '<') && (test->buf[pos + 1] == '<') && (test->buf[pos + 2] == '<')) {
-        if (test->buf[pos + 3] == '\n') {
-            return SERVER;
-        }
-
-        if (test->buf[pos + 3] == '\r') {
-            if (pos + 4 >= test->len) return -1;
-            else if (test->buf[pos + 4] == '\n') {
-                return SERVER;
-            }
-        }
-    }
-
-    if ((test->buf[pos] == '>') && (test->buf[pos + 1] == '>') && (test->buf[pos + 2] == '>')) {
-        if (test->buf[pos + 3] == '\n') {
-            return CLIENT;
-        }
-
-        if (test->buf[pos + 3] == '\r') {
-            if (pos + 4 >= test->len) return -1;
-            else if (test->buf[pos + 4] == '\n') {
-                return CLIENT;
-            }
-        }
-    }
-
-    return 0;
-}
-
-/**
- * Initializes test by loading the entire data file into a memory block.
- *
- * @param test
- * @param filename
- * @return Non-negative value on success, negative value on error.
- */
-static int test_init(test_t *test, const char *filename) {
-    memset(test, 0, sizeof (test_t));
-
-    int fd = open(filename, O_RDONLY | O_BINARY);
-    if (fd < 0) return -1;
-
-    struct stat buf;
-    if (fstat(fd, &buf) < 0) {
-        return -1;
-    }
-
-    test->buf = malloc(buf.st_size);
-    test->len = 0;
-    test->pos = 0;
-
-    int bytes_read = 0;
-    while ((bytes_read = read(fd, test->buf + test->len, buf.st_size - test->len)) > 0) {
-        test->len += bytes_read;
-    }
-
-    if (test->len != buf.st_size) {
-        free(test->buf);
-        return -2;
-    }
-
-    close(fd);
-
-    return 1;
-}
-
-void test_start(test_t *test) {
-    test->pos = 0;
-}
-
-/**
- * Finds the next data chunk in the given test.
- *
- * @param test
- * @return One if a chunk is found or zero if there are no more chunks in the test. On
- *         success, test->chunk will point to the beginning of the chunk, while
- *         test->chunk_len will contain its length.
- */
-static int test_next_chunk(test_t *test) {
-    if (test->pos >= test->len) {
-        return 0;
-    }
-
-    test->chunk = NULL;
-
-    while (test->pos < test->len) {
-        // Do we need to start another chunk?
-        if (test->chunk == NULL) {
-            // Are we at a boundary
-            test->chunk_direction = test_is_boundary(test, test->pos);
-            if (test->chunk_direction <= 0) {
-                // Error
-                return -1;
-            }
-
-            // Move over the boundary
-            test->pos += 4;
-            if (test->buf[test->pos] == '\n') test->pos++;
-
-            // Start new chunk
-            test->chunk = test->buf + test->pos;
-            test->chunk_offset = test->pos;
-        }
-
-        // Are we at the end of a line?
-        if (test->buf[test->pos] == '\n') {
-            int r = test_is_boundary(test, test->pos + 1);
-            if ((r == CLIENT) || (r == SERVER)) {
-                // We got ourselves a chunk
-                test->chunk_len = test->pos - test->chunk_offset;
-
-                // Remove one '\r' (in addition to the '\n' that we've already removed),
-                // which belongs to the next boundary
-                if ((test->chunk_len > 0) && (test->chunk[test->chunk_len - 1] == '\r')) {
-                    test->chunk_len--;
-                }
-
-                // Position at the next boundary line
-                test->pos++;
-
-                return 1;
-            }
-        }
-
-        test->pos++;
-    }
-
-
-    if (test->chunk != NULL) {
-        test->chunk_len = test->pos - test->chunk_offset;
-        return 1;
-    }
-
-    return 0;
-}
-
-static int parse_filename(const char *filename, char **remote_addr, int *remote_port, char **local_addr, int *local_port) {
-    char *copy = strdup(filename);
-    char *p, *saveptr;
-
-    char *start = copy;
-    char *q = strrchr(copy, '/');
-    if (q != NULL) start = q;
-
-    q = strrchr(start, '\\');
-    if (q != NULL) start = q;
-
-    int count = 0;
-    p = strtok_r(start, "_", &saveptr);
-    while (p != NULL) {
-        count++;
-        // printf("%i %s\n", count, p);
-
-        switch (count) {
-            case 2:
-                *remote_addr = strdup(p);
-                break;
-            case 3:
-                *remote_port = atoi(p);
-                break;
-            case 4:
-                *local_addr = strdup(p);
-            case 5:
-                *local_port = atoi(p);
-                break;
-        }
-
-        p = strtok_r(NULL, "_", &saveptr);
-    }
-
-    free(copy);
-
-    return 0;
-}
-
-/**
- * Runs a single test.
- *
- * @param filename
- * @param cfg
- * @return A pointer to the instance of htp_connp_t created during
- *         the test, or NULL if the test failed for some reason.
- */
-int test_run(const char *testsdir, const char *testname, htp_cfg_t *cfg, htp_connp_t **connp) {
-    char filename[1025];
-    test_t test;
-    struct timeval tv_start, tv_end;
-    int rc;
-
-    *connp = NULL;
-
-    strncpy(filename, testsdir, 1024);
-    strncat(filename, "/", 1024 - strlen(filename));
-    strncat(filename, testname, 1024 - strlen(filename));
-
-    printf("Filename: %s\n", filename);
-
-    // Initinialize test
-
-    rc = test_init(&test, filename);
-    if (rc < 0) {
-        return rc;
-    }
-
-    gettimeofday(&tv_start, NULL);
-
-    test_start(&test);
-
-    // Create parser
-    *connp = htp_connp_create(cfg);
-    if (*connp == NULL) {
-        fprintf(stderr, "Failed to create connection parser\n");
-        exit(1);
-    }
-
-    htp_connp_set_user_data(*connp, (void *) 0x02);
-
-    // Does the filename contain connection metdata?
-    if (strncmp(testname, "stream", 6) == 0) {
-        // It does; use it
-        char *remote_addr, *local_addr;
-        int remote_port, local_port;
-
-        parse_filename(testname, &remote_addr, &remote_port, &local_addr, &local_port);
-        htp_connp_open(*connp, (const char *) remote_addr, remote_port, (const char *) local_addr, local_port, tv_start.tv_usec);
-        free(remote_addr);
-        free(local_addr);
-    } else {
-        // No connection metadata; provide some fake information instead
-        htp_connp_open(*connp, (const char *) "127.0.0.1", 10000, (const char *) "127.0.0.1", 80, tv_start.tv_usec);
-    }
-
-    // Find all chunks and feed them to the parser
-    int in_data_other = 0;
-    char *in_data;
-    size_t in_data_len;
-    size_t in_data_offset;
-
-    int out_data_other = 0;
-    char *out_data;
-    size_t out_data_len;
-    size_t out_data_offset;
-
-    for (;;) {
-        if (test_next_chunk(&test) <= 0) {
-            break;
-        }
-
-        if (test.chunk_direction == CLIENT) {
-            if (in_data_other) {
-                test_destroy(&test);
-                fprintf(stderr, "Unable to buffer more than one inbound chunk.\n");
-                return -1;
-            }
-
-            int rc = htp_connp_req_data(*connp, tv_start.tv_usec, test.chunk, test.chunk_len);
-            if (rc == STREAM_STATE_ERROR) {
-                test_destroy(&test);
-                return -101;
-            }
-            if (rc == STREAM_STATE_DATA_OTHER) {
-                // Parser needs to see the outbound stream in order to continue
-                // parsing the inbound stream.
-                in_data_other = 1;
-                in_data = test.chunk;
-                in_data_len = test.chunk_len;
-                in_data_offset = htp_connp_req_data_consumed(*connp);                
-            }
-        } else {
-            if (out_data_other) {
-                int rc = htp_connp_res_data(*connp, tv_start.tv_usec, out_data + out_data_offset, out_data_len - out_data_offset);
-                if (rc == STREAM_STATE_ERROR) {
-                    test_destroy(&test);
-                    return -104;
-                }
-                out_data_other = 0;
-            }
-
-            int rc = htp_connp_res_data(*connp, tv_start.tv_usec, test.chunk, test.chunk_len);
-            if (rc == STREAM_STATE_ERROR) {
-                test_destroy(&test);
-                return -102;
-            }
-            if (rc == STREAM_STATE_DATA_OTHER) {
-                // Parser needs to see the outbound stream in order to continue
-                // parsing the inbound stream.
-                out_data_other = 1;
-                out_data = test.chunk;
-                out_data_len = test.chunk_len;
-                out_data_offset = htp_connp_res_data_consumed(*connp);
-                // printf("# YYY out offset is %d\n", out_data_offset);
-            }
-
-            if (in_data_other) {
-                int rc = htp_connp_req_data(*connp, tv_start.tv_usec, in_data + in_data_offset, in_data_len - in_data_offset);
-                if (rc == STREAM_STATE_ERROR) {
-                    test_destroy(&test);
-                    return -103;
-                }
-                in_data_other = 0;
-            }
-        }
-    }
-
-    if (out_data_other) {
-        int rc = htp_connp_res_data(*connp, tv_start.tv_usec, out_data + out_data_offset, out_data_len - out_data_offset);
-        if (rc == STREAM_STATE_ERROR) {
-            test_destroy(&test);
-            return -104;
-        }
-        out_data_other = 0;
-    }
-
-    gettimeofday(&tv_end, NULL);
-
-    // Close the connection
-    htp_connp_close(*connp, tv_end.tv_usec);
-
-    // printf("Parsing time: %i\n", tv_end.tv_usec - tv_start.tv_usec);
-
-    // Clean up
-    test_destroy(&test);
-
-    return 1;
-}
diff --git a/libhtp/test/test.h b/libhtp/test/test.h
deleted file mode 100644 (file)
index f9621f4..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * LibHTP (http://www.libhtp.org)
- * Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
- *
- * LibHTP is an open source product, released under terms of the General Public Licence
- * version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
- * of the license.
- *
- * In addition, there is a special exception that allows LibHTP to be freely
- * used with any OSI-approved open source licence. Please refer to the file
- * LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
- *
- */
-
-#ifndef _TEST_H
-#define        _TEST_H
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#define UNKNOWN     0
-#define CLIENT      1
-#define SERVER      2
-
-#ifndef O_BINARY
-#define O_BINARY    0
-#endif
-
-typedef struct test_t test_t;
-
-struct test_t {
-    char *buf;
-    size_t pos;
-    size_t len;
-
-    char *chunk;
-    size_t chunk_offset;
-    size_t chunk_len;
-    int chunk_direction;
-};
-
-int test_run(const char *testsdir, const char *testname, htp_cfg_t *cfg, htp_connp_t **connp);
-
-#endif /* _TEST_H */
-