Update bundled libhtp to libhtp svn tag 0.2.5.

remotes/origin/master-1.1.x
Victor Julien 15 years ago
parent 6e0d98d9c4
commit 3dfed0891f

@ -2,24 +2,18 @@ Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
2006 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
@ -48,7 +42,7 @@ may remove or edit it.
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
@ -59,22 +53,12 @@ of `autoconf'.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
the package.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
@ -83,22 +67,12 @@ of `autoconf'.
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
@ -111,41 +85,25 @@ is an example:
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
@ -156,47 +114,16 @@ Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
@ -208,53 +135,14 @@ find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
@ -262,8 +150,7 @@ type, such as `sun4', or a canonical name which has the form:
where SYSTEM can have one of these forms:
OS
KERNEL-OS
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
@ -281,9 +168,9 @@ eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
@ -292,7 +179,7 @@ A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
@ -311,19 +198,11 @@ an Autoconf bug. Until the bug is fixed you can use this workaround:
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
Print a summary of the options to `configure', and exit.
`--version'
`-V'
@ -350,16 +229,6 @@ operates.
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

@ -29,29 +29,29 @@ 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.
@ -99,7 +99,7 @@ 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.

@ -1,8 +1,7 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS= $(GENERIC_LIBRARY_NAME) test
EXTRA_DIST = ChangeLog COPYING LICENSE LIBHTP_LICENSING_EXCEPTION docs/doxygen.conf docs/QUICK_START
DIST_SUBDIRS = $(GENERIC_LIBRARY_NAME) test
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = htp.pc

@ -56,8 +56,8 @@ AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
AC_CONFIG_MACRO_DIR([m4])
AC_ARG_ENABLE(htp-debug, [ --enable-htp-debug Enable debug output], [ enable_debug=yes ])
if test "$enable_debug" = "yes"; then
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

@ -99,3 +99,4 @@ options:
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.

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@ includedir=${prefix}/include
Name: HTP
Description: HTTP parser
Version: 0.2.3
Version: 0.2.X
Libs: -L${libdir} -lhtp
Cflags: -I${includedir}/htp -I${libdir}/htp/include

@ -5,10 +5,10 @@ c_sources = bstr.c hooks.c htp_config.c htp_connection_parser.c htp_request_apac
library_includedir = $(includedir)/$(GENERIC_LIBRARY_NAME)
library_include_HEADERS = $(h_sources)
INCLUDES = -I. -I$(top_srcdir)
INCLUDES = -I$(top_srcdir)
AM_CFLAGS = -D_GNU_SOURCE -g -O2 -Wall -Wextra -std=gnu99 -pedantic
lib_LTLIBRARIES= libhtp.la
libhtp_la_SOURCES= $(c_sources)
libhtp_la_SOURCES= $(h_sources) $(c_sources)
libhtp_la_LDFLAGS= -version-info $(GENERIC_LIBRARY_VERSION) -release $(GENERIC_RELEASE)
libhtp_la_DEPENDENCIES = $(libhtp_la_SOURCES) ../config.h

