1 #ifndef HTTPD_H
2 #define HTTPD_H
3 
4 #include <vstr.h>
5 
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/unistd.h>
9 
10 #include "evnt.h"
11 
12 #define HTTPD_CONF_SERV_DEF_PORT 80
13 
14 /* if the data is less than this, queue instead of hitting write */
15 #define HTTPD_CONF_MAX_WAIT_SEND 16
16 
17 #define HTTPD_CONF_RECV_CALL_LIMIT 3 /* read+send+sendfile */
18 #define HTTPD_CONF_SEND_CALL_LIMIT 1 /* already blocking in send */
19 
20 struct Con;
21 struct Httpd_req_data;
22 
23 #include "httpd_conf_main.h"
24 #include "httpd_conf_req.h"
25 #include "httpd_err_codes.h"
26 
27 struct Http_hdrs
28 {
29  Vstr_sect_node hdr_ua[1];
30  Vstr_sect_node hdr_referer[1]; /* NOTE: referrer */
31 
32  Vstr_sect_node hdr_expect[1];
33  Vstr_sect_node hdr_host[1];
34  Vstr_sect_node hdr_if_modified_since[1];
35  Vstr_sect_node hdr_if_range[1];
36  Vstr_sect_node hdr_if_unmodified_since[1];
37  Vstr_sect_node hdr_authorization[1];
38 
39  /* can have multiple headers... */
40  struct Http_hdrs__multi {
41   Vstr_base *combiner_store;
42   Vstr_base *comb;
43   Vstr_sect_node hdr_accept[1];
44   Vstr_sect_node hdr_accept_charset[1];
45   Vstr_sect_node hdr_accept_encoding[1];
46   Vstr_sect_node hdr_accept_language[1];
47   Vstr_sect_node hdr_connection[1];
48   Vstr_sect_node hdr_if_match[1];
49   Vstr_sect_node hdr_if_none_match[1];
50   Vstr_sect_node hdr_range[1];
51  } multi[1];
52 };
53 
54 #define HTTPD__DECL_XTRA_HDR(x)                 \
55     const Vstr_base * x ## _vs1;                \
56     size_t            x ## _pos;                \
57     size_t            x ## _len
58 
59 typedef struct Httpd_req_data
60 {
61  const Httpd_policy_opts *policy;
62 
63  struct Http_hdrs http_hdrs[1];
64  Vstr_base *fname;
65  size_t len;
66  size_t path_pos;
67  size_t path_len;
68  unsigned int             error_code;
69  const char              *error_line;
70  const char              *error_msg;
71  VSTR_AUTOCONF_uintmax_t  error_len; /* due to custom files */
72  Vstr_sects *sects;
73  struct stat64 f_stat[1];
74  size_t orig_io_w_len;
75  Vstr_base *f_mmap;
76  Vstr_base *xtra_content;
77  HTTPD__DECL_XTRA_HDR(cache_control);
78  HTTPD__DECL_XTRA_HDR(content_disposition);
79  HTTPD__DECL_XTRA_HDR(content_language);
80  HTTPD__DECL_XTRA_HDR(content_location);
81  HTTPD__DECL_XTRA_HDR(content_md5); /* Note this is valid for range */
82  time_t               content_md5_time;
83  HTTPD__DECL_XTRA_HDR(gzip_content_md5);
84  time_t               gzip_content_md5_time;
85  HTTPD__DECL_XTRA_HDR(bzip2_content_md5);
86  time_t               bzip2_content_md5_time;
87  HTTPD__DECL_XTRA_HDR(content_type);
88  HTTPD__DECL_XTRA_HDR(etag);
89  time_t               etag_time;
90  HTTPD__DECL_XTRA_HDR(gzip_etag);
91  time_t               gzip_etag_time;
92  HTTPD__DECL_XTRA_HDR(bzip2_etag);
93  time_t               bzip2_etag_time;
94  HTTPD__DECL_XTRA_HDR(expires);
95  time_t               expires_time;
96  HTTPD__DECL_XTRA_HDR(ext_vary_a);
97  HTTPD__DECL_XTRA_HDR(ext_vary_ac);
98  HTTPD__DECL_XTRA_HDR(ext_vary_al);
99  HTTPD__DECL_XTRA_HDR(link);
100  HTTPD__DECL_XTRA_HDR(p3p);
101 
102  time_t encoded_mtime;
103 
104  time_t now;
105 
106  size_t vhost_prefix_len;
107 
108  unsigned int ver_0_9 : 1;
109  unsigned int ver_1_1 : 1;
110  unsigned int head_op : 1;
111 
112  unsigned int content_encoding_gzip  : 1;
113  unsigned int content_encoding_xgzip : 1; /* only valid if gzip is TRUE */
114  unsigned int content_encoding_bzip2 : 1;
115 
116  unsigned int content_encoding_identity : 1;
117 
118  unsigned int direct_uri         : 1;
119  unsigned int direct_filename    : 1;
120  unsigned int skip_document_root : 1;
121 
122  unsigned int parse_accept          : 1;
123  unsigned int parse_accept_language : 1;
124  unsigned int allow_accept_encoding : 1;
125  unsigned int output_keep_alive_hdr : 1;
126 
127  unsigned int user_return_error_code : 1;
128 
129  unsigned int vary_star : 1;
130  unsigned int vary_a    : 1;
131  unsigned int vary_ac   : 1;
132  unsigned int vary_ae   : 1;
133  unsigned int vary_al   : 1;
134  unsigned int vary_rf   : 1;
135  unsigned int vary_ua   : 1;
136 
137  unsigned int chked_encoded_path : 1;
138  unsigned int chk_encoded_slash  : 1;
139  unsigned int chk_encoded_dot    : 1;
140 
141  unsigned int neg_content_type_done : 1;
142  unsigned int neg_content_lang_done : 1;
143 
144  unsigned int conf_secure_dirs : 1;
145  unsigned int conf_friendly_dirs : 1;
146 
147  unsigned int using_req : 1;
148  unsigned int done_once : 1;
149 
150  unsigned int malloc_bad : 1;
151 } Httpd_req_data;
152 
153 struct File_sect
154 {
155   int fd;
156   VSTR_AUTOCONF_uintmax_t off;
157   VSTR_AUTOCONF_uintmax_t len;
158 };
159 
160 struct Con
161 {
162  struct Evnt evnt[1];
163 
164  Vstr_ref *acpt_sa_ref;
165 
166  const Httpd_policy_opts *policy;
167 
168  Vstr_base *mpbr_ct; /* multipart/byterange */
169  VSTR_AUTOCONF_uintmax_t mpbr_fs_len;
170  unsigned int fs_off;
171  unsigned int fs_num;
172  unsigned int fs_sz;
173  struct File_sect *fs;
174  struct File_sect fs_store[1];
175 
176  unsigned int io_limit_num : 8;
177 
178  unsigned int vary_star : 1;
179  unsigned int parsed_method_ver_1_0 : 1;
180  unsigned int keep_alive : 3;
181 
182  unsigned int use_mmap : 1;
183  unsigned int use_sendfile : 1;
184  unsigned int use_posix_fadvise : 1;
185  unsigned int use_mpbr : 1;
186 };
187 #define CON_CEVNT_SA(x)     EVNT_SA((x)->evnt)
188 #define CON_CEVNT_SA_IN4(x) EVNT_SA_IN4((x)->evnt)
189 #define CON_CEVNT_SA_IN6(x) EVNT_SA_IN6((x)->evnt)
190 #define CON_CEVNT_SA_UN(x)  EVNT_SA_UN((x)->evnt)
191 
192 #define CON_SEVNT_SA(x)     ACPT_SA((Acpt_data *)((x)->acpt_sa_ref->ptr))
193 #define CON_SEVNT_SA_IN4(x) ACPT_SA_IN4((Acpt_data *)((x)->acpt_sa_ref->ptr))
194 #define CON_SEVNT_SA_IN6(x) ACPT_SA_IN6((Acpt_data *)((x)->acpt_sa_ref->ptr))
195 #define CON_SEVNT_SA_UN(x)  ACPT_SA_UN((Acpt_data *)((x)->acpt_sa_ref->ptr))
196 
197 
198 #define HTTP_NON_KEEP_ALIVE 0
199 #define HTTP_1_0_KEEP_ALIVE 1
200 #define HTTP_1_1_KEEP_ALIVE 2
201 
202 /* Linear Whitespace, a full stds. check for " " and "\t" */
203 #define HTTP_LWS " \t"
204 
205 /* End of Line */
206 #define HTTP_EOL "\r\n"
207 
208 /* End of Request - blank line following previous line in request */
209 #define HTTP_END_OF_REQUEST HTTP_EOL HTTP_EOL
210 
211 /* HTTP crack -- Implied linear whitespace between tokens, note that it
212  * is *LWS == *([CRLF] 1*(SP | HT)) */
213 #define HTTP_SKIP_LWS(s1, p, l) do {                                    \
214       char http__q_tst_lws = 0;                                         \
215                                                                         \
216       if (!l) break;                                                    \
217       http__q_tst_lws = vstr_export_chr(s1, p);                         \
218       if ((http__q_tst_lws != '\r') && (http__q_tst_lws != ' ') &&      \
219           (http__q_tst_lws != '\t'))                                    \
220         break;                                                          \
221                                                                         \
222       http__skip_lws(s1, &p, &l);                                       \
223     } while (FALSE)
224 
225 #define HTTPD_APP_REF_VSTR(x, s2, p2, l2)                               \
226     vstr_add_vstr(x, (x)->len, s2, p2, l2, VSTR_TYPE_ADD_BUF_REF)
227 #define HTTPD_APP_REF_ALLVSTR(x, s2)                                    \
228     vstr_add_vstr(x, (x)->len, s2, 1, (s2)->len, VSTR_TYPE_ADD_BUF_REF)
229 
230 #ifdef HTTPD_HAVE_GLOBAL_OPTS
231 extern Httpd_opts httpd_opts[1]; /* hacky ... */
232 #endif
233 
234 extern void httpd_init(Vlg *);
235 extern void httpd_exit(void);
236 
237 extern Httpd_req_data *http_req_make(struct Con *);
238 extern void http_req_free(Httpd_req_data *);
239 extern void http_req_exit(void);
240 
241 extern void httpd_fin_fd_close(struct Con *);
242 
243 extern int httpd_valid_url_filename(Vstr_base *, size_t, size_t);
244 extern int httpd_init_default_hostname(Opt_serv_policy_opts *);
245 extern int httpd_sc_add_default_hostname(struct Con *, Httpd_req_data *,
246                                          Vstr_base *, size_t);
247 
248 extern int httpd_canon_path(Vstr_base *);
249 extern int httpd_canon_dir_path(Vstr_base *);
250 extern int httpd_canon_abs_dir_path(Vstr_base *);
251 
252 extern void httpd_req_absolute_uri(struct Con *, Httpd_req_data *,
253                                    Vstr_base *, size_t, size_t);
254 
255 extern int http_req_content_type(Httpd_req_data *);
256 
257 extern unsigned int http_parse_accept(Httpd_req_data *,
258                                       const Vstr_base *, size_t, size_t);
259 extern unsigned int http_parse_accept_language(Httpd_req_data *,
260                                                const Vstr_base *,
261                                                size_t, size_t);
262 
263 extern void http_app_def_hdrs(struct Con *, Httpd_req_data *,
264                               unsigned int, const char *, time_t,
265                               const char *, int, VSTR_AUTOCONF_uintmax_t);
266 
267 
268 extern int http_fmt_add_vstr_add_vstr(Vstr_conf *, const char *);
269 extern int http_fmt_add_vstr_add_sect_vstr(Vstr_conf *, const char *);
270 
271 
272 extern int http_req_op_get(struct Con *, Httpd_req_data *);
273 extern int http_req_op_opts(struct Con *, Httpd_req_data *);
274 extern int http_req_op_trace(struct Con *, Httpd_req_data *);
275 
276 extern int httpd_serv_send(struct Con *);
277 extern int httpd_serv_recv(struct Con *);
278 
279 extern int httpd_con_init(struct Con *, struct Acpt_listener *);
280 
281 #endif
282