Commit Graph

1061 Commits

Author SHA1 Message Date
Joris Vink a9683caed5 missing header 2019-04-24 00:16:51 +02:00
Joris Vink 2c88bc6120 Add asynchronous libcurl support.
This commit adds the CURL=1 build option. When enabled allows
you to schedule CURL easy handles onto the Kore event loop.

It also adds an easy to use HTTP client API that abstracts away the
settings required from libcurl to make HTTP requests.

Tied together with HTTP request state machines this means you can
write fully asynchronous HTTP client requests in an easy way.

Additionally this exposes that API to the Python code as well
allowing you do to things like:

	client = kore.httpclient("https://kore.io")
	status, body = await client.get()

Introduces 2 configuration options:
	- curl_recv_max
		Max incoming bytes for a response.

	- curl_timeout
		Timeout in seconds before a transfer is cancelled.

This API also allows you to take the CURL easy handle and send emails
with it, run FTP, etc. All asynchronously.
2019-04-24 00:15:17 +02:00
Joris Vink c89ba3daa3 check http timeouts better 2019-04-12 14:26:47 +02:00
Joris Vink 612fc034fa remove debug 2019-04-11 20:54:29 +02:00
Joris Vink aa49e181b6 Add http_[header|body]_timeout.
If the HTTP request headers or the HTTP body have not arrived before
these timeouts expire, Kore will send a 408 back to the client.
2019-04-11 20:51:49 +02:00
Joris Vink a191445f76 set body length+offset to 0 when populating data.
otherwise this isn't properly picked up by http_body_read() later
if dealing with in-memory HTTP bodies and you get inconsistent behaviour.
2019-04-02 22:26:44 +02:00
Joris Vink 5d16a7a123 make sure stdint.h is always included.
unbreaks NOTLS=1 and NOSENDFILE=1 builds on several platforms.

reported by Sam on irc, thanks.
2019-03-29 19:25:27 +01:00
Joris Vink a66d259271 kill debug line 2019-03-29 19:15:10 +01:00
Joris Vink d2aa64df5c add kore_proctitle().
manipulates the argv+environ pointers to get a sensible process title
under linux / darwin.
2019-03-29 16:24:14 +01:00
Joris Vink 92fb4974b1 only deschedule if not -1. 2019-03-27 22:15:35 +01:00
Joris Vink 39ffa047ca remove dh parameter check at configure time.
this is done when the workers startup if a domain with tls was used.
2019-03-26 21:44:44 +01:00
Joris Vink e4caac9e0c Be more clear when an invalid TLS setup is found 2019-03-26 21:36:45 +01:00
Joris Vink bf42e56c7d kill whitespace 2019-03-26 20:24:46 +01:00
Joris Vink 4ca7f29649 Add a concurrency parameter to kore.gather() 2019-03-25 10:13:52 +01:00
Joris Vink e1766e74ba always capture worker processes exiting.
even if they terminated normally.
2019-03-22 10:29:14 +01:00
Joris Vink 4238431b9e Add worker_death_policy setting.
By default kore will restart worker processes if they terminate
unexpected. However in certain scenarios you may want to bring down
an entire kore instance if a worker process fails.

By setting worker_death_policy to "terminate" the Kore server will
completely stop if a worker exits unexpected.
2019-03-22 09:49:50 +01:00
Joris Vink cd80685d9d get rid of pyko 2019-03-21 21:37:16 +01:00
Joris Vink 58c2739dee If fd is -1 in pysock_op_iternext just return None.
None in pysock signals EOF and if it was closed under our feet we should
relay that properly.
2019-03-21 14:44:41 +01:00
Joris Vink 370041656e Get rid of WORKER_LOCK_TIMEOUT.
Instead let the workers send a message on the msg channel to each
other when they have given up the accept lock and it is now available
to be grabbed.
2019-03-21 14:03:11 +01:00
Joris Vink 8b0279879a rework timers so they fire more predictably.
this change also stops python coroutines from waking up very
late after their timeout has expired.

