Commit Graph

8 Commits

Author SHA1 Message Date
Vladimir Dubrovin
292a855f34 Fix memory leaks found under AddressSanitizer
- readconfig() kept its line buffer and argument array on every error
  return, so each refused reload leaked them.
- A filter refusing a connection in filter_client (TLS: a failed
  handshake) was not kept, so its filter_clear never ran and the state
  it made was lost. makefilters() now clears it, and empties the slot
  first: a pooled worker's slot may hold the previous connection's.
- ssl_filter_close() freed the client CA paths but not the server ones,
  for every TLS service set up.
- Compiled patterns were never freed: an ACL's (pcre: and regex: host
  names), an httpsrv rule's. copyacl() shared them between the
  configuration's ACL and each service's copy; each copy now compiles
  its own, and freeacl() and freehttprules() free them.

What LeakSanitizer still reports is OpenSSL's per-thread random
generator state of pooled threads, released only by OpenSSL at exit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 796e9f8156)
2026-10-14 20:15:42 +03:00
Vladimir Dubrovin
9651848bf1 Fix the Watcom build, and UNC paths in httpsrv on Windows
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Waiting to run
Open Watcom has no struct _stat64 or _wstat64: its 64-bit stat is
struct _stati64 and _wstati64, so httpsrv.c did not compile there and
the 1.0.1 lite build had no binaries.

widepath() compared and wrote '\\\\', a two-character constant, for a
backslash: a UNC path (\\server\share) never took the \\?\UNC\ form,
and forward slashes became backslashes only because the constant was
truncated to its last byte.

The Watcom workflow passed although nmake failed; it now fails when
the build does or leaves no 3proxy.exe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 17:40:16 +03:00
Vladimir Dubrovin
1cea4fef4b Fix socket draining / lingering 2026-10-12 13:58:48 +03:00
Vladimir Dubrovin
f265ea0b52 Fix rewrite and over-long header handling on Windows
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Waiting to run
Update HTML documentation / docs (push) Has been cancelled
Update wiki / wiki (push) Has been cancelled
op_rewrite checked what it built with targetunsafe(), which describes a
path on this machine: on Windows it must name a drive or a share, so a
rewritten request path was refused and every rewrite rule failed there.
A rewrite produces a request path and is checked as one.

The header loop stopped at HTTPSRV_MAXHDR and answered anyway, leaving
the rest of the request in the stream for the next one to be read out
of. It refuses the request instead. A header longer than the buffer
arrives as several lines, so the count bounds what is read rather than
what a client may send in one header.

The test for the buffer growth after a PCRE rewrite sent its request
through to an httpsrv origin, which stops reading at that same cap; it
uses an origin which reads whatever it is sent, since what is under test
is the proxy in the middle.
2026-08-29 20:37:12 +03:00
Vladimir Dubrovin
ee0de3613a support proxypass in web server 2026-08-29 19:09:54 +03:00
Vladimir Dubrovin
9529a1dfcf http server implemented, pcre support for hostnames in acls implemented 2026-08-29 19:09:54 +03:00
Vladimir Dubrovin
488317da1d Read the request body before replying, and generate certificates portably
httpsrv parsed Content-Length and never read what followed. The reply is
followed by a close, and closing a socket that still holds unread data
resets the connection instead of ending it, so a POST could cost the client
the reply it was about to read. Windows does that reliably; the same test
passes on Linux and macOS, which is why it looked flaky. Drain the body,
bounded at a megabyte.

The test CA was built with -addext, which LibreSSL - the openssl on a stock
macOS - does not apply the same way, leaving a certificate that is not
usable as a CA and a client that cannot build a chain to it. Put the
extensions in a file both accept, and verify the generated chain before any
of it is handed to a proxy, so a failure there is not read as a fault in
the proxy.
2026-08-26 09:28:46 +03:00
Vladimir Dubrovin
3526759e59 implement small http server for admin and testing 2026-08-25 17:21:33 +03:00