1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- // SPDX-License-Identifier: GPL-3.0-or-later
- // Copyright © 2018-2019 Ariadne Devos
- /* s2 -- process HTTP input */
- #include "fd.h"
- #include "worker.h"
- #include <sHT/resource.h>
- #include <sHT/scheduling.h>
- #include <sHT/stream.h>
- #include <sHT/test.h>
- #include <errno.h>
- #include <stddef.h>
- #include <sys/epoll.h>
- #include <sys/socket.h>
- #define sHTTPd_DONE sHT_STREAM_USER1
- __attribute__((nonnull (1, 2)))
- static void
- sHTTPd_close_connection(struct sHT_worker *worker, struct sHT_task_stream *task)
- {
- sHT_close(task->stream.fd);
- sHT_free(worker->free_streams, task);
- }
- void
- sHT_socket_task(struct sHT_worker *worker, struct sHT_task_stream *task)
- {
- if (!sHT_and_any(task->task.epollflags, EPOLLIN | EPOLLOUT))
- return;
- /* @var{sHT_socket_mayread} and @var{sHT_socket_maywrite} don't
- leak information to the compiler, so no @var{sHT_test_hidden}
- magic is required. Their values may also speculatively be wrong,
- but it is merely advisory, improving performance by skipping
- code. */
- /* Read request headers */
- if (sHT_socket_mayread(task))
- sHT_socket_readsome_tcp(worker, task);
- /* Output headers, output response */
- if (sHT_socket_maywrite(task))
- sHT_socket_sendsome_tcp(worker, task);
- /* TODO: do HTTP */
- /* A graceful shutdown */
- if (sHT_zero_p(task->stream.to_write.length))
- /* The file descriptor remains intact, so no Spectre issues */
- shutdown(task->stream.fd, SHUT_WR);
- if (sHT_and_any(task->stream.flags, sHT_STREAM_RESET_GRACEFUL | sHT_STREAM_RESET_BLUNT | sHT_STREAM_WRITE_EOF | sHTTPd_DONE))
- sHTTPd_close_connection(worker, task);
- if (sHT_and_any(task->task.flags, sHT_TASK_SCHEDULE)) {
- task->task.flags &= ~sHT_TASK_SCHEDULE;
- sHT_qadd_try(&worker->todo.queue, &task->task);
- }
- }
|