in filerefs, don't prime the timer until we actually have something
to expire, and kill the timer when the last ref drops.
2019-03-21 10:17:08 +01:00
Joris Vink ce012e7bd5 set fd to -1 on close. 2019-03-21 10:09:24 +01:00
Joris Vink d371454dad do not grab the result if it was in a gatherop 2019-03-19 13:58:00 +01:00
Joris Vink 8afaac9fde log pid number of worker upon start. 2019-03-19 13:42:22 +01:00
Joris Vink 681a88d535 simplify af_unix recvfrom/sendto support. 2019-03-19 13:27:50 +01:00
Erik Karlsson d60994abb5 add python sendto recvfrom abstract socket support 2019-03-19 11:11:44 +01:00
Joris Vink 9caa45a050 Allow python validator methods to be async. 2019-03-18 09:34:31 +01:00
Joris Vink c3ab570f56 Append full module path if it is a directory. 2019-03-16 16:13:52 +01:00
Joris Vink ec7c8b8e1d fix a few minor problems with pylock.
- when pylocks are deallocated we ended up deleting the wrong object.
- do not call Py_DECREF on the op when inside the op its iternext call.
2019-03-14 17:31:57 +01:00
Joris Vink 2217c7a2c8 pysock: call disable read/write only when needed 2019-03-14 09:27:13 +01:00
Joris Vink d41054bd26 remove the socket from the event queue on dealloc. 2019-03-13 16:01:42 +01:00
Joris Vink b06160c768 Make sure coros are woken up on eof. 2019-03-13 15:45:55 +01:00
Joris Vink 3b4574d791 Rework pysocket async/await.
Attach the events directly to the pysocket data structure instead of
one event per pysocket_op.

Makes the code easier, gives us a good performance boost and reduces
the number of system calls required when doing an await on a socket.
2019-03-13 11:07:15 +01:00
Joris Vink 01f9b4fcde Check for EAGAIN when calling connect(2).
Linux does this under certain conditions.
2019-03-12 20:04:08 +01:00
Joris Vink eb9b7f7b14 explicitly include sys/types.h
some smaller libc variants do not include this from sys/param.h.
2019-03-06 09:29:46 +01:00
Joris Vink 61863bfd3a kill recv() timer if we have data.
also reset any exception that is set when we have successfully
read data from a socket.
2019-03-04 16:37:25 +01:00
Joris Vink a0c203f507 remove norwegian debug 2019-03-01 20:57:31 +01:00
Joris Vink 31a9a70d5a cleanup. 2019-03-01 20:56:03 +01:00
Erik Karlsson 01c1a8f8f8 support AF_UNIX in recvfrom()/sendto() python sockets 2019-03-01 20:13:28 +01:00
Joris Vink 2057f4db58 sprinkle more kore_quiet around 2019-02-27 19:59:31 +01:00
Joris Vink 1ebd82969c Add timeout support to proc.recv() 2019-02-26 15:22:55 +01:00
Joris Vink f4cd70956b Add an optional timeout to socketop.recv(). 2019-02-25 10:35:00 +01:00
Joris Vink bf1e8e5ffb bump copyright to 2019 2019-02-22 16:57:28 +01:00
Joris Vink 3dbb80463a allow double quotes in kore.proc argument lists. 2019-02-22 16:56:34 +01:00
Joris Vink 66305e551a sig_recv is extern'd in kore.h 2019-02-11 14:01:25 +01:00
Joris Vink 8a8b08f1e6 use %u when logging worker_rlimit_nofiles 2019-02-11 14:00:28 +01:00
Joris Vink 429159ee3c reprime idle timer if SSL_accept() fails.
reported by Daniel Chavez (@dacechavez)
2019-02-08 15:40:00 +01:00
Joris Vink 8040103458 fix for multiple consumers for the async queues. 2019-01-22 11:23:59 +01:00
Joris Vink 39467847fb remove SSL_get_verify_result() check.
If peer verification is turned on this becomes part of the handshake
process anyway and SSL_accept() will fail when appropriate.
2019-01-21 10:36:50 +01:00
Joris Vink 3f083d6126 deal with crls being expired / not-yet-valid.
if a crl is expired or not-yet-valid SSL_get_verify_result()
will return these errors too so check for them explicitly
instead of depending on X509_V_OK.

found by @dacechavez
2019-01-19 11:49:54 +01:00
Joris Vink d1e87c1a54 deal with PyObject_CallObject() returning NULL. 2019-01-15 10:20:13 +01:00
Joris Vink d6b05bcff7 always force reload cert so we get a new x509 store.
Otherwise older OpenSSL or current LibreSSL will fail to add the new
CRL as they still match on subject name rather then hash of the CRL data.
2019-01-14 20:57:40 +01:00
Joris Vink 73cdbd1a01 Let CRLs be reloadable via keymgr.
With these changes CRLs can be reloaded like certificates
by sending a SIGUSR1 to the parent process.

