1 |
siliconforks |
116 |
/* |
2 |
|
|
http-server.h - generic HTTP server |
3 |
|
|
Copyright (C) 2008 siliconforks.com |
4 |
|
|
|
5 |
|
|
This program is free software; you can redistribute it and/or modify |
6 |
|
|
it under the terms of the GNU General Public License as published by |
7 |
|
|
the Free Software Foundation; either version 2 of the License, or |
8 |
|
|
(at your option) any later version. |
9 |
|
|
|
10 |
|
|
This program is distributed in the hope that it will be useful, |
11 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
|
|
GNU General Public License for more details. |
14 |
|
|
|
15 |
|
|
You should have received a copy of the GNU General Public License along |
16 |
|
|
with this program; if not, write to the Free Software Foundation, Inc., |
17 |
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
18 |
|
|
*/ |
19 |
|
|
|
20 |
|
|
#ifndef HTTP_SERVER_H_ |
21 |
|
|
#define HTTP_SERVER_H_ |
22 |
|
|
|
23 |
|
|
#include <stdbool.h> |
24 |
|
|
#include <stdint.h> |
25 |
|
|
#include <stdlib.h> |
26 |
|
|
|
27 |
siliconforks |
125 |
#ifdef __MINGW32__ |
28 |
siliconforks |
116 |
#include <winsock2.h> |
29 |
siliconforks |
125 |
typedef int socklen_t; |
30 |
siliconforks |
116 |
#else |
31 |
siliconforks |
125 |
#include <arpa/inet.h> |
32 |
|
|
#include <netdb.h> |
33 |
siliconforks |
116 |
#include <netinet/in.h> |
34 |
siliconforks |
125 |
#include <sys/socket.h> |
35 |
|
|
#include <unistd.h> |
36 |
siliconforks |
116 |
typedef int SOCKET; |
37 |
siliconforks |
125 |
#define INVALID_SOCKET (-1) |
38 |
|
|
#define closesocket close |
39 |
siliconforks |
116 |
#endif |
40 |
|
|
|
41 |
|
|
#include "stream.h" |
42 |
|
|
|
43 |
|
|
#define HTTP_ACCEPT "Accept" |
44 |
|
|
#define HTTP_ACCEPT_CHARSET "Accept-Charset" |
45 |
|
|
#define HTTP_ACCEPT_ENCODING "Accept-Encoding" |
46 |
|
|
#define HTTP_ACCEPT_LANGUAGE "Accept-Language" |
47 |
|
|
#define HTTP_ACCEPT_RANGES "Accept-Ranges" |
48 |
|
|
#define HTTP_AGE "Age" |
49 |
|
|
#define HTTP_ALLOW "Allow" |
50 |
|
|
#define HTTP_AUTHORIZATION "Authorization" |
51 |
|
|
#define HTTP_CACHE_CONTROL "Cache-Control" |
52 |
|
|
#define HTTP_CONNECTION "Connection" |
53 |
|
|
#define HTTP_CONTENT_ENCODING "Content-Encoding" |
54 |
|
|
#define HTTP_CONTENT_LANGUAGE "Content-Language" |
55 |
|
|
#define HTTP_CONTENT_LENGTH "Content-Length" |
56 |
|
|
#define HTTP_CONTENT_LOCATION "Content-Location" |
57 |
|
|
#define HTTP_CONTENT_MD5 "Content-MD5" |
58 |
|
|
#define HTTP_CONTENT_RANGE "Content-Range" |
59 |
|
|
#define HTTP_CONTENT_TYPE "Content-Type" |
60 |
|
|
#define HTTP_DATE "Date" |
61 |
|
|
#define HTTP_ETAG "ETag" |
62 |
|
|
#define HTTP_EXPECT "Expect" |
63 |
|
|
#define HTTP_EXPIRES "Expires" |
64 |
|
|
#define HTTP_FROM "From" |
65 |
|
|
#define HTTP_HOST "Host" |
66 |
|
|
#define HTTP_IF_MATCH "If-Match" |
67 |
|
|
#define HTTP_IF_MODIFIED_SINCE "If-Modified-Since" |
68 |
|
|
#define HTTP_IF_NONE_MATCH "If-None-Match" |
69 |
|
|
#define HTTP_IF_RANGE "If-Range" |
70 |
|
|
#define HTTP_IF_UNMODIFIED_SINCE "If-Unmodified-Since" |
71 |
|
|
#define HTTP_LAST_MODIFIED "Last-Modified" |
72 |
|
|
#define HTTP_LOCATION "Location" |
73 |
|
|
#define HTTP_MAX_FORWARDS "Max-Forwards" |
74 |
|
|
#define HTTP_PRAGMA "Pragma" |
75 |
|
|
#define HTTP_PROXY_AUTHENTICATE "Proxy-Authenticate" |
76 |
|
|
#define HTTP_PROXY_AUTHORIZATION "Proxy-Authorization" |
77 |
|
|
#define HTTP_RANGE "Range" |
78 |
|
|
#define HTTP_REFERER "Referer" |
79 |
|
|
#define HTTP_RETRY_AFTER "Retry-After" |
80 |
|
|
#define HTTP_SERVER "Server" |
81 |
|
|
#define HTTP_TE "TE" |
82 |
|
|
#define HTTP_TRAILER "Trailer" |
83 |
|
|
#define HTTP_TRANSFER_ENCODING "Transfer-Encoding" |
84 |
|
|
#define HTTP_UPGRADE "Upgrade" |
85 |
|
|
#define HTTP_USER_AGENT "User-Agent" |
86 |
|
|
#define HTTP_VARY "Vary" |
87 |
|
|
#define HTTP_VIA "Via" |
88 |
|
|
#define HTTP_WARNING "Warning" |
89 |
|
|
#define HTTP_WWW_AUTHENTICATE "WWW-Authenticate" |
90 |
|
|
|
91 |
|
|
typedef struct HTTPHeader { |
92 |
|
|
char * name; |
93 |
|
|
char * value; |
94 |
|
|
struct HTTPHeader * next; |
95 |
|
|
} HTTPHeader; |
96 |
|
|
|
97 |
|
|
typedef struct HTTPMessage HTTPMessage; |
98 |
|
|
|
99 |
|
|
typedef struct HTTPExchange HTTPExchange; |
100 |
|
|
|
101 |
|
|
typedef struct HTTPConnection HTTPConnection; |
102 |
|
|
|
103 |
|
|
typedef void (*HTTPServerHandler)(HTTPExchange * exchange); |
104 |
|
|
|
105 |
|
|
/* HTTPConnection */ |
106 |
|
|
HTTPConnection * HTTPConnection_new_server(SOCKET s); |
107 |
|
|
HTTPConnection * HTTPConnection_new_client(const char * host, uint16_t port) __attribute__((warn_unused_result)); |
108 |
|
|
int HTTPConnection_delete(HTTPConnection * connection) __attribute__((warn_unused_result)); |
109 |
|
|
int HTTPConnection_get_peer(HTTPConnection * connection, struct sockaddr_in * peer) __attribute__((warn_unused_result)); |
110 |
|
|
int HTTPConnection_read_octet(HTTPConnection * connection, int * octet) __attribute__((warn_unused_result)); |
111 |
|
|
int HTTPConnection_peek_octet(HTTPConnection * connection, int * octet) __attribute__((warn_unused_result)); |
112 |
|
|
int HTTPConnection_write(HTTPConnection * connection, const void * p, size_t size) __attribute__((warn_unused_result)); |
113 |
|
|
int HTTPConnection_flush(HTTPConnection * connection) __attribute__((warn_unused_result)); |
114 |
|
|
|
115 |
|
|
/* HTTPMessage */ |
116 |
|
|
HTTPMessage * HTTPMessage_new(HTTPConnection * connection); |
117 |
|
|
void HTTPMessage_delete(HTTPMessage * message); |
118 |
|
|
HTTPConnection * HTTPMessage_get_connection(const HTTPMessage * message); |
119 |
|
|
const char * HTTPMessage_get_start_line(const HTTPMessage * message); |
120 |
|
|
void HTTPMessage_set_start_line(HTTPMessage * message, const char * start_line); |
121 |
|
|
const HTTPHeader * HTTPMessage_get_headers(const HTTPMessage * message); |
122 |
|
|
const char * HTTPMessage_find_header(const HTTPMessage * message, const char * name); |
123 |
|
|
void HTTPMessage_add_header(HTTPMessage * message, const char * name, const char * value); |
124 |
|
|
void HTTPMessage_set_header(HTTPMessage * message, const char * name, const char * value); |
125 |
siliconforks |
177 |
char * HTTPMessage_get_charset(const HTTPMessage * message); |
126 |
siliconforks |
116 |
void HTTPMessage_set_content_length(HTTPMessage * message, size_t value); |
127 |
|
|
int HTTPMessage_read_start_line_and_headers(HTTPMessage * message) __attribute__((warn_unused_result)); |
128 |
|
|
int HTTPMessage_write_start_line_and_headers(HTTPMessage * message) __attribute__((warn_unused_result)); |
129 |
|
|
bool HTTPMessage_has_sent_headers(const HTTPMessage * message); |
130 |
|
|
int HTTPMessage_write(HTTPMessage * message, const void * p, size_t size) __attribute__((warn_unused_result)); |
131 |
|
|
int HTTPMessage_flush(HTTPMessage * message) __attribute__((warn_unused_result)); |
132 |
|
|
|
133 |
|
|
/* |
134 |
|
|
This function reads the entire entity body from a message. If the message uses |
135 |
|
|
the "chunked" Transfer-Encoding, this function will decode it, so that the |
136 |
|
|
result will be the original entity. |
137 |
|
|
*/ |
138 |
|
|
int HTTPMessage_read_entire_entity_body(HTTPMessage * message, Stream * input_stream) __attribute__((warn_unused_result)); |
139 |
|
|
|
140 |
|
|
/* |
141 |
|
|
This function makes no attempt to decode the Transfer-Encoding. |
142 |
|
|
*/ |
143 |
|
|
int HTTPMessage_read_message_body(HTTPMessage * message, void * p, size_t capacity, size_t * bytes_read) __attribute__((warn_unused_result)); |
144 |
|
|
|
145 |
|
|
/* HTTPExchange */ |
146 |
|
|
HTTPExchange * HTTPExchange_new(HTTPConnection * connection); |
147 |
|
|
void HTTPExchange_delete(HTTPExchange * exchange); |
148 |
|
|
int HTTPExchange_get_peer(const HTTPExchange * exchange, struct sockaddr_in * peer) __attribute__((warn_unused_result)); |
149 |
|
|
|
150 |
|
|
HTTPMessage * HTTPExchange_get_request_message(const HTTPExchange * exchange); |
151 |
|
|
|
152 |
|
|
const char * HTTPExchange_get_request_line(const HTTPExchange * exchange); |
153 |
|
|
const char * HTTPExchange_get_method(const HTTPExchange * exchange); |
154 |
|
|
const char * HTTPExchange_get_request_uri(const HTTPExchange * exchange); |
155 |
|
|
const char * HTTPExchange_get_request_http_version(const HTTPExchange * exchange); |
156 |
|
|
const char * HTTPExchange_get_host(const HTTPExchange * exchange); |
157 |
|
|
uint16_t HTTPExchange_get_port(const HTTPExchange * exchange); |
158 |
|
|
const char * HTTPExchange_get_abs_path(const HTTPExchange * exchange); |
159 |
|
|
void HTTPExchange_set_method(HTTPExchange * exchange, const char * method); |
160 |
|
|
void HTTPExchange_set_request_uri(HTTPExchange * exchange, const char * request_uri); |
161 |
|
|
|
162 |
|
|
const HTTPHeader * HTTPExchange_get_request_headers(const HTTPExchange * exchange); |
163 |
|
|
const char * HTTPExchange_find_request_header(const HTTPExchange * exchange, const char * name); |
164 |
|
|
void HTTPExchange_add_request_header(HTTPExchange * exchange, const char * name, const char * value); |
165 |
|
|
void HTTPExchange_set_request_header(HTTPExchange * exchange, const char * name, const char * value); |
166 |
|
|
void HTTPExchange_set_request_content_length(HTTPExchange * exchange, size_t value); |
167 |
|
|
|
168 |
|
|
int HTTPExchange_read_request_headers(HTTPExchange * exchange) __attribute__((warn_unused_result)); |
169 |
|
|
int HTTPExchange_write_request_headers(HTTPExchange * exchange) __attribute__((warn_unused_result)); |
170 |
|
|
bool HTTPExchange_request_has_body(const HTTPExchange * exchange); |
171 |
|
|
int HTTPExchange_read_entire_request_entity_body(HTTPExchange * exchange, Stream * stream) __attribute__((warn_unused_result)); |
172 |
|
|
int HTTPExchange_flush_request(HTTPExchange * exchange) __attribute__((warn_unused_result)); |
173 |
|
|
|
174 |
|
|
HTTPMessage * HTTPExchange_get_response_message(const HTTPExchange * exchange); |
175 |
|
|
|
176 |
|
|
uint16_t HTTPExchange_get_status_code(const HTTPExchange * exchange); |
177 |
|
|
const char * HTTPExchange_get_response_http_version(const HTTPExchange * exchange); |
178 |
|
|
void HTTPExchange_set_status_code(HTTPExchange * exchange, uint16_t status_code); |
179 |
|
|
|
180 |
|
|
const HTTPHeader * HTTPExchange_get_response_headers(const HTTPExchange * exchange); |
181 |
|
|
const char * HTTPExchange_find_response_header(const HTTPExchange * exchange, const char * name); |
182 |
|
|
void HTTPExchange_add_response_header(HTTPExchange * exchange, const char * name, const char * value); |
183 |
|
|
void HTTPExchange_set_response_header(HTTPExchange * exchange, const char * name, const char * value); |
184 |
|
|
void HTTPExchange_set_response_content_length(HTTPExchange * exchange, size_t value); |
185 |
|
|
|
186 |
|
|
int HTTPExchange_read_response_headers(HTTPExchange * exchange) __attribute__((warn_unused_result)); |
187 |
|
|
int HTTPExchange_write_response_headers(HTTPExchange * exchange) __attribute__((warn_unused_result)); |
188 |
|
|
bool HTTPExchange_response_has_body(const HTTPExchange * exchange); |
189 |
|
|
int HTTPExchange_read_entire_response_entity_body(HTTPExchange * exchange, Stream * stream) __attribute__((warn_unused_result)); |
190 |
|
|
int HTTPExchange_write_response(HTTPExchange * exchange, const void * p, size_t size) __attribute__((warn_unused_result)); |
191 |
|
|
int HTTPExchange_flush_response(HTTPExchange * exchange) __attribute__((warn_unused_result)); |
192 |
|
|
|
193 |
|
|
void HTTPServer_run(const char * ip_address, uint16_t port, HTTPServerHandler handler); |
194 |
|
|
void HTTPServer_shutdown(void); |
195 |
|
|
void HTTPServer_log_out(const char * format, ...) __attribute__((__format__(printf, 1, 2))); |
196 |
|
|
void HTTPServer_log_err(const char * format, ...) __attribute__((__format__(printf, 1, 2))); |
197 |
|
|
|
198 |
|
|
int URL_parse(const char * url, char ** host, uint16_t * port, char ** abs_path, char ** query) __attribute__((warn_unused_result)); |
199 |
|
|
int URL_parse_host_and_port(const char * s, char ** host, uint16_t * port) __attribute__((warn_unused_result)); |
200 |
|
|
int URL_parse_abs_path_and_query(const char * s, char ** abs_path, char ** query) __attribute__((warn_unused_result)); |
201 |
|
|
|
202 |
|
|
int xgethostbyname(const char * host, struct in_addr * result) __attribute__((warn_unused_result)); |
203 |
|
|
|
204 |
siliconforks |
125 |
#ifndef HAVE_INET_ATON |
205 |
|
|
int inet_aton(const char * name, struct in_addr * a); |
206 |
|
|
#endif |
207 |
|
|
|
208 |
siliconforks |
116 |
#endif /* HTTP_SERVER_H_ */ |