1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-05 16:55:50 +03:00

428 Commits

Author SHA1 Message Date
Joe Orton
4915c21524 Add Multipath TCP (MPTCP) support (Proxy)
Multipath TCP (MPTCP), standardized in RFC8684 [1],
is a TCP extension that enables a TCP connection to
use different paths.

Multipath TCP has been used for several use cases.
On smartphones, MPTCP enables seamless handovers between
cellular and Wi-Fi networks while preserving established
connections. This use-case is what pushed Apple to use
MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to
automatically use the best performing path, either IPv4
or IPv6. If one path fails, MPTCP automatically uses
the other path.

To benefit from MPTCP, both the client and the server
have to support it. Multipath TCP is a backward-compatible
TCP extension that is enabled by default on recent
Linux distributions (Debian, Ubuntu, Redhat, ...). Multipath
TCP is included in the Linux kernel since version 5.6 [3].
To use it on Linux, an application must explicitly enable
it when creating the socket. No need to change anything
else in the application.

Adding the possibility to create MPTCP sockets would thus
be a really fine addition to httpd, by allowing clients
to make use of their different interfaces.

This patch introduces the possibilty to connect to backend
servers using MPTCP. Note however that these changes are
only available on Linux, as IPPROTO_MPTCP is Linux specific
for the time being.

For proxies, we can connect using MPTCP by passing the
\"multipathtcp\" parameter:

ProxyPass \"/example\" \"http://backend.example.com\" multipathtcp=On

We then store this information in the worker and create sockets
appropriately according to this value.

Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
Add Multipath TCP (MPTCP) support (Core)

Multipath TCP (MPTCP), standardized in RFC8684 [1],
is a TCP extension that enables a TCP connection to
use different paths.

Multipath TCP has been used for several use cases.
On smartphones, MPTCP enables seamless handovers between
cellular and Wi-Fi networks while preserving established
connections. This use-case is what pushed Apple to use
MPTCP since 2013 in multiple applications [2]. On dual-stack
hosts, Multipath TCP enables the TCP connection to
automatically use the best performing path, either IPv4
or IPv6. If one path fails, MPTCP automatically uses
the other path.

To benefit from MPTCP, both the client and the server
have to support it. Multipath TCP is a backward-compatible
TCP extension that is enabled by default on recent
Linux distributions (Debian, Ubuntu, Redhat, ...). Multipath
TCP is included in the Linux kernel since version 5.6 [3].
To use it on Linux, an application must explicitly enable
it when creating the socket. No need to change anything
else in the application.

Adding the possibility to create MPTCP sockets would thus
be a really fine addition to httpd, by allowing clients
to make use of their different interfaces.

This patch introduces the possibility to listen with MPTCP
sockets. Note however that these changes are only available
on Linux, as IPPROTO_MPTCP is Linux specific for the time being.

To do so, we extended the Listen directive to include
a \"multipathtcp\" option, allowing to create MPTCP sockets
instead of regular TCP ones:

Listen 80 options=multipathtcp

We then store this information in flags for the listen directive
and create sockets appropriately according to this value.

Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]

Submitted by: Aperence <anthony.doeraene hotmail.com>
Github: closes #476


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1920586 13f79535-47bb-0310-9956-ffa450edef68
2024-09-12 07:59:22 +00:00
Yann Ylavic
2f1f9c5df0 mod_proxy: Fix selection of ProxyPassMatch workers with host/port substitution. PR 69233.
With "ProxyPassMatch ^/([^/]+)/(.*)$ https://$1/$2", ap_proxy_get_worker_ex()
should not consider the length of scheme://host part of the given URL because
of the globbing match on the host part.

Fix it by setting worker->s>is_host_matchable when creating a worker with host
substitution and avoiding the min_match check in worker_matches() in this case.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1919617 13f79535-47bb-0310-9956-ffa450edef68
2024-08-01 11:35:26 +00:00
Yann Ylavic
6716ada174 mod_proxy: Fix canonicalisation and FCGI env (PATH_INFO, SCRIPT_NAME) for
"balancer:" URLs set via SetHandler, also allowing for "unix:"
           sockets with BalancerMember(s).  PR 69168.

* modules/proxy/proxy_util.h, modules/proxy/proxy_util.c:
  Move proxy_interpolate() from mod_proxy.c to ap_proxy_interpolate(),
  exported locally only (non public).
  Move proxy_fixup() from mod_proxy.c to ap_proxy_canon_url(), exported
  locally only too (non public).
  Rollback ap_proxy_fixup_uds_filename() to a local fixup_uds_filename()
  usable from proxy_util.c only. The public function will be removed in
  a following commit.

* modules/proxy/mod_proxy.h:
  Note that ap_proxy_fixup_uds_filename() is deprecated.

* modules/proxy/mod_proxy.c:
  Just use ap_proxy_canon_url() from proxy_fixup() and proxy_handler()
  for SetHandler URLs.

* modules/proxy/mod_proxy_balancer.c:
  Do not canonicalize the path from proxy_balancer_canon() anymore but
  rather from balancer_fixup() where the balancer URL is rewritten to
  the BalancerMember URL.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1919022 13f79535-47bb-0310-9956-ffa450edef68
2024-07-08 13:59:50 +00:00
Yann Ylavic
ad3f022fa1 mod_proxy: follow up to r1918626: Simplify ap_proxy_fixup_uds_filename() and callers.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1918647 13f79535-47bb-0310-9956-ffa450edef68
2024-06-26 09:19:16 +00:00
Yann Ylavic
6937b985ae mod_proxy: Fixup UDS filename for mod_proxy called through r->handler.
* modules/proxy/proxy_util.c:
  Export ap_proxy_fixup_uds_filename() from fix_uds_filename.
  Call it from ap_proxy_pre_request() even for rewritten balancer workers.

* modules/proxy/mod_proxy.h:
  Declare ap_proxy_fixup_uds_filename()

* modules/proxy/mod_proxy.c:
  Fixup UDS filename from r->handler in proxy_handler().

* include/ap_mmn.h:
  Bump MMN minor for ap_proxy_fixup_uds_filename()



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1918626 13f79535-47bb-0310-9956-ffa450edef68
2024-06-25 23:49:09 +00:00
Yann Ylavic
29fb603784 mod_proxy: Add ap_proxy_worker_get_name() and deprecate ap_proxy_worker_name().
The latter requires a pool and returns a non constant string although it may
return worker shared data.

By computing the worker "UDS" name at init time we can return a constant name
in any case with no need for a pool, that's the new ap_proxy_worker_get_name().



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1912461 13f79535-47bb-0310-9956-ffa450edef68
2023-09-21 13:31:15 +00:00
Yann Ylavic
3c7f67fa2a mod_proxy: Handle backend address renewal with address_ttl= parameter.
Define a new proxy_address struct holding the current/latest sockaddr in use
by each proxy worker and conn. Since backend addresses can be updated when
their TTL expires and while connections are being processed, each address is
refcounted and freed only when the last worker (or conn) using it grabs the
new one.

