日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HTTP服务器的本质:tinyhttpd源码分析及拓展

發(fā)布時(shí)間:2023/11/30 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HTTP服务器的本质:tinyhttpd源码分析及拓展 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  已經(jīng)有一個(gè)月沒有更新博客了,一方面是因?yàn)槠綍r(shí)太忙了,另一方面是想積攢一些干貨進(jìn)行分享。最近主要是做了一些開源項(xiàng)目的源碼分析工作,有c項(xiàng)目也有python項(xiàng)目,想提升一下內(nèi)功,今天分享一下tinyhttpd源碼分析的成果。tinyhttpd是一個(gè)非常輕量型的http服務(wù)器,c代碼500行左右,可以幫助我們了解http服務(wù)器運(yùn)行的實(shí)質(zhì)。在分析之前,我們先說一下http報(bào)文。(我的新書《Python爬蟲開發(fā)與項(xiàng)目實(shí)戰(zhàn)》出版了,大家可以看一下樣章

一.http請(qǐng)求

http請(qǐng)求由三部分組成,分別是:起始行、消息報(bào)頭、請(qǐng)求正文

Request Line<CRLF> Header-Name: header-value<CRLF> Header-Name: header-value<CRLF> //一個(gè)或多個(gè),均以<CRLF>結(jié)尾 <CRLF> body//請(qǐng)求正文

1、起始行以一個(gè)方法符號(hào)開頭,以空格分開,后面跟著請(qǐng)求的URI和協(xié)議的版本,格式如下:

Method Request-URI HTTP-Version CRLF

其中 Method表示請(qǐng)求方法;Request-URI是一個(gè)統(tǒng)一資源標(biāo)識(shí)符;HTTP-Version表示請(qǐng)求的HTTP協(xié)議版本;CRLF表示回車和換行(除了作為結(jié)尾的CRLF外,不允許出現(xiàn)單獨(dú)的CR或LF字符)。

2、請(qǐng)求方法(所有方法全為大寫)有多種,各個(gè)方法的解釋如下:

  • GET 請(qǐng)求獲取Request-URI所標(biāo)識(shí)的資源
  • POST 在Request-URI所標(biāo)識(shí)的資源后附加新的數(shù)據(jù)
  • HEAD 請(qǐng)求獲取由Request-URI所標(biāo)識(shí)的資源的響應(yīng)消息報(bào)頭
  • PUT 請(qǐng)求服務(wù)器存儲(chǔ)一個(gè)資源,并用Request-URI作為其標(biāo)識(shí)
  • DELETE 請(qǐng)求服務(wù)器刪除Request-URI所標(biāo)識(shí)的資源
  • TRACE 請(qǐng)求服務(wù)器回送收到的請(qǐng)求信息,主要用于測(cè)試或診斷
  • CONNECT 保留將來使用
  • OPTIONS 請(qǐng)求查詢服務(wù)器的性能,或者查詢與資源相關(guān)的選項(xiàng)和需求

應(yīng)用舉例:?
GET方法:在瀏覽器的地址欄中輸入網(wǎng)址的方式訪問網(wǎng)頁時(shí),瀏覽器采用GET方法向服務(wù)器獲取資源,eg:?

GET /form.html HTTP/1.1 (CRLF)

POST方法要求被請(qǐng)求服務(wù)器接受附在請(qǐng)求后面的數(shù)據(jù),常用于提交表單。eg:

POST /reg.jsp HTTP/ (CRLF) Accept:image/gif,image/x-xbit,... (CRLF) ... HOST:www.guet.edu.cn (CRLF) Content-Length:22 (CRLF) Connection:Keep-Alive (CRLF) Cache-Control:no-cache (CRLF) (CRLF) //該CRLF表示消息報(bào)頭已經(jīng)結(jié)束,在此之前為消息報(bào)頭 user=jeffrey&pwd=1234 //此行以下為提交的數(shù)據(jù)

?

二.tinyhttpd源碼分析 

 tinyhttpd總共包含以下函數(shù):

void accept_request(int);//處理從套接字上監(jiān)聽到的一個(gè) HTTP 請(qǐng)求 void bad_request(int);//返回給客戶端這是個(gè)錯(cuò)誤請(qǐng)求,400響應(yīng)碼 void cat(int, FILE *);//讀取服務(wù)器上某個(gè)文件寫到 socket 套接字 void cannot_execute(int);//處理發(fā)生在執(zhí)行 cgi 程序時(shí)出現(xiàn)的錯(cuò)誤 void error_die(const char *);//把錯(cuò)誤信息寫到 perror? void execute_cgi(int, const char *, const char *, const char *);//運(yùn)行cgi腳本,這個(gè)非常重要,涉及動(dòng)態(tài)解析 int get_line(int, char *, int);//讀取一行HTTP報(bào)文 void headers(int, const char *);//返回HTTP響應(yīng)頭 void not_found(int);//返回找不到請(qǐng)求文件 void serve_file(int, const char *);//調(diào)用 cat 把服務(wù)器文件內(nèi)容返回給瀏覽器。 int startup(u_short *);//開啟http服務(wù),包括綁定端口,監(jiān)聽,開啟線程處理鏈接 void unimplemented(int);//返回給瀏覽器表明收到的 HTTP 請(qǐng)求所用的 method 不被支持。

建議源碼閱讀順序: main -> startup -> accept_request -> execute_cgi 

按照以上順序,看一下瀏覽器和tinyhttpd交互的整個(gè)流程:

三.注釋版源碼

  注釋版源碼已經(jīng)放到github上了,以后所有的源碼分析都會(huì)上傳github上。由于tinyhttpd源碼較少,下面將完整的代碼貼出來。

/* J. David's webserver */ /* This is a simple webserver.* Created November 1999 by J. David Blackstone.* CSE 4344 (Network concepts), Prof. Zeigler* University of Texas at Arlington*/ /* This program compiles for Sparc Solaris 2.6.* To compile for Linux:* 1) Comment out the #include <pthread.h> line.* 2) Comment out the line that defines the variable newthread.* 3) Comment out the two lines that run pthread_create().* 4) Uncomment the line that runs accept_request().* 5) Remove -lsocket from the Makefile.*/ #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <ctype.h> #include <strings.h> #include <string.h> #include <sys/stat.h> #include <pthread.h> #include <sys/wait.h> #include <stdlib.h>#define ISspace(x) isspace((int)(x)) //函數(shù)說明:檢查參數(shù)c是否為空格字符, //也就是判斷是否為空格(' ')、定位字符(' \t ')、CR(' \r ')、換行(' \n ')、垂直定位字符(' \v ')或翻頁(' \f ')的情況。 //返回值:若參數(shù)c 為空白字符,則返回非 0,否則返回 0。#define SERVER_STRING "Server: jdbhttpd/0.1.0\r\n"//定義server名稱void accept_request(int);//接收請(qǐng)求void bad_request(int);//無效請(qǐng)求 void cat(int, FILE *); void cannot_execute(int); void error_die(const char *); void execute_cgi(int, const char *, const char *, const char *); int get_line(int, char *, int); void headers(int, const char *); void not_found(int); void serve_file(int, const char *); int startup(u_short *); void unimplemented(int);/**********************************************************************/ /* A request has caused a call to accept() on the server port to* return. Process the request appropriately.* Parameters: the socket connected to the client */ /**********************************************************************/ //接收客戶端的連接,并讀取請(qǐng)求數(shù)據(jù) 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; //獲取一行HTTP報(bào)文數(shù)據(jù)numchars = get_line(client, buf, sizeof(buf));//i = 0; j = 0;//對(duì)于HTTP報(bào)文來說,第一行的內(nèi)容即為報(bào)文的起始行,格式為<method> <request-URL> <version>,//每個(gè)字段用空白字符相連while (!ISspace(buf[j]) && (i < sizeof(method) - 1)){//提取其中的請(qǐng)求方式是GET還是POSTmethod[i] = buf[j];i++; j++;}method[i] = '\0'; //函數(shù)說明:strcasecmp()用來比較參數(shù)s1 和s2 字符串,比較時(shí)會(huì)自動(dòng)忽略大小寫的差異。 //返回值:若參數(shù)s1 和s2 字符串相同則返回0。s1 長度大于s2 長度則返回大于0 的值,s1 長度若小于s2 長度則返回小于0 的值。if (strcasecmp(method, "GET") && strcasecmp(method, "POST")){//tinyhttp僅僅實(shí)現(xiàn)了GET和POSTunimplemented(client);return;} //cgi為標(biāo)志位,置1說明開啟cgi解析if (strcasecmp(method, "POST") == 0) //如果請(qǐng)求方法為POST,需要cgi解析cgi = 1;i = 0;//將method后面的后邊的空白字符略過while (ISspace(buf[j]) && (j < sizeof(buf)))j++;//繼續(xù)讀取request-URLwhile (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))){url[i] = buf[j];i++; j++;}url[i] = '\0'; //如果是GET請(qǐng)求,url可能會(huì)帶有?,有查詢參數(shù)if (strcasecmp(method, "GET") == 0){query_string = url;while ((*query_string != '?') && (*query_string != '\0'))query_string++;if (*query_string == '?'){//如果帶有查詢參數(shù),需要執(zhí)行cgi,解析參數(shù),設(shè)置標(biāo)志位為1cgi = 1;//將解析參數(shù)截取下來*query_string = '\0';query_string++;}} //以上已經(jīng)將起始行解析完畢 //url中的路徑格式化到pathsprintf(path, "htdocs%s", url); //學(xué)習(xí)到這里明天繼續(xù)TODO //如果path只是一個(gè)目錄,默認(rèn)設(shè)置為首頁index.htmlif (path[strlen(path) - 1] == '/')strcat(path, "index.html");//函數(shù)定義: int stat(const char *file_name, struct stat *buf); //函數(shù)說明: 通過文件名filename獲取文件信息,并保存在buf所指的結(jié)構(gòu)體stat中 //返回值: 執(zhí)行成功則返回0,失敗返回-1,錯(cuò)誤代碼存于errno(需要include <errno.h>)if (stat(path, &st) == -1) {//假如訪問的網(wǎng)頁不存在,則不斷的讀取剩下的請(qǐng)求頭信息,并丟棄即可while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */numchars = get_line(client, buf, sizeof(buf));//最后聲明網(wǎng)頁不存在not_found(client);}else{//如果訪問的網(wǎng)頁存在則進(jìn)行處理if ((st.st_mode & S_IFMT) == S_IFDIR)//S_IFDIR代表目錄//如果路徑是個(gè)目錄,那就將主頁進(jìn)行顯示strcat(path, "/index.html");if ((st.st_mode & S_IXUSR) ||(st.st_mode & S_IXGRP) ||(st.st_mode & S_IXOTH) )//S_IXUSR:文件所有者具可執(zhí)行權(quán)限//S_IXGRP:用戶組具可執(zhí)行權(quán)限//S_IXOTH:其他用戶具可讀取權(quán)限 cgi = 1;if (!cgi)//將靜態(tài)文件返回serve_file(client, path);else//執(zhí)行cgi動(dòng)態(tài)解析execute_cgi(client, path, method, query_string);}close(client);//因?yàn)閔ttp是面向無連接的,所以要關(guān)閉 }/**********************************************************************/ /* Inform the client that a request it has made has a problem.* Parameters: client socket */ /**********************************************************************/ void bad_request(int client) {char buf[1024]; //發(fā)送400sprintf(buf, "HTTP/1.0 400 BAD REQUEST\r\n");send(client, buf, sizeof(buf), 0);sprintf(buf, "Content-type: text/html\r\n");send(client, buf, sizeof(buf), 0);sprintf(buf, "\r\n");send(client, buf, sizeof(buf), 0);sprintf(buf, "<P>Your browser sent a bad request, ");send(client, buf, sizeof(buf), 0);sprintf(buf, "such as a POST without a Content-Length.\r\n");send(client, buf, sizeof(buf), 0); }/**********************************************************************/ /* Put the entire contents of a file out on a socket. This function* is named after the UNIX "cat" command, because it might have been* easier just to do something like pipe, fork, and exec("cat").* Parameters: the client socket descriptor* FILE pointer for the file to cat */ /**********************************************************************/ void cat(int client, FILE *resource) { //發(fā)送文件的內(nèi)容char buf[1024]; //讀取文件到buf中fgets(buf, sizeof(buf), resource);while (!feof(resource))//判斷文件是否讀取到末尾{//讀取并發(fā)送文件內(nèi)容send(client, buf, strlen(buf), 0);fgets(buf, sizeof(buf), resource);} }/**********************************************************************/ /* Inform the client that a CGI script could not be executed.* Parameter: the client socket descriptor. */ /**********************************************************************/ void cannot_execute(int client) {char buf[1024]; //發(fā)送500sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "Content-type: text/html\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "<P>Error prohibited CGI execution.\r\n");send(client, buf, strlen(buf), 0); }/**********************************************************************/ /* Print out an error message with perror() (for system errors; based* on value of errno, which indicates system call errors) and exit the* program indicating an error. */ /**********************************************************************/ void error_die(const char *sc) {perror(sc);exit(1); }/**********************************************************************/ /* Execute a CGI script. Will need to set environment variables as* appropriate.* Parameters: client socket descriptor* path to the CGI script */ /**********************************************************************/ //執(zhí)行cgi動(dòng)態(tài)解析 void execute_cgi(int client, const char *path,const char *method, const char *query_string) {char buf[1024];int cgi_output[2];//聲明的讀寫管道,切莫被名稱給忽悠,會(huì)給出圖進(jìn)行說明int cgi_input[2];//pid_t pid;int status;int i;char c;int numchars = 1;int content_length = -1;buf[0] = 'A'; buf[1] = '\0';if (strcasecmp(method, "GET") == 0)//如果是GET請(qǐng)求//讀取并且丟棄頭信息while ((numchars > 0) && strcmp("\n", buf)) numchars = get_line(client, buf, sizeof(buf));else {//處理的請(qǐng)求為POSTnumchars = get_line(client, buf, sizeof(buf));while ((numchars > 0) && strcmp("\n", buf)){//循環(huán)讀取頭信息找到Content-Length字段的值buf[15] = '\0';//目的是為了截取Content-Length:if (strcasecmp(buf, "Content-Length:") == 0)//"Content-Length: 15"content_length = atoi(&(buf[16]));//獲取Content-Length的值numchars = get_line(client, buf, sizeof(buf));}if (content_length == -1) {//錯(cuò)誤請(qǐng)求bad_request(client);return;}} //返回正確響應(yīng)碼200sprintf(buf, "HTTP/1.0 200 OK\r\n");send(client, buf, strlen(buf), 0); //#include<unistd.h> //int pipe(int filedes[2]); //返回值:成功,返回0,否則返回-1。參數(shù)數(shù)組包含pipe使用的兩個(gè)文件的描述符。fd[0]:讀管道,fd[1]:寫管道。 //必須在fork()中調(diào)用pipe(),否則子進(jìn)程不會(huì)繼承文件描述符。 //兩個(gè)進(jìn)程不共享祖先進(jìn)程,就不能使用pipe。但是可以使用命名管道。 //pipe(cgi_output)執(zhí)行成功后,cgi_output[0]:讀通道 cgi_output[1]:寫通道,這就是為什么說不要被名稱所迷惑if (pipe(cgi_output) < 0) {cannot_execute(client);return;}if (pipe(cgi_input) < 0) {cannot_execute(client);return;}if ( (pid = fork()) < 0 ) {cannot_execute(client);return;}//fork出一個(gè)子進(jìn)程運(yùn)行cgi腳本if (pid == 0) /* 子進(jìn)程: 運(yùn)行CGI 腳本 */{char meth_env[255];char query_env[255];char length_env[255];dup2(cgi_output[1], 1);//1代表著stdout,0代表著stdin,將系統(tǒng)標(biāo)準(zhǔn)輸出重定向?yàn)閏gi_output[1]dup2(cgi_input[0], 0);//將系統(tǒng)標(biāo)準(zhǔn)輸入重定向?yàn)閏gi_input[0],這一點(diǎn)非常關(guān)鍵,//cgi程序中用的是標(biāo)準(zhǔn)輸入輸出進(jìn)行交互close(cgi_output[0]);//關(guān)閉了cgi_output中的讀通道close(cgi_input[1]);//關(guān)閉了cgi_input中的寫通道//CGI標(biāo)準(zhǔn)需要將請(qǐng)求的方法存儲(chǔ)環(huán)境變量中,然后和cgi腳本進(jìn)行交互//存儲(chǔ)REQUEST_METHODsprintf(meth_env, "REQUEST_METHOD=%s", method);putenv(meth_env);if (strcasecmp(method, "GET") == 0) {//存儲(chǔ)QUERY_STRINGsprintf(query_env, "QUERY_STRING=%s", query_string);putenv(query_env);}else { /* POST *///存儲(chǔ)CONTENT_LENGTHsprintf(length_env, "CONTENT_LENGTH=%d", content_length);putenv(length_env);}// 表頭文件#include<unistd.h>// 定義函數(shù)// int execl(const char * path,const char * arg,....);// 函數(shù)說明// execl()用來執(zhí)行參數(shù)path字符串所代表的文件路徑,接下來的參數(shù)代表執(zhí)行該文件時(shí)傳遞過去的argv(0)、argv[1]……,最后一個(gè)參數(shù)必須用空指針(NULL)作結(jié)束。// 返回值// 如果執(zhí)行成功則函數(shù)不會(huì)返回,執(zhí)行失敗則直接返回-1,失敗原因存于errno中。execl(path, path, NULL);//執(zhí)行CGI腳本exit(0);} else { /* 父進(jìn)程 */close(cgi_output[1]);//關(guān)閉了cgi_output中的寫通道,注意這是父進(jìn)程中cgi_output變量和子進(jìn)程要區(qū)分開close(cgi_input[0]);//關(guān)閉了cgi_input中的讀通道if (strcasecmp(method, "POST") == 0)for (i = 0; i < content_length; i++) {//開始讀取POST中的內(nèi)容recv(client, &c, 1, 0);//將數(shù)據(jù)發(fā)送給cgi腳本write(cgi_input[1], &c, 1);}//讀取cgi腳本返回?cái)?shù)據(jù)while (read(cgi_output[0], &c, 1) > 0)//發(fā)送給瀏覽器send(client, &c, 1, 0); //運(yùn)行結(jié)束關(guān)閉close(cgi_output[0]);close(cgi_input[1]); //定義函數(shù):pid_t waitpid(pid_t pid, int * status, int options); //函數(shù)說明:waitpid()會(huì)暫時(shí)停止目前進(jìn)程的執(zhí)行, 直到有信號(hào)來到或子進(jìn)程結(jié)束. //如果在調(diào)用wait()時(shí)子進(jìn)程已經(jīng)結(jié)束, 則wait()會(huì)立即返回子進(jìn)程結(jié)束狀態(tài)值. 子進(jìn)程的結(jié)束狀態(tài)值會(huì)由參數(shù)status 返回, //而子進(jìn)程的進(jìn)程識(shí)別碼也會(huì)一快返回. //如果不在意結(jié)束狀態(tài)值, 則參數(shù)status 可以設(shè)成NULL. 參數(shù)pid 為欲等待的子進(jìn)程識(shí)別碼, 其他數(shù)值意義如下: //1、pid<-1 等待進(jìn)程組識(shí)別碼為pid 絕對(duì)值的任何子進(jìn)程. //2、pid=-1 等待任何子進(jìn)程, 相當(dāng)于wait(). //3、pid=0 等待進(jìn)程組識(shí)別碼與目前進(jìn)程相同的任何子進(jìn)程. //4、pid>0 等待任何子進(jìn)程識(shí)別碼為pid 的子進(jìn)程.waitpid(pid, &status, 0);} }/**********************************************************************/ /* Get a line from a socket, whether the line ends in a newline,* carriage return, or a CRLF combination. Terminates the string read* with a null character. If no newline indicator is found before the* end of the buffer, the string is terminated with a null. If any of* the above three line terminators is read, the last character of the* string will be a linefeed and the string will be terminated with a* null character.* Parameters: the socket descriptor* the buffer to save the data in* the size of the buffer* Returns: the number of bytes stored (excluding null) */ /**********************************************************************/ //解析一行http報(bào)文 int get_line(int sock, char *buf, int size) {int i = 0;char c = '\0';int n;while ((i < size - 1) && (c != '\n')){n = recv(sock, &c, 1, 0);/* DEBUG printf("%02X\n", c); */if (n > 0){if (c == '\r'){n = recv(sock, &c, 1, MSG_PEEK);/* DEBUG printf("%02X\n", c); */if ((n > 0) && (c == '\n'))recv(sock, &c, 1, 0);elsec = '\n';}buf[i] = c;i++;}elsec = '\n';}buf[i] = '\0';return(i); }/**********************************************************************/ /* Return the informational HTTP headers about a file. */ /* Parameters: the socket to print the headers on* the name of the file */ /**********************************************************************/ void headers(int client, const char *filename) {char buf[1024];(void)filename; /* could use filename to determine file type */ //發(fā)送HTTP頭strcpy(buf, "HTTP/1.0 200 OK\r\n");send(client, buf, strlen(buf), 0);strcpy(buf, SERVER_STRING);send(client, buf, strlen(buf), 0);sprintf(buf, "Content-Type: text/html\r\n");send(client, buf, strlen(buf), 0);strcpy(buf, "\r\n");send(client, buf, strlen(buf), 0); }/**********************************************************************/ /* Give a client a 404 not found status message. */ /**********************************************************************/ void not_found(int client) {char buf[1024];//返回404sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, SERVER_STRING);send(client, buf, strlen(buf), 0);sprintf(buf, "Content-Type: text/html\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "<HTML><TITLE>Not Found</TITLE>\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "<BODY><P>The server could not fulfill\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "your request because the resource specified\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "is unavailable or nonexistent.\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "</BODY></HTML>\r\n");send(client, buf, strlen(buf), 0); }/**********************************************************************/ /* Send a regular file to the client. Use headers, and report* errors to client if they occur.* Parameters: a pointer to a file structure produced from the socket* file descriptor* the name of the file to serve */ /**********************************************************************/ //將請(qǐng)求的文件發(fā)送回瀏覽器客戶端 void serve_file(int client, const char *filename) {FILE *resource = NULL;int numchars = 1;char buf[1024];buf[0] = 'A'; buf[1] = '\0';//這個(gè)賦值不清楚是干什么的while ((numchars > 0) && strcmp("\n", buf)) //將HTTP請(qǐng)求頭讀取并丟棄numchars = get_line(client, buf, sizeof(buf)); //打開文件resource = fopen(filename, "r");if (resource == NULL)//如果文件不存在,則返回not_foundnot_found(client);else{//添加HTTP頭headers(client, filename);//并發(fā)送文件內(nèi)容cat(client, resource);}fclose(resource);//關(guān)閉文件句柄 }/**********************************************************************/ /* This function starts the process of listening for web connections* on a specified port. If the port is 0, then dynamically allocate a* port and modify the original port variable to reflect the actual* port.* Parameters: pointer to variable containing the port to connect on* Returns: the socket */ /**********************************************************************/ //啟動(dòng)服務(wù)端 int startup(u_short *port) {int httpd = 0;struct sockaddr_in name; //設(shè)置http sockethttpd = socket(PF_INET, SOCK_STREAM, 0);if (httpd == -1)error_die("socket");memset(&name, 0, sizeof(name));name.sin_family = AF_INET;name.sin_port = htons(*port);name.sin_addr.s_addr = htonl(INADDR_ANY);//綁定端口if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0)error_die("bind");if (*port == 0) /*動(dòng)態(tài)分配一個(gè)端口 */{int namelen = sizeof(name);if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1)error_die("getsockname");*port = ntohs(name.sin_port);}//監(jiān)聽連接if (listen(httpd, 5) < 0)error_die("listen");return(httpd); }/**********************************************************************/ /* Inform the client that the requested web method has not been* implemented.* Parameter: the client socket */ /**********************************************************************/ void unimplemented(int client) {char buf[1024]; //發(fā)送501說明相應(yīng)方法沒有實(shí)現(xiàn)sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, SERVER_STRING);send(client, buf, strlen(buf), 0);sprintf(buf, "Content-Type: text/html\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "<HTML><HEAD><TITLE>Method Not Implemented\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "</TITLE></HEAD>\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "<BODY><P>HTTP request method not supported.\r\n");send(client, buf, strlen(buf), 0);sprintf(buf, "</BODY></HTML>\r\n");send(client, buf, strlen(buf), 0); }/**********************************************************************/int main(void) {int server_sock = -1;u_short port = 0;int client_sock = -1;struct sockaddr_in client_name;int client_name_len = sizeof(client_name);pthread_t newthread; //啟動(dòng)server socketserver_sock = startup(&port);printf("httpd running on port %d\n", port);while (1){//接受客戶端連接client_sock = accept(server_sock,(struct sockaddr *)&client_name,&client_name_len);if (client_sock == -1)error_die("accept");/*啟動(dòng)線程處理新的連接 */if (pthread_create(&newthread , NULL, accept_request, client_sock) != 0)perror("pthread_create");} //關(guān)閉server socketclose(server_sock);return(0); }

  不過這個(gè)項(xiàng)目并不能直接在Linux上編譯運(yùn)行。它本來是在solaris上實(shí)現(xiàn)的,貌似在socket和pthread的實(shí)現(xiàn)上和一般的Linux還是不一樣的,需要修改一部分內(nèi)容。至于如何修改大家參考這篇文章,我也將修改版上傳到github上了,名稱為tinyhttpd-0.1.0_for_linux,大家可以clone下來,直接make編譯即可。下面演示一下如何運(yùn)行tinyhttpd,編譯完成的效果如下:

下面運(yùn)行./httpd,并在瀏覽器中訪問。

tinyhttpd默認(rèn)cgi腳本是perl腳本,比如color.cgi,位于htdocs目錄下。

#!/usr/bin/perl -Twuse strict; use CGI;my($cgi) = new CGI;print $cgi->header; my($color) = "blue"; $color = $cgi->param('color') if defined $cgi->param('color');print $cgi->start_html(-title => uc($color),-BGCOLOR => $color); print $cgi->h1("This is $color"); print $cgi->end_html;

 下面我想用python來實(shí)現(xiàn)cgi腳本,添加一些頁面,為了更加了解cgi程序的運(yùn)行實(shí)質(zhì),不用python封裝好的cgi模塊,完全手工打造。首先在htdocs目錄下添加一個(gè)register.html頁面,html文檔內(nèi)容如下:

<html><head><title>注冊(cè)信息</title><meta charset="utf-8"></head><body><form action="register.cgi" method="POST">賬號(hào):<input type="text" name="zhanghao" value="" size="10" maxlength="5"><br><br>密碼:<input type="password" value="" name="mima" size="10"><br><br><input type="hidden" value="隱藏的內(nèi)容" name="mihiddenma" size="10">愛好:<input type="checkbox" name="tiyu" checked="checked">體育<input type="checkbox" name="changge">唱歌<br><br>性別:<input type="radio" name="sex" checked="checked">男<input type="radio" name="sex">女<br><br>自我介紹:<br><textarea cols="35" rows="10" name="ziwojieshao">這里是自我介紹</textarea><br><br>地址:<select name="dizhi"><option value="sichuan">四川</option><option value="beijing">北京</option><option value="shanghai">上海</option></select><br><br><input type="submit" value="提交"><input type="reset" value="重置"></form></body> </html>

  這是一個(gè)表單,action指向register.cgi,method為post。下面看一下register.cgi,其實(shí)是個(gè)python腳本。

#!/usr/bin/python #coding:utf-8 import sys,os length = os.getenv('CONTENT_LENGTH')if length:postdata = sys.stdin.read(int(length))print "Content-type:text/html\n"print '<html>' print '<head>' print '<title>POST</title>' print '</head>' print '<body>' print '<h2> POST data </h2>'print '<ul>'for data in postdata.split('&'):print '<li>'+data+'</li>'print '</ul>'print '</body>'print '</html>'else:print "Content-type:text/html\n"print 'no found'

  代碼的意思是從標(biāo)準(zhǔn)輸入中讀取post中的數(shù)據(jù),并將顯示數(shù)據(jù)輸出到標(biāo)準(zhǔn)輸出中,對(duì)比一下流程圖,更好理解。下面看一下運(yùn)行效果。

?


今天的分享就到這里,下一篇繼續(xù)分析。如果大家覺得還可以呀,記得推薦呦。

參考文章:HTTP協(xié)議全覽,tinyhttpd在Linux編譯 歡迎大家支持我公眾號(hào):

本文章屬于原創(chuàng)作品,歡迎大家轉(zhuǎn)載分享。尊重原創(chuàng),轉(zhuǎn)載請(qǐng)注明來自:七夜的故事?http://www.cnblogs.com/qiyeboy/

轉(zhuǎn)載于:https://www.cnblogs.com/qiyeboy/p/6296387.html

總結(jié)

以上是生活随笔為你收集整理的HTTP服务器的本质:tinyhttpd源码分析及拓展的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

亚洲人视频在线 | 国产精品1000| 日本精品在线视频 | 久久九九九九 | 婷婷色伊人 | 97热久久免费频精品99 | 色综合亚洲精品激情狠狠 | 91看片淫黄大片在线播放 | www成人av| 日本韩国中文字幕 | 婷婷伊人网 | 91黄视频在线观看 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 天天干天天操天天做 | 97国产超碰 | www日韩在线 | 亚洲区二区 | 亚洲精品女人 | 欧美乱码精品一区 | 成人午夜黄色影院 | 韩日在线一区 | 亚洲开心色| 中文字幕大全 | 91精品在线免费观看视频 | 国产午夜精品理论片在线 | 国产精品一区二区久久精品爱涩 | 在线免费视频一区 | 日韩专区在线 | 美女视频久久 | 黄色资源网站 | 手机看片久久 | 亚洲一区在线看 | 亚洲国产最新 | 视频成人永久免费视频 | 国产美女被啪进深处喷白浆视频 | 久草免费在线观看 | 亚洲欧美成人 | 国产成人精品久久久久蜜臀 | www.久久色 | 亚洲一区二区三区四区在线视频 | 中文字幕网站视频在线 | 免费视频黄色 | 91麻豆精品国产91久久久无限制版 | 精品九九久久 | 欧美一级大片在线观看 | 99热这里只有精品国产首页 | 狠狠操狠狠干2017 | 91精品国产一区二区在线观看 | 成人黄色毛片 | 在线看国产一区 | 成 人 黄 色 免费播放 | 最新日本中文字幕 | 欧美另类交在线观看 | 午夜精品99久久免费 | 久草电影免费在线观看 | av成人在线观看 | 狠狠色伊人亚洲综合网站色 | 久久天天躁狠狠躁夜夜不卡公司 | 久久免费视频7 | 久久综合久久综合久久综合 | 五月婷婷在线综合 | 久久av中文字幕片 | 激情五月av | 欧洲激情综合 | 国产视频九色蝌蚪 | 午夜视频在线观看欧美 | 国产永久免费高清在线观看视频 | 国产原创中文在线 | 精品免费久久久久 | 久久婷婷激情 | 中文字幕在线观看视频一区 | www色综合 | 欧美韩国在线 | 国产精品久久片 | 亚州天堂 | 午夜精品麻豆 | 色在线网| 亚洲欧美日韩中文在线 | 久久久久久国产精品 | av直接看| 欧美日韩一区二区三区在线免费观看 | 97精品伊人 | 制服丝袜在线 | 欧美欧美 | 在线日本v二区不卡 | 国产高清精品在线观看 | 久久国际影院 | 毛片网站在线观看 | 免费高清在线一区 | 成人黄色免费观看 | 久久国产精品免费视频 | 91精彩视频在线观看 | 日韩成人免费在线观看 | 九九热re| av爱干| 国产精品久久久免费 | 日日操日日插 | www中文在线 | 国产一区二区久久久 | 亚洲综合国产精品 | 午夜精品久久久久久久久久久久 | 韩国av免费观看 | 超级碰碰碰免费视频 | 免费99精品国产自在在线 | 国产一区视频免费在线观看 | 精品自拍av| 欧美少妇影院 | 蜜臀av夜夜澡人人爽人人桃色 | 中文字幕 欧美性 | 国产精品99免费看 | 欧美人人| 爱色av.com| 久久8| 日韩免费一区二区在线观看 | 一区二区三区四区五区在线 | 久久国产精品免费一区 | 国产精品a级 | 少妇搡bbbb搡bbb搡忠贞 | 黄色毛片视频免费观看中文 | 日日操网站 | 免费看国产a| 久久99这里只有精品 | 色99导航| 成人在线一区二区 | 99久久婷婷国产综合精品 | www.在线看片.com | 美女在线观看网站 | 亚洲精品在线观看的 | 成人久久 | 最新中文字幕在线播放 | 最新国产在线观看 | 日韩在线高清免费视频 | 成年人国产精品 | 久久69av | 亚洲mv大片欧洲mv大片免费 | 1024手机在线看 | 久久久久久久久久久久电影 | 尤物一区二区三区 | 天天操天| 成人精品亚洲 | 午夜视频在线网站 | 国产精品日韩久久久久 | 中文字幕一区二区三区在线视频 | 日韩在线观看一区二区三区 | 午夜电影久久久 | 中文字幕在线资源 | 69欧美视频 | 天天摸日日操 | 日本在线观看中文字幕 | 精品少妇一区二区三区在线 | 婷婷国产精品 | 久久综合9988久久爱 | 91精品久久久久久久99蜜桃 | 国产色啪 | 日韩中文字幕91 | 国内精品视频免费 | 亚洲黄色三级 | 久久夜色精品国产欧美乱极品 | 午夜国产成人 | 久久精品导航 | 日韩成人高清在线 | 97视频中文字幕 | 中文字幕91 | 国产精品青草综合久久久久99 | 日韩剧 | 久久在线免费 | 久久影视一区二区 | 处女av在线 | 久久久久久久久久久免费av | 三级动图 | 亚洲午夜在线视频 | 亚洲免费在线视频 | 夜又临在线观看 | av免费黄色| 国产九九精品 | 国产亚洲高清视频 | 91人人视频在线观看 | 一区二区三区免费在线观看视频 | 中文字幕一区二区三区久久蜜桃 | 欧美 日韩 成人 | 91高清免费在线观看 | 日韩二区在线 | 久久在线免费观看 | 综合五月婷婷 | 免费看污网站 | 国产玖玖视频 | 中文字幕黄网 | 99精品国产免费久久久久久下载 | 亚洲jizzjizz日本少妇 | 中国一级片在线观看 | 99久久精品免费一区 | 久久av免费电影 | a成人在线| 欧美另类调教 | 最近日本mv字幕免费观看 | 美女精品| 日韩综合精品 | 国产美女网站在线观看 | 亚洲精品在线二区 | 日本黄色免费大片 | 亚洲专区欧美专区 | 日韩一区二区三区免费视频 | 日韩欧美网站 | 91爱爱网址 | 91麻豆文化传媒在线观看 | 99色在线观看 | 91系列在线 | 一区 二区 精品 | 免费精品视频在线观看 | 成人99免费视频 | 国产精品中文字幕av | 日韩精品一区二区三区不卡 | av网址在线播放 | 91丨精品丨蝌蚪丨白丝jk | 日韩欧美精品在线视频 | 在线视频观看91 | 日韩成人免费在线观看 | 亚洲欧美日韩精品久久奇米一区 | 成人av在线亚洲 | 色视频成人在线观看免 | 五月天精品视频 | 天天射天天干天天 | 国产护士hd高朝护士1 | 91人人爱| 亚洲成人精品在线 | 日本mv大片欧洲mv大片 | 中文字幕不卡在线88 | 国产a视频免费观看 | 国产剧情在线一区 | 免费 在线 中文 日本 | 98福利在线 | 国产精品网红直播 | 久草久草久草久草 | 久久免费播放视频 | 久久久www成人免费精品张筱雨 | 亚洲国产97在线精品一区 | 91人人视频在线观看 | 五月天最新网址 | 日本精品一区二区三区在线播放视频 | 国产一区二区三区 在线 | 菠萝菠萝蜜在线播放 | 中文在线字幕观看电影 | 亚洲高清在线精品 | a v在线视频 | 99爱精品视频 | 在线观看激情av | 日日夜夜艹 | 亚洲va天堂va欧美ⅴa在线 | 伊人婷婷在线 | 日韩乱码中文字幕 | 亚洲综合日韩在线 | 久久99久久99精品 | 日韩网站在线观看 | 激情综合啪啪 | 成人av电影网址 | 精品国产不卡 | 一级黄色片毛片 | 久久成人亚洲欧美电影 | 国产成人综合在线观看 | 五月婷婷在线观看视频 | 亚洲成av人片在线观看香蕉 | 国语对白少妇爽91 | 国产不卡av在线播放 | 色 免费观看 | 国产一区二区三区网站 | www免费看| 精品久久久久久亚洲综合网 | 日韩精品一区二区不卡 | 亚洲第一区在线播放 | 精品久久久久久久 | 国产无遮挡猛进猛出免费软件 | 97福利| 国产精品一区二区视频 | 九九交易行官网 | 国产成人久久av免费高清密臂 | 999电影免费在线观看 | 亚洲精品综合一二三区在线观看 | 日韩大片在线播放 | 超碰成人网 | 国产精品门事件 | 日韩欧美一区二区三区免费观看 | 欧美一级视频免费看 | 亚洲婷婷综合色高清在线 | 在线不卡a | 国际精品久久久久 | 免费看日韩片 | 中文字幕免费高清在线观看 | 精品播放 | 国产流白浆高潮在线观看 | 日韩videos | 国产高清成人 | 国产精品自在欧美一区 | 国产视 | 中文字幕视频一区二区 | 国产黄色免费 | 日韩r级在线 | 天天干天天碰 | 亚洲最大免费成人网 | 免费黄色网址网站 | 日韩高清一区二区 | 毛片网站在线看 | 激情五月婷婷激情 | 91精品推荐 | 国产我不卡 | 欧美激情xxxx | 日韩中文在线播放 | 国产日产欧美在线观看 | 97国产一区二区 | 久久久久日本精品一区二区三区 | 日韩精品中文字幕久久臀 | 最近免费中文字幕 | 香蕉97视频观看在线观看 | 日韩肉感妇bbwbbwbbw | 日本在线免费看 | 天堂久色| 我要色综合天天 | 久草精品网 | 99精品国产福利在线观看免费 | 天堂av中文字幕 | 欧美经典久久 | 精品一区二区免费视频 | 91私密视频 | 久久久久久久国产精品 | 丁香六月国产 | 成av人电影 | 国产老妇av| 超碰九九| 91丨九色丨国产女 | 久久久久久欧美二区电影网 | 91免费看黄色 | 精品国产电影 | 日批视频在线观看免费 | 欧美成年黄网站色视频 | 一区二区三区手机在线观看 | 国产91学生粉嫩喷水 | 国产精品麻豆一区二区三区 | 国产精品久久久777 成人手机在线视频 | 亚洲电影在线看 | 韩日色视频 | 中文字幕 欧美性 | 中文字幕色综合网 | av电影免费在线看 | 亚洲欧美国产精品18p | 国产精品毛片一区二区在线 | 欧美日韩高清一区二区三区 | 亚洲激情综合网 | 久久艹国产视频 | 91爱爱网址 | 99免费精品 | 在线影院中文字幕 | 成人午夜精品 | 操操操天天操 | 在线有码中文 | av一级片在线观看 | 成人一级片在线观看 | 日韩在线播放av | 久久久久久久国产精品影院 | 国产高清视频在线免费观看 | 狠狠ri| 亚洲精品自拍 | 国产视频一区在线 | 伊人久久精品久久亚洲一区 | 人人dvd| 亚洲天堂精品视频在线观看 | 国产一级视频免费看 | 欧美日韩国产精品久久 | 免费在线国产视频 | 久产久精国产品 | 日本精品久久久一区二区三区 | 亚洲激情电影在线 | 久久99精品一区二区三区三区 | 黄色av网站在线观看免费 | 91看片看淫黄大片 | 美国av大片| 日韩美女免费线视频 | 久草在线免费播放 | 久草久热 | 超碰97免费观看 | 久久久久久久久久国产精品 | 国产精品h在线观看 | 日韩免费b | 亚洲精品视频免费看 | 欧美一级黄色视屏 | 亚洲aⅴ免费在线观看 | 久久 精品一区 | 免费观看国产精品视频 | 狠狠色狠狠色综合日日92 | 黄色大全在线观看 | 日韩大片在线观看 | av一级免费| 日日爱av| 国产精品激情 | 岛国av在线不卡 | 国产99精品在线观看 | 久久精品在线免费观看 | 在线观看视频一区二区 | 欧美精品久久久久久久亚洲调教 | 午夜精品福利一区二区 | 久久一视频 | 91人人澡人人爽人人精品 | 亚洲一区二区观看 | 亚洲人在线视频 | 成人一区二区三区在线 | 精品999在线观看 | 日韩欧美一区二区三区黑寡妇 | 国产精品欧美久久 | 九九在线免费视频 | 又黄又爽又刺激 | 久久亚洲人 | 亚洲第一伊人 | 欧美激情xxxx性bbbb | 九九九九免费视频 | 国产激情电影综合在线看 | 亚洲精品视频在线观看免费 | 国产亚洲精品bv在线观看 | 狠狠干免费 | 91污污视频在线观看 | 久草在线综合网 | 久草在线视频中文 | 97精品久久 | 一区二区视频在线观看免费 | 日韩爱爱片| 国产一区av在线 | 五月婷婷深开心 | 亚洲免费在线视频 | 国产亚洲一区二区在线观看 | 久久精品在线视频 | 一级片视频在线 | 国产精品久久艹 | 国产高清av免费在线观看 | 久久久久久久久电影 | 黄色毛片视频 | 久久亚洲免费 | 日韩a在线 | 精品亚洲一区二区 | 亚洲精品免费在线播放 | 国产高清 不卡 | 亚洲区二区 | 狠狠网亚洲精品 | 中文字幕有码在线播放 | 一区二区久久 | 最新日韩视频 | 91麻豆精品国产午夜天堂 | 成 人 黄 色 片 在线播放 | 四虎在线观看视频 | www免费黄色 | 草久草久 | 天堂在线一区二区 | 午夜久久久影院 | 精品美女久久久久久免费 | 国产亚洲va综合人人澡精品 | 婷婷在线视频 | 麻豆一区在线观看 | 在线观看免费高清视频大全追剧 | 国产精品久久久久久爽爽爽 | 日日狠狠 | 国产精品四虎 | 草久在线观看视频 | 超碰人人舔 | 天天综合网久久综合网 | 天天天天色射综合 | 久久久久久久久久亚洲精品 | 日韩一二区在线 | 91在线观看黄 | 免费观看av网站 | 亚洲黄a | 少妇bbbb| 国产一区电影在线观看 | 国产 日韩 欧美 中文 在线播放 | 久草在线最新 | 亚洲在线视频免费 | 欧美日韩精品在线观看 | 午夜精品视频免费在线观看 | 日韩欧美视频二区 | 最新日韩在线观看视频 | 视频国产在线观看18 | 免费视频久久 | 亚洲综合国产精品 | avav99| 天天色棕合合合合合合 | 国产不卡视频在线播放 | 久久免费福利 | 成人黄色电影在线播放 | 日韩精品视频网站 | 亚欧洲精品视频在线观看 | 久久综合精品国产一区二区三区 | 亚洲婷婷在线视频 | 午夜 久久 tv | 色婷婷88av视频一二三区 | 在线免费中文字幕 | 国产精久久久久久久 | 亚洲午夜av | 日韩天堂在线观看 | 欧美在线观看小视频 | 亚洲狠狠婷婷综合久久久 | 男女日麻批 | 一区二区三区 中文字幕 | 成人免费观看电影 | 国产黄色大片免费看 | 在线观看日韩免费视频 | 欧美一级性视频 | 免费看高清毛片 | 欧美一二三视频 | 国内精品久久久久久久97牛牛 | 日韩在线观看视频免费 | av中文字幕电影 | 操操操干干干 | 一区精品在线 | 国产精品久久久久久久久久直播 | 热久久精品在线 | 99精品视频在线播放免费 | 6080yy精品一区二区三区 | 日韩中文在线视频 | 欧美日韩一区三区 | 国产精品久久久电影 | 精品一区91| 国产免费成人 | 99热超碰 | 黄色一级在线视频 | 日韩高清二区 | 亚洲伊人av | 国产高清中文字幕 | 涩五月婷婷 | 天天搞天天 | 成人手机在线视频 | 亚洲国产精品va在线看黑人动漫 | 久久精品在线 | 天天爱天天舔 | 爱色av.com | 玖玖在线免费视频 | 国产精久久久久久久 | 99草视频| 成年人黄色免费视频 | 中文字幕资源在线 | 综合色站导航 | 免费日韩一区二区 | 黄色免费网战 | 九九九视频在线 | 欧美色图88 | 丁香婷婷激情啪啪 | 久久激情视频免费观看 | av在线中文| 欧洲亚洲女同hd | 精品99免费 | 久久国产精品99国产精 | 天天爽天天搞 | 婷婷网站天天婷婷网站 | 色九九视频 | 在线免费观看视频 | 国模一区二区三区四区 | 精品视频免费播放 | 亚洲激情视频在线 | 国产精品不卡在线观看 | 欧美黄色高清 | 亚洲3级| 日韩在线观看一区二区三区 | 色视频在线观看免费 | 99热99 | 色婷婷狠狠18 | 久久伊人精品天天 | 99精品国产成人一区二区 | 亚洲欧洲精品一区二区 | 国产精品久久久久久久av大片 | 天天操偷偷干 | 成人中文字幕av | 狠狠网亚洲精品 | 人人爱在线视频 | 99热在线国产 | 日韩精品久久久久久久电影99爱 | 热热热热热色 | 免费精品人在线二线三线 | 国产美女视频免费观看的网站 | 亚洲色图色| 91激情小视频 | 亚洲综合色av | 丁香婷婷深情五月亚洲 | 亚洲精品videossex少妇 | 国产免费高清视频 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 69久久99精品久久久久婷婷 | 亚洲精品午夜国产va久久成人 | 在线国产激情视频 | 超碰97人人干 | 国产成人精品av久久 | 黄毛片在线观看 | 欧美一区二区视频97 | 久久97精品 | a视频在线观看 | 久久不卡视频 | 又黄又爽的免费高潮视频 | 欧美大片www | 国产成人一二片 | 91大片成人网 | 超碰人人干人人 | 97超碰在线久草超碰在线观看 | 五月婷影院 | 97在线观看免费观看 | 深夜福利视频在线观看 | 久久久久久久久久久电影 | 成人黄色视 | 97av超碰 | 免费在线观看污 | 国产精品毛片久久久久久久 | 国产玖玖精品视频 | 国产高清视频免费 | 亚洲精品乱码久久久久久久久久 | 国产一区二区在线免费视频 | 亚洲国产婷婷 | 视频直播国产精品 | va视频在线观看 | 青草草在线视频 | 久久观看免费视频 | 午夜免费视频网站 | 亚洲精品五月 | 最近更新中文字幕 | 永久免费精品视频网站 | 伊人婷婷激情 | 国产系列在线观看 | 国内精品视频久久 | 亚洲最新av在线网址 | 日韩精品中字 | 中文字幕91视频 | 国产精品一区二区久久 | 国产最新在线 | 国产第一页精品 | 综合色亚洲 | 亚洲va欧美va人人爽春色影视 | 欧美日韩裸体免费视频 | 人人澡人人模 | 色播五月婷婷 | 久久免费激情视频 | 天天爽夜夜爽人人爽一区二区 | 日韩精品久久久 | 欧美视频一区二 | 日本精品va在线观看 | 日韩免费看片 | 99爱精品视频 | 精品成人国产 | 国产精品久久久久永久免费 | a v在线观看 | 色天天中文 | 国产成人精品一区二区在线观看 | 欧美日韩国产二区 | 又黄又爽的免费高潮视频 | 欧美激情视频一区二区三区免费 | 在线观看视频一区二区 | 亚洲一二区精品 | 三上悠亚一区二区在线观看 | 九九免费在线看完整版 | 久久精品国产免费观看 | 久久草在线精品 | 亚洲国产中文字幕在线 | 天天色天天搞 | 亚洲精品美女视频 | 亚洲久草视频 | 欧美成人69av | 狠狠干网 | 国产精品黄 | 国产精品一区二区你懂的 | 亚洲精品电影在线 | 久久综合婷婷 | 高潮久久久久久久久 | 免费毛片一区二区三区久久久 | 日韩免费在线观看视频 | 美女性爽视频国产免费app | 日本精品va在线观看 | 婷婷综合国产 | 久久久久久不卡 | 久久大香线蕉app | 伊人射 | 91黄色在线看 | 国产专区在线视频 | 亚洲欧美日韩在线看 | 91视频在线观看免费 | 一级一片免费观看 | 91在线一区| 欧洲亚洲国产视频 | 丝袜美女视频网站 | 国产精品久久久久婷婷二区次 | 久久久久 免费视频 | 高清av网站 | 国产一级淫片免费看 | 久久精品一区二 | 久久久久麻豆v国产 | 日韩高清不卡在线 | 久久久久综合 | 99综合视频| 人人草在线视频 | 亚洲国产人午在线一二区 | 亚洲精品乱码久久久久久高潮 | 欧美性极品xxxx做受 | 国产一区二区三区免费在线观看 | 成人理论在线观看 | 亚洲在线视频观看 | 免费a现在观看 | 日韩在线观看视频网站 | 久草视频网| 亚洲视频免费在线看 | 在线观看色视频 | 欧美精品在线一区二区 | 91中文字幕网 | 婷婷av网 | 91喷水| 久久久久色 | 在线观看视频99 | 国产精品久久久久久爽爽爽 | 精品视频久久久 | 十八岁以下禁止观看的1000个网站 | 国产亚洲精品久久19p | 国产午夜在线观看 | 国产黄大片 | 91av资源在线 | 欧美在线视频日韩 | 欧美国产日韩一区二区三区 | 国产精品淫 | 亚洲最新av网站 | 日韩黄色软件 | 国产一区视频导航 | 99精品色| 欧美日本日韩aⅴ在线视频 插插插色综合 | 美女av在线免费 | 天天射射天天 | 欧美激情第28页 | 美女视频一区 | www黄免费 | 91精品91| 午夜黄色| 国产精品国内免费一区二区三区 | 欧美性成人| 91九色网站 | 人人干人人草 | 日本久久成人中文字幕电影 | 欧美日韩精品免费观看视频 | 人人爽人人澡人人添人人人人 | 亚洲精品激情 | 狂野欧美激情性xxxx | 国产一级电影免费观看 | 在线 视频 一区二区 | 综合视频在线 | 成人黄色小说在线观看 | 久久激情视频 久久 | 97日日| 久久在视频 | 成人在线免费观看网站 | 蜜臀久久99精品久久久酒店新书 | 欧美淫视频| 国产一级黄色片免费看 | 91大神一区二区三区 | 国产精品久久久久久av | 最新极品jizzhd欧美 | 高清av网 | 欧美午夜a | 免费看日韩 | 99精品福利 | 97在线视频免费观看 | 字幕网av| 国产日韩精品一区二区 | 欧美日韩有码 | 亚洲影视资源 | 亚洲精品在线视频观看 | 久影院 | 黄色在线免费观看网址 | 91中文在线视频 | 人人看97| 久久99国产精品免费网站 | 亚洲免费成人av电影 | 久久久久久久久久久免费av | 久久久久久国产精品久久 | 国内精品久久久久影院优 | 国产在线观看高清视频 | 天天se天天cao天天干 | 国产丝袜| www.com久久 | 9在线观看免费 | 18岁免费看片 | 日本精品一区二区三区在线观看 | 成人精品电影 | 91高清在线看| 九九九九九精品 | 久久免费国产精品 | 香蕉视频免费在线播放 | 一二三区av | 一二三区av | 国产午夜激情视频 | 日本三级中文字幕在线观看 | 国产毛片久久 | 国产香蕉97碰碰碰视频在线观看 | 午夜精品一区二区三区在线播放 | 久草在线免费在线观看 | 91精品国产自产在线观看永久 | 欧美做受高潮 | 日本一区二区三区免费观看 | 国产精品9999 | 色综合久久88色综合天天6 | 久草电影在线观看 | 992tv在线| 少妇搡bbbb搡bbb搡忠贞 | 干狠狠| 欧美高清视频不卡网 | 国产视频1| 最新一区二区三区 | 日本在线观看一区二区三区 | 手机成人av在线 | 激情五月婷婷激情 | 久久6精品 | 久久成人综合 | 日本三级中文字幕在线观看 | 国产精品成人在线观看 | 午夜精品一区二区三区视频免费看 | 欧美日本国产在线观看 | 国产精品久久久久影视 | 日韩av电影免费观看 | 亚洲综合成人在线 | 国产精品日韩欧美 | 91精品欧美一区二区三区 | 激情综合五月婷婷 | 日韩av在线高清 | 久久电影中文字幕视频 | 六月丁香婷婷在线 | 欧美成人黄 | 国产群p视频| 婷婷色在线播放 | 色片网站在线观看 | 亚洲黑丝少妇 | 日韩欧美电影 | 91精品国产高清 | 美女网站视频免费黄 | 亚洲另类xxxx| 国产成人a亚洲精品 | 国产精品福利午夜在线观看 | 免费观看国产视频 | 日韩精品在线观看av | 日韩有码中文字幕在线 | 精品国产一二区 | av动态图片 | 婷婷夜夜 | 五月婷婷开心 | 中文字幕在线视频精品 | 成人午夜毛片 | 久久国产一区二区三区 | 中文字幕在线一区二区三区 | 六月久久婷婷 | 久久久黄色免费网站 | 久久九九影院 | 91视频高清完整版 | 色视频网站免费观看 | 正在播放国产精品 | 日韩视频欧美视频 | 黄色av网站在线观看 | 国产手机在线观看 | 亚洲视频电影在线 | 国产一级电影 | 精品久久久久久国产91 | 一区二区三区高清不卡 | 久久久久亚洲精品成人网小说 | 狠狠干成人综合网 | 色噜噜在线观看 | 欧美精品久久久久 | 激情视频免费观看 | 国产精品白浆视频 | 国产午夜精品一区 | 免费视频一二三区 | 精品国产1区 | a黄色一级 | 在线观看免费福利 | 在线有码中文字幕 | 国产三级午夜理伦三级 | 叶爱av在线 | 欧洲一区精品 | 六月丁香六月婷婷 | 中文字幕av日韩 | 久久久久欧美精品999 | 天天曰天天爽 | 日日夜夜免费精品视频 | 亚洲年轻女教师毛茸茸 | 在线天堂中文在线资源网 | 欧美精品久久久久性色 | 美女免费黄网站 | 色wwww| 91免费视频网站在线观看 | 开心激情婷婷 | 波多野结衣视频一区二区 | 欧美一区二区三区激情视频 | aaawww| 中文字幕乱码电影 | 成人av免费网站 | 日韩成人精品一区二区 | 日韩精品一区二区久久 | www.天天射.com | 中文字幕第一页av | 精品少妇一区二区三区在线 | 91视频免费网址 | 国产一区二区三区高清播放 | 美女久久一区 | 成人va在线观看 | 亚洲va天堂va欧美ⅴa在线 | 久久精品高清视频 | 高清视频一区 | 国产免费资源 | 国产免费国产 | 久久a热6 | 888av| 亚洲精品mv在线观看 | 亚洲成人频道 | 99久久这里只有精品 | 日韩在线观看视频中文字幕 | 最新影院 | 亚洲精品白浆高清久久久久久 | 久久网址 | 日韩免费高清 | 久久亚洲热 | 成人av影视 | 麻豆视频国产精品 | 免费看一级一片 | 亚洲欧美在线观看视频 | 久久久久免费精品国产 | 免费观看国产精品视频 | 日韩理论电影网 | 99精品在线 | www.久久91| 国产一区二区三区黄 | 手机在线小视频 | 91免费国产在线观看 | 在线播放国产精品 | 亚洲国产精彩中文乱码av | 国产视频手机在线 | 一区二区三区不卡在线 | 日韩电影在线观看一区二区 | 久久人人97超碰精品888 | 干 操 插 | 国产黄色a | 亚洲激情视频 | www.久久精品视频 | 激情欧美日韩一区二区 | zzijzzij亚洲日本少妇熟睡 | 最近在线中文字幕 | 精品久久久成人 | 国产亚洲成人网 | 91视频免费看网站 | 久久99热这里只有精品国产 | 欧美日韩在线视频观看 | 天天做日日爱夜夜爽 | 亚洲激情电影在线 | 久久99热精品 | 欧美日韩91 | 狠狠干.com | 日韩一区精品 | 日韩性xxx| 亚洲综合五月天 | 国产精品久久9 | 91你懂的 | 激情一区二区三区欧美 | 午夜视频在线观看欧美 | 日韩电影一区二区三区 | 日韩免费观看高清 | av高清一区 | 亚洲永久av| 免费人成在线观看网站 | 亚洲精品无 | 日三级在线 | 欧女人精69xxxxxx | 亚洲最新视频在线 | 黄色免费网| 激情久久久久久久久久久久久久久久 | 国产精品视频免费在线观看 | 91在线播放视频 | 亚洲精品久久久久久久蜜桃 | 天堂在线视频中文网 | va视频在线| 久久字幕 | 一二三区视频在线 | 91麻豆精品91久久久久同性 | 欧美日韩一区二区三区在线观看视频 | 国产精品国产三级在线专区 | 欧美精品久久久久性色 | 一区二区三区四区五区在线 | 国产免费观看高清完整版 | 伊人中文字幕在线 | 一级免费黄色 | a特级毛片| 欧美福利片在线观看 | 亚洲四虎影院 | 免费观看www7722午夜电影 | 黄色网址a| 九色porny真实丨国产18 | 一二三精品视频 | 亚洲黄色a | 99精品免费久久久久久日本 | 欧美aaa大片 | 国产成人精品福利 | 国产精品第一页在线观看 | 国产一区二区久久久久 | 国产护士hd高朝护士1 | 国产精品国产三级国产 | 五月婷影院 | 亚洲国产精品电影在线观看 | 成人欧美一区二区三区黑人麻豆 | av色综合网 |