在CGI程序中POST和GET消息的处理

  数据传送格式 当用户填完表格并按了SUBMIT按钮后,Web浏览器并非将用户所填的数据直接送给Web服务器, 而先要经过一定的编码处理。 Web浏览器总是将数据按照“变量名=变量值”这样的数据对格式进行编码,并且每对数据之间 用一个&符号相连接。其中“变量名”就是Form元素中的NAME属性值;“变量值”则是用户在 输入框中所输入的数据,或者是用户所选择的数据(即RADIO,CHECKBOX,OPTION中 的VALUE值)。 并且Web浏览器将用户数据中的所有空格都替换成"+"号。另外一些特殊字符的表示使用转义 符"%"后面加上该特殊字符的十六进制ASCII码。特殊字符主要包括"="、"+"、"&"、"%"以及多 行文本中的回车,换行符,所有不能直接显示的高位ASCII符等。


  一个Form的简单例子 例如在上例中用户填入了下述信息(其中/n表示回车换行): name "J&K" sex "male" flavor "apple" flavor "orange" weight "middle" opinion "I think it is necessary that/nman eat fruit everyday." 则Web浏览器发送数据时的字符序列为: name=J%26K&sex=male&flavor=apple&flavor=orange&weight=middle& opinion=I+think+it+is+necessary+that%0D%0Aman+eat+fruit+everyday. 用CGI程序处理得到的数据 当Web浏览器将Form数据经过编码后,就传送给了Web服务器,而Web服务器并非自己处理这些 数据,而是先依靠CGI程序来帮忙处理这些数据,然后Web服务器再把CGI程序产生的处理结果 返回给Web浏览器。


    CGI(Common Gateway Interface,通用网关接口)是信息服务器(如Web服 务器)与外部应用程序之间的一个接口标准。通常被Web服务器所取到的HTML文件总是事先编 辑好的,固定不变的信息,但若通过实时运行着的CGI程序Web服务器就有可能向Web浏览器 输出动态的信息。 CGI标准用最简单的话来说就是:CGI程序是通过标准输入(stdin)或环境变量来得到服务器的输 入信息,并通过标准输出(stdout)向服务器输出信息。 当Web服务器收到了由Web浏览器传来的Form数据时,就启动标记中ACTION属性所指 明的CGI程序。如果METHOD属性值是GET,CGI程序就从环境变量QUERY_STRING中获取Form数 据;若METHOD属性值是POST,CGI程序就从标准输入(stdin)中获取Form数据。 CGI程序获取Form数据并经过处理后,还要向Web服务器返回一定的信息(如数据的处理结果等 )。为让Web服务器能正确理解所返回的是何种信息,CGI规定在输出的信息体前加上一个头部 信息,该头部信息由若干行ASCII文本构成,并用一个空行将头部信息与信息体隔开。


    例如要返 回HTML文档则头部信息为"Content-type: text/html"。 下面给出一个用C语言编写的CGI程序的基本框架:

#include   <stdio.h>
#include   <stdlib.h>
#include   <string.h>
char InputBuffer[4096];

int DecodeAndProcessData(char *input);    /*具体译码和处理数据,该函数代码略*/