The lifetime of the addresses is handled at a single place by the new
ap_proxy_determine_address() function. It guarantees to bind the current/latest
backend address to the passed in conn (or do nothing if it's up to date already).
The function is called indirectly by ap_proxy_determine_connection() for the
proxy modules that use it, or directly by mod_proxy_ftp and mod_proxy_hcheck.
It also is called eventually by ap_proxy_connect_backend() when connect()ing all
the current addresses fails, to check (PROXY_DETERMINE_ADDRESS_CHECK) if some
new addrs are available.

This commit is also a rework of the lifetime of conn->addr, conn->hostname
and conn->forward, using the conn->uds_pool and conn->fwd_pool for the cases
where the backend is connected through a UDS socket and a remote CONNECT proxy
respectively.

* include/ap_mmn.h:
  Minor bump for new function/fields.

* modules/proxy/mod_proxy.h (struct proxy_address,
                             ap_proxy_determine_addresss()):
  Declare ap_proxy_determine_addresss() and opaque struct proxy_address,
  new fields to structs proxy_conn_rec/proxy_worker_shared/proxy_worker.

* modules/proxy/mod_proxy.c (set_worker_param):
  Parse/set the new worker->address_ttl parameter.

* modules/proxy/proxy_util.c (proxy_util_register_hooks(),
                              ap_proxy_initialize_worker(),
                              ap_proxy_connection_reusable(),
                              ap_proxyerror(), proxyerror_core(),
                              init_conn_pool(), make_conn_subpool(),
                              connection_make(), connection_cleanup(),
                              connection_constructor()):
 Initialize *proxy_start_time in proxy_util_register_hooks() as the epoch
 from which expiration times are relative (i.e. seconds stored in an uint32_t
 for atomic changes).
 Make sure worker->s->is_address_reusable and worker->s->disablereuse are
 consistant in ap_proxy_initialize_worker(), thus no need to check for both
 in ap_proxy_connection_reusable().
 New proxyerror_core() helper taking an apr_status_t to log, wrap in
 ap_proxyerror().
 New make_conn_subpool() to create worker->cp->{pool,dns} with their own
 allocator.
 New connection_make() helper to factorize code in connection_cleanup() and
 connection_constructor().

* modules/proxy/proxy_util.c (proxy_address_inc(), proxy_address_dec(),
                              proxy_address_cleanup(), proxy_address_set_expired(),
                              worker_address_get(), worker_address_set(),
                              worker_address_resolve(), proxy_addrs_equal(),
                              ap_proxy_determine_address(),
                              ap_proxy_determine_connection(),
                              ap_proxy_connect_backend()):
 Implement ap_proxy_determine_address() using the above helpers for atomic changes,
 and call it from ap_proxy_determine_connection() and ap_proxy_connect_backend().

* modules/proxy/mod_proxy_ftp.c (proxy_ftp_handler):
  Use ap_proxy_determine_address() and use the returned backend->addr.

* modules/proxy/mod_proxy_hcheck.c (hc_determine_connection, hc_get_backend,
                                    hc_init_worker, hc_watchdog_callback):
  Use ap_proxy_determine_address() in hc_determine_connection() and call the
  latter from hc_get_backend(), replace hc_init_worker() by hc_init_baton()
  which now calls hc_get_hcworker() and hc_get_backend() to resolve the first
  address at init time.

* modules/proxy/mod_proxy_http.c (proxy_http_handler):
  Use backend->addr and ->hostname instead of worker->cp->addr and
  worker->s->hostname_ex respectively.

* modules/proxy/mod_proxy_ajp.c (ap_proxy_ajp_request):
  Use backend->addr and ->hostname instead of worker->cp->addr and
  worker->s->hostname_ex respectively.


Closes #367



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1912459 13f79535-47bb-0310-9956-ffa450edef68
2023-09-21 13:15:35 +00:00
Ruediger Pluem
2fa15c2c06 Do not double encode encoded slashes
In case that AllowEncodedSlashes is set to NoDecode do not double encode
encoded slashes in the URL sent by the reverse proxy to the backend.

* include/ap_mmn.h: Document the addition of ap_proxy_canonenc_ex to the API.

* modules/proxy/mod_proxy.h: Declare ap_proxy_canonenc_ex and define flag
      values.

* modules/proxy/proxy_util.c: Implement ap_proxy_canonenc_ex by modifying
      ap_proxy_canonenc accordingly and reimplement ap_proxy_canonenc to
      use ap_proxy_canonenc_ex with the appropriate flag.

* modules/http2/mod_proxy_http2.c, modules/proxy/mod_proxy_*.c: Set the
      correct flag based on the AllowEncodedSlashes configuration and use
      ap_proxy_canonenc_ex instead of ap_proxy_canonenc.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1908341 13f79535-47bb-0310-9956-ffa450edef68
2023-03-13 10:24:30 +00:00
Jim Jagielski
ac04f2ff6b *) mod_proxy_hcheck: Re-enable workers in standard ERROR state. PR 66302.
[Alessandro Cavaliere <alessandro.cavalier7 unibo.it>]


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1904518 13f79535-47bb-0310-9956-ffa450edef68
2022-10-11 13:20:11 +00:00
Jim Jagielski
eb2325b125 Allow for HTTP/1.1 or HTTP/1.0 protocol health checks
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1903744 13f79535-47bb-0310-9956-ffa450edef68
2022-08-28 18:46:21 +00:00
Yann Ylavic
9a8214d08f mod_proxy_http: Avoid 417 responses for non forwardable 100-continue. PR 65666.
Stop returning 417 when mod_proxy has to forward an HTTP/1.1 request with both
"Expect: 100-continue" and "force-proxy-request-1.0" set, mod_proxy can instead
handle the 100-continue by itself before forwarding the request, like in the
"Proxy100Continue Off" case.

Note that this does not change the behaviour of httpd receiving an HTTP/1.0
request with an Expect header, ap_check_request_header() will still correctly
return 417 in this case.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1901420 13f79535-47bb-0310-9956-ffa450edef68
2022-05-30 15:54:34 +00:00
Jean-Frederic Clere
05e559da21 Revert r1899390.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1899479 13f79535-47bb-0310-9956-ffa450edef68
2022-04-01 10:30:06 +00:00
Jean-Frederic Clere
2bcf00780e Add WorkerBalancerGrowth. To allow creation of workers
to dynamically added balancers.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1899390 13f79535-47bb-0310-9956-ffa450edef68
2022-03-30 14:42:14 +00:00
Yann Ylavic
85051bd9ac mod_proxy: Bump max worker name to 384 chars.
The worker name is a fully qualified URI while the hostname's limit is 256
already, so potentially more than 256 are needed to store the name. Let's
use 384.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1896253 13f79535-47bb-0310-9956-ffa450edef68
2021-12-21 18:42:30 +00:00
Yann Ylavic
15a5cde916 mod_proxy: follow up to r1895921: Don't prevent forwarding URIs w/ no hostname.
r1895921 changed proxy_detect() to disable forward proxying for URIs with no
hostname which is wrong, there might exist a third-party proxy module handling
the "urn:" scheme for instance (thanks Roy for the catch!).

For this to work, we also need to leave the forward proxied URI alone in
ap_proxy_pre_request() with no UDS special case or alike, a proxy module can
then catch (or not) the original URI as expected.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1895981 13f79535-47bb-0310-9956-ffa450edef68
2021-12-15 11:35:36 +00:00
Yann Ylavic
5338e45798 mod_proxy: SetEnv proxy-nohalfclose to disable half-close tunneling. PR 65662.
Some connect/wstunnel protocols might want half-close forwarding while some
might not, let's provide an r->subprocess_env opt-out.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1895304 13f79535-47bb-0310-9956-ffa450edef68
2021-11-24 17:49:47 +00:00
Yann Ylavic
3d2842e915 mod_proxy: Add tunnel_forward hook.
* modules/proxy/mod_proxy.h, modules/proxy/mod_proxy.c:
  Declare/implement the hook.

* modules/proxy/proxy_util.c(proxy_transfer):
  Run tunnel_forward hooks when called by the tunneling loop.
  Simpler input/output brigade cleanup on exit.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1893603 13f79535-47bb-0310-9956-ffa450edef68
2021-09-24 15:52:50 +00:00
Yann Ylavic
b44b9b6b2a mod_proxy: Handle ap_proxy_buckets_lifetime_transform() errors.
* modules/proxy/mod_proxy.h,modules/proxy/proxy_util.c:
  Add ap_proxy_fill_error_brigade() to factorize proxy error handling
  on the client connection side.

* modules/proxy/mod_proxy_{http,ajp,uwsgi}.c:
  Use ap_proxy_fill_error_brigade() where needed, including when an
  empty brigade is returned on the backend side or when calling
  ap_proxy_buckets_lifetime_transform fails.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1893595 13f79535-47bb-0310-9956-ffa450edef68
2021-09-24 11:25:42 +00:00
Yann Ylavic
074d55133a mod_proxy: Restore ap_proxy_transfer_between_connections().
* modules/proxy/mod_proxy.h:
  Restore the interface of ap_proxy_transfer_between_connections() back to
  before MMN 20210506.0.
  Add ap_proxy_tunnel_conn_bytes_in() and ap_proxy_tunnel_conn_bytes_out().
  New proxy_tunnel_conn_t typedef'ed from opaque struct proxy_tunnel_conn.

* modules/proxy/mod_proxy.h(ap_proxy_tunnel_conn_get_read,
                            ap_proxy_tunnel_conn_get_transferred):
  Axed/replaced by ap_proxy_tunnel_conn_bytes_in() and
  ap_proxy_tunnel_conn_bytes_out().

* modules/proxy/proxy_util.c(struct proxy_tunnel_conn):
  Replace "exchanged" by "bytes_in" and "bytes_out".

* modules/proxy/proxy_util.c(proxy_transfer):
  New helper implementing ap_proxy_transfer_between_connections() and
  returning both &bytes_in and &bytes_out.

* modules/proxy/proxy_util.c(ap_proxy_transfer_between_connections):
  Now calls proxy_transfer().

* modules/proxy/proxy_util.c(ap_proxy_tunnel_conn_bytes_in,
                             ap_proxy_tunnel_conn_bytes_out):
  Return tc->bytes_in and tc->bytes_out respectively.

* modules/proxy/proxy_util.c(proxy_tunnel_forward):
  Use proxy_transfer() which updates in->bytes_in, &out->bytes_out.
  tunnel->replied will be updated in proxy_tunnel_run().

* modules/proxy/proxy_util.c(proxy_tunnel_forward):
  Fall through the "done" label in any case to set tunnel->replied based
  on tunnel->client->bytes_out > 0.

* modules/proxy/mod_proxy_http.c(ap_proxy_http_process_response):
  Use ap_proxy_tunnel_conn_bytes_{in,out}() for worker->s->{read,transferred}
  accounting.

* modules/proxy/mod_proxy_http.c(proxy_http_async_finish):
  Update worker->s->{read,transferred} when async too.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1893594 13f79535-47bb-0310-9956-ffa450edef68
2021-09-24 10:27:16 +00:00
Yann Ylavic
63da5b997f mod_proxy: typedef struct proxy_tunnel_conn proxy_tunnel_conn_t.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1893593 13f79535-47bb-0310-9956-ffa450edef68
2021-09-24 10:09:23 +00:00
Yann Ylavic
20dd120ce4 mod_proxy: Avoid confusion of prefix/regex matching workers at loading. PR 65429.
ap_proxy_get_worker() needs to know whether it should lookup for prefix or
match or both matching workers, depending on the context.

