If set, will call a given handler with the prototype of
`void body_chunk(struct http_request *req, const void *data, size_t len);`
for each chunk of the received HTTP body, allowing a developer to handle
it in their own way.
The incoming body is still being handled and retained in the same way
as before (in a kore_buf or temporary file).
While here, allow HTTP_STATUS_CONTINUE to work via http_response() and
make the handling of incoming HTTP header data a bit better.
Introduce an on_headers callback for routes, allowing one to inspect
the headers before the request is processed further.
Additionall,
Add a new way of obtaining HTTP headers. Much like http_argument_get_*()
functions, these new APIs allow you to fetch the data of an HTTP header
as a specified C type.
The new APIs are:
* http_request_header_int16()
* http_request_header_uint16()
* http_request_header_int32()
* http_request_header_uint32()
* http_request_header_int64()
* http_request_header_uint64()
* http_request_header_float()
* http_request_header_double()
Should make it easier to operate in HTTP header data in a safe way.
No need to always roll your own string to int conversion functions.
Routes are now configured in a context per route:
route /path {
handler handler_name
methods get post head
validate qs:get id v_id
}
All route related configurations are per-route, allowing multiple
routes for the same path (for different methods).
The param context is removed and merged into the route context now
so that you use the validate keyword to specify what needs validating.
Since its an HTTP response function it functions like http_response() but
takes a kore_json_item pointer that it will automatically convert to a kore_buf
and send/free using http_response_stream().
While here fix a problem with http_response_stream() which could end up
not calling the cb() in case of HTTP_METHOD_HEAD. Since the behaviour is
that it should call cb() when done it should do so immediately.
This is the same as http_response() except it will automatically
close the connection after the response is sent.
This is a bit easier than setting CONN_CLOSE_EMPTY yourself manually.
With the new process startup code we must handle the SIGSTOP
from the processes if seccomp_tracing is enabled. Otherwise
they just hang indefinitely and we assume they failed to start,
which is somewhat true.
Starting with the privsep config, this commit changes the following:
- Removes the root, runas, keymgr_root, keymgr_runas, acme_root and
acme_runas configuration options.
Instead these are now configured via a privsep configuration context:
privsep worker {
root /tmp
runas nobody
}
This is also configurable via Python using the new kore.privsep() method:
kore.privsep("worker", root="/tmp", runas="nobody", skip=["chroot"])
Tied into this we also better handle worker startup:
- Per worker process, wait until it signalled it is ready.
- If a worker fails at startup, display its last log lines more clearly.
- Don't start acme process if no domain requires acme.
- Remove each process its individual startup log message in favour
of a generalized one that displays its PID, root and user.
- At startup, log the kore version and built-ins in a nicer way.
- The worker processes now check things they need to start running
before signaling they are ready (such as access to CA certs for
TLS client authentication).
We always called kore_pgsql_query_param_fields() regardless if the
params keyword was specified or not, instead only use it if actual
parameters have been given.
Otherwise use the kore_pgsql_query() function directly to execute the query.
If set to True, will skip the chroot() of the Kore workers.
This can be handy in case you want to set your deployment target to
production or docker so you get user changes but you don't want
to chroot the processes.
Before each worker process would either directly print to stdout if
Kore was running in foreground mode, or syslog otherwise.
With this commit the workers will submit their log messages to the
parent process who will either put it onto stdout or syslog.
This change in completely under the hood and users shouldn't care about it.
Now you can set curlopt on kore.httpclient at both the
global httpclient object level and individual requests.
Eg:
client = kore.httpclient("https://kore.io",
curlopt={
kore.CURLOPT_VERBOSE: 1
}
)
status, body = await client.get(
curlopt={
kore.CURLOPT_VERBOSE: 0
}
)
Now you can specify the qs keyword in a route which can contain
validators for the query string.
Eg:
@kore.route("/", methods=["post"], qs={"id": "^[0-9]+$"})
def index:
...