int main(int argc, char*argv[])
{
        int   ContentLength;   /*数据长度*/
        int   x;
        int   i;
        char   *p;
        char   *pRequestMethod;     /*   METHOD属性值   */
        setvbuf(stdin,NULL,_IONBF,0);     /*关闭stdin的缓冲*/
        printf("Content-type:text/html\n\n");     /*从stdout中输出,告诉Web服务器返回的信息类型*/
        printf("\n");                                           /*插入一个空行,结束头部信息*/
        printf("<p>hello test</p>");
        /*   从环境变量REQUEST_METHOD中得到METHOD属性值   */

        pRequestMethod = getenv("REQUEST_METHOD");
        if(pRequestMethod==NULL)
        {
                printf("<p>request = null</p>");
                return   0;
        }
        if (strcasecmp(pRequestMethod,"POST")==0)
        {
                printf("<p>OK the method is POST!\n</p>");
                p = getenv("CONTENT_LENGTH");     //从环境变量CONTENT_LENGTH中得到数据长度    
                if (p!=NULL)
                {
                        ContentLength = atoi(p);
                }
                else
                {
                        ContentLength = 0;
                }
                if (ContentLength > sizeof(InputBuffer)-1)   {
                        ContentLength = sizeof (InputBuffer) - 1;
                }

                i   =   0;
                while (i < ContentLength)
                {                         //从stdin中得到Form数据    
                        x  = fgetc(stdin);
                        if (x==EOF)
                                break;
                        InputBuffer[i++] = x;
                }
                InputBuffer[i] = '\0';
                ContentLength   =   i;
                DecodeAndProcessData(InputBuffer);                 //具体译码和处理数据,该函数代码略    
        }
        else if (strcasecmp(pRequestMethod,"GET")==0)
        {
                printf("<p>OK the method is GET!\n</p>");
                p = getenv("QUERY_STRING");     //从环境变量QUERY_STRING中得到Form数据    
                if   (p!=NULL)
                {
                        strncpy(InputBuffer,p,sizeof(InputBuffer));
                        DecodeAndProcessData(InputBuffer);    //具体译码和处理数据,该函数代码略    
                }
        }
        printf("<HEAD><TITLE>Submitted OK</TITLE></HEAD>\n");//从stdout中输出返回信息    
        printf("<BODY>The information you supplied has been accepted.</BODY>\n");

        return   0;
}


int DecodeAndProcessData(char *input)    //具体译码和处理数据   
{
        // 补充具体操作
        return 0;
}



  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现一个基本的 WEB 服务器程序需要以下步骤: 1. 创建一个 Socket 监听客户端请求; 2. 解析客户端请求,判断是 GET 还是 POST 请求; 3. 如果是 GET 请求,获取请求文件的路径和文件名,并读取文件内容; 4. 如果是 POST 请求,解析请求参数,并调用相应的 CGI 程序处理; 5. 构造 HTTP 响应报文,将响应内容发送回客户端。 下面是一个简单的示例代码: ```python import socket import os def handle_request(client_socket): # 读取客户端请求数据 request_data = client_socket.recv(1024).decode() # 解析请求头信息 request_lines = request_data.splitlines() # 获取请求方法(GET/POST)和请求路径 request_method, request_path, request_proto = request_lines[0].split(' ') if request_method == 'GET': # 处理 GET 请求 file_path = '.' + request_path if os.path.isfile(file_path): # 如果请求文件存在,读取文件内容并构造 HTTP 响应报文 with open(file_path, 'rb') as f: response_body = f.read() response_header = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: {}\r\n\r\n'.format(len(response_body)) response_data = response_header.encode() + response_body else: # 如果请求文件不存在,返回 404 错误 response_body = b'404 Not Found' response_header = 'HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\nContent-Length: {}\r\n\r\n'.format(len(response_body)) response_data = response_header.encode() + response_body elif request_method == 'POST': # 处理 POST 请求,调用相应的 CGI 程序处理请求 # TODO: 实现 CGI 程序调用 pass else: # 不支持的请求方法,返回 501 错误 response_body = b'501 Not Implemented' response_header = 'HTTP/1.1 501 Not Implemented\r\nContent-Type: text/html\r\nContent-Length: {}\r\n\r\n'.format(len(response_body)) response_data = response_header.encode() + response_body # 发送响应数据到客户端 client_socket.send(response_data) # 关闭客户端连接 client_socket.close() def run_server(): # 创建 Socket 监听客户端请求 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('127.0.0.1', 8888)) server_socket.listen(5) while True: # 接受客户端连接请求 client_socket, client_address = server_socket.accept() # 处理客户端请求 handle_request(client_socket) if __name__ == '__main__': run_server() ``` 需要注意的是,该示例代码只是一个基本的实现,还有很多细节和安全问题需要考虑,比如请求参数的安全性、文件路径的合法性检查等。在实际应用,建议使用成熟的 Web 服务器框架,如 Flask、Django 等,它们已经考虑了很多安全和性能问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值