diff options
Diffstat (limited to 'rubbos/app/httpd-2.0.64/modules/proxy')
23 files changed, 0 insertions, 8856 deletions
diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/.deps b/rubbos/app/httpd-2.0.64/modules/proxy/.deps deleted file mode 100644 index e69de29b..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/.deps +++ /dev/null diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/.indent.pro b/rubbos/app/httpd-2.0.64/modules/proxy/.indent.pro deleted file mode 100644 index e2cd357a..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/.indent.pro +++ /dev/null @@ -1,58 +0,0 @@ --i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 --TBUFF --TFILE --TTRANS --TUINT4 --T_trans --Tallow_options_t --Tapache_sfio --Tarray_header --Tbool_int --Tapr_bucket_brigade --Tapr_pool_t --Tap_filter_t --Tbuf_area --Tbuff_struct --Tbuffy --Tcmd_how --Tcmd_parms --Tcommand_rec --Tcommand_struct --Tconn_rec --Tcore_dir_config --Tcore_server_config --Tdir_maker_func --Tevent --Tglobals_s --Thandler_func --Thandler_rec --Tjoblist_s --Tlisten_rec --Tmerger_func --Tmode_t --Tmodule --Tmodule_struct --Tmutex --Tn_long --Tother_child_rec --Toverrides_t --Tparent_score --Tpid_t --Tpiped_log --Tpool --Trequest_rec --Trequire_line --Trlim_t --Tscoreboard --Tsemaphore --Tserver_addr_rec --Tserver_rec --Tserver_rec_chain --Tshort_score --Ttable --Ttable_entry --Tthread --Tu_wide_int --Tvtime_t --Twide_int --Tproxy_server_conf diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/CHANGES b/rubbos/app/httpd-2.0.64/modules/proxy/CHANGES deleted file mode 100644 index 73a9228d..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/CHANGES +++ /dev/null @@ -1,223 +0,0 @@ -****************************************** -* PLEASE NOTE: Now that development for * -* mod_proxy has been folded back into * -* the httpd-2.0 tree, this file has * -* been depreciated. Proxy changes should * -* be noted in httpd-2.0's CHANGES file. * -* This file exists for historical * -* purposes. * -****************************************** - -mod_proxy changes for httpd 2.0.29-dev - *) don't do keepalives for sub-requests. [Ian Holsman] - - *) fix up proxypass handling [Ian Holsman] - - *) don't send If-Modified-Since, Cache-Control, or If-None-Match on - a subrequest [Ian Holsman] - -mod_proxy changes for httpd 2.0.26-dev - *) Add New option 'HTTPProxyOverrideReturnedErrors'. By Turning the - Flag on, you will mask the error pages returned by the proxied - server, and will it will be handled as if your server generated - the error. This change was put in so that a 404 on a included - r-proxied component will act in the same manner as a 404 on a - included file. [Ian Holsman <ianh@cnet.com>] - -mod_proxy changes for httpd 2.0.25-dev - - *) Split proxy: space using <Proxy[Match] > directive blocks from - the <Directory[Match] > and <Files[Match] > blocks. Mod_proxy - now bypasses the directory and files testing phase (and skips - the http TRACE default handler on it's own, as well). Note that - <Location > blocks continue to be processed for proxy: requests. - [William Rowe <wrowe@covalent.net>] - - *) apr_uri type/function namespace changes in apr_uri functions - [Doug MacEachern <dougm@covalent.net>] - -mod_proxy changes for httpd 2.0.23-dev - - *) break the proxy_http_handler into multiple smaller functions. - [John Barbee <barbee@veribox.net>] - - *) Fix the proxy when the origin server sends back a 100 - Continue response. [John Barbee <barbee@veribox.net>] - - *) Change 'readbytes' from apr_size_t to apr_off_t due to change - in ap_get_brigade's parameters [John Barbee <barbee@veribox.net>] - -mod_proxy changes for httpd 2.0.20-dev - *) Timeout added for backend connections. - [Victor Orlikowski <v.j.orlikowski@gte.net>] - - *) Fix abort code path in proxy_http.c, similar to FTP fix. - [Chuck Murcko <chuck@topsail.org>] - - *) Fix FTP ABOR command execution path. - [Victor Orlikowski <v.j.orlikowski@gte.net>] - - *) FTP return code variable cleanup; fixed problem in login - [Chuck Murcko <chuck@topsail.org>] - - *) Get PORT working again in the ftp proxy. - [Victor Orlikowski <v.j.orlikowski@gte.net>] - - *) Return result code check for FTP QUIT, after fixing - problems with passive connection handling. - [Victor Orlikowski <v.j.orlikowski@gte.net>] - - *) Reorganize ap_proxy_string_read() internally to not process eos - buckets. - [Chuck Murcko <chuck@topsail.org>] - [Victor Orlikowski <v.j.orlikowski@gte.net>] - - *) Remove result code check for FTP QUIT command. Some servers send - nothing at all back in response to QUIT. - [Chuck Murcko <chuck@topsail.org>] - [Victor Orlikowski <v.j.orlikowski@gte.net>] - -mod_proxy changes for httpd 2.0.19 - - *) Reverse previous patch since the core reverted. - [Chuck Murcko <chuck@topsail.org>] - - *) Remove indirection on number of bytes to read for input filters. - [Chuck Murcko <chuck@topsail.org>] - - *) Fixed a problem with directory listing corruption in the - PROXY_DIR filter. - [Graham Leggett <minfrin@sharp.fm>] - - *) mod_proxy and the proxy submodules now build properly as DSOs. - [Graham Leggett <minfrin@sharp.fm>] - - *) Stopped the HTTP proxy from trying to read entity bodies when there - wasn't one (response was 1xx, 204, 205 or 304). - [Graham Leggett <minfrin@sharp.fm>] - - *) Made sure dates were canonicalised correctly when passed to the client - browser through the HTTP proxy. - [Graham Leggett <minfrin@sharp.fm>] - - *) Split each individual proxy protocol into separate modules. - [Graham Leggett <minfrin@sharp.fm>] - - *) Added Max-Forwards support for all request types so as to prevent - loops. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fix warnings about byte count type on Darwin (connect handler). - [Chuck Murcko <chuck@topsail.org>] - -mod_proxy changes for httpd 2.0.18 - - *) IPV6 EPSV support for IPV6 in FTP proxy. - [Graham Leggett <minfrin@sharp.fm>] - - *) FTP directory filter works now. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fixed some thread-safety issues with the HTTP proxy in mod_proxy. - [Graham Leggett <minfrin@sharp.fm>] - - *) PASV FTP works now. - [Graham Leggett <minfrin@sharp.fm>] - - *) Reworked the line-at-a-time read from the control connection to - workaround a stray empty bucket returned by the HTTP_IN filter. - [Graham Leggett <minfrin@sharp.fm>] - - *) Stopped the CORE filter from sending off an HTTP response when a - CONNECT tunnel was closed. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fixed the poll() loop in proxy_connect.c -> it works now!!! - [Graham Leggett <minfrin@sharp.fm>] - - *) Converted send_dir() to ap_proxy_send_dir_filter() in proxy_ftp.c. - [Graham Leggett <minfrin@sharp.fm>] - -mod_proxy changes for httpd 2.0.17 - - *) Major rework of ap_proxy_ftp_handler() to use filters (begone foul - BUFF!!!). It compiles, but is untested, and the build environment needs - to be fixed to include proxy_ftp.c. - [Graham Leggett <minfrin@sharp.fm>] - - *) Cleanup of dead functions within proxy_util.c. - [Graham Leggett <minfrin@sharp.fm>] - - *) Reworked the storage of the client socket between keepalive connections - to fix some nasty problems with the socket lasting longer than the - memory pool it was allocated from. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fixed bug where a hostname without a "." in it (such as "localhost") - would not trigger an IP address check with ProxyBlock. - [Graham Leggett <minfrin@sharp.fm>] - -mod_proxy changes for httpd 2.0.16 - - *) Fixed ProxyBlock bugs with ap_proxy_http_handler() and - ap_proxy_connect_handler(). - [Graham Leggett <minfrin@sharp.fm>] - - *) Updated ap_proxy_connect_handler() to support APR, while - moving some common code between http_handler and connect_handler - to proxy_util.c. - [Graham Leggett <minfrin@sharp.fm>] - - *) Updated mod_proxy.html docs to include v2.0 configuration. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fixed problem where responses without entity bodies would cause - the directly following proxy keepalive request to fail. - [Graham Leggett <minfrin@sharp.fm>] - -mod_proxy changes for httpd 2.0.15 - - *) Added support for downstream keepalives in mod_proxy. - [Graham Leggett <minfrin@sharp.fm>] - - *) Changed mod_proxy ap_proxy_http_handler() to support APR properly. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fix problem where incoming response headers were not being returned - to the client in mod_proxy. - [Graham Leggett <minfrin@sharp.fm>] - - *) Added X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Server to - reverse proxied request headers in mod_proxy. - [Graham Leggett <minfrin@sharp.fm>] - - *) replace INADDR_NONE with APR_INADDR_NONE [Ian Holsman <IanH@cnet.com>] - - *) Fix problem with proxy configuration where globally set - configuration options were overridden inside virtual hosts. - [Graham Leggett <minfrin@sharp.fm>] - - *) Fix ProxyReceiveBufferSize where default value was left - uninitialised. - [Graham Leggett <minfrin@sharp.fm>] - - *) Some small changes: - - Ensured hop-by-hop headers were stripped as per - RFC2616 13.5.1. - - Upgraded version code to HTTP/1.1. - - Added Connection: close until Keepalives come. - - Some cosmetic fixes and commenting. - [Graham Leggett <minfrin@sharp.fm>] - -mod_proxy changes for httpd 2.0.14 - - *) removed ProxyNoCache and ProxyCacheForceCompletion config directives, - since we no longer directly cache from this module - [Chuck Murcko <chuck@topsail.org>] - - *) removed cache - [Chuck Murcko <chuck@topsail.org>] - - *) initial rerebuild for 2.0 - [Chuck Murcko <chuck@topsail.org>] - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/Makefile b/rubbos/app/httpd-2.0.64/modules/proxy/Makefile deleted file mode 100644 index d1597bdf..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -top_srcdir = /bottlenecks/rubbos/app/httpd-2.0.64 -top_builddir = /bottlenecks/rubbos/app/httpd-2.0.64 -srcdir = /bottlenecks/rubbos/app/httpd-2.0.64/modules/proxy -builddir = /bottlenecks/rubbos/app/httpd-2.0.64/modules/proxy -VPATH = /bottlenecks/rubbos/app/httpd-2.0.64/modules/proxy -# a modules Makefile has no explicit targets -- they will be defined by -# whatever modules are enabled. just grab special.mk to deal with this. -include $(top_srcdir)/build/special.mk diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/Makefile.in b/rubbos/app/httpd-2.0.64/modules/proxy/Makefile.in deleted file mode 100644 index 7c5c149d..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/Makefile.in +++ /dev/null @@ -1,3 +0,0 @@ -# a modules Makefile has no explicit targets -- they will be defined by -# whatever modules are enabled. just grab special.mk to deal with this. -include $(top_srcdir)/build/special.mk diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUmakefile b/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUmakefile deleted file mode 100644 index 61842f0a..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUmakefile +++ /dev/null @@ -1,247 +0,0 @@ -# -# Declare the sub-directories to be built here -# - -SUBDIRS = \ - $(EOLIST) - -# -# Get the 'head' of the build environment. This includes default targets and -# paths to tools -# - -include $(AP_WORK)\build\NWGNUhead.inc - -# -# build this level's files - -# -# Make sure all needed macro's are defined -# - -# -# These directories will be at the beginning of the include list, followed by -# INCDIRS -# -XINCDIRS += \ - $(EOLIST) - -# -# These flags will come after CFLAGS -# -XCFLAGS += \ - $(EOLIST) - -# -# These defines will come after DEFINES -# -XDEFINES += \ - $(EOLIST) - -# -# These flags will be added to the link.opt file -# -XLFLAGS += \ - $(EOLIST) - -# -# These values will be appended to the correct variables based on the value of -# RELEASE -# -ifeq "$(RELEASE)" "debug" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "noopt" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "release" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -# -# These are used by the link target if an NLM is being generated -# This is used by the link 'name' directive to name the nlm. If left blank -# TARGET_nlm (see below) will be used. -# -NLM_NAME = - -# -# This is used by the link '-desc ' directive. -# If left blank, NLM_NAME will be used. -# -NLM_DESCRIPTION = - -# -# This is used by the '-threadname' directive. If left blank, -# NLM_NAME Thread will be used. -# -NLM_THREAD_NAME = - -# -# If this is specified, it will override VERSION value in -# $(AP_WORK)\build\NWGNUenvironment.inc -# -NLM_VERSION = - -# -# If this is specified, it will override the default of 64K -# -NLM_STACK_SIZE = - - -# -# If this is specified it will be used by the link '-entry' directive -# -NLM_ENTRY_SYM = - -# -# If this is specified it will be used by the link '-exit' directive -# -NLM_EXIT_SYM = - -# -# If this is specified it will be used by the link '-check' directive -# -NLM_CHECK_SYM = - -# -# If these are specified it will be used by the link '-flags' directive -# -NLM_FLAGS = - -# -# If this is specified it will be linked in with the XDCData option in the def -# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled -# by setting APACHE_UNIPROC in the environment -# -XDCDATA = - -# -# If there is an NLM target, put it here -# -TARGET_nlm = \ - $(OBJDIR)/proxy.nlm \ - $(OBJDIR)/proxycon.nlm \ - $(OBJDIR)/proxyftp.nlm \ - $(OBJDIR)/proxyhtp.nlm \ - $(EOLIST) - -# -# If there is an LIB target, put it here -# -TARGET_lib = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the NLM target above. -# Paths must all use the '/' character -# -FILES_nlm_objs = \ - $(EOLIST) - -# -# These are the LIB files needed to create the NLM target above. -# These will be added as a library command in the link.opt file. -# -FILES_nlm_libs = \ - $(EOLIST) - -# -# These are the modules that the above NLM target depends on to load. -# These will be added as a module command in the link.opt file. -# -FILES_nlm_modules = \ - $(EOLIST) - -# -# If the nlm has a msg file, put it's path here -# -FILE_nlm_msg = - -# -# If the nlm has a hlp file put it's path here -# -FILE_nlm_hlp = - -# -# If this is specified, it will override $(NWOS)\copyright.txt. -# -FILE_nlm_copyright = - -# -# Any additional imports go here -# -FILES_nlm_Ximports = \ - $(EOLIST) - -# -# Any symbols exported to here -# -FILES_nlm_exports = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the LIB target above. -# Paths must all use the '/' character -# -FILES_lib_objs = \ - $(EOLIST) - -# -# implement targets and dependancies (leave this section alone) -# - -libs :: $(OBJDIR) $(TARGET_lib) - -nlms :: libs $(TARGET_nlm) - -# -# Updated this target to create necessary directories and copy files to the -# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) -# -install :: nlms FORCE - copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* - -# -# Any specialized rules here -# - -# -# Include the 'tail' makefile that has targets that depend on variables defined -# in this makefile -# - -include $(AP_WORK)\build\NWGNUtail.inc - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxy b/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxy deleted file mode 100644 index d6abf6b3..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxy +++ /dev/null @@ -1,261 +0,0 @@ -# -# Make sure all needed macro's are defined -# - -# -# Get the 'head' of the build environment if necessary. This includes default -# targets and paths to tools -# - -ifndef EnvironmentDefined -include $(AP_WORK)\build\NWGNUhead.inc -endif - -# -# These directories will be at the beginning of the include list, followed by -# INCDIRS -# -XINCDIRS += \ - $(APR)/include \ - $(APRUTIL)/include \ - $(AP_WORK)/include \ - $(AP_WORK)/modules/http \ - $(NWOS) \ - $(EOLIST) - -# -# These flags will come after CFLAGS -# -XCFLAGS += \ - $(EOLIST) - -# -# These defines will come after DEFINES -# -XDEFINES += \ - $(EOLIST) - -# -# These flags will be added to the link.opt file -# -XLFLAGS += \ - $(EOLIST) - -# -# These values will be appended to the correct variables based on the value of -# RELEASE -# -ifeq "$(RELEASE)" "debug" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "noopt" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "release" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -# -# These are used by the link target if an NLM is being generated -# This is used by the link 'name' directive to name the nlm. If left blank -# TARGET_nlm (see below) will be used. -# -NLM_NAME = proxy - -# -# This is used by the link '-desc ' directive. -# If left blank, NLM_NAME will be used. -# -NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy Module - -# -# This is used by the '-threadname' directive. If left blank, -# NLM_NAME Thread will be used. -# -NLM_THREAD_NAME = Proxy Module - -# -# If this is specified, it will override VERSION value in -# $(AP_WORK)\build\NWGNUenvironment.inc -# -NLM_VERSION = - -# -# If this is specified, it will override the default of 64K -# -NLM_STACK_SIZE = 8192 - - -# -# If this is specified it will be used by the link '-entry' directive -# -NLM_ENTRY_SYM = _LibCPrelude - -# -# If this is specified it will be used by the link '-exit' directive -# -NLM_EXIT_SYM = _LibCPostlude - -# -# If this is specified it will be used by the link '-check' directive -# -NLM_CHECK_SYM = - -# -# If these are specified it will be used by the link '-flags' directive -# -NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION - -# -# If this is specified it will be linked in with the XDCData option in the def -# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled -# by setting APACHE_UNIPROC in the environment -# -XDCDATA = - -# -# If there is an NLM target, put it here -# -TARGET_nlm = \ - $(OBJDIR)/proxy.nlm \ - $(EOLIST) - -# -# If there is an LIB target, put it here -# -TARGET_lib = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the NLM target above. -# Paths must all use the '/' character -# -FILES_nlm_objs = \ - $(OBJDIR)/mod_proxy.o \ - $(OBJDIR)/proxy_util.o \ - $(OBJDIR)/libprews.o \ - $(EOLIST) - -# -# These are the LIB files needed to create the NLM target above. -# These will be added as a library command in the link.opt file. -# -FILES_nlm_libs = \ - libcpre.o \ - $(EOLIST) - -# -# These are the modules that the above NLM target depends on to load. -# These will be added as a module command in the link.opt file. -# -FILES_nlm_modules = \ - aprlib \ - libc \ - $(EOLIST) - -# -# If the nlm has a msg file, put it's path here -# -FILE_nlm_msg = - -# -# If the nlm has a hlp file put it's path here -# -FILE_nlm_hlp = - -# -# If this is specified, it will override $(NWOS)\copyright.txt. -# -FILE_nlm_copyright = - -# -# Any additional imports go here -# -FILES_nlm_Ximports = \ - @$(APR)/aprlib.imp \ - @$(NWOS)/httpd.imp \ - @libc.imp \ - @ws2nlm.imp \ - $(EOLIST) - -# -# Any symbols exported to here -# -FILES_nlm_exports = \ - proxy_module \ - proxy_hook_scheme_handler \ - proxy_hook_canon_handler \ - ap_proxy_ssl_enable \ - ap_proxy_ssl_disable \ - proxy_run_fixups \ - $(EOLIST) - -# -# These are the OBJ files needed to create the LIB target above. -# Paths must all use the '/' character -# -FILES_lib_objs = \ - $(EOLIST) - -# -# implement targets and dependancies (leave this section alone) -# - -libs :: $(OBJDIR) $(TARGET_lib) - -nlms :: libs $(TARGET_nlm) - -# -# Updated this target to create necessary directories and copy files to the -# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) -# -install :: nlms FORCE - -# -# Any specialized rules here -# - -$(OBJDIR)/%.o: ../arch/netware/%.c $(OBJDIR)\$(NLM_NAME)_cc.opt - @echo compiling $< - $(CC) $< -o=$(OBJDIR)\$(@F) @$(OBJDIR)\$(NLM_NAME)_cc.opt - -# -# Include the 'tail' makefile that has targets that depend on variables defined -# in this makefile -# - -include $(AP_WORK)\build\NWGNUtail.inc - - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxycon b/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxycon deleted file mode 100644 index 07c91f70..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxycon +++ /dev/null @@ -1,254 +0,0 @@ -# -# Make sure all needed macro's are defined -# - -# -# Get the 'head' of the build environment if necessary. This includes default -# targets and paths to tools -# - -ifndef EnvironmentDefined -include $(AP_WORK)\build\NWGNUhead.inc -endif - -# -# These directories will be at the beginning of the include list, followed by -# INCDIRS -# -XINCDIRS += \ - $(APR)/include \ - $(APRUTIL)/include \ - $(AP_WORK)/include \ - $(AP_WORK)/modules/http \ - $(NWOS) \ - $(EOLIST) - -# -# These flags will come after CFLAGS -# -XCFLAGS += \ - $(EOLIST) - -# -# These defines will come after DEFINES -# -XDEFINES += \ - $(EOLIST) - -# -# These flags will be added to the link.opt file -# -XLFLAGS += \ - $(EOLIST) - -# -# These values will be appended to the correct variables based on the value of -# RELEASE -# -ifeq "$(RELEASE)" "debug" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "noopt" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "release" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -# -# These are used by the link target if an NLM is being generated -# This is used by the link 'name' directive to name the nlm. If left blank -# TARGET_nlm (see below) will be used. -# -NLM_NAME = proxycon - -# -# This is used by the link '-desc ' directive. -# If left blank, NLM_NAME will be used. -# -NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy Connection Sub-Module - -# -# This is used by the '-threadname' directive. If left blank, -# NLM_NAME Thread will be used. -# -NLM_THREAD_NAME = Proxy Conn Module - -# -# If this is specified, it will override VERSION value in -# $(AP_WORK)\build\NWGNUenvironment.inc -# -NLM_VERSION = - -# -# If this is specified, it will override the default of 64K -# -NLM_STACK_SIZE = 8192 - - -# -# If this is specified it will be used by the link '-entry' directive -# -NLM_ENTRY_SYM = _LibCPrelude - -# -# If this is specified it will be used by the link '-exit' directive -# -NLM_EXIT_SYM = _LibCPostlude - -# -# If this is specified it will be used by the link '-check' directive -# -NLM_CHECK_SYM = - -# -# If these are specified it will be used by the link '-flags' directive -# -NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION - -# -# If this is specified it will be linked in with the XDCData option in the def -# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled -# by setting APACHE_UNIPROC in the environment -# -XDCDATA = - -# -# If there is an NLM target, put it here -# -TARGET_nlm = \ - $(OBJDIR)/proxycon.nlm \ - $(EOLIST) - -# -# If there is an LIB target, put it here -# -TARGET_lib = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the NLM target above. -# Paths must all use the '/' character -# -FILES_nlm_objs = \ - $(OBJDIR)/proxy_connect.o \ - $(OBJDIR)/proxy_util.o \ - $(EOLIST) - -# -# These are the LIB files needed to create the NLM target above. -# These will be added as a library command in the link.opt file. -# -FILES_nlm_libs = \ - libcpre.o \ - $(EOLIST) - -# -# These are the modules that the above NLM target depends on to load. -# These will be added as a module command in the link.opt file. -# -FILES_nlm_modules = \ - aprlib \ - libc \ - proxy \ - $(EOLIST) - -# -# If the nlm has a msg file, put it's path here -# -FILE_nlm_msg = - -# -# If the nlm has a hlp file put it's path here -# -FILE_nlm_hlp = - -# -# If this is specified, it will override $(NWOS)\copyright.txt. -# -FILE_nlm_copyright = - -# -# Any additional imports go here -# -FILES_nlm_Ximports = \ - @$(APR)/aprlib.imp \ - @$(NWOS)/httpd.imp \ - @libc.imp \ - proxy_module \ - proxy_hook_scheme_handler \ - proxy_hook_canon_handler \ - $(EOLIST) - -# -# Any symbols exported to here -# -FILES_nlm_exports = \ - proxy_connect_module \ - $(EOLIST) - -# -# These are the OBJ files needed to create the LIB target above. -# Paths must all use the '/' character -# -FILES_lib_objs = \ - $(EOLIST) - -# -# implement targets and dependancies (leave this section alone) -# - -libs :: $(OBJDIR) $(TARGET_lib) - -nlms :: libs $(TARGET_nlm) - -# -# Updated this target to create necessary directories and copy files to the -# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) -# -install :: nlms FORCE - -# -# Any specialized rules here -# - -# -# Include the 'tail' makefile that has targets that depend on variables defined -# in this makefile -# - -include $(AP_WORK)\build\NWGNUtail.inc - - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxyftp b/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxyftp deleted file mode 100644 index bd5d527c..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxyftp +++ /dev/null @@ -1,260 +0,0 @@ -# -# Make sure all needed macro's are defined -# - -# -# Get the 'head' of the build environment if necessary. This includes default -# targets and paths to tools -# - -ifndef EnvironmentDefined -include $(AP_WORK)\build\NWGNUhead.inc -endif - -# -# These directories will be at the beginning of the include list, followed by -# INCDIRS -# -XINCDIRS += \ - $(APR)/include \ - $(APRUTIL)/include \ - $(AP_WORK)/include \ - $(AP_WORK)/modules/http \ - $(NWOS) \ - $(EOLIST) - -# -# These flags will come after CFLAGS -# -XCFLAGS += \ - $(EOLIST) - -# -# These defines will come after DEFINES -# -XDEFINES += \ - $(EOLIST) - -# -# These flags will be added to the link.opt file -# -XLFLAGS += \ - $(EOLIST) - -# -# These values will be appended to the correct variables based on the value of -# RELEASE -# -ifeq "$(RELEASE)" "debug" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "noopt" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "release" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -# -# These are used by the link target if an NLM is being generated -# This is used by the link 'name' directive to name the nlm. If left blank -# TARGET_nlm (see below) will be used. -# -NLM_NAME = proxyftp - -# -# This is used by the link '-desc ' directive. -# If left blank, NLM_NAME will be used. -# -NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy FTP Sub-Module - -# -# This is used by the '-threadname' directive. If left blank, -# NLM_NAME Thread will be used. -# -NLM_THREAD_NAME = Proxy FTP Module - -# -# If this is specified, it will override VERSION value in -# $(AP_WORK)\build\NWGNUenvironment.inc -# -NLM_VERSION = - -# -# If this is specified, it will override the default of 64K -# -NLM_STACK_SIZE = 8192 - - -# -# If this is specified it will be used by the link '-entry' directive -# -NLM_ENTRY_SYM = _LibCPrelude - -# -# If this is specified it will be used by the link '-exit' directive -# -NLM_EXIT_SYM = _LibCPostlude - -# -# If this is specified it will be used by the link '-check' directive -# -NLM_CHECK_SYM = - -# -# If these are specified it will be used by the link '-flags' directive -# -NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION - -# -# If this is specified it will be linked in with the XDCData option in the def -# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled -# by setting APACHE_UNIPROC in the environment -# -XDCDATA = - -# -# If there is an NLM target, put it here -# -TARGET_nlm = \ - $(OBJDIR)/proxyftp.nlm \ - $(EOLIST) - -# -# If there is an LIB target, put it here -# -TARGET_lib = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the NLM target above. -# Paths must all use the '/' character -# -FILES_nlm_objs = \ - $(OBJDIR)/proxy_ftp.o \ - $(OBJDIR)/proxy_util.o \ - $(OBJDIR)/libprews.o \ - $(EOLIST) - -# -# These are the LIB files needed to create the NLM target above. -# These will be added as a library command in the link.opt file. -# -FILES_nlm_libs = \ - libcpre.o \ - $(EOLIST) - -# -# These are the modules that the above NLM target depends on to load. -# These will be added as a module command in the link.opt file. -# -FILES_nlm_modules = \ - aprlib \ - libc \ - proxy \ - $(EOLIST) - -# -# If the nlm has a msg file, put it's path here -# -FILE_nlm_msg = - -# -# If the nlm has a hlp file put it's path here -# -FILE_nlm_hlp = - -# -# If this is specified, it will override $(NWOS)\copyright.txt. -# -FILE_nlm_copyright = - -# -# Any additional imports go here -# -FILES_nlm_Ximports = \ - @$(APR)/aprlib.imp \ - @$(NWOS)/httpd.imp \ - @libc.imp \ - @ws2nlm.imp \ - proxy_module \ - proxy_hook_scheme_handler \ - proxy_hook_canon_handler \ - $(EOLIST) - -# -# Any symbols exported to here -# -FILES_nlm_exports = \ - proxy_ftp_module \ - $(EOLIST) - -# -# These are the OBJ files needed to create the LIB target above. -# Paths must all use the '/' character -# -FILES_lib_objs = \ - $(EOLIST) - -# -# implement targets and dependancies (leave this section alone) -# - -libs :: $(OBJDIR) $(TARGET_lib) - -nlms :: libs $(TARGET_nlm) - -# -# Updated this target to create necessary directories and copy files to the -# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) -# -install :: nlms FORCE - -# -# Any specialized rules here -# - -$(OBJDIR)/%.o: ../arch/netware/%.c $(OBJDIR)\$(NLM_NAME)_cc.opt - @echo compiling $< - $(CC) $< -o=$(OBJDIR)\$(@F) @$(OBJDIR)\$(NLM_NAME)_cc.opt - -# -# Include the 'tail' makefile that has targets that depend on variables defined -# in this makefile -# - -include $(AP_WORK)\build\NWGNUtail.inc - - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxyhtp b/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxyhtp deleted file mode 100644 index 5fda2693..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/NWGNUproxyhtp +++ /dev/null @@ -1,263 +0,0 @@ -# -# Make sure all needed macro's are defined -# - -# -# Get the 'head' of the build environment if necessary. This includes default -# targets and paths to tools -# - -ifndef EnvironmentDefined -include $(AP_WORK)\build\NWGNUhead.inc -endif - -# -# These directories will be at the beginning of the include list, followed by -# INCDIRS -# -XINCDIRS += \ - $(APR)/include \ - $(APRUTIL)/include \ - $(AP_WORK)/include \ - $(AP_WORK)/modules/http \ - $(NWOS) \ - $(EOLIST) - -# -# These flags will come after CFLAGS -# -XCFLAGS += \ - $(EOLIST) - -# -# These defines will come after DEFINES -# -XDEFINES += \ - $(EOLIST) - -# -# These flags will be added to the link.opt file -# -XLFLAGS += \ - $(EOLIST) - -# -# These values will be appended to the correct variables based on the value of -# RELEASE -# -ifeq "$(RELEASE)" "debug" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "noopt" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -ifeq "$(RELEASE)" "release" -XINCDIRS += \ - $(EOLIST) - -XCFLAGS += \ - $(EOLIST) - -XDEFINES += \ - $(EOLIST) - -XLFLAGS += \ - $(EOLIST) -endif - -# -# These are used by the link target if an NLM is being generated -# This is used by the link 'name' directive to name the nlm. If left blank -# TARGET_nlm (see below) will be used. -# -NLM_NAME = proxyhtp - -# -# This is used by the link '-desc ' directive. -# If left blank, NLM_NAME will be used. -# -NLM_DESCRIPTION = Apache $(VERSION_STR) Proxy HTTP Sub-Module - -# -# This is used by the '-threadname' directive. If left blank, -# NLM_NAME Thread will be used. -# -NLM_THREAD_NAME = Proxy HTTP Module - -# -# If this is specified, it will override VERSION value in -# $(AP_WORK)\build\NWGNUenvironment.inc -# -NLM_VERSION = - -# -# If this is specified, it will override the default of 64K -# -NLM_STACK_SIZE = 8192 - - -# -# If this is specified it will be used by the link '-entry' directive -# -NLM_ENTRY_SYM = _LibCPrelude - -# -# If this is specified it will be used by the link '-exit' directive -# -NLM_EXIT_SYM = _LibCPostlude - -# -# If this is specified it will be used by the link '-check' directive -# -NLM_CHECK_SYM = - -# -# If these are specified it will be used by the link '-flags' directive -# -NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION - -# -# If this is specified it will be linked in with the XDCData option in the def -# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled -# by setting APACHE_UNIPROC in the environment -# -XDCDATA = - -# -# If there is an NLM target, put it here -# -TARGET_nlm = \ - $(OBJDIR)/proxyhtp.nlm \ - $(EOLIST) - -# -# If there is an LIB target, put it here -# -TARGET_lib = \ - $(EOLIST) - -# -# These are the OBJ files needed to create the NLM target above. -# Paths must all use the '/' character -# -FILES_nlm_objs = \ - $(OBJDIR)/proxy_http.o \ - $(OBJDIR)/proxy_util.o \ - $(OBJDIR)/libprews.o \ - $(EOLIST) - -# -# These are the LIB files needed to create the NLM target above. -# These will be added as a library command in the link.opt file. -# -FILES_nlm_libs = \ - libcpre.o \ - $(EOLIST) - -# -# These are the modules that the above NLM target depends on to load. -# These will be added as a module command in the link.opt file. -# -FILES_nlm_modules = \ - aprlib \ - libc \ - proxy \ - $(EOLIST) - -# -# If the nlm has a msg file, put it's path here -# -FILE_nlm_msg = - -# -# If the nlm has a hlp file put it's path here -# -FILE_nlm_hlp = - -# -# If this is specified, it will override $(NWOS)\copyright.txt. -# -FILE_nlm_copyright = - -# -# Any additional imports go here -# -FILES_nlm_Ximports = \ - @$(APR)/aprlib.imp \ - @$(NWOS)/httpd.imp \ - @libc.imp \ - @ws2nlm.imp \ - proxy_module \ - proxy_hook_scheme_handler \ - proxy_hook_canon_handler \ - proxy_run_fixups \ - ap_proxy_ssl_enable \ - ap_proxy_ssl_disable \ - $(EOLIST) - -# -# Any symbols exported to here -# -FILES_nlm_exports = \ - proxy_http_module \ - $(EOLIST) - -# -# These are the OBJ files needed to create the LIB target above. -# Paths must all use the '/' character -# -FILES_lib_objs = \ - $(EOLIST) - -# -# implement targets and dependancies (leave this section alone) -# - -libs :: $(OBJDIR) $(TARGET_lib) - -nlms :: libs $(TARGET_nlm) - -# -# Updated this target to create necessary directories and copy files to the -# correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) -# -install :: nlms FORCE - -# -# Any specialized rules here -# - -$(OBJDIR)/%.o: ../arch/netware/%.c $(OBJDIR)\$(NLM_NAME)_cc.opt - @echo compiling $< - $(CC) $< -o=$(OBJDIR)\$(@F) @$(OBJDIR)\$(NLM_NAME)_cc.opt - -# -# Include the 'tail' makefile that has targets that depend on variables defined -# in this makefile -# - -include $(AP_WORK)\build\NWGNUtail.inc - - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/config.m4 b/rubbos/app/httpd-2.0.64/modules/proxy/config.m4 deleted file mode 100644 index d33683e9..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/config.m4 +++ /dev/null @@ -1,34 +0,0 @@ -dnl modules enabled in this directory by default - -APACHE_MODPATH_INIT(proxy) - -if test "$enable_proxy" = "shared"; then - proxy_mods_enable=shared -elif test "$enable_proxy" = "yes"; then - proxy_mods_enable=yes -else - proxy_mods_enable=no -fi - -proxy_objs="mod_proxy.lo proxy_util.lo" -APACHE_MODULE(proxy, Apache proxy module, $proxy_objs, , $proxy_mods_enable) - -proxy_connect_objs="proxy_connect.lo" -proxy_ftp_objs="proxy_ftp.lo" -proxy_http_objs="proxy_http.lo" - -case "$host" in - *os2*) - # OS/2 DLLs must resolve all symbols at build time and - # these sub-modules need some from the main proxy module - proxy_connect_objs="$proxy_connect_objs mod_proxy.la" - proxy_ftp_objs="$proxy_ftp_objs mod_proxy.la" - proxy_http_objs="$proxy_http_objs mod_proxy.la" - ;; -esac - -APACHE_MODULE(proxy_connect, Apache proxy CONNECT module, $proxy_connect_objs, , $proxy_mods_enable) -APACHE_MODULE(proxy_ftp, Apache proxy FTP module, $proxy_ftp_objs, , $proxy_mods_enable) -APACHE_MODULE(proxy_http, Apache proxy HTTP module, $proxy_http_objs, , $proxy_mods_enable) - -APACHE_MODPATH_FINISH diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/libproxy.exp b/rubbos/app/httpd-2.0.64/modules/proxy/libproxy.exp deleted file mode 100644 index a20f2378..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/libproxy.exp +++ /dev/null @@ -1 +0,0 @@ -proxy_module diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.c b/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.c deleted file mode 100644 index 84d5fb10..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.c +++ /dev/null @@ -1,1181 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define CORE_PRIVATE - -#include "mod_proxy.h" -#include "mod_core.h" - -#include "apr_optional.h" - -#ifndef MAX -#define MAX(x,y) ((x) >= (y) ? (x) : (y)) -#endif - -/* - * A Web proxy module. Stages: - * - * translate_name: set filename to proxy:<URL> - * map_to_storage: run proxy_walk (rather than directory_walk/file_walk) - * can't trust directory_walk/file_walk since these are - * not in our filesystem. Prevents mod_http from serving - * the TRACE request we will set aside to handle later. - * type_checker: set type to PROXY_MAGIC_TYPE if filename begins proxy: - * fix_ups: convert the URL stored in the filename to the - * canonical form. - * handler: handle proxy requests - */ - -/* -------------------------------------------------------------- */ -/* Translate the URL into a 'filename' */ - -static int alias_match(const char *uri, const char *alias_fakename) -{ - const char *end_fakename = alias_fakename + strlen(alias_fakename); - const char *aliasp = alias_fakename, *urip = uri; - - while (aliasp < end_fakename) { - if (*aliasp == '/') { - /* any number of '/' in the alias matches any number in - * the supplied URI, but there must be at least one... - */ - if (*urip != '/') - return 0; - - while (*aliasp == '/') - ++aliasp; - while (*urip == '/') - ++urip; - } - else { - /* Other characters are compared literally */ - if (*urip++ != *aliasp++) - return 0; - } - } - - /* Check last alias path component matched all the way */ - - if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/') - return 0; - - /* Return number of characters from URI which matched (may be - * greater than length of alias, since we may have matched - * doubled slashes) - */ - - return urip - uri; -} - -/* Detect if an absoluteURI should be proxied or not. Note that we - * have to do this during this phase because later phases are - * "short-circuiting"... i.e. translate_names will end when the first - * module returns OK. So for example, if the request is something like: - * - * GET http://othervhost/cgi-bin/printenv HTTP/1.0 - * - * mod_alias will notice the /cgi-bin part and ScriptAlias it and - * short-circuit the proxy... just because of the ordering in the - * configuration file. - */ -static int proxy_detect(request_rec *r) -{ - void *sconf = r->server->module_config; - proxy_server_conf *conf; - - conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - - /* Ick... msvc (perhaps others) promotes ternary short results to int */ - - if (conf->req && r->parsed_uri.scheme) { - /* but it might be something vhosted */ - if (!(r->parsed_uri.hostname - && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r)) - && ap_matches_request_vhost(r, r->parsed_uri.hostname, - (apr_port_t)(r->parsed_uri.port_str ? r->parsed_uri.port - : ap_default_port(r))))) { - r->proxyreq = PROXYREQ_PROXY; - r->uri = r->unparsed_uri; - r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); - r->handler = "proxy-server"; - } - } - /* We need special treatment for CONNECT proxying: it has no scheme part */ - else if (conf->req && r->method_number == M_CONNECT - && r->parsed_uri.hostname - && r->parsed_uri.port_str) { - r->proxyreq = PROXYREQ_PROXY; - r->uri = r->unparsed_uri; - r->filename = apr_pstrcat(r->pool, "proxy:", r->uri, NULL); - r->handler = "proxy-server"; - } - return DECLINED; -} - -static int proxy_trans(request_rec *r) -{ - void *sconf = r->server->module_config; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - int i, len; - struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts; - - if (r->proxyreq) { - /* someone has already set up the proxy, it was possibly ourselves - * in proxy_detect - */ - return OK; - } - - /* XXX: since r->uri has been manipulated already we're not really - * compliant with RFC1945 at this point. But this probably isn't - * an issue because this is a hybrid proxy/origin server. - */ - - for (i = 0; i < conf->aliases->nelts; i++) { - len = alias_match(r->uri, ent[i].fake); - - if (len > 0) { - if ((ent[i].real[0] == '!' ) && ( ent[i].real[1] == 0 )) { - return DECLINED; - } - - r->filename = apr_pstrcat(r->pool, "proxy:", ent[i].real, - (r->uri + len ), NULL); - r->handler = "proxy-server"; - r->proxyreq = PROXYREQ_REVERSE; - return OK; - } - } - return DECLINED; -} - -static int proxy_walk(request_rec *r) -{ - proxy_server_conf *sconf = ap_get_module_config(r->server->module_config, - &proxy_module); - ap_conf_vector_t *per_dir_defaults = r->server->lookup_defaults; - ap_conf_vector_t **sec_proxy = (ap_conf_vector_t **) sconf->sec_proxy->elts; - ap_conf_vector_t *entry_config; - proxy_dir_conf *entry_proxy; - int num_sec = sconf->sec_proxy->nelts; - /* XXX: shouldn't we use URI here? Canonicalize it first? - * Pass over "proxy:" prefix - */ - const char *proxyname = r->filename + 6; - int j; - - for (j = 0; j < num_sec; ++j) - { - entry_config = sec_proxy[j]; - entry_proxy = ap_get_module_config(entry_config, &proxy_module); - - /* XXX: What about case insensitive matching ??? - * Compare regex, fnmatch or string as appropriate - * If the entry doesn't relate, then continue - */ - if (entry_proxy->r - ? ap_regexec(entry_proxy->r, proxyname, 0, NULL, 0) - : (entry_proxy->p_is_fnmatch - ? apr_fnmatch(entry_proxy->p, proxyname, 0) - : strncmp(proxyname, entry_proxy->p, - strlen(entry_proxy->p)))) { - continue; - } - per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults, - entry_config); - } - - r->per_dir_config = per_dir_defaults; - - return OK; -} - -static int proxy_map_location(request_rec *r) -{ - int access_status; - - if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) - return DECLINED; - - /* Don't let the core or mod_http map_to_storage hooks handle this, - * We don't need directory/file_walk, and we want to TRACE on our own. - */ - if ((access_status = proxy_walk(r))) { - ap_die(access_status, r); - return access_status; - } - - return OK; -} - -/* -------------------------------------------------------------- */ -/* Fixup the filename */ - -/* - * Canonicalise the URL - */ -static int proxy_fixup(request_rec *r) -{ - char *url, *p; - int access_status; - - if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) - return DECLINED; - - /* XXX: Shouldn't we try this before we run the proxy_walk? */ - url = &r->filename[6]; - - /* canonicalise each specific scheme */ - if ((access_status = proxy_run_canon_handler(r, url))) { - return access_status; - } - - p = strchr(url, ':'); - if (p == NULL || p == url) - return HTTP_BAD_REQUEST; - - return OK; /* otherwise; we've done the best we can */ -} - -/* Send a redirection if the request contains a hostname which is not */ -/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */ -/* servers like Netscape's allow this and access hosts from the local */ -/* domain in this case. I think it is better to redirect to a FQDN, since */ -/* these will later be found in the bookmarks files. */ -/* The "ProxyDomain" directive determines what domain will be appended */ -static int proxy_needsdomain(request_rec *r, const char *url, const char *domain) -{ - char *nuri; - const char *ref; - - /* We only want to worry about GETs */ - if (!r->proxyreq || r->method_number != M_GET || !r->parsed_uri.hostname) - return DECLINED; - - /* If host does contain a dot already, or it is "localhost", decline */ - if (strchr(r->parsed_uri.hostname, '.') != NULL - || strcasecmp(r->parsed_uri.hostname, "localhost") == 0) - return DECLINED; /* host name has a dot already */ - - ref = apr_table_get(r->headers_in, "Referer"); - - /* Reassemble the request, but insert the domain after the host name */ - /* Note that the domain name always starts with a dot */ - r->parsed_uri.hostname = apr_pstrcat(r->pool, r->parsed_uri.hostname, - domain, NULL); - nuri = apr_uri_unparse(r->pool, - &r->parsed_uri, - APR_URI_UNP_REVEALPASSWORD); - - apr_table_set(r->headers_out, "Location", nuri); - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "Domain missing: %s sent to %s%s%s", r->uri, - apr_uri_unparse(r->pool, &r->parsed_uri, - APR_URI_UNP_OMITUSERINFO), - ref ? " from " : "", ref ? ref : ""); - - return HTTP_MOVED_PERMANENTLY; -} - -/* -------------------------------------------------------------- */ -/* Invoke handler */ - -static int proxy_handler(request_rec *r) -{ - char *url, *scheme, *p; - const char *p2; - void *sconf = r->server->module_config; - proxy_server_conf *conf = (proxy_server_conf *) - ap_get_module_config(sconf, &proxy_module); - apr_array_header_t *proxies = conf->proxies; - struct proxy_remote *ents = (struct proxy_remote *) proxies->elts; - int i, rc, access_status; - int direct_connect = 0; - const char *str; - long maxfwd; - - /* is this for us? */ - if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) - return DECLINED; - - /* handle max-forwards / OPTIONS / TRACE */ - if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) { - maxfwd = strtol(str, NULL, 10); - if (maxfwd < 1) { - switch (r->method_number) { - case M_TRACE: { - int access_status; - r->proxyreq = PROXYREQ_NONE; - if ((access_status = ap_send_http_trace(r))) - ap_die(access_status, r); - else - ap_finalize_request_protocol(r); - return OK; - } - case M_OPTIONS: { - int access_status; - r->proxyreq = PROXYREQ_NONE; - if ((access_status = ap_send_http_options(r))) - ap_die(access_status, r); - else - ap_finalize_request_protocol(r); - return OK; - } - default: { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Max-Forwards has reached zero - proxy loop?"); - } - } - } - maxfwd = (maxfwd > 0) ? maxfwd - 1 : 0; - } - else { - /* set configured max-forwards */ - maxfwd = conf->maxfwd; - } - apr_table_set(r->headers_in, "Max-Forwards", - apr_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd : 0)); - - if (r->method_number == M_TRACE) { - core_server_config *coreconf = (core_server_config *) - ap_get_module_config(sconf, &core_module); - - if (coreconf->trace_enable == AP_TRACE_DISABLE) - { - /* Allow "error-notes" string to be printed by ap_send_error_response() - * Note; this goes nowhere, canned error response need an overhaul. - */ - apr_table_setn(r->notes, "error-notes", - "TRACE forbidden by server configuration"); - apr_table_setn(r->notes, "verbose-error-to", "*"); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: TRACE forbidden by server configuration"); - return HTTP_FORBIDDEN; - } - - /* Can't test ap_should_client_block, we aren't ready to send - * the client a 100 Continue response till the connection has - * been established - */ - if (coreconf->trace_enable != AP_TRACE_EXTENDED - && (r->read_length || r->read_chunked || r->remaining)) - { - /* Allow "error-notes" string to be printed by ap_send_error_response() - * Note; this goes nowhere, canned error response need an overhaul. - */ - apr_table_setn(r->notes, "error-notes", - "TRACE with request body is not allowed"); - apr_table_setn(r->notes, "verbose-error-to", "*"); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: TRACE with request body is not allowed"); - return HTTP_REQUEST_ENTITY_TOO_LARGE; - } - } - - url = r->filename + 6; - p = strchr(url, ':'); - if (p == NULL) - return HTTP_BAD_REQUEST; - - /* If the host doesn't have a domain name, add one and redirect. */ - if (conf->domain != NULL) { - rc = proxy_needsdomain(r, url, conf->domain); - if (ap_is_HTTP_REDIRECT(rc)) - return HTTP_MOVED_PERMANENTLY; - } - - *p = '\0'; - scheme = apr_pstrdup(r->pool, url); - *p = ':'; - - /* Check URI's destination host against NoProxy hosts */ - /* Bypass ProxyRemote server lookup if configured as NoProxy */ - /* we only know how to handle communication to a proxy via http */ - /*if (strcasecmp(scheme, "http") == 0) */ - { - int ii; - struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts; - - for (direct_connect = ii = 0; ii < conf->dirconn->nelts && !direct_connect; ii++) { - direct_connect = list[ii].matcher(&list[ii], r); - } -#if DEBUGGING - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - (direct_connect) ? "NoProxy for %s" : "UseProxy for %s", - r->uri); -#endif - } - - /* firstly, try a proxy, unless a NoProxy directive is active */ - if (!direct_connect) { - for (i = 0; i < proxies->nelts; i++) { - p2 = ap_strchr_c(ents[i].scheme, ':'); /* is it a partial URL? */ - if (strcmp(ents[i].scheme, "*") == 0 || - (ents[i].use_regex && - ap_regexec(ents[i].regexp, url, 0,NULL, 0) == 0) || - (p2 == NULL && strcasecmp(scheme, ents[i].scheme) == 0) || - (p2 != NULL && - strncasecmp(url, ents[i].scheme, strlen(ents[i].scheme)) == 0)) { - - /* handle the scheme */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Trying to run scheme_handler against proxy"); - access_status = proxy_run_scheme_handler(r, conf, url, ents[i].hostname, ents[i].port); - - /* an error or success */ - if (access_status != DECLINED && access_status != HTTP_BAD_GATEWAY) { - return access_status; - } - /* we failed to talk to the upstream proxy */ - } - } - } - - /* otherwise, try it direct */ - /* N.B. what if we're behind a firewall, where we must use a proxy or - * give up?? - */ - - /* handle the scheme */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Trying to run scheme_handler"); - access_status = proxy_run_scheme_handler(r, conf, url, NULL, 0); - if (DECLINED == access_status) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: No protocol handler was valid for the URL %s. " - "If you are using a DSO version of mod_proxy, make sure " - "the proxy submodules are included in the configuration " - "using LoadModule.", r->uri); - return HTTP_FORBIDDEN; - } - return access_status; -} - -/* -------------------------------------------------------------- */ -/* Setup configurable data */ - -static void * create_proxy_config(apr_pool_t *p, server_rec *s) -{ - proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf)); - - ps->sec_proxy = apr_array_make(p, 10, sizeof(ap_conf_vector_t *)); - ps->proxies = apr_array_make(p, 10, sizeof(struct proxy_remote)); - ps->aliases = apr_array_make(p, 10, sizeof(struct proxy_alias)); - ps->raliases = apr_array_make(p, 10, sizeof(struct proxy_alias)); - ps->noproxies = apr_array_make(p, 10, sizeof(struct noproxy_entry)); - ps->dirconn = apr_array_make(p, 10, sizeof(struct dirconn_entry)); - ps->allowed_connect_ports = apr_array_make(p, 10, sizeof(int)); - ps->domain = NULL; - ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */ - ps->viaopt_set = 0; /* 0 means default */ - ps->req = 0; - ps->req_set = 0; - ps->recv_buffer_size = 0; /* this default was left unset for some reason */ - ps->recv_buffer_size_set = 0; - ps->io_buffer_size = AP_IOBUFSIZE; - ps->io_buffer_size_set = 0; - ps->maxfwd = DEFAULT_MAX_FORWARDS; - ps->maxfwd_set = 0; - ps->error_override = 0; - ps->error_override_set = 0; - ps->preserve_host_set = 0; - ps->preserve_host = 0; - ps->timeout = 0; - ps->timeout_set = 0; - ps->badopt = bad_error; - ps->badopt_set = 0; - return ps; -} - -static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) -{ - proxy_server_conf *ps = apr_pcalloc(p, sizeof(proxy_server_conf)); - proxy_server_conf *base = (proxy_server_conf *) basev; - proxy_server_conf *overrides = (proxy_server_conf *) overridesv; - - ps->proxies = apr_array_append(p, base->proxies, overrides->proxies); - ps->sec_proxy = apr_array_append(p, base->sec_proxy, overrides->sec_proxy); - ps->aliases = apr_array_append(p, base->aliases, overrides->aliases); - ps->raliases = apr_array_append(p, base->raliases, overrides->raliases); - ps->noproxies = apr_array_append(p, base->noproxies, overrides->noproxies); - ps->dirconn = apr_array_append(p, base->dirconn, overrides->dirconn); - ps->allowed_connect_ports = apr_array_append(p, base->allowed_connect_ports, overrides->allowed_connect_ports); - - ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain; - ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt; - ps->viaopt_set = overrides->viaopt_set || base->viaopt_set; - ps->req = (overrides->req_set == 0) ? base->req : overrides->req; - ps->req_set = overrides->req_set || base->req_set; - ps->recv_buffer_size = (overrides->recv_buffer_size_set == 0) ? base->recv_buffer_size : overrides->recv_buffer_size; - ps->recv_buffer_size_set = overrides->recv_buffer_size_set || base->recv_buffer_size_set; - ps->io_buffer_size = (overrides->io_buffer_size_set == 0) ? base->io_buffer_size : overrides->io_buffer_size; - ps->io_buffer_size_set = overrides->io_buffer_size_set || base->io_buffer_size_set; - ps->maxfwd = (overrides->maxfwd_set == 0) ? base->maxfwd : overrides->maxfwd; - ps->maxfwd_set = overrides->maxfwd_set || base->maxfwd_set; - ps->error_override = (overrides->error_override_set == 0) ? base->error_override : overrides->error_override; - ps->error_override_set = overrides->error_override_set || base->error_override_set; - ps->preserve_host = (overrides->preserve_host_set == 0) ? base->preserve_host : overrides->preserve_host; - ps->preserve_host_set = overrides->preserve_host_set || base->preserve_host_set; - ps->timeout= (overrides->timeout_set == 0) ? base->timeout : overrides->timeout; - ps->timeout_set = overrides->timeout_set || base->timeout_set; - ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt; - ps->badopt_set = overrides->badopt_set || base->badopt_set; - - return ps; -} - -static void *create_proxy_dir_config(apr_pool_t *p, char *dummy) -{ - proxy_dir_conf *new = - (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf)); - - /* Filled in by proxysection, when applicable */ - - return (void *) new; -} - -static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv) -{ - proxy_dir_conf *new = (proxy_dir_conf *) apr_pcalloc(p, sizeof(proxy_dir_conf)); - proxy_dir_conf *add = (proxy_dir_conf *) addv; - proxy_dir_conf *base = (proxy_dir_conf *) basev; - - new->p = add->p; - new->p_is_fnmatch = add->p_is_fnmatch; - new->r = add->r; - new->ftp_directory_charset = add->ftp_directory_charset ? - add->ftp_directory_charset : - base->ftp_directory_charset; - return new; -} - - -static const char * - add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex) -{ - server_rec *s = cmd->server; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); - struct proxy_remote *new; - char *p, *q; - char *r, *f, *scheme; - regex_t *reg = NULL; - int port; - - r = apr_pstrdup(cmd->pool, r1); - scheme = apr_pstrdup(cmd->pool, r1); - f = apr_pstrdup(cmd->pool, f1); - p = strchr(r, ':'); - if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { - if (regex) - return "ProxyRemoteMatch: Bad syntax for a remote proxy server"; - else - return "ProxyRemote: Bad syntax for a remote proxy server"; - } - else { - scheme[p-r] = 0; - } - q = strchr(p + 3, ':'); - if (q != NULL) { - if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) { - if (regex) - return "ProxyRemoteMatch: Bad syntax for a remote proxy server (bad port number)"; - else - return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)"; - } - *q = '\0'; - } - else - port = -1; - *p = '\0'; - if (regex) { - reg = ap_pregcomp(cmd->pool, f, REG_EXTENDED); - if (!reg) - return "Regular expression for ProxyRemoteMatch could not be compiled."; - } - else - if (strchr(f, ':') == NULL) - ap_str_tolower(f); /* lowercase scheme */ - ap_str_tolower(p + 3); /* lowercase hostname */ - - if (port == -1) { - port = apr_uri_port_of_scheme(scheme); - } - - new = apr_array_push(conf->proxies); - new->scheme = f; - new->protocol = r; - new->hostname = p + 3; - new->port = port; - new->regexp = reg; - new->use_regex = regex; - return NULL; -} - -static const char * - add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) -{ - return add_proxy(cmd, dummy, f1, r1, 0); -} - -static const char * - add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) -{ - return add_proxy(cmd, dummy, f1, r1, 1); -} - -static const char * - add_pass(cmd_parms *cmd, void *dummy, const char *f, const char *r) -{ - server_rec *s = cmd->server; - proxy_server_conf *conf = - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); - struct proxy_alias *new; - if (r!=NULL && cmd->path == NULL ) { - new = apr_array_push(conf->aliases); - new->fake = f; - new->real = r; - } else if (r==NULL && cmd->path != NULL) { - new = apr_array_push(conf->aliases); - new->fake = cmd->path; - new->real = f; - } else { - if ( r== NULL) - return "ProxyPass needs a path when not defined in a location"; - else - return "ProxyPass can not have a path when defined in a location"; - } - - return NULL; -} - -static const char * - add_pass_reverse(cmd_parms *cmd, void *dummy, const char *f, const char *r) -{ - server_rec *s = cmd->server; - proxy_server_conf *conf; - struct proxy_alias *new; - - conf = (proxy_server_conf *)ap_get_module_config(s->module_config, - &proxy_module); - if (r!=NULL && cmd->path == NULL ) { - new = apr_array_push(conf->raliases); - new->fake = f; - new->real = r; - } else if (r==NULL && cmd->path != NULL) { - new = apr_array_push(conf->raliases); - new->fake = cmd->path; - new->real = f; - } else { - if ( r == NULL) - return "ProxyPassReverse needs a path when not defined in a location"; - else - return "ProxyPassReverse can not have a path when defined in a location"; - } - - return NULL; -} - -static const char * - set_proxy_exclude(cmd_parms *parms, void *dummy, const char *arg) -{ - server_rec *s = parms->server; - proxy_server_conf *conf = - ap_get_module_config(s->module_config, &proxy_module); - struct noproxy_entry *new; - struct noproxy_entry *list = (struct noproxy_entry *) conf->noproxies->elts; - struct apr_sockaddr_t *addr; - int found = 0; - int i; - - /* Don't duplicate entries */ - for (i = 0; i < conf->noproxies->nelts; i++) { - if (apr_strnatcasecmp(arg, list[i].name) == 0) { /* ignore case for host names */ - found = 1; - } - } - - if (!found) { - new = apr_array_push(conf->noproxies); - new->name = arg; - if (APR_SUCCESS == apr_sockaddr_info_get(&addr, new->name, APR_UNSPEC, 0, 0, parms->pool)) { - new->addr = addr; - } - else { - new->addr = NULL; - } - } - return NULL; -} - -/* - * Set the ports CONNECT can use - */ -static const char * - set_allowed_ports(cmd_parms *parms, void *dummy, const char *arg) -{ - server_rec *s = parms->server; - proxy_server_conf *conf = - ap_get_module_config(s->module_config, &proxy_module); - int *New; - - if (!apr_isdigit(arg[0])) - return "AllowCONNECT: port number must be numeric"; - - New = apr_array_push(conf->allowed_connect_ports); - *New = atoi(arg); - return NULL; -} - -/* Similar to set_proxy_exclude(), but defining directly connected hosts, - * which should never be accessed via the configured ProxyRemote servers - */ -static const char * - set_proxy_dirconn(cmd_parms *parms, void *dummy, const char *arg) -{ - server_rec *s = parms->server; - proxy_server_conf *conf = - ap_get_module_config(s->module_config, &proxy_module); - struct dirconn_entry *New; - struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts; - int found = 0; - int i; - - /* Don't duplicate entries */ - for (i = 0; i < conf->dirconn->nelts; i++) { - if (strcasecmp(arg, list[i].name) == 0) - found = 1; - } - - if (!found) { - New = apr_array_push(conf->dirconn); - New->name = apr_pstrdup(parms->pool, arg); - New->hostaddr = NULL; - - if (ap_proxy_is_ipaddr(New, parms->pool)) { -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Parsed addr %s", inet_ntoa(New->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Parsed mask %s", inet_ntoa(New->mask)); -#endif - } - else if (ap_proxy_is_domainname(New, parms->pool)) { - ap_str_tolower(New->name); -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Parsed domain %s", New->name); -#endif - } - else if (ap_proxy_is_hostname(New, parms->pool)) { - ap_str_tolower(New->name); -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Parsed host %s", New->name); -#endif - } - else { - ap_proxy_is_word(New, parms->pool); -#if DEBUGGING - fprintf(stderr, "Parsed word %s\n", New->name); -#endif - } - } - return NULL; -} - -static const char * - set_proxy_domain(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - if (arg[0] != '.') - return "ProxyDomain: domain name must start with a dot."; - - psf->domain = arg; - return NULL; -} - -static const char * - set_proxy_req(cmd_parms *parms, void *dummy, int flag) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - psf->req = flag; - psf->req_set = 1; - return NULL; -} -static const char * - set_proxy_error_override(cmd_parms *parms, void *dummy, int flag) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - psf->error_override = flag; - psf->error_override_set = 1; - return NULL; -} -static const char * - set_preserve_host(cmd_parms *parms, void *dummy, int flag) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - psf->preserve_host = flag; - psf->preserve_host_set = 1; - return NULL; -} - -static const char * - set_recv_buffer_size(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - int s = atoi(arg); - if (s < 512 && s != 0) { - return "ProxyReceiveBufferSize must be >= 512 bytes, or 0 for system default."; - } - - psf->recv_buffer_size = s; - psf->recv_buffer_size_set = 1; - return NULL; -} - -static const char * - set_io_buffer_size(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - long s = atol(arg); - - psf->io_buffer_size = ((s > AP_IOBUFSIZE) ? s : AP_IOBUFSIZE); - psf->io_buffer_size_set = 1; - return NULL; -} - -static const char * - set_max_forwards(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - long s = atol(arg); - if (s < 0) { - return "ProxyMaxForwards must be greater or equal to zero.."; - } - - psf->maxfwd = s; - psf->maxfwd_set = 1; - return NULL; -} -static const char* - set_proxy_timeout(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - int timeout; - - timeout=atoi(arg); - if (timeout<1) { - return "Proxy Timeout must be at least 1 second."; - } - psf->timeout_set=1; - psf->timeout=apr_time_from_sec(timeout); - - return NULL; -} - -static const char* - set_via_opt(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - if (strcasecmp(arg, "Off") == 0) - psf->viaopt = via_off; - else if (strcasecmp(arg, "On") == 0) - psf->viaopt = via_on; - else if (strcasecmp(arg, "Block") == 0) - psf->viaopt = via_block; - else if (strcasecmp(arg, "Full") == 0) - psf->viaopt = via_full; - else { - return "ProxyVia must be one of: " - "off | on | full | block"; - } - - psf->viaopt_set = 1; - return NULL; -} - -static const char* - set_bad_opt(cmd_parms *parms, void *dummy, const char *arg) -{ - proxy_server_conf *psf = - ap_get_module_config(parms->server->module_config, &proxy_module); - - if (strcasecmp(arg, "IsError") == 0) - psf->badopt = bad_error; - else if (strcasecmp(arg, "Ignore") == 0) - psf->badopt = bad_ignore; - else if (strcasecmp(arg, "StartBody") == 0) - psf->badopt = bad_body; - else { - return "ProxyBadHeader must be one of: " - "IsError | Ignore | StartBody"; - } - - psf->badopt_set = 1; - return NULL; -} - -static const char* set_ftp_directory_charset(cmd_parms *cmd, void *dconf, - const char *arg) -{ - proxy_dir_conf *conf = dconf; - - conf->ftp_directory_charset = arg; - return NULL; -} - -static void ap_add_per_proxy_conf(server_rec *s, ap_conf_vector_t *dir_config) -{ - proxy_server_conf *sconf = ap_get_module_config(s->module_config, - &proxy_module); - void **new_space = (void **)apr_array_push(sconf->sec_proxy); - - *new_space = dir_config; -} - -static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg) -{ - const char *errmsg; - const char *endp = ap_strrchr_c(arg, '>'); - int old_overrides = cmd->override; - char *old_path = cmd->path; - proxy_dir_conf *conf; - ap_conf_vector_t *new_dir_conf = ap_create_per_dir_config(cmd->pool); - regex_t *r = NULL; - const command_rec *thiscmd = cmd->cmd; - - const char *err = ap_check_cmd_context(cmd, - NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); - if (err != NULL) { - return err; - } - - if (endp == NULL) { - return apr_pstrcat(cmd->pool, cmd->cmd->name, - "> directive missing closing '>'", NULL); - } - - arg=apr_pstrndup(cmd->pool, arg, endp-arg); - - if (!arg) { - if (thiscmd->cmd_data) - return "<ProxyMatch > block must specify a path"; - else - return "<Proxy > block must specify a path"; - } - - cmd->path = ap_getword_conf(cmd->pool, &arg); - cmd->override = OR_ALL|ACCESS_CONF; - - if (!strncasecmp(cmd->path, "proxy:", 6)) - cmd->path += 6; - - /* XXX Ignore case? What if we proxy a case-insensitive server?!? - * While we are at it, shouldn't we also canonicalize the entire - * scheme? See proxy_fixup() - */ - if (thiscmd->cmd_data) { /* <ProxyMatch> */ - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED); - if (!r) { - return "Regex could not be compiled"; - } - } - else if (!strcmp(cmd->path, "~")) { - cmd->path = ap_getword_conf(cmd->pool, &arg); - if (!cmd->path) - return "<Proxy ~ > block must specify a path"; - if (strncasecmp(cmd->path, "proxy:", 6)) - cmd->path += 6; - r = ap_pregcomp(cmd->pool, cmd->path, REG_EXTENDED); - if (!r) { - return "Regex could not be compiled"; - } - } - - /* initialize our config and fetch it */ - conf = ap_set_config_vectors(cmd->server, new_dir_conf, cmd->path, - &proxy_module, cmd->pool); - - errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_dir_conf); - if (errmsg != NULL) - return errmsg; - - conf->r = r; - conf->p = cmd->path; - conf->p_is_fnmatch = apr_fnmatch_test(conf->p); - - ap_add_per_proxy_conf(cmd->server, new_dir_conf); - - if (*arg != '\0') { - return apr_pstrcat(cmd->pool, "Multiple ", thiscmd->name, - "> arguments not (yet) supported.", NULL); - } - - cmd->path = old_path; - cmd->override = old_overrides; - - return NULL; -} - -static const command_rec proxy_cmds[] = -{ - AP_INIT_RAW_ARGS("<Proxy", proxysection, NULL, RSRC_CONF, - "Container for directives affecting resources located in the proxied " - "location"), - AP_INIT_RAW_ARGS("<ProxyMatch", proxysection, (void*)1, RSRC_CONF, - "Container for directives affecting resources located in the proxied " - "location, in regular expression syntax"), - AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF, - "on if the true proxy requests should be accepted"), - AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF, - "a scheme, partial URL or '*' and a proxy server"), - AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF, - "a regex pattern and a proxy server"), - AP_INIT_TAKE12("ProxyPass", add_pass, NULL, RSRC_CONF|ACCESS_CONF, - "a virtual path and a URL"), - AP_INIT_TAKE12("ProxyPassReverse", add_pass_reverse, NULL, RSRC_CONF|ACCESS_CONF, - "a virtual path and a URL for reverse proxy behaviour"), - AP_INIT_ITERATE("ProxyBlock", set_proxy_exclude, NULL, RSRC_CONF, - "A list of names, hosts or domains to which the proxy will not connect"), - AP_INIT_TAKE1("ProxyReceiveBufferSize", set_recv_buffer_size, NULL, RSRC_CONF, - "Receive buffer size for outgoing HTTP and FTP connections in bytes"), - AP_INIT_TAKE1("ProxyIOBufferSize", set_io_buffer_size, NULL, RSRC_CONF, - "IO buffer size for outgoing HTTP and FTP connections in bytes"), - AP_INIT_TAKE1("ProxyMaxForwards", set_max_forwards, NULL, RSRC_CONF, - "The maximum number of proxies a request may be forwarded through."), - AP_INIT_ITERATE("NoProxy", set_proxy_dirconn, NULL, RSRC_CONF, - "A list of domains, hosts, or subnets to which the proxy will connect directly"), - AP_INIT_TAKE1("ProxyDomain", set_proxy_domain, NULL, RSRC_CONF, - "The default intranet domain name (in absence of a domain in the URL)"), - AP_INIT_ITERATE("AllowCONNECT", set_allowed_ports, NULL, RSRC_CONF, - "A list of ports which CONNECT may connect to"), - AP_INIT_TAKE1("ProxyVia", set_via_opt, NULL, RSRC_CONF, - "Configure Via: proxy header header to one of: on | off | block | full"), - AP_INIT_FLAG("ProxyErrorOverride", set_proxy_error_override, NULL, RSRC_CONF, - "use our error handling pages instead of the servers' we are proxying"), - AP_INIT_FLAG("ProxyPreserveHost", set_preserve_host, NULL, RSRC_CONF, - "on if we should preserve host header while proxying"), - AP_INIT_TAKE1("ProxyTimeout", set_proxy_timeout, NULL, RSRC_CONF, - "Set the timeout (in seconds) for a proxied connection. " - "This overrides the server timeout"), - AP_INIT_TAKE1("ProxyBadHeader", set_bad_opt, NULL, RSRC_CONF, - "How to handle bad header line in response: IsError | Ignore | StartBody"), - AP_INIT_TAKE1("ProxyFtpDirCharset", set_ftp_directory_charset, NULL, - RSRC_CONF|ACCESS_CONF, "Define the character set for proxied FTP listings"), - {NULL} -}; - -APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *)); -APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); - -static APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *proxy_ssl_enable = NULL; -static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *proxy_ssl_disable = NULL; - -PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c) -{ - /* - * if c == NULL just check if the optional function was imported - * else run the optional function so ssl filters are inserted - */ - if (proxy_ssl_enable) { - return c ? proxy_ssl_enable(c) : 1; - } - - return 0; -} - -PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c) -{ - if (proxy_ssl_disable) { - return proxy_ssl_disable(c); - } - - return 0; -} - -static int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog, - apr_pool_t *ptemp, server_rec *s) -{ - proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable); - proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable); - - return OK; -} - -static void register_hooks(apr_pool_t *p) -{ - /* fixup before mod_rewrite, so that the proxied url will not - * escaped accidentally by our fixup. - */ - static const char * const aszSucc[]={ "mod_rewrite.c", NULL }; - - /* handler */ - ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST); - /* filename-to-URI translation */ - ap_hook_translate_name(proxy_trans, NULL, NULL, APR_HOOK_FIRST); - /* walk <Proxy > entries and suppress default TRACE behavior */ - ap_hook_map_to_storage(proxy_map_location, NULL,NULL, APR_HOOK_FIRST); - /* fixups */ - ap_hook_fixups(proxy_fixup, NULL, aszSucc, APR_HOOK_FIRST); - /* post read_request handling */ - ap_hook_post_read_request(proxy_detect, NULL, NULL, APR_HOOK_FIRST); - /* post config handling */ - ap_hook_post_config(proxy_post_config, NULL, NULL, APR_HOOK_MIDDLE); -} - -module AP_MODULE_DECLARE_DATA proxy_module = -{ - STANDARD20_MODULE_STUFF, - create_proxy_dir_config, /* create per-directory config structure */ - merge_proxy_dir_config, /* merge per-directory config structures */ - create_proxy_config, /* create per-server config structure */ - merge_proxy_config, /* merge per-server config structures */ - proxy_cmds, /* command table */ - register_hooks -}; - -APR_HOOK_STRUCT( - APR_HOOK_LINK(scheme_handler) - APR_HOOK_LINK(canon_handler) -) - -APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler, - (request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyhost, - apr_port_t proxyport),(r,conf,url, - proxyhost,proxyport),DECLINED) -APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler, - (request_rec *r, char *url),(r, - url),DECLINED) -APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups, - (request_rec *r), (r), - OK, DECLINED) diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.dsp b/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.dsp deleted file mode 100644 index 9fa9feb0..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.dsp +++ /dev/null @@ -1,140 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mod_proxy" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mod_proxy - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy.mak" CFG="mod_proxy - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_proxy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_proxy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Release\mod_proxy_src" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /out:"Release/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so /opt:ref - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "PROXY_DECLARE_EXPORT" /Fd"Debug\mod_proxy_src" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy.so - -!ENDIF - -# Begin Target - -# Name "mod_proxy - Win32 Release" -# Name "mod_proxy - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\mod_proxy.c -# End Source File -# Begin Source File - -SOURCE=.\proxy_util.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\mod_proxy.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\build\win32\win32ver.awk - -!IF "$(CFG)" == "mod_proxy - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy.so "proxy_module for Apache" ../../include/ap_release.h > .\mod_proxy.rc - -# End Custom Build - -!ELSEIF "$(CFG)" == "mod_proxy - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy.so "proxy_module for Apache" ../../include/ap_release.h > .\mod_proxy.rc - -# End Custom Build - -!ENDIF - -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.h b/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.h deleted file mode 100644 index d1ed7d46..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy.h +++ /dev/null @@ -1,255 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MOD_PROXY_H -#define MOD_PROXY_H - -/* - * Main include file for the Apache proxy - */ - -/* - - Also note numerous FIXMEs and CHECKMEs which should be eliminated. - - This code is once again experimental! - - Things to do: - - 1. Make it completely work (for FTP too) - - 2. HTTP/1.1 - - Chuck Murcko <chuck@topsail.org> 02-06-01 - - */ - -#define CORE_PRIVATE - -#include "apr_hooks.h" -#include "apr.h" -#include "apr_lib.h" -#include "apr_strings.h" -#include "apr_buckets.h" -#include "apr_md5.h" -#include "apr_network_io.h" -#include "apr_pools.h" -#include "apr_strings.h" -#include "apr_uri.h" -#include "apr_date.h" -#include "apr_fnmatch.h" -#define APR_WANT_STRFUNC -#include "apr_want.h" - -#include "httpd.h" -#include "http_config.h" -#include "ap_config.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_request.h" -#include "http_vhost.h" -#include "http_main.h" -#include "http_log.h" -#include "http_connection.h" -#include "util_filter.h" -#include "util_ebcdic.h" - -#if APR_HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#if APR_HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -/* for proxy_canonenc() */ -enum enctype { - enc_path, enc_search, enc_user, enc_fpath, enc_parm -}; - -#if APR_CHARSET_EBCDIC -#define CRLF "\r\n" -#else /*APR_CHARSET_EBCDIC*/ -#define CRLF "\015\012" -#endif /*APR_CHARSET_EBCDIC*/ - -/* default Max-Forwards header setting */ -#define DEFAULT_MAX_FORWARDS 10 - -/* static information about a remote proxy */ -struct proxy_remote { - const char *scheme; /* the schemes handled by this proxy, or '*' */ - const char *protocol; /* the scheme used to talk to this proxy */ - const char *hostname; /* the hostname of this proxy */ - apr_port_t port; /* the port for this proxy */ - regex_t *regexp; /* compiled regex (if any) for the remote */ - int use_regex; /* simple boolean. True if we have a regex pattern */ -}; - -struct proxy_alias { - const char *real; - const char *fake; -}; - -struct dirconn_entry { - char *name; - struct in_addr addr, mask; - struct apr_sockaddr_t *hostaddr; - int (*matcher) (struct dirconn_entry * This, request_rec *r); -}; - -struct noproxy_entry { - const char *name; - struct apr_sockaddr_t *addr; -}; - -typedef struct { - apr_array_header_t *proxies; - apr_array_header_t *sec_proxy; - apr_array_header_t *aliases; - apr_array_header_t *raliases; - apr_array_header_t *noproxies; - apr_array_header_t *dirconn; - apr_array_header_t *allowed_connect_ports; - const char *domain; /* domain name to use in absence of a domain name in the request */ - int req; /* true if proxy requests are enabled */ - char req_set; - enum { - via_off, - via_on, - via_block, - via_full - } viaopt; /* how to deal with proxy Via: headers */ - char viaopt_set; - apr_size_t recv_buffer_size; - char recv_buffer_size_set; - apr_size_t io_buffer_size; - char io_buffer_size_set; - long maxfwd; - char maxfwd_set; - /** - * the following setting masks the error page - * returned from the 'proxied server' and just - * forwards the status code upwards. - * This allows the main server (us) to generate - * the error page, (so it will look like a error - * returned from the rest of the system - */ - int error_override; - int error_override_set; - int preserve_host; - int preserve_host_set; - apr_interval_time_t timeout; - apr_interval_time_t timeout_set; - enum { - bad_error, - bad_ignore, - bad_body - } badopt; /* how to deal with bad headers */ - char badopt_set; - -} proxy_server_conf; - -typedef struct { - const char *p; /* The path */ - int p_is_fnmatch; /* Is this path an fnmatch candidate? */ - regex_t *r; /* Is this a regex? */ - const char *ftp_directory_charset; -} proxy_dir_conf; - -typedef struct { - conn_rec *connection; - char *hostname; - apr_port_t port; - int is_ssl; -} proxy_conn_rec; - -typedef struct { - float cache_completion; /* completion percentage */ - int content_length; /* length of the content */ -} proxy_completion; - - -/* hooks */ - -/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and - * PROXY_DECLARE_DATA with appropriate export and import tags for the platform - */ -#if !defined(WIN32) -#define PROXY_DECLARE(type) type -#define PROXY_DECLARE_NONSTD(type) type -#define PROXY_DECLARE_DATA -#elif defined(PROXY_DECLARE_STATIC) -#define PROXY_DECLARE(type) type __stdcall -#define PROXY_DECLARE_NONSTD(type) type -#define PROXY_DECLARE_DATA -#elif defined(PROXY_DECLARE_EXPORT) -#define PROXY_DECLARE(type) __declspec(dllexport) type __stdcall -#define PROXY_DECLARE_NONSTD(type) __declspec(dllexport) type -#define PROXY_DECLARE_DATA __declspec(dllexport) -#else -#define PROXY_DECLARE(type) __declspec(dllimport) type __stdcall -#define PROXY_DECLARE_NONSTD(type) __declspec(dllimport) type -#define PROXY_DECLARE_DATA __declspec(dllimport) -#endif - -/** - * Hook an optional proxy hook. Unlike static hooks, this uses a macro - * instead of a function. - */ -#define PROXY_OPTIONAL_HOOK(name,fn,pre,succ,order) \ - APR_OPTIONAL_HOOK(proxy,name,fn,pre,succ,order) - -APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r, - proxy_server_conf *conf, char *url, - const char *proxyhost, apr_port_t proxyport)) -APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r, - char *url)) - -APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr)) -APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r)) - -/* proxy_util.c */ - -PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r); -PROXY_DECLARE(int) ap_proxy_hex2c(const char *x); -PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x); -PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, - int isenc); -PROXY_DECLARE(char *)ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, - char **passwordp, char **hostp, apr_port_t *port); -PROXY_DECLARE(const char *)ap_proxy_date_canon(apr_pool_t *p, const char *x); -PROXY_DECLARE(apr_table_t *)ap_proxy_read_headers(request_rec *r, request_rec *rp, char *buffer, int size, conn_rec *c); -PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val); -PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val); -PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x); -PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y); -PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message); -PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p); -PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p); -PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p); -PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p); -PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, apr_sockaddr_t *uri_addr); -PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r); -PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen, int *eos); -PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key); -PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, server_rec *, apr_pool_t *); -PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c); -PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c); - -/* For proxy_util */ -extern module AP_MODULE_DECLARE_DATA proxy_module; - -#endif /*MOD_PROXY_H*/ diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_connect.dsp b/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_connect.dsp deleted file mode 100644 index 0c2a12b0..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_connect.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mod_proxy_connect" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mod_proxy_connect - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy_connect.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy_connect.mak" CFG="mod_proxy_connect - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_proxy_connect - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_proxy_connect - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mod_proxy_connect - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_connect_src" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /out:"Release/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so /opt:ref - -!ELSEIF "$(CFG)" == "mod_proxy_connect - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_connect_src" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy_connect.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_connect.so - -!ENDIF - -# Begin Target - -# Name "mod_proxy_connect - Win32 Release" -# Name "mod_proxy_connect - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\proxy_connect.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter ".h" -# Begin Source File - -SOURCE=.\mod_proxy.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\build\win32\win32ver.awk - -!IF "$(CFG)" == "mod_proxy_connect - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy_connect.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy_connect.so "proxy_connect_module for Apache" ../../include/ap_release.h > .\mod_proxy_connect.rc - -# End Custom Build - -!ELSEIF "$(CFG)" == "mod_proxy_connect - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy_connect.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy_connect.so "proxy_connect_module for Apache" ../../include/ap_release.h > .\mod_proxy_connect.rc - -# End Custom Build - -!ENDIF - -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_ftp.dsp b/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_ftp.dsp deleted file mode 100644 index 3dfe0b7e..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_ftp.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mod_proxy_ftp" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mod_proxy_ftp - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy_ftp.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy_ftp.mak" CFG="mod_proxy_ftp - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_proxy_ftp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_proxy_ftp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mod_proxy_ftp - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_ftp_src" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /out:"Release/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so /opt:ref - -!ELSEIF "$(CFG)" == "mod_proxy_ftp - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_ftp_src" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy_ftp.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_ftp.so - -!ENDIF - -# Begin Target - -# Name "mod_proxy_ftp - Win32 Release" -# Name "mod_proxy_ftp - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\proxy_ftp.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter ".h" -# Begin Source File - -SOURCE=.\mod_proxy.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\build\win32\win32ver.awk - -!IF "$(CFG)" == "mod_proxy_ftp - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy_ftp.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy_ftp.so "proxy_ftp_module for Apache" ../../include/ap_release.h > .\mod_proxy_ftp.rc - -# End Custom Build - -!ELSEIF "$(CFG)" == "mod_proxy_ftp - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy_ftp.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy_ftp.so "proxy_ftp_module for Apache" ../../include/ap_release.h > .\mod_proxy_ftp.rc - -# End Custom Build - -!ENDIF - -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_http.dsp b/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_http.dsp deleted file mode 100644 index d8f29006..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/mod_proxy_http.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mod_proxy_http" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mod_proxy_http - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy_http.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mod_proxy_http.mak" CFG="mod_proxy_http - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mod_proxy_http - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mod_proxy_http - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mod_proxy_http - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /Zi /O2 /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_proxy_http_src" /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /out:"Release/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Release/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so /opt:ref - -!ELSEIF "$(CFG)" == "mod_proxy_http - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_proxy_http_src" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so -# ADD LINK32 kernel32.lib ws2_32.lib mswsock.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:"Debug/mod_proxy_http.so" /base:@..\..\os\win32\BaseAddr.ref,mod_proxy_http.so - -!ENDIF - -# Begin Target - -# Name "mod_proxy_http - Win32 Release" -# Name "mod_proxy_http - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\proxy_http.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter ".h" -# Begin Source File - -SOURCE=.\mod_proxy.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\build\win32\win32ver.awk - -!IF "$(CFG)" == "mod_proxy_http - Win32 Release" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy_http.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy_http.so "proxy_http_module for Apache" ../../include/ap_release.h > .\mod_proxy_http.rc - -# End Custom Build - -!ELSEIF "$(CFG)" == "mod_proxy_http - Win32 Debug" - -# PROP Ignore_Default_Tool 1 -# Begin Custom Build - Creating Version Resource -InputPath=..\..\build\win32\win32ver.awk - -".\mod_proxy_http.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - awk -f ../../build/win32/win32ver.awk mod_proxy_http.so "proxy_http_module for Apache" ../../include/ap_release.h > .\mod_proxy_http.rc - -# End Custom Build - -!ENDIF - -# End Source File -# End Target -# End Project diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/modules.mk b/rubbos/app/httpd-2.0.64/modules/proxy/modules.mk deleted file mode 100644 index ceb52a1b..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/modules.mk +++ /dev/null @@ -1,3 +0,0 @@ -DISTCLEAN_TARGETS = modules.mk -static = -shared = diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_connect.c b/rubbos/app/httpd-2.0.64/modules/proxy/proxy_connect.c deleted file mode 100644 index 20e40ebb..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_connect.c +++ /dev/null @@ -1,377 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* CONNECT method for Apache proxy */ - -#define CORE_PRIVATE - -#include "mod_proxy.h" -#include "apr_poll.h" - -module AP_MODULE_DECLARE_DATA proxy_connect_module; - -int ap_proxy_connect_canon(request_rec *r, char *url); -int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyname, - apr_port_t proxyport); - -/* - * This handles Netscape CONNECT method secure proxy requests. - * A connection is opened to the specified host and data is - * passed through between the WWW site and the browser. - * - * This code is based on the INTERNET-DRAFT document - * "Tunneling SSL Through a WWW Proxy" currently at - * http://www.mcom.com/newsref/std/tunneling_ssl.html. - * - * If proxyhost and proxyport are set, we send a CONNECT to - * the specified proxy.. - * - * FIXME: this doesn't log the number of bytes sent, but - * that may be okay, since the data is supposed to - * be transparent. In fact, this doesn't log at all - * yet. 8^) - * FIXME: doesn't check any headers initally sent from the - * client. - * FIXME: should allow authentication, but hopefully the - * generic proxy authentication is good enough. - * FIXME: no check for r->assbackwards, whatever that is. - */ - -static int -allowed_port(proxy_server_conf *conf, int port) -{ - int i; - int *list = (int *) conf->allowed_connect_ports->elts; - - for(i = 0; i < conf->allowed_connect_ports->nelts; i++) { - if(port == list[i]) - return 1; - } - return 0; -} - -/* canonicalise CONNECT URLs. */ -int ap_proxy_connect_canon(request_rec *r, char *url) -{ - - if (r->method_number != M_CONNECT) { - return DECLINED; - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: canonicalising URL %s", url); - - return OK; -} - -/* CONNECT handler */ -int ap_proxy_connect_handler(request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyname, - apr_port_t proxyport) -{ - apr_pool_t *p = r->pool; - apr_socket_t *sock; - apr_status_t err, rv; - apr_size_t i, o, nbytes; - char buffer[HUGE_STRING_LEN]; - apr_socket_t *client_socket = ap_get_module_config(r->connection->conn_config, &core_module); - int failed; - apr_pollfd_t *pollfd; - apr_int32_t pollcnt; - apr_int16_t pollevent; - apr_sockaddr_t *uri_addr, *connect_addr; - - apr_uri_t uri; - const char *connectname; - int connectport = 0; - - /* is this for us? */ - if (r->method_number != M_CONNECT) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: declining URL %s", url); - return DECLINED; - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: serving URL %s", url); - - - /* - * Step One: Determine Who To Connect To - * - * Break up the URL to determine the host to connect to - */ - - /* we break the URL into host, port, uri */ - if (APR_SUCCESS != apr_uri_parse_hostinfo(p, url, &uri)) { - return ap_proxyerror(r, HTTP_BAD_REQUEST, - apr_pstrcat(p, "URI cannot be parsed: ", url, NULL)); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: connecting %s to %s:%d", url, uri.hostname, uri.port); - - /* do a DNS lookup for the destination host */ - err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, p); - - /* are we connecting directly, or via a proxy? */ - if (proxyname) { - connectname = proxyname; - connectport = proxyport; - err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, p); - } - else { - connectname = uri.hostname; - connectport = uri.port; - connect_addr = uri_addr; - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: connecting to remote proxy %s on port %d", connectname, connectport); - - /* check if ProxyBlock directive on this host */ - if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) { - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - - /* Check if it is an allowed port */ - if (conf->allowed_connect_ports->nelts == 0) { - /* Default setting if not overridden by AllowCONNECT */ - switch (uri.port) { - case APR_URI_HTTPS_DEFAULT_PORT: - case APR_URI_SNEWS_DEFAULT_PORT: - break; - default: - /* XXX can we call ap_proxyerror() here to get a nice log message? */ - return HTTP_FORBIDDEN; - } - } else if(!allowed_port(conf, uri.port)) { - /* XXX can we call ap_proxyerror() here to get a nice log message? */ - return HTTP_FORBIDDEN; - } - - /* - * Step Two: Make the Connection - * - * We have determined who to connect to. Now make the connection. - */ - - /* get all the possible IP addresses for the destname and loop through them - * until we get a successful connection - */ - if (APR_SUCCESS != err) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, - "DNS lookup failure for: ", - connectname, NULL)); - } - - /* - * At this point we have a list of one or more IP addresses of - * the machine to connect to. If configured, reorder this - * list so that the "best candidate" is first try. "best - * candidate" could mean the least loaded server, the fastest - * responding server, whatever. - * - * For now we do nothing, ie we get DNS round robin. - * XXX FIXME - */ - failed = ap_proxy_connect_to_backend(&sock, "CONNECT", connect_addr, - connectname, conf, r->server, - r->pool); - - /* handle a permanent error from the above loop */ - if (failed) { - if (proxyname) { - return DECLINED; - } - else { - return HTTP_BAD_GATEWAY; - } - } - - /* - * Step Three: Send the Request - * - * Send the HTTP/1.1 CONNECT request to the remote server - */ - - /* we are acting as a tunnel - the output filter stack should - * be completely empty, because when we are done here we are done completely. - * We add the NULL filter to the stack to do this... - */ - r->output_filters = NULL; - r->connection->output_filters = NULL; - - - /* If we are connecting through a remote proxy, we need to pass - * the CONNECT request on to it. - */ - if (proxyport) { - /* FIXME: Error checking ignored. - */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: sending the CONNECT request to the remote proxy"); - nbytes = apr_snprintf(buffer, sizeof(buffer), - "CONNECT %s HTTP/1.0" CRLF, r->uri); - apr_send(sock, buffer, &nbytes); - nbytes = apr_snprintf(buffer, sizeof(buffer), - "Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); - apr_send(sock, buffer, &nbytes); - } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: Returning 200 OK Status"); - nbytes = apr_snprintf(buffer, sizeof(buffer), - "HTTP/1.0 200 Connection Established" CRLF); - ap_xlate_proto_to_ascii(buffer, nbytes); - apr_send(client_socket, buffer, &nbytes); - nbytes = apr_snprintf(buffer, sizeof(buffer), - "Proxy-agent: %s" CRLF CRLF, ap_get_server_version()); - ap_xlate_proto_to_ascii(buffer, nbytes); - apr_send(client_socket, buffer, &nbytes); -#if 0 - /* This is safer code, but it doesn't work yet. I'm leaving it - * here so that I can fix it later. - */ - r->status = HTTP_OK; - r->header_only = 1; - apr_table_set(r->headers_out, "Proxy-agent: %s", ap_get_server_version()); - ap_rflush(r); -#endif - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: setting up poll()"); - - /* - * Step Four: Handle Data Transfer - * - * Handle two way transfer of data over the socket (this is a tunnel). - */ - -/* r->sent_bodyct = 1;*/ - - if((rv = apr_poll_setup(&pollfd, 2, r->pool)) != APR_SUCCESS) - { - apr_socket_close(sock); - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: CONNECT: error apr_poll_setup()"); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* Add client side to the poll */ - apr_poll_socket_add(pollfd, client_socket, APR_POLLIN); - - /* Add the server side to the poll */ - apr_poll_socket_add(pollfd, sock, APR_POLLIN); - - while (1) { /* Infinite loop until error (one side closes the connection) */ -/* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: CONNECT: going to sleep (poll)");*/ - if ((rv = apr_poll(pollfd, 2, &pollcnt, -1)) != APR_SUCCESS) - { - apr_socket_close(sock); - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: CONNECT: error apr_poll()"); - return HTTP_INTERNAL_SERVER_ERROR; - } -/* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: woke from select(), i=%d", pollcnt);*/ - - if (pollcnt) { - apr_poll_revents_get(&pollevent, sock, pollfd); - if (pollevent & APR_POLLIN) { -/* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: sock was set");*/ - nbytes = sizeof(buffer); - if (apr_recv(sock, buffer, &nbytes) == APR_SUCCESS) { - o = 0; - i = nbytes; - while(i > 0) - { - nbytes = i; - /* This is just plain wrong. No module should ever write directly - * to the client. For now, this works, but this is high on my list of - * things to fix. The correct line is: - * if ((nbytes = ap_rwrite(buffer + o, nbytes, r)) < 0) - * rbb - */ - if (apr_send(client_socket, buffer + o, &nbytes) != APR_SUCCESS) - break; - o += nbytes; - i -= nbytes; - } - } - else - break; - } - else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) - break; - - - apr_poll_revents_get(&pollevent, client_socket, pollfd); - if (pollevent & APR_POLLIN) { -/* ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: client was set");*/ - nbytes = sizeof(buffer); - if (apr_recv(client_socket, buffer, &nbytes) == APR_SUCCESS) { - o = 0; - i = nbytes; - while(i > 0) - { - nbytes = i; - if (apr_send(sock, buffer + o, &nbytes) != APR_SUCCESS) - break; - o += nbytes; - i -= nbytes; - } - } - else - break; - } - else if ((pollevent & APR_POLLERR) || (pollevent & APR_POLLHUP)) - break; - } - else - break; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: CONNECT: finished with poll() - cleaning up"); - - /* - * Step Five: Clean Up - * - * Close the socket and clean up - */ - - apr_socket_close(sock); - - return OK; -} - -static void ap_proxy_connect_register_hook(apr_pool_t *p) -{ - proxy_hook_scheme_handler(ap_proxy_connect_handler, NULL, NULL, APR_HOOK_MIDDLE); - proxy_hook_canon_handler(ap_proxy_connect_canon, NULL, NULL, APR_HOOK_MIDDLE); -} - -module AP_MODULE_DECLARE_DATA proxy_connect_module = { - STANDARD20_MODULE_STUFF, - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - NULL, /* command apr_table_t */ - ap_proxy_connect_register_hook /* register hooks */ -}; diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_ftp.c b/rubbos/app/httpd-2.0.64/modules/proxy/proxy_ftp.c deleted file mode 100644 index cbbf23c9..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_ftp.c +++ /dev/null @@ -1,1936 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* FTP routines for Apache proxy */ - -#include "mod_proxy.h" -#if APR_HAVE_TIME_H -#include <time.h> -#endif - -#define AUTODETECT_PWD -/* Automatic timestamping (Last-Modified header) based on MDTM is used if: - * 1) the FTP server supports the MDTM command and - * 2) HAVE_TIMEGM (preferred) or HAVE_GMTOFF is available at compile time - */ -#define USE_MDTM - - -module AP_MODULE_DECLARE_DATA proxy_ftp_module; - -int ap_proxy_ftp_canon(request_rec *r, char *url); -int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyhost, - apr_port_t proxyport); -apr_status_t ap_proxy_send_dir_filter(ap_filter_t * f, - apr_bucket_brigade *bb); - - -/* - * Decodes a '%' escaped string, and returns the number of characters - */ -static int decodeenc(char *x) -{ - int i, j, ch; - - if (x[0] == '\0') - return 0; /* special case for no characters */ - for (i = 0, j = 0; x[i] != '\0'; i++, j++) { - /* decode it if not already done */ - ch = x[i]; - if (ch == '%' && apr_isxdigit(x[i + 1]) && apr_isxdigit(x[i + 2])) { - ch = ap_proxy_hex2c(&x[i + 1]); - i += 2; - } - x[j] = ch; - } - x[j] = '\0'; - return j; -} - -/* - * Escape the globbing characters in a path used as argument to - * the FTP commands (SIZE, CWD, RETR, MDTM, ...). - * ftpd assumes '\\' as a quoting character to escape special characters. - * Returns: escaped string - */ -#define FTP_GLOBBING_CHARS "*?[{~" -static char *ftp_escape_globbingchars(apr_pool_t *p, const char *path) -{ - char *ret = apr_palloc(p, 2*strlen(path)+sizeof("")); - char *d; - for (d = ret; *path; ++path) { - if (strchr(FTP_GLOBBING_CHARS, *path) != NULL) - *d++ = '\\'; - *d++ = *path; - } - *d = '\0'; - return ret; -} - -/* - * Check for globbing characters in a path used as argument to - * the FTP commands (SIZE, CWD, RETR, MDTM, ...). - * ftpd assumes '\\' as a quoting character to escape special characters. - * Returns: 0 (no globbing chars, or all globbing chars escaped), 1 (globbing chars) - */ -static int ftp_check_globbingchars(const char *path) -{ - for ( ; *path; ++path) { - if (*path == '\\') - ++path; - if (*path != '\0' && strchr(FTP_GLOBBING_CHARS, *path) != NULL) - return TRUE; - } - return FALSE; -} - -/* - * checks an encoded ftp string for bad characters, namely, CR, LF or - * non-ascii character - */ -static int ftp_check_string(const char *x) -{ - int i, ch = 0; -#if APR_CHARSET_EBCDIC - char buf[1]; -#endif - - for (i = 0; x[i] != '\0'; i++) { - ch = x[i]; - if (ch == '%' && apr_isxdigit(x[i + 1]) && apr_isxdigit(x[i + 2])) { - ch = ap_proxy_hex2c(&x[i + 1]); - i += 2; - } -#if !APR_CHARSET_EBCDIC - if (ch == '\015' || ch == '\012' || (ch & 0x80)) -#else /* APR_CHARSET_EBCDIC */ - if (ch == '\r' || ch == '\n') - return 0; - buf[0] = ch; - ap_xlate_proto_to_ascii(buf, 1); - if (buf[0] & 0x80) -#endif /* APR_CHARSET_EBCDIC */ - return 0; - } - return 1; -} - -/* - * Canonicalise ftp URLs. - */ -int ap_proxy_ftp_canon(request_rec *r, char *url) -{ - char *user, *password, *host, *path, *parms, *strp, sport[7]; - apr_pool_t *p = r->pool; - const char *err; - apr_port_t port, def_port; - - /* */ - if (strncasecmp(url, "ftp:", 4) == 0) { - url += 4; - } - else { - return DECLINED; - } - def_port = apr_uri_port_of_scheme("ftp"); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: canonicalising URL %s", url); - - port = def_port; - err = ap_proxy_canon_netloc(p, &url, &user, &password, &host, &port); - if (err) - return HTTP_BAD_REQUEST; - if (user != NULL && !ftp_check_string(user)) - return HTTP_BAD_REQUEST; - if (password != NULL && !ftp_check_string(password)) - return HTTP_BAD_REQUEST; - - /* now parse path/parameters args, according to rfc1738 */ - /* - * N.B. if this isn't a true proxy request, then the URL path (but not - * query args) has already been decoded. This gives rise to the problem - * of a ; being decoded into the path. - */ - strp = strchr(url, ';'); - if (strp != NULL) { - *(strp++) = '\0'; - parms = ap_proxy_canonenc(p, strp, strlen(strp), enc_parm, - r->proxyreq); - if (parms == NULL) - return HTTP_BAD_REQUEST; - } - else - parms = ""; - - path = ap_proxy_canonenc(p, url, strlen(url), enc_path, r->proxyreq); - if (path == NULL) - return HTTP_BAD_REQUEST; - if (!ftp_check_string(path)) - return HTTP_BAD_REQUEST; - - if (r->proxyreq && r->args != NULL) { - if (strp != NULL) { - strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_parm, 1); - if (strp == NULL) - return HTTP_BAD_REQUEST; - parms = apr_pstrcat(p, parms, "?", strp, NULL); - } - else { - strp = ap_proxy_canonenc(p, r->args, strlen(r->args), enc_fpath, 1); - if (strp == NULL) - return HTTP_BAD_REQUEST; - path = apr_pstrcat(p, path, "?", strp, NULL); - } - r->args = NULL; - } - -/* now, rebuild URL */ - - if (port != def_port) - apr_snprintf(sport, sizeof(sport), ":%d", port); - else - sport[0] = '\0'; - - if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ - host = apr_pstrcat(p, "[", host, "]", NULL); - } - r->filename = apr_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "", - (password != NULL) ? ":" : "", - (password != NULL) ? password : "", - (user != NULL) ? "@" : "", host, sport, "/", path, - (parms[0] != '\0') ? ";" : "", parms, NULL); - - return OK; -} - -/* we chop lines longer than 80 characters */ -#define MAX_LINE_LEN 80 - -/* - * Reads response lines, returns both the ftp status code and - * remembers the response message in the supplied buffer - */ -static int ftp_getrc_msg(conn_rec *ftp_ctrl, apr_bucket_brigade *bb, char *msgbuf, int msglen) -{ - int status; - char response[MAX_LINE_LEN]; - char buff[5]; - char *mb = msgbuf, *me = &msgbuf[msglen]; - apr_status_t rv; - int eos; - - if (APR_SUCCESS != (rv = ap_proxy_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) { - return -1; - } -/* - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, - "proxy: <FTP: %s", response); -*/ - if (!apr_isdigit(response[0]) || !apr_isdigit(response[1]) || - !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-')) - status = 0; - else - status = 100 * response[0] + 10 * response[1] + response[2] - 111 * '0'; - - mb = apr_cpystrn(mb, response + 4, me - mb); - - if (response[3] == '-') { - memcpy(buff, response, 3); - buff[3] = ' '; - do { - if (APR_SUCCESS != (rv = ap_proxy_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) { - return -1; - } - mb = apr_cpystrn(mb, response + (' ' == response[0] ? 1 : 4), me - mb); - } while (memcmp(response, buff, 4) != 0); - } - - return status; -} - -/* this is a filter that turns a raw ASCII directory listing into pretty HTML */ - -/* ideally, mod_proxy should simply send the raw directory list up the filter - * stack to mod_autoindex, which in theory should turn the raw ascii into - * pretty html along with all the bells and whistles it provides... - * - * all in good time...! :) - */ - -typedef struct { - apr_bucket_brigade *in; - char buffer[MAX_STRING_LEN]; - enum { - HEADER, BODY, FOOTER - } state; -} proxy_dir_ctx_t; - -/* fallback regex for ls -s1; ($0..$2) == 3 */ -#define LS_REG_PATTERN "^ *([0-9]+) +([^ ]+)$" -#define LS_REG_MATCH 3 - -apr_status_t ap_proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *in) -{ - request_rec *r = f->r; - conn_rec *c = r->connection; - apr_pool_t *p = r->pool; - apr_bucket_brigade *out = apr_brigade_create(p, c->bucket_alloc); - apr_status_t rv; - - register int n; - char *dir, *path, *reldir, *site, *str, *type; - - const char *pwd = apr_table_get(r->notes, "Directory-PWD"); - const char *readme = apr_table_get(r->notes, "Directory-README"); - - proxy_dir_ctx_t *ctx = f->ctx; - - if (!ctx) { - f->ctx = ctx = apr_pcalloc(p, sizeof(*ctx)); - ctx->in = apr_brigade_create(p, c->bucket_alloc); - ctx->buffer[0] = 0; - ctx->state = HEADER; - } - - /* combine the stored and the new */ - APR_BRIGADE_CONCAT(ctx->in, in); - - if (HEADER == ctx->state) { - - /* basedir is either "", or "/%2f" for the "squid %2f hack" */ - const char *basedir = ""; /* By default, path is relative to the $HOME dir */ - char *wildcard = NULL; - - /* Save "scheme://site" prefix without password */ - site = apr_uri_unparse(p, &f->r->parsed_uri, APR_URI_UNP_OMITPASSWORD | APR_URI_UNP_OMITPATHINFO); - /* ... and path without query args */ - path = apr_uri_unparse(p, &f->r->parsed_uri, APR_URI_UNP_OMITSITEPART | APR_URI_UNP_OMITQUERY); - - /* If path began with /%2f, change the basedir */ - if (strncasecmp(path, "/%2f", 4) == 0) { - basedir = "/%2f"; - } - - /* Strip off a type qualifier. It is ignored for dir listings */ - if ((type = strstr(path, ";type=")) != NULL) - *type++ = '\0'; - - (void)decodeenc(path); - - while (path[1] == '/') /* collapse multiple leading slashes to one */ - ++path; - - reldir = strrchr(path, '/'); - if (reldir != NULL && ftp_check_globbingchars(reldir)) { - wildcard = &reldir[1]; - reldir[0] = '\0'; /* strip off the wildcard suffix */ - } - - /* Copy path, strip (all except the last) trailing slashes */ - /* (the trailing slash is needed for the dir component loop below) */ - path = dir = apr_pstrcat(p, path, "/", NULL); - for (n = strlen(path); n > 1 && path[n - 1] == '/' && path[n - 2] == '/'; --n) - path[n - 1] = '\0'; - - /* Add a link to the root directory (if %2f hack was used) */ - str = (basedir[0] != '\0') ? "<a href=\"/%2f/\">%2f</a>/" : ""; - - /* print "ftp://host/" */ - str = apr_psprintf(p, DOCTYPE_HTML_3_2 - "<html>\n <head>\n <title>%s%s%s</title>\n" - " </head>\n" - " <body>\n <h2>Directory of " - "<a href=\"/\">%s</a>/%s", - site, basedir, ap_escape_html(p, path), - site, str); - - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), - p, c->bucket_alloc)); - - for (dir = path+1; (dir = strchr(dir, '/')) != NULL; ) - { - *dir = '\0'; - if ((reldir = strrchr(path+1, '/'))==NULL) { - reldir = path+1; - } - else - ++reldir; - /* print "path/" component */ - str = apr_psprintf(p, "<a href=\"%s%s/\">%s</a>/", basedir, - ap_escape_uri(p, path), - ap_escape_html(p, reldir)); - *dir = '/'; - while (*dir == '/') - ++dir; - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, - strlen(str), p, - c->bucket_alloc)); - } - if (wildcard != NULL) { - wildcard = ap_escape_html(p, wildcard); - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(wildcard, - strlen(wildcard), p, - c->bucket_alloc)); - } - - /* If the caller has determined the current directory, and it differs */ - /* from what the client requested, then show the real name */ - if (pwd == NULL || strncmp(pwd, path, strlen(pwd)) == 0) { - str = apr_psprintf(p, "</h2>\n\n <hr />\n\n<pre>"); - } - else { - str = apr_psprintf(p, "</h2>\n\n(%s)\n\n <hr />\n\n<pre>", - ap_escape_html(p, pwd)); - } - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), - p, c->bucket_alloc)); - - /* print README */ - if (readme) { - str = apr_psprintf(p, "%s\n</pre>\n\n<hr />\n\n<pre>\n", - ap_escape_html(p, readme)); - - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, - strlen(str), p, - c->bucket_alloc)); - } - - /* make sure page intro gets sent out */ - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc)); - if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) { - return rv; - } - apr_brigade_cleanup(out); - - ctx->state = BODY; - } - - /* loop through each line of directory */ - while (BODY == ctx->state) { - char *filename; - int found = 0; - int eos = 0; - - regex_t *re = NULL; - regmatch_t re_result[LS_REG_MATCH]; - - /* Compile the output format of "ls -s1" as a fallback for non-unix ftp listings */ - re = ap_pregcomp(p, LS_REG_PATTERN, REG_EXTENDED); - ap_assert(re != NULL); - - /* get a complete line */ - /* if the buffer overruns - throw data away */ - while (!found && !APR_BRIGADE_EMPTY(ctx->in)) { - char *pos, *response; - apr_size_t len, max; - apr_bucket *e; - - e = APR_BRIGADE_FIRST(ctx->in); - if (APR_BUCKET_IS_EOS(e)) { - eos = 1; - break; - } - if (APR_SUCCESS != (rv = apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ))) { - return rv; - } - pos = memchr(response, APR_ASCII_LF, len); - if (pos != NULL) { - if ((response + len) != (pos + 1)) { - len = pos - response + 1; - apr_bucket_split(e, pos - response + 1); - } - found = 1; - } - max = sizeof(ctx->buffer) - strlen(ctx->buffer) - 1; - if (len > max) { - len = max; - } - - /* len+1 to leave space for the trailing nil char */ - apr_cpystrn(ctx->buffer+strlen(ctx->buffer), response, len+1); - - APR_BUCKET_REMOVE(e); - apr_bucket_destroy(e); - } - - /* EOS? jump to footer */ - if (eos) { - ctx->state = FOOTER; - break; - } - - /* not complete? leave and try get some more */ - if (!found) { - return APR_SUCCESS; - } - - { - apr_size_t n = strlen(ctx->buffer); - if (ctx->buffer[n-1] == CRLF[1]) /* strip trailing '\n' */ - ctx->buffer[--n] = '\0'; - if (ctx->buffer[n-1] == CRLF[0]) /* strip trailing '\r' if present */ - ctx->buffer[--n] = '\0'; - } - - /* a symlink? */ - if (ctx->buffer[0] == 'l' && (filename = strstr(ctx->buffer, " -> ")) != NULL) { - char *link_ptr = filename; - - do { - filename--; - } while (filename[0] != ' ' && filename > ctx->buffer); - if (filename > ctx->buffer) - *(filename++) = '\0'; - *(link_ptr++) = '\0'; - str = apr_psprintf(p, "%s <a href=\"%s\">%s %s</a>\n", - ap_escape_html(p, ctx->buffer), - ap_escape_uri(p, filename), - ap_escape_html(p, filename), - ap_escape_html(p, link_ptr)); - } - - /* a directory/file? */ - else if (ctx->buffer[0] == 'd' || ctx->buffer[0] == '-' || ctx->buffer[0] == 'l' || apr_isdigit(ctx->buffer[0])) { - int searchidx = 0; - char *searchptr = NULL; - int firstfile = 1; - if (apr_isdigit(ctx->buffer[0])) { /* handle DOS dir */ - searchptr = strchr(ctx->buffer, '<'); - if (searchptr != NULL) - *searchptr = '['; - searchptr = strchr(ctx->buffer, '>'); - if (searchptr != NULL) - *searchptr = ']'; - } - - filename = strrchr(ctx->buffer, ' '); - *(filename++) = '\0'; - - /* handle filenames with spaces in 'em */ - if (!strcmp(filename, ".") || !strcmp(filename, "..") || firstfile) { - firstfile = 0; - searchidx = filename - ctx->buffer; - } - else if (searchidx != 0 && ctx->buffer[searchidx] != 0) { - *(--filename) = ' '; - ctx->buffer[searchidx - 1] = '\0'; - filename = &ctx->buffer[searchidx]; - } - - /* Append a slash to the HREF link for directories */ - if (!strcmp(filename, ".") || !strcmp(filename, "..") || ctx->buffer[0] == 'd') { - str = apr_psprintf(p, "%s <a href=\"%s/\">%s</a>\n", - ap_escape_html(p, ctx->buffer), - ap_escape_uri(p, filename), - ap_escape_html(p, filename)); - } - else { - str = apr_psprintf(p, "%s <a href=\"%s\">%s</a>\n", - ap_escape_html(p, ctx->buffer), - ap_escape_uri(p, filename), - ap_escape_html(p, filename)); - } - } - /* Try a fallback for listings in the format of "ls -s1" */ - else if (0 == ap_regexec(re, ctx->buffer, LS_REG_MATCH, re_result, 0)) { - - filename = apr_pstrndup(p, &ctx->buffer[re_result[2].rm_so], re_result[2].rm_eo - re_result[2].rm_so); - - str = apr_pstrcat(p, ap_escape_html(p, apr_pstrndup(p, ctx->buffer, re_result[2].rm_so)), - "<a href=\"", ap_escape_uri(p, filename), "\">", - ap_escape_html(p, filename), "</a>\n", NULL); - } - else { - strcat(ctx->buffer, "\n"); /* re-append the newline */ - str = ap_escape_html(p, ctx->buffer); - } - - /* erase buffer for next time around */ - ctx->buffer[0] = 0; - - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), p, - c->bucket_alloc)); - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc)); - if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) { - return rv; - } - apr_brigade_cleanup(out); - - } - - if (FOOTER == ctx->state) { - str = apr_psprintf(p, "</pre>\n\n <hr />\n\n %s\n\n </body>\n</html>\n", ap_psignature("", r)); - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str), p, - c->bucket_alloc)); - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc)); - APR_BRIGADE_INSERT_TAIL(out, apr_bucket_eos_create(c->bucket_alloc)); - if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) { - return rv; - } - apr_brigade_destroy(out); - } - - return APR_SUCCESS; -} - -/* Parse EPSV reply and return port, or zero on error. */ -static apr_port_t parse_epsv_reply(const char *reply) -{ - const char *p; - char *ep; - long port; - - /* Reply syntax per RFC 2428: "229 blah blah (|||port|)" where '|' - * can be any character in ASCII from 33-126, obscurely. Verify - * the syntax. */ - p = ap_strchr_c(reply, '('); - if (p == NULL || !p[1] || p[1] != p[2] || p[1] != p[3] - || p[4] == p[1]) { - return 0; - } - - errno = 0; - port = strtol(p + 4, &ep, 10); - if (errno || port < 1 || port > 65535 || ep[0] != p[1] || ep[1] != ')') { - return 0; - } - - return (apr_port_t)port; -} - -/* - * Generic "send FTP command to server" routine, using the control socket. - * Returns the FTP returncode (3 digit code) - * Allows for tracing the FTP protocol (in LogLevel debug) - */ -static int -proxy_ftp_command(const char *cmd, request_rec *r, conn_rec *ftp_ctrl, - apr_bucket_brigade *bb, char **pmessage) -{ - char *crlf; - int rc; - char message[HUGE_STRING_LEN]; - - /* If cmd == NULL, we retrieve the next ftp response line */ - if (cmd != NULL) { - conn_rec *c = r->connection; - APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pool_create(cmd, strlen(cmd), r->pool, c->bucket_alloc)); - APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(c->bucket_alloc)); - ap_pass_brigade(ftp_ctrl->output_filters, bb); - - /* strip off the CRLF for logging */ - apr_cpystrn(message, cmd, sizeof(message)); - if ((crlf = strchr(message, '\r')) != NULL || - (crlf = strchr(message, '\n')) != NULL) - *crlf = '\0'; - if (strncmp(message,"PASS ", 5) == 0) - strcpy(&message[5], "****"); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy:>FTP: %s", message); - } - - rc = ftp_getrc_msg(ftp_ctrl, bb, message, sizeof message); - if (rc == -1 || rc == 421) - strcpy(message,"<unable to read result>"); - if ((crlf = strchr(message, '\r')) != NULL || - (crlf = strchr(message, '\n')) != NULL) - *crlf = '\0'; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy:<FTP: %3.3u %s", rc, message); - - if (pmessage != NULL) - *pmessage = apr_pstrdup(r->pool, message); - - return rc; -} - -/* Set ftp server to TYPE {A,I,E} before transfer of a directory or file */ -static int ftp_set_TYPE(char xfer_type, request_rec *r, conn_rec *ftp_ctrl, - apr_bucket_brigade *bb, char **pmessage) -{ - char old_type[2] = { 'A', '\0' }; /* After logon, mode is ASCII */ - int ret = HTTP_OK; - int rc; - - /* set desired type */ - old_type[0] = xfer_type; - - rc = proxy_ftp_command(apr_pstrcat(r->pool, "TYPE ", old_type, CRLF, NULL), - r, ftp_ctrl, bb, pmessage); -/* responses: 200, 421, 500, 501, 504, 530 */ - /* 200 Command okay. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 504 Command not implemented for that parameter. */ - /* 530 Not logged in. */ - if (rc == -1 || rc == 421) { - ret = ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - else if (rc != 200 && rc != 504) { - ret = ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Unable to set transfer type"); - } -/* Allow not implemented */ - else if (rc == 504) - /* ignore it silently */; - - return ret; -} - - -/* Return the current directory which we have selected on the FTP server, or NULL */ -static char *ftp_get_PWD(request_rec *r, conn_rec *ftp_ctrl, apr_bucket_brigade *bb) -{ - char *cwd = NULL; - char *ftpmessage = NULL; - - /* responses: 257, 500, 501, 502, 421, 550 */ - /* 257 "<directory-name>" <commentary> */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 550 Requested action not taken. */ - switch (proxy_ftp_command("PWD" CRLF, r, ftp_ctrl, bb, &ftpmessage)) { - case -1: - case 421: - case 550: - ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Failed to read PWD on ftp server"); - break; - - case 257: { - const char *dirp = ftpmessage; - cwd = ap_getword_conf(r->pool, &dirp); - } - } - return cwd; -} - - -/* Common routine for failed authorization (i.e., missing or wrong password) - * to an ftp service. This causes most browsers to retry the request - * with username and password (which was presumably queried from the user) - * supplied in the Authorization: header. - * Note that we "invent" a realm name which consists of the - * ftp://user@host part of the reqest (sans password -if supplied but invalid-) - */ -static int ftp_unauthorized(request_rec *r, int log_it) -{ - r->proxyreq = PROXYREQ_NONE; - /* - * Log failed requests if they supplied a password (log username/password - * guessing attempts) - */ - if (log_it) - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "proxy: missing or failed auth to %s", - apr_uri_unparse(r->pool, - &r->parsed_uri, APR_URI_UNP_OMITPATHINFO)); - - apr_table_setn(r->err_headers_out, "WWW-Authenticate", - apr_pstrcat(r->pool, "Basic realm=\"", - apr_uri_unparse(r->pool, &r->parsed_uri, - APR_URI_UNP_OMITPASSWORD | APR_URI_UNP_OMITPATHINFO), - "\"", NULL)); - - return HTTP_UNAUTHORIZED; -} - - -/* - * Handles direct access of ftp:// URLs - * Original (Non-PASV) version from - * Troy Morrison <spiffnet@zoom.com> - * PASV added by Chuck - * Filters by [Graham Leggett <minfrin@sharp.fm>] - */ -int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyhost, - apr_port_t proxyport) -{ - apr_pool_t *p = r->pool; - conn_rec *c = r->connection; - proxy_conn_rec *backend; - apr_socket_t *sock, *local_sock, *data_sock = NULL; - apr_sockaddr_t *connect_addr; - apr_status_t rv; - conn_rec *origin, *data = NULL; - int err; - apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); - char *buf, *connectname; - apr_port_t connectport; - char buffer[MAX_STRING_LEN]; - char *ftpmessage = NULL; - char *path, *strp, *type_suffix, *cwd = NULL; - apr_uri_t uri; - char *user = NULL; -/* char *account = NULL; how to supply an account in a URL? */ - const char *password = NULL; - int len, rc; - int one = 1; - char *size = NULL; - apr_socket_t *origin_sock = NULL; - char xfer_type = 'A'; /* after ftp login, the default is ASCII */ - int dirlisting = 0; -#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) - apr_time_t mtime = 0L; -#endif - - /* stuff for PASV mode */ - int connect = 0, use_port = 0; - char dates[APR_RFC822_DATE_LEN]; - - /* is this for us? */ - if (proxyhost) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: declining URL %s - proxyhost %s specified:", url, proxyhost); - return DECLINED; /* proxy connections are via HTTP */ - } - if (strncasecmp(url, "ftp:", 4)) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: declining URL %s - not ftp:", url); - return DECLINED; /* only interested in FTP */ - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: serving URL %s", url); - - /* create space for state information */ - backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, &proxy_ftp_module); - if (!backend) { - backend = apr_pcalloc(c->pool, sizeof(proxy_conn_rec)); - backend->connection = NULL; - backend->hostname = NULL; - backend->port = 0; - ap_set_module_config(c->conn_config, &proxy_ftp_module, backend); - } - if (backend->connection) - origin_sock = ap_get_module_config(backend->connection->conn_config, &core_module); - - - /* - * I: Who Do I Connect To? ----------------------- - * - * Break up the URL to determine the host to connect to - */ - - /* we only support GET and HEAD */ - if (r->method_number != M_GET) - return HTTP_NOT_IMPLEMENTED; - - /* We break the URL into host, port, path-search */ - if (r->parsed_uri.hostname == NULL) { - if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) { - return ap_proxyerror(r, HTTP_BAD_REQUEST, - apr_psprintf(p, "URI cannot be parsed: %s", url)); - } - connectname = uri.hostname; - connectport = uri.port; - path = apr_pstrdup(p, uri.path); - } - else { - connectname = r->parsed_uri.hostname; - connectport = r->parsed_uri.port; - path = apr_pstrdup(p, r->parsed_uri.path); - } - if (connectport == 0) { - connectport = apr_uri_port_of_scheme("ftp"); - } - path = (path != NULL && path[0] != '\0') ? &path[1] : ""; - - type_suffix = strchr(path, ';'); - if (type_suffix != NULL) - *(type_suffix++) = '\0'; - - if (type_suffix != NULL && strncmp(type_suffix, "type=", 5) == 0 - && apr_isalpha(type_suffix[5])) { - /* "type=d" forces a dir listing. - * The other types (i|a|e) are directly used for the ftp TYPE command - */ - if ( ! (dirlisting = (apr_tolower(type_suffix[5]) == 'd'))) - xfer_type = apr_toupper(type_suffix[5]); - - /* Check valid types, rather than ignoring invalid types silently: */ - if (strchr("AEI", xfer_type) == NULL) - return ap_proxyerror(r, HTTP_BAD_REQUEST, apr_pstrcat(r->pool, - "ftp proxy supports only types 'a', 'i', or 'e': \"", - type_suffix, "\" is invalid.", NULL)); - } - else { - /* make binary transfers the default */ - xfer_type = 'I'; - } - - - /* - * The "Authorization:" header must be checked first. We allow the user - * to "override" the URL-coded user [ & password ] in the Browsers' - * User&Password Dialog. NOTE that this is only marginally more secure - * than having the password travel in plain as part of the URL, because - * Basic Auth simply uuencodes the plain text password. But chances are - * still smaller that the URL is logged regularly. - */ - if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL - && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0 - && (password = ap_pbase64decode(r->pool, password))[0] != ':') { - /* Check the decoded string for special characters. */ - if (!ftp_check_string(password)) { - return ap_proxyerror(r, HTTP_BAD_REQUEST, - "user credentials contained invalid character"); - } - /* - * Note that this allocation has to be made from r->connection->pool - * because it has the lifetime of the connection. The other - * allocations are temporary and can be tossed away any time. - */ - user = ap_getword_nulls(r->connection->pool, &password, ':'); - r->ap_auth_type = "Basic"; - r->user = r->parsed_uri.user = user; - } - else if ((user = r->parsed_uri.user) != NULL) { - user = apr_pstrdup(p, user); - decodeenc(user); - if ((password = r->parsed_uri.password) != NULL) { - char *tmp = apr_pstrdup(p, password); - decodeenc(tmp); - password = tmp; - } - } - else { - user = "anonymous"; - password = "apache-proxy@"; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: connecting %s to %s:%d", url, connectname, connectport); - - /* do a DNS lookup for the destination host */ - err = apr_sockaddr_info_get(&connect_addr, connectname, APR_UNSPEC, connectport, 0, p); - - /* check if ProxyBlock directive on this host */ - if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) { - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - - - /* - * II: Make the Connection ----------------------- - * - * We have determined who to connect to. Now make the connection. - */ - - /* - * get all the possible IP addresses for the destname and loop through - * them until we get a successful connection - */ - if (APR_SUCCESS != err) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, - "DNS lookup failure for: ", - connectname, NULL)); - } - - /* - * At this point we have a list of one or more IP addresses of the - * machine to connect to. If configured, reorder this list so that the - * "best candidate" is first try. "best candidate" could mean the least - * loaded server, the fastest responding server, whatever. - * - * For now we do nothing, ie we get DNS round robin. XXX FIXME - */ - - - /* try each IP address until we connect successfully */ - { - int failed = 1; - while (connect_addr) { - - if ((rv = apr_socket_create(&sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error creating socket"); - connect_addr = connect_addr->next; - continue; - } - -#if !defined(TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 - && (rv = apr_socket_opt_set(sock, APR_SO_RCVBUF, - conf->recv_buffer_size))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "apr_socket_opt_set(APR_SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - if (APR_SUCCESS != (rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, one))) { - apr_socket_close(sock); -#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error setting reuseaddr option: apr_socket_opt_set(APR_SO_REUSEADDR)"); - connect_addr = connect_addr->next; - continue; -#endif /* _OSD_POSIX */ - } - - /* Set a timeout on the socket */ - if (conf->timeout_set == 1) { - apr_socket_timeout_set(sock, conf->timeout); - } - else { - apr_socket_timeout_set(sock, r->server->timeout); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: fam %d socket created, trying to connect to %pI (%s)...", - connect_addr->family, connect_addr, connectname); - - /* make the connection out of the socket */ - rv = apr_connect(sock, connect_addr); - - /* if an error occurred, loop round and try again */ - if (rv != APR_SUCCESS) { - apr_socket_close(sock); - ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, - "proxy: FTP: attempt to connect to %pI (%s) failed", connect_addr, connectname); - connect_addr = connect_addr->next; - continue; - } - - /* if we get here, all is well */ - failed = 0; - break; - } - - /* handle a permanent error from the above loop */ - if (failed) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool, - "Could not connect to remote machine: %s port %d", - connectname, connectport)); - } - } - - /* the socket is now open, create a new connection */ - origin = ap_run_create_connection(p, r->server, sock, r->connection->id, - r->connection->sbh, c->bucket_alloc); - if (!origin) { - /* - * the peer reset the connection already; ap_run_create_connection() closed - * the socket - */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: an error occurred creating a new connection to %pI (%s)", connect_addr, connectname); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* if a keepalive connection is floating around, close it first! */ - /* we might support ftp keepalives later, but not now... */ - if (backend->connection) { - apr_socket_close(origin_sock); - backend->connection = NULL; - origin_sock = NULL; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: control connection complete"); - - - /* - * III: Send Control Request ------------------------- - * - * Log into the ftp server, send the username & password, change to the - * correct directory... - */ - - /* set up the connection filters */ - rc = ap_run_pre_connection(origin, sock); - if (rc != OK && rc != DONE) { - origin->aborted = 1; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: pre_connection setup failed (%d)", - rc); - return rc; - } - - /* possible results: */ - /* 120 Service ready in nnn minutes. */ - /* 220 Service ready for new user. */ - /* 421 Service not available, closing control connection. */ - rc = proxy_ftp_command(NULL, r, origin, bb, &ftpmessage); - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server"); - } - if (rc == 120) { - /* - * RFC2616 states: 14.37 Retry-After - * - * The Retry-After response-header field can be used with a 503 (Service - * Unavailable) response to indicate how long the service is expected - * to be unavailable to the requesting client. [...] The value of - * this field can be either an HTTP-date or an integer number of - * seconds (in decimal) after the time of the response. Retry-After - * = "Retry-After" ":" ( HTTP-date | delta-seconds ) - */ - char *secs_str = ftpmessage; - time_t secs; - - /* Look for a number, preceded by whitespace */ - while (*secs_str) - if ((secs_str==ftpmessage || apr_isspace(secs_str[-1])) && - apr_isdigit(secs_str[0])) - break; - if (*secs_str != '\0') { - secs = atol(secs_str); - apr_table_add(r->headers_out, "Retry-After", - apr_psprintf(p, "%lu", (unsigned long)(60 * secs))); - } - return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, ftpmessage); - } - if (rc != 220) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - - rc = proxy_ftp_command(apr_pstrcat(p, "USER ", user, CRLF, NULL), - r, origin, bb, &ftpmessage); - /* possible results; 230, 331, 332, 421, 500, 501, 530 */ - /* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */ - /* 230 User logged in, proceed. */ - /* 331 User name okay, need password. */ - /* 332 Need account for login. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* (This may include errors such as command line too long.) */ - /* 501 Syntax error in parameters or arguments. */ - /* 530 Not logged in. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server"); - } - if (rc == 530) { - return ftp_unauthorized(r, 1); /* log it: user name guessing - * attempt? */ - } - if (rc != 230 && rc != 331) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - - if (rc == 331) { /* send password */ - if (password == NULL) { - return ftp_unauthorized(r, 0); - } - - rc = proxy_ftp_command(apr_pstrcat(p, "PASS ", password, CRLF, NULL), - r, origin, bb, &ftpmessage); - /* possible results 202, 230, 332, 421, 500, 501, 503, 530 */ - /* 230 User logged in, proceed. */ - /* 332 Need account for login. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 503 Bad sequence of commands. */ - /* 530 Not logged in. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 332) { - return ap_proxyerror(r, HTTP_UNAUTHORIZED, - apr_pstrcat(p, "Need account for login: ", ftpmessage, NULL)); - } - /* @@@ questionable -- we might as well return a 403 Forbidden here */ - if (rc == 530) { - return ftp_unauthorized(r, 1); /* log it: passwd guessing - * attempt? */ - } - if (rc != 230 && rc != 202) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - } - apr_table_set(r->notes, "Directory-README", ftpmessage); - - - /* Special handling for leading "%2f": this enforces a "cwd /" - * out of the $HOME directory which was the starting point after login - */ - if (strncasecmp(path, "%2f", 3) == 0) { - path += 3; - while (*path == '/') /* skip leading '/' (after root %2f) */ - ++path; - - rc = proxy_ftp_command("CWD /" CRLF, r, origin, bb, &ftpmessage); - if (rc == -1 || rc == 421) - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - - /* - * set the directory (walk directory component by component): this is - * what we must do if we don't know the OS type of the remote machine - */ - for (;;) { - strp = strchr(path, '/'); - if (strp == NULL) - break; - *strp = '\0'; - - len = decodeenc(path); /* Note! This decodes a %2f -> "/" */ - - if (strchr(path, '/')) { /* are there now any '/' characters? */ - return ap_proxyerror(r, HTTP_BAD_REQUEST, - "Use of /%2f is only allowed at the base directory"); - } - - /* NOTE: FTP servers do globbing on the path. - * So we need to escape the URI metacharacters. - * We use a special glob-escaping routine to escape globbing chars. - * We could also have extended gen_test_char.c with a special T_ESCAPE_FTP_PATH - */ - rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", - ftp_escape_globbingchars(p, path), CRLF, NULL), - r, origin, bb, &ftpmessage); - *strp = '/'; - /* responses: 250, 421, 500, 501, 502, 530, 550 */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 550) { - return ap_proxyerror(r, HTTP_NOT_FOUND, ftpmessage); - } - if (rc != 250) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - - path = strp + 1; - } - - /* - * IV: Make Data Connection? ------------------------- - * - * Try EPSV, if that fails... try PASV, if that fails... try PORT. - */ -/* this temporarily switches off EPSV/PASV */ -/*goto bypass;*/ - - /* set up data connection - EPSV */ - { - apr_sockaddr_t *data_addr; - char *data_ip; - apr_port_t data_port; - - /* - * The EPSV command replaces PASV where both IPV4 and IPV6 is - * supported. Only the port is returned, the IP address is always the - * same as that on the control connection. Example: Entering Extended - * Passive Mode (|||6446|) - */ - rc = proxy_ftp_command("EPSV" CRLF, - r, origin, bb, &ftpmessage); - /* possible results: 227, 421, 500, 501, 502, 530 */ - /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc != 229 && rc != 500 && rc != 501 && rc != 502) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - else if (rc == 229) { - /* Parse the port out of the EPSV reply. */ - data_port = parse_epsv_reply(ftpmessage); - - if (data_port) { - apr_sockaddr_t *epsv_addr; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: EPSV contacting remote host on port %d", - data_port); - - if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error creating EPSV socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - -#if !defined (TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 - && (rv = apr_socket_opt_set(data_sock, APR_SO_RCVBUF, - conf->recv_buffer_size))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - /* make the connection */ - apr_socket_addr_get(&data_addr, APR_REMOTE, sock); - apr_sockaddr_ip_get(&data_ip, data_addr); - apr_sockaddr_info_get(&epsv_addr, data_ip, connect_addr->family, data_port, 0, p); - rv = apr_connect(data_sock, epsv_addr); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, - "proxy: FTP: EPSV attempt to connect to %pI failed - Firewall/NAT?", epsv_addr); - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool, - "EPSV attempt to connect to %pI failed - firewall/NAT?", epsv_addr)); - } - else { - connect = 1; - } - } - } - } - - /* set up data connection - PASV */ - if (!connect) { - rc = proxy_ftp_command("PASV" CRLF, - r, origin, bb, &ftpmessage); - /* possible results: 227, 421, 500, 501, 502, 530 */ - /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc != 227 && rc != 502) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - else if (rc == 227) { - unsigned int h0, h1, h2, h3, p0, p1; - char *pstr; - char *tok_cntx; - -/* FIXME: Check PASV against RFC1123 */ - - pstr = ftpmessage; - pstr = apr_strtok(pstr, " ", &tok_cntx); /* separate result code */ - if (pstr != NULL) { - if (*(pstr + strlen(pstr) + 1) == '=') { - pstr += strlen(pstr) + 2; - } - else { - pstr = apr_strtok(NULL, "(", &tok_cntx); /* separate address & - * port params */ - if (pstr != NULL) - pstr = apr_strtok(NULL, ")", &tok_cntx); - } - } - -/* FIXME: Only supports IPV4 - fix in RFC2428 */ - - if (pstr != NULL && (sscanf(pstr, - "%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) { - - apr_sockaddr_t *pasv_addr; - apr_port_t pasvport = (p1 << 8) + p0; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: PASV contacting host %d.%d.%d.%d:%d", - h3, h2, h1, h0, pasvport); - - if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: error creating PASV socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - -#if !defined (TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 - && (rv = apr_socket_opt_set(data_sock, APR_SO_RCVBUF, - conf->recv_buffer_size))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - /* make the connection */ - apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), connect_addr->family, pasvport, 0, p); - rv = apr_connect(data_sock, pasv_addr); - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, - "proxy: FTP: PASV attempt to connect to %pI failed - Firewall/NAT?", pasv_addr); - return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool, - "PASV attempt to connect to %pI failed - firewall/NAT?", pasv_addr)); - } - else { - connect = 1; - } - } - } - } -/*bypass:*/ - - /* set up data connection - PORT */ - if (!connect) { - apr_sockaddr_t *local_addr; - char *local_ip; - apr_port_t local_port; - unsigned int h0, h1, h2, h3, p0, p1; - - if ((rv = apr_socket_create(&local_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error creating local socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - apr_socket_addr_get(&local_addr, APR_LOCAL, sock); - apr_sockaddr_port_get(&local_port, local_addr); - apr_sockaddr_ip_get(&local_ip, local_addr); - - if ((rv = apr_socket_opt_set(local_sock, APR_SO_REUSEADDR, one)) - != APR_SUCCESS) { -#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error setting reuseaddr option"); - return HTTP_INTERNAL_SERVER_ERROR; -#endif /* _OSD_POSIX */ - } - - apr_sockaddr_info_get(&local_addr, local_ip, APR_UNSPEC, local_port, 0, r->pool); - - if ((rv = apr_bind(local_sock, local_addr)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error binding to ftp data socket %pI", local_addr); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* only need a short queue */ - if ((rv = apr_listen(local_sock, 2)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error listening to ftp data socket %pI", local_addr); - return HTTP_INTERNAL_SERVER_ERROR; - } - -/* FIXME: Sent PORT here */ - - if (local_ip && (sscanf(local_ip, - "%d.%d.%d.%d", &h3, &h2, &h1, &h0) == 4)) { - p1 = (local_port >> 8); - p0 = (local_port & 0xFF); - - rc = proxy_ftp_command(apr_psprintf(p, "PORT %d,%d,%d,%d,%d,%d" CRLF, h3, h2, h1, h0, p1, p0), - r, origin, bb, &ftpmessage); - /* possible results: 200, 421, 500, 501, 502, 530 */ - /* 200 Command okay. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc != 200) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer); - } - - /* signal that we must use the EPRT/PORT loop */ - use_port = 1; - } - else { -/* IPV6 FIXME: - * The EPRT command replaces PORT where both IPV4 and IPV6 is supported. The first - * number (1,2) indicates the protocol type. Examples: - * EPRT |1|132.235.1.2|6275| - * EPRT |2|1080::8:800:200C:417A|5282| - */ - return ap_proxyerror(r, HTTP_NOT_IMPLEMENTED, "Connect to IPV6 ftp server using EPRT not supported. Enable EPSV."); - } - } - - - /* - * V: Set The Headers ------------------- - * - * Get the size of the request, set up the environment for HTTP. - */ - - /* set request; "path" holds last path component */ - len = decodeenc(path); - - if (strchr(path, '/')) { /* are there now any '/' characters? */ - return ap_proxyerror(r, HTTP_BAD_REQUEST, - "Use of /%2f is only allowed at the base directory"); - } - - /* If len == 0 then it must be a directory (you can't RETR nothing) - * Also, don't allow to RETR by wildcard. Instead, create a dirlisting - */ - if (len == 0 || ftp_check_globbingchars(path)) { - dirlisting = 1; - } - else { - /* (from FreeBSD ftpd): - * SIZE is not in RFC959, but Postel has blessed it and - * it will be in the updated RFC. - * - * Return size of file in a format suitable for - * using with RESTART (we just count bytes). - */ - /* from draft-ietf-ftpext-mlst-14.txt: - * This value will - * change depending on the current STRUcture, MODE and TYPE of the data - * connection, or a data connection which would be created were one - * created now. Thus, the result of the SIZE command is dependent on - * the currently established STRU, MODE and TYPE parameters. - */ - /* Therefore: switch to binary if the user did not specify ";type=a" */ - ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); - rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ", - ftp_escape_globbingchars(p, path), CRLF, NULL), - r, origin, bb, &ftpmessage); - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - else if (rc == 213) {/* Size command ok */ - int j; - for (j = 0; apr_isdigit(ftpmessage[j]); j++) - ; - ftpmessage[j] = '\0'; - if (ftpmessage[0] != '\0') - size = ftpmessage; /* already pstrdup'ed: no copy necessary */ - } - else if (rc == 550) { /* Not a regular file */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: SIZE shows this is a directory"); - dirlisting = 1; - rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", - ftp_escape_globbingchars(p, path), CRLF, NULL), - r, origin, bb, &ftpmessage); - /* possible results: 250, 421, 500, 501, 502, 530, 550 */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 550) { - return ap_proxyerror(r, HTTP_NOT_FOUND, ftpmessage); - } - if (rc != 250) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - path = ""; - len = 0; - } - } - - cwd = ftp_get_PWD(r, origin, bb); - if (cwd != NULL) { - apr_table_set(r->notes, "Directory-PWD", cwd); - } - - if (dirlisting) { - ftp_set_TYPE('A', r, origin, bb, NULL); - /* If the current directory contains no slash, we are talking to - * a non-unix ftp system. Try LIST instead of "LIST -lag", it - * should return a long listing anyway (unlike NLST). - * Some exotic FTP servers might choke on the "-lag" switch. - */ - /* Note that we do not escape the path here, to allow for - * queries like: ftp://user@host/apache/src/server/http_*.c - */ - if (len != 0) - buf = apr_pstrcat(p, "LIST ", path, CRLF, NULL); - else if (cwd == NULL || strchr(cwd, '/') != NULL) - buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL); - else - buf = "LIST" CRLF; - } - else { - /* switch to binary if the user did not specify ";type=a" */ - ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage); -#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) - /* from draft-ietf-ftpext-mlst-14.txt: - * The FTP command, MODIFICATION TIME (MDTM), can be used to determine - * when a file in the server NVFS was last modified. <..> - * The syntax of a time value is: - * time-val = 14DIGIT [ "." 1*DIGIT ] <..> - * Symbolically, a time-val may be viewed as - * YYYYMMDDHHMMSS.sss - * The "." and subsequent digits ("sss") are optional. <..> - * Time values are always represented in UTC (GMT) - */ - rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path), CRLF, NULL), - r, origin, bb, &ftpmessage); - /* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx GMT). */ - if (rc == 213) { - struct { - char YYYY[4+1]; - char MM[2+1]; - char DD[2+1]; - char hh[2+1]; - char mm[2+1]; - char ss[2+1]; - } time_val; - if (6 == sscanf(ftpmessage, "%4[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]%2[0-9]", - time_val.YYYY, time_val.MM, time_val.DD, time_val.hh, time_val.mm, time_val.ss)) { - struct tm tms; - memset (&tms, '\0', sizeof tms); - tms.tm_year = atoi(time_val.YYYY) - 1900; - tms.tm_mon = atoi(time_val.MM) - 1; - tms.tm_mday = atoi(time_val.DD); - tms.tm_hour = atoi(time_val.hh); - tms.tm_min = atoi(time_val.mm); - tms.tm_sec = atoi(time_val.ss); -#ifdef HAVE_TIMEGM /* Does system have timegm()? */ - mtime = timegm(&tms); - mtime *= APR_USEC_PER_SEC; -#elif HAVE_GMTOFF /* does struct tm have a member tm_gmtoff? */ - /* mktime will subtract the local timezone, which is not what we want. - * Add it again because the MDTM string is GMT - */ - mtime = mktime(&tms); - mtime += tms.tm_gmtoff; - mtime *= APR_USEC_PER_SEC; -#else - mtime = 0L; -#endif - } - } -#endif /* USE_MDTM */ -/* FIXME: Handle range requests - send REST */ - buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path), CRLF, NULL); - } - rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage); - /* rc is an intermediate response for the LIST or RETR commands */ - - /* - * RETR: 110, 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 530, - * 550 NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, - * 530 - */ - /* 110 Restart marker reply. */ - /* 125 Data connection already open; transfer starting. */ - /* 150 File status okay; about to open data connection. */ - /* 226 Closing data connection. */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 425 Can't open data connection. */ - /* 426 Connection closed; transfer aborted. */ - /* 450 Requested file action not taken. */ - /* 451 Requested action aborted. Local error in processing. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 550) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: RETR failed, trying LIST instead"); - - /* Directory Listings should always be fetched in ASCII mode */ - dirlisting = 1; - ftp_set_TYPE('A', r, origin, bb, NULL); - - rc = proxy_ftp_command(apr_pstrcat(p, "CWD ", - ftp_escape_globbingchars(p, path), CRLF, NULL), - r, origin, bb, &ftpmessage); - /* possible results: 250, 421, 500, 501, 502, 530, 550 */ - /* 250 Requested file action okay, completed. */ - /* 421 Service not available, closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - /* 501 Syntax error in parameters or arguments. */ - /* 502 Command not implemented. */ - /* 530 Not logged in. */ - /* 550 Requested action not taken. */ - if (rc == -1 || rc == 421) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc == 550) { - return ap_proxyerror(r, HTTP_NOT_FOUND, ftpmessage); - } - if (rc != 250) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - - /* Update current directory after CWD */ - cwd = ftp_get_PWD(r, origin, bb); - if (cwd != NULL) { - apr_table_set(r->notes, "Directory-PWD", cwd); - } - - /* See above for the "LIST" vs. "LIST -lag" discussion. */ - rc = proxy_ftp_command((cwd == NULL || strchr(cwd, '/') != NULL) - ? "LIST -lag" CRLF : "LIST" CRLF, - r, origin, bb, &ftpmessage); - - /* rc is an intermediate response for the LIST command (125 transfer starting, 150 opening data connection) */ - if (rc == -1 || rc == 421) - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - if (rc != 125 && rc != 150 && rc != 226 && rc != 250) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, ftpmessage); - } - - r->status = HTTP_OK; - r->status_line = "200 OK"; - - apr_rfc822_date(dates, r->request_time); - apr_table_setn(r->headers_out, "Date", dates); - apr_table_setn(r->headers_out, "Server", ap_get_server_version()); - - /* set content-type */ - if (dirlisting) { - ap_set_content_type(r, "text/html; charset=ISO-8859-1"); - } - else { - if (r->content_type) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: Content-Type set to %s", r->content_type); - } - else { - ap_set_content_type(r, ap_default_type(r)); - } - if (xfer_type != 'A' && size != NULL) { - /* We "trust" the ftp server to really serve (size) bytes... */ - apr_table_setn(r->headers_out, "Content-Length", size); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: Content-Length set to %s", size); - } - } - apr_table_setn(r->headers_out, "Content-Type", r->content_type); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: Content-Type set to %s", r->content_type); - -#if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF)) - if (mtime != 0L) { - char datestr[APR_RFC822_DATE_LEN]; - apr_rfc822_date(datestr, mtime); - apr_table_set(r->headers_out, "Last-Modified", datestr); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: Last-Modified set to %s", datestr); - } -#endif /* USE_MDTM */ - - /* If an encoding has been set by mistake, delete it. - * @@@ FIXME (e.g., for ftp://user@host/file*.tar.gz, - * @@@ the encoding is currently set to x-gzip) - */ - if (dirlisting && r->content_encoding != NULL) - r->content_encoding = NULL; - - /* set content-encoding (not for dir listings, they are uncompressed)*/ - if (r->content_encoding != NULL && r->content_encoding[0] != '\0') { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: Content-Encoding set to %s", r->content_encoding); - apr_table_setn(r->headers_out, "Content-Encoding", r->content_encoding); - } - - /* wait for connection */ - if (use_port) { - for (;;) { - rv = apr_accept(&data_sock, local_sock, r->pool); - if (rv == APR_EINTR) { - continue; - } - else if (rv == APR_SUCCESS) { - break; - } - else { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: failed to accept data connection"); - return HTTP_BAD_GATEWAY; - } - } - } - - /* the transfer socket is now open, create a new connection */ - data = ap_run_create_connection(p, r->server, data_sock, r->connection->id, - r->connection->sbh, c->bucket_alloc); - if (!data) { - /* - * the peer reset the connection already; ap_run_create_connection() closed - * the socket - */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: an error occurred creating the transfer connection"); - return HTTP_INTERNAL_SERVER_ERROR; - } - - /* set up the connection filters */ - rc = ap_run_pre_connection(data, data_sock); - if (rc != OK && rc != DONE) { - data->aborted = 1; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: pre_connection setup failed (%d)", - rc); - return rc; - } - - /* - * VI: Receive the Response ------------------------ - * - * Get response from the remote ftp socket, and pass it up the filter chain. - */ - - /* send response */ - r->sent_bodyct = 1; - - if (dirlisting) { - /* insert directory filter */ - ap_add_output_filter("PROXY_SEND_DIR", NULL, r, r->connection); - } - - /* send body */ - if (!r->header_only) { - apr_bucket *e; - int finish = FALSE; - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: start body send"); - - /* read the body, pass it to the output filters */ - while (ap_get_brigade(data->input_filters, - bb, - AP_MODE_READBYTES, - APR_BLOCK_READ, - conf->io_buffer_size) == APR_SUCCESS) { -#if DEBUGGING - { - apr_off_t readbytes; - apr_brigade_length(bb, 0, &readbytes); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, - r->server, "proxy (PID %d): readbytes: %#x", - getpid(), readbytes); - } -#endif - /* sanity check */ - if (APR_BRIGADE_EMPTY(bb)) { - apr_brigade_cleanup(bb); - break; - } - - /* found the last brigade? */ - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { - /* if this is the last brigade, cleanup the - * backend connection first to prevent the - * backend server from hanging around waiting - * for a slow client to eat these bytes - */ - ap_flush_conn(data); - if (data_sock) { - apr_socket_close(data_sock); - } - data_sock = NULL; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: data connection closed"); - /* signal that we must leave */ - finish = TRUE; - } - - /* if no EOS yet, then we must flush */ - if (FALSE == finish) { - e = apr_bucket_flush_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - - /* try send what we read */ - if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS - || c->aborted) { - /* Ack! Phbtt! Die! User aborted! */ - finish = TRUE; - } - - /* make sure we always clean up after ourselves */ - apr_brigade_cleanup(bb); - - /* if we are done, leave */ - if (TRUE == finish) { - break; - } - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: end body send"); - - } - if (data_sock) { - ap_flush_conn(data); - apr_socket_close(data_sock); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: data connection closed"); - } - - /* Retrieve the final response for the RETR or LIST commands */ - rc = proxy_ftp_command(NULL, r, origin, bb, &ftpmessage); - apr_brigade_cleanup(bb); - - /* - * VII: Clean Up ------------- - * - * If there are no KeepAlives, or if the connection has been signalled to - * close, close the socket and clean up - */ - - /* finish */ - rc = proxy_ftp_command("QUIT" CRLF, - r, origin, bb, &ftpmessage); - /* responses: 221, 500 */ - /* 221 Service closing control connection. */ - /* 500 Syntax error, command unrecognized. */ - ap_flush_conn(origin); - if (origin_sock) { - apr_socket_close(origin_sock); - origin_sock = NULL; - } - apr_brigade_destroy(bb); - return OK; -} - -static void ap_proxy_ftp_register_hook(apr_pool_t *p) -{ - /* hooks */ - proxy_hook_scheme_handler(ap_proxy_ftp_handler, NULL, NULL, APR_HOOK_MIDDLE); - proxy_hook_canon_handler(ap_proxy_ftp_canon, NULL, NULL, APR_HOOK_MIDDLE); - /* filters */ - ap_register_output_filter("PROXY_SEND_DIR", ap_proxy_send_dir_filter, - NULL, AP_FTYPE_RESOURCE); -} - -module AP_MODULE_DECLARE_DATA proxy_ftp_module = { - STANDARD20_MODULE_STUFF, - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - NULL, /* command apr_table_t */ - ap_proxy_ftp_register_hook /* register hooks */ -}; diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_http.c b/rubbos/app/httpd-2.0.64/modules/proxy/proxy_http.c deleted file mode 100644 index ca5f038b..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_http.c +++ /dev/null @@ -1,1824 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* HTTP routines for Apache proxy */ - -#include "mod_proxy.h" - -module AP_MODULE_DECLARE_DATA proxy_http_module; - -int ap_proxy_http_canon(request_rec *r, char *url); -int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyname, - apr_port_t proxyport); - -typedef struct { - const char *name; - apr_port_t port; - apr_sockaddr_t *addr; - apr_socket_t *sock; - int close; -} proxy_http_conn_t; - -static apr_status_t ap_proxy_http_cleanup(request_rec *r, - proxy_http_conn_t *p_conn, - proxy_conn_rec *backend); - -/* - * Canonicalise http-like URLs. - * scheme is the scheme for the URL - * url is the URL starting with the first '/' - * def_port is the default port for this scheme. - */ -int ap_proxy_http_canon(request_rec *r, char *url) -{ - char *host, *path, *search, sport[7]; - const char *err; - const char *scheme; - apr_port_t port, def_port; - - /* ap_port_of_scheme() */ - if (strncasecmp(url, "http:", 5) == 0) { - url += 5; - scheme = "http"; - } - else if (strncasecmp(url, "https:", 6) == 0) { - url += 6; - scheme = "https"; - } - else { - return DECLINED; - } - def_port = apr_uri_port_of_scheme(scheme); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: HTTP: canonicalising URL %s", url); - - /* do syntatic check. - * We break the URL into host, port, path, search - */ - port = def_port; - err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port); - if (err) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "error parsing URL %s: %s", - url, err); - return HTTP_BAD_REQUEST; - } - - /* now parse path/search args, according to rfc1738 */ - /* N.B. if this isn't a true proxy request, then the URL _path_ - * has already been decoded. True proxy requests have r->uri - * == r->unparsed_uri, and no others have that property. - */ - if (r->uri == r->unparsed_uri) { - search = strchr(url, '?'); - if (search != NULL) - *(search++) = '\0'; - } - else - search = r->args; - - /* process path */ - path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, r->proxyreq); - if (path == NULL) - return HTTP_BAD_REQUEST; - - if (port != def_port) - apr_snprintf(sport, sizeof(sport), ":%d", port); - else - sport[0] = '\0'; - - if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */ - host = apr_pstrcat(r->pool, "[", host, "]", NULL); - } - r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, - "/", path, (search) ? "?" : "", (search) ? search : "", NULL); - return OK; -} - -static const char *ap_proxy_location_reverse_map(request_rec *r, proxy_server_conf *conf, const char *url) -{ - struct proxy_alias *ent; - int i, l1, l2; - char *u; - - /* XXX FIXME: Make sure this handled the ambiguous case of the :80 - * after the hostname */ - - l1 = strlen(url); - ent = (struct proxy_alias *)conf->raliases->elts; - for (i = 0; i < conf->raliases->nelts; i++) { - l2 = strlen(ent[i].real); - if (l1 >= l2 && strncmp(ent[i].real, url, l2) == 0) { - u = apr_pstrcat(r->pool, ent[i].fake, &url[l2], NULL); - return ap_construct_url(r->pool, u, r); - } - } - return url; -} - -/* Clear all connection-based headers from the incoming headers table */ -static void ap_proxy_clear_connection(apr_pool_t *p, apr_table_t *headers) -{ - const char *name; - char *next = apr_pstrdup(p, apr_table_get(headers, "Connection")); - - apr_table_unset(headers, "Proxy-Connection"); - if (!next) - return; - - while (*next) { - name = next; - while (*next && !apr_isspace(*next) && (*next != ',')) { - ++next; - } - while (*next && (apr_isspace(*next) || (*next == ','))) { - *next = '\0'; - ++next; - } - apr_table_unset(headers, name); - } - apr_table_unset(headers, "Connection"); -} - -static -apr_status_t ap_proxy_http_determine_connection(apr_pool_t *p, request_rec *r, - proxy_http_conn_t *p_conn, - conn_rec *c, - proxy_server_conf *conf, - apr_uri_t *uri, - char **url, - const char *proxyname, - apr_port_t proxyport, - char *server_portstr, - int server_portstr_size) { - int server_port; - apr_status_t err; - apr_sockaddr_t *uri_addr; - /* - * Break up the URL to determine the host to connect to - */ - - /* we break the URL into host, port, uri */ - if (APR_SUCCESS != apr_uri_parse(p, *url, uri)) { - return ap_proxyerror(r, HTTP_BAD_REQUEST, - apr_pstrcat(p,"URI cannot be parsed: ", *url, - NULL)); - } - if (!uri->port) { - uri->port = apr_uri_port_of_scheme(uri->scheme); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: HTTP connecting %s to %s:%d", *url, uri->hostname, - uri->port); - - /* do a DNS lookup for the destination host */ - /* see memory note above */ - err = apr_sockaddr_info_get(&uri_addr, apr_pstrdup(c->pool, uri->hostname), - APR_UNSPEC, uri->port, 0, c->pool); - - /* allocate these out of the connection pool - the check on - * r->connection->id makes sure that this string does not get accessed - * past the connection lifetime */ - /* are we connecting directly, or via a proxy? */ - if (proxyname) { - p_conn->name = apr_pstrdup(c->pool, proxyname); - p_conn->port = proxyport; - /* see memory note above */ - err = apr_sockaddr_info_get(&p_conn->addr, p_conn->name, APR_UNSPEC, - p_conn->port, 0, c->pool); - } else { - p_conn->name = apr_pstrdup(c->pool, uri->hostname); - p_conn->port = uri->port; - p_conn->addr = uri_addr; - *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "", - uri->query ? uri->query : "", - uri->fragment ? "#" : "", - uri->fragment ? uri->fragment : "", NULL); - } - - if (err != APR_SUCCESS) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - apr_pstrcat(p, "DNS lookup failure for: ", - p_conn->name, NULL)); - } - - /* Get the server port for the Via headers */ - { - server_port = ap_get_server_port(r); - if (ap_is_default_port(server_port, r)) { - strcpy(server_portstr,""); - } else { - apr_snprintf(server_portstr, server_portstr_size, ":%d", - server_port); - } - } - - /* check if ProxyBlock directive on this host */ - if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) { - return ap_proxyerror(r, HTTP_FORBIDDEN, - "Connect to remote machine blocked"); - } - return OK; -} - -static -apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r, - proxy_http_conn_t *p_conn, - conn_rec *c, conn_rec **origin, - proxy_conn_rec *backend, - proxy_server_conf *conf, - const char *proxyname) { - int failed=0, new=0; - apr_socket_t *client_socket = NULL; - - /* We have determined who to connect to. Now make the connection, supporting - * a KeepAlive connection. - */ - - /* get all the possible IP addresses for the destname and loop through them - * until we get a successful connection - */ - - /* if a keepalive socket is already open, check whether it must stay - * open, or whether it should be closed and a new socket created. - */ - /* see memory note above */ - if (backend->connection) { - client_socket = ap_get_module_config(backend->connection->conn_config, &core_module); - if ((backend->connection->id == c->id) && - (backend->port == p_conn->port) && - (backend->hostname) && - (!apr_strnatcasecmp(backend->hostname, p_conn->name))) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: keepalive address match (keep original socket)"); - } else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: keepalive address mismatch / connection has" - " changed (close old socket (%s/%s, %d/%d))", - p_conn->name, backend->hostname, p_conn->port, - backend->port); - apr_socket_close(client_socket); - backend->connection = NULL; - } - } - - /* get a socket - either a keepalive one, or a new one */ - new = 1; - if ((backend->connection) && (backend->connection->id == c->id)) { - apr_size_t buffer_len = 1; - char test_buffer[1]; - apr_status_t socket_status; - apr_interval_time_t current_timeout; - - /* use previous keepalive socket */ - *origin = backend->connection; - p_conn->sock = client_socket; - new = 0; - - /* save timeout */ - apr_socket_timeout_get(p_conn->sock, ¤t_timeout); - /* set no timeout */ - apr_socket_timeout_set(p_conn->sock, 0); - socket_status = apr_recv(p_conn->sock, test_buffer, &buffer_len); - /* put back old timeout */ - apr_socket_timeout_set(p_conn->sock, current_timeout); - if ( APR_STATUS_IS_EOF(socket_status) ) { - ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, - "proxy: previous connection is closed, creating a new connection."); - new = 1; - } - } - if (new) { - int rc; - - /* create a new socket */ - backend->connection = NULL; - - /* - * At this point we have a list of one or more IP addresses of - * the machine to connect to. If configured, reorder this - * list so that the "best candidate" is first try. "best - * candidate" could mean the least loaded server, the fastest - * responding server, whatever. - * - * For now we do nothing, ie we get DNS round robin. - * XXX FIXME - */ - failed = ap_proxy_connect_to_backend(&p_conn->sock, "HTTP", - p_conn->addr, p_conn->name, - conf, r->server, c->pool); - - /* handle a permanent error on the connect */ - if (failed) { - if (proxyname) { - return DECLINED; - } else { - return HTTP_BAD_GATEWAY; - } - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: socket is connected"); - - /* the socket is now open, create a new backend server connection */ - *origin = ap_run_create_connection(c->pool, r->server, p_conn->sock, - r->connection->id, - r->connection->sbh, c->bucket_alloc); - if (!*origin) { - /* the peer reset the connection already; ap_run_create_connection() - * closed the socket - */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, - r->server, "proxy: an error occurred creating a " - "new connection to %pI (%s)", p_conn->addr, - p_conn->name); - apr_socket_close(p_conn->sock); - return HTTP_INTERNAL_SERVER_ERROR; - } - backend->connection = *origin; - backend->hostname = apr_pstrdup(c->pool, p_conn->name); - backend->port = p_conn->port; - - if (backend->is_ssl) { - if (!ap_proxy_ssl_enable(backend->connection)) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, - r->server, "proxy: failed to enable ssl support " - "for %pI (%s)", p_conn->addr, p_conn->name); - return HTTP_INTERNAL_SERVER_ERROR; - } - } - else { - ap_proxy_ssl_disable(backend->connection); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: connection complete to %pI (%s)", - p_conn->addr, p_conn->name); - - /* set up the connection filters */ - rc = ap_run_pre_connection(*origin, p_conn->sock); - if (rc != OK && rc != DONE) { - (*origin)->aborted = 1; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: HTTP: pre_connection setup failed (%d)", - rc); - return rc; - } - } - return OK; -} - -static void add_te_chunked(apr_pool_t *p, - apr_bucket_alloc_t *bucket_alloc, - apr_bucket_brigade *header_brigade) -{ - apr_bucket *e; - char *buf; - const char te_hdr[] = "Transfer-Encoding: chunked" CRLF; - - buf = apr_pmemdup(p, te_hdr, sizeof(te_hdr)-1); - ap_xlate_proto_to_ascii(buf, sizeof(te_hdr)-1); - - e = apr_bucket_pool_create(buf, sizeof(te_hdr)-1, p, bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); -} - -static void add_cl(apr_pool_t *p, - apr_bucket_alloc_t *bucket_alloc, - apr_bucket_brigade *header_brigade, - const char *cl_val) -{ - apr_bucket *e; - char *buf; - - buf = apr_pstrcat(p, "Content-Length: ", - cl_val, - CRLF, - NULL); - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); -} - -#define ASCII_CRLF "\015\012" -#define ASCII_ZERO "\060" - -static void terminate_headers(apr_bucket_alloc_t *bucket_alloc, - apr_bucket_brigade *header_brigade) -{ - apr_bucket *e; - - /* add empty line at the end of the headers */ - e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); -} - -static apr_status_t pass_brigade(apr_bucket_alloc_t *bucket_alloc, - request_rec *r, proxy_http_conn_t *p_conn, - conn_rec *origin, apr_bucket_brigade *bb, - int flush) -{ - apr_status_t status; - - if (flush) { - apr_bucket *e = apr_bucket_flush_create(bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - status = ap_pass_brigade(origin->output_filters, bb); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: pass request body failed to %pI (%s)", - p_conn->addr, p_conn->name); - return status; - } - apr_brigade_cleanup(bb); - return APR_SUCCESS; -} - -static apr_status_t stream_reqbody_chunked(apr_pool_t *p, - request_rec *r, - proxy_http_conn_t *p_conn, - conn_rec *origin, - apr_bucket_brigade *header_brigade, - apr_bucket_brigade *input_brigade) -{ - int seen_eos = 0; - apr_size_t hdr_len; - apr_off_t bytes; - apr_status_t status; - apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; - apr_bucket_brigade *bb; - apr_bucket *e; - - add_te_chunked(p, bucket_alloc, header_brigade); - terminate_headers(bucket_alloc, header_brigade); - - while (!APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) - { - char chunk_hdr[20]; /* must be here due to transient bucket. */ - - /* If this brigade contains EOS, either stop or remove it. */ - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { - seen_eos = 1; - - /* We can't pass this EOS to the output_filters. */ - e = APR_BRIGADE_LAST(input_brigade); - apr_bucket_delete(e); - } - - apr_brigade_length(input_brigade, 1, &bytes); - - hdr_len = apr_snprintf(chunk_hdr, sizeof(chunk_hdr), - "%" APR_UINT64_T_HEX_FMT CRLF, - (apr_uint64_t)bytes); - - ap_xlate_proto_to_ascii(chunk_hdr, hdr_len); - e = apr_bucket_transient_create(chunk_hdr, hdr_len, - bucket_alloc); - APR_BRIGADE_INSERT_HEAD(input_brigade, e); - - /* - * Append the end-of-chunk CRLF - */ - e = apr_bucket_immortal_create(ASCII_CRLF, 2, bucket_alloc); - APR_BRIGADE_INSERT_TAIL(input_brigade, e); - - if (header_brigade) { - /* we never sent the header brigade, so go ahead and - * take care of that now - */ - bb = header_brigade; - - /* - * Save input_brigade in bb brigade. (At least) in the SSL case - * input_brigade contains transient buckets whose data would get - * overwritten during the next call of ap_get_brigade in the loop. - * ap_save_brigade ensures these buckets to be set aside. - * Calling ap_save_brigade with NULL as filter is OK, because - * bb brigade already has been created and does not need to get - * created by ap_save_brigade. - */ - status = ap_save_brigade(NULL, &bb, &input_brigade, p); - if (status != APR_SUCCESS) { - return status; - } - - header_brigade = NULL; - } - else { - bb = input_brigade; - } - - /* The request is flushed below this loop with chunk EOS header */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 0); - if (status != APR_SUCCESS) { - return status; - } - - if (seen_eos) { - break; - } - - status = ap_get_brigade(r->input_filters, input_brigade, - AP_MODE_READBYTES, APR_BLOCK_READ, - HUGE_STRING_LEN); - - if (status != APR_SUCCESS) { - return status; - } - } - - if (header_brigade) { - /* we never sent the header brigade because there was no request body; - * send it now - */ - bb = header_brigade; - } - else { - if (!APR_BRIGADE_EMPTY(input_brigade)) { - /* input brigade still has an EOS which we can't pass to the output_filters. */ - e = APR_BRIGADE_LAST(input_brigade); - AP_DEBUG_ASSERT(APR_BUCKET_IS_EOS(e)); - apr_bucket_delete(e); - } - bb = input_brigade; - } - - e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF - /* <trailers> */ - ASCII_CRLF, - 5, bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - - /* Now we have headers-only, or the chunk EOS mark; flush it */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 1); - return status; -} - -static apr_status_t stream_reqbody_cl(apr_pool_t *p, - request_rec *r, - proxy_http_conn_t *p_conn, - conn_rec *origin, - apr_bucket_brigade *header_brigade, - apr_bucket_brigade *input_brigade, - const char *old_cl_val) -{ - int seen_eos = 0; - apr_status_t status = APR_SUCCESS; - apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; - apr_bucket_brigade *bb; - apr_bucket *e; - apr_off_t cl_val = 0; - apr_off_t bytes; - apr_off_t bytes_streamed = 0; - - if (old_cl_val) { - add_cl(p, bucket_alloc, header_brigade, old_cl_val); - cl_val = atol(old_cl_val); - } - terminate_headers(bucket_alloc, header_brigade); - - while (!APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) - { - apr_brigade_length(input_brigade, 1, &bytes); - bytes_streamed += bytes; - - /* If this brigade contains EOS, either stop or remove it. */ - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { - seen_eos = 1; - - /* We can't pass this EOS to the output_filters. */ - e = APR_BRIGADE_LAST(input_brigade); - apr_bucket_delete(e); - } - - /* C-L < bytes streamed?!? - * We will error out after the body is completely - * consumed, but we can't stream more bytes at the - * back end since they would in part be interpreted - * as another request! If nothing is sent, then - * just send nothing. - * - * Prevents HTTP Response Splitting. - */ - if (bytes_streamed > cl_val) - continue; - - if (header_brigade) { - /* we never sent the header brigade, so go ahead and - * take care of that now - */ - bb = header_brigade; - - /* - * Save input_brigade in bb brigade. (At least) in the SSL case - * input_brigade contains transient buckets whose data would get - * overwritten during the next call of ap_get_brigade in the loop. - * ap_save_brigade ensures these buckets to be set aside. - * Calling ap_save_brigade with NULL as filter is OK, because - * bb brigade already has been created and does not need to get - * created by ap_save_brigade. - */ - status = ap_save_brigade(NULL, &bb, &input_brigade, p); - if (status != APR_SUCCESS) { - return status; - } - - header_brigade = NULL; - } - else { - bb = input_brigade; - } - - /* Once we hit EOS, we are ready to flush. */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, seen_eos); - if (status != APR_SUCCESS) { - return status; - } - - if (seen_eos) { - break; - } - - status = ap_get_brigade(r->input_filters, input_brigade, - AP_MODE_READBYTES, APR_BLOCK_READ, - HUGE_STRING_LEN); - - if (status != APR_SUCCESS) { - return status; - } - } - - if (bytes_streamed != cl_val) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "proxy: client %s given Content-Length did not match" - " number of body bytes read", r->connection->remote_ip); - return APR_EOF; - } - - if (header_brigade) { - /* we never sent the header brigade since there was no request - * body; send it now with the flush flag - */ - bb = header_brigade; - status = pass_brigade(bucket_alloc, r, p_conn, origin, bb, 1); - } - return status; -} - -#define MAX_MEM_SPOOL 16384 - -static apr_status_t spool_reqbody_cl(apr_pool_t *p, - request_rec *r, - proxy_http_conn_t *p_conn, - conn_rec *origin, - apr_bucket_brigade *header_brigade, - apr_bucket_brigade *input_brigade, - int force_cl) -{ - int seen_eos = 0; - apr_status_t status; - apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; - apr_bucket_brigade *body_brigade; - apr_bucket *e; - apr_off_t bytes, bytes_spooled = 0, fsize = 0; - apr_file_t *tmpfile = NULL; - - body_brigade = apr_brigade_create(p, bucket_alloc); - - while (!APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(input_brigade))) - { - /* If this brigade contains EOS, either stop or remove it. */ - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { - seen_eos = 1; - - /* We can't pass this EOS to the output_filters. */ - e = APR_BRIGADE_LAST(input_brigade); - apr_bucket_delete(e); - } - - apr_brigade_length(input_brigade, 1, &bytes); - - if (bytes_spooled + bytes > MAX_MEM_SPOOL) { - /* can't spool any more in memory; write latest brigade to disk */ - if (tmpfile == NULL) { - const char *temp_dir; - char *template; - - status = apr_temp_dir_get(&temp_dir, p); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: search for temporary directory failed"); - return status; - } - apr_filepath_merge(&template, temp_dir, - "modproxy.tmp.XXXXXX", - APR_FILEPATH_NATIVE, p); - status = apr_file_mktemp(&tmpfile, template, 0, p); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: creation of temporary file in directory %s failed", - temp_dir); - return status; - } - } - for (e = APR_BRIGADE_FIRST(input_brigade); - e != APR_BRIGADE_SENTINEL(input_brigade); - e = APR_BUCKET_NEXT(e)) { - const char *data; - apr_size_t bytes_read, bytes_written; - - apr_bucket_read(e, &data, &bytes_read, APR_BLOCK_READ); - status = apr_file_write_full(tmpfile, data, bytes_read, &bytes_written); - if (status != APR_SUCCESS) { - const char *tmpfile_name; - - if (apr_file_name_get(&tmpfile_name, tmpfile) != APR_SUCCESS) { - tmpfile_name = "(unknown)"; - } - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: write to temporary file %s failed", - tmpfile_name); - return status; - } - AP_DEBUG_ASSERT(bytes_read == bytes_written); - fsize += bytes_written; - } - apr_brigade_cleanup(input_brigade); - } - else { - - /* - * Save input_brigade in body_brigade. (At least) in the SSL case - * input_brigade contains transient buckets whose data would get - * overwritten during the next call of ap_get_brigade in the loop. - * ap_save_brigade ensures these buckets to be set aside. - * Calling ap_save_brigade with NULL as filter is OK, because - * body_brigade already has been created and does not need to get - * created by ap_save_brigade. - */ - status = ap_save_brigade(NULL, &body_brigade, &input_brigade, p); - if (status != APR_SUCCESS) { - return status; - } - - } - - bytes_spooled += bytes; - - if (seen_eos) { - break; - } - - status = ap_get_brigade(r->input_filters, input_brigade, - AP_MODE_READBYTES, APR_BLOCK_READ, - HUGE_STRING_LEN); - - if (status != APR_SUCCESS) { - return status; - } - } - - if (bytes_spooled || force_cl) { - add_cl(p, bucket_alloc, header_brigade, apr_off_t_toa(p, bytes_spooled)); - } - terminate_headers(bucket_alloc, header_brigade); - APR_BRIGADE_CONCAT(header_brigade, body_brigade); - if (tmpfile) { - /* For platforms where the size of the file may be larger than - * that which can be stored in a single bucket (where the - * length field is an apr_size_t), split it into several - * buckets: */ - if (sizeof(apr_off_t) > sizeof(apr_size_t) - && fsize > AP_MAX_SENDFILE) { - e = apr_bucket_file_create(tmpfile, 0, AP_MAX_SENDFILE, p, - bucket_alloc); - while (fsize > AP_MAX_SENDFILE) { - apr_bucket *ce; - apr_bucket_copy(e, &ce); - APR_BRIGADE_INSERT_TAIL(header_brigade, ce); - e->start += AP_MAX_SENDFILE; - fsize -= AP_MAX_SENDFILE; - } - e->length = (apr_size_t)fsize; /* Resize just the last bucket */ - } - else { - e = apr_bucket_file_create(tmpfile, 0, (apr_size_t)fsize, p, - bucket_alloc); - } - APR_BRIGADE_INSERT_TAIL(header_brigade, e); - } - /* This is all a single brigade, pass with flush flagged */ - status = pass_brigade(bucket_alloc, r, p_conn, origin, header_brigade, 1); - return status; -} - -static -apr_status_t ap_proxy_http_request(apr_pool_t *p, request_rec *r, - proxy_http_conn_t *p_conn, conn_rec *origin, - proxy_server_conf *conf, - apr_uri_t *uri, - char *url, - apr_bucket_brigade *header_brigade, - char *server_portstr) -{ - conn_rec *c = r->connection; - apr_bucket_alloc_t *bucket_alloc = c->bucket_alloc; - apr_bucket_brigade *input_brigade; - apr_bucket_brigade *temp_brigade; - apr_bucket *e; - char *buf; - const apr_array_header_t *headers_in_array; - const apr_table_entry_t *headers_in; - int counter; - apr_status_t status; - enum rb_methods {RB_INIT, RB_STREAM_CL, RB_STREAM_CHUNKED, RB_SPOOL_CL}; - enum rb_methods rb_method = RB_INIT; - const char *old_cl_val = NULL; - const char *old_te_val = NULL; - apr_off_t bytes_read = 0; - apr_off_t bytes; - int force10; - - /* - * Send the HTTP/1.1 request to the remote server - */ - - /* strip connection listed hop-by-hop headers from the request */ - /* even though in theory a connection: close coming from the client - * should not affect the connection to the server, it's unlikely - * that subsequent client requests will hit this thread/process, - * so we cancel server keepalive if the client does. - */ - if (ap_proxy_liststr(apr_table_get(r->headers_in, - "Connection"), "close")) { - p_conn->close++; - /* XXX: we are abusing r->headers_in rather than a copy, - * give the core output handler a clue the client would - * rather just close. - */ - c->keepalive = AP_CONN_CLOSE; - } - ap_proxy_clear_connection(p, r->headers_in); - - if (apr_table_get(r->subprocess_env, "force-proxy-request-1.0")) { - buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.0" CRLF, NULL); - force10 = 1; - p_conn->close++; - } else { - buf = apr_pstrcat(p, r->method, " ", url, " HTTP/1.1" CRLF, NULL); - force10 = 0; - } - if (apr_table_get(r->subprocess_env, "proxy-nokeepalive")) { - origin->keepalive = AP_CONN_CLOSE; - p_conn->close++; - } - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); - if (conf->preserve_host == 0) { - if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) { - buf = apr_pstrcat(p, "Host: ", uri->hostname, ":", uri->port_str, - CRLF, NULL); - } else { - buf = apr_pstrcat(p, "Host: ", uri->hostname, CRLF, NULL); - } - } - else { - /* don't want to use r->hostname, as the incoming header might have a - * port attached - */ - const char* hostname = apr_table_get(r->headers_in,"Host"); - if (!hostname) { - hostname = r->server->server_hostname; - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "proxy: no HTTP 0.9 request (with no host line) " - "on incoming request and preserve host set " - "forcing hostname to be %s for uri %s", - hostname, - r->uri ); - } - buf = apr_pstrcat(p, "Host: ", hostname, CRLF, NULL); - } - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); - - /* handle Via */ - if (conf->viaopt == via_block) { - /* Block all outgoing Via: headers */ - apr_table_unset(r->headers_in, "Via"); - } else if (conf->viaopt != via_off) { - const char *server_name = ap_get_server_name(r); - /* If USE_CANONICAL_NAME_OFF was configured for the proxy virtual host, - * then the server name returned by ap_get_server_name() is the - * origin server name (which does make too much sense with Via: headers) - * so we use the proxy vhost's name instead. - */ - if (server_name == r->hostname) - server_name = r->server->server_hostname; - /* Create a "Via:" request header entry and merge it */ - /* Generate outgoing Via: header with/without server comment: */ - apr_table_mergen(r->headers_in, "Via", - (conf->viaopt == via_full) - ? apr_psprintf(p, "%d.%d %s%s (%s)", - HTTP_VERSION_MAJOR(r->proto_num), - HTTP_VERSION_MINOR(r->proto_num), - server_name, server_portstr, - AP_SERVER_BASEVERSION) - : apr_psprintf(p, "%d.%d %s%s", - HTTP_VERSION_MAJOR(r->proto_num), - HTTP_VERSION_MINOR(r->proto_num), - server_name, server_portstr) - ); - } - - /* X-Forwarded-*: handling - * - * XXX Privacy Note: - * ----------------- - * - * These request headers are only really useful when the mod_proxy - * is used in a reverse proxy configuration, so that useful info - * about the client can be passed through the reverse proxy and on - * to the backend server, which may require the information to - * function properly. - * - * In a forward proxy situation, these options are a potential - * privacy violation, as information about clients behind the proxy - * are revealed to arbitrary servers out there on the internet. - * - * The HTTP/1.1 Via: header is designed for passing client - * information through proxies to a server, and should be used in - * a forward proxy configuation instead of X-Forwarded-*. See the - * ProxyVia option for details. - */ - - if (PROXYREQ_REVERSE == r->proxyreq) { - const char *buf; - - /* Add X-Forwarded-For: so that the upstream has a chance to - * determine, where the original request came from. - */ - apr_table_mergen(r->headers_in, "X-Forwarded-For", - r->connection->remote_ip); - - /* Add X-Forwarded-Host: so that upstream knows what the - * original request hostname was. - */ - if ((buf = apr_table_get(r->headers_in, "Host"))) { - apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf); - } - - /* Add X-Forwarded-Server: so that upstream knows what the - * name of this proxy server is (if there are more than one) - * XXX: This duplicates Via: - do we strictly need it? - */ - apr_table_mergen(r->headers_in, "X-Forwarded-Server", - r->server->server_hostname); - } - - /* send request headers */ - proxy_run_fixups(r); - headers_in_array = apr_table_elts(r->headers_in); - headers_in = (const apr_table_entry_t *) headers_in_array->elts; - for (counter = 0; counter < headers_in_array->nelts; counter++) { - if (headers_in[counter].key == NULL - || headers_in[counter].val == NULL - - /* Already sent */ - || !strcasecmp(headers_in[counter].key, "Host") - - /* Clear out hop-by-hop request headers not to send - * RFC2616 13.5.1 says we should strip these headers - */ - || !strcasecmp(headers_in[counter].key, "Keep-Alive") - || !strcasecmp(headers_in[counter].key, "TE") - || !strcasecmp(headers_in[counter].key, "Trailer") - || !strcasecmp(headers_in[counter].key, "Upgrade") - - /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be - * suppressed if THIS server requested the authentication, - * not when a frontend proxy requested it! - * - * The solution to this problem is probably to strip out - * the Proxy-Authorisation header in the authorisation - * code itself, not here. This saves us having to signal - * somehow whether this request was authenticated or not. - */ - || !strcasecmp(headers_in[counter].key,"Proxy-Authorization") - || !strcasecmp(headers_in[counter].key,"Proxy-Authenticate")) { - continue; - } - - /* Skip Transfer-Encoding and Content-Length for now. - */ - if (!strcasecmp(headers_in[counter].key, "Transfer-Encoding")) { - old_te_val = headers_in[counter].val; - continue; - } - if (!strcasecmp(headers_in[counter].key, "Content-Length")) { - old_cl_val = headers_in[counter].val; - continue; - } - - /* for sub-requests, ignore freshness/expiry headers */ - if (r->main) { - if ( !strcasecmp(headers_in[counter].key, "If-Match") - || !strcasecmp(headers_in[counter].key, "If-Modified-Since") - || !strcasecmp(headers_in[counter].key, "If-Range") - || !strcasecmp(headers_in[counter].key, "If-Unmodified-Since") - || !strcasecmp(headers_in[counter].key, "If-None-Match")) { - continue; - } - } - - buf = apr_pstrcat(p, headers_in[counter].key, ": ", - headers_in[counter].val, CRLF, - NULL); - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); - } - - /* We have headers, let's figure out our request body... */ - input_brigade = apr_brigade_create(p, bucket_alloc); - - /* sub-requests never use keepalives, and mustn't pass request bodies. - * Because the new logic looks at input_brigade, we will self-terminate - * input_brigade and jump past all of the request body logic... - * Reading anything with ap_get_brigade is likely to consume the - * main request's body or read beyond EOS - which would be unplesant. - */ - if (r->main) { - p_conn->close++; - if (old_cl_val) { - old_cl_val = NULL; - apr_table_unset(r->headers_in, "Content-Length"); - } - if (old_te_val) { - old_te_val = NULL; - apr_table_unset(r->headers_in, "Transfer-Encoding"); - } - rb_method = RB_STREAM_CL; - e = apr_bucket_eos_create(input_brigade->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(input_brigade, e); - goto skip_body; - } - - /* WE only understand chunked. Other modules might inject - * (and therefore, decode) other flavors but we don't know - * that the can and have done so unless they they remove - * their decoding from the headers_in T-E list. - * XXX: Make this extensible, but in doing so, presume the - * encoding has been done by the extensions' handler, and - * do not modify add_te_chunked's logic - */ - if (old_te_val && strcmp(old_te_val, "chunked") != 0) { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, - "proxy: %s Transfer-Encoding is not supported", - old_te_val); - return APR_EINVAL; - } - - if (old_cl_val && old_te_val) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_ENOTIMPL, r->server, - "proxy: client %s (%s) requested Transfer-Encoding body" - " with Content-Length (C-L ignored)", - c->remote_ip, c->remote_host ? c->remote_host: ""); - apr_table_unset(r->headers_in, "Content-Length"); - old_cl_val = NULL; - origin->keepalive = AP_CONN_CLOSE; - p_conn->close++; - } - - /* Prefetch MAX_MEM_SPOOL bytes - * - * This helps us avoid any election of C-L v.s. T-E - * request bodies, since we are willing to keep in - * memory this much data, in any case. This gives - * us an instant C-L election if the body is of some - * reasonable size. - */ - temp_brigade = apr_brigade_create(p, bucket_alloc); - do { - status = ap_get_brigade(r->input_filters, temp_brigade, - AP_MODE_READBYTES, APR_BLOCK_READ, - MAX_MEM_SPOOL - bytes_read); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: prefetch request body failed to %s" - " from %s (%s)", - p_conn->name ? p_conn->name: "", - c->remote_ip, c->remote_host ? c->remote_host: ""); - return status; - } - - apr_brigade_length(temp_brigade, 1, &bytes); - bytes_read += bytes; - - /* - * Save temp_brigade in input_brigade. (At least) in the SSL case - * temp_brigade contains transient buckets whose data would get - * overwritten during the next call of ap_get_brigade in the loop. - * ap_save_brigade ensures these buckets to be set aside. - * Calling ap_save_brigade with NULL as filter is OK, because - * input_brigade already has been created and does not need to get - * created by ap_save_brigade. - */ - status = ap_save_brigade(NULL, &input_brigade, &temp_brigade, p); - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: processing prefetched request body failed" - " to %s from %s (%s)", - p_conn->name ? p_conn->name: "", - c->remote_ip, c->remote_host ? c->remote_host: ""); - return status; - } - - /* Ensure we don't hit a wall where we have a buffer too small - * for ap_get_brigade's filters to fetch us another bucket, - * surrender once we hit 80 bytes less than MAX_MEM_SPOOL - * (an arbitrary value.) - */ - } while ((bytes_read < MAX_MEM_SPOOL - 80) - && !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))); - - /* Use chunked request body encoding or send a content-length body? - * - * Prefer C-L when: - * - * We have no request body (handled by RB_STREAM_CL) - * - * We have a request body length <= MAX_MEM_SPOOL - * - * The administrator has setenv force-proxy-request-1.0 - * - * The client sent a C-L body, and the administrator has - * not setenv proxy-sendchunked or has set setenv proxy-sendcl - * - * The client sent a T-E body, and the administrator has - * setenv proxy-sendcl, and not setenv proxy-sendchunked - * - * If both proxy-sendcl and proxy-sendchunked are set, the - * behavior is the same as if neither were set, large bodies - * that can't be read will be forwarded in their original - * form of C-L, or T-E. - * - * To ensure maximum compatibility, setenv proxy-sendcl - * To reduce server resource use, setenv proxy-sendchunked - * - * Then address specific servers with conditional setenv - * options to restore the default behavior where desireable. - * - * We have to compute content length by reading the entire request - * body; if request body is not small, we'll spool the remaining - * input to a temporary file. Chunked is always preferable. - * - * We can only trust the client-provided C-L if the T-E header - * is absent, and the filters are unchanged (the body won't - * be resized by another content filter). - */ - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { - /* The whole thing fit, so our decision is trivial, use - * the filtered bytes read from the client for the request - * body Content-Length. - * - * If we expected no body, and read no body, do not set - * the Content-Length. - */ - if (old_cl_val || old_te_val || bytes_read) { - old_cl_val = apr_off_t_toa(r->pool, bytes_read); - } - rb_method = RB_STREAM_CL; - } - else if (old_te_val) { - if (force10 - || (apr_table_get(r->subprocess_env, "proxy-sendcl") - && !apr_table_get(r->subprocess_env, "proxy-sendchunks") - && !apr_table_get(r->subprocess_env, "proxy-sendchunked"))) { - rb_method = RB_SPOOL_CL; - } - else { - rb_method = RB_STREAM_CHUNKED; - } - } - else if (old_cl_val) { - if (r->input_filters == r->proto_input_filters) { - rb_method = RB_STREAM_CL; - } - else if (!force10 - && (apr_table_get(r->subprocess_env, "proxy-sendchunks") - || apr_table_get(r->subprocess_env, "proxy-sendchunked")) - && !apr_table_get(r->subprocess_env, "proxy-sendcl")) { - rb_method = RB_STREAM_CHUNKED; - } - else { - rb_method = RB_SPOOL_CL; - } - } - else { - /* This is an appropriate default; very efficient for no-body - * requests, and has the behavior that it will not add any C-L - * when the old_cl_val is NULL. - */ - rb_method = RB_SPOOL_CL; - } - -/* Yes I hate gotos. This is the subrequest shortcut */ -skip_body: - /* Handle Connection: header */ - if (!force10 && p_conn->close) { - buf = apr_pstrdup(p, "Connection: close" CRLF); - ap_xlate_proto_to_ascii(buf, strlen(buf)); - e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(header_brigade, e); - } - - /* send the request body, if any. */ - switch(rb_method) { - case RB_STREAM_CHUNKED: - status = stream_reqbody_chunked(p, r, p_conn, origin, header_brigade, - input_brigade); - break; - case RB_STREAM_CL: - status = stream_reqbody_cl(p, r, p_conn, origin, header_brigade, - input_brigade, old_cl_val); - break; - case RB_SPOOL_CL: - status = spool_reqbody_cl(p, r, p_conn, origin, header_brigade, - input_brigade, (old_cl_val != NULL) - || (old_te_val != NULL) - || (bytes_read > 0)); - break; - default: - ap_assert(1 != 1); - break; - } - - if (status != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, - "proxy: pass request body failed to %pI (%s)" - " from %s (%s)", - p_conn->addr, p_conn->name ? p_conn->name: "", - c->remote_ip, c->remote_host ? c->remote_host: ""); - return status; - } - - return APR_SUCCESS; -} - -static int addit_dammit(void *v, const char *key, const char *val) -{ - apr_table_addn(v, key, val); - return 1; -} - -/* - * Limit the number of interim respones we sent back to the client. Otherwise - * we suffer from a memory build up. Besides there is NO sense in sending back - * an unlimited number of interim responses to the client. Thus if we cross - * this limit send back a 502 (Bad Gateway). - */ -#ifndef AP_MAX_INTERIM_RESPONSES -#define AP_MAX_INTERIM_RESPONSES 10 -#endif - -static -apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, - proxy_http_conn_t *p_conn, - conn_rec *origin, - proxy_conn_rec *backend, - proxy_server_conf *conf, - apr_bucket_brigade *bb, - char *server_portstr) { - conn_rec *c = r->connection; - char buffer[HUGE_STRING_LEN]; - const char *buf; - char keepchar; - request_rec *rp; - apr_bucket *e; - apr_table_t *save_table; - int len, backasswards; - int received_continue = 1; /* flag to indicate if we should - * loop over response parsing logic - * in the case that the origin told us - * to HTTP_CONTINUE - */ - - /* Get response from the remote server, and pass it up the - * filter chain - */ - - rp = ap_proxy_make_fake_req(origin, r); - /* In case anyone needs to know, this is a fake request that is really a - * response. - */ - rp->proxyreq = PROXYREQ_RESPONSE; - - while (received_continue && (received_continue <= AP_MAX_INTERIM_RESPONSES)) { - apr_brigade_cleanup(bb); - - len = ap_getline(buffer, sizeof(buffer), rp, 0); - if (len == 0) { - /* handle one potential stray CRLF */ - len = ap_getline(buffer, sizeof(buffer), rp, 0); - } - if (len <= 0) { - apr_socket_close(p_conn->sock); - backend->connection = NULL; - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: error reading status line from remote " - "server %s", p_conn->name); - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - "Error reading from remote server"); - } - - /* Is it an HTTP/1 response? - * This is buggy if we ever see an HTTP/1.10 - */ - if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) { - int major, minor; - - if (2 != sscanf(buffer, "HTTP/%u.%u", &major, &minor)) { - major = 1; - minor = 1; - } - /* If not an HTTP/1 message or - * if the status line was > 8192 bytes - */ - else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) { - apr_socket_close(p_conn->sock); - backend->connection = NULL; - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - apr_pstrcat(p, "Corrupt status line returned by remote " - "server: ", buffer, NULL)); - } - backasswards = 0; - - keepchar = buffer[12]; - buffer[12] = '\0'; - r->status = atoi(&buffer[9]); - - if (keepchar != '\0') { - buffer[12] = keepchar; - } else { - /* 2616 requires the space in Status-Line; the origin - * server may have sent one but ap_rgetline_core will - * have stripped it. */ - buffer[12] = ' '; - buffer[13] = '\0'; - } - r->status_line = apr_pstrdup(p, &buffer[9]); - - /* read the headers. */ - /* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers*/ - /* Also, take care with headers with multiple occurences. */ - - /* First, tuck away all already existing cookies */ - save_table = apr_table_make(r->pool, 2); - apr_table_do(addit_dammit, save_table, r->headers_out, - "Set-Cookie", NULL); - - r->headers_out = ap_proxy_read_headers(r, rp, buffer, - sizeof(buffer), origin); - if (r->headers_out == NULL) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, - r->server, "proxy: bad HTTP/%d.%d header " - "returned by %s (%s)", major, minor, r->uri, - r->method); - p_conn->close += 1; - /* - * ap_send_error relies on a headers_out to be present. we - * are in a bad position here.. so force everything we send out - * to have nothing to do with the incoming packet - */ - r->headers_out = apr_table_make(r->pool,1); - r->status = HTTP_BAD_GATEWAY; - r->status_line = "bad gateway"; - return r->status; - } - - /* Now, add in the just read cookies */ - apr_table_do(addit_dammit, save_table, r->headers_out, - "Set-Cookie", NULL); - - /* and now load 'em all in */ - if (!apr_is_empty_table(save_table)) { - apr_table_unset(r->headers_out, "Set-Cookie"); - r->headers_out = apr_table_overlay(r->pool, - r->headers_out, - save_table); - } - - /* can't have both Content-Length and Transfer-Encoding */ - if (apr_table_get(r->headers_out, "Transfer-Encoding") - && apr_table_get(r->headers_out, "Content-Length")) { - /* 2616 section 4.4, point 3: "if both Transfer-Encoding - * and Content-Length are received, the latter MUST be - * ignored"; so unset it here to prevent any confusion - * later. */ - apr_table_unset(r->headers_out, "Content-Length"); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, - r->server, - "proxy: server %s returned Transfer-Encoding and Content-Length", - p_conn->name); - p_conn->close += 1; - } - - /* strip connection listed hop-by-hop headers from response */ - p_conn->close += ap_proxy_liststr(apr_table_get(r->headers_out, - "Connection"), - "close"); - ap_proxy_clear_connection(p, r->headers_out); - if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { - ap_set_content_type(r, apr_pstrdup(p, buf)); - } - if (!ap_is_HTTP_INFO(r->status)) { - ap_proxy_pre_http_request(origin, rp); - } - - /* handle Via header in response */ - if (conf->viaopt != via_off && conf->viaopt != via_block) { - const char *server_name = ap_get_server_name(r); - /* If USE_CANONICAL_NAME_OFF was configured for the proxy virtual host, - * then the server name returned by ap_get_server_name() is the - * origin server name (which does make too much sense with Via: headers) - * so we use the proxy vhost's name instead. - */ - if (server_name == r->hostname) - server_name = r->server->server_hostname; - - /* create a "Via:" response header entry and merge it */ - apr_table_mergen(r->headers_out, "Via", - (conf->viaopt == via_full) - ? apr_psprintf(p, "%d.%d %s%s (%s)", - HTTP_VERSION_MAJOR(r->proto_num), - HTTP_VERSION_MINOR(r->proto_num), - server_name, - server_portstr, - AP_SERVER_BASEVERSION) - : apr_psprintf(p, "%d.%d %s%s", - HTTP_VERSION_MAJOR(r->proto_num), - HTTP_VERSION_MINOR(r->proto_num), - server_name, - server_portstr) - ); - } - - /* cancel keepalive if HTTP/1.0 or less */ - if ((major < 1) || (minor < 1)) { - p_conn->close += 1; - origin->keepalive = AP_CONN_CLOSE; - } - } else { - /* an http/0.9 response */ - backasswards = 1; - r->status = 200; - r->status_line = "200 OK"; - p_conn->close += 1; - } - - if ( r->status != HTTP_CONTINUE ) { - received_continue = 0; - } else { - received_continue++; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, - "proxy: HTTP: received 100 CONTINUE"); - } - - /* we must accept 3 kinds of date, but generate only 1 kind of date */ - if ((buf = apr_table_get(r->headers_out, "Date")) != NULL) { - apr_table_set(r->headers_out, "Date", - ap_proxy_date_canon(p, buf)); - } - if ((buf = apr_table_get(r->headers_out, "Expires")) != NULL) { - apr_table_set(r->headers_out, "Expires", - ap_proxy_date_canon(p, buf)); - } - if ((buf = apr_table_get(r->headers_out, "Last-Modified")) != NULL) { - apr_table_set(r->headers_out, "Last-Modified", - ap_proxy_date_canon(p, buf)); - } - - /* munge the Location and URI response headers according to - * ProxyPassReverse - */ - if ((buf = apr_table_get(r->headers_out, "Location")) != NULL) { - apr_table_set(r->headers_out, "Location", - ap_proxy_location_reverse_map(r, conf, buf)); - } - if ((buf = apr_table_get(r->headers_out, "Content-Location")) != NULL) { - apr_table_set(r->headers_out, "Content-Location", - ap_proxy_location_reverse_map(r, conf, buf)); - } - if ((buf = apr_table_get(r->headers_out, "URI")) != NULL) { - apr_table_set(r->headers_out, "URI", - ap_proxy_location_reverse_map(r, conf, buf)); - } - - if ((r->status == 401) && (conf->error_override != 0)) { - const char *wa = "WWW-Authenticate"; - if ((buf = apr_table_get(r->headers_out, wa))) { - apr_table_set(r->err_headers_out, wa, buf); - } else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: origin server sent 401 without WWW-Authenticate header"); - } - } - - r->sent_bodyct = 1; - /* Is it an HTTP/0.9 response? If so, send the extra data */ - if (backasswards) { - apr_ssize_t cntr = len; - e = apr_bucket_heap_create(buffer, cntr, NULL, c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - - /* send body - but only if a body is expected */ - if ((!r->header_only) && /* not HEAD request */ - (r->status > 199) && /* not any 1xx response */ - (r->status != HTTP_NO_CONTENT) && /* not 204 */ - (r->status != HTTP_RESET_CONTENT) && /* not 205 */ - (r->status != HTTP_NOT_MODIFIED)) { /* not 304 */ - - /* We need to copy the output headers and treat them as input - * headers as well. BUT, we need to do this before we remove - * TE, so that they are preserved accordingly for - * ap_http_filter to know where to end. - */ - rp->headers_in = apr_table_copy(r->pool, r->headers_out); - - apr_table_unset(r->headers_out,"Transfer-Encoding"); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: start body send"); - - /* - * if we are overriding the errors, we can't put the content - * of the page into the brigade - */ - if ( (conf->error_override ==0) || r->status < 400 ) { - - /* read the body, pass it to the output filters */ - int finish = FALSE; - while (ap_get_brigade(rp->input_filters, - bb, - AP_MODE_READBYTES, - APR_BLOCK_READ, - conf->io_buffer_size) == APR_SUCCESS) { -#if DEBUGGING - { - apr_off_t readbytes; - apr_brigade_length(bb, 0, &readbytes); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, - r->server, "proxy (PID %d): readbytes: %#x", - getpid(), readbytes); - } -#endif - /* sanity check */ - if (APR_BRIGADE_EMPTY(bb)) { - apr_brigade_cleanup(bb); - break; - } - - /* found the last brigade? */ - if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { - /* if this is the last brigade, cleanup the - * backend connection first to prevent the - * backend server from hanging around waiting - * for a slow client to eat these bytes - */ - ap_proxy_http_cleanup(r, p_conn, backend); - /* signal that we must leave */ - finish = TRUE; - } - - /* try send what we read */ - if (ap_pass_brigade(r->output_filters, bb) != APR_SUCCESS - || c->aborted) { - /* Ack! Phbtt! Die! User aborted! */ - p_conn->close = 1; /* this causes socket close below */ - finish = TRUE; - } - - /* make sure we always clean up after ourselves */ - apr_brigade_cleanup(bb); - - /* if we are done, leave */ - if (TRUE == finish) { - break; - } - } - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: end body send"); - } else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: header only"); - } - } - - /* See define of AP_MAX_INTERIM_RESPONSES for why */ - if (received_continue > AP_MAX_INTERIM_RESPONSES) { - return ap_proxyerror(r, HTTP_BAD_GATEWAY, - apr_psprintf(p, - "Too many (%d) interim responses from origin server", - received_continue)); - } - - if ( conf->error_override ) { - /* the code above this checks for 'OK' which is what the hook expects */ - if ( r->status == HTTP_OK ) - return OK; - else { - /* clear r->status for override error, otherwise ErrorDocument - * thinks that this is a recursive error, and doesn't find the - * custom error page - */ - int status = r->status; - r->status = HTTP_OK; - /* Discard body, if one is expected */ - if ((status > 199) && /* not any 1xx response */ - (status != HTTP_NO_CONTENT) && /* not 204 */ - (status != HTTP_RESET_CONTENT) && /* not 205 */ - (status != HTTP_NOT_MODIFIED)) { /* not 304 */ - ap_discard_request_body(rp); - } - return status; - } - } else - return OK; -} - -static -apr_status_t ap_proxy_http_cleanup(request_rec *r, proxy_http_conn_t *p_conn, - proxy_conn_rec *backend) { - /* If there are no KeepAlives, or if the connection has been signalled - * to close, close the socket and clean up - */ - - /* if the connection is < HTTP/1.1, or Connection: close, - * we close the socket, otherwise we leave it open for KeepAlive support - */ - if (p_conn->close || (r->proto_num < HTTP_VERSION(1,1))) { - if (p_conn->sock) { - apr_socket_close(p_conn->sock); - p_conn->sock = NULL; - backend->connection = NULL; - } - } - return OK; -} - -/* - * This handles http:// URLs, and other URLs using a remote proxy over http - * If proxyhost is NULL, then contact the server directly, otherwise - * go via the proxy. - * Note that if a proxy is used, then URLs other than http: can be accessed, - * also, if we have trouble which is clearly specific to the proxy, then - * we return DECLINED so that we can try another proxy. (Or the direct - * route.) - */ -int ap_proxy_http_handler(request_rec *r, proxy_server_conf *conf, - char *url, const char *proxyname, - apr_port_t proxyport) -{ - int status; - char server_portstr[32]; - conn_rec *origin = NULL; - proxy_conn_rec *backend = NULL; - int is_ssl = 0; - - /* Note: Memory pool allocation. - * A downstream keepalive connection is always connected to the existence - * (or not) of an upstream keepalive connection. If this is not done then - * load balancing against multiple backend servers breaks (one backend - * server ends up taking 100% of the load), and the risk is run of - * downstream keepalive connections being kept open unnecessarily. This - * keeps webservers busy and ties up resources. - * - * As a result, we allocate all sockets out of the upstream connection - * pool, and when we want to reuse a socket, we check first whether the - * connection ID of the current upstream connection is the same as that - * of the connection when the socket was opened. - */ - apr_pool_t *p = r->connection->pool; - conn_rec *c = r->connection; - apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); - apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri)); - proxy_http_conn_t *p_conn = apr_pcalloc(r->connection->pool, - sizeof(*p_conn)); - - /* is it for us? */ - if (strncasecmp(url, "https:", 6) == 0) { - if (!ap_proxy_ssl_enable(NULL)) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: HTTPS: declining URL %s" - " (mod_ssl not configured?)", url); - return DECLINED; - } - is_ssl = 1; - } - else if (!(strncasecmp(url, "http:", 5)==0 || (strncasecmp(url, "ftp:", 4)==0 && proxyname))) { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: HTTP: declining URL %s", url); - return DECLINED; /* only interested in HTTP, or FTP via proxy */ - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: HTTP: serving URL %s", url); - - - /* only use stored info for top-level pages. Sub requests don't share - * in keepalives - */ - if (!r->main) { - backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, - &proxy_http_module); - } - /* create space for state information */ - if (!backend) { - backend = apr_pcalloc(c->pool, sizeof(proxy_conn_rec)); - backend->connection = NULL; - backend->hostname = NULL; - backend->port = 0; - if (!r->main) { - ap_set_module_config(c->conn_config, &proxy_http_module, backend); - } - } - - backend->is_ssl = is_ssl; - - /* Step One: Determine Who To Connect To */ - status = ap_proxy_http_determine_connection(p, r, p_conn, c, conf, uri, - &url, proxyname, proxyport, - server_portstr, - sizeof(server_portstr)); - if ( status != OK ) { - return status; - } - - /* Step Two: Make the Connection */ - status = ap_proxy_http_create_connection(p, r, p_conn, c, &origin, backend, - conf, proxyname); - if ( status != OK ) { - return status; - } - - /* Step Three: Send the Request */ - status = ap_proxy_http_request(p, r, p_conn, origin, conf, uri, url, bb, - server_portstr); - if ( status != OK ) { - return status; - } - - /* Step Four: Receive the Response */ - status = ap_proxy_http_process_response(p, r, p_conn, origin, backend, conf, - bb, server_portstr); - if ( status != OK ) { - /* clean up even if there is an error */ - ap_proxy_http_cleanup(r, p_conn, backend); - return status; - } - - /* Step Five: Clean Up */ - status = ap_proxy_http_cleanup(r, p_conn, backend); - if ( status != OK ) { - return status; - } - - return OK; -} - -static void ap_proxy_http_register_hook(apr_pool_t *p) -{ - proxy_hook_scheme_handler(ap_proxy_http_handler, NULL, NULL, APR_HOOK_FIRST); - proxy_hook_canon_handler(ap_proxy_http_canon, NULL, NULL, APR_HOOK_FIRST); -} - -module AP_MODULE_DECLARE_DATA proxy_http_module = { - STANDARD20_MODULE_STUFF, - NULL, /* create per-directory config structure */ - NULL, /* merge per-directory config structures */ - NULL, /* create per-server config structure */ - NULL, /* merge per-server config structures */ - NULL, /* command apr_table_t */ - ap_proxy_http_register_hook/* register hooks */ -}; - diff --git a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_util.c b/rubbos/app/httpd-2.0.64/modules/proxy/proxy_util.c deleted file mode 100644 index bab945f5..00000000 --- a/rubbos/app/httpd-2.0.64/modules/proxy/proxy_util.c +++ /dev/null @@ -1,1120 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Utility routines for Apache proxy */ -#include "mod_proxy.h" - - -static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r); -static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r); -static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r); -static int proxy_match_word(struct dirconn_entry *This, request_rec *r); - -APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, create_req, - (request_rec *r, request_rec *pr), (r, pr), - OK, DECLINED) - -/* already called in the knowledge that the characters are hex digits */ -PROXY_DECLARE(int) ap_proxy_hex2c(const char *x) -{ - int i, ch; - -#if !APR_CHARSET_EBCDIC - ch = x[0]; - if (apr_isdigit(ch)) - i = ch - '0'; - else if (apr_isupper(ch)) - i = ch - ('A' - 10); - else - i = ch - ('a' - 10); - i <<= 4; - - ch = x[1]; - if (apr_isdigit(ch)) - i += ch - '0'; - else if (apr_isupper(ch)) - i += ch - ('A' - 10); - else - i += ch - ('a' - 10); - return i; -#else /*APR_CHARSET_EBCDIC*/ - /* we assume that the hex value refers to an ASCII character - * so convert to EBCDIC so that it makes sense locally; - * - * example: - * - * client specifies %20 in URL to refer to a space char; - * at this point we're called with EBCDIC "20"; after turning - * EBCDIC "20" into binary 0x20, we then need to assume that 0x20 - * represents an ASCII char and convert 0x20 to EBCDIC, yielding - * 0x40 - */ - char buf[1]; - - if (1 == sscanf(x, "%2x", &i)) { - buf[0] = i & 0xFF; - ap_xlate_proto_from_ascii(buf, 1); - return buf[0]; - } - else { - return 0; - } -#endif /*APR_CHARSET_EBCDIC*/ -} - -PROXY_DECLARE(void) ap_proxy_c2hex(int ch, char *x) -{ -#if !APR_CHARSET_EBCDIC - int i; - - x[0] = '%'; - i = (ch & 0xF0) >> 4; - if (i >= 10) - x[1] = ('A' - 10) + i; - else - x[1] = '0' + i; - - i = ch & 0x0F; - if (i >= 10) - x[2] = ('A' - 10) + i; - else - x[2] = '0' + i; -#else /*APR_CHARSET_EBCDIC*/ - static const char ntoa[] = { "0123456789ABCDEF" }; - char buf[1]; - - ch &= 0xFF; - - buf[0] = ch; - ap_xlate_proto_to_ascii(buf, 1); - - x[0] = '%'; - x[1] = ntoa[(buf[0] >> 4) & 0x0F]; - x[2] = ntoa[buf[0] & 0x0F]; - x[3] = '\0'; -#endif /*APR_CHARSET_EBCDIC*/ -} - -/* - * canonicalise a URL-encoded string - */ - -/* - * Convert a URL-encoded string to canonical form. - * It decodes characters which need not be encoded, - * and encodes those which must be encoded, and does not touch - * those which must not be touched. - */ -PROXY_DECLARE(char *)ap_proxy_canonenc(apr_pool_t *p, const char *x, int len, enum enctype t, - int isenc) -{ - int i, j, ch; - char *y; - char *allowed; /* characters which should not be encoded */ - char *reserved; /* characters which much not be en/de-coded */ - -/* N.B. in addition to :@&=, this allows ';' in an http path - * and '?' in an ftp path -- this may be revised - * - * Also, it makes a '+' character in a search string reserved, as - * it may be form-encoded. (Although RFC 1738 doesn't allow this - - * it only permits ; / ? : @ = & as reserved chars.) - */ - if (t == enc_path) - allowed = "$-_.+!*'(),;:@&="; - else if (t == enc_search) - allowed = "$-_.!*'(),;:@&="; - else if (t == enc_user) - allowed = "$-_.+!*'(),;@&="; - else if (t == enc_fpath) - allowed = "$-_.+!*'(),?:@&="; - else /* if (t == enc_parm) */ - allowed = "$-_.+!*'(),?/:@&="; - - if (t == enc_path) - reserved = "/"; - else if (t == enc_search) - reserved = "+"; - else - reserved = ""; - - y = apr_palloc(p, 3 * len + 1); - - for (i = 0, j = 0; i < len; i++, j++) { -/* always handle '/' first */ - ch = x[i]; - if (strchr(reserved, ch)) { - y[j] = ch; - continue; - } -/* decode it if not already done */ - if (isenc && (isenc != PROXYREQ_REVERSE) && (ch == '%')) { - if (!apr_isxdigit(x[i + 1]) || !apr_isxdigit(x[i + 2])) - return NULL; - ch = ap_proxy_hex2c(&x[i + 1]); - i += 2; - if (ch != 0 && strchr(reserved, ch)) { /* keep it encoded */ - ap_proxy_c2hex(ch, &y[j]); - j += 2; - continue; - } - } -/* recode it, if necessary */ - if (!apr_isalnum(ch) && !strchr(allowed, ch)) { - ap_proxy_c2hex(ch, &y[j]); - j += 2; - } - else - y[j] = ch; - } - y[j] = '\0'; - return y; -} - -/* - * Parses network-location. - * urlp on input the URL; on output the path, after the leading / - * user NULL if no user/password permitted - * password holder for password - * host holder for host - * port port number; only set if one is supplied. - * - * Returns an error string. - */ -PROXY_DECLARE(char *) - ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp, - char **passwordp, char **hostp, apr_port_t *port) -{ - char *addr, *scope_id, *strp, *host, *url = *urlp; - char *user = NULL, *password = NULL; - apr_port_t tmp_port; - apr_status_t rv; - - if (url[0] != '/' || url[1] != '/') - return "Malformed URL"; - host = url + 2; - url = strchr(host, '/'); - if (url == NULL) - url = ""; - else - *(url++) = '\0'; /* skip seperating '/' */ - - /* find _last_ '@' since it might occur in user/password part */ - strp = strrchr(host, '@'); - - if (strp != NULL) { - *strp = '\0'; - user = host; - host = strp + 1; - -/* find password */ - strp = strchr(user, ':'); - if (strp != NULL) { - *strp = '\0'; - password = ap_proxy_canonenc(p, strp + 1, strlen(strp + 1), enc_user, 1); - if (password == NULL) - return "Bad %-escape in URL (password)"; - } - - user = ap_proxy_canonenc(p, user, strlen(user), enc_user, 1); - if (user == NULL) - return "Bad %-escape in URL (username)"; - } - if (userp != NULL) { - *userp = user; - } - if (passwordp != NULL) { - *passwordp = password; - } - - /* Parse the host string to separate host portion from optional port. - * Perform range checking on port. - */ - rv = apr_parse_addr_port(&addr, &scope_id, &tmp_port, host, p); - if (rv != APR_SUCCESS || addr == NULL || scope_id != NULL) { - return "Invalid host/port"; - } - if (tmp_port != 0) { /* only update caller's port if port was specified */ - *port = tmp_port; - } - - ap_str_tolower(addr); /* DNS names are case-insensitive */ - - *urlp = url; - *hostp = addr; - - return NULL; -} - -/* - * If the date is a valid RFC 850 date or asctime() date, then it - * is converted to the RFC 1123 format. - */ -PROXY_DECLARE(const char *) - ap_proxy_date_canon(apr_pool_t *p, const char *date) -{ - apr_status_t rv; - char* ndate; - - apr_time_t time = apr_date_parse_http(date); - if (!time) { - return date; - } - - ndate = apr_palloc(p, APR_RFC822_DATE_LEN); - rv = apr_rfc822_date(ndate, time); - if (rv != APR_SUCCESS) { - return date; - } - - return ndate; -} - -PROXY_DECLARE(request_rec *)ap_proxy_make_fake_req(conn_rec *c, request_rec *r) -{ - request_rec *rp = apr_pcalloc(c->pool, sizeof(*r)); - - rp->pool = c->pool; - rp->status = HTTP_OK; - - rp->headers_in = apr_table_make(c->pool, 50); - rp->subprocess_env = apr_table_make(c->pool, 50); - rp->headers_out = apr_table_make(c->pool, 12); - rp->err_headers_out = apr_table_make(c->pool, 5); - rp->notes = apr_table_make(c->pool, 5); - - rp->server = r->server; - rp->proxyreq = r->proxyreq; - rp->request_time = r->request_time; - rp->connection = c; - rp->output_filters = c->output_filters; - rp->input_filters = c->input_filters; - rp->proto_output_filters = c->output_filters; - rp->proto_input_filters = c->input_filters; - - rp->request_config = ap_create_request_config(c->pool); - proxy_run_create_req(r, rp); - - return rp; -} - -/* - * Reads headers from a buffer and returns an array of headers. - * Returns NULL on file error - * This routine tries to deal with too long lines and continuation lines. - * - * Note: Currently the headers are passed through unmerged. This has to be - * done so that headers which react badly to merging (such as Set-Cookie - * headers, which contain commas within the date field) do not get stuffed - * up. - */ -PROXY_DECLARE(apr_table_t *)ap_proxy_read_headers(request_rec *r, request_rec *rr, char *buffer, int size, conn_rec *c) -{ - apr_table_t *headers_out; - int len; - char *value, *end; - char field[MAX_STRING_LEN]; - int saw_headers = 0; - void *sconf = r->server->module_config; - proxy_server_conf *psc; - - psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); - - headers_out = apr_table_make(r->pool, 20); - - /* - * Read header lines until we get the empty separator line, a read error, - * the connection closes (EOF), or we timeout. - */ - while ((len = ap_getline(buffer, size, rr, 1)) > 0) { - - if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */ - - /* We may encounter invalid headers, usually from buggy - * MS IIS servers, so we need to determine just how to handle - * them. We can either ignore them, assume that they mark the - * start-of-body (eg: a missing CRLF) or (the default) mark - * the headers as totally bogus and return a 500. The sole - * exception is an extra "HTTP/1.0 200, OK" line sprinkled - * in between the usual MIME headers, which is a favorite - * IIS bug. - */ - /* XXX: The mask check is buggy if we ever see an HTTP/1.10 */ - - if (!apr_date_checkmask(buffer, "HTTP/#.# ###*")) { - if (psc->badopt == bad_error) { - /* Nope, it wasn't even an extra HTTP header. Give up. */ - return NULL; - } - else if (psc->badopt == bad_body) { - /* if we've already started loading headers_out, then - * return what we've accumulated so far, in the hopes - * that they are useful. Otherwise, we completely bail. - */ - /* FIXME: We've already scarfed the supposed 1st line of - * the body, so the actual content may end up being bogus - * as well. If the content is HTML, we may be lucky. - */ - if (saw_headers) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: Starting body due to bogus non-header in headers " - "returned by %s (%s)", r->uri, r->method); - return headers_out; - } else { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: No HTTP headers " - "returned by %s (%s)", r->uri, r->method); - return NULL; - } - } - } - /* this is the psc->badopt == bad_ignore case */ - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: Ignoring bogus HTTP header " - "returned by %s (%s)", r->uri, r->method); - continue; - } - - *value = '\0'; - ++value; - /* XXX: RFC2068 defines only SP and HT as whitespace, this test is - * wrong... and so are many others probably. - */ - while (apr_isspace(*value)) - ++value; /* Skip to start of value */ - - /* should strip trailing whitespace as well */ - for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) - *end = '\0'; - - /* make sure we add so as not to destroy duplicated headers */ - apr_table_add(headers_out, buffer, value); - saw_headers = 1; - - /* the header was too long; at the least we should skip extra data */ - if (len >= size - 1) { - while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1)) - >= MAX_STRING_LEN - 1) { - /* soak up the extra data */ - } - if (len == 0) /* time to exit the larger loop as well */ - break; - } - } - return headers_out; -} - - -/* - * list is a comma-separated list of case-insensitive tokens, with - * optional whitespace around the tokens. - * The return returns 1 if the token val is found in the list, or 0 - * otherwise. - */ -PROXY_DECLARE(int) ap_proxy_liststr(const char *list, const char *val) -{ - int len, i; - const char *p; - - len = strlen(val); - - while (list != NULL) { - p = ap_strchr_c(list, ','); - if (p != NULL) { - i = p - list; - do - p++; - while (apr_isspace(*p)); - } - else - i = strlen(list); - - while (i > 0 && apr_isspace(list[i - 1])) - i--; - if (i == len && strncasecmp(list, val, len) == 0) - return 1; - list = p; - } - return 0; -} - -/* - * list is a comma-separated list of case-insensitive tokens, with - * optional whitespace around the tokens. - * if val appears on the list of tokens, it is removed from the list, - * and the new list is returned. - */ -PROXY_DECLARE(char *)ap_proxy_removestr(apr_pool_t *pool, const char *list, const char *val) -{ - int len, i; - const char *p; - char *new = NULL; - - len = strlen(val); - - while (list != NULL) { - p = ap_strchr_c(list, ','); - if (p != NULL) { - i = p - list; - do - p++; - while (apr_isspace(*p)); - } - else - i = strlen(list); - - while (i > 0 && apr_isspace(list[i - 1])) - i--; - if (i == len && strncasecmp(list, val, len) == 0) { - /* do nothing */ - } - else { - if (new) - new = apr_pstrcat(pool, new, ",", apr_pstrndup(pool, list, i), NULL); - else - new = apr_pstrndup(pool, list, i); - } - list = p; - } - return new; -} - -/* - * Converts 8 hex digits to a time integer - */ -PROXY_DECLARE(int) ap_proxy_hex2sec(const char *x) -{ - int i, ch; - unsigned int j; - - for (i = 0, j = 0; i < 8; i++) { - ch = x[i]; - j <<= 4; - if (apr_isdigit(ch)) - j |= ch - '0'; - else if (apr_isupper(ch)) - j |= ch - ('A' - 10); - else - j |= ch - ('a' - 10); - } - if (j == 0xffffffff) - return -1; /* so that it works with 8-byte ints */ - else - return j; -} - -/* - * Converts a time integer to 8 hex digits - */ -PROXY_DECLARE(void) ap_proxy_sec2hex(int t, char *y) -{ - int i, ch; - unsigned int j = t; - - for (i = 7; i >= 0; i--) { - ch = j & 0xF; - j >>= 4; - if (ch >= 10) - y[i] = ch + ('A' - 10); - else - y[i] = ch + '0'; - } - y[8] = '\0'; -} - -PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message) -{ - apr_table_setn(r->notes, "error-notes", - apr_pstrcat(r->pool, - "The proxy server could not handle the request " - "<em><a href=\"", ap_escape_uri(r->pool, r->uri), - "\">", ap_escape_html(r->pool, r->method), - " ", - ap_escape_html(r->pool, r->uri), "</a></em>.<p>\n" - "Reason: <strong>", - ap_escape_html(r->pool, message), - "</strong></p>", NULL)); - - /* Allow "error-notes" string to be printed by ap_send_error_response() */ - apr_table_setn(r->notes, "verbose-error-to", apr_pstrdup(r->pool, "*")); - - r->status_line = apr_psprintf(r->pool, "%3.3u Proxy Error", statuscode); - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "proxy: %s returned by %s", message, r->uri); - return statuscode; -} - -static const char * - proxy_get_host_of_request(request_rec *r) -{ - char *url, *user = NULL, *password = NULL, *err, *host; - apr_port_t port; - - if (r->hostname != NULL) - return r->hostname; - - /* Set url to the first char after "scheme://" */ - if ((url = strchr(r->uri, ':')) == NULL - || url[1] != '/' || url[2] != '/') - return NULL; - - url = apr_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */ - - err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port); - - if (err != NULL) - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, - "%s", err); - - r->hostname = host; - - return host; /* ought to return the port, too */ -} - -/* Return TRUE if addr represents an IP address (or an IP network address) */ -PROXY_DECLARE(int) ap_proxy_is_ipaddr(struct dirconn_entry *This, apr_pool_t *p) -{ - const char *addr = This->name; - long ip_addr[4]; - int i, quads; - long bits; - - /* if the address is given with an explicit netmask, use that */ - /* Due to a deficiency in apr_inet_addr(), it is impossible to parse */ - /* "partial" addresses (with less than 4 quads) correctly, i.e. */ - /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */ - /* I therefore have to parse the IP address manually: */ - /*if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) == 0) */ - /* addr and mask were set by proxy_readmask() */ - /*return 1; */ - - /* Parse IP addr manually, optionally allowing */ - /* abbreviated net addresses like 192.168. */ - - /* Iterate over up to 4 (dotted) quads. */ - for (quads = 0; quads < 4 && *addr != '\0'; ++quads) { - char *tmp; - - if (*addr == '/' && quads > 0) /* netmask starts here. */ - break; - - if (!apr_isdigit(*addr)) - return 0; /* no digit at start of quad */ - - ip_addr[quads] = strtol(addr, &tmp, 0); - - if (tmp == addr) /* expected a digit, found something else */ - return 0; - - if (ip_addr[quads] < 0 || ip_addr[quads] > 255) { - /* invalid octet */ - return 0; - } - - addr = tmp; - - if (*addr == '.' && quads != 3) - ++addr; /* after the 4th quad, a dot would be illegal */ - } - - for (This->addr.s_addr = 0, i = 0; i < quads; ++i) - This->addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i)); - - if (addr[0] == '/' && apr_isdigit(addr[1])) { /* net mask follows: */ - char *tmp; - - ++addr; - - bits = strtol(addr, &tmp, 0); - - if (tmp == addr) /* expected a digit, found something else */ - return 0; - - addr = tmp; - - if (bits < 0 || bits > 32) /* netmask must be between 0 and 32 */ - return 0; - - } - else { - /* Determine (i.e., "guess") netmask by counting the */ - /* number of trailing .0's; reduce #quads appropriately */ - /* (so that 192.168.0.0 is equivalent to 192.168.) */ - while (quads > 0 && ip_addr[quads - 1] == 0) - --quads; - - /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */ - if (quads < 1) - return 0; - - /* every zero-byte counts as 8 zero-bits */ - bits = 8 * quads; - - if (bits != 32) /* no warning for fully qualified IP address */ - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Warning: NetMask not supplied with IP-Addr; guessing: %s/%ld", - inet_ntoa(This->addr), bits); - } - - This->mask.s_addr = htonl(APR_INADDR_NONE << (32 - bits)); - - if (*addr == '\0' && (This->addr.s_addr & ~This->mask.s_addr) != 0) { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "Warning: NetMask and IP-Addr disagree in %s/%ld", - inet_ntoa(This->addr), bits); - This->addr.s_addr &= This->mask.s_addr; - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " Set to %s/%ld", - inet_ntoa(This->addr), bits); - } - - if (*addr == '\0') { - This->matcher = proxy_match_ipaddr; - return 1; - } - else - return (*addr == '\0'); /* okay iff we've parsed the whole string */ -} - -/* Return TRUE if addr represents an IP address (or an IP network address) */ -static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r) -{ - int i, ip_addr[4]; - struct in_addr addr, *ip; - const char *host = proxy_get_host_of_request(r); - - if (host == NULL) /* oops! */ - return 0; - - memset(&addr, '\0', sizeof addr); - memset(ip_addr, '\0', sizeof ip_addr); - - if (4 == sscanf(host, "%d.%d.%d.%d", &ip_addr[0], &ip_addr[1], &ip_addr[2], &ip_addr[3])) { - for (addr.s_addr = 0, i = 0; i < 4; ++i) - addr.s_addr |= htonl(ip_addr[i] << (24 - 8 * i)); - - if (This->addr.s_addr == (addr.s_addr & This->mask.s_addr)) { -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "1)IP-Match: %s[%s] <-> ", host, inet_ntoa(addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s", inet_ntoa(This->mask)); -#endif - return 1; - } -#if DEBUGGING - else { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "1)IP-NoMatch: %s[%s] <-> ", host, inet_ntoa(addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s", inet_ntoa(This->mask)); - } -#endif - } - else { - struct apr_sockaddr_t *reqaddr; - - if (apr_sockaddr_info_get(&reqaddr, host, APR_UNSPEC, 0, 0, r->pool) - != APR_SUCCESS) { -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "2)IP-NoMatch: hostname=%s msg=Host not found", - host); -#endif - return 0; - } - - /* Try to deal with multiple IP addr's for a host */ - /* FIXME: This needs to be able to deal with IPv6 */ - while (reqaddr) { - ip = (struct in_addr *) reqaddr->ipaddr_ptr; - if (This->addr.s_addr == (ip->s_addr & This->mask.s_addr)) { -#if DEBUGGING - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "3)IP-Match: %s[%s] <-> ", host, - inet_ntoa(*ip)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s", inet_ntoa(This->mask)); -#endif - return 1; - } -#if DEBUGGING - else { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "3)IP-NoMatch: %s[%s] <-> ", host, - inet_ntoa(*ip)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s/", inet_ntoa(This->addr)); - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "%s", inet_ntoa(This->mask)); - } -#endif - reqaddr = reqaddr->next; - } - } - - return 0; -} - -/* Return TRUE if addr represents a domain name */ -PROXY_DECLARE(int) ap_proxy_is_domainname(struct dirconn_entry *This, apr_pool_t *p) -{ - char *addr = This->name; - int i; - - /* Domain name must start with a '.' */ - if (addr[0] != '.') - return 0; - - /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */ - for (i = 0; apr_isalnum(addr[i]) || addr[i] == '-' || addr[i] == '.'; ++i) - continue; - -#if 0 - if (addr[i] == ':') { - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - "@@@@ handle optional port in proxy_is_domainname()"); - /* @@@@ handle optional port */ - } -#endif - - if (addr[i] != '\0') - return 0; - - /* Strip trailing dots */ - for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i) - addr[i] = '\0'; - - This->matcher = proxy_match_domainname; - return 1; -} - -/* Return TRUE if host "host" is in domain "domain" */ -static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r) -{ - const char *host = proxy_get_host_of_request(r); - int d_len = strlen(This->name), h_len; - - if (host == NULL) /* some error was logged already */ - return 0; - - h_len = strlen(host); - - /* @@@ do this within the setup? */ - /* Ignore trailing dots in domain comparison: */ - while (d_len > 0 && This->name[d_len - 1] == '.') - --d_len; - while (h_len > 0 && host[h_len - 1] == '.') - --h_len; - return h_len > d_len - && strncasecmp(&host[h_len - d_len], This->name, d_len) == 0; -} - -/* Return TRUE if host represents a host name */ -PROXY_DECLARE(int) ap_proxy_is_hostname(struct dirconn_entry *This, apr_pool_t *p) -{ - struct apr_sockaddr_t *addr; - char *host = This->name; - int i; - - /* Host names must not start with a '.' */ - if (host[0] == '.') - return 0; - - /* rfc1035 says DNS names must consist of "[-a-zA-Z0-9]" and '.' */ - for (i = 0; apr_isalnum(host[i]) || host[i] == '-' || host[i] == '.'; ++i); - - if (host[i] != '\0' || apr_sockaddr_info_get(&addr, host, APR_UNSPEC, 0, 0, p) != APR_SUCCESS) - return 0; - - This->hostaddr = addr; - - /* Strip trailing dots */ - for (i = strlen(host) - 1; i > 0 && host[i] == '.'; --i) - host[i] = '\0'; - - This->matcher = proxy_match_hostname; - return 1; -} - -/* Return TRUE if host "host" is equal to host2 "host2" */ -static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r) -{ - char *host = This->name; - const char *host2 = proxy_get_host_of_request(r); - int h2_len; - int h1_len; - - if (host == NULL || host2 == NULL) - return 0; /* oops! */ - - h2_len = strlen(host2); - h1_len = strlen(host); - -#if 0 - struct apr_sockaddr_t *addr = *This->hostaddr; - - /* Try to deal with multiple IP addr's for a host */ - while (addr) { - if (addr->ipaddr_ptr == ? ? ? ? ? ? ? ? ? ? ? ? ?) - return 1; - addr = addr->next; - } -#endif - - /* Ignore trailing dots in host2 comparison: */ - while (h2_len > 0 && host2[h2_len - 1] == '.') - --h2_len; - while (h1_len > 0 && host[h1_len - 1] == '.') - --h1_len; - return h1_len == h2_len - && strncasecmp(host, host2, h1_len) == 0; -} - -/* Return TRUE if addr is to be matched as a word */ -PROXY_DECLARE(int) ap_proxy_is_word(struct dirconn_entry *This, apr_pool_t *p) -{ - This->matcher = proxy_match_word; - return 1; -} - -/* Return TRUE if string "str2" occurs literally in "str1" */ -static int proxy_match_word(struct dirconn_entry *This, request_rec *r) -{ - const char *host = proxy_get_host_of_request(r); - return host != NULL && ap_strstr_c(host, This->name) != NULL; -} - -/* checks whether a host in uri_addr matches proxyblock */ -PROXY_DECLARE(int) ap_proxy_checkproxyblock(request_rec *r, proxy_server_conf *conf, - apr_sockaddr_t *uri_addr) -{ - int j; - apr_sockaddr_t * src_uri_addr = uri_addr; - /* XXX FIXME: conf->noproxies->elts is part of an opaque structure */ - for (j = 0; j < conf->noproxies->nelts; j++) { - struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; - struct apr_sockaddr_t *conf_addr = npent[j].addr; - uri_addr = src_uri_addr; - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: checking remote machine [%s] against [%s]", uri_addr->hostname, npent[j].name); - if ((npent[j].name && ap_strstr_c(uri_addr->hostname, npent[j].name)) - || npent[j].name[0] == '*') { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: connect to remote machine %s blocked: name %s matched", uri_addr->hostname, npent[j].name); - return HTTP_FORBIDDEN; - } - while (conf_addr) { - while (uri_addr) { - char *conf_ip; - char *uri_ip; - apr_sockaddr_ip_get(&conf_ip, conf_addr); - apr_sockaddr_ip_get(&uri_ip, uri_addr); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: ProxyBlock comparing %s and %s", conf_ip, uri_ip); - if (!apr_strnatcasecmp(conf_ip, uri_ip)) { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: connect to remote machine %s blocked: IP %s matched", uri_addr->hostname, conf_ip); - return HTTP_FORBIDDEN; - } - uri_addr = uri_addr->next; - } - conf_addr = conf_addr->next; - } - } - return OK; -} - -/* set up the minimal filter set */ -PROXY_DECLARE(int) ap_proxy_pre_http_request(conn_rec *c, request_rec *r) -{ - ap_add_input_filter("HTTP_IN", NULL, r, c); - return OK; -} - -/* converts a series of buckets into a string - * XXX: BillS says this function performs essentially the same function as - * ap_rgetline() in protocol.c. Deprecate this function and use ap_rgetline() - * instead? I think ap_proxy_string_read() will not work properly on non ASCII - * (EBCDIC) machines either. - */ -PROXY_DECLARE(apr_status_t) ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, - char *buff, apr_size_t bufflen, int *eos) -{ - apr_bucket *e; - apr_status_t rv; - char *pos = buff; - char *response; - int found = 0; - apr_size_t len; - - /* start with an empty string */ - buff[0] = 0; - *eos = 0; - - /* loop through each brigade */ - while (!found) { - /* get brigade from network one line at a time */ - if (APR_SUCCESS != (rv = ap_get_brigade(c->input_filters, bb, - AP_MODE_GETLINE, - APR_BLOCK_READ, - 0))) { - return rv; - } - /* loop through each bucket */ - while (!found) { - if (*eos || APR_BRIGADE_EMPTY(bb)) { - /* The connection aborted or timed out */ - return APR_ECONNABORTED; - } - e = APR_BRIGADE_FIRST(bb); - if (APR_BUCKET_IS_EOS(e)) { - *eos = 1; - } - else { - if (APR_SUCCESS != apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ)) { - return rv; - } - /* is string LF terminated? - * XXX: This check can be made more efficient by simply checking - * if the last character in the 'response' buffer is an ASCII_LF. - * See ap_rgetline() for an example. - */ - if (memchr(response, APR_ASCII_LF, len)) { - found = 1; - } - /* concat strings until buff is full - then throw the data away */ - if (len > ((bufflen-1)-(pos-buff))) { - len = (bufflen-1)-(pos-buff); - } - if (len > 0) { - pos = apr_cpystrn(pos, response, len); - } - } - APR_BUCKET_REMOVE(e); - apr_bucket_destroy(e); - } - } - - return APR_SUCCESS; -} - -/* unmerge an element in the table */ -PROXY_DECLARE(void) ap_proxy_table_unmerge(apr_pool_t *p, apr_table_t *t, char *key) -{ - apr_off_t offset = 0; - apr_off_t count = 0; - char *value = NULL; - - /* get the value to unmerge */ - const char *initial = apr_table_get(t, key); - if (!initial) { - return; - } - value = apr_pstrdup(p, initial); - - /* remove the value from the headers */ - apr_table_unset(t, key); - - /* find each comma */ - while (value[count]) { - if (value[count] == ',') { - value[count] = 0; - apr_table_add(t, key, value + offset); - offset = count + 1; - } - count++; - } - apr_table_add(t, key, value + offset); -} - -PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **newsock, - const char *proxy_function, - apr_sockaddr_t *backend_addr, - const char *backend_name, - proxy_server_conf *conf, - server_rec *s, - apr_pool_t *p) -{ - apr_status_t rv; - int connected = 0; - int loglevel; - - while (backend_addr && !connected) { - if ((rv = apr_socket_create(newsock, backend_addr->family, - SOCK_STREAM, p)) != APR_SUCCESS) { - loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; - ap_log_error(APLOG_MARK, loglevel, rv, s, - "proxy: %s: error creating fam %d socket for target %s", - proxy_function, - backend_addr->family, - backend_name); - /* this could be an IPv6 address from the DNS but the - * local machine won't give us an IPv6 socket; hopefully the - * DNS returned an additional address to try - */ - backend_addr = backend_addr->next; - continue; - } - -#if !defined(TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 && - (rv = apr_socket_opt_set(*newsock, APR_SO_RCVBUF, - conf->recv_buffer_size))) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "apr_socket_opt_set(SO_RCVBUF): Failed to set " - "ProxyReceiveBufferSize, using default"); - } -#endif - - /* Set a timeout on the socket */ - if (conf->timeout_set == 1) { - apr_socket_timeout_set(*newsock, conf->timeout); - } - else { - apr_socket_timeout_set(*newsock, s->timeout); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "proxy: %s: fam %d socket created to connect to %s", - proxy_function, backend_addr->family, backend_name); - - /* make the connection out of the socket */ - rv = apr_connect(*newsock, backend_addr); - - /* if an error occurred, loop round and try again */ - if (rv != APR_SUCCESS) { - apr_socket_close(*newsock); - loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; - ap_log_error(APLOG_MARK, loglevel, rv, s, - "proxy: %s: attempt to connect to %pI (%s) failed", - proxy_function, - backend_addr, - backend_name); - backend_addr = backend_addr->next; - continue; - } - connected = 1; - } - return connected ? 0 : 1; -} - |