For instance <Proxy[Match]> or ProxyPass[Match] directives need to lookup for
an existing worker with the same type as the directive (*Match or not), because
they will define one with that matching type if none exists.

On the contrary, "ProxySet <url>" at load time or ap_proxy_pre_request() at run
time need to find a worker matching an url whether it's by prefix or by regex.

So this commit adds ap_proxy_get_worker_ex() which takes a bitmask for the
matching type and calls it appropriately where needed.

For consistency, ap_proxy_define_worker_ex() is also added, using the same
bitmask flags, deprecating ap_proxy_define_match_worker().

Follow up to r1891206.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1891284 13f79535-47bb-0310-9956-ffa450edef68
2021-07-05 16:23:33 +00:00
Jean-Frederic Clere
cfd93e6c70 Allow the tunnelled connections to report the
read and trasnfered to the back-end worker.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1889550 13f79535-47bb-0310-9956-ffa450edef68
2021-05-06 06:25:09 +00:00
Stefan Eissing
587d170151 *) core: provide ap_ssl_* functions in new http_ssl.h header file.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1888083 13f79535-47bb-0310-9956-ffa450edef68
2021-03-26 11:27:34 +00:00
Jean-Frederic Clere
f5fbe0f338 Add CPING to health check logic.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1887415 13f79535-47bb-0310-9956-ffa450edef68
2021-03-10 10:36:46 +00:00
Jean-Frederic Clere
6cbbf4f0b1 Use an optional function as adviced by Rüdiger.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1887359 13f79535-47bb-0310-9956-ffa450edef68
2021-03-09 08:39:21 +00:00
Yann Ylavic
35a2656068 mod_proxy_wstunnel: leave Upgrade requests handling to mod_proxy_http.
Let mod_proxy_http's canon and scheme handlers accept "ws[s]:" schemes so that
mod_proxy_wstunnel can decline requests when mod_proxy_http is loaded.

* modules/proxy/{mod_proxy.h,proxy_util.c} (ap_proxy_worker_can_upgrade):
  Add a "dflt" argument to ap_proxy_worker_can_upgrade() which, if not NULL,
  is matched when no worker upgrade= parameter is configured. This allows to
  handle the default "Upgrade: websocket" case for "ws[s]:" schemes.

* modules/proxy/mod_proxy_http.c (proxy_http_canon, proxy_http_handler):
  Add and use the new get_url_scheme() helper to parse URL schemes handled by
  mod_proxy_http and use it in canon and scheme handlers. This helper now
  accepts ws[s] schemes.

* modules/proxy/mod_proxy_wstunnel.c (proxy_wstunnel_post_config):
  New post_config hook to detect whether mod_proxy_http is loaded and set
  global fallback_to_mod_proxy_http flag in this case.

* modules/proxy/mod_proxy_wstunnel.c (proxy_wstunnel_check_trans,
                                      proxy_wstunnel_canon,
                                      proxy_wstunnel_handler):
  These hooks now early return DECLINED if fallback_to_mod_proxy_http is set.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1885239 13f79535-47bb-0310-9956-ffa450edef68
2021-01-07 13:19:08 +00:00
Yann Ylavic
b288fac3b5 mod_proxy: provide prefetching and spooling mechanisms to all proxy modules.
Export ap_proxy_prefetch_input(), ap_proxy_spool_input() and
ap_proxy_read_input() from mod_proxy_http to mod_proxy.h/proxy_util.c so
that they are usable by all proxy modules.

mod_proxy_fcgi will use them in a following commit.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1884067 13f79535-47bb-0310-9956-ffa450edef68
2020-12-03 14:06:17 +00:00
Joe Orton
c77e6abe3b mod_proxy: Add support for an optional third argument to ProxyRemote*
to configure the Basic auth credentials to send to the remote proxy.

(Note that credentials are always sent w/o waiting for a challenge as
with proxy-chain-auth, and only Basic is supported - both of which are
not exactly ideal - but better than nothing.)

* modules/proxy/mod_proxy.h (struct proxy_remote): Add creds field.

* modules/proxy/mod_proxy.c (proxy_handler): Pass forward proxy
  credentials via r->notes.
  (add_proxy): Take credentials and base64-encode into ->creds field if
  passed.
  (add_proxy_noregex, add_proxy_regex): Take optional creds argument.

* modules/proxy/proxy_util.c (ap_proxy_determine_connection):
  Use proxy credentials from r->notes if available.
  (ap_proxy_create_hdrbrgd): Set Proxy-Authorization header from
  credentials in r->notes if present.

