serval-dna/httpd.h

313 lines
9.3 KiB
C
Raw Normal View History

2014-01-22 05:21:59 +00:00
/*
Serval DNA HTTP interface - common definitions
2014-01-22 05:21:59 +00:00
Copyright (C) 2013-2014 Serval Project Inc.
Copyright (C) 2017 Flinders University
2014-01-22 05:21:59 +00:00
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 2
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
2014-02-03 11:10:05 +00:00
#ifndef __SERVAL_DNA__HTTPD_H
#define __SERVAL_DNA__HTTPD_H
2014-01-22 05:21:59 +00:00
#include "http_server.h"
2014-10-31 03:13:23 +00:00
#include "keyring.h"
#include "overlay_address.h"
#include "meshms.h"
#include "os.h"
2014-01-22 05:21:59 +00:00
int is_httpd_server_running();
extern uint16_t httpd_server_port;
extern unsigned int current_httpd_request_count;
2014-01-22 05:21:59 +00:00
// Some non-standard MIME types for the Content-Type header
extern const struct mime_content_type CONTENT_TYPE_SID_HEX;
extern const struct mime_content_type CONTENT_TYPE_IDENTITY_HEX;
extern const struct mime_content_type CONTENT_TYPE_RHIZOME_BUNDLE_ID_HEX;
extern const struct mime_content_type CONTENT_TYPE_RHIZOME_BUNDLE_KEY_HEX;
extern const struct mime_content_type CONTENT_TYPE_RHIZOME_BUNDLE_SECRET_HEX;
extern const struct mime_content_type CONTENT_TYPE_RHIZOME_FILEHASH_HEX;
extern const struct mime_content_type CONTENT_TYPE_RHIZOME_MANIFEST;
2014-10-31 03:13:23 +00:00
enum list_phase { LIST_HEADER = 0, LIST_FIRST, LIST_ROWS, LIST_END, LIST_DONE };
struct form_buf_malloc {
char *buffer;
size_t size_limit; // == 0 means no limit
size_t buffer_alloc_size;
size_t length;
};
struct httpd_request;
2017-01-10 01:14:37 +00:00
struct meshmb_session;
int form_buf_malloc_init(struct form_buf_malloc *, size_t size_limit);
int form_buf_malloc_accumulate(struct httpd_request *, const char *partname, struct form_buf_malloc *, const char *, size_t);
void form_buf_malloc_release(struct form_buf_malloc *);
typedef struct httpd_request
2014-01-22 05:21:59 +00:00
{
struct http_request http; // MUST BE FIRST ELEMENT
/* Doubly-linked list of current requests. Used to pass triggers to requests.
*/
struct httpd_request *next;
struct httpd_request *prev;
2014-01-22 05:21:59 +00:00
/* For requests/responses that pertain to a single manifest.
*/
rhizome_manifest *manifest;
enum rhizome_payload_status payload_status;
struct rhizome_bundle_result bundle_result;
2014-01-22 05:21:59 +00:00
/* For requests/responses that contain one or two SIDs.
2014-01-22 05:21:59 +00:00
*/
sid_t sid1;
sid_t sid2;
2014-01-22 05:21:59 +00:00
/* For requests/responses that contain a Rhizome Bundle ID.
*/
rhizome_bid_t bid;
/* For requests/responses that contain a 64-bit unsigned integer (eg,
* manifest version, SQLite ROWID, byte offset).
*/
uint64_t ui64;
/* Trigger function for Rhizome bundle added.
*/
void (*trigger_rhizome_bundle_added)(struct httpd_request *, rhizome_manifest *);
2014-01-22 05:21:59 +00:00
/* Finaliser for union contents (below).
*/
void (*finalise_union)(struct httpd_request *);
2014-01-22 05:21:59 +00:00
/* Mutually exclusive response arguments.
*/
union {
/* For receiving Rhizome Direct import request
*/
struct {
// Which part is currently being received
const char *current_part;
// Temporary file currently current part is being written to
int part_fd;
// Which parts have already been received
bool_t received_manifest;
bool_t received_data;
// Name of data file supplied in part's Content-Disposition header, filename
// parameter (if any)
char data_file_name[MIME_FILENAME_MAXLEN + 1];
}
direct_import;
/* For receiving RESTful Rhizome insert request
*/
struct {
// Which part is currently being received
const char *current_part;
// For storing the "bundle-author" hex SID as we receive it
char author_hex[SID_STRLEN];
size_t author_hex_len;
sid_t author;
// For storing the "bundle-secret" hex as we receive it
char secret_text[RHIZOME_BUNDLE_SECRET_MAX_STRLEN];
size_t secret_text_len;
2014-01-22 05:21:59 +00:00
rhizome_bk_t bundle_secret;
// For storing the "bundle-id" hex as we receive it
char bid_text[RHIZOME_BUNDLE_ID_STRLEN];
size_t bid_text_len;
2014-01-22 05:21:59 +00:00
// The "force-new" parameter
char force_new_text[5]; // enough for "false"
size_t force_new_text_len;
2017-05-17 00:46:46 +00:00
2014-01-22 05:21:59 +00:00
// For storing the manifest text (malloc/realloc) as we receive it
struct form_buf_malloc manifest;
2014-01-22 05:21:59 +00:00
// For receiving the payload
uint64_t payload_size;
struct rhizome_write write;
2017-05-17 00:46:46 +00:00
// If this is really a (journal) append request
bool_t appending:1;
// Whether this is an import request
2017-05-17 00:46:46 +00:00
bool_t importing:1;
// Whether the Bundle ID and version were supplied on the command line
// (must be consistent with the supplied manifest); the supplied values are
// in 'bid' and 'ui64'.
bool_t verify_id_version:1;
2017-05-17 00:46:46 +00:00
// Which parts have already been received
bool_t received_author:1;
bool_t received_secret:1;
bool_t received_bundleid:1;
bool_t received_manifest:1;
bool_t received_payload:1;
bool_t force_new:1;
2014-01-22 05:21:59 +00:00
}
insert;
/* For responses that send part or all of a payload.
*/
struct rhizome_read read_state;
/* For responses that list identities in the keyring.
*/
struct {
enum list_phase phase;
2014-10-31 03:13:23 +00:00
keyring_iterator it;
}
sidlist;
/* For responses that list known subscribers, eg, routing table.
*/
struct {
enum list_phase phase;
subscriber_iterator it;
}
subscriberlist;
2014-01-22 05:21:59 +00:00
/* For responses that list manifests.
*/
struct {
enum list_phase phase;
2014-01-22 05:21:59 +00:00
uint64_t rowid_highest;
size_t rowcount;
time_ms_t end_time;
struct rhizome_list_cursor cursor;
}
rhlist;
/* For responses that list MeshMS conversations.
*/
struct {
enum list_phase phase;
size_t rowcount;
struct meshms_conversations *conv;
struct meshms_conversation_iterator iter;
}
mclist;
2014-01-22 05:21:59 +00:00
/* For responses that list MeshMS messages in a single conversation.
*/
struct {
2016-10-05 00:17:51 +00:00
struct meshms_position {
enum meshms_which_ply which_ply;
uint64_t offset;
uint64_t their_ack;
}
token,
current,
latest;
time_ms_t end_time;
enum list_phase phase;
size_t rowcount;
struct meshms_message_iterator iter;
unsigned dirty;
int finished;
}
msglist;
/* For responses that send a MeshMS / MeshMB message.
*/
struct {
// Which part is currently being received
const char *current_part;
// Which parts have already been received
bool_t received_message;
// The text of the message to send
struct form_buf_malloc message;
}
sendmsg;
struct{
struct message_ply_read ply_reader;
enum list_phase phase;
uint64_t start_offset;
uint64_t current_offset;
uint64_t end_offset;
size_t rowcount;
time_ms_t end_time;
time_s_t timestamp;
bool_t eof;
} plylist;
struct {
rhizome_bid_t bundle_id;
2017-03-08 00:03:50 +00:00
struct meshmb_activity_iterator *iterator;
2017-01-10 01:14:37 +00:00
struct meshmb_session *session;
uint8_t generation;
enum list_phase phase;
size_t rowcount;
time_ms_t end_time;
uint64_t start_ack_offset;
uint64_t current_ack_offset;
uint64_t current_msg_offset;
uint64_t end_ack_offset;
uint64_t end_msg_offset;
} meshmb_feeds;
struct {
int fd;
size_t offset;
}
file;
2014-01-22 05:21:59 +00:00
} u;
} httpd_request;
int httpd_server_start(const uint16_t port_low, const uint16_t port_high);
2014-01-22 05:21:59 +00:00
typedef int HTTP_HANDLER(httpd_request *r, const char *remainder);
2014-01-22 05:21:59 +00:00
struct http_handler {
const char *path;
HTTP_HANDLER *parser;
};
DECLARE_SECTION(struct http_handler, httpd);
#define DECLARE_HANDLER(PATH, FUNC) \
static HTTP_HANDLER FUNC;\
static struct http_handler __##FUNC IN_SECTION(httpd) = {\
.path=PATH,\
.parser=FUNC\
}
2014-01-22 05:21:59 +00:00
int is_http_header_complete(const char *buf, size_t len, size_t read_since_last_call);
int authorize_restful(struct http_request *r);
int http_response_content_type(httpd_request *r, uint16_t result, const char *what, const struct mime_content_type *ct);
int http_response_content_disposition(httpd_request *r, uint16_t result, const char *what, const char *type);
int http_response_form_part(httpd_request *r, uint16_t result, const char *what, const char *partname, const char *text, size_t textlen);
int http_response_init_content_range(httpd_request *r, size_t resource_length);
int accumulate_text(httpd_request *r, const char *partname, char *textbuf, size_t textsiz, size_t *textlenp, const char *buf, size_t len);
int rhizome_response_content_init_filehash(httpd_request *r, const rhizome_filehash_t *hash);
int rhizome_response_content_init_payload(httpd_request *r, rhizome_manifest *);
HTTP_CONTENT_GENERATOR rhizome_payload_content;
2014-01-22 05:21:59 +00:00
struct http_response_parts {
uint16_t code;
char *reason;
uint64_t range_start;
uint64_t content_length;
char *content_start;
};
#define HTTP_RESPONSE_CONTENT_LENGTH_UNSET UINT64_MAX
int unpack_http_response(char *response, struct http_response_parts *parts);
2014-02-03 11:10:05 +00:00
#endif // __SERVAL_DNA__HTTPD_H