@ -76,15 +76,15 @@ bstr *bstr_add_cstr(bstr *destination, char *source) {
* @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) {
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;
}
if (destination == NULL) return NULL;
}
bstr_t *b = (bstr_t *) destination;
memcpy(bstr_ptr(destination) + b->len, data, len);
b->len = b->len + len;
b->len = b->len + len;
return destination;
}
@ -526,7 +526,7 @@ int bstr_indexofmem(bstr *haystack, char *data2, size_t len2) {
// 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;

@ -68,13 +68,13 @@ 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.
*/

@ -148,7 +148,7 @@ static int list_array_push(list_t *_q, void *element) {
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
@ -167,10 +167,10 @@ static int list_array_push(list_t *_q, void *element) {
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;
@ -179,7 +179,7 @@ static int list_array_push(list_t *_q, void *element) {
q->elements[q->last] = element;
q->current_size++;
q->last++;
if (q->last == q->max_size) {
q->last = 0;
@ -260,7 +260,7 @@ static void *list_array_get(list_t *_l, size_t idx) {
* @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;
list_array_t *l = (list_array_t *) _l;
if (idx + 1 > l->current_size) return 0;
@ -368,7 +368,7 @@ table_t *table_create(size_t size) {
free(t);
return NULL;
}
return t;
}
@ -411,7 +411,7 @@ int table_add(table_t *table, bstr *key, void *element) {
bstr *lkey = bstr_dup_lower(key);
if (lkey == NULL) {
return -1;
}
}
// Add key
if (list_add(table->list, lkey) != 1) {
@ -526,18 +526,18 @@ size_t table_size(table_t *table) {
*
* @param table
*/
void table_clear(table_t *table) {
void table_clear(table_t *table) {
// TODO Clear table by removing the existing elements
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);
}
free(table);
}
}
#if 0

@ -27,7 +27,7 @@ htp_hook_t *hook_create() {
if (hook->callbacks == NULL) {
free(hook);
return NULL;
}
}
return hook;
}
@ -75,7 +75,7 @@ void hook_destroy(htp_hook_t *hook) {
}
list_destroy(hook->callbacks);
free(hook);
}
@ -104,12 +104,12 @@ int hook_register(htp_hook_t **hook, int (*callback_fn)()) {
hook_created = 1;
}
// Add callback
// Add callback
if (list_add((*hook)->callbacks, callback) < 0) {
if (hook_created) {
free(*hook);
}
free(callback);
return -1;
}
@ -119,7 +119,7 @@ int hook_register(htp_hook_t **hook, int (*callback_fn)()) {
/**
* Runs all the callbacks associated with a given hook. Only stops if
* one of the callbacks returns an error (HOOK_ERROR).
* one of the callbacks returns an error (HOOK_ERROR).
*
* @param hook
* @param data

@ -35,7 +35,7 @@ struct htp_hook_t {
};
struct htp_callback_t {
int (*fn)();
int (*fn)();
};
int hook_register(htp_hook_t **hook, int (*callback_fn)());

@ -18,7 +18,7 @@
/**
* Returns the library version.
*/
const char *htp_get_version() {
const char *htp_get_version() {
return HTP_BASE_VERSION_TEXT " (r$REVISION_MISSING)";
}

@ -41,7 +41,7 @@ typedef struct htp_urldecoder_t htp_urldecoder_t;
// -- Defines -------------------------------------------------------------------------------------
#define HTP_BASE_VERSION_TEXT "0.2.3"
#define HTP_BASE_VERSION_TEXT "0.2.5"
#define HTP_ERROR -1
#define HTP_OK 0
@ -290,16 +290,16 @@ struct htp_cfg_t {
* 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;
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;
int log_level;
/**
* Server personality ID.
@ -318,12 +318,12 @@ struct htp_cfg_t {
/** 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;
/** Should we treat paths as case insensitive? */
int path_case_insensitive;
@ -365,7 +365,7 @@ struct htp_cfg_t {
unsigned char path_replacement_char;
/** How will the server handle UCS-2 characters? */
int path_unicode_mapping;
int path_unicode_mapping;
/** XXX Unused */
int path_utf8_overlong_handling;
@ -387,6 +387,9 @@ struct htp_cfg_t {
/** 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;
@ -458,17 +461,17 @@ struct htp_conn_t {
list_t *transactions;
/** Log messages associated with this connection. */
list_t *messages;
list_t *messages;
/** Parsing flags: PIPELINED_CONNECTION. */
unsigned int flags;
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;
@ -484,7 +487,7 @@ struct htp_conn_t {
struct htp_connp_t {
// General fields
/** Current parser configuration structure. */
htp_cfg_t *cfg;
@ -498,7 +501,7 @@ struct htp_connp_t {
htp_conn_t *conn;
/** Opaque user data associated with this parser. */
void *user_data;
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,
@ -545,10 +548,10 @@ struct htp_connp_t {
size_t in_line_size;
/** Lenght of the current request line. */
size_t in_line_len;
size_t in_line_len;
/** Ongoing inbound transaction. */
htp_tx_t *in_tx;
htp_tx_t *in_tx;
/** The request header line currently being processed. */
htp_header_line_t *in_header_line;
@ -616,8 +619,8 @@ struct htp_connp_t {
size_t out_line_size;
/** Lenght of the current response line. */
size_t out_line_len;
size_t out_line_len;
/** Ongoing outbound transaction */
htp_tx_t *out_tx;
@ -701,7 +704,7 @@ struct htp_header_line_t {
/** Parsing flags: HTP_FIELD_INVALID_NOT_FATAL, HTP_FIELD_INVALID_FATAL, HTP_FIELD_LONG */
unsigned int flags;
/** Header that uses this line. */
htp_header_t *header;
};
@ -711,7 +714,7 @@ struct htp_header_t {
bstr *name;
/** Header value. */
bstr *value;
bstr *value;
/** Parsing flags: HTP_FIELD_INVALID_NOT_FATAL, HTP_FIELD_FOLDED, HTP_FIELD_REPEATED */
unsigned int flags;
@ -735,7 +738,7 @@ struct htp_tx_t {
/** The user data associated with this transaction. */
void *user_data;
// Request
unsigned int request_ignored_lines;
@ -773,7 +776,7 @@ struct htp_tx_t {
int request_protocol_number;
/** Is this request using a short-style HTTP/0.9 request? */
int protocol_is_simple;
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
@ -817,7 +820,7 @@ struct htp_tx_t {
* 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;
size_t request_filedata_len;
/** Original request header lines. This list stores instances of htp_header_line_t. */
list_t *request_header_lines;
@ -873,7 +876,7 @@ struct htp_tx_t {
bstr *response_message;
/** Have we seen the server respond with a 100 response? */
int seen_100continue;
int seen_100continue;
/** Original response header lines. */
list_t *response_header_lines;
@ -899,8 +902,8 @@ struct htp_tx_t {
int response_transfer_coding;
/** Compression; currently COMPRESSION_NONE or COMPRESSION_GZIP. */
int response_content_encoding;
int response_content_encoding;
// Common
/** Parsing flags: HTP_INVALID_CHUNKING, HTP_INVALID_FOLDING,
@ -963,10 +966,11 @@ 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_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 *));

@ -178,6 +178,14 @@ htp_cfg_t *htp_config_copy(htp_cfg_t *cfg) {
}
}
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) {
@ -209,7 +217,7 @@ htp_cfg_t *htp_config_copy(htp_cfg_t *cfg) {
return NULL;
}
}
if (cfg->hook_response_line != NULL) {
copy->hook_response_line = hook_copy(cfg->hook_response_line);
if (copy->hook_response_line == NULL) {
@ -263,13 +271,14 @@ htp_cfg_t *htp_config_copy(htp_cfg_t *cfg) {
/**
* 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);
@ -287,9 +296,9 @@ void htp_config_destroy(htp_cfg_t *cfg) {
/**
* Registers a transaction_start callback.
*
*
* @param cfg
* @param callback_fn
* @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);
@ -299,17 +308,27 @@ void htp_config_register_transaction_start(htp_cfg_t *cfg, int (*callback_fn)(ht
* Registers a request_line callback.
*
* @param cfg
* @param callback_fn
* @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
* @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);
@ -319,7 +338,7 @@ void htp_config_register_request_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_
* Registers a request_trailer callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -329,7 +348,7 @@ void htp_config_register_request_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_
* Registers a request_body_data callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -339,7 +358,7 @@ void htp_config_register_request_body_data(htp_cfg_t *cfg, int (*callback_fn)(ht
* Registers a request callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -349,7 +368,7 @@ void htp_config_register_request(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t
* Registers a request_line callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -359,7 +378,7 @@ void htp_config_register_response_line(htp_cfg_t *cfg, int (*callback_fn)(htp_co
* Registers a request_headers callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -369,7 +388,7 @@ void htp_config_register_response_headers(htp_cfg_t *cfg, int (*callback_fn)(htp
* Registers a request_trailer callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -379,7 +398,7 @@ void htp_config_register_response_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp
* Registers a request_body_data callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -389,7 +408,7 @@ void htp_config_register_response_body_data(htp_cfg_t *cfg, int (*callback_fn)(h
* Registers a request callback.
*
* @param cfg
* @param callback_fn
* @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);
@ -509,7 +528,7 @@ void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int 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.
* will be treated as invalid URL encoding if decoding is not desireable.
*
* @param cfg
* @param decode_u_encoding
@ -653,11 +672,11 @@ int htp_config_set_server_personality(htp_cfg_t *cfg, int personality) {
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_invalid_encoding_handling = URL_DECODER_STATUS_400;
cfg->path_control_char_handling = NONE;
break;
@ -704,13 +723,13 @@ int htp_config_set_server_personality(htp_cfg_t *cfg, int personality) {
cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
cfg->path_control_char_handling = STATUS_400;
break;
default:
return HTP_ERROR;
}
// Remember the personality
cfg->spersonality = personality;
cfg->spersonality = personality;
return HTP_OK;
}

@ -53,7 +53,7 @@ htp_conn_t *htp_conn_create(htp_connp_t *connp) {
*/
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
@ -65,7 +65,7 @@ void htp_conn_destroy(htp_conn_t *conn) {
htp_tx_destroy(tx);
}
}
list_destroy(conn->transactions);
// Destroy individual messages
@ -85,7 +85,7 @@ void htp_conn_destroy(htp_conn_t *conn) {
if (conn->remote_addr != NULL) {
free(conn->remote_addr);
}
// Finally, destroy the connection
// structure itself.
free(conn);

@ -203,7 +203,7 @@ void htp_connp_destroy_all(htp_connp_t *connp) {
/**
* Retrieve the user data associated with this connection parser.
*
*
* @param connp
* @return User data, or NULL if there isn't any.
*/

@ -132,7 +132,7 @@ static int htp_gzip_decompressor_decompress(htp_decompressor_gzip_t *drec, htp_t
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);
@ -140,7 +140,7 @@ static int htp_gzip_decompressor_decompress(htp_decompressor_gzip_t *drec, htp_t
return -1;
}
// TODO Handle trailer
// TODO Handle trailer
return 1;
}

@ -41,7 +41,7 @@ struct htp_decompressor_gzip_t {
uint8_t header_len;
z_stream stream;
unsigned char *buffer;
unsigned long crc;
unsigned long crc;
};
htp_decompressor_t * htp_gzip_decompressor_create(htp_connp_t *connp);

@ -18,7 +18,7 @@
* 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.
*/

@ -339,7 +339,7 @@ int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp) {
connp->in_tx->progress = TX_PROGRESS_WAIT;
}
// Host resolution
// Host resolution
htp_header_t *h = table_getc(connp->in_tx->request_headers, "host");
if (h == NULL) {
// No host information in the headers
@ -430,7 +430,7 @@ int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
// Cleanup
free(connp->in_header_line);
connp->in_line_len = 0;
connp->in_header_line = NULL;
connp->in_header_line = NULL;
// We've seen all request headers
if (connp->in_chunk_count != connp->in_chunk_request_index) {
@ -495,7 +495,7 @@ int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
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;
@ -598,32 +598,40 @@ int htp_connp_REQ_LINE(htp_connp_t *connp) {
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->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
@ -665,7 +673,7 @@ int htp_connp_REQ_LINE(htp_connp_t *connp) {
if (connp->in_tx->parsed_uri->path == NULL) {
return HTP_ERROR;
}
}
}
}
// Run hook REQUEST_LINE
@ -759,7 +767,7 @@ size_t htp_connp_req_data_consumed(htp_connp_t *connp) {
/**
* Process a chunk of inbound (client or request) data.
*
*
* @param connp
* @param timestamp
* @param data

@ -102,7 +102,7 @@ int htp_process_request_header_apache_2_2(htp_connp_t *connp) {
free(h->value);
free(h);
// Keep track of same-name headers
// Keep track of same-name headers
h_existing->flags |= HTP_FIELD_REPEATED;
} else {
// Add as a new header

@ -108,7 +108,7 @@ int htp_process_request_header_generic(htp_connp_t *connp) {
free(h->value);
free(h);
// Keep track of same-name headers
// Keep track of same-name headers
h_existing->flags |= HTP_FIELD_REPEATED;
} else {
// Add as a new header
@ -135,15 +135,15 @@ int htp_parse_request_header_generic(htp_connp_t *connp, htp_header_t *h, unsign
size_t name_start, name_end;
size_t value_start, value_end;
htp_chomp(data, &len);
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;
@ -200,7 +200,7 @@ int htp_parse_request_header_generic(htp_connp_t *connp, htp_header_t *h, unsign
// Look for the end of field-content
value_end = value_start;
while (value_end < len) value_end++;
// Ignore LWS after field-content

@ -99,7 +99,7 @@ htp_header_t *htp_connp_header_parse(htp_connp_t *reqp, unsigned char *data, siz
htp_header_t *h = calloc(1, sizeof (htp_header_t));
if (h == NULL) return NULL;
// Parse the header line
// Parse the header line
if (reqp->impl_header_parse(data, len, h) < 0) {
// Invalid header line
h->is_parsed = 0;

@ -72,7 +72,7 @@ int htp_connp_RES_BODY_CHUNKED_DATA(htp_connp_t *connp) {
for (;;) {
OUT_NEXT_BYTE(connp);
if (connp->out_next_byte == -1) {
if (connp->out_next_byte == -1) {
if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {
connp->out_decompressor->decompress(connp->out_decompressor, &d);
} else {
@ -95,7 +95,7 @@ int htp_connp_RES_BODY_CHUNKED_DATA(htp_connp_t *connp) {
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 {
@ -180,7 +180,7 @@ int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp) {
// Send data to callbacks
if (d.len != 0) {
if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {
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);
@ -189,7 +189,7 @@ int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp) {
"Response body data callback returned error (%d)", rc);
return HTP_ERROR;
}
}
}
}
// If we don't know the length, then we must check
@ -219,7 +219,7 @@ int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp) {
// Send data to callbacks
if (d.len != 0) {
if (connp->out_tx->response_content_encoding != COMPRESSION_NONE) {
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);
@ -312,7 +312,7 @@ int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
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
// There's no response body
connp->out_state = htp_connp_RES_IDLE;
} else {
// We have a response body
@ -463,7 +463,7 @@ int htp_connp_RES_HEADERS(htp_connp_t *connp) {
// Cleanup
free(connp->out_header_line);
connp->out_line_len = 0;
connp->out_header_line = NULL;
connp->out_header_line = NULL;
// We've seen all response headers
if (connp->out_tx->progress == TX_PROGRESS_RES_HEADERS) {
@ -490,7 +490,7 @@ int htp_connp_RES_HEADERS(htp_connp_t *connp) {
// Check for header folding
if (htp_connp_is_line_folded(connp->out_line, connp->out_line_len) == 0) {
// New header line
// New header line
// Parse previous header, if any
if (connp->out_header_line_index != -1) {
@ -671,7 +671,7 @@ int htp_connp_RES_IDLE(htp_connp_t * connp) {
// Parsing a new response
// Find the next outgoing transaction
// 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,

@ -16,7 +16,7 @@
/**
* Generic response line parser.
*
*
* @param connp
* @return HTP status
*/
@ -77,13 +77,13 @@ int htp_parse_response_line_generic(htp_connp_t *connp) {
#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
@ -198,7 +198,7 @@ int htp_parse_response_header_generic(htp_connp_t *connp, htp_header_t *h, char
/**
* Generic response header line(s) processor, which assembles folded lines
* into a single buffer before invoking the parsing function.
*
*
* @param connp
* @return HTP status
*/
@ -209,7 +209,7 @@ int htp_process_response_header_generic(htp_connp_t *connp) {
// Parse header
htp_header_t *h = calloc(1, sizeof (htp_header_t));
if (h == NULL) return HTP_ERROR;
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) {

@ -96,7 +96,7 @@ void htp_tx_destroy(htp_tx_t *tx) {
list_destroy(tx->request_header_lines);
// Destroy request_headers
// Destroy request_headers
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
while (table_iterator_next(tx->request_headers, (void **) & h) != NULL) {
@ -127,7 +127,7 @@ void htp_tx_destroy(htp_tx_t *tx) {
}
list_destroy(tx->response_header_lines);
// Destroy response headers
// Destroy response headers
h = NULL;
table_iterator_reset(tx->response_headers);
while (table_iterator_next(tx->response_headers, (void **) & h) != NULL) {
@ -154,7 +154,7 @@ void htp_tx_destroy(htp_tx_t *tx) {
}
/**
* Returns the user data associated with this transaction.
* Returns the user data associated with this transaction.
*
* @param tx
* @return A pointer to user data or NULL
@ -182,5 +182,5 @@ void htp_tx_set_config(htp_tx_t *tx, htp_cfg_t *cfg, int is_cfg_shared) {
* @param user_data
*/
void htp_tx_set_user_data(htp_tx_t *tx, void *user_data) {
tx->user_data = user_data;
tx->user_data = user_data;
}

@ -198,7 +198,7 @@ int htp_is_line_empty(unsigned char *data, size_t len) {
/**
* Does line consist entirely of whitespace characters?
*
*
* @param data
* @param len
* @return 0 or 1
@ -241,7 +241,7 @@ int htp_parse_chunked_length(unsigned char *data, size_t len) {
/**
* 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
@ -271,7 +271,7 @@ int htp_parse_positive_integer_whitespace(unsigned char *data, size_t len, int b
/**
* Prints one log message to stderr.
*
*
* @param log
*/
void htp_print_log(FILE *stream, htp_log_t *log) {
@ -286,7 +286,7 @@ void htp_print_log(FILE *stream, htp_log_t *log) {
/**
* Records one log message.
*
*
* @param connp
* @param file
* @param line
@ -428,7 +428,7 @@ int htp_parse_authority(htp_connp_t *connp, bstr *authority, htp_uri_t **uri) {
// 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
// Valid port
(*uri)->port_number = port;
} else {
htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Invalid authority port");
@ -440,7 +440,7 @@ int htp_parse_authority(htp_connp_t *connp, bstr *authority, htp_uri_t **uri) {
/**
* Parses request URI, making no attempt to validate the contents.
*
*
* @param input
* @param uri
* @return HTP_ERROR on memory allocation failure, HTP_OK otherwise
@ -467,7 +467,7 @@ int htp_parse_uri(bstr *input, htp_uri_t **uri) {
// 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
// Parse scheme
// Find the colon, which marks the end of the scheme part
start = pos;
@ -1722,7 +1722,7 @@ char *htp_tx_progress_as_string(htp_tx_t *tx) {
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;
@ -1744,11 +1744,11 @@ bstr *htp_unparse_uri_noencode(htp_uri_t *uri) {
}
len += 1; // "@"
}
}
if (uri->hostname != NULL) {
len += bstr_len(uri->hostname);
}
}
if (uri->port != NULL) {
len += 1; // ":"
@ -1767,18 +1767,18 @@ bstr *htp_unparse_uri_noencode(htp_uri_t *uri) {
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) {
@ -1792,20 +1792,20 @@ bstr *htp_unparse_uri_noencode(htp_uri_t *uri) {
}
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);
@ -1813,13 +1813,13 @@ bstr *htp_unparse_uri_noencode(htp_uri_t *uri) {
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;
}

@ -16,7 +16,7 @@
#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

@ -8,3 +8,5 @@ AM_CFLAGS = -g -O2
#check: all
# ./main

@ -1,5 +1,5 @@
>>>
GET / HTTP/1.0
GET /?p=%20 HTTP/1.0
User-Agent: Mozilla

@ -31,3 +31,4 @@ Transfer-Encoding: chunked
1
9
0

@ -29,3 +29,4 @@ Location: https://www.feistyduck.com/
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=iso-8859-1

@ -37,7 +37,7 @@ int test_get(htp_cfg_t *cfg) {
return -1;
}
htp_connp_destroy_all(connp);
htp_connp_destroy_all(connp);
return 1;
}
@ -509,7 +509,7 @@ int test_connect_complete(htp_cfg_t *cfg) {
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);
@ -637,7 +637,7 @@ int callback_response_trailer(htp_connp_t *connp) {
}
int callback_response(htp_connp_t *connp) {
printf("-- Callback: response\n");
printf("-- Callback: response\n");
}
int callback_response_destroy(htp_connp_t *connp) {
@ -645,7 +645,7 @@ int callback_response_destroy(htp_connp_t *connp) {
printf("-- Destroyed transaction\n");
}
int callback_log(htp_log_t *log) {
int callback_log(htp_log_t *log) {
htp_print_log(stdout, log);
}
@ -692,7 +692,7 @@ static int run_directory(char *dirname, htp_cfg_t *cfg) {
}
while ((entry = readdir(d)) != NULL) {
if (strncmp(entry->d_name, "stream", 6) == 0) {
if (strncmp(entry->d_name, "stream", 6) == 0) {
int rc = test_run(dirname, entry->d_name, cfg, &connp);
if (rc < 0) {
@ -734,10 +734,10 @@ 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);
}
@ -819,24 +819,24 @@ int main(int argc, char** argv) {
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_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);
@ -1042,14 +1042,14 @@ int main_path_tests(int argc, char** argv) {
bstr *expected = NULL;
int success = 0;
int tests = 0;
int failures = 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");
expected = bstr_cstrdup("/dest");
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("Invalid URL-encoded, preserve %");
@ -1085,7 +1085,7 @@ int main_path_tests(int argc, char** argv) {
expected = bstr_cstrdup("/%xxest");
expected_status = 400;
expected_flags = HTP_PATH_INVALID_ENCODING;
cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("%u decoding (expected not to decode; 400)");
@ -1101,8 +1101,8 @@ int main_path_tests(int argc, char** argv) {
expected = bstr_cstrdup("/d");
expected_status = 400;
expected_flags = HTP_PATH_OVERLONG_U;
cfg->path_decode_u_encoding = STATUS_400;
PATH_DECODE_TEST_AFTER();
cfg->path_decode_u_encoding = STATUS_400;
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("%u decoding (also overlong)");
input = bstr_cstrdup("/%u0064");
@ -1158,11 +1158,11 @@ int main_path_tests(int argc, char** argv) {
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_AFTER();
PATH_DECODE_TEST_BEFORE("%u decoding, best-fit mapping");
input = bstr_cstrdup("/%u0107");
expected = bstr_cstrdup("/c");
expected = bstr_cstrdup("/c");
cfg->path_decode_u_encoding = YES;
cfg->path_unicode_mapping = BESTFIT;
PATH_DECODE_TEST_AFTER();
@ -1195,7 +1195,7 @@ int main_path_tests(int argc, char** argv) {
PATH_DECODE_TEST_BEFORE("Forward slash (%u-encoded), expect to decode");
input = bstr_cstrdup("/one%u002ftwo");
expected = bstr_cstrdup("/one/two");
expected = bstr_cstrdup("/one/two");
cfg->path_decode_separators = YES;
cfg->path_decode_u_encoding = YES;
PATH_DECODE_TEST_AFTER();
@ -1222,7 +1222,7 @@ int main_path_tests(int argc, char** argv) {
PATH_DECODE_TEST_BEFORE("Backslash (not encoded), as path segment separator");
input = bstr_cstrdup("/one\\two");
expected = bstr_cstrdup("/one/two");
expected = bstr_cstrdup("/one/two");
cfg->path_backslash_separators = YES;
PATH_DECODE_TEST_AFTER();
@ -1240,7 +1240,7 @@ int main_path_tests(int argc, char** argv) {
cfg->path_decode_separators = YES;
cfg->path_backslash_separators = 1;
cfg->path_decode_u_encoding = YES;
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("Invalid UTF-8 encoding, encoded");
input = bstr_cstrdup("/%f7test");
@ -1253,7 +1253,7 @@ int main_path_tests(int argc, char** argv) {
expected_status = 400;
expected_flags = HTP_PATH_UTF8_INVALID;
cfg->path_invalid_utf8_handling = STATUS_400;
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("NUL byte (raw) in path; leave");
input = bstr_memdup("/test\0text", 10);
@ -1331,12 +1331,12 @@ int main_path_tests(int argc, char** argv) {
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;
cfg->path_control_char_handling = STATUS_400;
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("Control char in path, raw (400)");
@ -1344,7 +1344,7 @@ int main_path_tests(int argc, char** argv) {
expected = bstr_cstrdup("/\x01test");
expected_status = 400;
cfg->path_control_char_handling = STATUS_400;
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_AFTER();
PATH_DECODE_TEST_BEFORE("UTF-8; overlong 2-byte sequence");
input = bstr_cstrdup("/%c1%b4est");

@ -314,7 +314,7 @@ int test_run(const char *testsdir, const char *testname, htp_cfg_t *cfg, htp_con
in_data_other = 1;
in_data = test.chunk;
in_data_len = test.chunk_len;
in_data_offset = htp_connp_req_data_consumed(*connp);
in_data_offset = htp_connp_req_data_consumed(*connp);
}
} else {
if (out_data_other) {

Loading…
Cancel
Save