|
myTinySQL v0.2.0-2-g5000098
A tiny SQL interpreter over fixed-width text files
|
Classes | |
| struct | Request |
| One HTTP request, split into the parts the server uses. More... | |
| class | Socket |
| Owns a socket descriptor and closes it when it goes out of scope (RAII). More... | |
Functions | |
| void | throwSystemError (std::string_view what) |
| Throws the error of the last failed system call. | |
| std::string_view | headerValue (std::string_view head, std::string_view name) |
| Finds a header's value in the raw request, ignoring the case of its name. | |
| Request | readRequest (int fd) |
| Reads one HTTP request: the request line, the headers and, if there is one, the body. | |
| void | sendAll (int fd, std::string_view data) |
Sends all of data, retrying until it is written or the client goes away. | |
| std::string | httpResponse (std::string_view status, std::string_view contentType, std::string_view body) |
| Builds a complete HTTP response. | |
| std::string | errorResponse (std::string_view status, std::string_view message) |
Builds a JSON error answer, e.g. {"error":"Not found"}. | |
| std::string_view | contentTypeFor (std::string_view name) |
| The content type of a file of the page, from its extension. | |
| bool | isSafeFileName (std::string_view name) |
Tells whether a requested file name is safe to serve from the web/ directory. | |
| std::string | serveFile (const ServerConfig &config, std::string_view name) |
Serves one file of the page from the web/ directory. | |
| std::string | runSql (const ServerConfig &config, std::string_view sql) |
Runs the SQL of a POST /api/sql request, logs it, and builds the JSON answer. | |
| std::string | listTables (const ServerConfig &config) |
Builds the JSON answer of GET /api/tables. Call it only while holding workMutex. | |
| std::string | clientAddress (const sockaddr_in &address) |
| Formats a client's IPv4 address. | |
| void | handleClient (const ServerConfig &config, int fd, const std::string &client) |
| Serves one connection: reads the request, answers it, and closes. | |
Variables | |
| constexpr std::size_t | kMaxRequestSize = 64 * 1024 |
| The largest request read (headers and body), in bytes; the rest is ignored. | |
| constexpr int | kIdleSeconds = 30 |
| How long a connection may stay silent before it is closed, in seconds. | |
| std::mutex | workMutex |
| Lets only one request at a time run SQL and write to the console. | |
| std::string tinysql::anonymous_namespace{Server.cpp}::clientAddress | ( | const sockaddr_in & | address | ) |
Formats a client's IPv4 address.
| address | The address returned by accept(). |
Definition at line 264 of file Server.cpp.
| std::string_view tinysql::anonymous_namespace{Server.cpp}::contentTypeFor | ( | std::string_view | name | ) |
The content type of a file of the page, from its extension.
| name | The file name, e.g. "app.js". |
Definition at line 193 of file Server.cpp.
| std::string tinysql::anonymous_namespace{Server.cpp}::errorResponse | ( | std::string_view | status, |
| std::string_view | message | ||
| ) |
Builds a JSON error answer, e.g. {"error":"Not found"}.
| status | The status line's code and text, e.g. "404 Not Found". |
| message | The error message. |
Definition at line 185 of file Server.cpp.
| void tinysql::anonymous_namespace{Server.cpp}::handleClient | ( | const ServerConfig & | config, |
| int | fd, | ||
| const std::string & | client | ||
| ) |
Serves one connection: reads the request, answers it, and closes.
The routes:
GET / and GET /<file>: the page, from the web/ directory;GET /api/tables: the tables and their columns, as JSON;POST /api/sql: runs the SQL in the body, answers with the results as JSON.A connection that sends nothing is closed without an answer; a POST elsewhere gets 404, other methods 405.
| config | The server settings. |
| fd | The connection. |
| client | The client's address, for the log. |
Definition at line 282 of file Server.cpp.
| std::string_view tinysql::anonymous_namespace{Server.cpp}::headerValue | ( | std::string_view | head, |
| std::string_view | name | ||
| ) |
Finds a header's value in the raw request, ignoring the case of its name.
| head | The request line and headers. |
| name | The header name, e.g. "content-length". |
Definition at line 95 of file Server.cpp.
| std::string tinysql::anonymous_namespace{Server.cpp}::httpResponse | ( | std::string_view | status, |
| std::string_view | contentType, | ||
| std::string_view | body | ||
| ) |
Builds a complete HTTP response.
| status | The status line's code and text, e.g. "200 OK". |
| contentType | The type of the body, e.g. "application/json". |
| body | The body. |
no-cache makes the browser ask again each time, so a change to a file in web/ shows up on the next reload. Definition at line 174 of file Server.cpp.
| bool tinysql::anonymous_namespace{Server.cpp}::isSafeFileName | ( | std::string_view | name | ) |
Tells whether a requested file name is safe to serve from the web/ directory.
| name | The name, without the leading /. |
app.js: letters, digits, ., - and _, not starting with .. This rules out .. and /, so no request can reach a file outside web/. Definition at line 207 of file Server.cpp.
| std::string tinysql::anonymous_namespace{Server.cpp}::listTables | ( | const ServerConfig & | config | ) |
Builds the JSON answer of GET /api/tables. Call it only while holding workMutex.
| config | The server settings. |
Definition at line 252 of file Server.cpp.
| Request tinysql::anonymous_namespace{Server.cpp}::readRequest | ( | int | fd | ) |
Reads one HTTP request: the request line, the headers and, if there is one, the body.
| fd | The connection. |
Definition at line 115 of file Server.cpp.
| std::string tinysql::anonymous_namespace{Server.cpp}::runSql | ( | const ServerConfig & | config, |
| std::string_view | sql | ||
| ) |
Runs the SQL of a POST /api/sql request, logs it, and builds the JSON answer.
Call it only while holding workMutex.
| config | The server settings. |
| sql | The statements, as sent in the request body. |
Definition at line 238 of file Server.cpp.
| void tinysql::anonymous_namespace{Server.cpp}::sendAll | ( | int | fd, |
| std::string_view | data | ||
| ) |
Sends all of data, retrying until it is written or the client goes away.
| fd | The connection. |
| data | The bytes to send. |
Definition at line 157 of file Server.cpp.
| std::string tinysql::anonymous_namespace{Server.cpp}::serveFile | ( | const ServerConfig & | config, |
| std::string_view | name | ||
| ) |
Serves one file of the page from the web/ directory.
| config | The server settings. |
| name | The file name; index.html for the page itself. |
Definition at line 218 of file Server.cpp.
| void tinysql::anonymous_namespace{Server.cpp}::throwSystemError | ( | std::string_view | what | ) |
Throws the error of the last failed system call.
| what | What was being done, e.g. "bind to port 8080". |
| std::system_error | Always, with the current errno. |
Definition at line 79 of file Server.cpp.
|
constexpr |
How long a connection may stay silent before it is closed, in seconds.
Browsers open connections early ("preconnect") and may send nothing on them for several seconds.
Definition at line 38 of file Server.cpp.
|
constexpr |
The largest request read (headers and body), in bytes; the rest is ignored.
Definition at line 33 of file Server.cpp.
| std::mutex tinysql::anonymous_namespace{Server.cpp}::workMutex |
Lets only one request at a time run SQL and write to the console.
Each connection is read in its own thread; this lock keeps the table files and the log from being mixed up.
Definition at line 43 of file Server.cpp.