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