diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-12-14 06:48:15 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-12-14 06:48:15 +0100 |
commit | 86b0f9ddb6407baa394e548e80748ec6e9b120e6 (patch) | |
tree | ed44dc9cbb7614a0ca6b8b77da08eca485452fc7 | |
parent | 7c68632107e2b42db5fbb7d032f5d957e99be7f9 (diff) | |
parent | a55a225899dbd47dd4238adf3a49f62846cb87f9 (diff) |
Merge tag 'upstream/1.0.0'
Upstream version 1.0.0
-rw-r--r-- | .travis.yml | 41 | ||||
-rw-r--r-- | README.md | 108 | ||||
-rw-r--r-- | changelog | 39 | ||||
-rw-r--r-- | conf/bitz-server.conf.in | 8 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | doc/bitz-server.conf.man | 4 | ||||
-rw-r--r-- | doc/bitz-server.man | 6 | ||||
-rw-r--r-- | doc/doxygen.cfg.in | 1612 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/icap/Makefile.am | 4 | ||||
-rw-r--r-- | lib/icap/util.cpp | 127 | ||||
-rw-r--r-- | lib/icap/util.h | 34 | ||||
-rw-r--r-- | lib/socket/Makefile.am | 4 | ||||
-rw-r--r-- | lib/socket/socket.cpp | 472 | ||||
-rw-r--r-- | lib/socket/socket.h | 427 | ||||
-rw-r--r-- | modules/modpy/modules/modpy.py | 8 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/bitz-server.cpp | 4 | ||||
-rw-r--r-- | src/bitz-server.h | 3 | ||||
-rw-r--r-- | src/bitz/config.cpp | 11 | ||||
-rw-r--r-- | src/bitz/config.h | 1 | ||||
-rw-r--r-- | src/bitz/manager.cpp | 40 | ||||
-rw-r--r-- | src/bitz/manager.h | 14 | ||||
-rw-r--r-- | src/bitz/options_request_handler.cpp | 2 | ||||
-rw-r--r-- | src/bitz/options_request_handler.h | 2 | ||||
-rw-r--r-- | src/bitz/request_handler.cpp | 6 | ||||
-rw-r--r-- | src/bitz/request_handler.h | 8 | ||||
-rw-r--r-- | src/bitz/worker.cpp | 139 | ||||
-rw-r--r-- | src/bitz/worker.h | 6 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | test/icap-client.py | 40 |
31 files changed, 406 insertions, 2786 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..32341e9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,41 @@ +language: cpp + +sudo: false + +addons: + apt: + packages: + - liblog4cpp5-dev + +compiler: + - gcc + - clang + +before_install: + - echo $LANG + - echo $LC_ALL + - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install libconfig log4cpp; fi + +install: + - curl -L https://github.com/nukedzn/psocksxx/releases/download/v1.0.0/psocksxx-1.0.0.tar.gz | tar -zx -C /tmp + - cd /tmp/psocksxx-* && ./configure --prefix=/tmp/root && make && make install + - if [ $TRAVIS_OS_NAME == linux ]; then curl -L http://www.hyperrealm.com/libconfig/libconfig-1.4.9.tar.gz | tar -zx -C /tmp; fi + - if [ $TRAVIS_OS_NAME == linux ]; then cd /tmp/libconfig-* && ./configure --prefix=/tmp/root && make && make install; fi + - cd ${TRAVIS_BUILD_DIR} + +before_script: + - if [ $TRAVIS_OS_NAME == linux ]; then libtoolize; fi + - if [ $TRAVIS_OS_NAME == osx ]; then glibtoolize; fi + - aclocal + - autoheader + - autoconf + - automake --add-missing + - export PKG_CONFIG_PATH=/tmp/root/lib/pkgconfig && ./configure + +script: + - make distcheck + +os: + - linux + - osx + @@ -1,11 +1,14 @@ bitz-server =========== +[![Build Status](https://travis-ci.org/uditha-atukorala/bitz-server.svg)](https://travis-ci.org/uditha-atukorala/bitz-server) + An ICAP server implementation in C++ -### Copyright and License -Copyright (C) 2012-2013 Uditha Atukorala. +## Copyright and License + +Copyright (C) 2012-2015 Uditha Atukorala. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,7 +22,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the for more details. -### The concept +## The concept The main goal of this project is to create an ICAP server ([RFC 3507](http://www.ietf.org/rfc/rfc3507.txt)) implementation in C++ @@ -35,124 +38,59 @@ scanning etc. and to make it easier to write (and faster to implement) such modu there is hope to exploit python programming language. -### Acknowledgements +## Acknowledgements * Many thanks to Kenneth Oksanen for his support in finding and fixing bugs -### Downloads -You can download the source distributions from http://packages.geniusse.com/source/bitz-server/. - - -#### Debian/Ubuntu packages -First you should add the repository key to avoid warning. - - $ wget -q -O - http://packages.geniusse.com/debian/packman.gpg.key | sudo apt-key add - - -Then add the following to your `/etc/apt/sources.list`; - - $ deb http://packages.geniusse.com/debian/ [release] main +## Downloads -where the `[release]` being wheezy, jessie, sid etc. +You can download the source distributions from https://github.com/uditha-atukorala/bitz-server/releases. -Finally update your package list and install bitz-server; - $ sudo aptitude update - $ sudo aptitude install bitz-server - - -### Dependencies +## Dependencies +* [psocksxx >= 0.0.6](https://nukedzn.github.io/psocksxx/) * [libconfig++ >= 1.4](http://www.hyperrealm.com/libconfig/) * log4cpp >= 1.0 * python 2.7 (for modpy module) -### Bugs and Feature Requests - -Please report all bugs and feature requests [here](http://bugs.geniusse.com/) under the -[bitz-server](http://bugs.geniusse.com/enter_bug.cgi?product=bitz-server) project. -Known issues can be found [here](http://bugs.geniusse.com/buglist.cgi?query_format=specific&order=relevance%20desc&bug_status=__open__&product=bitz-server&list_id=36). - - -### Version history - -__0.1.6__ - _28th September 2013_ -* Few tweaks and minor changes distribution files (no functional changes) +## Bugs and Feature Requests -__0.1.5__ - _11th August 2013_ -* Fixing modpy interface module string copy bug +Please report all bugs and feature requests under [issues](https://github.com/uditha-atukorala/bitz-server/issues). -__0.1.4__ - _01st August 2013_ -* Code optimisations -* Fixing bug [#34](http://bugs.geniusse.com/show_bug.cgi?id=34) -__0.1.3__ - _29th July 2013_ -* Fixing bugs - [#31](http://bugs.geniusse.com/show_bug.cgi?id=31), - [#32](http://bugs.geniusse.com/show_bug.cgi?id=32) +## Compiling from source -__0.1.2__ - _07th July 2013_ -* Added a RESPMOD handler ([bug #16](http://bugs.geniusse.com/show_bug.cgi?id=16)) -* Added Message Preview features ([bug #17](http://bugs.geniusse.com/show_bug.cgi?id=17)) -* Code cleanup and optimisations -* Fixing bugs [#15](http://bugs.geniusse.com/show_bug.cgi?id=15), - [#23](http://bugs.geniusse.com/show_bug.cgi?id=23), - [#24](http://bugs.geniusse.com/show_bug.cgi?id=24), - [#25](http://bugs.geniusse.com/show_bug.cgi?id=25) - -__0.1.1__ - _06th March 2013_ -* Fixing bugs [#19](http://bugs.geniusse.com/show_bug.cgi?id=19) and [#22](http://bugs.geniusse.com/show_bug.cgi?id=22) - -__0.1.0__ - _03rd March 2013_ - -* Daemonized version ([bug #18](http://bugs.geniusse.com/show_bug.cgi?id=18)), hence - the minor version bump. Server core is re-organised with bitz::server namespace to - be more cleaner and easier to read. -* Make it possible to pass in command-line options -* Closed a memory leak in modpy module -* Fixing bugs [#20](http://bugs.geniusse.com/show_bug.cgi?id=20) and [#21](http://bugs.geniusse.com/show_bug.cgi?id=21) - - -__0.0.1__ - _24th February 2013_ - -* Proof of concept. An ICAP server with only a REQMOD handler. Includes a template - _echo_ module to demonstrate the pluggable module architecture and the _modpy_ module - to demonstrate the python interface. - ---------------------------------------- - - -### Compiling from source - -First you need to initialise the autotools +If you are using the github source then first you need to initialise autotools. $ libtoolize (glibtoolize in OS X) $ aclocal $ autoheader $ autoconf - $ automake --add-missing --foreign - -Or you can grab the latest source distribution tar from [CI artifacts](http://jenkins.geniusse.com/job/bitz-server/). + $ automake --add-missing After that you can use the usual `./configure && make` -#### Notes -##### modpy +-------------------------------------------------------------------------------- + +### Notes +#### modpy This is the (long awaited) python interface module. It provides a template for any other python interface module implementations either as C++ module template or as a C++ interface for python modules. -##### Debugging +#### Debugging Use the following to create the binaries with debug symbols $ ./configure CXXFLAGS="-g -O0" -##### config file +#### config file The default config file location is `/etc/bitz/bitz-server.conf` but this can changed using the `--with-config` option when you run `configure`. @@ -162,7 +100,7 @@ e.g. $ ./configure --with-config=/[path to source code]/conf/bitz-server.conf -##### valgrind checks +#### valgrind checks $ valgrind --leak-check=full --read-var-info=yes --trace-children=yes --suppressions=test/valgrind.supp --log-file=valgrind.log ./src/bitz-server --debug @@ -1,33 +1,46 @@ +1.0.0 - 25th November 2015 + * [New] Configurable communication (socket) timeouts + * [New] Support for persistent connections + * [New] Use psocksxx as the socket library + * Code restructure + * Updated man pages + * Fix issue #2 + 0.1.6 - 28th September 2013 - * Few tweaks and minor changes distribution files (no functional changes) + * Few tweaks and minor changes to distribution files (no functional changes) 0.1.5 - 11th August 2013 - * Fixing modpy interface module string copy bug + * Fix modpy interface module string copy bug 0.1.4 - 01st August 2013 * Code optimisations - * Fixing bug #34 + * Make sure all the data requested is read in icap::util::read_data() + (found by Kenneth Oksanen) 0.1.3 - 29th July 2013 - * Fixing bugs #31, #32 + * Fix char buffers (found by Kenneth Oksanen) + * Fix modpy module to handle null-characters properly (found by Kenneth + Oksanen) 0.1.2 - 07th July 2013 - * Added a RESPMOD handler (bug #16) - * Added Message Preview features (bug #17) + * [New] RESPMOD handler + * [New] Message Preview features * Code cleanup and optimisations - * Fixing bugs #15, #23, #24, #25 + * Stop workers from segfaulting when modifier modules aren't loaded + * Minor bug fixes 0.1.1 - 06th March 2013 - * Fixing bugs #19 and #22 + * Remove hard coded file paths in daemonized code + * Fix `make install` to not to install empty log files 0.1.0 - 03rd March 2013 - * Daemonized version (bug #18), hence the minor version bump. Server - core is re-organised with bitz::server namespace to be more cleaner - and easier to read. + * Daemonized version (hence the minor version bump), + Server core is re-organised with bitz::server namespace to be more cleaner + and easier to read, * Make it possible to pass in command-line options * Closed a memory leak in modpy module - * Fixing bugs #20, #21 - + * Make workers (child processes) and max requests per worker configurable + * Man pages 0.0.1 - 24th February 2013 * Proof of concept. An ICAP server with only a REQMOD handler. Includes diff --git a/conf/bitz-server.conf.in b/conf/bitz-server.conf.in index 95083c4..416a555 100644 --- a/conf/bitz-server.conf.in +++ b/conf/bitz-server.conf.in @@ -14,6 +14,10 @@ max_workers = 1; # maximum number of requests a worker will serve max_worker_requests = 100; +# communication timeout value in seconds. set this value to +# be 0 to disable timeouts. +comm_timeout = 5; + # request handlers req_handlers : @@ -26,7 +30,7 @@ req_handlers : name = "modpy"; module = "@pkglibdir@/modules/mod_py.so"; } - ) + ); }, { handler = "RESPMOD"; @@ -37,7 +41,7 @@ req_handlers : name = "modpy"; module = "@pkglibdir@/modules/mod_py.so"; } - ) + ); }); diff --git a/configure.ac b/configure.ac index 9f43dd1..b88fc75 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ -# -*- Autoconf -*- +# configure.ac # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT([bitz-server], [0.1.6], [http://bugs.geniusse.com/]) +AC_INIT([bitz-server], [1.0.0], [https://github.com/uditha-atukorala/bitz-server/issues]) AC_CONFIG_AUX_DIR([aux-build]) AC_CONFIG_MACRO_DIR([aux-build/m4]) AC_CONFIG_HEADERS([include/config.h]) @@ -33,7 +33,7 @@ AC_CONFIG_HEADERS([include/config.h]) # CURRENT : REVISION : AGE # lib versions -ICAP_LT_VERSION=0:3:0 +ICAP_LT_VERSION=1:0:0 AC_SUBST(ICAP_LT_VERSION) # Init @@ -78,6 +78,9 @@ PKG_CHECK_MODULES([libconfig], [libconfig++ >= 1.4],, PKG_CHECK_MODULES([log4cpp], [log4cpp >= 1.0],, AC_MSG_ERROR([log4cpp 1.0 or newer not found.]) ) +PKG_CHECK_MODULES([psocksxx], [psocksxx >= 0.0.6],, + AC_MSG_ERROR([psocksxx 0.0.6 or newer not found.]) +) # Checks for header files. @@ -134,7 +137,6 @@ AC_CONFIG_FILES([ \ doc/Makefile \ include/Makefile \ lib/Makefile \ - lib/socket/Makefile \ lib/icap/Makefile \ src/Makefile \ modules/Makefile \ diff --git a/doc/bitz-server.conf.man b/doc/bitz-server.conf.man index 1c9b5b0..6bac421 100644 --- a/doc/bitz-server.conf.man +++ b/doc/bitz-server.conf.man @@ -1,4 +1,4 @@ -.TH bitz-server.conf 5 "March 2013" Linux "File Formats Manual" +.TH bitz-server.conf 5 "November 2015" Linux "File Formats Manual" .SH NAME bitz-server.conf \- bitz-server configuration file .SH SYNOPSIS @@ -58,7 +58,7 @@ Terminals are defined below as regular expressions: ([\-+]([0-9]+)(\\.[0-9]*)?[eE][-+]?[0-9]+) .fi .SH AUTHOR -Uditha Atukorala <udi at geniusse dot com> +Uditha Atukorala <ua@nuked.zone> .SH "SEE ALSO" .BR bitz-server (1) diff --git a/doc/bitz-server.man b/doc/bitz-server.man index d59ffc1..543cd69 100644 --- a/doc/bitz-server.man +++ b/doc/bitz-server.man @@ -1,4 +1,4 @@ -.TH bitz-server 1 "March 2013" Linux "User Manuals" +.TH bitz-server 1 "November 2015" Linux "User Manuals" .SH NAME bitz-server \- An ICAP server .SH SYNOPSIS @@ -39,9 +39,9 @@ Default configuration file. See for further details. .RE .SH BUGS -Please report all bugs and feature requests at <http://bugs.geniusse.com/> +Please report all bugs and feature requests at <https://github.com/uditha-atukorala/bitz-server/issues> .SH AUTHOR -Uditha Atukorala <udi at geniusse dot com> +Uditha Atukorala <ua@nuked.zone> .SH "SEE ALSO" .BR bitz-server.conf (5) diff --git a/doc/doxygen.cfg.in b/doc/doxygen.cfg.in index c4bb0e3..73bd0d1 100644 --- a/doc/doxygen.cfg.in +++ b/doc/doxygen.cfg.in @@ -1,1864 +1,308 @@ -# Doxyfile 1.8.3 - -# 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 (" "). +# Doxyfile 1.8.7 #--------------------------------------------------------------------------- # 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 sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - PROJECT_NAME = @PACKAGE_NAME@ - -# 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 = @PACKAGE_VERSION@ - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - PROJECT_LOGO = - -# 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 = @top_builddir@/doc/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, Esperanto, 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, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - +ALLOW_UNICODE_NAMES = NO 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. Note that you specify absolute paths here, but also -# relative paths, which will be relative from the directory where doxygen is -# started. - 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 if your file system -# 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 INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - OPTIMIZE_OUTPUT_JAVA = NO - -# 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 - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, -# and language is one of the parsers supported by doxygen: IDL, Java, -# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, -# C++. For instance to make doxygen treat .inc files as Fortran files (default -# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note -# that for custom extensions you also need to set FILE_PATTERNS otherwise the -# files are not read by doxygen. - EXTENSION_MAPPING = - -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. - MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented classes, -# or namespaces to their corresponding documentation. Such a link can be -# prevented in individual cases by by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. - AUTOLINK_SUPPORT = YES - -# 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 makes 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 - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES (the -# default) will make doxygen replace the get and set methods by a property in -# the documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - IDL_PROPERTY_SUPPORT = YES - -# 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 the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). - INLINE_SIMPLE_STRUCTS = NO - -# 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 - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - LOOKUP_CACHE_SIZE = 0 - #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. - EXTRACT_PACKAGE = 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 namespaces 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 = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - +SHOW_GROUPED_MEMB_INC = NO FORCE_LOCAL_INCLUDES = NO - -# 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_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - SORT_MEMBERS_CTORS_1ST = 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 - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - STRICT_PROTO_MATCHING = 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 section-label ... \endif -# and \cond section-label ... \endcond blocks. - ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro 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 macros 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 = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - SHOW_NAMESPACES = YES - -# 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 = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. Do not use -# file names with spaces, bibtex cannot handle them. - CITE_BIB_FILES = - #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# 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 = YES - -# 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 - -# The WARN_NO_PARAMDOC option can be enabled 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 +# 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 = @top_srcdir@ - -# 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++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# 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. -# Note that relative paths are relative to the directory from which doxygen is -# run. - EXCLUDE = @top_srcdir@/doc - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system 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 or if -# non of the patterns match the file name, INPUT_FILTER is applied. - 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 - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - FILTER_SOURCE_PATTERNS = - -# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page (index.html). -# This can be useful if you have a project on for instance GitHub and want reuse -# the introduction page also for the doxygen output. - USE_MDFILE_AS_MAINPAGE = - #--------------------------------------------------------------------------- -# configuration options related to source browsing +# 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, C++ and Fortran comments will always remain visible. - STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# 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 -# 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 documentation. - 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. - +SOURCE_TOOLTIPS = YES 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 +# 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 = YES - -# 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 +# Configuration options related to the HTML output #--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - 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 left blank doxygen will -# generate a default style sheet. Note that it is recommended to use -# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this -# tag will in the future become obsolete. - HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional -# user-defined cascading style sheet that is included after the standard -# style sheets created by doxygen. Using this option one can overrule -# certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more -# robust against future updates. Doxygen will copy the style sheet file to -# the output directory. - HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - HTML_TIMESTAMP = YES - -# 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. - HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. - HTML_INDEX_NUM_ENTRIES = 100 - -# 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. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - 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 - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. - DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - DOCSET_PUBLISHER_NAME = Publisher - -# 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_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 CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - CHM_INDEX_ENCODING = - -# 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 - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> -# Qt Help Project / Custom Filters</a>. - QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> -# Qt Help Project / Filter Attributes</a>. - QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value 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 (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - ENUM_VALUES_PER_LINE = 4 - -# 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 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and -# SVG. The default value is HTML-CSS, which is slower, but has the best -# compatibility. - MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. - MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - MATHJAX_EXTENSIONS = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - +MATHJAX_CODEFILE = SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. -# There are two flavours of web server based search depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. -# See the manual for details. - SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain -# the search results. Doxygen ships with an example indexer (doxyindexer) and -# search engine (doxysearch.cgi) which are based on the open source search engine -# library Xapian. See the manual for configuration details. - EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will returned the search results when EXTERNAL_SEARCH is enabled. -# Doxygen ships with an example search engine (doxysearch) which is based on -# the open source search engine library Xapian. See the manual for configuration -# details. - SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. - SEARCHDATA_FILE = searchdata.xml - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other -# doxygen projects that are not otherwise connected via tags files, but are -# all added to the same search index. Each project needs to have a tag file set -# via GENERATE_TAGFILE. The search mapping then maps the name of the tag file -# to a relative location where the documentation can be found, -# similar to the -# TAGFILES option but without actually processing the tag file. -# The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... - +EXTERNAL_SEARCH_ID = EXTRA_SEARCH_MAPPINGS = - #--------------------------------------------------------------------------- -# configuration options related to the LaTeX output +# 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. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - 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, letter, legal and -# executive. If left blank a4wide will be used. - PAPER_TYPE = a4 - -# 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 = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - LATEX_FOOTER = - -# 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. - +LATEX_EXTRA_FILES = 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 - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - LATEX_BIB_STYLE = plain - #--------------------------------------------------------------------------- -# configuration options related to the RTF output +# 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 style sheet 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 +# 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_SUBDIR = MAN_LINKS = NO - #--------------------------------------------------------------------------- -# configuration options related to the XML output +# 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 +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +#--------------------------------------------------------------------------- +# 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 +# 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 -# pointed to by INCLUDE_PATH will be searched when 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 that -# overrules the definition found in the source code. - EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - SKIP_FUNCTION_MACROS = YES - #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration options related to external references #--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. 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. 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'). - +EXTERNAL_PAGES = YES 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 also works with HAVE_DOT disabled, but 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. - +DIA_PATH = 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 - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - DOT_FONTPATH = - -# 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 -# 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 the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be -# exceeded by 50% before the limit is enforced. - UML_LIMIT_NUM_FIELDS = 10 - -# 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 generate a graphical hierarchy of all classes instead of a textual one. - GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH 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 svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - INTERACTIVE_SVG = NO - -# 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 MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - MSCFILE_DIRS = - -# The 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. - +DIAFILE_DIRS = 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 disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - DOT_CLEANUP = YES diff --git a/lib/Makefile.am b/lib/Makefile.am index bcd3933..af3b92e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,3 +1,3 @@ ## [bitz-server] lib/ -SUBDIRS = socket icap +SUBDIRS = icap diff --git a/lib/icap/Makefile.am b/lib/icap/Makefile.am index 02d8bb4..f73a8f6 100644 --- a/lib/icap/Makefile.am +++ b/lib/icap/Makefile.am @@ -1,9 +1,9 @@ ## [icap-library] lib/icap/ -AM_CPPFLAGS = -I$(top_srcdir)/lib +AM_CPPFLAGS = -I$(top_srcdir)/lib ${psocksxx_CFLAGS} libicapincludedir = $(includedir)/icap lib_LTLIBRARIES = libicap.la -libicap_la_LIBADD = $(top_builddir)/lib/socket/libsocket.la +libicap_la_LIBADD = ${psocksxx_LIBS} libicap_la_LDFLAGS = -version-info @ICAP_LT_VERSION@ -no-undefined libicap_la_SOURCES = \ header.cpp \ diff --git a/lib/icap/util.cpp b/lib/icap/util.cpp index c383261..91a73e1 100644 --- a/lib/icap/util.cpp +++ b/lib/icap/util.cpp @@ -55,41 +55,45 @@ namespace icap { } - int read_line( socketlibrary::TCPSocket * socket, char * buf, int buf_length, bool incl_endl ) throw() { + int read_line( psocksxx::iosockstream * socket, char * buf, int buf_length, bool incl_endl ) throw() { - int i = 0, n; - char c = '\0'; + int i = 0; + char c = '\0'; + char c_last = '\0'; while ( i < ( buf_length - 1 ) ) { - n = socket->recv( &c, 1 ); - - if ( n > 0 ) { - if ( c == '\r' ) { + // read a char + if ( ( c = socket->get() ) > 0 ) { - if ( incl_endl ) { - buf[i] = c; - i++; - } + // check last read char for \r + if ( c_last == '\r' ) { - // peak for \n - n = socket->peek( &c, 1 ); - - if ( ( n > 0 ) && ( c == '\n' ) ) { - - n = socket->recv( &c, 1 ); + // check for \n + if ( c == '\n' ) { + // include \r\n in the read buffer? if ( incl_endl ) { buf[i] = c; i++; + } else { + + // remove \r + i--; + } - break; // end of line + break; + } + } buf[i] = c; i++; + + c_last = c; + } else { break; // nothing read from socket } @@ -102,52 +106,44 @@ namespace icap { } - std::string read_line( socketlibrary::TCPSocket * socket, bool incl_endl ) throw() { + std::string read_line( psocksxx::iosockstream * socket, bool incl_endl ) throw() { int n; std::string line; char c = '\0'; + char c_last = '\0'; - try { - while ( ( n = socket->recv( &c, 1 ) ) > 0 ) { + while ( ( c = socket->get() ) > 0 ) { - if ( c == '\r' ) { + if ( c_last == '\r' ) { + + if ( c == '\n' ) { if ( incl_endl ) { line += c; + } else { + line.erase( line.size() - 1 ); } - // peak for \n - n = socket->peek( &c, 1 ); - - if ( ( n > 0 ) && ( c == '\n' ) ) { - - n = socket->recv( &c, 1 ); - - if ( incl_endl ) { - line += c; - } + break; - break; // end of line - } } - line += c; - } - } catch ( socketlibrary::SocketException &sex ) { - // TODO: log error? - line = ""; + line += c; + c_last = c; + } + return line; } - std::string read_data( socketlibrary::TCPSocket * socket, int size ) throw() { + std::string read_data( psocksxx::iosockstream * socket, int size ) throw() { char buffer[ICAP_BUFFER_SIZE]; std::string data = ""; @@ -159,20 +155,20 @@ namespace icap { try { // read from socket - n = socket->recv( buffer, min( size, ICAP_BUFFER_SIZE ) ); + socket->read( buffer, std::min( size, ICAP_BUFFER_SIZE ) ); // sanity check - if ( n == 0 ) { + if (! socket->good() ) { break; } // append to data - data.append( buffer, n ); + data.append( buffer, socket->gcount() ); // update size with remaining bytes - size -= n; + size -= socket->gcount(); - } catch ( socketlibrary::SocketException &sex ) { + } catch ( psocksxx::sockexception &e ) { // TODO: log errors ?? } @@ -183,7 +179,7 @@ namespace icap { } - unsigned int read_chunk_size( socketlibrary::TCPSocket * socket ) throw() { + unsigned int read_chunk_size( psocksxx::iosockstream * socket ) throw() { std::string line; std::vector<std::string> chunk_header; @@ -196,7 +192,7 @@ namespace icap { } - void read_chunk_header( socketlibrary::TCPSocket * socket, chunk_t &chunk ) throw() { + void read_chunk_header( psocksxx::iosockstream * socket, chunk_t &chunk ) throw() { std::string line; std::vector<std::string> chunk_header; @@ -223,7 +219,7 @@ namespace icap { } - chunk_t read_chunk( socketlibrary::TCPSocket * socket ) throw() { + chunk_t read_chunk( psocksxx::iosockstream * socket ) throw() { chunk_t chunk; std::string line; @@ -250,7 +246,7 @@ namespace icap { } - std::string read_chunked( socketlibrary::TCPSocket * socket ) throw() { + std::string read_chunked( psocksxx::iosockstream * socket ) throw() { unsigned int chunk_size = 0; unsigned int offset = 0; @@ -282,7 +278,7 @@ namespace icap { } - bool read_chunked_payload( socketlibrary::TCPSocket * socket, std::string &payload ) throw() { + bool read_chunked_payload( psocksxx::iosockstream * socket, std::string &payload ) throw() { chunk_t chunk; bool ieof = false; @@ -313,12 +309,12 @@ namespace icap { } - bool send_line( const std::string &line, socketlibrary::TCPSocket * socket ) throw() { + bool send_line( const std::string &line, psocksxx::iosockstream * socket ) throw() { try { - socket->send( line.c_str(), line.length() ); - socket->send( "\r\n", 2 ); - } catch ( socketlibrary::SocketException &sex ) { + socket->write( line.c_str(), line.length() ); + socket->write( "\r\n", 2 ); + } catch ( psocksxx::sockexception &e ) { // TODO: log errors return false; } @@ -328,11 +324,11 @@ namespace icap { } - bool send_data( const std::string &data, socketlibrary::TCPSocket * socket ) throw() { + bool send_data( const std::string &data, psocksxx::iosockstream * socket ) throw() { try { - socket->send( data.c_str(), data.size() ); - } catch( socketlibrary::SocketException &sex ) { + socket->write( data.c_str(), data.size() ); + } catch ( psocksxx::sockexception &e ) { // TODO: log errors return false; } @@ -342,7 +338,7 @@ namespace icap { } - bool send_chunked( const std::string &data, socketlibrary::TCPSocket * socket ) throw() { + bool send_chunked( const std::string &data, psocksxx::iosockstream * socket ) throw() { std::string chunked_data = ""; unsigned int offset = 0; @@ -388,7 +384,7 @@ namespace icap { return false; } - } catch ( socketlibrary::SocketException &sex ) { + } catch ( psocksxx::sockexception &e ) { // TODO: log errors ?? return false; } @@ -432,7 +428,7 @@ namespace icap { } - icap::RequestHeader * read_req_header( socketlibrary::TCPSocket * socket ) throw() { + icap::RequestHeader * read_req_header( psocksxx::iosockstream * socket ) throw() { char buffer[ICAP_BUFFER_SIZE]; int n = 0; @@ -448,7 +444,7 @@ namespace icap { } - bool read_req_data( icap::Request * request, socketlibrary::TCPSocket * socket ) throw() { + bool read_req_data( icap::Request * request, psocksxx::iosockstream * socket ) throw() { int data_offset = 0; int data_length = 0; @@ -529,7 +525,7 @@ namespace icap { } - bool read_req_continue_data( icap::Request * request, socketlibrary::TCPSocket * socket ) throw() { + bool read_req_continue_data( icap::Request * request, psocksxx::iosockstream * socket ) throw() { std::vector<icap::Header::encapsulated_header_data_t> sorted_encaps_header; icap::Header::encapsulated_header_data_t header_idx; @@ -574,7 +570,7 @@ namespace icap { } - bool send_headers( icap::Header * header, socketlibrary::TCPSocket * socket ) throw() { + bool send_headers( icap::Header * header, psocksxx::iosockstream * socket ) throw() { std::string line; icap::Header::headers_index_t i; @@ -612,7 +608,7 @@ namespace icap { } - bool send_response( icap::Response * response, socketlibrary::TCPSocket * socket ) throw() { + bool send_response( icap::Response * response, psocksxx::iosockstream * socket ) throw() { bool r_success = true; @@ -660,6 +656,9 @@ namespace icap { } + // flush-out socket stream buffer + socket->flush(); + return r_success; } diff --git a/lib/icap/util.h b/lib/icap/util.h index 366bb9c..14765ac 100644 --- a/lib/icap/util.h +++ b/lib/icap/util.h @@ -22,7 +22,7 @@ #include <sstream> -#include <socket/socket.h> +#include <psocksxx/iosockstream.h> #include "request.h" #include "response.h" @@ -80,7 +80,7 @@ namespace icap { * default is false. * @return number of bytes read */ - int read_line( socketlibrary::TCPSocket * socket, char * buf, int buf_length, bool incl_endl = false ) throw(); + int read_line( psocksxx::iosockstream * socket, char * buf, int buf_length, bool incl_endl = false ) throw(); /** * Read a line (ending with \r\n) from the socket @@ -90,7 +90,7 @@ namespace icap { * default is false. * @return read data */ - std::string read_line( socketlibrary::TCPSocket * socket, bool incl_endl = false ) throw(); + std::string read_line( psocksxx::iosockstream * socket, bool incl_endl = false ) throw(); /** * Read data from the socket @@ -99,7 +99,7 @@ namespace icap { * @param size size / length of data to be read * @return read data */ - std::string read_data( socketlibrary::TCPSocket * socket, int size ) throw(); + std::string read_data( psocksxx::iosockstream * socket, int size ) throw(); /** * Read chunk size. This is a helper method used by read_chunked(). @@ -107,7 +107,7 @@ namespace icap { * @param socket socket instance to read from * @return chunk size */ - unsigned int read_chunk_size( socketlibrary::TCPSocket * socket ) throw(); + unsigned int read_chunk_size( psocksxx::iosockstream * socket ) throw(); /** * Read chunk header from the given socket. @@ -115,7 +115,7 @@ namespace icap { * @param socket socket instance to read data from * @param chunk chunk data structure to store header data */ - void read_chunk_header( socketlibrary::TCPSocket * socket, chunk_t &chunk ) throw(); + void read_chunk_header( psocksxx::iosockstream * socket, chunk_t &chunk ) throw(); /** * Read a data chunk from a HTTP chunked transfer encoded data stream. @@ -123,7 +123,7 @@ namespace icap { * @param socket socket instance to read data from * @return chunk data structure */ - chunk_t read_chunk( socketlibrary::TCPSocket * socket ) throw(); + chunk_t read_chunk( psocksxx::iosockstream * socket ) throw(); /** * Read chunked data from the given socket @@ -131,7 +131,7 @@ namespace icap { * @param socket socket instance to read data from * @return read data (without the control characters) */ - std::string read_chunked( socketlibrary::TCPSocket * socket ) throw(); + std::string read_chunked( psocksxx::iosockstream * socket ) throw(); /** * Read chunked payload data from the given socket @@ -140,7 +140,7 @@ namespace icap { * @param payload payload to read data into * @return boolean flag to denote the presence of "ieof" */ - bool read_chunked_payload( socketlibrary::TCPSocket * socket, std::string &payload ) throw(); + bool read_chunked_payload( psocksxx::iosockstream * socket, std::string &payload ) throw(); /** * Send / write a line (ending with \r\n) to the socket @@ -149,7 +149,7 @@ namespace icap { * @param socket socket object to write the data to * @return boolean to denote success or failure */ - bool send_line( const std::string &line, socketlibrary::TCPSocket * socket ) throw(); + bool send_line( const std::string &line, psocksxx::iosockstream * socket ) throw(); /** * Send / write data to the socket. @@ -160,7 +160,7 @@ namespace icap { * @param socket socket instance to write to * @return boolean to denote success or failure */ - bool send_data( const std::string &data, socketlibrary::TCPSocket * socket ) throw(); + bool send_data( const std::string &data, psocksxx::iosockstream * socket ) throw(); /** * Send / write data to the socket using chunked transfer encoding @@ -169,7 +169,7 @@ namespace icap { * @param socket socket instance to write to * @return boolean to denote success or failure */ - bool send_chunked( const std::string &data, socketlibrary::TCPSocket * socket ) throw(); + bool send_chunked( const std::string &data, psocksxx::iosockstream * socket ) throw(); /** * split a string into a vector by the given delimiter @@ -209,7 +209,7 @@ namespace icap { * @param socket socket object to read data from * @return icap request header object */ - icap::RequestHeader * read_req_header( socketlibrary::TCPSocket * socket ) throw(); + icap::RequestHeader * read_req_header( psocksxx::iosockstream * socket ) throw(); /** * Read icap request into the icap::Request instance @@ -219,7 +219,7 @@ namespace icap { * @param socket socket object to read data from * @return boolean to denote success or failure */ - bool read_req_data( icap::Request * request, socketlibrary::TCPSocket * socket ) throw(); + bool read_req_data( icap::Request * request, psocksxx::iosockstream * socket ) throw(); /** * Read icap request data after a '100 Continue' response. This will not look for any @@ -229,7 +229,7 @@ namespace icap { * @param socket socket object to read data from * @return boolean to denote success or failure */ - bool read_req_continue_data( icap::Request * request, socketlibrary::TCPSocket * socket ) throw(); + bool read_req_continue_data( icap::Request * request, psocksxx::iosockstream * socket ) throw(); /** * Send / write header data to a socket @@ -238,7 +238,7 @@ namespace icap { * @param socket socket object to write the data to * @return boolean to denote success or failure */ - bool send_headers( icap::Header::headers_t headers, socketlibrary::TCPSocket * socket ) throw(); + bool send_headers( icap::Header::headers_t headers, psocksxx::iosockstream * socket ) throw(); /** * Output a response using the passed in icap::Response class to the @@ -248,7 +248,7 @@ namespace icap { * @param socket socket object to send the data to * @return boolean to denote success or failure */ - bool send_response( icap::Response * response, socketlibrary::TCPSocket * socket ) throw(); + bool send_response( icap::Response * response, psocksxx::iosockstream * socket ) throw(); /** * Returns the response status text for the given status diff --git a/lib/socket/Makefile.am b/lib/socket/Makefile.am deleted file mode 100644 index 93f98a5..0000000 --- a/lib/socket/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -## [socket-library] lib/ -noinst_LTLIBRARIES = libsocket.la -libsocket_la_SOURCES = socket.h socket.cpp - diff --git a/lib/socket/socket.cpp b/lib/socket/socket.cpp deleted file mode 100644 index a086d95..0000000 --- a/lib/socket/socket.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* - * C++ sockets on Unix and Windows - * Copyright (C) 2002 <unknown> - * Copyright (C) 2010 Uditha Atukorala - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <socket.h> - -#ifndef WIN32 - #include <sys/types.h> // For data types - #include <sys/socket.h> // For socket(), connect(), send(), and recv() - #include <netdb.h> // For gethostbyname() - #include <arpa/inet.h> // For inet_addr() - #include <unistd.h> // For close() -#endif - -#include <cerrno> // For errno -#include <cstring> // For strerror -#include <cstdlib> // For atoi() - -using namespace std; - -namespace socketlibrary { - -#ifdef WIN32 - static bool initialized = false; -#endif - -// SocketException Code - -SocketException::SocketException(const string &message, bool inclSysMsg) throw() : userMessage(message) { - if (inclSysMsg) { - userMessage.append(": "); - userMessage.append(strerror(errno)); - } -} - -SocketException::~SocketException() throw() { -} - -const char *SocketException::what() const throw() { - return userMessage.c_str(); -} - -// Function to fill in address structure given an address and port -void fillAddr(const string &address, unsigned short port, sockaddr_in &addr) { - - memset(&addr, 0, sizeof(addr)); // Zero out address structure - addr.sin_family = AF_INET; // Internet address - - hostent *host; // Resolve name - if ((host = gethostbyname(address.c_str())) == NULL) { - // strerror() will not work for gethostbyname() and hstrerror() - // is supposedly obsolete - throw SocketException("Failed to resolve name (gethostbyname())"); - } - - addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]); - addr.sin_port = htons(port); // Assign port in network byte order - -} - -// Socket Code - -Socket::Socket(int type, int protocol) throw(SocketException) { -#ifdef WIN32 - if (!initialized) { - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 0); // Request WinSock v2.0 - if (WSAStartup(wVersionRequested, &wsaData) != 0) { // Load WinSock DLL - throw SocketException("Unable to load WinSock DLL"); - } - initialized = true; - } -#endif - - // Make a new socket - if ((sock = socket(PF_INET, type, protocol)) < 0) { - throw SocketException("Socket creation failed (socket())", true); - } -} - -Socket::Socket(int sock) { - this->sock = sock; -} - -Socket::~Socket() { - -#ifdef WIN32 - ::closesocket(sock); -#else - ::close(sock); -#endif - sock = -1; -} - -string Socket::getLocalAddress() throw(SocketException) { - sockaddr_in addr; - unsigned int addr_len = sizeof(addr); - - if (getsockname(sock, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) { - throw SocketException("Fetch of local address failed (getsockname())", true); - } - return inet_ntoa(addr.sin_addr); -} - -unsigned short Socket::getLocalPort() throw(SocketException) { - sockaddr_in addr; - unsigned int addr_len = sizeof(addr); - - if (getsockname(sock, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) { - throw SocketException("Fetch of local port failed (getsockname())", true); - } - return ntohs(addr.sin_port); -} - -void Socket::setLocalPort(unsigned short localPort) throw(SocketException) { - // Bind the socket to its port - sockaddr_in localAddr; - memset(&localAddr, 0, sizeof(localAddr)); - localAddr.sin_family = AF_INET; - localAddr.sin_addr.s_addr = htonl(INADDR_ANY); - localAddr.sin_port = htons(localPort); - - if (bind(sock, (sockaddr *) &localAddr, sizeof(sockaddr_in)) < 0) { - throw SocketException("Set of local port failed (bind())", true); - } -} - -void Socket::setLocalAddressAndPort(const string &localAddress, unsigned short localPort) throw(SocketException) { - // Get the address of the requested host - sockaddr_in localAddr; - fillAddr(localAddress, localPort, localAddr); - - if (bind(sock, (sockaddr *) &localAddr, sizeof(sockaddr_in)) < 0) { - throw SocketException("Set of local address and port failed (bind())", true); - } -} - -void Socket::cleanUp() throw(SocketException) { -#ifdef WIN32 - if (WSACleanup() != 0) { - throw SocketException("WSACleanup() failed"); - } -#endif -} - -unsigned short Socket::resolveService(const string &service, const string &protocol) { - - struct servent *serv; /* Structure containing service information */ - - if ((serv = getservbyname(service.c_str(), protocol.c_str())) == NULL) - return atoi(service.c_str()); /* Service is port number */ - else - return ntohs(serv->s_port); /* Found port (network byte order) by name */ - -} - -// CommunicatingSocket Code - -CommunicatingSocket::CommunicatingSocket(int type, int protocol) throw(SocketException) : Socket(type, protocol) { -} - -CommunicatingSocket::CommunicatingSocket(int newSD) : Socket(newSD) { -} - -void CommunicatingSocket::connect(const string &foreignAddress, unsigned short foreignPort) throw(SocketException) { - // Get the address of the requested host - sockaddr_in destAddr; - fillAddr(foreignAddress, foreignPort, destAddr); - - // Try to connect to the given port - if (::connect(sock, (sockaddr *) &destAddr, sizeof(destAddr)) < 0) { - throw SocketException("Connect failed (connect())", true); - } -} - -void CommunicatingSocket::send(const void *buffer, int bufferLen) throw(SocketException) { - if (::send(sock, (raw_type *) buffer, bufferLen, 0) < 0) { - throw SocketException("Send failed (send())", true); - } -} - -int CommunicatingSocket::recv(void *buffer, int bufferLen) throw(SocketException) { - int rtn; - if ((rtn = ::recv(sock, (raw_type *) buffer, bufferLen, 0)) < 0) { - throw SocketException("Received failed (recv()) for socket ", true); - } - return rtn; -} - -int CommunicatingSocket::peek(void *buffer, int bufferLen) throw(SocketException) { - int rtn; - if ((rtn = ::recv(sock, (raw_type *) buffer, bufferLen, MSG_PEEK)) < 0) { - throw SocketException("Received failed (recv()) for socket ", true); - } - return rtn; -} - -int CommunicatingSocket::readLine(char *buffer, int bufferLen, const char delimiter) throw(SocketException) { - - int n, rc; - char c; - - for (n = 1; n < bufferLen; n++) { - if ((rc = recv(&c, 1)) == 1) { - *buffer++ = c; - if (c == delimiter) { - break; - } - } else if (rc == 0) { - if (n == 1) { - return 0; // EOF, no data read - } else { - break; // EOF, read some data - } - } else { - throw SocketException("Failed to read data from socket ", true); - } - } - - *buffer = '\0'; - return n; - -} - -string CommunicatingSocket::getForeignAddress() throw(SocketException) { - sockaddr_in addr; - unsigned int addr_len = sizeof(addr); - - if (getpeername(sock, (sockaddr *) &addr,(socklen_t *) &addr_len) < 0) { - throw SocketException("Fetch of foreign address failed (getpeername())", true); - } - return inet_ntoa(addr.sin_addr); -} - -unsigned short CommunicatingSocket::getForeignPort() throw(SocketException) { - sockaddr_in addr; - unsigned int addr_len = sizeof(addr); - - if (getpeername(sock, (sockaddr *) &addr, (socklen_t *) &addr_len) < 0) { - throw SocketException("Fetch of foreign port failed (getpeername())", true); - } - return ntohs(addr.sin_port); -} - -// TCPSocket Code - -TCPSocket::TCPSocket() throw(SocketException) : CommunicatingSocket(SOCK_STREAM, IPPROTO_TCP) { -} - -TCPSocket::TCPSocket(const string &foreignAddress, unsigned short foreignPort) throw(SocketException) : CommunicatingSocket(SOCK_STREAM, IPPROTO_TCP) { - connect(foreignAddress, foreignPort); -} - -TCPSocket::TCPSocket(int newSD) : CommunicatingSocket(newSD) { -} - -// TCPServerSocket Code - -TCPServerSocket::TCPServerSocket(unsigned short localPort, int queueLen) throw(SocketException) : Socket(SOCK_STREAM, IPPROTO_TCP) { - setLocalPort(localPort); - setListen(queueLen); -} - -TCPServerSocket::TCPServerSocket(const string &localAddress, unsigned short localPort, int queueLen) throw(SocketException) : Socket(SOCK_STREAM, IPPROTO_TCP) { - setLocalAddressAndPort(localAddress, localPort); - setListen(queueLen); -} - -TCPSocket *TCPServerSocket::accept() throw(SocketException) { - int newSD; - if ((newSD = ::accept(sock, NULL, 0)) < 0) { - throw SocketException("Accept failed (accept())", true); - } - return new TCPSocket(newSD); -} - -void TCPServerSocket::setListen(int queueLen) throw(SocketException) { - if (listen(sock, queueLen) < 0) { - throw SocketException("Set listening socket failed (listen())", true); - } -} - -// TCPServerSocketM Code - -TCPServerSocketM::TCPServerSocketM(unsigned short localPort, int queueLen) throw(SocketException) : TCPServerSocket(localPort, queueLen) { - - FD_ZERO(&fds_master); // clear the master and temp sets - - FD_SET(sock, &fds_master); // Add ourself to the master set - fdmax = sock; // keep track of the biggest file descriptor, only ourself for the moment - -} - -TCPSocket *TCPServerSocketM::accept() throw(SocketException) { - - TCPSocket *newClient = TCPServerSocket::accept(); - int newSD = newClient->sock; - - FD_SET(newSD, &fds_master); // add to master set - if (newSD > fdmax) { // keep track of the max - fdmax = newSD; - } - - v_clients.push_back(newClient); - return newClient; - -} - -bool TCPServerSocketM::pendingConnections() throw (SocketException) { - - fd_set read_fds; - FD_ZERO(&read_fds); - - read_fds = fds_master; - if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { - throw SocketException("Failed to select read fds (select())", true); - } - - if (FD_ISSET(sock, &read_fds)) { - return true; - } else { - return false; - } - -} - -int TCPServerSocketM::getWaitingClients(vector<TCPSocket *> &clients) throw (SocketException) { - - fd_set read_fds; - FD_ZERO(&read_fds); - - int cl_count = 0; - - read_fds = fds_master; - if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { - throw SocketException("Failed to select read fds (select())", true); - } - - // resize the vector so it doesn't contain any old information - clients.resize(0); - - for(unsigned int i=0; i<v_clients.size(); i++) { - if (FD_ISSET(v_clients.at(i)->sock, &read_fds)) { // we got one!! - clients.push_back(v_clients.at(i)); - cl_count++; - } - } - - return cl_count; -} - -void TCPServerSocketM::closeClientConnection(TCPSocket * client) { - - for(unsigned int i=0; i<v_clients.size(); i++) { - if (client->sock == v_clients.at(i)->sock) { - FD_CLR(client->sock, &fds_master); - v_clients.erase(v_clients.begin() + i); - delete client; - break; - } - } - -} - - -// UDPSocket Code - -UDPSocket::UDPSocket() throw(SocketException) : CommunicatingSocket(SOCK_DGRAM, IPPROTO_UDP) { - setBroadcast(); -} - -UDPSocket::UDPSocket(unsigned short localPort) throw(SocketException) : CommunicatingSocket(SOCK_DGRAM, IPPROTO_UDP) { - setLocalPort(localPort); - setBroadcast(); -} - -UDPSocket::UDPSocket(const string &localAddress, unsigned short localPort) throw(SocketException) : CommunicatingSocket(SOCK_DGRAM, IPPROTO_UDP) { - setLocalAddressAndPort(localAddress, localPort); - setBroadcast(); -} - -void UDPSocket::setBroadcast() { - // If this fails, we'll hear about it when we try to send. This will allow - // system that cannot broadcast to continue if they don't plan to broadcast - int broadcastPermission = 1; - setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (raw_type *) &broadcastPermission, sizeof(broadcastPermission)); -} - -void UDPSocket::disconnect() throw(SocketException) { - sockaddr_in nullAddr; - memset(&nullAddr, 0, sizeof(nullAddr)); - nullAddr.sin_family = AF_UNSPEC; - - // Try to disconnect - if (::connect(sock, (sockaddr *) &nullAddr, sizeof(nullAddr)) < 0) { -#ifdef WIN32 - if (errno != WSAEAFNOSUPPORT) { -#else - if (errno != EAFNOSUPPORT) { -#endif - throw SocketException("Disconnect failed (connect())", true); - } - } -} - -void UDPSocket::sendTo(const void *buffer, int bufferLen, const string &foreignAddress, unsigned short foreignPort) throw(SocketException) { - sockaddr_in destAddr; - fillAddr(foreignAddress, foreignPort, destAddr); - - // Write out the whole buffer as a single message. - if (sendto(sock, (raw_type *) buffer, bufferLen, 0, (sockaddr *) &destAddr, sizeof(destAddr)) != bufferLen) { - throw SocketException("Send failed (sendto())", true); - } -} - -int UDPSocket::recvFrom(void *buffer, int bufferLen, string &sourceAddress, unsigned short &sourcePort) throw(SocketException) { - sockaddr_in clntAddr; - socklen_t addrLen = sizeof(clntAddr); - int rtn; - if ((rtn = recvfrom(sock, (raw_type *) buffer, bufferLen, 0, (sockaddr *) &clntAddr, (socklen_t *) &addrLen)) < 0) { - throw SocketException("Receive failed (recvfrom())", true); - } - sourceAddress = inet_ntoa(clntAddr.sin_addr); - sourcePort = ntohs(clntAddr.sin_port); - return rtn; -} - -void UDPSocket::setMulticastTTL(unsigned char multicastTTL) throw(SocketException) { - if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (raw_type *) &multicastTTL, sizeof(multicastTTL)) < 0) { - throw SocketException("Multicast TTL set failed (setsockopt())", true); - } -} - -void UDPSocket::joinGroup(const string &multicastGroup) throw(SocketException) { - struct ip_mreq multicastRequest; - - multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str()); - multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (raw_type *) &multicastRequest, sizeof(multicastRequest)) < 0) { - throw SocketException("Multicast group join failed (setsockopt())", true); - } -} - -void UDPSocket::leaveGroup(const string &multicastGroup) throw(SocketException) { - struct ip_mreq multicastRequest; - - multicastRequest.imr_multiaddr.s_addr = inet_addr(multicastGroup.c_str()); - multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (raw_type *) &multicastRequest, sizeof(multicastRequest)) < 0) { - throw SocketException("Multicast group leave failed (setsockopt())", true); - } -} - -} // End of namespace SocketLibrary diff --git a/lib/socket/socket.h b/lib/socket/socket.h deleted file mode 100644 index 2c4d777..0000000 --- a/lib/socket/socket.h +++ /dev/null @@ -1,427 +0,0 @@ -/* - * C++ sockets on Unix and Windows - * Copyright (C) 2002 <unknown> - * Copyright (C) 2010 Uditha Atukorala - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef SL_SOCKET_H -#define SL_SOCKET_H - -#include <string> // For string -#include <exception> // For exception class -#include <vector> // For vectors - -#ifdef WIN32 - #include <winsock.h> // For socket(), connect(), send(), and recv() - typedef int socklen_t; - typedef char raw_type; // Type used for raw data on this platform -#else - #include <netinet/in.h> // For sockaddr_in - typedef void raw_type; // Type used for raw data on this platform -#endif - -using namespace std; - -namespace socketlibrary { - -/** - * Function to fill in address structure given an address and port - */ -void fillAddr(const string &address, unsigned short port, sockaddr_in &addr); - -/** - * Signals a problem with the execution of a socket call. - */ -class SocketException : public exception { -public: - /** - * Construct a SocketException with a explanatory message. - * @param message explanatory message - * @param incSysMsg true if system message (from strerror(errno)) - * should be postfixed to the user provided message - */ - SocketException(const string &message, bool inclSysMsg = false) throw(); - - /** - * Provided just to guarantee that no exceptions are thrown. - */ - ~SocketException() throw(); - - /** - * Get the exception message - * @return exception message - */ - const char *what() const throw(); - -private: - string userMessage; // Exception message -}; - - -/** - * Base class representing basic communication endpoint - */ -class Socket { -public: - /** - * Close and deallocate this socket - */ - ~Socket(); - - /** - * Get the local address - * @return local address of socket - * @exception SocketException thrown if fetch fails - */ - string getLocalAddress() throw(SocketException); - - /** - * Get the local port - * @return local port of socket - * @exception SocketException thrown if fetch fails - */ - unsigned short getLocalPort() throw(SocketException); - - /** - * Set the local port to the specified port and the local address - * to any interface - * @param localPort local port - * @exception SocketException thrown if setting local port fails - */ - void setLocalPort(unsigned short localPort) throw(SocketException); - - /** - * Set the local port to the specified port and the local address - * to the specified address. If you omit the port, a random port - * will be selected. - * @param localAddress local address - * @param localPort local port - * @exception SocketException thrown if setting local port or address fails - */ - void setLocalAddressAndPort(const string &localAddress, unsigned short localPort = 0) throw(SocketException); - - /** - * If WinSock, unload the WinSock DLLs; otherwise do nothing. We ignore - * this in our sample client code but include it in the library for - * completeness. If you are running on Windows and you are concerned - * about DLL resource consumption, call this after you are done with all - * Socket instances. If you execute this on Windows while some instance of - * Socket exists, you are toast. For portability of client code, this is - * an empty function on non-Windows platforms so you can always include it. - * @param buffer buffer to receive the data - * @param bufferLen maximum number of bytes to read into buffer - * @return number of bytes read, 0 for EOF, and -1 for error - * @exception SocketException thrown WinSock clean up fails - */ - static void cleanUp() throw(SocketException); - - /** - * Resolve the specified service for the specified protocol to the - * corresponding port number in host byte order - * @param service service to resolve (e.g., "http") - * @param protocol protocol of service to resolve. Default is "tcp". - */ - static unsigned short resolveService(const string &service, const string &protocol = "tcp"); - -private: - // Prevent the user from trying to use value semantics on this object - Socket(const Socket &sock); - void operator=(const Socket &sock); - -protected: - int sock; // Socket descriptor - Socket(int type, int protocol) throw(SocketException); - Socket(int sock); -}; - -/** - * Socket which is able to connect, send, and receive - */ -class CommunicatingSocket : public Socket { -public: - /** - * Establish a socket connection with the given foreign - * address and port - * @param foreignAddress foreign address (IP address or name) - * @param foreignPort foreign port - * @exception SocketException thrown if unable to establish connection - */ - void connect(const string &foreignAddress, unsigned short foreignPort) throw(SocketException); - - /** - * Write the given buffer to this socket. Call connect() before - * calling send() - * @param buffer buffer to be written - * @param bufferLen number of bytes from buffer to be written - * @exception SocketException thrown if unable to send data - */ - void send(const void *buffer, int bufferLen) throw(SocketException); - - /** - * Read into the given buffer up to bufferLen bytes data from this - * socket. Call connect() before calling recv() - * @param buffer buffer to receive the data - * @param bufferLen maximum number of bytes to read into buffer - * @return number of bytes read, 0 for EOF, and -1 for error - * @exception SocketException thrown if unable to receive data - */ - int recv(void *buffer, int bufferLen) throw(SocketException); - - /** - * Read into the given buffer up to bufferLen bytes data from this - * socket but don't remove the read bytes from the socket read buffer. - * Call connect() before calling peek() - * - * @param buffer buffer to receive the data - * @param bufferLen maximum number of bytes to read into buffer - * @return number of bytes read, 0 for EOF, and -1 for error - * @exception SocketException thrown if unable to receive data - */ - int peek(void *buffer, int bufferLen) throw(SocketException); - - /** - * Read a line into the given buffer from this socket. - * Call connect() before calling recv() - * - * @param buffer buffer to receive the data - * @param bufferLen maximum number of bytes to read into buffer - * @param delimiter (optional) end of line delimiter - * @return number of bytes read, 0 for EOF, and -1 for error - * @exception SocketException thrown if unable to receive data - */ - int readLine(char *buffer, int bufferLen, const char delimiter = '\n') throw(SocketException); - - /** - * Get the foreign address. Call connect() before calling recv() - * @return foreign address - * @exception SocketException thrown if unable to fetch foreign address - */ - string getForeignAddress() throw(SocketException); - - /** - * Get the foreign port. Call connect() before calling recv() - * @return foreign port - * @exception SocketException thrown if unable to fetch foreign port - */ - unsigned short getForeignPort() throw(SocketException); - -protected: - CommunicatingSocket(int type, int protocol) throw(SocketException); - CommunicatingSocket(int newSD); -}; - -/** - * TCP socket for communication with other TCP sockets - */ -class TCPSocket : public CommunicatingSocket { -public: - /** - * Construct a TCP socket with no connection - * @exception SocketException thrown if unable to create TCP socket - */ - TCPSocket() throw(SocketException); - - /** - * Construct a TCP socket with a connection to the given foreign address - * and port - * @param foreignAddress foreign address (IP address or name) - * @param foreignPort foreign port - * @exception SocketException thrown if unable to create TCP socket - */ - TCPSocket(const string &foreignAddress, unsigned short foreignPort) throw(SocketException); - -private: - friend class TCPServerSocket; // Access for TCPServerSocket::accept() connection creation - friend class TCPServerSocketM; // Access for TCPServerSocketM::accept() connection creation - TCPSocket(int newSD); -}; - -/** - * TCP socket class for servers - */ -class TCPServerSocket : public Socket { -public: - /** - * Construct a TCP socket for use with a server, accepting connections - * on the specified port on any interface - * @param localPort local port of server socket, a value of zero will - * give a system-assigned unused port - * @param queueLen maximum queue length for outstanding - * connection requests (default 5) - * @exception SocketException thrown if unable to create TCP server socket - */ - TCPServerSocket(unsigned short localPort, int queueLen = 5) throw(SocketException); - - /** - * Construct a TCP socket for use with a server, accepting connections - * on the specified port on the interface specified by the given address - * @param localAddress local interface (address) of server socket - * @param localPort local port of server socket - * @param queueLen maximum queue length for outstanding - * connection requests (default 5) - * @exception SocketException thrown if unable to create TCP server socket - */ - TCPServerSocket(const string &localAddress, unsigned short localPort, int queueLen = 5) throw(SocketException); - - /** - * Blocks until a new connection is established on this socket or error - * @return new connection socket - * @exception SocketException thrown if attempt to accept a new connection fails - */ - TCPSocket *accept() throw(SocketException); - -private: - void setListen(int queueLen) throw(SocketException); -}; - -/** - * TCP socket class for multi-client servers - */ -class TCPServerSocketM : public TCPServerSocket { -public: - - /** - * Construct a TCP socket for use with a server, accepting connections - * on the specified port on any interface - * @param localPort local port of server socket, a value of zero will - * give a system-assigned unused port - * @param queueLen maximum queue length for outstanding - * connection requests (default 5) - * @exception SocketException thrown if unable to create TCP server socket - */ - TCPServerSocketM(unsigned short localPort, int queueLen = 5) throw(SocketException); - - /** - * Blocks until a new connection is established on this socket or error - * @return new connection socket - * @exception SocketException thrown if attempt to accept a new connection fails - */ - TCPSocket *accept() throw(SocketException); - - /** - * Checks for incoming connections or error - * @return boolean (true if incoming connections are present) - * @exception SocketException thrown if attempt to check for new connections fail - */ - bool pendingConnections() throw(SocketException); - - /** - * Checks for read waiting clients - * @param clients a vector of TCPSocket pointers to get the waiting clients - * @return number of clients waiting - * @exception SocketException thrown if attempt to check for waiting clients fail - */ - int getWaitingClients(vector<TCPSocket *> &clients) throw (SocketException); - - /** - * Closes the connection to a client - * @param client the client TCPSocket to close - */ - void closeClientConnection(TCPSocket *client); - -private: - fd_set fds_master; // master file descriptor list - int fdmax; // maximum file descriptor number - - vector<TCPSocket *> v_clients; -}; - -/** - * UDP socket class - */ -class UDPSocket : public CommunicatingSocket { -public: - /** - * Construct a UDP socket - * @exception SocketException thrown if unable to create UDP socket - */ - UDPSocket() throw(SocketException); - - /** - * Construct a UDP socket with the given local port - * @param localPort local port - * @exception SocketException thrown if unable to create UDP socket - */ - UDPSocket(unsigned short localPort) throw(SocketException); - - /** - * Construct a UDP socket with the given local port and address - * @param localAddress local address - * @param localPort local port - * @exception SocketException thrown if unable to create UDP socket - */ - UDPSocket(const string &localAddress, unsigned short localPort) throw(SocketException); - - /** - * Unset foreign address and port - * @return true if disassociation is successful - * @exception SocketException thrown if unable to disconnect UDP socket - */ - void disconnect() throw(SocketException); - - /** - * Send the given buffer as a UDP datagram to the - * specified address/port - * @param buffer buffer to be written - * @param bufferLen number of bytes to write - * @param foreignAddress address (IP address or name) to send to - * @param foreignPort port number to send to - * @return true if send is successful - * @exception SocketException thrown if unable to send datagram - */ - void sendTo(const void *buffer, int bufferLen, const string &foreignAddress, unsigned short foreignPort) throw(SocketException); - - /** - * Read read up to bufferLen bytes data from this socket. The given buffer - * is where the data will be placed - * @param buffer buffer to receive data - * @param bufferLen maximum number of bytes to receive - * @param sourceAddress address of datagram source - * @param sourcePort port of data source - * @return number of bytes received and -1 for error - * @exception SocketException thrown if unable to receive datagram - */ - int recvFrom(void *buffer, int bufferLen, string &sourceAddress, unsigned short &sourcePort) throw(SocketException); - - /** - * Set the multicast TTL - * @param multicastTTL multicast TTL - * @exception SocketException thrown if unable to set TTL - */ - void setMulticastTTL(unsigned char multicastTTL) throw(SocketException); - - /** - * Join the specified multicast group - * @param multicastGroup multicast group address to join - * @exception SocketException thrown if unable to join group - */ - void joinGroup(const string &multicastGroup) throw(SocketException); - - /** - * Leave the specified multicast group - * @param multicastGroup multicast group address to leave - * @exception SocketException thrown if unable to leave group - */ - void leaveGroup(const string &multicastGroup) throw(SocketException); - -private: - void setBroadcast(); -}; - -} // End of namespace SocketLibrary - -#endif /* !SL_SOCKET_H */ diff --git a/modules/modpy/modules/modpy.py b/modules/modpy/modules/modpy.py index 9a5e578..874a615 100644 --- a/modules/modpy/modules/modpy.py +++ b/modules/modpy/modules/modpy.py @@ -6,15 +6,15 @@ import bitz def init(): - print "init() called"; + print( "init() called" ); def cleanup(): - print "cleanup() called"; + print( "cleanup() called" ); def preview( request ): request = bitz.get_request( request ); req_payload = request['payload']; - print "preview payload: \r\n", req_payload; + print( "preview payload: \r\n", req_payload ); # response if req_payload['ieof']: @@ -27,7 +27,7 @@ def preview( request ): def modify( request ): request = bitz.get_request( request ); req_payload = request['payload']; - print "modify payload: \r\n", req_payload; + print( "modify payload: \r\n", req_payload ); # response resp_payload = {}; diff --git a/src/Makefile.am b/src/Makefile.am index 201a051..b3038cd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,13 +1,13 @@ ## src/ AUTOMAKE_OPTIONS = subdir-objects -AM_CPPFLAGS = -I$(top_srcdir)/lib ${libconfig_CFLAGS} ${log4cpp_CFLAGS} +AM_CPPFLAGS = -I$(top_srcdir)/lib ${libconfig_CFLAGS} ${log4cpp_CFLAGS} ${psocksxx_CFLAGS} bitzincludedir = $(pkgincludedir) sbin_PROGRAMS = bitz-server bitz_server_LDFLAGS = -ldl -export-dynamic -bitz_server_LDADD = $(top_builddir)/lib/socket/libsocket.la \ - $(top_builddir)/lib/icap/libicap.la \ - ${libconfig_LIBS} ${log4cpp_LIBS} +bitz_server_LDADD = $(top_builddir)/lib/icap/libicap.la \ + ${libconfig_LIBS} ${log4cpp_LIBS} \ + ${psocksxx_LIBS} bitz_server_SOURCES = main.cpp \ bitz-server.h bitz-server.cpp \ diff --git a/src/bitz-server.cpp b/src/bitz-server.cpp index c444762..d6257fd 100644 --- a/src/bitz-server.cpp +++ b/src/bitz-server.cpp @@ -416,11 +416,11 @@ namespace bitz { } - void start( int port, unsigned int children, int max_requests ) { + void start( int port, unsigned int children, int max_requests, int comm_timeout ) { try { globals.manager = new bitz::Manager( port ); - globals.manager->spawn( children, max_requests ); + globals.manager->spawn( children, max_requests, comm_timeout ); } catch ( bitz::ManagerException &mex ) { syslog( LOG_ERR, "failed to start, exception: %s", mex.what() ); exit( EXIT_FAILURE ); diff --git a/src/bitz-server.h b/src/bitz-server.h index 87129ad..c7dda05 100644 --- a/src/bitz-server.h +++ b/src/bitz-server.h @@ -95,8 +95,9 @@ namespace bitz { * @param port port number to listen to * @param children number of children to spawn * @param max_request maximum number of requests that a child will serve + * @param comm_timeout communication timeout value in seconds */ - void start( int port, unsigned int children, int max_requests ); + void start( int port, unsigned int children, int max_requests, int comm_timeout ); /** * Run the server managing workers until a termination signal is received. diff --git a/src/bitz/config.cpp b/src/bitz/config.cpp index a9ca856..aaa247f 100644 --- a/src/bitz/config.cpp +++ b/src/bitz/config.cpp @@ -39,6 +39,7 @@ namespace bitz { _config.max_workers = 0; _config.max_worker_requests = 0; + _config.comm_timeout = 0; // defaults _lconfig = NULL; @@ -70,11 +71,11 @@ namespace bitz { try { config->readFile( config_file.c_str() ); - } catch( const libconfig::FileIOException &ex ) { + } catch ( const libconfig::FileIOException &ex ) { std::cerr << "[config] failed to read config file: " << config_file << ", exception: " << ex.what() << std::endl; exit( EXIT_FAILURE ); - } catch( const libconfig::ParseException &pex ) { + } catch ( const libconfig::ParseException &pex ) { std::cerr << "[config] parse error at " << pex.getFile() << ":" << pex.getLine() << " - " << pex.getError() << std::endl; exit( EXIT_FAILURE ); @@ -91,7 +92,9 @@ namespace bitz { config->lookupValue( "max_workers", _config.max_workers ); config->lookupValue( "max_worker_requests", _config.max_worker_requests ); - } catch( const libconfig::SettingNotFoundException &e ) { + config->lookupValue( "comm_timeout", _config.comm_timeout ); + + } catch ( const libconfig::SettingNotFoundException &e ) { std::cerr << "[config] failed to load core configs, " << e.getPath() << " : " << e.what() << std::endl; } @@ -121,7 +124,7 @@ namespace bitz { try { libconfig::Setting &setting = _lconfig->lookup( std::string( "modules." ).append( module ) ); setting.lookupValue( config, config_value ); - } catch( const libconfig::SettingNotFoundException &e ) { + } catch ( const libconfig::SettingNotFoundException &e ) { // TODO: log errors ?? std::cerr << "[config] " << e.getPath() << " : " << e.what() << std::endl; } diff --git a/src/bitz/config.h b/src/bitz/config.h index 453d29d..021384b 100644 --- a/src/bitz/config.h +++ b/src/bitz/config.h @@ -47,6 +47,7 @@ namespace bitz { int port; int max_workers; int max_worker_requests; + int comm_timeout; std::string pid_file; std::string log_file; std::string log_category; diff --git a/src/bitz/manager.cpp b/src/bitz/manager.cpp index ffa2dae..14033a5 100644 --- a/src/bitz/manager.cpp +++ b/src/bitz/manager.cpp @@ -31,8 +31,11 @@ namespace bitz { Manager::Manager( unsigned short port, const std::string &address, int backlog ) throw( ManagerException ) { // initialise manager - _manager.worker = false; - _manager.max_workers = 0; + _manager.worker = false; + _manager.max_workers = 0; + _manager.max_worker_requests = 0; + _manager.comm_timeout = 0; + _manager.workers_count = 0; _manager.worker_id = 0; _manager.socket = NULL; @@ -40,13 +43,16 @@ namespace bitz { // initialise listening socket try { - if ( address.empty() ) { - _manager.socket = new socketlibrary::TCPServerSocket( port, backlog ); - } else { - _manager.socket = new socketlibrary::TCPServerSocket( address, port, backlog ); - } - } catch ( socketlibrary::SocketException &sex ) { - throw ManagerException( "failed to initialise socket" ); + + // network socket address + psocksxx::nsockaddr naddr( address.c_str(), port ); + + _manager.socket = new psocksxx::tcpnsockstream(); + _manager.socket->bind( &naddr, true ); + _manager.socket->listen( backlog ); + + } catch ( psocksxx::sockexception &e ) { + throw ManagerException( std::string( "failed to initialise socket, " ).append( e.what() ) ); } Logger &logger = Logger::instance(); @@ -71,10 +77,11 @@ namespace bitz { } - void Manager::spawn( unsigned int max_workers, unsigned int max_worker_requests ) throw( ManagerException ) { + void Manager::spawn( unsigned int max_workers, unsigned int max_worker_requests, unsigned int comm_timeout ) throw( ManagerException ) { _manager.max_workers = max_workers; _manager.max_worker_requests = max_worker_requests; + _manager.comm_timeout = comm_timeout; _manager.worker_pool = new worker_pool_t[max_workers]; // pre-fork workers @@ -114,7 +121,7 @@ namespace bitz { _manager.worker_pool[worker_id].worker_id = worker_id; _manager.worker_pool[worker_id].worker_pid = worker_pid; - _manager.worker_pool[worker_id].worker->run( _manager.socket, _manager.max_worker_requests ); + _manager.worker_pool[worker_id].worker->run( _manager.socket, _manager.max_worker_requests, _manager.comm_timeout ); logger.info( std::string( "end of cycle, worker[" ).append( util::itoa( worker_id ) ).append( "]" ) ); delete _manager.worker_pool[worker_id].worker; @@ -200,6 +207,9 @@ namespace bitz { void Manager::manager_workers() throw() { + // logger + Logger &logger = Logger::instance(); + if (! _manager.worker ) { // check the worker count @@ -208,8 +218,12 @@ namespace bitz { // we are missing workers, find out who for (unsigned int i = 0; i < _manager.max_workers; i++ ) { if ( _manager.worker_pool[i].worker_pid == 0 ) { - // spawn a worker for the missing - spawn_worker( i ); + try { + // spawn a worker for the missing + spawn_worker( i ); + } catch ( ManagerException &mex ) { + logger.warn( std::string( "[manager] failed to spawn worker[" ).append( util::itoa( i ) ).append( "], exception: ").append( mex.what() ) ); + } } } diff --git a/src/bitz/manager.h b/src/bitz/manager.h index cc15f9c..ce49e9e 100644 --- a/src/bitz/manager.h +++ b/src/bitz/manager.h @@ -20,8 +20,8 @@ #ifndef BITZ_MANAGER_H #define BITZ_MANAGER_H -#include <unistd.h> // pid_t, fork() etc. -#include <socket/socket.h> // socket-library +#include <unistd.h> +#include <psocksxx/tcpnsockstream.h> #include "manager_exception.h" #include "worker.h" @@ -50,10 +50,11 @@ namespace bitz { bool worker; unsigned int max_workers; unsigned int max_worker_requests; + unsigned int comm_timeout; unsigned int workers_count; unsigned int worker_id; - socketlibrary::TCPServerSocket * socket; + psocksxx::tcpnsockstream * socket; worker_pool_t * worker_pool; }; @@ -61,14 +62,17 @@ namespace bitz { /** * Note: backlog = SOMAXCONN (from sys/socket.h) */ - Manager( unsigned short port, const std::string &address = "", int backlog = 128 ) throw( ManagerException ); + Manager( unsigned short port, const std::string &address = "0.0.0.0", int backlog = 128 ) throw( ManagerException ); /** * deconstructor */ virtual ~Manager(); - virtual void spawn( unsigned int max_workers = BITZ_MAX_WORKERS, unsigned int max_worker_requests = BITZ_MAX_WORKER_REQUESTS ) throw( ManagerException ); + virtual void spawn( unsigned int max_workers = BITZ_MAX_WORKERS, + unsigned int max_worker_requests = BITZ_MAX_WORKER_REQUESTS, + unsigned int comm_timeout = 0 ) throw( ManagerException ); + virtual void shutdown( bool graceful = true ) throw(); virtual void reap_worker( pid_t worker_pid ) throw(); virtual void manager_workers() throw(); diff --git a/src/bitz/options_request_handler.cpp b/src/bitz/options_request_handler.cpp index 6872b5c..81def32 100644 --- a/src/bitz/options_request_handler.cpp +++ b/src/bitz/options_request_handler.cpp @@ -26,7 +26,7 @@ namespace bitz { OptionsRequestHandler::~OptionsRequestHandler() { } - icap::Response * OptionsRequestHandler::process( icap::RequestHeader * req_header, socketlibrary::TCPSocket * socket ) throw() { + icap::Response * OptionsRequestHandler::process( icap::RequestHeader * req_header, psocksxx::iosockstream * socket ) throw() { icap::ResponseHeader * header; icap::Response * response; diff --git a/src/bitz/options_request_handler.h b/src/bitz/options_request_handler.h index a81377f..136d111 100644 --- a/src/bitz/options_request_handler.h +++ b/src/bitz/options_request_handler.h @@ -30,7 +30,7 @@ namespace bitz { OptionsRequestHandler(); virtual ~OptionsRequestHandler(); - icap::Response * process( icap::RequestHeader * req_header, socketlibrary::TCPSocket * socket ) throw(); + icap::Response * process( icap::RequestHeader * req_header, psocksxx::iosockstream * socket ) throw(); /** * Register a request handler so it is known to the OPTIONS diff --git a/src/bitz/request_handler.cpp b/src/bitz/request_handler.cpp index 3665cba..56f9bc0 100644 --- a/src/bitz/request_handler.cpp +++ b/src/bitz/request_handler.cpp @@ -63,7 +63,7 @@ namespace bitz { } - icap::Response * RequestHandler::process( icap::RequestHeader * req_header, socketlibrary::TCPSocket * socket ) throw() { + icap::Response * RequestHandler::process( icap::RequestHeader * req_header, psocksxx::iosockstream * socket ) throw() { icap::Request * request; @@ -238,7 +238,7 @@ namespace bitz { } - icap::Response * RequestHandler::process_preview( icap::Request * request, socketlibrary::TCPSocket * socket ) throw() { + icap::Response * RequestHandler::process_preview( icap::Request * request, psocksxx::iosockstream * socket ) throw() { icap::Response * response = NULL; Modifier * modifier; @@ -365,7 +365,7 @@ namespace bitz { } - bool RequestHandler::preview_continue( icap::Response * response, icap::Request * request, socketlibrary::TCPSocket * socket ) throw() { + bool RequestHandler::preview_continue( icap::Response * response, icap::Request * request, psocksxx::iosockstream * socket ) throw() { bool status = false; diff --git a/src/bitz/request_handler.h b/src/bitz/request_handler.h index 3fe99f1..2c31090 100644 --- a/src/bitz/request_handler.h +++ b/src/bitz/request_handler.h @@ -24,7 +24,7 @@ #include <icap/response.h> #include <icap/request.h> -#include <socket/socket.h> +#include <psocksxx/iosockstream.h> namespace bitz { @@ -58,7 +58,7 @@ namespace bitz { * @param socket socket object to read the data from * @return response object */ - virtual icap::Response * process( icap::RequestHeader * req_header, socketlibrary::TCPSocket * socket ) throw(); + virtual icap::Response * process( icap::RequestHeader * req_header, psocksxx::iosockstream * socket ) throw(); protected: @@ -101,7 +101,7 @@ namespace bitz { * @param socket socket object to read data from * @return preview response (response object) */ - icap::Response * process_preview( icap::Request * request, socketlibrary::TCPSocket * socket ) throw(); + icap::Response * process_preview( icap::Request * request, psocksxx::iosockstream * socket ) throw(); /** * This method will use the loaded handler modules to get a response to the request. @@ -119,7 +119,7 @@ namespace bitz { * @param socket socket object to read / write data * @return */ - bool preview_continue( icap::Response * response, icap::Request * request, socketlibrary::TCPSocket * socket ) throw(); + bool preview_continue( icap::Response * response, icap::Request * request, psocksxx::iosockstream * socket ) throw(); private: diff --git a/src/bitz/worker.cpp b/src/bitz/worker.cpp index efbeef3..42fb3d0 100644 --- a/src/bitz/worker.cpp +++ b/src/bitz/worker.cpp @@ -51,65 +51,51 @@ namespace bitz { } - void Worker::run( socketlibrary::TCPServerSocket * server_sock, unsigned int max_requests ) throw() { + void Worker::run( psocksxx::tcpnsockstream * server_sock, unsigned int max_requests, + unsigned int comm_timeout ) throw() { + // logger Logger &logger = Logger::instance(); - socketlibrary::TCPSocket * client_sock; - icap::RequestHeader * req_header; - icap::Response * response; - RequestHandler * req_handler; - + // client socket stream + psocksxx::nsockstream * client_sock; - try { + while ( max_requests > 0 ) { - while ( max_requests > 0 ) { + logger.debug( std::string( "[worker] waiting for a connection" ) ); - logger.debug( std::string( "[worker] waiting for a connection" ) ); + try { + // accept a client connection client_sock = server_sock->accept(); - logger.debug( std::string( "[worker] new connection accepted on " ).append( client_sock->getForeignAddress() ) - .append( ":" ).append( util::itoa( client_sock->getForeignPort() ) ) ); - - // request header - req_header = icap::util::read_req_header( client_sock ); - logger.debug( std::string( "[worker] request header:\r\n" ).append( req_header->raw_data() ) ); - - // try to find a handler for the request - req_handler = util::find_req_handler( _req_handlers, req_header->method() ); - - if ( req_handler != NULL ) { - logger.debug( std::string( "[worker] handling request: " ).append( req_header->method() ) ); - - // process the request and grab the response - response = req_handler->process( req_header, client_sock ); - - } else { - - // unsupported request - logger.info( std::string( "[worker] unsupported request: " ).append( req_header->method() ) ); - response = new icap::Response( new icap::ResponseHeader( icap::ResponseHeader::NOT_ALLOWED ) ); + // FIXME: log accepted client details (e.g. address, port etc.) + logger.debug( std::string( "[worker] new connection accepted on [...]" ) ); + // set timeout value + if ( comm_timeout > 0 ) { + client_sock->timeout( comm_timeout, 0 ); + // TODO: add debug logging } - // send the response back to the client - icap::util::send_response( response, client_sock ); + } catch ( psocksxx::sockexception &e ) { - // cleanup - delete response; - delete req_header; - - // destroy / close connection - delete client_sock; + // failed to accept client connection + logger.error( std::string( "[worker] failed to accept connection: " ).append( e.what() ) ); + // update request count max_requests--; + continue; } - } catch( socketlibrary::SocketException &sex ) { - logger.error( std::string( "[worker] ERROR: " ).append( sex.what() ) ); - } + // handle client request(s) + max_requests = serve_client( client_sock, max_requests ); + + // destroy / close connection + delete client_sock; + + }; } @@ -134,5 +120,76 @@ namespace bitz { } + + unsigned int Worker::serve_client( psocksxx::nsockstream * client_sock, unsigned int max_requests ) throw() { + + // logger + Logger &logger = Logger::instance(); + + icap::RequestHeader * req_header = NULL; + icap::Response * response; + RequestHandler * req_handler; + + + do { + + // cleanup request header + if ( req_header != NULL ) { + delete req_header; + } + + // request header + req_header = icap::util::read_req_header( client_sock ); + logger.debug( std::string( "[worker] request header:\r\n" ).append( req_header->raw_data() ) ); + + // check timeout + if ( client_sock->timedout() ) { + logger.warn( "[worker] communication timed out..." ); + return --max_requests; + } + + // try to find a handler for the request + req_handler = util::find_req_handler( _req_handlers, req_header->method() ); + + // sanity check + if ( req_handler != NULL ) { + + logger.debug( std::string( "[worker] handling request: " ).append( req_header->method() ) ); + + // process the request and grab the response + response = req_handler->process( req_header, client_sock ); + + } else { + + // unsupported request + logger.info( std::string( "[worker] unsupported request: " ).append( req_header->method() ) ); + response = new icap::Response( new icap::ResponseHeader( icap::ResponseHeader::NOT_ALLOWED ) ); + + } + + // FIXME: this should be configurable and should default to close + // connection if the client doesn't send a connection header + if ( req_header->value( "Connection" ) == "keep-alive" ) { + response->header()->attach( "Connection" , "keep-alive" ); + } + + // send the response back to the client + icap::util::send_response( response, client_sock ); + + // cleanup + delete response; + + } while ( ( --max_requests > 0 ) && ( req_header->value( "Connection" ) == "keep-alive" ) ); + + + // cleanup request header + if ( req_header != NULL ) { + delete req_header; + } + + return max_requests; + + } + } /* end of namespace bitz */ diff --git a/src/bitz/worker.h b/src/bitz/worker.h index 69edbca..25b7bac 100644 --- a/src/bitz/worker.h +++ b/src/bitz/worker.h @@ -20,7 +20,7 @@ #ifndef BITZ_WORKER_H #define BITZ_WORKER_H -#include <socket/socket.h> +#include <psocksxx/tcpnsockstream.h> #include "common.h" @@ -32,12 +32,14 @@ namespace bitz { Worker(); virtual ~Worker(); - virtual void run( socketlibrary::TCPServerSocket * server_sock, unsigned int max_requests ) throw(); + virtual void run( psocksxx::tcpnsockstream * server_sock, + unsigned int max_requests, unsigned int comm_timeout = 0 ) throw(); private: req_handlers_t _req_handlers; virtual void load_req_handlers() throw(); + virtual unsigned int serve_client( psocksxx::nsockstream * client_sock, unsigned int max_requests ) throw(); }; diff --git a/src/main.cpp b/src/main.cpp index e00c1c6..7570e3a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,7 +68,7 @@ int main( int argc, char **argv ) { logger.info( std::string( PACKAGE_STRING ) + " initialised" ); // start the server - bitz::server::start( config.port, config.max_workers, config.max_worker_requests ); + bitz::server::start( config.port, config.max_workers, config.max_worker_requests, config.comm_timeout ); // run the server bitz::server::run(); diff --git a/test/icap-client.py b/test/icap-client.py index 622d9ca..be1d895 100644 --- a/test/icap-client.py +++ b/test/icap-client.py @@ -14,16 +14,16 @@ SERVICE = 'icap://icap.server.net/sample-service' PORT = 1344 # OPTIONS -print "----- OPTIONS -----" +print("----- OPTIONS -----") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(1) try: sock.connect((HOST, PORT)) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(2) @@ -40,20 +40,20 @@ while len(data): data = sock.recv(1024) sock.close() -print string +print(string) # REQMOD, GET -print "----- REQMOD - GET -----" +print("----- REQMOD - GET -----") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(1) try: sock.connect((HOST, PORT)) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(2) @@ -78,20 +78,20 @@ while len(data): data = sock.recv(1024) sock.close() -print string +print(string) # REQMOD, POST -print "----- REQMOD - POST -----" +print("----- REQMOD - POST -----") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(1) try: sock.connect((HOST, PORT)) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(2) @@ -118,20 +118,20 @@ while len(data): data = sock.recv(1024) sock.close() -print string +print(string) # REQMOD - Message preview -print "----- REQMOD - Message preview -----" +print("----- REQMOD - Message preview -----") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(1) try: sock.connect((HOST, PORT)) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(2) @@ -158,20 +158,20 @@ while len(data): data = sock.recv(1024) sock.close() -print string +print(string) # RESPMOD -print "----- RESPMOD -----" +print("----- RESPMOD -----") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(1) try: sock.connect((HOST, PORT)) -except socket.error, msg: +except socket.error as msg: sys.stderr.write("[ERROR] %s\n" % msg[1]) sys.exit(2) @@ -204,7 +204,7 @@ while len(data): data = sock.recv(1024) sock.close() -print string +print(string) sys.exit(0) |