/*! * restd_http_handler.h * * Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA * * @Author: NADAL Jean-Baptiste * @Date: 23/12/2019 * */ #ifndef _RESTD_HTTP_HANDLER_H #define _RESTD_HTTP_HANDLER_H /*------------------------------- INCLUDES ----------------------------------*/ /*----------------------------------------------------------------------------*\ | HTTP PROTOCOL SPECIFICS | \*----------------------------------------------------------------------------*/ /* HTTP PROTOCOL CODES */ #define HTTP_PROTOCOL_09 "HTTP/0.9" #define HTTP_PROTOCOL_10 "HTTP/1.0" #define HTTP_PROTOCOL_11 "HTTP/1.1" /* HTTP RESPONSE CODES */ #define HTTP_NO_RESPONSE (0) #define HTTP_CODE_CONTINUE (100) #define HTTP_CODE_OK (200) #define HTTP_CODE_CREATED (201) #define HTTP_CODE_NO_CONTENT (204) #define HTTP_CODE_PARTIAL_CONTENT (206) #define HTTP_CODE_MULTI_STATUS (207) #define HTTP_CODE_MOVED_TEMPORARILY (302) #define HTTP_CODE_NOT_MODIFIED (304) #define HTTP_CODE_Brestd_REQUEST (400) #define HTTP_CODE_UNAUTHORIZED (401) #define HTTP_CODE_FORBIDDEN (403) #define HTTP_CODE_NOT_FOUND (404) #define HTTP_CODE_METHOD_NOT_ALLOWED (405) #define HTTP_CODE_REQUEST_TIME_OUT (408) #define HTTP_CODE_GONE (410) #define HTTP_CODE_REQUEST_URI_TOO_LONG (414) #define HTTP_CODE_LOCKED (423) #define HTTP_CODE_INTERNAL_SERVER_ERROR (500) #define HTTP_CODE_NOT_IMPLEMENTED (501) #define HTTP_CODE_SERVICE_UNAVAILABLE (503) /* DEFAULT BEHAVIORS */ #define HTTP_CRLF "\r\n" #define HTTP_DEF_CONTENTTYPE "application/octet-stream" /*----------------------------------------------------------------------------*\ | TYPEDEFS | \*----------------------------------------------------------------------------*/ typedef struct restd_http_s restd_http_t; /*!< Hook type */ #define RESTD_HOOK_ALL (0) /*!< call on each and every phases */ #define RESTD_HOOK_ON_CONNECT (1) /*!< call right after the establishment of connection */ #define RESTD_HOOK_AFTER_REQUESTLINE (1 << 2) /*!< call after parsing request line */ #define RESTD_HOOK_AFTER_HEADER (1 << 3) /*!< call after parsing all headers */ #define RESTD_HOOK_ON_BODY (1 << 4) /*!< call on every time body data received */ #define RESTD_HOOK_ON_REQUEST (1 << 5) /*!< call with complete request */ #define RESTD_HOOK_ON_CLOSE (1 << 6) /*!< call right before closing or next request */ enum restd_http_request_status_e { RESTD_HTTP_REQ_INIT = 0, /*!< initial state */ RESTD_HTTP_REQ_REQUESTLINE_DONE, /*!< received 1st line */ RESTD_HTTP_REQ_HEADER_DONE, /*!< received headers completely */ RESTD_HTTP_REQ_DONE, /*!< received body completely. no more data expected */ RESTD_HTTP_ERROR, /*!< unrecoverable error found. */ }; /*----------------------------------------------------------------------------*\ | PUBLIC FUNCTIONS | \*----------------------------------------------------------------------------*/ extern restd_http_t *http_new(struct evbuffer *out); extern void http_free_cb(restd_conn_t *conn, void *userdata); extern int restd_http_handler(short event, restd_conn_t *conn, void *userdata); extern enum restd_http_request_status_e restd_http_get_status(restd_conn_t *conn); extern struct evbuffer *restd_http_get_inbuf(restd_conn_t *conn); extern struct evbuffer *restd_http_get_outbuf(restd_conn_t *conn); extern const char *restd_http_get_request_header(restd_conn_t *conn, const char *name); extern off_t restd_http_get_content_length(restd_conn_t *conn); extern size_t restd_http_get_content_length_stored(restd_conn_t *conn); extern void *restd_http_get_content(restd_conn_t *conn, size_t maxsize, size_t *storedsize); extern int restd_http_is_keepalive_request(restd_conn_t *conn); extern int restd_http_set_response_header(restd_conn_t *conn, const char *name, const char *value); extern const char *restd_http_get_response_header(restd_conn_t *conn, const char *name); extern int restd_http_set_response_code(restd_conn_t *conn, int code, const char *reason); extern int restd_http_set_response_content(restd_conn_t *conn, const char *contenttype, off_t size); extern size_t restd_http_response(restd_conn_t *conn, int code, const char *contenttype, const void *data, off_t size); extern size_t restd_http_send_header(restd_conn_t *conn); extern size_t restd_http_send_data(restd_conn_t *conn, const void *data, size_t size); extern size_t restd_http_send_chunk(restd_conn_t *conn, const void *data, size_t size); extern const char *restd_http_get_reason(int code); /*---------------------------------------------------------------------------*\ | DATA STRUCTURES | \*---------------------------------------------------------------------------*/ struct restd_http_s { // HTTP Request struct { enum restd_http_request_status_e status; /*!< request status. */ struct evbuffer *inbuf; /*!< input data buffer. */ // request line - available on REQ_REQUESTLINE_DONE. char *method; /*!< request method ex) GET */ char *uri; /*!< url+query ex) /data%20path?query=the%20value */ char *httpver; /*!< version ex) HTTP/1.1 */ char *path; /*!< decoded path ex) /data path */ char *query; /*!< query string ex) query=the%20value */ // request header - available on REQ_HEADER_DONE. qlisttbl_t *headers; /*!< parsed request header entries */ char *host; /*!< host ex) www.domain.com or www.domain.com:8080 */ char *domain; /*!< domain name ex) www.domain.com (no port number) */ off_t contentlength; /*!< value of Content-Length header.*/ size_t bodyin; /*!< bytes moved to in-buff */ } request; // HTTP Response struct { struct evbuffer *outbuf; /*!< output data buffer. */ bool frozen_header; /*!< indicator whether we sent header out or not */ // response headers int code; /*!< response status-code */ char *reason; /*!< reason-phrase */ qlisttbl_t *headers; /*!< response header entries */ off_t contentlength; /*!< content length in response */ size_t bodyout; /*!< bytes added to out-buffer */ } response; }; #endif /* _RESTD_HTTP_HANDLER_H */