As given in the config, we match a regex of hosts to a canonical host
which points to an internal directory.
Regexes are compiled on initialization, so we can error out early.
The rest is just modifications to use relative directories rather than
absolute ones, as we chdir() into the vhost directories dynamically.
Given we normalize the targets beforehand, there is no danger of
malformed requests escaping the vhost-context.
this fixes the lower and upper offset and adds a 416 (range not satisfiable
status). It returns the filesize if it cannot be satisfied as the standard
suggests so the client can do something.
the range check was done after the check lower > upper
so if it meets these conditions: lower <= upper and
lower > st.st_size then lower could still be > upper.
sort in order: directory or non-directory, filename (case-sensitive).
show filetypes after filename:
- / for directory
- @ for symlink
- | for pipe
- = for socket
- etc
The approach with lastp only works if we only go back one dir at a time.
Of course, this cannot be assumed, so we traverse the path backwards
looking for the previous /.
Compiled against musl, quark will not work as musl needs the presence
of procfs to process paths in realpath().
We could wait for it to be implemented[0] or also notice that we don't
want to overengineer the target-resolving. I don't think it's very
suckless if we deploy such a huge infrastructure to resolve paths.
To counteract this and given there are no good solutions available, I
set out to write the function normabspath(), which normalizes an
absolute path.
It is idempotent and works on the buffer passed to it. We don't need a
target, as the resulting resolved path is guaranteed to be of equal
length or shorter. This requires a memcpy in our case before calling it,
but I see it as a nice demonstration of the possibilities and it might
prove to be useful for other projects.
Not requiring a target buffer (that needs to have its length specified),
the one-string-call also simplifies the calling semantics drasticly.
With this function in place, quark works with musl. Statically linked,
stripped and with -Os, it only weighs 102K.
[0]: http://www.openwall.com/lists/musl/2016/11/03/5
The aim was to write quark without any mallocs. This was successful, but
proved to be a bit ugly looking at how we construct data to be sent.
Before this change, we had static buffers in each function that needed
them and filled them up, possibly risking overflow.
After that, we sent them off using our own function sendbuffer(), which
in itself represented a buffering mechanism.
Using dprintf, which is POSIX 2008, we can send things off directly,
with no need for sendbuffer() or buffers for these things.
This way we can factor out sendbuffer(), dropping a few more LOCs.
Thanks Hiltjo for the suggestion!
I noticed that the data structures didn't allow a flexible handling of
the code while trying to extend it to support if-modified-since-responses.
To tackle this, I refactored the data structures and proceeded to
rewrite the server from the ground up, implementing all present features
plus fixing a lot of bugs and introducing the 304 header handling as
requested by many people.
Please report bugs if you find them.
While at it, I refactored the build system as well and updated all
surrounding files respectively.
Roughly 700 LOC (half of the old quark on the Hiltjo branch) in size,
this rewrite supports partial content and other good stuff that will
make it fun again to use quark for simple static purposes.
The error checking is rigorous and strict and it will report proper
error codes back to the client whenever there was a problem or the
request was invalid in some way.
A cool feature is the support for listening on a UNIX-domain socket,
which will in the long run allow us to solve problems with virtual hosts
and other things in separate programs. But until then, this should be
robust enough for most use-cases.
This resets quark's version to 0, but this was no problem as there
haven't been any quark releases yet.
Feedback is appreciated.