introduced in 88153e944f.
when connect method is used (HTTPS), and e.g. a filtered domain requested,
there's no data on readfds, only on writefds.
this caused the response from the connection to hang until the timeout was
hit. in the past in such scenario always a "no entity" response
was produced in tinyproxy logs.
tested with 32K acl rules, generated by
for x in `seq 128` ; do for y in `seq 255` ; do \
echo "Deny 10.$x.$y.0/24" ; done ; done
after loading the config (which is dogslow too), tinyproxy
required 9.5 seconds for the acl check on every request.
after switching the list implementation to sblist, a request
with the full acl check now takes only 0.025 seconds.
the time spent for loading the config file is identical for both
list implementations, roughly 30 seconds.
(in a previous test, 65K acl rules were generated, but every
connection required almost 2 minutes to crunch through the list...)
get_request_entity() is only called on error, for example if a client
doesn't pass a check_acl() check. in such a case it's possible that
the client fd isn't yet ready to read from.
using select() with a timeout timeval of {0,0} causes it to return
immediately and return 0 if there's no data ready to be read.
this resulted in immediate connection termination rather than returning
the 403 access denied error page to the client and a confusing
"no entity" message displayed in the proxy log.
the code wrongly processed the site_spec (here: domain) parameter
only when PT_TYPE == PT_NONE.
re-arranged code to process it correctly whenever passed.
additionally the mask is now also applied to the passed subnet/ip,
so a site_spec like 127.0.0.1/8 is converted into 127.0.0.0/8.
also the case where inet_aton fails now produces a proper error
message.
note that the code still doesn't process ipv6 addresses and mask.
to support it, we should use the existing code in acl.c and refactor
it so it can be used from both call sites.
closes#83closes#165
previously, in order to detect and insert {variables} into error/stats
templates, tinyproxy iterated char-by-char over the input file, and would
try to parse anything inside {} pairs and treat it like a variable name.
this breaks CSS, and additionally it's dog slow as tinyproxy wrote every
single character to the client via a write syscall.
now we process line-by-line, and inspect all matches of the regex
\{[a-z]{1,32}\}. if the contents of the regex are a known variable name,
substitution is taking place. if not, the contents are passed as-is to
the client. also the chunks before and after matches are written in
a single syscall.
closes#108
it's quite unexpected for an application running foreground in a
terminal to keep running when the terminal is closed.
also in such a case (if file logging is disabled) there's no way to
see what's happening to the proxy.
fixes an error in travis, which makes a shallow clone of 50 commits.
if the last tag is older than 50 commits, we get:
"fatal: No names found, cannot describe anything."
this caused a premature exit due to an assert error in safe_write()
on this line: assert (count > 0);
because the version variable in tinyproxy was empty.
inet_ntoa() uses a static buffer and is therefore not threadsafe.
additionally it has been deprecated by POSIX.
by using inet_ntop() instead the code has been made ipv6 aware.
note that this codepath was only entered in the unlikely event that
no hosts header was being passed to the proxy, i.e. pre-HTTP/1.1.
* check return values of memory allocation and abort gracefully
in out-of-memory situations
* use sblist (linear dynamic array) instead of linked list
- this removes one pointer per filter rule
- removes need to manually allocate/free every single list item
(instead block allocation is used)
- simplifies code
* remove storage of (unused) input rule
- removes one char* pointer per filter rule
- removes storage of the raw bytes of each filter rule
* add line number to display on out-of-memory/invalid regex situation
* replace duplicate filter_domain()/filter_host() code with a single
function filter_run()
- reduces code size and management effort
with these improvements, >1 million regex rules can be loaded with
4 GB of RAM, whereas previously it crashed with about 950K.
the list for testing was assembled from
http://www.shallalist.de/Downloads/shallalist.tar.gzcloses#20
the file docs/filter-howto.txt was removed, as it contained misleading
information since it was first checked in.
it suggests the syntax for filter rules is fnmatch()-like, when in
fact they need to be specified as posix regular expressions.
additionally it contained a lot of utterly unrelated and irrelevant/
outdated text.
a few examples with the correct syntax have now been added to
tinyproxy.conf.5 manpage.
closes#212
it turned out that the upstream section in tinyproxy.conf.5 wasn't rendered
properly, because in asciidoc items following a list item are always explicitly
appended to the last list item.
after several hours of finding a workaround, it was decided to change the
manpage generator to pod2man instead.
as pod2man ships together with any perl base install, it should be available
on almost every UNIX system, unlike asciidoc which requires installation
of a huge set of dependencies (more than 1.3 GB on Ubuntu 16.04), and the
replacement asciidoctor requires a ruby installation plus a "gem" (which is
by far better than asciidoc, but still more effort than using the already
available pod2man).
tinyproxy's hard requirement of a2x (asciidoctor) for building from source
caused rivers of tears (and dozens of support emails/issues) in the past, but
finally we get rid of it. a tool such as a2x with its XML based bloat-
technology isn't really suited to go along with a supposedly lightweight
C program.
if it ever turns out that even pod2man is too heavy a dependency, we could
still write our own replacement in less than 50 lines of awk, as the pod
syntax is very low level and easy to parse.
using --disable-manpage-support it's finally possibly to disable
the formerly obligatory use of a2x to generate the manpage
documentation.
this is the final solution to the decade old problem that users need
to install the enormous asciidoc package to compile TINYproxy from
source, or otherwise get a build error, even though the vast majority
is only interested in the program itself.
solution was inspired by PR #179.
closes#179closes#111
note that since 1.10.0 release the generated release tarball includes
the generated manpages too; in which case neither the use of a2x
nor --disable-manpage-support is required.
xsltproc was once[1] used to generate AUTHORS from xml input, but
fortunately this is no longer the case.
[1]: in a time when everybody thought XML would be a Good Idea (TM)
distcheck chokes on man5/8 files still in the file tree, while the input
files (.txt) are not. these are generated by the configure script and
it would require quite some effort to get this test working.
as it is non-essential, we simply disable it.
according to https://www.gnu.org/prep/standards/html_node/Standard-Targets.html#Standard-Targets
`maintainer-clean` is the proper make target for files that are distributed
in a release tarball:
> The ‘maintainer-clean’ target is intended to be used by a maintainer of the
> package, not by ordinary users.
> You may need special tools to reconstruct some of the files that
> ‘make maintainer-clean’ deletes.
this prevents users without a2x or asciidoctor from losing their ability to
recompile tinyproxy after `make clean`, but it also means that users wanting
to regenerate the documentation need to run `make maintainer-clean`.
otherwise object files will not be rebuilt with the new configure options.
this will prevent cases like db4bd162a3
where it turned out there was a build error with --enable-debug since several
git revisions.
asciidoctor is a modern replacement for asciidoc and much more lightweight,
issuing "apt-get install asciidoc" on ubuntu 16.04 results in an attempt to
install more than 1.3 GB of dependencies.
the timeout option set by the config file wasn't respected at all
so it could happen that connections became stale and were never released,
which eventually caused tinyproxy to hit the limit of open connections and
never accepting new ones.
addresses #274
getsockname() requires addrlen to be set to the size of the sockaddr struct
passed as the addr, and a check whether the returned addrlen exceeds the
initially passed size (to determine whether the address returned is truncated).
with a request like "GET /\r\n\r\n" where length is 0 this caused the code
to assume success and use the values of the uninitialized sockaddr struct.
unlike other functions called from the config parser code,
anonymous_insert() accesses the global config variable rather than
passing it as an argument. however the global variable is only set
after successful loading of the entire config.
we fix this by adding a conf argument to each anonymous_* function,
passing the global pointer in calls done from outside the config
parser.
fixes#292