void read_html_request(int fd, struct node* slaves){ char* request; char* dir; int c = 0; ssize_t len; int file_id = -1; request = malloc(100); c = read(fd, request, 100); printf("HTML REQUEST: %s\n", request); dir = strtok(request, " "); if(strcmp(dir, "/") == 0) { printf("UDERZAMY PO GŁÓWNĄ\n"); serve_files_page(fd); } else { file_id = atoi(strtok(dir, "/")); printf("UDERZAMY PO KONKRETNY PLIK NUMER: %d\n", file_id); serve_file(fd, file_id, slaves); } free(request); close(fd); }
/** * @brief authenticated - called for all request from authenticated clients. * @param connection * @param ip_addr * @param mac * @param url * @param client * @return * * It's unsual to received request from clients which are already authed. * Happens when the user: * - clicked in multiple windows on "accept" -> redirect to origin - no checking * - when the user reloaded a splashpage -> redirect to origin * - when a user calls deny url -> deauth it */ static int authenticated(struct MHD_Connection *connection, const char *ip_addr, const char *mac, const char *url, t_client *client) { s_config *config = config_get_config(); const char *redirect_url; const char *host = NULL; char redirect_to_us[128]; MHD_get_connection_values(connection, MHD_HEADER_KIND, get_host_value_callback, &host); if (is_splashpage(host, url) || check_authdir_match(url, config->authdir)) { redirect_url = get_redirect_url(connection); /* TODO: what should we do when we get such request? */ if (redirect_url == NULL || strlen(redirect_url) == 0) return show_splashpage(connection, client); else return authenticate_client(connection, ip_addr, mac, redirect_url, client); } else if (check_authdir_match(url, config->denydir)) { auth_client_action(ip_addr, mac, AUTH_MAKE_DEAUTHENTICATED); snprintf(redirect_to_us, 128, "http://%s:%u/", config->gw_address, config->gw_port); return send_redirect_temp(connection, redirect_to_us); } /* user doesn't wants the splashpage or tried to auth itself */ return serve_file(connection, client, url); }
static void *accept_request(void *arg) { char buf[1024]; char method [255]; char url[255]; char path[512]; /* int numchars; */ char *query_string = NULL; int cgi = 0; size_t i, j; struct stat st; int client = (int)(intptr_t)arg; /* numchars = get_line(client, buf, sizeof(buf)); */ get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!isspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; i = 0; while ((isspace(buf[j])) && (j < sizeof(buf))) j++; while ((!isspace(buf[j])) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\n')) query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } } puts(url); sprintf(path, "htdocs%s", url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (stat(path, &st) == -1) { not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); if (!cgi) serve_file(client, path); } close(client); return NULL; }
/* Thread: httpd */ static void httpd_gen_cb(struct evhttp_request *req, void *arg) { const char *req_uri; char *uri; char *ptr; req_uri = evhttp_request_get_uri(req); if (!req_uri) { redirect_to_index(req, "/"); return; } uri = strdup(req_uri); ptr = strchr(uri, '?'); if (ptr) { DPRINTF(E_SPAM, L_HTTPD, "Found query string\n"); *ptr = '\0'; } ptr = uri; uri = evhttp_decode_uri(uri); free(ptr); /* Dispatch protocol-specific URIs */ if (rsp_is_request(req, uri)) { rsp_request(req); goto out; } else if (daap_is_request(req, uri)) { daap_request(req); goto out; } else if (dacp_is_request(req, uri)) { dacp_request(req); goto out; } DPRINTF(E_DBG, L_HTTPD, "HTTP request: %s\n", uri); /* Serve web interface files */ serve_file(req, uri); out: free(uri); }
int main (int ac, char **av) { CC_SPORT *p = (CC_SPORT *) NULL; CC_SFILE *f = (CC_SFILE *) NULL; int rval = 0; if (parseargs (ac, av)) return 0; CCutil_signal_init (); if (debug) { printf ("Serving files for %s\n", probname); fflush (stdout); } p = CCutil_snet_listen (probport); if (p == (CC_SPORT *) NULL) { fprintf (stderr, "CCutil_snet_listen failed\n"); rval = 1; goto CLEANUP; } for (;;) { if (debug) { printf ("Waiting for connection\n"); fflush (stdout); } f = CCutil_snet_receive (p); if (f == (CC_SFILE *) NULL) { fprintf (stderr, "CCutil_snet_receive failed\n"); continue; } if (debug) { printf ("Received connection\n"); fflush (stdout); } rval = serve_file (f, probname, run_silently); if (rval) { fprintf (stderr, "serve_file failed\n"); if (CCutil_sclose (f)) { fprintf (stderr, "CCutil_sclose failed\n"); } continue; } if (debug) { printf ("Closing connection\n"); fflush (stdout); } rval = CCutil_sclose (f); if (rval) { fprintf (stderr, "CCutil_sclose failed\n"); } f = (CC_SFILE *) NULL; } CLEANUP: if (f != (CC_SFILE *) NULL) CCutil_sclose (f); if (p != (CC_SPORT *) NULL) CCutil_snet_unlisten (p); return rval; }
int main(int argc, char **argv) { int fd; int nfd; int c; /* process arguments */ while ((c = getopt(argc, argv, POS "d")) != -1) { switch (c) { case 'd': debug = 1; break; default: usage(); } } argc -= optind; argv += optind; if (argc != 2) usage(); fd = setup_listener(atoi(argv[0])); if (fd == -1) exit(1); /* don't bother reaping, this is a test program... */ signal(SIGCHLD, SIG_IGN); for (;;) { pid_t kid; nfd = accept(fd, NULL, NULL); kid = fork(); switch (kid) { case -1: /* XXXrcd: error. */ close(nfd); fprintf(stderr, "fork: %s\n", strerror(errno)); break; case 0: close(fd); serve_file(nfd, argv[1]); exit(0); default: close(nfd); break; } } }
/** * @brief preauthenticated - called for all request of a client in this state. * @param connection * @param ip_addr * @param mac * @return */ static int preauthenticated(struct MHD_Connection *connection, const char *ip_addr, const char *mac, const char *url, t_client *client) { char *host = NULL; const char *redirect_url; s_config *config = config_get_config(); if (!client) { client = add_client(ip_addr); if (!client) return send_error(connection, 503); } MHD_get_connection_values(connection, MHD_HEADER_KIND, get_host_value_callback, &host); /* check if this is a redirect querty with a foreign host as target */ if(is_foreign_hosts(connection, host)) { return redirect_to_splashpage(connection, client, host, url); } /* request is directed to us */ /* check if client wants to be authenticated */ if(check_authdir_match(url, config->authdir)) { /* Only the first request will redirected to config->redirectURL. * When the client reloads a page when it's authenticated, it should be redirected * to their origin url */ if (config->redirectURL) redirect_url = config->redirectURL; else redirect_url = get_redirect_url(connection); if (try_to_authenticate(connection, client, host, url)) { return authenticate_client(connection, ip_addr, mac, redirect_url, client); } else { /* user used an invalid token, redirect to splashpage but hold query "redir" intact */ return encode_and_redirect_to_splashpage(connection, redirect_url); } } if(is_splashpage(host, url)) { return show_splashpage(connection, client); } /* no special handling left - try to serve static content to the user */ return serve_file(connection, client, url); }
int httpd_response(struct client *cli, int code, char *reason) { Logger(LOG_INFO, 0, "%s...\n", __FUNCTION__); Logger(LOG_INFO, 0, "code:%d...\n", code); if (code == 0) { if ( cli->req.method == HTTP_MSG_GET ) { URL url; prase_url(cli->req.url, &url); serve_file(cli->clientfd, url.file_path); } } return 0; }
static void handle_clutch( struct evhttp_request * req, struct tr_rpc_server * server ) { const char * clutchDir = tr_getClutchDir( server->session ); assert( !strncmp( req->uri, "/transmission/web/", 18 ) ); if( !clutchDir || !*clutchDir ) { send_simple_response( req, HTTP_NOTFOUND, "<p>Couldn't find Transmission's web interface files!</p>" "<p>Users: to tell Transmission where to look, " "set the TRANSMISSION_WEB_HOME environmental " "variable to the folder where the web interface's " "index.html is located.</p>" "<p>Package Builders: to set a custom default at compile time, " "#define PACKAGE_DATA_DIR in libtransmission/platform.c " "or tweak tr_getClutchDir() by hand.</p>" ); } else { char * pch; char * subpath; char * filename; subpath = tr_strdup( req->uri + 18 ); if(( pch = strchr( subpath, '?' ))) *pch = '\0'; filename = tr_strdup_printf( "%s%s%s", clutchDir, TR_PATH_DELIMITER_STR, subpath && *subpath ? subpath : "index.html" ); serve_file( req, server, filename ); tr_free( filename ); tr_free( subpath ); } }
/** * @brief authenticated - called for all request from authenticated clients. * @param connection * @param ip_addr * @param mac * @param url * @param client * @return * * It's unsual to received request from clients which are already authed. * Happens when the user: * - clicked in multiple windows on "accept" -> redirect to origin - no checking * - when the user reloaded a splashpage -> redirect to origin * - when a user calls deny url -> deauth it */ static int authenticated(struct MHD_Connection *connection, const char *ip_addr, const char *mac, const char *url, t_client *client) { s_config *config = config_get_config(); const char *redirect_url; const char *host = NULL; char redirect_to_us[128]; MHD_get_connection_values(connection, MHD_HEADER_KIND, get_host_value_callback, &host); if (is_splashpage(host, url) || check_authdir_match(url, config->authdir)) { redirect_url = get_redirect_url(connection); /* TODO: what should we do when we get such request? */ if (redirect_url == NULL || strlen(redirect_url) == 0) return show_splashpage(connection, client); else return authenticate_client(connection, ip_addr, mac, redirect_url, client); } else if (check_authdir_match(url, config->denydir)) { auth_client_action(ip_addr, mac, AUTH_MAKE_DEAUTHENTICATED); snprintf(redirect_to_us, 128, "http://%s:%u/", config->gw_address, config->gw_port); return send_redirect_temp(connection, redirect_to_us); } /* check if this is an late request meaning the user tries to get the internet, but ended up here, * because the iptables rule came to late */ if (is_foreign_hosts(connection, host)) { /* might happen if the firewall rule isn't yet installed */ return send_refresh(connection); } /* user doesn't wants the splashpage or tried to auth itself */ return serve_file(connection, client, url); }
void* accept_request(void* client1) //accept_request解析header里面的第一行获得request method(get/post)和请求路径,映射到htdoc文件夹下的路径, //其中当对应的文件可执行的时候,就调用execute_cgi函数 { int client = (intptr_t)client1; char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); // 仅仅支持GET和POST方法,否则抛出未支持的方法 return NULL; } if (strcasecmp(method, "POST") == 0) cgi = 1; i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) j++; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } } sprintf(path, "htdocs%s", url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (stat(path, &st) == -1) { while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; if (!cgi) serve_file(client, path); else execute_cgi(client, path, method, query_string); } close(client); return NULL; }
void accept_request(int client) { char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf));//把client里的\r都换成\n i = 0; j = 0; //找出method是get还是post,只支持这两种方法 while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; //函数说明 strcasecmp()用来比较参数s1和s2字符串,比较时会自动忽略大小写的差异。 //返回值 若参数s1和s2字符串相等则返回0。s1大于s2则返回大于0 的值,s1 小于s2 则返回小于0的值。 if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client);//返回给浏览器表明收到的 HTTP 请求所用的 method 不被支持。 return; } if (strcasecmp(method, "POST") == 0) cgi = 1; i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) j++; //找出URL while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } } sprintf(path, "htdocs%s", url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (stat(path, &st) == -1) { while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; if (!cgi) serve_file(client, path); else execute_cgi(client, path, method, query_string); } close(client); }
void accept_request(nunetwork_socket client, struct nunetwork_headerstruct *headerbuf) { int auth_form = 0; int p = 0,i,t; char path[512], parameters[512]; char env_str[512]; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI program */ char *query_string = NULL; char *tmp_str = NULL; char *tmp_url = NULL; char *client_sid = " "; char method[5]; char url[256]; char header[256]; char value[256]; /* Vars for processing HTTP 304*/ /*enum en_day { Sun = 0, Mon, Tue, Wed, Thu, Fri, Sat} days; enum en_month { Jan = 0, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } months;*/ /*char *withoutsession[] = { "/netustad.css", "/authform", "/images/bg.png", "/images/buton_0.png", "/images/buton_1.png", "/images/buton_2.png", "/images/buton_3.png", "/images/buton_4.png", "/images/buton_5.png", "/images/buton_6.png", "/images/buton_7.png", "/images/banner.png", "/images/banner-alt.png", "/images/menu_login.png", "/images/menu_rulelist.png", "/images/menu_addrule.png", "/images/menu_logout.png", NULL }; int ifwithoutsession=0;*/ /*struct tm zamanstr; time_t zaman_t; char str4[5]="123";*/ char *start; /*****************************************/ /* Processing the header buffer */ /* GET request is saved to be processed at the end*/ for (t=0; t< headerbuf->number_of_headers; t++) { if (!strcasecmp(headerbuf->headers[t].header_id, "POST") ) { /* sorry maybe next time */ unimplemented(client); return; } else if (!strcasecmp(headerbuf->headers[t].header_id, "HEAD")) { tmp_url = strdup(headerbuf->headers[t].header_value); /*Getting the requested url */ start = headerbuf->headers[t].header_value; while (*start!=' ' || *start!='\t') start++; tmp_url = strstr(start, "HTTP/") - 1; while ( *tmp_url!= ' ' || *tmp_url != '\t' ) tmp_url--; snprintf(url, tmp_url - start + 1, "script%s", start ); headers(client, url); return; } else if (!strcasecmp(headerbuf->headers[t].header_id, "GET")) { /* this is it ... getting the method and the url without HTTP id */ strncpy(method, headerbuf->headers[t].header_id, sizeof(method)); strncpy(url, headerbuf->headers[t].header_value, sizeof(url)); i=0; while(url[i++]!=' '); url[i-1]='\0'; /*} else if (!strcasecmp(headerbuf->headers[t].header_id, "If-Modified-Since")) {*/ /* Processing If-Modified-Since header value if its not related with cgis */ /*if ( (strstr(url, ".png")!=NULL && strstr(url, "images")!=NULL) || strstr(url, "netustad.css") ) {*/ /* Getting Day */ /* HTTP/1.1 304 Not Modified Date: Fri, 31 Dec 1999 23:59:59 GMT */ /*start = headerbuf->headers[t].header_value; if (strlen(start)>10) { while (*start==' ') start++; start+=5; snprintf(str4, 2, start, "%s"); zamanstr.tm_mday=atoi(start); start+=2; snprintf(str4, 3, start, "%s"); zamanstr.tm_mon=months[str4]; start+=4; snprintf(str4, 4, start, "%s"); zamanstr.tm_year= atoi(str4)-1900; start+=5; snprintf(str4, 2, start, "%s"); zamanstr.tm_hour=atoi(str4); start+=3; snprintf(str4, 2, start, "%s"); zamanstr.tm_min=atoi(str4); start+=3; snprintf(str4, 2, start, "%s"); zamanstr.tm_sec=atoi(str4); zamanstr.tm_isdst=-1; zaman_t = mktime(&zamanstr); } }*/ } } query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } /*******************/ /* Parse SessionID */ /*******************/ if (query_string[0] == 0) { tmp_str = url; tmp_url = strtok(tmp_str, "$\n"); while (tmp_url != NULL && (int) p <= (int) strlen(value)) value[p++] = *tmp_url++; } else { tmp_str = strdup(query_string); query_string = strtok(tmp_str, "$\n"); } client_sid = strtok(NULL, "$\n"); if (client_sid == 0) client_sid = "$"; /****************************/ /* add script folder to url */ /****************************/ snprintf(path, sizeof (path)-1, "script%s", url); /*****************************/ /* Check Unwanted Characters */ /*****************************/ if (strstr(path, "..") != NULL) { server_sid[0] = '$'; server_sid[1] = '\0'; snprintf(parameters, sizeof (parameters)-1, " -- %s: %s. %s: %s\n", (char *) gettext("Bad Request From"), (char *) inet_ntoa(client_name.sin_addr), (char *) gettext("The Request is"), (char *) path); log_msg(mainlogfile, parameters, 1); log_msg(mainlogfile, gettext("Session Killed Because of Bad Request\n"), 1); snprintf(auth_msg, sizeof (auth_msg)-1, " "); auth_form = 1; } /************************/ /* Check Session Expire */ /************************/ time(¤tsec); if ((long) currentsec - (long) lastactionsec <= sesexpiretime) { /* Session Not Expired */ time(&lastactionsec); } else { /* Session Expired, close session */ server_sid[0] = '$'; server_sid[1] = '\0'; if (!(rightcmp(path, "/netustad.css") ||\ rightcmp(path, "/authform") ||\ rightcmp(path, "/images/bg.png") ||\ rightcmp(path, "/images/buton_0.png") ||\ rightcmp(path, "/images/buton_1.png") ||\ rightcmp(path, "/images/buton_2.png") ||\ rightcmp(path, "/images/buton_3.png") ||\ rightcmp(path, "/images/buton_4.png") ||\ rightcmp(path, "/images/buton_5.png") ||\ rightcmp(path, "/images/buton_6.png") ||\ rightcmp(path, "/images/buton_7.png") ||\ rightcmp(path, "/images/banner.png") ||\ rightcmp(path, "/images/banner-alt.png") ||\ rightcmp(path, "/images/editor.png") ||\ rightcmp(path, "/images/eraser.png") ||\ rightcmp(path, "/images/menu_rulelist.png") ||\ rightcmp(path, "/images/menu_addrule.png") ||\ rightcmp(path, "/images/menu_logout.png") ||\ rightcmp(path, "/images/menu_login.png"))) { log_msg(mainlogfile, gettext("Administrator's Session Expired!\n"), 1); } /*t=0; while (withoutsession[t]!=NULL && !rightcmp(path, withoutsession[t])) { t++; } if (withoutsession[t]!=NULL && !rightcmp(path, withoutsession[t])) { log_msg(mainlogfile, gettext("Administrator's Session Expired!\n"), 1); } else { ifwithoutsession=1; }*/ snprintf(auth_msg, sizeof (auth_msg)-1, gettext("Session Expired!")); auth_form = 1; } /********************/ /* Check Session ID */ /********************/ if (strcmp(server_sid, "$") != 0 && *client_sid != '$') if (strcmp(client_sid, server_sid) != 0 || strcmp(client_ip, (char *) inet_ntoa(client_name.sin_addr)) != 0) { snprintf(auth_msg, sizeof (auth_msg)-1, gettext("You are not logged in!")); auth_form = 1; } else auth_form = 0; else { if ((long) lastactionsec == 0) snprintf(auth_msg, sizeof (auth_msg)-1, " "); auth_form = 1; } /********************************/ /* Define Environment Variables */ /********************************/ snprintf(env_str, sizeof (env_str)-1, "netustadversion=%s", NUVERSION); env_p[0] = strdup(env_str); /* netustad version */ snprintf(env_str, sizeof (env_str)-1, "work_path=%s/script", workdir); env_p[1] = strdup(env_str); /* work_path */ env_p[2] = "auth_msg="; /* authform message */ snprintf(env_str, sizeof (env_str)-1, "server_sid=%s", server_sid); env_p[3] = strdup(env_str); /* server session id */ snprintf(env_str, sizeof (env_str)-1, "fw_cmd=%s", fw_cmd); env_p[4] = strdup(env_str); /* iptables command */ snprintf(env_str, sizeof (env_str)-1, "TEXTDOMAIN=%s", PACKAGE); env_p[5] = strdup(env_str); /* TEXTDOMAIN (for gettext) */ snprintf(env_str, sizeof (env_str)-1, "TEXTDOMAINDIR=%s", PACKAGE_LOCALE_DIR); env_p[6] = strdup(env_str); /* TEXTDOMAINDIR (for gettext) */ snprintf(env_str, sizeof (env_str)-1, "LC_ALL=%s", lc_all ); env_p[7] = strdup(env_str); /* Choose locale */ snprintf(env_str, sizeof (env_str)-1, "gettext_cmd=%s", gettext_cmd); env_p[8] = strdup(env_str); /* gettext command */ snprintf(env_str, sizeof (env_str)-1, "cat_cmd=%s", cat_cmd); env_p[9] = strdup(env_str); /* full path of cat command */ snprintf(env_str, sizeof (env_str)-1, "awk_cmd=%s", awk_cmd); env_p[10] = strdup(env_str); /* full path of awk command */ snprintf(env_str, sizeof (env_str)-1, "MM_CHARSET=%s", gettext("charset")); env_p[11] = strdup(env_str); /* charset environ */ snprintf(env_str, sizeof (env_str)-1, "LANG=%s", lc_all ); env_p[12] = strdup(env_str); /* LANG environ */ snprintf(env_str, sizeof (env_str)-1, "netstat_cmd=%s", netstat_cmd ); env_p[13] = strdup(env_str); /* netstat_cmd environ */ snprintf(env_str, sizeof (env_str)-1, "grep_cmd=%s", grep_cmd ); env_p[14] = strdup(env_str); /* grep_cmd environ */ snprintf(env_str, sizeof (env_str)-1, "tr_cmd=%s", tr_cmd ); env_p[15] = strdup(env_str); /* tr_cmd environ */ snprintf(env_str, sizeof (env_str)-1, "sed_cmd=%s", sed_cmd ); env_p[16] = strdup(env_str); /* sed_cmd environ */ snprintf(env_str, sizeof (env_str)-1, "tail_cmd=%s", tail_cmd ); env_p[17] = strdup(env_str); /* tail_cmd environ */ snprintf(env_str, sizeof (env_str)-1, "route_cmd=%s", route_cmd ); env_p[18] = strdup(env_str); /* route_cmd environ */ snprintf(env_str, sizeof (env_str)-1, "QUERY_STRING=a"); env_p[19] = strdup(env_str); /* QUERY_STRING environ */ snprintf(env_str, sizeof (env_str)-1, "ifconfig_cmd=%s", ifconfig_cmd ); env_p[20] = strdup(env_str); /* ifconfig_cmd environ */ env_p[21] = NULL; /*temporary variable */ env_p[22] = NULL; /*temporary variable */ env_p[23] = NULL; /*parameter terminate */ /***************************/ /* Parse Requested Address */ /***************************/ /* If Logout Requested Close Session and Goto Auth */ if (rightcmp(path, "/logout")) { server_sid[0] = '$'; server_sid[1] = '\0'; snprintf(auth_msg, sizeof (auth_msg)-1, gettext("You are logged out")); log_msg(mainlogfile, gettext("Administrator logged out\n"), 1); auth_form = 1; /*} else if (ifwithoutsession && strcmp(withoutsession[t], "/authform")!=0) { snprintf(path, sizeof(path)-1, "script%s", withoutsession[t]); }*/ } else if (rightcmp(path, "/images/bg.png")) { snprintf(path, sizeof (path)-1, "script/images/bg.png"); } else if (rightcmp(path, "/images/buton_0.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_0.png"); } else if (rightcmp(path, "/images/buton_1.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_1.png"); } else if (rightcmp(path, "/images/buton_2.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_2.png"); } else if (rightcmp(path, "/images/buton_3.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_3.png"); } else if (rightcmp(path, "/images/menu_login.png")) { snprintf(path, sizeof(path)-1, "script/images/menu_login.png"); } else if (rightcmp(path, "/images/menu_logout.png")) { snprintf(path, sizeof(path)-1, "script/images/menu_logout.png"); } else if (rightcmp(path, "/images/menu_addrule.png")) { snprintf(path, sizeof(path)-1, "script/images/menu_addrule.png"); } else if (rightcmp(path, "/images/menu_rulelist.png")) { snprintf(path, sizeof(path)-1, "script/images/menu_rulelist.png"); } else if (rightcmp(path, "/images/buton_4.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_4.png"); } else if (rightcmp(path, "/images/buton_5.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_5.png"); } else if (rightcmp(path, "/images/buton_7.png")) { snprintf(path, sizeof(path)-1, "script/images/buton_7.png"); } else if (rightcmp(path, "/images/banner.png")) { snprintf(path, sizeof(path)-1, "script/images/banner.png"); } else if (rightcmp(path, "/images/banner-alt.png")) { snprintf(path, sizeof(path)-1, "script/images/banner-alt.png"); } else if (rightcmp(path, "/images/editor.png")) { snprintf(path, sizeof(path)-1, "script/images/editor.png"); } else if (rightcmp(path, "/images/eraser.png")) { snprintf(path, sizeof(path)-1, "script/images/eraser.png"); } else if (rightcmp(path, "/netustad.css")) { snprintf(path, sizeof(path)-1, "script/netustad.css"); } /* Other Requests */ if (auth_form == 1 && \ !(rightcmp(path, "/auth")) && \ !(rightcmp(path, "/netustad.css")) && \ !(rightcmp(path, "/images/bg.png")) && \ !(rightcmp(path, "/images/buton_0.png")) && \ !(rightcmp(path, "/images/buton_1.png")) && \ !(rightcmp(path, "/images/buton_2.png")) && \ !(rightcmp(path, "/images/buton_3.png")) && \ !(rightcmp(path, "/images/buton_4.png")) && \ !(rightcmp(path, "/images/buton_5.png")) && \ !(rightcmp(path, "/images/buton_6.png")) && \ !(rightcmp(path, "/images/buton_7.png")) && \ !(rightcmp(path, "/images/banner.png")) && \ !(rightcmp(path, "/images/banner-alt.png")) && \ !(rightcmp(path, "/images/editor.png")) && \ !(rightcmp(path, "/images/eraser.png")) && \ !(rightcmp(path, "/images/menu_logout.png")) && \ !(rightcmp(path, "/images/menu_addrule.png")) && \ !(rightcmp(path, "/images/menu_rulelist.png")) && \ !(rightcmp(path, "/images/menu_login.png"))) { snprintf(env_str, sizeof (env_str)-1, "auth_msg=%s", auth_msg); env_p[2] = strdup(env_str); snprintf(path, sizeof (path)-1, "script/authform"); } else if (path[strlen(path) - 1] == '/') { strncat(path, "showrule", (size_t) (sizeof (path) - 1 - strlen(path))); } else if (rightcmp(path, "/edit")) { snprintf(env_str, sizeof (env_str)-1, "ruleno=%s", strtok(query_string,"@\n")); env_p[21] = strdup(env_str); #ifdef LINUX snprintf(env_str, sizeof (env_str)-1, "chain=%s", strtok(NULL,"@\n")); env_p[22] = strdup(env_str); #endif strncat(path, "form", (size_t) (sizeof (path) - 1 - strlen(path))); } else if (rightcmp(path, "/if_edit")) { snprintf(env_str, sizeof (env_str)-1, "if_name=%s", strtok(query_string,"@\n")); env_p[21] = strdup(env_str); snprintf(path, sizeof(path)-1, "script/if_edit"); } else if (rightcmp(path, "/nat_del")) { snprintf(env_str, sizeof (env_str)-1, "nat_name=%s", strtok(query_string,"@\n")); env_p[21] = strdup(env_str); snprintf(path, sizeof(path)-1, "script/nat_del"); } else if (rightcmp(path, "/rt_del")) { snprintf(env_str, sizeof (env_str)-1, "route=%s", strtok(query_string,"@\n")); env_p[21] = strdup(env_str); snprintf(path, sizeof(path)-1, "script/rt_del"); } else if (rightcmp(path, "/auth") && auth_form == 1) { snprintf(path, sizeof (path)-1, "%s", auth(query_string)); snprintf(env_str, sizeof (env_str)-1, "auth_msg=%s", auth_msg); env_p[2] = strdup(env_str); snprintf(env_str, sizeof (env_str)-1, "server_sid=%s", server_sid); env_p[3] = strdup(env_str); #ifdef FREEBSD } else if (rightcmp(path, "/write")) { snprintf(path, sizeof(path)-1, "script/writeconfig"); #endif } /* If Rule Deleting Requested ("del" word) */ if (rightcmp(path, "/del")) { strncpy(path, fw_cmd, sizeof (path)-1); deleterule(client, path, header, query_string); } else if (rightcmp(path, "/addnew")) { strncpy(path, fw_cmd, sizeof (path)-1); addnewrule(client, path, header, query_string); } else if (rightcmp(path, "/applyedit")) { strncpy(path, fw_cmd, sizeof (path)-1); editrule(client, path, header, query_string); } else if (stat(path, &st) == -1) { snprintf(log_msg_text, sizeof(log_msg_text)-1, gettext("File not found: %s"), path); log_msg(logfile, log_msg_text, 1); not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) strncat(path, "/showrule", (size_t) (sizeof (path) - 1 - strlen(path))); if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH)) cgi = 1; if (!cgi) serve_file(client, path); else snprintf(env_str, sizeof (env_str)-1, "QUERY_STRING=%s", query_string); env_p[19] = strdup(env_str); /* QUERY_STRING environ */ execute_cgi(client, path, header, query_string, env_p, 1); } return; }
// Handle input from an HTTP socket. void process_http_cb(socket_t *socket) { int used; connection_t *ptr = ilist_fetch(connections, socket->fd); if (ptr == NULL) { printf("%d: Tried to get from list, but got NULL.\n", socket->fd); return; } if (ptr->is_websocket) { // Try to decode a frame. frame_t *f = read_frame(socket->rbuf, socket->rbuf_len, &used); if (f == NULL) { return; } // TODO: Consume instead. bcopy(socket->rbuf, socket->rbuf + used, socket->rbuf_len - used); socket->rbuf_len -= used; char *p = malloc(f->len + 1); strncpy(p, f->payload, f->len); p[f->len] = 0; cmd_t *cmd = parse_msg(p); if (cmd != NULL && cmd->type == CMD_EXECUTE) { process_t *p = execute_cmd((cmd_execute_t *)cmd); ilist_insert(processes, p); sock_pid_t *sp = malloc(sizeof(sock_pid_t)); sp->socket = socket; sp->pid = p; // Write new_process message? char format[] = "{\"newProcess\" : {" "\"pid\" : %d, \"command\" : \"%s\"," "\"startTime\" : %ld," "\"requestId\" : %d}}"; char str[1000]; struct timeval tp; gettimeofday(&tp, NULL); long int time = tp.tv_sec * 1000 + tp.tv_usec; sprintf(str, format, p->pid, ((cmd_execute_t*)cmd)->command_str, time, ((cmd_execute_t*)cmd)->request_id); frame_t *frame = malloc(sizeof(frame_t *)); frame->fin = 1; frame->len = strlen(str); frame->opcode = WS_OP_BIN; frame->payload = str; int fr_len; char *fr_str = write_frame(frame, &fr_len); socket_write(socket, fr_str, fr_len); socket_new(p->out, &process_child_out_cb, sp, socket); ev_child *child_watcher = (struct ev_child*) malloc (sizeof(struct ev_child)); ev_child_init (child_watcher, child_cb, p->pid, 1); child_watcher->data = socket; ev_child_start(loop, child_watcher); } free(f->payload); free(f); free(p); return; } request_t *req = parse_request(socket->rbuf, socket->rbuf_len, &used); if (req) { printf("%d: New Request: %s %s\n", socket->fd, req->method, req->uri); // Take it out of the read buffer. // TODO: Consume bcopy(socket->rbuf, socket->rbuf + used, socket->rbuf_len - used); socket->rbuf_len -= used; // Got a request! int upgraded = try_upgrade(req, ptr); if (upgraded) { printf("%d: Upgraded to WebSocket!\n", socket->fd); } else if (!strcmp(req->uri, "/")) { serve_file(socket, "static/index.html"); } else if (!strcmp(req->uri, "/tnrl.js")) { serve_file(socket, "static/tnrl.js"); } else if (!strcmp(req->uri, "/tnrl.css")) { serve_file(socket, "static/tnrl.css"); } else if (!strcmp(req->uri, "/favicon.ico")) { serve_file(socket, "static/favicon.ico"); } else { // Unknown URL? char *str = "HTTP/1.1 404 Not Found\r\n\r\n"; socket_write(socket, str, strlen(str)); } request_delete(req); } //printf("%s", buf); }
void accept_request(void *arg){ int client = *(int*)arg; char buf[1024]; size_t numchars; char method[255]; char url[255]; char path[512]; char *query_string = NULL; struct stat st; size_t i, j; numchars = get_line(client, buf, sizeof(buf)); i = 0; while(!ISSPace(buf[i]) && i < numchars){ method[i] = buf[i]; i++; } method[i] = '\0'; if(strcasecmp(method, "GET") && strcasecmp(method, "POST")){//只处理GET和POST请求 unimplemented(client); return; } j = 0; while(ISSPace(buf[i]) && i < numchars){ i++; } while(!ISSPace(buf[i]) && i < numchars){ url[j] = buf[i]; i++; j++; } url[j] = '\0'; if(strcasecmp(method, "GET") == 0){ query_string = url; while((*query_string != '?') && (*query_string != '\0')){ query_string++; } if(*query_string == '?'){ *query_string = '\0'; query_string++; } } sprintf(path, "htdcos%s", url); if(path[strlen(path)-1] == '/'){ strcat(path, "index.html"); } if(stat(path, &st) == -1){ while(numchars > 0 && strcmp("\n", buf)){ numchars = get_line(client, buf, sizeof(buf)); } not_found(client); printf("not found acc\n"); }else{ if((st.st_mode & S_IFMT) == S_IFDIR){ strcat(path, "/index.html"); } serve_file(client, path); } printf("method: %s\n", method); printf("url: %s\n", url); printf("path: %s\n", path); close(client); }
void accept_request(int client) { char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; //int cgi = 0; /* becomes true if server decides this is a CGI program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); close(client); return; } /* if (strcasecmp(method, "POST") == 0) cgi = 1; */ i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) j++; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { // cgi = 1; *query_string = '\0'; query_string++; } } /* serve_gpio_request(client, NULL); */ logMessage (LOG_DEBUG,"HTTPD processing %s %s\n",url, query_string); if ( strcmp(url, "/gpio") == 0 || strcmp(url, "/gpio/") == 0) { serve_gpio_request(client, query_string); } else if ( strcmp(url, "/led") == 0 || strcmp(url, "/led/") == 0) { serve_led_request(client, query_string); } else if ( strcmp(url, "/mh") == 0 || strcmp(url, "/mh/") == 0) { serve_meteohub_request(client, query_string); } else { if ( _gpioconfig_.docroot != 0 ) sprintf(path, "%s/%s", _gpioconfig_.docroot, url); else sprintf(path, "htdocs%s", url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (stat(path, &st) == -1) { while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) { while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { serve_file(client, path); } /* put cgi in here in the future */ } } close(client); }
/* ******************************** * @描述:处理客户端HTTP请求 * @输入:[in] client: 客户端地址 * @输出: 无 * ********************************/ void accept_request(int client) { char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; // unsigned int struct stat st; // 保存文件信息 int cgi = 0; // 当服务端认为它是一个CGI时变成1 char *query_string = NULL; /* 得到请求的第一行 */ numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; /* 把客户端的请求方法存到method数组,遇到空格则停止 */ while(!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; /* 既不是GET也不是POST的情况,忽略大小写进行比较 */ if(strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); return; } /* POST的情况,开启CGI */ if(strcasecmp(method, "POST") == 0) cgi = 1; /* 读取URL地址 */ i = 0; while(ISspace(buf[j]) && (j < sizeof(buf)))// 过滤掉空格 j++; while(!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; // 存下URL i++; j++; } url[i] = '\0'; /* 处理GET方法 */ if(strcasecmp(method, "GET") == 0) { query_string = url; /* 找到URL中的? */ while((*query_string != '?') && (*query_string != '\0')) query_string++; /* GET方法特点,?后面为参数 */ if(*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; //query_string指向'?'后面 } } /* 格式化URL到path数组,html文件在htdocs目录中 */ sprintf(path, "htdocs%s", url); /* 默认情况为index.html */ if(path[strlen(path) - 1] == '/')// path中最后一个字符 strcat(path, "index.html"); /* 根据路径找到对应文件 */ if(stat(path, &st) == -1) // 通过文件名path获取文件信息,并保存到st中,-1表示失败 { /* 读取并丢弃header */ while((numchars > 0) && strcmp("\n", buf))// strcmp 相等返回0 numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { /* 如果是目录,则默认使用该目录下的index.html 文件*/ if((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); if((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; if(!cgi) // cgi == 0 serve_file(client, path); else // cgi == 1 execute_cgi(client, path, method, query_string); } /* 断开与客户端的连接 */ close(client); }
void accept_request(int client) { char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI program */ char *query_string = NULL; /*得到请求的第一行*/ numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; /*把客户端的请求方法存到 method 数组*/ while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; /*如果既不是 GET 又不是 POST 则无法处理 */ if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); return; } /* POST 的时候开启 cgi */ if (strcasecmp(method, "POST") == 0) cgi = 1; /*读取 url 地址*/ i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) j++; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { /*存下 url */ url[i] = buf[j]; i++; j++; } url[i] = '\0'; /*处理 GET 方法*/ if (strcasecmp(method, "GET") == 0) { /* 待处理请求为 url */ query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; /* GET 方法特点,? 后面为参数*/ if (*query_string == '?') { /*开启 cgi */ cgi = 1; *query_string = '\0'; query_string++; } } /*格式化 url 到 path 数组,html 文件都在 htdocs 中*/ sprintf(path, "htdocs%s", url); /*默认情况为 index.html */ if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); /*根据路径找到对应文件 */ if (stat(path, &st) == -1) { /*把所有 headers 的信息都丢弃*/ while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); /*回应客户端找不到*/ not_found(client); } else { /*如果是个目录,则默认使用该目录下 index.html 文件*/ if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; /*不是 cgi,直接把服务器文件返回,否则执行 cgi */ if (!cgi) serve_file(client, path); else execute_cgi(client, path, method, query_string); } /*断开与客户端的连接(HTTP 特点:无连接)*/ close(client); }
int serve(int *clientSocket, http_message *message) { int bytecount = 0; // SLOG(INFO, "A new HTTP request has been received <%s>.", message->request_uri); if (message->request_uri) { if (strncmp(message->request_uri, URI_FILE, strlen(URI_FILE)) == 0) { std::string uri(message->request_uri); std::string app, filepath; std::size_t found = uri.find_first_of('/',strlen(URI_FILE)); if(found) { app = uri.substr(strlen(URI_FILE),found - strlen(URI_FILE)); filepath = uri.substr(found+1); } if (message->method == 1) // GET { bytecount = serve_file(clientSocket, message, filepath.c_str()); } else if (message->method == 3) // POST { bytecount = recv_file(clientSocket, message, filepath.c_str()); if(bytecount>0) { onCMDEvent(app, filepath); } } else { bytecount = serve_error(clientSocket, "400 Bad Request"); } } else if (strncmp(message->request_uri, URI_SIGCHECK, strlen(URI_SIGCHECK)) == 0) { char *filepath = message->request_uri + strlen(URI_SIGCHECK); // bytecount = serve_sigcheck(clientSocket, message, filepath); } else if (strncmp(message->request_uri, URI_PING, strlen(URI_PING)) == 0) { bytecount = serve_ping(clientSocket, message); } else if (strncmp(message->request_uri, URI_RUN, strlen(URI_RUN)) == 0) { char *filepath = message->request_uri + strlen(URI_RUN); bytecount = serve_run(clientSocket, message, filepath); } else if (strncmp(message->request_uri, URI_OPEN, strlen(URI_OPEN)) == 0) { char *filepath = message->request_uri + strlen(URI_OPEN); bytecount = serve_open(clientSocket, message, filepath); } else if (strncmp(message->request_uri, URI_EXPLORER, strlen(URI_EXPLORER)) == 0) { // bytecount = serve_explorer(clientSocket, message); } else if (strncmp(message->request_uri, URI_CLEANTEMP, strlen(URI_CLEANTEMP)) == 0) { bytecount = serve_cleantemp(clientSocket, message); } else if (strncmp(message->request_uri, URI_START, strlen(URI_START)) == 0) { // bytecount = serve_start(clientSocket, message); } else if (strncmp(message->request_uri, URI_STOP, strlen(URI_STOP)) == 0) { // bytecount = serve_stop(clientSocket, message); } else if (strncmp(message->request_uri, URI_SCREENSHOT, strlen(URI_SCREENSHOT)) == 0) { // bytecount = serve_screenshot(clientSocket, message); } else if (strncmp(message->request_uri, URI_EVENTS, strlen(URI_EVENTS)) == 0) { // bytecount = serve_events(clientSocket, message); } else if (strncmp(message->request_uri, URI_DATA_POLLUTION, strlen(URI_DATA_POLLUTION)) == 0) { bytecount = serve_data_pollution(clientSocket, message); } else { //LOG(WARN,"Bad request: %s\n", message->request_uri); bytecount = serve_error(clientSocket, "400 Bad Request"); } } else { // TODO empty request URI bytecount = serve_error(clientSocket, "400 Bad Request"); } //LOG(INFO,"Sent bytes %d\n", bytecount); return bytecount; }
void* accept_request(void* arg) { int client=(int)arg; char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0;/* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; //解析method:GET OR POST? while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); return NULL; } //如果method为POST,则开启CGI; if (strcasecmp(method, "POST") == 0) cgi = 1; i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) j++; //获取method对应的url,例如:url=/color.cgi?color=red; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; //如果method为GET,判断url中是否有CGI; if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } } sprintf(path, "htdocs%s", url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (stat(path, &st) == -1) { while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); //如果path指定的文件为可执行文件,则CGI置位; if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; if (!cgi) serve_file(client, path); else execute_cgi(client, path, method, query_string); } close(client); return NULL; }
void accept_request(void *arg) { int client = *((int*)arg); char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; //读http 请求的第一行数据(request line),把请求方法存进 method 中 numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; //如果请求的方法不是 GET 或 POST 任意一个的话就直接发送 response 告诉客户端没实现该方法 if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); return; } //如果是 POST 方法就将 cgi 标志变量置一(true) if (strcasecmp(method, "POST") == 0) cgi = 1; i = 0; //跳过所有的空白字符(空格) while (ISspace(buf[j]) && (j < sizeof(buf))) j++; //然后把 URL 读出来放到 url 数组中 while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; //如果这个请求是一个 GET 方法的话 if (strcasecmp(method, "GET") == 0) { //用一个指针指向 url query_string = url; //去遍历这个 url,跳过字符 ?前面的所有字符,如果遍历完毕也没找到字符 ?则退出循环 while ((*query_string != '?') && (*query_string != '\0')) query_string++; //退出循环后检查当前的字符是 ?还是字符串(url)的结尾 if (*query_string == '?') { //如果是 ? 的话,证明这个请求需要调用 cgi,将 cgi 标志变量置一(true) cgi = 1; //从字符 ? 处把字符串 url 给分隔会两份 *query_string = '\0'; //使指针指向字符 ?后面的那个字符 query_string++; } } //将前面分隔两份的前面那份字符串,拼接在字符串htdocs的后面之后就输出存储到数组 path 中。相当于现在 path 中存储着一个字符串 sprintf(path, "htdocs%s", url); //如果 path 数组中的这个字符串的最后一个字符是以字符 / 结尾的话,就拼接上一个"index.html"的字符串。首页的意思 if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); //在系统上去查询该文件是否存在 if (stat(path, &st) == -1) { //如果不存在,那把这次 http 的请求后续的内容(head 和 body)全部读完并忽略 while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); //然后返回一个找不到文件的 response 给客户端 not_found(client); } else { LOG_INFO("accept request 1"); //文件存在,那去跟常量S_IFMT相与,相与之后的值可以用来判断该文件是什么类型的 //S_IFMT参读《TLPI》P281,与下面的三个常量一样是包含在<sys/stat.h> if ((st.st_mode & S_IFMT) == S_IFDIR) //如果这个文件是个目录,那就需要再在 path 后面拼接一个"/index.html"的字符串 strcat(path, "/index.html"); //S_IXUSR, S_IXGRP, S_IXOTH三者可以参读《TLPI》P295 if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) //如果这个文件是一个可执行文件,不论是属于用户/组/其他这三者类型的,就将 cgi 标志变量置一 cgi = 1; if (!cgi) //如果不需要 cgi 机制的话, serve_file(client, path); else //如果需要则调用 execute_cgi(client, path, method, query_string); } LOG_INFO("accept request end"); close(client); }
void accept_request(int client) { char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); i = 0; j = 0; while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } method[i] = '\0'; if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) { unimplemented(client); return; } if (strcasecmp(method, "POST") == 0) cgi = 1; i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) j++; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } url[i] = '\0'; if (strcasecmp(method, "GET") == 0) { query_string = url; while ((*query_string != '?') && (*query_string != '\0')) query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; query_string++; } } //sprintf(path, "htdocs%s", url); sprintf(path, ".%s", url); if (path[strlen(path) - 1] == '/') strcat(path, "index.html"); if (stat(path, &st) == -1) { while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ numchars = get_line(client, buf, sizeof(buf)); not_found(client); } else { if ((st.st_mode & S_IFMT) == S_IFDIR) strcat(path, "/index.html"); if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) cgi = 1; cgi = 0;//must not cgi if (!cgi) serve_file(client, path); else execute_cgi(client, path, method, query_string); } close(client); }
// 处理客户端请求,服务器核心控制逻辑 void accept_request(int client) { char buf[1024]; int numchars; char method[255]; char url[255]; char path[512]; size_t i, j; struct stat st; int cgi = 0; /* becomes true if server decides this is a CGI * program */ char *query_string = NULL; numchars = get_line(client, buf, sizeof(buf)); // 读取请求行 i = 0; j = 0; while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) { method[i] = buf[j]; i++; j++; } // 循环截取出请求方法 method[i] = '\0'; if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) // 只接收GET和POST请求 { unimplemented(client); // 响应未实现页面 return; } if (strcasecmp(method, "POST") == 0) // POST请求 cgi = 1; i = 0; while (ISspace(buf[j]) && (j < sizeof(buf))) // 刚才截取method后j定位到后面的一个空格处,现在一直向后移动j直到指向非空白字符 j++; while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) { url[i] = buf[j]; i++; j++; } // 循环截取出请求的url资源 url[i] = '\0'; if (strcasecmp(method, "GET") == 0) // GET请求 { query_string = url; // 查询字符串在url中的?号后面 while ((*query_string != '?') && (*query_string != '\0')) // 一直移动到?号处 query_string++; if (*query_string == '?') { cgi = 1; *query_string = '\0'; // ?号置为\0,url就切出来了 query_string++; // 查询字符串从?后面一个字符开始 } } sprintf(path, "htdocs%s", url); // htdocs/url/ htdocs/res.html if (path[strlen(path) - 1] == '/') // 最后一个字符是‘/’,默认访问该目录下的 index.html 页面 strcat(path, "index.html"); if (stat(path, &st) == -1) { // 获取文件详细信息失败 while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ // 读取剩下的请求头 numchars = get_line(client, buf, sizeof(buf)); not_found(client); // 404 } else { if ((st.st_mode & S_IFMT) == S_IFDIR) // 是一个目录,默认访问该目录下的 index.html 页面 strcat(path, "/index.html"); if ((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH) ) // 这个资源有执行权限 包括 所有者 同组 其他人 cgi = 1; if (!cgi) serve_file(client, path); // 请求的是个页面,返回这页面 else execute_cgi(client, path, method, query_string); // cgi程序,可以执行这个程序,处理过程交给cgi程序 } close(client); // 关闭client socket }