Track mtime on both certificate files and CRL files as well
and only submit them to the workers if this has changed.
2019-01-14 11:41:50 +01:00
Joris Vink b07cc0237c Support recvfrom()/sendto() on kore python sockets. 2019-01-08 17:49:00 +01:00
Joris Vink a868ff2b25 wrap accesslog calls in !KORE_NO_HTTP. 2018-12-22 09:41:55 +01:00
Joris Vink 9aa0e95643 Rework accesslog handling.
Move away from the parent constantly hitting the disk for every
accesslog the workers are sending.

The workers will now write their own accesslogs to shared
memory before the parent will pick those up. The parent
will flush them to disk once every second or if they grow
larger then 1MB.

This removes the heavy penalty for having access logs
turned on when you are dealing with a large volume
of requests.
2018-12-22 09:25:00 +01:00
Joris Vink 0d6a188b01 close fd if we're a directory in filemap. 2018-12-17 16:22:36 +01:00
Joris Vink 61b385ae11 do not set CONN_CLOSE_EMPTY for 1.0 until we reply. 2018-11-30 22:12:43 +01:00
Joris Vink ce3b60b8c8 keep a reference around for tracer. 2018-11-29 09:53:26 +01:00
Joris Vink d9f543ef5b Allow user-supplied tracer callback. 2018-11-29 09:51:24 +01:00
Joris Vink b400fdcd9f include sys/param.h in python.c 2018-11-29 09:11:31 +01:00
Joris Vink fd1ab5879d KODEV_OUTPUT tells kodev the outdir of the binary.
eg:

$ env KODEV_OUTPUT=/tmp kodev build

will place the resulting binary under /tmp/<binary>
2018-11-28 14:24:42 +01:00
Joris Vink 8dd075e71c style 2018-11-28 14:22:27 +01:00
Joris Vink e3efeb9465 Move assets.h into object_dir. 2018-11-28 14:19:32 +01:00
Joris Vink c431c2bf72 Add support to obtain peer certificate from Python
This will return the DER encoded bytes representing the peer certificate.
2018-11-28 11:28:07 +01:00
Joris Vink 2d8874dd2a change accept threshold default to 16. 2018-11-16 11:37:09 +01:00
Joris Vink 4e70636269 Reduce accept lock accept lockout time to 100ms. 2018-11-16 11:35:53 +01:00
Joris Vink 5c8efde841 allow foo.method symbols in python.
this way you can create page handlers that reside inside
of other objects.

eg:

static / restapi.index
2018-11-16 11:07:21 +01:00
Joris Vink baafa4897e Add -q flag.
If specified Kore will run quietly and only log important messages.
2018-11-15 16:01:37 +01:00
Joris Vink cb482d8e8f Always use http_response_stream() in req.response.
Keep around the python bytes object while we stream the contents
of it out over the wire. This avoids an entire copy of the data.
2018-11-14 10:03:32 +01:00
Joris Vink 966eaf8f7a Add a kore_python_preinit() hook.
This is called before the python initialization is completed
and allows developers to inject their own built-in methods.
2018-11-12 09:01:05 +01:00
Joris Vink 3925ba60ad don't call close() no underlying socket. 2018-11-12 09:00:36 +01:00
Joris Vink 4cc9e216bb Don't call close() on the python socket on dealloc 2018-11-06 16:54:26 +01:00
Joris Vink 2dd66586ff several python improvements.
- add kore.time() as equivalent for kore_time_ms().
- call waitpid() until no more children are available for reaping otherwise
  we risk missing a process if several die at the same time and only one
  SIGCHLD is delivered to us.
- drain a RECV socket operation if eof is set but no exception was given.
2018-10-30 20:28:27 +01:00
Joris Vink 5456f2e1d5 save/restore coro_running in pygather_op_dealloc(). 2018-10-30 12:37:30 +01:00
Joris Vink 062c80c1ac start enforcing a mininum number of elms in pools. 2018-10-30 10:41:49 +01:00
Joris Vink 71c145932c grow kore_pools at a slower rate.
Before we just doubled in size the second we exhausted a pool instead
of doing a more controlled expansion.

Now we will expand at 25% of the initial elm count whenever we need to.

