myTinySQL v0.2.0-2-g5000098
A tiny SQL interpreter over fixed-width text files
Loading...
Searching...
No Matches
Classes | Functions | Variables
tinysql::anonymous_namespace{Server.cpp} Namespace Reference

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.
 

Function Documentation

◆ clientAddress()

std::string tinysql::anonymous_namespace{Server.cpp}::clientAddress ( const sockaddr_in &  address)

Formats a client's IPv4 address.

Parameters
addressThe address returned by accept().
Returns
The address as text, e.g. "192.168.1.10".

Definition at line 264 of file Server.cpp.

◆ contentTypeFor()

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.

Parameters
nameThe file name, e.g. "app.js".
Returns
The type to send in the Content-Type header.

Definition at line 193 of file Server.cpp.

◆ errorResponse()

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"}.

Parameters
statusThe status line's code and text, e.g. "404 Not Found".
messageThe error message.
Returns
The response.

Definition at line 185 of file Server.cpp.

◆ handleClient()

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.

Parameters
configThe server settings.
fdThe connection.
clientThe client's address, for the log.

Definition at line 282 of file Server.cpp.

◆ headerValue()

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.

Parameters
headThe request line and headers.
nameThe header name, e.g. "content-length".
Returns
The value without surrounding spaces, or an empty view if the header is missing.

Definition at line 95 of file Server.cpp.

◆ httpResponse()

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.

Parameters
statusThe status line's code and text, e.g. "200 OK".
contentTypeThe type of the body, e.g. "application/json".
bodyThe body.
Returns
The response, headers included. 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.

◆ isSafeFileName()

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.

Parameters
nameThe name, without the leading /.
Returns
True for plain names such as 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.

◆ listTables()

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.

Parameters
configThe server settings.
Returns
The response, or a 500 error if SYSTEM_TABLE cannot be read.

Definition at line 252 of file Server.cpp.

◆ readRequest()

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.

Parameters
fdThe connection.
Returns
The request. Its method is empty if the client sent nothing before the idle timeout, and the body is cut at kMaxRequestSize bytes.

Definition at line 115 of file Server.cpp.

◆ runSql()

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.

Parameters
configThe server settings.
sqlThe statements, as sent in the request body.
Returns
The response.

Definition at line 238 of file Server.cpp.

◆ sendAll()

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.

Parameters
fdThe connection.
dataThe bytes to send.

Definition at line 157 of file Server.cpp.

◆ serveFile()

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.

Parameters
configThe server settings.
nameThe file name; index.html for the page itself.
Returns
The response: the file, or 404 if the name is not safe or the file does not exist.

Definition at line 218 of file Server.cpp.

◆ throwSystemError()

void tinysql::anonymous_namespace{Server.cpp}::throwSystemError ( std::string_view  what)

Throws the error of the last failed system call.

Parameters
whatWhat was being done, e.g. "bind to port 8080".
Exceptions
std::system_errorAlways, with the current errno.

Definition at line 79 of file Server.cpp.

Variable Documentation

◆ kIdleSeconds

constexpr int tinysql::anonymous_namespace{Server.cpp}::kIdleSeconds = 30
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.

◆ kMaxRequestSize

constexpr std::size_t tinysql::anonymous_namespace{Server.cpp}::kMaxRequestSize = 64 * 1024
constexpr

The largest request read (headers and body), in bytes; the rest is ignored.

Definition at line 33 of file Server.cpp.

◆ workMutex

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.