PR: 37355
Github: closes #135


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1881790 13f79535-47bb-0310-9956-ffa450edef68
2020-09-17 11:31:43 +00:00
Yann Ylavic
90d3807181 mod_proxy: follow up to r1879401: call filters on tunnel POLLERR.
proxy_util.c:
    Set POLLERR in reqevents for pollset providers that require it to detect
    socket errors (like select() based one).
    Call filters to read/write on POLLERR socket event, so that they know about
    the error by experiencing the failure. If no POLLIN|POLLOUT is returned
    with POLLERR (depending on the system or pollset provider), go with the
    requested read or write event handling.
    Restore ap_proxy_transfer_between_connections() so that it always tries to
    read first (i.e. move yielding conditions afterward).
    Add proxy_tunnel_forward() helper that calls transfer_between_connections()
    and handles errors pollset updates.
    Call proxy_tunnel_forward() when write completion finishes and there are
    pending input data.

mod_proxy.h:
    Add read_buf_size to proxy_tunnel_rec (trunk only, no MMN minor bump).



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1880200 13f79535-47bb-0310-9956-ffa450edef68
2020-07-23 12:00:04 +00:00
Yann Ylavic
b5faaa48c3 mod_proxy_http: handle async tunneling of Upgrade(d) protocols.
When supported by the MPM (i.e. "event"), provide async callbacks and let
them be scheduled by ap_mpm_register_poll_callback_timeout(), while the
handler returns SUSPENDED.

The new ProxyAsyncDelay directive (if positive) enables async handling,
while ProxyAsyncIdleTimeout determines the timeout applied on both ends
while tunneling.

Github: closes #126



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879419 13f79535-47bb-0310-9956-ffa450edef68
2020-07-02 00:14:26 +00:00
Yann Ylavic
3d5ace0a30 mod_proxy: improved and reentrant tunneling loop.
modules/proxy/mod_proxy.h:
    Rename AP_PROXY_TRANSFER_SHOULD_YIELD to AP_PROXY_TRANSFER_YIELD_PENDING
    and add AP_PROXY_TRANSFER_YIELD_MAX_READS.

modules/proxy/mod_proxy_http.c:
modules/proxy/mod_proxy_wstunnel.c:
    Removing of reqtimeout filter is now handled by ap_proxy_tunnel_create().

modules/proxy/proxy_util.c:
    ap_proxy_transfer_between_connections():
        Reorganize loop to break out early.
        When AP_PROXY_TRANSFER_YIELD_PENDING, if !ap_filter_should_yield() we
        still need to run and check ap_filter_output_pending() since it may
        release pending data.
        When AP_PROXY_TRANSFER_YIELD_MAX_READS, stop the loop after too much
        reads (PROXY_TRANSFER_MAX_READS = 10000) to release the thread and
        give the caller a chance to schedule the other direction.
        Don't return APR_INCOMPLETE when it comes from an incomplete body
        detected by ap_http_filter().

    ap_proxy_tunnel_create():
        Start with POLLOUT on both directions so that any pending output data
        is flushed first.

    ap_proxy_tunnel_run():
        Remove re-init/clear of the pollset for each call so that the function
        is reentrant.
        Handle POLLOUT before POLLIN so that we can read in the same pass once
        all buffered output data are flushed, using ap_filter_input_pending()
        to drain buffered input data.

This is preparatory patch for async websocket tunneling is mod_proxy_http.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879401 13f79535-47bb-0310-9956-ffa450edef68
2020-07-01 16:35:48 +00:00
Yann Ylavic
eb4ba427a4 Follow up to r1879080 and r1879137: servlet-normalize r->uri if matched.
If a ProxyPass mapping=servlet matches (in pre_trans hook), update r->uri with
the servlet normalization so that later <Location> or any dir context match
does not have to handle potential path parameters.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879235 13f79535-47bb-0310-9956-ffa450edef68
2020-06-26 12:51:08 +00:00
Yann Ylavic
b11eb1d7a3 Follow up to r1879080: replace ProxyUseOriginalURI by mapping=encoded.
Instead of having a separate ProxyUseOriginalURI directive to control pre_ vs
normal translate stage, let's handle this at each ProxyPass level, with the
mapping= parameter.

At pre_translate stage mod_proxy will handle the "encoded" mapping only, and
at translate stage only the others (unless a worker was already elected at
the first stage).

Note that since mapping=servlet needs to happen encoded too, it's defined like:
    #define PROXYPASS_MAP_ENCODED 0x08
    #define PROXYPASS_MAP_SERVLET 0x18 /* + MAP_ENCODED */
so uch that proxy_trans does the right thing.

Follow up to r1879080: replace ProxyUseOriginalURI by mapping=encoded.

