static void setup_request_object(sl_vm_t* vm, request_rec* r) { struct iter_args ia; sl_request_opts_t opts; opts.method = (char*)r->method; opts.uri = r->uri; opts.path_info = r->path_info; opts.query_string = r->args; opts.remote_addr = r->connection->remote_ip; opts.content_type = (char*)apr_table_get(r->headers_in, "content-type"); ia.count = 0; ia.capacity = 4; ia.kvs = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * ia.capacity); ia.vm = vm; apr_table_do(iterate_apr_table, &ia, r->headers_in, NULL); opts.header_count = ia.count; opts.headers = ia.kvs; ap_add_common_vars(r); ap_add_cgi_vars(r); ia.count = 0; ia.capacity = 4; ia.kvs = sl_alloc(vm->arena, sizeof(sl_request_key_value_t) * ia.capacity); ia.vm = vm; apr_table_do(iterate_apr_table, &ia, r->subprocess_env, NULL); opts.env_count = ia.count; opts.env = ia.kvs; read_post_data(vm, &opts, r); sl_request_set_opts(vm, &opts); }
static bool setup_request_object(sl_vm_t* vm, slash_request_info_t* info) { bool result = true; sl_request_opts_t opts; opts.method = info->request_method ? info->request_method->value : "GET"; opts.uri = info->real_uri ? info->real_uri : ""; opts.path_info = info->real_path_info ? info->real_path_info : ""; opts.query_string = info->query_string ? info->query_string->value : ""; opts.remote_addr = info->remote_addr ? info->remote_addr->value : ""; opts.content_type = info->content_type ? info->content_type->value : NULL; opts.header_count = info->http_headers->count; opts.headers = info->http_headers->kvs; opts.env_count = info->environment->count; opts.env = info->environment->kvs; result = read_post_data(vm, &opts, info); sl_request_set_opts(vm, &opts); return result; }
void do_post(int fd, char *uri) { int is_static; struct stat sbuf; char filename[MAXLINE], cgiargs[MAXLINE]; read_post_data(fd); /* 从POST request 中解析 URI */ is_static = parse_uri(uri, filename, cgiargs); if (stat(filename, &sbuf) < 0) { send_error(fd, filename, "404", "Not Found"); return; } send_error(fd, filename, "403", "Forbidden"); close(fd); return; }
/*************************************************************************** * Function Name: cfe_web_bg_process * Description : This function processes an HTTP request on a socket. * Returns : None. ***************************************************************************/ static void cfe_web_bg_process(PSOCKET_INFO si) { char post_subst[] = {UPLOAD_FATAL, '\0'}; char *post_substs[] = {post_subst}; int close_tcp = 0; switch( si->state ) { case HTTP_READ_FIRST_HDR: if( read_first_hdr( si->s, si->web_first_buf, sizeof(si->web_first_buf), &si->web_buf_idx, &close_tcp ) == 0 ) { /* Not all of the first header has been read yet. Try again later.*/ break; } /* The first header has been read. */ si->state = HTTP_READ_REMAINING_HDRS; /* fall thru */ case HTTP_READ_REMAINING_HDRS: if( read_remaining_hdrs( si->s, si->web_buf, sizeof(si->web_buf), &si->web_buf_idx, &close_tcp, &si->post_content_length ) ) { if( g_processing_cmd == 0 ) { char *method = NULL; char *path = NULL; char *ptr = (char *) si->web_first_buf; method = gettoken(&ptr); if( method ) path = gettoken(&ptr); /* Process the HTTP request. Only GET and POST are supported. */ if( method && path ) { if( !strcmpi( method, "get" ) ) { send_page( si->s, path, 1, NULL, 0 ); close_tcp = 1; } else { if( !strcmpi( method, "post" ) ) { if( g_post_data_in_progress == 0 ) { g_post_data_in_progress = 1; si->state = HTTP_READ_POST_DATA; } else { send_error( si->s, 501, "Upload Busy", (char*) 0, "An image is already being uploaded." ); close_tcp = 1; } } else { send_error( si->s, 501, "Not Implemented", (char*) 0, "That method is not implemented." ); close_tcp = 1; } } } else { send_error( si->s, 400, "Bad Request", (char *) 0, "Can't parse request." ); close_tcp = 1; } } else { /* A download and flash image command is being executed from * the serial port console. */ send_error( si->s, 400, "Bad Request", (char *) 0, "Console command is in progress." ); close_tcp = 1; } } if( si->state != HTTP_READ_POST_DATA ) break; case HTTP_READ_POST_DATA: /* Read the post data, which contains an image to flash, into low * memory. */ if( (post_subst[0] = read_post_data( si->s, POST_DATA_START, si->post_content_length, &g_post_data_idx )) == UPLOAD_OK ) { /* Verify that the post data is a valid image to flash. */ post_subst[0] = parse_post_data( si->s, POST_DATA_START, g_post_data_idx, (unsigned char **) &g_image_start, &g_image_len, &g_image_format ); } switch( post_subst[0] ) { case UPLOAD_PENDING: break; case UPLOAD_TCP_ERROR: close_tcp = 1; g_post_data_in_progress = 0; g_post_data_idx = 0; break; case UPLOAD_OK: /* Notify foreground to abort the console input so it can * write the image to flash memory. */ g_console_abort = 1; send_page(si->s, "/uploadinfo.html", 0, post_substs, 1); close_tcp = 1; g_post_data_idx = 0; break; default: /* The image was downloaded OK but there was a problem with it * so it could not be written to flash memory. */ send_page(si->s, "/uploadinfo.html", 0, post_substs, 1); close_tcp = 1; g_post_data_in_progress = 0; g_post_data_idx = 0; break; } break; } /* Close the socket if the HTTP transaction is done. */ if( close_tcp ) { POLL(); tcp_close(si->s); si->s = SOCKET_CLOSED; si->state = HTTP_READ_FIRST_HDR; si->web_buf_idx = 0; si->post_content_length = 0; } } /* cfe_web_poll */
int main(int argc, char *argv[]) { fd_set rfds, wfds; struct connstruct *tp, *to; struct serverstruct *sp; int rnum, wnum, active; int i = 1; time_t currtime; char *httpAddress = NULL; int httpPort = CONFIG_HTTP_PORT; char *httpsAddress = NULL; int httpsPort = CONFIG_HTTP_HTTPS_PORT; uint32_t options = CONFIG_HTTP_DEFAULT_SSL_OPTIONS; char *portStr; char *private_key = NULL; char *cert = NULL; #ifdef WIN32 WORD wVersionRequested = MAKEWORD(2, 2); WSADATA wsaData; WSAStartup(wVersionRequested,&wsaData); #else signal(SIGPIPE, SIG_IGN); #if defined(CONFIG_HTTP_HAS_CGI) signal(SIGCHLD, reaper); #endif #ifdef CONFIG_HTTP_VERBOSE signal(SIGQUIT, die); #endif #endif #ifdef CONFIG_HTTP_VERBOSE signal(SIGTERM, die); signal(SIGINT, sigint_cleanup); #endif tdate_init(); /* get some command-line parameters */ while (argv[i] != NULL) { if (strcmp(argv[i], "-p") == 0 && argv[i+1] != NULL) { if ((portStr = strchr(argv[i+1], ':')) != NULL) { httpAddress = argv[i+1]; *portStr = 0; httpPort = atoi(portStr + 1); } else httpPort = atoi(argv[i+1]); i += 2; continue; } if (strcmp(argv[i], "-s") == 0 && argv[i+1] != NULL) { if ((portStr = strchr(argv[i+1], ':')) != NULL) { httpsAddress = argv[i+1]; *portStr = 0; httpsPort = atoi(portStr + 1); } else httpsPort = atoi(argv[i+1]); i += 2; continue; } if (strcmp(argv[i], "-w") == 0 && argv[i+1] != NULL) { webroot = argv[i+1]; i += 2; continue; } if (strcmp(argv[i], "-cert") == 0 && argv[i+1] != NULL) { cert = argv[i+1]; i += 2; continue; } if (strcmp(argv[i], "-key") == 0 && argv[i+1] != NULL) { private_key = argv[i+1]; i += 2; continue; } printf("%s:\n" " [-p [address:]httpport]\n" " [-s [address:]httpsport]\n" " [-key private_key]\n" " [-cert cert]\n" " [-w webroot]\n", argv[0]); exit(1); } for (i = 0; i < INITIAL_CONNECTION_SLOTS; i++) { tp = freeconns; freeconns = (struct connstruct *)calloc(1, sizeof(struct connstruct)); freeconns->next = tp; } if ((active = openlistener(httpAddress, httpPort)) == -1) { #ifdef CONFIG_HTTP_VERBOSE fprintf(stderr, "ERR: Couldn't bind to port %d\n", httpPort); #endif exit(1); } addtoservers(active); if ((active = openlistener(httpsAddress, httpsPort)) == -1) { #ifdef CONFIG_HTTP_VERBOSE fprintf(stderr, "ERR: Couldn't bind to port %d\n", httpsPort); #endif exit(1); } addtoservers(active); if (cert != NULL && private_key != NULL) options |= SSL_NO_DEFAULT_KEY; servers->ssl_ctx = ssl_ctx_new(options, CONFIG_HTTP_SESSION_CACHE_SIZE); servers->is_ssl = 1; if (cert != NULL && private_key != NULL) { printf("YEAH\n"); if (ssl_obj_load(servers->ssl_ctx, SSL_OBJ_RSA_KEY, private_key, NULL)) { #ifdef CONFIG_HTTP_VERBOSE fprintf(stderr, "ERR: Couldn't load private key %s\n", private_key); #endif exit(1); } if (ssl_obj_load(servers->ssl_ctx, SSL_OBJ_X509_CERT, cert, NULL)) { #ifdef CONFIG_HTTP_VERBOSE fprintf(stderr, "ERR: Couldn't load cert %s\n", cert); #endif exit(1); } } #if defined(CONFIG_HTTP_HAS_CGI) addcgiext(CONFIG_HTTP_CGI_EXTENSIONS); #endif #if defined(CONFIG_HTTP_VERBOSE) #if defined(CONFIG_HTTP_HAS_CGI) printf("addcgiext %s\n", CONFIG_HTTP_CGI_EXTENSIONS); #endif printf("%s: listening on ports %d (http) and %d (https)\n", server_version, httpPort, httpsPort); TTY_FLUSH(); #endif ax_chdir(); #ifdef CONFIG_HTTP_ENABLE_DIFFERENT_USER { struct passwd *pd = getpwnam(CONFIG_HTTP_USER); if (pd != NULL) { int res = setuid(pd->pw_uid); res |= setgid(pd->pw_gid); #if defined(CONFIG_HTTP_VERBOSE) if (res == 0) { printf("change to '%s' successful\n", CONFIG_HTTP_USER); TTY_FLUSH(); } #endif } } #endif #ifndef WIN32 #ifdef CONFIG_HTTP_IS_DAEMON if (fork() > 0) /* parent will die */ exit(0); setsid(); #endif #endif /* main loop */ while (1) { struct timeval tv = { 10, 0 }; FD_ZERO(&rfds); FD_ZERO(&wfds); rnum = wnum = -1; sp = servers; while (sp != NULL) /* read each server port */ { FD_SET(sp->sd, &rfds); if (sp->sd > rnum) rnum = sp->sd; sp = sp->next; } /* Add the established sockets */ tp = usedconns; currtime = time(NULL); while (tp != NULL) { if (currtime > tp->timeout) /* timed out? Kill it. */ { to = tp; tp = tp->next; removeconnection(to); continue; } if (tp->state == STATE_WANT_TO_READ_HEAD) { FD_SET(tp->networkdesc, &rfds); if (tp->networkdesc > rnum) rnum = tp->networkdesc; } if (tp->state == STATE_WANT_TO_SEND_HEAD) { FD_SET(tp->networkdesc, &wfds); if (tp->networkdesc > wnum) wnum = tp->networkdesc; } if (tp->state == STATE_WANT_TO_READ_FILE) { FD_SET(tp->filedesc, &rfds); if (tp->filedesc > rnum) rnum = tp->filedesc; } if (tp->state == STATE_WANT_TO_SEND_FILE) { FD_SET(tp->networkdesc, &wfds); if (tp->networkdesc > wnum) wnum = tp->networkdesc; } #if defined(CONFIG_HTTP_DIRECTORIES) if (tp->state == STATE_DOING_DIR) { FD_SET(tp->networkdesc, &wfds); if (tp->networkdesc > wnum) wnum = tp->networkdesc; } #endif tp = tp->next; } active = select(wnum > rnum ? wnum+1 : rnum+1, rnum != -1 ? &rfds : NULL, wnum != -1 ? &wfds : NULL, NULL, usedconns ? &tv : NULL); /* timeout? */ if (active == 0) continue; /* New connection? */ sp = servers; while (active > 0 && sp != NULL) { if (FD_ISSET(sp->sd, &rfds)) { handlenewconnection(sp->sd, sp->is_ssl); active--; } sp = sp->next; } /* Handle the established sockets */ tp = usedconns; while (active > 0 && tp != NULL) { to = tp; tp = tp->next; if (to->state == STATE_WANT_TO_READ_HEAD && FD_ISSET(to->networkdesc, &rfds)) { active--; #if defined(CONFIG_HTTP_HAS_CGI) if (to->post_state) read_post_data(to); else #endif procreadhead(to); } if (to->state == STATE_WANT_TO_SEND_HEAD && FD_ISSET(to->networkdesc, &wfds)) { active--; procsendhead(to); } if (to->state == STATE_WANT_TO_READ_FILE && FD_ISSET(to->filedesc, &rfds)) { active--; procreadfile(to); } if (to->state == STATE_WANT_TO_SEND_FILE && FD_ISSET(to->networkdesc, &wfds)) { active--; procsendfile(to); } #if defined(CONFIG_HTTP_DIRECTORIES) if (to->state == STATE_DOING_DIR && FD_ISSET(to->networkdesc, &wfds)) { active--; procdodir(to); } #endif } } return 0; }
int oversight_main(int argc,char **argv,int send_content_type_header) { int result=0; int done=0; g_start_clock = time(NULL); assert(sizeof(long long) >= 8); init_view(); adjust_path(); char *q=getenv("QUERY_STRING"); char *sp=getenv("SCRIPT_NAME"); char *p; char *req; if (q && (p = delimited_substring(q,"&",REMOTE_VOD_PREFIX2,"=",1,0)) != NULL) { gaya_auto_load(p+strlen(REMOTE_VOD_PREFIX2)+1); done=1; } else if (q && strstr(q,YAMJ_PREFIX2)) { g_query=parse_query_string(q,g_query); //req = url_decode(q+strlen(YAMJ_PREFIX2)); req = url_decode(query_val("yamj")); yamj_xml(req); FREE(req); done=1; } else if (sp && (req=strstr(sp,YAMJ_PREFIX)) != NULL) { // If oversight script is launched as /oversight/yamj/xxxxx.xml // then use xxxxxx.xml as a yamj xml request. // This is to allow for Apache ModAlias to serve static images whilst calling oversight for CGI // The rewrite rules should be // ScriptAliasMatch ^/oversight/yamj/(.*).xml /share/Apps/oversight/oversight.cgi // AliasMatch ^/oversight/yamj/banner_(.*jpg) /oversight/db/global/_b/ovs_$1 // AliasMatch ^/oversight/yamj/fanart_(.*jpg) /oversight/db/global/_fa/ovs_$1 // AliasMatch ^/oversight/yamj/poster_(.*jpg) /oversight/db/global/_J/ovs_$1 // AliasMatch ^/oversight/yamj/thumb_(.*).jpg /oversight/db/global/_J/ovs_$1.thumb.jpg // AliasMatch ^/oversight/yamj/boxset_(.*).jpg /oversight/db/global/_J/ovs_$1.thumb.boxset.jpg` // req += strlen(YAMJ_PREFIX); yamj_xml(req); done=1; } else if (q == NULL || strchr(q,'=') == NULL ) { if (argc > 1 ) { if ( argv[1] && *argv[1] && argv[2] == NULL && util_starts_with(argv[1],YAMJ_PREFIX) ) { char *req = url_decode(argv[1]+strlen(YAMJ_PREFIX)); yamj_xml(req); FREE(req); done=1; } else if ( argv[1] && *argv[1] && argv[2] == NULL && strchr(argv[1],'=') == NULL) { // Single argument passed. // char *path = url_decode(argv[1]); char *dot = strrchr(path,'.'); if (dot < path) dot = strchr(path,'\0'); int result = 0; fprintf(stderr,"path=[%s]",path); // should really use file command or magic number to determine file type if (dot && STRCMP(dot,".png") == 0 ) { result = cat(CONTENT_TYPE"image/png",path); } else if (dot && STRCMP(dot,".jpg") == 0 ) { result = cat(CONTENT_TYPE"image/jpeg",path); } else if (dot && STRCMP(dot,".gif") == 0) { result = cat(CONTENT_TYPE"image/gif",path); } else if (dot && (STRCMP(dot,".swf") == 0 || STRCMP(dot,".phf" ) == 0) ) { result = cat(CONTENT_TYPE"application/x-shockwave-flash",path); } else if (browsing_from_lan() ) { if (is_dir(path)) { // load_configs(); // load configs so we can use file_to_url() functions result = ls(path); } else { int exists = is_file(path); char *all_headers = NULL; char *content_headers = NULL; if (exists) { if (strstr(path,".tar.gz") || strcmp(dot,".tgz") == 0) { ovs_asprintf(&content_headers,"%s%s\n%s%s", CONTENT_TYPE,"application/x-tar",CONTENT_ENC,"gzip"); } else if (strcmp(dot,".gz") == 0 ) { ovs_asprintf(&content_headers,"%s%s\n%s%s", CONTENT_TYPE,"application/x-gzip",CONTENT_ENC,"identity"); } else if (strcmp(dot,".html") == 0 ) { ovs_asprintf(&content_headers,"%s%s", CONTENT_TYPE,"text/html;charset=utf-8"); } else { ovs_asprintf(&content_headers,"%s%s", CONTENT_TYPE,"text/plain;charset=utf-8"); } } else { // .gz.txt is a fake extension added by the ls command to view log.gz inline without browser downloading. if (strstr(path,".gz.txt")) { ovs_asprintf(&content_headers,"%s%s\n%s%s", CONTENT_TYPE,"text/plain;charset=utf-8", CONTENT_ENC,"gzip"); // remove .txt to get real zip file. // .txt is needed so a certain browser displays inline. (might be other ways) *dot = '\0'; } else { // 404 error would be here } } ovs_asprintf(&all_headers,"%s\n%s%ld",content_headers,CONTENT_LENGTH,file_size(path)); FREE(content_headers); result = cat(all_headers,path); FREE(all_headers); } } FREE(path); fflush(stdout); done=1; } } } if (!done) { if (send_content_type_header) { printf("Content-Type: text/html; charset=utf-8\n\n"); start_page("CGI"); } else { start_page("WGET"); } html_log_level_set(2); load_configs(); //html_hashtable_dump(0,"settings",g_nmt_settings); long log_level; if (config_check_long(g_oversight_config,"ovs_log_level",&log_level)) { html_log_level_set(log_level); } html_comment("Appdir= [%s]",appDir()); //array_unittest(); //util_unittest(); //config_unittest(); g_query = string_string_hashtable("g_query2",16); html_comment("default query ... "); add_default_html_parameters(g_query); html_hashtable_dump(0,"prequery",g_query); html_comment("read query ... "); g_query=parse_query_string(getenv("QUERY_STRING"),g_query); html_hashtable_dump(0,"query",g_query); html_comment("read post ... "); struct hashtable *post=read_post_data(getenv("TEMP_FILE")); html_hashtable_dump(0,"post",g_query); html_comment("merge query and post data"); merge_hashtables(g_query,post,1); // post is destroyed html_hashtable_dump(0,"query final",g_query); #if 0 html_comment("utf8len expect 2 = %d",utf8len("Àa")); html_comment("utf8len expect 2 = %d",utf8len("àa")); html_comment("utf8len expect 2 = %d",utf8len("üa")); html_comment("utf8cmp_char 0 = %d",utf8cmp_char("üa","üb")); html_comment("utf8cmp_char !0 = %d",utf8cmp_char("üa","üa")); html_comment("utf8cmp_char 0 = %d",utf8cmp_char("a","a")); html_comment("utf8cmp_char !0 = %d",utf8cmp_char("a","b")); html_comment("utf8cmp_char !0 = %d",utf8cmp_char("üa","üa")); html_comment("utf8cmp_char !0 = %d",utf8cmp_char("a","üa")); Abet *a = abet_create("abcdefghijklmnopqrstuvwxyz"); html_comment("inc a %d",abet_letter_inc_or_add(a,"a",1)); html_comment("inc a %d",abet_letter_inc_or_add(a,"a",1)); html_comment("inc z %d",abet_letter_inc_or_add(a,"z",1)); html_comment("inc 4 %d",abet_letter_inc_or_add(a,"4",1)); html_comment("inc 5 %d",abet_letter_inc_or_add(a,"5",1)); html_comment("inc 5 %d",abet_letter_inc_or_add(a,"5",1)); html_comment("inc 6* %d",abet_letter_inc_or_add(a,"6",0)); html_comment("inc 7* %d",abet_letter_inc_or_add(a,"7",0)); html_comment("inc a %d",abet_letter_inc_or_add(a,"a",1)); abet_free(a); #endif config_read_dimensions(1); HTML_LOG(0,"Begin Actions"); do_actions(); ViewMode *view; DbSortedRows *sortedRows = NULL; while(1) { view=get_view_mode(1); HTML_LOG(0,"view mode = [%s]",view->name); // If movie view but all ids have been removed , then move up if (view == VIEW_MOVIE && !*query_val(QUERY_PARAM_IDLIST)) { query_pop(); view=get_view_mode(1); } sortedRows = get_sorted_rows_from_params(); dump_all_rows("sorted",sortedRows->num_rows,sortedRows->rows); // If it's not a tv/movie detail or boxset view then break if (view == VIEW_MENU || view == VIEW_ADMIN ) { break; } // Found some data - as we are on a smaller view - filter it if (sortedRows->num_rows && sortedRows->num_rows < 50 ) { int new_num = sortedRows->num_rows; int max_new = sortedRows->num_rows; DbItem **new_list = filter_page_items(0,sortedRows->num_rows,sortedRows->rows,max_new,&new_num); FREE(sortedRows->rows); sortedRows->rows = new_list; sortedRows->num_rows=new_num; } if (sortedRows->num_rows) break; // No data found in this view - try to return to the previous view. query_pop(); // Adjust config - // TODO Change the config structure to reload more efficiently. //reload_configs(); config_read_dimensions(1); // Now refetch all data again with new parameters. sorted_rows_free_all(sortedRows); HTML_LOG(0,"reparsing database"); } // Remove and store the last navigation cell. eg if user clicked on cell 12 this is passed in // the URL as @i=12. The url that returns to this page then has i=12. If we have returned to this // page we must remove i=12 from the query so that it is not passed to the new urls created for this // page. set_selected_item(); char *skin_name=get_skin_name(); if (strchr(skin_name,'/') || *skin_name == '.' || !*skin_name ) { html_error("Invalid skin name[%s]",skin_name); } else { playlist_open(); //exp_test(); if (view->view_class == VIEW_CLASS_ADMIN) { setPermissions(); display_admin(sortedRows); } else { char *template = query_val(QUERY_PARAM_TEMPLATE_NAME); if (EMPTY_STR(template)) {