Will help with memory pressure in certain scenarios.
2018-10-30 10:36:18 +01:00
Joris Vink bb00deca2c don't leak op in error path 2018-10-29 21:18:38 +01:00
Joris Vink 1c30da855c Add kore.gather() to the python api.
Allows one to run coroutines concurrently and gather all their
results in a single returned list.

If any of the coroutines throw an exception the exception is
returned as the value of that coroutine in the returned list.
2018-10-29 21:16:08 +01:00
Joris Vink 740acb4760 make sure we can still build vs 1.1.0 2018-10-29 21:11:29 +01:00
Joris Vink 818c7847cd simplify even more 2018-10-29 20:43:40 +01:00
Joris Vink ae72b21d35 make sure older openssl/libressl builds work. 2018-10-29 20:42:28 +01:00
Joris Vink 339df66fd5 Add support for TLS 1.3 via OpenSSL 1.1.1.
This commit removes TLS 1.0 support no matter what OpenSSL
you are linking against.

Changes the value of tls_version from 1.2 to both. Meaning if
you link with OpenSSL 1.1.1 you will get 1.2 + 1.3.
2018-10-29 20:38:58 +01:00
Joris Vink dda2e1fb2c Some things still talk http/1.0. 2018-10-26 21:24:51 +02:00
Joris Vink e2651889e0 Add asynchronous subprocess support.
This adds kore.proc to the python runtime allowing async processing
handling:

The kore.proc method takes the command to run and an optional timeout
parameter in milliseconds. If the process did not exit normally after
that amount of time a TimeoutError exception is raised.

For instance:

async def run(cmd):
	proc = kore.proc(cmd, 1000)

	try:
		await proc.send("hello")
		proc.close_stdin()
	except TimeoutError:
		proc.kill()

	retcode = await proc.reap()

	return retcode
2018-10-26 19:19:47 +02:00
Joris Vink ea7ea48840 actually just query for HW_NCPU on all BSDs. 2018-10-25 19:31:48 +02:00
Joris Vink 9d9e9dcec2 set cpu_count to 1 for unknown BSDs 2018-10-25 19:30:10 +02:00
Joris Vink 892814e353 Add kore_[parent|worker]_teardown().
If exists these functions are called when the worker is exiting
and when right before the parent exists.

Allows for cleanup code for applications if need to do cleanup on exit.
2018-10-23 21:46:34 +02:00
Joris Vink fc5fc4f4ab make sure timers don't go out of scope. 2018-10-23 21:36:19 +02:00
Joris Vink 8ea32983ae Add kore.suspend(delay) to python.
Will suspend the coroutine for a number of milliseconds.

Example:

async def page(req):
	await kore.suspend(1000)
	req.response(200, b'')
2018-10-23 21:32:08 +02:00
Joris Vink 47776a9fbb Hook kore timers into python. 2018-10-23 20:44:43 +02:00
Joris Vink c41c1db303 Add kore_shutdown().
Allows workers to cleanly initiate a shutdown of the
entire server process.
2018-10-23 19:49:42 +02:00
Joris Vink 4c35073232 Use number of cpu cores if no worker count is set. 2018-10-22 21:27:17 +02:00
Joris Vink b70d1ee80f Add a locking mechanism in pykore.
Support the async with syntax:

	lock = kore.lock()

	async with lock:
		# your block

Fix some small issues with other parts of the python system.
2018-10-22 20:09:23 +02:00
Joris Vink 1ac131c48f If we hit the accept threshold, unlock worker. 2018-10-22 09:01:05 +02:00
Joris Vink 8be316ac0c Let kore_worker_make_busy() set next_lock. 2018-10-22 09:00:55 +02:00
Joris Vink fad5c6ea6f Give pyqueues "popnow". 2018-10-22 08:28:03 +02:00
Joris Vink c8795b7d7f pyqueue improvements.
- cleanup queue if it gets deallocated.
- make sure waitables on a queue get removed if their pyqueue_op dies.
2018-10-21 21:58:34 +02:00
Joris Vink 4ae3d23c7e s/INCREF/DECREF 2018-10-18 22:24:58 +02:00
Joris Vink 0cda9ecfb0 Add an asynchronous queue mechanism.
This allows coroutines to submit messages to and pop
messages from a queue in an asynchronous way.
2018-10-18 22:15:21 +02:00
Joris Vink b5958f7d7d Add kore_parent_daemonized().
This is called for single binaries after the parent
process has called daemon().

Also fix kore_parent_configure() for !single binaries.
2018-10-18 17:18:41 +02:00