Instead of having a separate ProxyUseOriginalURI directive to control pre_ vs
normal translate stage, let's handle this at each ProxyPass level, with the
mapping= parameter.

At pre_translate stage mod_proxy will handle the "encoded" mapping only, and
at translate stage only the others (unless a worker was already elected at
the first stage).

Note that since mapping=servlet needs to happen encoded too, it's defined like:
    #define PROXYPASS_MAP_ENCODED 0x08
    #define PROXYPASS_MAP_SERVLET 0x18 /* + MAP_ENCODED */
so that proxy_trans does the right thing.

This allows for simpler and consistent mapping configuration, where the
translate stage depends only on the mapping= parameter.

To implement a fast path (do nothing) when no encoded mapping is configured
at pre_trans stage, or all mappings are encoded at translate stage, two bits
are added to proxy_server_conf (map_encoded_one:1, map_encoded_all:1) and
updated at load time. Thus MINOR is bumped too.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879145 13f79535-47bb-0310-9956-ffa450edef68
2020-06-24 10:16:06 +00:00
Yann Ylavic
8dc2bb6714 Follow up to r1879094: make use_original_uri signed for unsigned char archs.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879110 13f79535-47bb-0310-9956-ffa450edef68
2020-06-23 10:12:52 +00:00
Yann Ylavic
6917e54aad Follow up to r1879080: rename ProxyMappingDecoded to ProxyUseOriginalURI.
Same for proxy_dir_conf field.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879094 13f79535-47bb-0310-9956-ffa450edef68
2020-06-22 20:00:23 +00:00
Yann Ylavic
d8848084e3 Allow for proxy servlet mapping at pre_translate_name stage.
Provide alias_match_servlet(), the servlet counterpart of alias_match(),
which maps the request URI-path to the ProxyPass alias ignoring path
parameters, while still forwarding them (above the alias).

This is needed to proxy servlet URIs for application handled by Tomcat,
which can then make use of the path/segments parameters.

Github: closes #128



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1879080 13f79535-47bb-0310-9956-ffa450edef68
2020-06-22 10:37:41 +00:00
Yann Ylavic
1dc3c88d41 mod_proxy_http: handle Upgrade requests and upgraded protocol forwarding.
If the request Upgrade header matches the worker upgrade= parameter and
the backend switches the protocol, do the tunneling in mod_proxy_http.
This allows to keep the protocol to HTTP until the backend really
switches the protocol, and apply usual output filters.

When configured to forward Upgrade mechanism, we want the backend to be
able to announce its Upgrade protocol to the client (e.g. with 426
Upgrade Required response) and thus forward back the Upgrade header that
matches the one(s) configured in the worker upgrade= parameter.

modules/proxy/mod_proxy.h:
modules/proxy/proxy_util.c:
    ap_proxy_worker_can_upgrade(): added helper to determine whether a
    proxy worker is configured to forward an Upgrade protocol.

include/ap_mmn.h:
    Bump MMN minor for ap_proxy_worker_can_upgrade().

modules/proxy/mod_proxy.c:
    set_worker_param(): handle worker parameter upgrade=ANY as upgrade=*
    (should the "any" protocol scheme be something some day..).

modules/proxy/mod_proxy_wstunnel.c:
    proxy_wstunnel_handler(): use ap_proxy_worker_can_upgrade() to match
    the Upgrade header. Axe handling of upgrade=NONE, it makes no sense to
    Upgrade a connection if the client did not ask for it, nor to configure
    mod_proxy_wstunnel to use a worker with upgrade=NONE by the way.

modules/proxy/mod_proxy_http.c:
    proxy_http_req_t: add fields force10 (force HTTP/1.0) and upgrade (value
    of the Upgrade header sent by the client if it matches the configuration,
    NULL otherwise).
    proxy_http_handler(): use ap_proxy_worker_can_upgrade() to determine
    whether the request is electable for end to end protocol upgrading and set
    req->upgrade accordingly.
    terminate_headers(): handle Connection and Upgrade headers to send to the
    backend, according to req->force10 and req->upgrade set before.
    ap_proxy_http_prefetch(): use req->force10 and terminate_headers().
    send_continue_body(): added helper to send the body retained for end to
    end 100-continue handling.
    ap_proxy_http_process_response(): use ap_proxy_worker_can_upgrade() to
    match the response Upgrade header and forward it back if it matches the
    configured one(s). That is for 101 Switching Protocol obviously but also
    any other status code which is not overidden, at the backend wish. If the
    protocol is switching, create a proxy tunnel and run it, using the minimal
    timeout from the client or backend connection.

Github: closes #125



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1877646 13f79535-47bb-0310-9956-ffa450edef68
2020-05-12 12:20:57 +00:00
Eric Covener
a545608f83 PR63628: individual status codes for ProxyErrorOverride.
Support specifying the http status codes to be considered by ProxyErrorOverride 

Submitted By: Martin Drößler <mail martindroessler.de>
Committed By: covener



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1876404 13f79535-47bb-0310-9956-ffa450edef68
2020-04-11 21:19:08 +00:00
Mike Rumph
85760859ca Fix spelling errors found by codespell. [skip ci]
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1873985 13f79535-47bb-0310-9956-ffa450edef68
2020-02-13 18:15:57 +00:00
Yann Ylavic
124a26fb09 mod_proxy: Improve tunneling loop.
Support half closed connections and pending data draining (for protocols like
rsync). PR 61616.

When reading on one side goes faster than writing on the other side, the output
filters chain may start buffering data and finally block, which will break
bidirectional tunneling for some protocols.

To avoid this, proxy_tunnel_run() now stops polling/reading until pending data
are drained, and recovers appropriately.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1869420 13f79535-47bb-0310-9956-ffa450edef68
2019-11-05 16:41:14 +00:00
Yann Ylavic
3d3e03a63a mod_proxy: Add proxy check_trans hook.
This allows proxy modules to decline request handling at early stage.
Then mod_proxy_wstunnel can implement that hook to verify that an Upgrade
is requested, and otherwise hand over to mod_proxy_http.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1869399 13f79535-47bb-0310-9956-ffa450edef68
2019-11-05 12:43:29 +00:00
Yann Ylavic
641102d747 mod_proxy: factorize mod_proxy_{connect,wstunnel} tunneling code in proxy_util.
This commit adds struct proxy_tunnel_rec that contains the fields needed for a
poll() loop through the filters chains, plus functions ap_proxy_tunnel_create()
and ap_proxy_tunnel_run() to respectively initialize a tunnel and (re)start it.
 
Proxy connect and wstunnel modules now make use of this new API to avoid
duplicating logic and code.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1869338 13f79535-47bb-0310-9956-ffa450edef68
2019-11-03 15:48:53 +00:00
Ruediger Pluem
fadc83a84f Fix pool concurrency problems
Create a subpool of the connection pool for worker scoped DNS resolutions.
This is needed to avoid race conditions in using the connection pool by multiple
threads during ramp up.

Recheck after obtaining the lock if we still need to do things or if they
were already done by another thread while we were waiting on the lock.

* modules/proxy/proxy_util.c: Create a subpool of the connection pool for worker
  scoped DNS resolutions and use it.

* modules/proxy/mod_proxy.h: Define AP_VOLATILIZE_T and add dns_pool to
  struct proxy_conn_pool.

* modules/proxy/mod_proxy_ftp.c: Use dns_pool and consider that
  worker->cp->addr is volatile in this location of the code.

PR: 63503


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1868296 13f79535-47bb-0310-9956-ffa450edef68
2019-10-11 15:11:40 +00:00
Eric Covener
fece93508b restore use of global mutex under !APR_HAS_THREADS
followup to r1852442 which appears to have been too agressive in wrapping
blocks with #if APR_HAS_THREADS.  With !APR_HAS_THREADS a global mutex 
is a proc mutex.




git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1866145 13f79535-47bb-0310-9956-ffa450edef68
2019-08-30 11:58:41 +00:00
Eric Covener
b8df3343a1 no-op PROXY_THREAD_LOCK if !APR_HAS_THREADS
... instead of wrapping them in #if themselves in the C code.

r1852442 is a trunk-only change to make mod_proxy compile with !APR_HAS_THREADS.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1865936 13f79535-47bb-0310-9956-ffa450edef68
2019-08-26 13:55:40 +00:00
Yann Ylavic
0848891b92 mod_proxy: follow up to r1836588: configurable Proxy100Continue.
Add Proxy100Continue directive to allow for 100-continue forwarding opt-out.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1856036 13f79535-47bb-0310-9956-ffa450edef68
2019-03-22 09:53:29 +00:00
Stefan Sperling
3ee1b624b8 Make proxy modules compile if APR_HAS_THREADS is not defined.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1852442 13f79535-47bb-0310-9956-ffa450edef68
2019-01-29 12:28:35 +00:00
Jim Jagielski
43b8f2569b better struct layout ...
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1838941 13f79535-47bb-0310-9956-ffa450edef68
2018-08-24 19:46:57 +00:00
Jim Jagielski
56251065c2 optimize struct layout
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1838940 13f79535-47bb-0310-9956-ffa450edef68
2018-08-24 19:45:04 +00:00
Jim Jagielski
52412c8900 update field comment
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1838939 13f79535-47bb-0310-9956-ffa450edef68
2018-08-24 19:45:01 +00:00