static void process_tok(char *tok) { char *p; if((p = index(tok, '-')) != NULL) { *p++ = 0; process_range(atoi(tok), atoi(p)); return; } process_port(atoi(tok)); }
static int serve_with_generator(struct st_h2o_sendfile_generator_t *generator, h2o_req_t *req, const char *rpath, size_t rpath_len, h2o_mimemap_type_t *mime_type) { enum { METHOD_IS_GET, METHOD_IS_HEAD, METHOD_IS_OTHER } method_type; size_t if_modified_since_header_index, if_none_match_header_index; size_t range_header_index; /* determine the method */ if (h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET"))) { method_type = METHOD_IS_GET; } else if (h2o_memis(req->method.base, req->method.len, H2O_STRLIT("HEAD"))) { method_type = METHOD_IS_HEAD; } else { method_type = METHOD_IS_OTHER; } /* if-non-match and if-modified-since */ if ((if_none_match_header_index = h2o_find_header(&req->headers, H2O_TOKEN_IF_NONE_MATCH, SIZE_MAX)) != -1) { h2o_iovec_t *if_none_match = &req->headers.entries[if_none_match_header_index].value; char etag[H2O_FILECACHE_ETAG_MAXLEN + 1]; size_t etag_len = h2o_filecache_get_etag(generator->file.ref, etag); if (h2o_memis(if_none_match->base, if_none_match->len, etag, etag_len)) goto NotModified; } else if ((if_modified_since_header_index = h2o_find_header(&req->headers, H2O_TOKEN_IF_MODIFIED_SINCE, SIZE_MAX)) != -1) { h2o_iovec_t *ims_vec = &req->headers.entries[if_modified_since_header_index].value; struct tm ims_tm, *last_modified_tm; if (h2o_time_parse_rfc1123(ims_vec->base, ims_vec->len, &ims_tm) == 0) { last_modified_tm = h2o_filecache_get_last_modified(generator->file.ref, NULL); if (!tm_is_lessthan(&ims_tm, last_modified_tm)) goto NotModified; } } /* obtain mime type */ if (mime_type->type == H2O_MIMEMAP_TYPE_DYNAMIC) { do_close(&generator->super, req); return delegate_dynamic_request(req, req->path_normalized.len, rpath, rpath_len, mime_type); } assert(mime_type->type == H2O_MIMEMAP_TYPE_MIMETYPE); /* only allow GET or POST for static files */ if (method_type == METHOD_IS_OTHER) { do_close(&generator->super, req); send_method_not_allowed(req); return 0; } /* if-range */ if ((range_header_index = h2o_find_header(&req->headers, H2O_TOKEN_RANGE, SIZE_MAX)) != -1) { h2o_iovec_t *range = &req->headers.entries[range_header_index].value; size_t *range_infos, range_count; range_infos = process_range(&req->pool, range, generator->bytesleft, &range_count); if (range_infos == NULL) { h2o_iovec_t content_range; content_range.base = h2o_mem_alloc_pool(&req->pool, 32); content_range.len = sprintf(content_range.base, "bytes */%zu", generator->bytesleft); h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_RANGE, content_range.base, content_range.len); h2o_send_error(req, 416, "Request Range Not Satisfiable", "requested range not satisfiable", H2O_SEND_ERROR_KEEP_HEADERS); goto Close; } generator->ranged.range_count = range_count; generator->ranged.range_infos = range_infos; generator->ranged.current_range = 0; generator->ranged.filesize = generator->bytesleft; /* set content-length according to range */ if (range_count == 1) generator->bytesleft = range_infos[1]; else { generator->ranged.mimetype = h2o_strdup(&req->pool, mime_type->data.mimetype.base, mime_type->data.mimetype.len); size_t final_content_len = 0, size_tmp = 0, size_fixed_each_part, i; generator->ranged.boundary.base = h2o_mem_alloc_pool(&req->pool, BOUNDARY_SIZE + 1); generator->ranged.boundary.len = BOUNDARY_SIZE; gen_rand_string(&generator->ranged.boundary); i = generator->bytesleft; while (i) { i /= 10; size_tmp++; } size_fixed_each_part = FIXED_PART_SIZE + mime_type->data.mimetype.len + size_tmp; for (i = 0; i < range_count; i++) { size_tmp = *range_infos++; if (size_tmp == 0) final_content_len++; while (size_tmp) { size_tmp /= 10; final_content_len++; } size_tmp = *(range_infos - 1); final_content_len += *range_infos; size_tmp += *range_infos++ - 1; if (size_tmp == 0) final_content_len++; while (size_tmp) { size_tmp /= 10; final_content_len++; } } final_content_len += sizeof("\r\n--") - 1 + BOUNDARY_SIZE + sizeof("--\r\n") - 1 + size_fixed_each_part * range_count - (sizeof("\r\n") - 1); generator->bytesleft = final_content_len; } do_send_file(generator, req, 206, "Partial Content", mime_type->data.mimetype, &h2o_mime_attributes_as_is, method_type == METHOD_IS_GET); return 0; } /* return file */ do_send_file(generator, req, 200, "OK", mime_type->data.mimetype, &mime_type->data.attr, method_type == METHOD_IS_GET); return 0; NotModified: req->res.status = 304; req->res.reason = "Not Modified"; add_headers_unconditional(generator, req); h2o_send_inline(req, NULL, 0); Close: do_close(&generator->super, req); return 0; }
NFA *regex_parser::parse_re(const char *re, int *ptr, bool bracket){ NFA *fa=new NFA(); NFA *to_link=NULL; bool open_b=bracket; bool close_b=false; while((*ptr)<strlen(re)){ if(re[(*ptr)]==ESCAPE){ int_set *chars=new int_set(CSIZE); (*ptr)=process_escape(re, (*ptr)+1,chars); if((*ptr)==strlen(re)||!is_repetition(re[(*ptr)])){ fa=fa->add_transition(chars); }else{ to_link=new NFA(); to_link=to_link->add_transition(chars); } delete chars; }else if (!is_special(re[(*ptr)]) && ((*ptr)==(strlen(re)-1)||!is_repetition(re[(*ptr)+1]))){ fa=fa->add_transition(re[(*ptr)++]); }else if(!is_special(re[(*ptr)])){ to_link=new NFA(); to_link=to_link->add_transition(re[(*ptr)++]); }else if (re[(*ptr)]==ANY && ((*ptr)==(strlen(re)-1)||!is_repetition(re[(*ptr)+1]))){ fa=fa->add_any(); (*ptr)++; }else if(re[(*ptr)]==ANY){ to_link=new NFA(); to_link=to_link->add_any(); (*ptr)++; }else if (re[(*ptr)]==STAR){ (*ptr)++; if (close_b) return fa->make_rep(0,_INFINITY); else{ to_link=to_link->make_rep(0,_INFINITY); fa=fa->link(to_link); } }else if (re[(*ptr)]==OPT){ (*ptr)++; if (close_b) return fa->make_rep(0,1); else{ to_link=to_link->make_rep(0,1); fa=fa->link(to_link); } }else if (re[(*ptr)]==PLUS){ (*ptr)++; if (close_b){ return fa->make_rep(1,_INFINITY); }else{ to_link=to_link->make_rep(1,_INFINITY); fa=fa->link(to_link); } }else if(re[(*ptr)]==OPEN_QBRACKET){ if ((*ptr)==(strlen(re)-1)) fatal("regex_parser:: parse_re: { in last position."); else{ int lb=0; int ub=_INFINITY; (*ptr)=process_quantifier(re,(*ptr)+1,&lb,&ub); if (close_b) return fa->make_rep(lb,ub); else{ to_link=to_link->make_rep(lb,ub); fa=fa->link(to_link); } } }else if(re[(*ptr)]==OPEN_SBRACKET){ if ((*ptr)==(strlen(re)-1)) fatal("regex_parser:: parse_re: [ in last position."); else (*ptr)=process_range(&fa,&to_link,re,(*ptr)+1); }else if(re[(*ptr)]==OR){ (*ptr)++; fa=fa->make_or(parse_re(re,ptr,false)); }else if(re[(*ptr)]==OPEN_RBRACKET){ (*ptr)++; fa=fa->get_last()->link(parse_re(re,ptr,true)); }else if(re[(*ptr)]==CLOSE_RBRACKET){ if (open_b){ close_b=true; (*ptr)++; if ((*ptr)==strlen(re) || !is_repetition(re[(*ptr)])) return fa; } //fatal("parse:: parse_re : close ) without opening it."); else{ return fa; } } } return fa->get_first(); }
//------------------------------------------------------------------- // PURPOSE: Parse script (script_source_str) for @xxx // PARAMETERS: fn - full path of script // RESULTS: script_title // script_params // script_params_order // script_loaded_params, conf.script_vars //------------------------------------------------------------------- static void script_scan(const char *fn) { register const char *ptr = script_source_str; register int i, j=0, n; char *c; if ( !ptr ) { ptr = lua_script_default; } // sanity check // Build title c=strrchr(fn, '/'); strncpy(script_title, (c)?c+1:fn, sizeof(script_title)); script_title[sizeof(script_title)-1]=0; // Reset everything for (i=0; i<SCRIPT_NUM_PARAMS; ++i) { conf.script_vars[i] = 0; script_loaded_params[i] = 0; script_params[i][0]=0; script_param_order[i]=0; script_range_values[i] = 0; if (script_named_values[i]) free(script_named_values[i]); script_named_values[i] = 0; if (script_named_strings[i]) free(script_named_strings[i]); script_named_strings[i] = 0; script_named_counts[i] = 0; } // Fillup order, defaults while (ptr[0]) { ptr = skip_whitespace(ptr); if (ptr[0]=='@') { if (strncmp("@title", ptr, 6)==0) { process_title(ptr+6); } else if (strncmp("@param", ptr, 6)==0) { n = process_param(ptr+6); // n=1 if '@param a' was processed, n=2 for 'b' ... n=26 for 'z'. n=0 if failed. if (n>0 && n<=SCRIPT_NUM_PARAMS) { script_param_order[j]=n; j++; } } else if (strncmp("@default", ptr, 8)==0) { process_default(ptr+8); } else if (strncmp("@range", ptr, 6)==0) { process_range(ptr+6); } else if (strncmp("@values", ptr, 7)==0) { process_values(ptr+7); } } ptr = skip_eol(ptr); } }
//------------------------------------------------------------------- // PURPOSE: Parse script (conf.script_file) for parameters and title //------------------------------------------------------------------- static void script_scan() { // Reset everything sc_param *p = script_params; while (p) { if (p->name) free(p->name); if (p->desc) free(p->desc); if (p->options) free(p->options); if (p->option_buf) free(p->option_buf); sc_param *l = p; p = p->next; free(l); } script_params = tail = 0; script_param_count = 0; parse_version(&script_version, "1.3.0.0", 0); script_has_version = 0; is_script_loaded = 0; // Load script file const char *buf=0; if (conf.script_file[0] != 0) buf = load_file_to_length(conf.script_file, 0, 1, 4096); // Assumes parameters are in first 4K of script file // Check file loaded if (buf == 0) { strcpy(script_title, "NO SCRIPT"); return; } // Build title from name (in case no title in script) const char *c = get_script_filename(); strncpy(script_title, c, sizeof(script_title)-1); script_title[sizeof(script_title)-1]=0; // Fillup order, defaults const char *ptr = buf; while (ptr[0]) { ptr = skip_whitespace(ptr); if (ptr[0] == '@') { if (strncmp("@title", ptr, 6)==0) { process_title(ptr+6); } else if (strncmp("@subtitle", ptr, 9)==0) { process_subtitle(ptr+9); } else if (strncmp("@param", ptr, 6)==0) { process_param(ptr+6); } else if (strncmp("@default", ptr, 8)==0) { process_default(ptr+8, 1); } else if (strncmp("@range", ptr, 6)==0) { process_range(ptr+6); } else if (strncmp("@values", ptr, 7)==0) { process_values(ptr+7); } else if (strncmp("@chdk_version", ptr, 13)==0) { ptr = skip_whitespace(ptr+13); parse_version(&script_version, ptr, 0); script_has_version = 1; } } else if (ptr[0] == '#') { process_single(ptr+1); } ptr = skip_eol(ptr); } free((void*)buf); is_script_loaded = 1; }