美文网首页
php之CGI、FastCGI 和 php-fpm

php之CGI、FastCGI 和 php-fpm

作者: 猿来是八阿哥 | 来源:发表于2020-03-02 02:40 被阅读0次

    一、cgi 规范

    官方文档:RFC3875: CGI - the Common Gateway Interface`

    1. CGI 目的

    The Common Gateway Interface (CGI) allows an HTTP server and a CGI script to share responsibility for responding to client requests.

    CGI 使得 Http-ServerCGI 程序 可以在 客户端请求提供相应 上分工合作、各司其职。

    2. Server 职责

    The server acts as an application gateway. It receives the request from the client, selects a CGI script to handle the request, converts the client request to a CGI request, executes the script and converts the CGI response into a response for the client.

    Http-Server 作为一个应用网关,负责:

    • 接受http请求
    • 选择一个cgi程序处理http请求
    • 将http请求转化成cgi请求
    • 执行cgi程序
    • 将cgi程序的响应转为为http响应
    3. server 发起 CGI 请求

    Server 在发起 cgi 请求时,需要从 http 请求中解析到以下信息:

    • Meta-variables: CONTENT_TYPE PATH_INFO REMOTE_ADDR REMOTE_HOST REQUEST_METHOD SCRIPT_NAME SERVER_NAME
    • 请求体:post 数据等
    • 请求方法:GET POST HEAD
    • cgi 程序的执行命令
    4. server 解析 CGI 响应
    • 接收 cgi 响应:

    cgi 程序通过使用 server 提供的方法 或者 标准输出文件符 将结果返回给 server,同时,server 也会实现一个等待 cgi 返回的超时策略,用来终止超时未返回的 cgi 进程。

    • 解析 cgi 响应类型:

      • document-response,文档响应,如:Content-Type [ Status ] *other-field NL response-bodyserver 会在此基础上做一些改动,以符合 http 协议。
      • local-redir-response,本地重定向响应,如:local-Location NLserver 需要根据此影响,发起另一次的 cgi 请求
      • client-redir-response,客户端重定向响应,如:client-Location *extension-field NL。对于 http 请求,server 需要返回给客户端一个 302 found 的客户端重定向响应。
      • client-redirdoc-response,客户端文档重定向响应,如:client-Location Status Content-Type *other-field NL response-body
    • 解析 cgi 响应头信息:

      • Content-Type,响应类型,如:"Content-Type:" media-type
      • Location,重定向相关头信息,包含:Location client-Location local-Location fragment-URI fragment local-pathquery abs-path 等。
      • Status,处理状态,定义:Status:" status-code SP reason-phrase NL,如:200 'OK'302 'Found'400 'Bad Request'501 'Not Implemented'等。
      • Protocol-Specific Header Fields,协议特殊响应,如:HTTP/1.0HTTP/1.1等。
      • Extension Header Fields,扩展头信息,以 X-CGI- 打头的响应头。
    • 解析 cgi 响应内容:

    cgi 响应体的定义是 response-body = *OCTET,server 需要将 cgi 响应体原封不动的返回给客户端,除非 cgi 响应头信息中要求了 transfer-codingscontent-codingscharset conversions 相关的转化。

    5. cgi 对 server 的规范要求

    define any restrictions on allowed path segments, in particular whether non-terminal NULL segments are permitted;

    • server 要对 允许访问的 path 进行限制

    define the behaviour for "." or ".." path segments; i.e., whether they are prohibited, treated as ordinary path segments or interpreted in accordance with the relative URL specification.

    • server 要明确 ... 的处理方式

    define any limits of the implementation, including limits on path or search string lengths, and limits on the volume of header fields the server will parse.

    • server 要对 path query_string 头信息数量及长度 进行限制
    6. cgi 对 cgi 程序的规范要求
    • 对于无法处理的 path_info 给与 404 Not Found 响应。
    • 对于无法确认 content_type 的表单给与 415 'Unsupported Media Type' 响应。即:不是 application/x-www-form-urlencoded 且不是 multipart/form-data 的表单。
    • 在返回头信息时,cgi 程序应当在 http 头信息之前,尽可能快的返回 cgi 头信息,以便节省 server 的内存使用。
    • cgi 应该明白 REMOTE_ADDRREMOTE_HOST 并不能正确表明请求的最终来源,这些只表明了请求的最近来源,而这个来源可能是代理或者网关。
    7. cgi 中的安全考虑
    • gethead 请求方法应该是安全的,幂等的(多次请求和一次请求的效果是一样的)。
    • 对于 http 头信息中包含的 敏感信息,如:HTTP_AUTHORIZATION,server 不应该将这些头信息传递给 cgi 程序。
    • 重要的数据应该作为 post 请求的消息体,而不是在 uri 中或者 header 中。
    • 对于 TLS 连接的认证,应该在 server 端完成,而不是 cgi 程序来完成。
    • 在一般的 cgi 实现中,cgi 进程作为 server 进程的子进程,用户 server 一样的 usergroup,cgi 程序不应该影响 server 进程,包含:配置文件、文档、日志等。
    • 固定长度缓冲区的使用如果不仔细检查溢出,可能会导致攻击者利用操作系统的“stack smashing”或“stack overflow”漏洞。
    • 要充分考虑 web 请求的无状态性,对于构成一个 web 事务 的多次请求,要充分验证数据的合法性,不能对发起请求的网络代理(user-agent)做任何上下文的假设。

    二、fastcgi 规范

    官网:www.fastcgi.com
    二手中文文档:FastCGI规范

    fastcgi 在 cgi 的基础上进行了优化,主要体现在:cgi 程序的执行方式cgi 程序的角色 两方面。

    1. 执行方式上的优化
    • 在 cgi 模式中,server 对于每一个请求,都启动一个进程,由这个进程负责 cgi 程序的执行,得到影响后退出进程。即:fork-and-execute
    • 在 fastcgi 模式中:
      • server 和 fastcgi 分开部署,server 和 fastcgi 基于 socket 通信
      • fastcgi 包含 一个负责 socket 通信的父进程若干个负责处理请求的子进程
      • fastcgi 的子进程在处理完一个请求后,并不退出,会等待处理下一个请求
    2. 角色上的变化
    • 在 cgi 模式中,server 解析 http 请求,组织 cgi 请求参数,转化为 cgi 请求,由 cgi 程序给出响应,然后再由 server 转化为 http 响应,发送给客户端。即:一个 Responder 角色。
    • 在 fastcgi 模式中,cgi 程序:
      • Responder,像 cgi 模式中一样,作为 响应者 给出响应。
      • Authorizer,根据所收到的 cgi 请求信息,对请求做出一个 认可 或者 未认可 的判定。
      • Filter,对所收到的 http 请求信息进行过滤,返回一个 过滤后的 http 请求信息
    3. fastcgi 工作流程
    1. fastcgi 进程启动一个 socket 监听,等待 server 进程的 socket 连接,并启动若干个子进程,用于 cgi 程序的执行。
    2. serverfastcgi 进行 socket 通信,并以 fastcgi 协议的形式,发送 cgi环境变量标准输入数据用于 cgi 执行的子进程
    3. 用于 cgi 执行的子进程 在执行完 cgi 程序后将响应发送给 server 进程。
    4. 用于 cgi 执行的子进程 处理完一个 socket 连接,等待下一个连接。

    三、 cgi 个人理解

    综上对 rfc3875 的阅读整理以及对 fastcgi 的学习,个人对 cgi 的理解是:

    1. cgi 是一个协议规范,它在职责、实现要求、通信方式、安全性等方面对 server 和 cgi 程序进行了规范,使得很多语言在满足 CGI 规范的前提下,能和 server 分工合作,构建起了我们的动态网站(Dynamic website)。
    2. cgi 规范中缺少 server 对 cgi-script 执行方式的规范,使得 cgi 的执行停留在 fork-and-execute 阶段,性能低下。
    3. fastcgi 在 cgi 程序的执行方式上进行了优化,以 serverfastcgi 进行 socket 通信的方式实现了分开部署,甚至多机器部署。
    4. fastcgi 还进一步扩充了 cgi 程序的 角色,使得 cgi 程序在单一的 Responder 的基础上,有了 AuthorizerFilter 两个功能。
    5. php-cgifastcgi 的一个 php 版本实现,使得 php 可以作为 cgi 语言的一种,承担动态网站的开发。
    6. php-fpmFastCGI Process Manager,它是 php-cgi 的一个进程管理器,提供了对 php-cgi 进程的一系列管理功能,如:平滑终止、平滑重启(加载新的php.ini)等。

    相关文章

      网友评论

          本文标题:php之CGI、FastCGI 和 php-fpm

          本文链接:https://www.haomeiwen.com/subject/uvwjkhtx.html