📄 httpd.c
字号:
fprintf(stderr,"%03d/%d: tcp_cork=%d\n",req->fd,req->state,req->tcp_cork);#endif setsockopt(req->fd,SOL_TCP,TCP_CORK,&req->tcp_cork,sizeof(int)); }#endif } else { /* there is a pipelined request in the queue ... */#ifdef DEBUG fprintf(stderr,"%03d/%d: keepalive pipeline\n",req->fd,req->state);#endif req->state = STATE_READ_HEADER; memmove(req->hreq,req->hreq + req->lreq + req->lbreq, req->hdata - (req->lreq + req->lbreq)); req->hdata -= req->lreq + req->lbreq; req->lreq = 0; read_header(req,1); goto parsing; } } /* connections to close */ if (req->state == STATE_CLOSE) { /* access log hook */ /*if (log_request_func != NULL) { log_request_func(req, now); }*/ FD_CLR(req->fd, &fds->rset); FD_CLR(req->fd, &fds->wset); /* leave max as is */ /* cleanup */ close(req->fd);#ifdef USE_SSL if (with_ssl) { SSL_free(req->ssl_s); }#endif if (req->bfd != -1) { close(req->bfd);#ifdef USE_SSL if (with_ssl) { BIO_vfree(req->bio_in); }#endif } curr_conn--;#ifdef DEBUG fprintf(stderr,"%03d/%d: done (%d)\n",req->fd,req->state,curr_conn);#endif /* unlink from list */ tmp = req; if (prev == NULL) { conns = req->next; req = conns; } else { prev->next = req->next; req = req->next; } /* free memory */ if (tmp->r_start) { free(tmp->r_start); } if (tmp->r_end) { free(tmp->r_end); } if (tmp->r_head) { free(tmp->r_head); } if (tmp->r_hlen) { free(tmp->r_hlen); } list_free(&tmp->header); free(tmp); } else { prev = req; req = req->next; } } return 0;}/* initialize http server *//* return file descriptor if success, <0 otherwise */int httpd_init(int sport, char *sname, int use_ssl, const char *certificate, const char *password, int use_v6){ struct addrinfo ask,*res = NULL; struct sockaddr_storage ss; int opt, rc, ss_len, v4 = 1, v6 = 0; char host[INET6_ADDRSTRLEN+1]; char serv[16]; char listen_port[6]; char *listen_ip = NULL; /* set config */ sprintf(listen_port, "%d", sport); server_name = sname; if (use_v6) { v6 = 1; } #ifdef USE_SSL with_ssl = use_ssl;#endif /* FIXME nthreads */ /* get server name */ gethostname(server_host,255); memset(&ask,0,sizeof(ask)); ask.ai_flags = AI_CANONNAME; if ((rc = getaddrinfo(server_host, NULL, &ask, &res)) == 0) { if (res->ai_canonname) { strcpy(server_host,res->ai_canonname); } if (res != NULL) { freeaddrinfo(res); res = NULL; } } /* bind to socket */ slisten = -1; memset(&ask, 0, sizeof(ask)); ask.ai_flags = AI_PASSIVE; if (listen_ip) { ask.ai_flags |= AI_CANONNAME; } ask.ai_socktype = SOCK_STREAM; /* try ipv6 first ... */ if (slisten == -1 && v6) { ask.ai_family = PF_INET6; g_timeout = 0; alarm(2); rc = getaddrinfo(listen_ip, listen_port, &ask, &res); if (g_timeout) { log_error_func(1, LOG_ERR,"getaddrinfo (ipv6): DNS timeout",NULL); } alarm(0); if (rc == 0) { if ((slisten = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { log_error_func(1, LOG_ERR,"socket (ipv6)",NULL); } } else { log_error_func(1, LOG_ERR, "getaddrinfo (ipv6)", NULL); } } g_timeout = 0; alarm(2); /* ... failing that try ipv4 */ if (slisten == -1 && v4) { ask.ai_family = PF_INET; g_timeout = 0; alarm(1); rc = getaddrinfo(listen_ip, listen_port, &ask, &res); if (g_timeout) { log_error_func(1, LOG_ERR,"getaddrinfo (ipv4): DNS timeout",NULL); return -1; } alarm(0); if (rc == 0) { if ((slisten = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { log_error_func(1, LOG_ERR,"socket (ipv4)",NULL); return -1; } } else { log_error_func(1, LOG_ERR, "getaddrinfo (ipv4)", NULL); return -1; } } if (slisten == -1) { return -1; } memcpy(&ss,res->ai_addr,res->ai_addrlen); ss_len = res->ai_addrlen; if (res->ai_canonname) { strcpy(server_host,res->ai_canonname); } if ((rc = getnameinfo((struct sockaddr*)&ss,ss_len, host,INET6_ADDRSTRLEN,serv,15, NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { log_error_func(1, LOG_ERR, "getnameinfo", NULL); return -1; } tcp_port = atoi(serv); opt = 1; setsockopt(slisten,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); fcntl(slisten,F_SETFL,O_NONBLOCK); /* Use accept filtering, if available. */#ifdef SO_ACCEPTFILTER { struct accept_filter_arg af; memset(&af,0,sizeof(af)); strcpy(af.af_name,"httpready"); setsockopt(slisten, SOL_SOCKET, SO_ACCEPTFILTER, (char*)&af, sizeof(af)); }#endif /* SO_ACCEPTFILTER */ if (bind(slisten, (struct sockaddr*) &ss, ss_len) == -1) { log_error_func(1, LOG_ERR,"bind",NULL); return -1; } if (listen(slisten, 2*max_conn) == -1) { log_error_func(1, LOG_ERR,"listen",NULL); return -1; } /* init misc stuff */ init_mime(mimetypes,"text/plain"); init_quote(); #ifdef USE_SSL if (with_ssl) { init_ssl(certificate, password); }#endif#ifdef DEBUG fprintf(stderr, "http server started\n" " ipv6 : %s\n"#ifdef USE_SSL " ssl : %s\n"#endif " node : %s\n" " ipaddr: %s\n" " port : %d\n" , res->ai_family == PF_INET6 ? "yes" : "no",#ifdef USE_SSL with_ssl ? "yes" : "no",#endif server_host,host,tcp_port);#endif if (res != NULL) { freeaddrinfo(res); } /* go! */#ifdef HTTPD_USE_THREADS if (nthreads > 1) { int i; threads = malloc(sizeof(pthread_t) * nthreads); for (i = 1; i < nthreads; i++) { pthread_create(threads+i,NULL,mainloop,threads+i); pthread_detach(threads[i]); } }#endif return slisten;}void httpd_shutdown(){ struct REQUEST *req, *tmp; close(slisten); for (req = conns; req != NULL;) { tmp = req->next; close(req->fd); if (req->bfd != -1) { close(req->bfd); } if (req->body != NULL) { free(req->body); } if (req->r_start) { free(req->r_start); } if (req->r_end) { free(req->r_end); } if (req->r_head) { free(req->r_head); } if (req->r_hlen) { free(req->r_hlen); } list_free(&req->header); free(req); req = tmp; } shutdown_mime();}int httpd_uses_ssl(){#ifdef USE_SSL return (with_ssl > 0);#else return 0;#endif}int httpd_register_access_check(access_check_func_t f){ access_check_func = f; return 0;}int httpd_register_log_request(log_request_func_t f){ log_request_func = f; return 0;}int httpd_register_log_error(log_error_func_t f){ log_error_func = f; return 0;}int httpd_register_parse_request(parse_request_func_t f){ parse_request_func = f; return 0;}int httpd_get_keepalive(){ return keepalive_time;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -