2018-02-04 20:27:33 +00:00
|
|
|
/* See LICENSE file for copyright and license details. */
|
|
|
|
#ifndef HTTP_H
|
|
|
|
#define HTTP_H
|
|
|
|
|
|
|
|
#include <limits.h>
|
2020-08-29 11:02:51 +00:00
|
|
|
#include <sys/socket.h>
|
2018-02-04 20:27:33 +00:00
|
|
|
|
2020-08-17 09:37:25 +00:00
|
|
|
#include "util.h"
|
|
|
|
|
2018-02-04 20:27:33 +00:00
|
|
|
#define HEADER_MAX 4096
|
|
|
|
#define FIELD_MAX 200
|
|
|
|
|
|
|
|
enum req_field {
|
|
|
|
REQ_HOST,
|
|
|
|
REQ_RANGE,
|
2020-08-05 13:46:03 +00:00
|
|
|
REQ_IF_MODIFIED_SINCE,
|
2018-02-04 20:27:33 +00:00
|
|
|
NUM_REQ_FIELDS,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const char *req_field_str[];
|
|
|
|
|
|
|
|
enum req_method {
|
|
|
|
M_GET,
|
|
|
|
M_HEAD,
|
|
|
|
NUM_REQ_METHODS,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const char *req_method_str[];
|
|
|
|
|
|
|
|
struct request {
|
|
|
|
enum req_method method;
|
2020-08-22 21:37:08 +00:00
|
|
|
char uri[PATH_MAX];
|
2018-02-04 20:27:33 +00:00
|
|
|
char field[NUM_REQ_FIELDS][FIELD_MAX];
|
|
|
|
};
|
|
|
|
|
|
|
|
enum status {
|
|
|
|
S_OK = 200,
|
|
|
|
S_PARTIAL_CONTENT = 206,
|
|
|
|
S_MOVED_PERMANENTLY = 301,
|
|
|
|
S_NOT_MODIFIED = 304,
|
|
|
|
S_BAD_REQUEST = 400,
|
|
|
|
S_FORBIDDEN = 403,
|
|
|
|
S_NOT_FOUND = 404,
|
|
|
|
S_METHOD_NOT_ALLOWED = 405,
|
|
|
|
S_REQUEST_TIMEOUT = 408,
|
|
|
|
S_RANGE_NOT_SATISFIABLE = 416,
|
|
|
|
S_REQUEST_TOO_LARGE = 431,
|
|
|
|
S_INTERNAL_SERVER_ERROR = 500,
|
|
|
|
S_VERSION_NOT_SUPPORTED = 505,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const char *status_str[];
|
|
|
|
|
2020-08-05 11:41:44 +00:00
|
|
|
enum res_field {
|
|
|
|
RES_ACCEPT_RANGES,
|
|
|
|
RES_ALLOW,
|
|
|
|
RES_LOCATION,
|
|
|
|
RES_LAST_MODIFIED,
|
|
|
|
RES_CONTENT_LENGTH,
|
|
|
|
RES_CONTENT_RANGE,
|
|
|
|
RES_CONTENT_TYPE,
|
|
|
|
NUM_RES_FIELDS,
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const char *res_field_str[];
|
|
|
|
|
2020-08-22 07:24:57 +00:00
|
|
|
enum res_type {
|
2020-08-22 21:20:00 +00:00
|
|
|
RESTYPE_ERROR,
|
2020-08-22 07:24:57 +00:00
|
|
|
RESTYPE_FILE,
|
2020-08-22 21:20:00 +00:00
|
|
|
RESTYPE_DIRLISTING,
|
2020-08-22 07:24:57 +00:00
|
|
|
NUM_RES_TYPES,
|
|
|
|
};
|
|
|
|
|
2020-08-05 11:41:44 +00:00
|
|
|
struct response {
|
2020-08-22 07:24:57 +00:00
|
|
|
enum res_type type;
|
2020-08-05 11:41:44 +00:00
|
|
|
enum status status;
|
|
|
|
char field[NUM_RES_FIELDS][FIELD_MAX];
|
2020-08-22 21:20:00 +00:00
|
|
|
char uri[PATH_MAX];
|
2020-08-22 07:24:57 +00:00
|
|
|
char path[PATH_MAX];
|
|
|
|
struct {
|
|
|
|
size_t lower;
|
|
|
|
size_t upper;
|
|
|
|
} file;
|
|
|
|
};
|
|
|
|
|
2020-08-28 22:42:54 +00:00
|
|
|
extern enum status (* const body_fct[])(int, const struct response *);
|
|
|
|
|
2020-08-22 07:24:57 +00:00
|
|
|
enum conn_state {
|
|
|
|
C_VACANT,
|
|
|
|
C_RECV_HEADER,
|
|
|
|
C_SEND_HEADER,
|
2020-08-28 22:42:54 +00:00
|
|
|
C_SEND_BODY,
|
2020-08-22 07:24:57 +00:00
|
|
|
NUM_CONN_STATES,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct connection {
|
|
|
|
enum conn_state state;
|
|
|
|
int fd;
|
2020-08-29 11:02:51 +00:00
|
|
|
struct sockaddr_storage ia;
|
2020-08-22 07:24:57 +00:00
|
|
|
char header[HEADER_MAX]; /* general req/res-header buffer */
|
|
|
|
size_t off; /* general offset (header/file/dir) */
|
|
|
|
struct request req;
|
|
|
|
struct response res;
|
2020-08-05 11:41:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum status http_send_header(int, const struct response *);
|
2018-02-04 20:27:33 +00:00
|
|
|
enum status http_send_status(int, enum status);
|
2020-08-22 09:05:20 +00:00
|
|
|
enum status http_recv_header(int, char *, size_t, size_t *);
|
|
|
|
enum status http_parse_header(const char *, struct request *);
|
2020-08-28 20:48:32 +00:00
|
|
|
void http_prepare_response(const struct request *, struct response *,
|
|
|
|
const struct server *);
|
2020-08-28 20:32:47 +00:00
|
|
|
void http_prepare_error_response(const struct request *,
|
|
|
|
struct response *, enum status);
|
2020-08-28 22:42:54 +00:00
|
|
|
enum status http_send_body(int, const struct response *,
|
|
|
|
const struct request *);
|
2018-02-04 20:27:33 +00:00
|
|
|
|
|
|
|
#endif /* HTTP_H */
|