• FastCGI协议分析


    不知道什么时候,就开始有了让HomeServer支持PHP的念头。于是分析起了FastCGI协议。FastCGI用于WebServer与WebApplication之间的通讯,例如Apache与PHP程序。

    FastCGI协议数据包是8字节对齐的,由包头(Header)和包体(Body)组成。例如要请求一个index.php的页面,WebServer首先向WebApp发送一个Request数据包。包头有个请求ID用于并行工作时,区别不同的请求。

    包头

    [版本:1][类型:1][请求ID:2][数据长度:2][填充字节数:1][保留:1]

    包体

    [角色:2][参数:1][保留:5]

    接着,再发送一个Params数据包,用于传递执行页面所需要的参数和环境变量。

    包头

    [版本:1][类型:1][请求ID:2][数据长度:2][填充字节数:1][保留:1]

    包体

    [名称长度:1或4][值长度:1或4][名称:变长][值:变长] …

    其中,名称和值的长度占用的字节数是可变,取决于第一个字节(高位)的最高位是否为1,为1则长度是4个字节,否则为1个字节。即如果长度不超过128字节,就用一个字节来保存长度足够了。

    参数发送后还要发送一个没有包体,只有包头的空的Params数据包,用来表示参数发送结束。

    如果请求页面时POST方式,还会发送表单数据。这就要用到Stdin数据包了。

    包头

    [版本:1][类型:1][请求ID:2][数据长度:2][填充字节数:1][保留:1]

    包体

    [数据内容:长度在包头中设置,8字节对齐]

    有时候POST的数据大于或等于64KB,就不能使用一个Stdin数据包发送完毕了,需要使用多次Stdin数据包来完成所有数据的传输。与Params数据包一样,结尾要发送一个没有包体,只有包头的空的Stdin数据包,用来表示参数发送结束。

    至此,WebServer要提供给WebApplication的数据已经发送完毕。接着就接收来自WebApplication的数据了。

    数据接收包Stdout与Stdin是差不多的,这里不再描述。不过接收到的数据由HTTP头和网页数据两部分组成,WebServer要对其做一定的处理后才能发送到浏览器。同Stdin数据包一样,WebServer会接收到一个来自WebApplication的Stdout的空数据包,表示接收的Stdout数据已经完毕。

    最后,WebApplication会发送一个包含状态的EndRequest数据包,至此,一次页面请求处理完毕。

    下面给出一些相关结构参考。

    通用包头:

    typedef struct {
        unsigned char version;
        unsigned char type;
        unsigned char requestIdB1;
        unsigned char requestIdB0;
        unsigned char contentLengthB1;
        unsigned char contentLengthB0;
        unsigned char paddingLength;
        unsigned char reserved;
    }FCGI_Header;
    
    typedef struct {
        unsigned char roleB1;
        unsigned char roleB0;
        unsigned char flags;
        unsigned char reserved[5];
    } FCGI_BeginRequestBody;
    
    typedef struct {
        FCGI_Header header;
        FCGI_BeginRequestBody body;
    } FCGI_BeginRequestRecord;
    
    typedef struct {
        unsigned char appStatusB3;
        unsigned char appStatusB2;
        unsigned char appStatusB1;
        unsigned char appStatusB0;
        unsigned char protocolStatus;
        unsigned char reserved[3];
    } FCGI_EndRequestBody;
    

    每次请求页面时,传递给PHP程序的参数:

    SCRIPT_FILENAME,

    QUERY_STRING,

    REQUEST_METHOD,

    CONTENT_TYPE,

    CONTENT_LENGTH,

    SCRIPT_NAME,

    REQUEST_URI,

    DOCUMENT_URI,

    DOCUMENT_ROOT,

    SERVER_PROTOCOL,

    GATEWAY_INTERFACE,

    SERVER_SOFTWARE,

    REMOTE_ADDR,

    REMOTE_PORT,

    SERVER_ADDR,

    SERVER_PORT,

    SERVER_NAME,

    REDIRECT_STATUS,

    HTTP_ACCEPT,

    HTTP_ACCEPT_LANGUAGE,

    HTTP_ACCEPT_ENCODING,

    HTTP_USER_AGENT,

    HTTP_HOST,

    HTTP_CONNECTION,

    HTTP_CONTENT_TYPE,

    HTTP_CONTENT_LENGTH,

    HTTP_CACHE_CONTROL,

    HTTP_COOKIE,

    HTTP_FCGI_PARAMS_MAX

    好像很多,但是很多空值的,可以省去,不发送之,即可。

    转自:http://xiaoxia.org/2009/10/05/fastcgi-protocol-analysis/

  • 相关阅读:
    web设计_6_图片/标题/说明文字布局
    web设计_5_自由的框式组件
    web设计_4_可扩展的行
    ubuntu下把python脚本转为二进制字节码文件
    Ubuntu与Window双系统安装的注意事项
    安装Windows和Ubuntu双系统2
    安装Windows和Ubuntu双系统
    Configuring and Running Django + Celery in Docker Containers
    ggplot绘图之基本语法
    R Multiple Plots
  • 原文地址:https://www.cnblogs.com/chengxuzhixin/p/4933085.html
Copyright © 2020-2023  润新知