123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- /* shttpd - accept HTTP connections
- Copyright (C) 2018 Ariadne Devos
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "worker.h"
- #include "fd.h"
- #include <sHT/bugs.h>
- #include <sHT/compiler.h>
- #include <sHT/nospec.h>
- #include <sHT/resource.h>
- #include <sHT/stream.h>
- #include <sHT/accept.h>
- #include <string.h>
- /* TODO: configuration, errno handling in task/accept.c, task/sockrw.c */
- static const char test_message[] =
- "HTTP/1.1 200 OK\r\n"
- "Server: sHTTPd\r\n"
- "Connection: Close\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Language: en\r\n"
- "\r\n"
- "Hello!";
- struct sHT_task_stream *
- sHT_accept_subtask(struct sHT_worker *worker, struct sHT_task_accept *task)
- {
- /* TODO: allow different settings for different TCP ports */
- return sHT_alloc(worker->free_streams);
- }
- void
- sHT_accept_abort(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *subtask)
- {
- sHT_free(worker->free_streams, subtask);
- }
- void
- sHT_accept_logic(struct sHT_worker *worker, struct sHT_task_accept *task, struct sHT_task_stream *subtask)
- {
- _Bool oops = sHT_init_stream(worker->papers, &subtask->stream);
- if (sHT_unlikely(sHT_test_hidden(oops, oops))) {
- /* XXX Spectre: what if this branch is ignored?
- Then a NULL paper might be written to,
- might be problematic. */
- sHT_close(subtask->stream.fd);
- sHT_free(worker->free_streams, subtask);
- return;
- }
- /* TODO: consider patching the kernel to allow 'reservation' of
- epoll events. TODO: reconsider this previous TODO. */
- oops = sHT_install_edge_trigger(worker->watches, subtask->stream.fd, &subtask->task);
- if (sHT_unlikely(sHT_test_hidden(oops, oops))) {
- /* Spectre: a speculatively missing watch isn't problematic.
- For a teeny while,
- the task won't run although it should be. */
- sHT_free_stream(worker->papers, &subtask->stream);
- sHT_close(subtask->stream.fd);
- sHT_free(worker->free_streams, subtask);
- return;
- }
- sHT_assert(subtask->stream.to_write.offset == 0);
- sHT_assert(subtask->stream.to_write.length == 0);
- sHT_assert(sizeof(test_message) <= sHT_PAPER_SIZE);
- memcpy(subtask->stream.to_write.first, test_message, sizeof(test_message));
- sHT_init_task(&subtask->task);
- subtask->task.epollflags |= EPOLLIN | EPOLLOUT;
- subtask->stream.to_write.length = sizeof(test_message);
- }
|