zoukankan      html  css  js  c++  java
  • 【Web学习笔记】浅析CGI概念及用法

    1. CGI是什么
            CGI是Common Gateway Interface的简写,它提供了一种标准方法使得位于WebServer后端的web应用可以根据client的请求动态生成网页内容。在互联网应用常见的C-S模式中,从Server角度来看,CGI提供了WebServer和生成具体内容的Web程序之间的接口,具体实现CGI标准协议的程序称为CGI脚本(因为它们通常是用脚本语言实现的)或简称CGI。
            可见,严格意义上的CGI其实是一个标准(详见 CGI-RFC-Doc ),而我们经常听到的CGI其实是指实现CGI标准的CGI程序(可能由脚本语言实 现,也可能由C/C++实现
            对于新手来说,有必要搞清楚CGI的这两重概念,否则可能由于概念不清而导致一头雾水。
            关于初学者对CGI的困惑,StackOverflow上有篇有趣且经典的帖子,强烈建议围观:I never really understood: what is  CGI? ,相信对理解CGI的两重概念有帮助。

    2. 引入CGI的目的
            CGI标准定义了一系列被称为meta-variables的抽象参数,这些meta-variables可描述来自客户端的http请求,从而实现了一个WebServer和后端CGI程序的接口,这个接口是与平台无关的。
            由于CGI的存在,WebServer与后端程序得以各司其职:
             1) WebServer负责处理HTTP连接、数据传输、网络事件等与客户端请求相关但与具体应用无关的逻辑
             2) 后端程序处理应用相关逻辑,根据请求参数动态生成数据并由WebServer返回给客户端
            一个典型C-S交互的完整流程如下所述:
            WebServer接收来自client的请求并将其请求参数转换为CGI的meta-variables和message-body(如HTTP POST的body数据),接着,根据URI参数来选择合适的CGI程序并调用之以处理用户请求,然后,接收CGI程序返回的结果数据,最后,将数据返回给client。
            需要说明的是:在处理client request过程中,WebServer负责实现协议级或传输层的安全认证(如https认证)。

    3. 实例说明
            以client的http GET请求http://somehost.com/cgi-bin/somescript/this%2eis%2epath%3binfo?param1=hello&param2=world为
    例,其可以被抽象为如下格式:
               <scheme> "://" <server-name> ":" <server-port> <script-path> <extra-path> "?" <query-string>
            根据CGI标准,位于WebServer下游的CGI程序会将该http请求转换为CGI标准定义的一系列meta-variables,例如:
             <scheme>:值为"http",对应meta-variables中的SERVER_PROTOCOL
             <server-name>:值为"somehost.com",对应SERVER_NAME
             <server-port>:默认值80,对应SERVER_PORT
             <script-path>:值为"/cgi-bin/somescript/",对应SCRIPT_NAME
             <extra-path>:值为"this%2eis%2epath%3binfo",实际上,它是另一个meta变量PATH_INFO的url-encoded形式
             <query-string>:值为param1=hello&param2=world,对应QUERY_STRING
            由于CGI程序已经将http请求转换为标准的CGI meta varialbes,故不管后端业务模块是什么语言实现的,它不用再去关心具体的
    http请求需要怎么解析,只需访问这些meta变量并做对应处理即可。这正是CGI标准及CGI程序的意义所在。

    4. 关于CGI的补充说明
           传统CGI脚本其实是一段可执行程序,每次执行都会创建新进程。这样就引起一个问题:webserver每次响应client请求,均需创建并运行CGI进程后才能返回结果。在Linux系统中,创建进程的代价是比较高的,尤其是生产环境要求高并发且低延时的情况下,新建进程对系统性能的影响会更加明显。
           在这种现实驱动下,出现了两种常见的优化思路:
           1) 预先创建(prefork)一系列CGI进程,从而避免每次新建进程。典型代表:FastCGI 
           2) 业务代码直接以扩展模块的形式嵌入WebServer执行。典型代表:Apache或Nginx的mod_php扩展等

    5. CGI实际部署示例
            以lighttpd为例,只需在lighttpd.conf中做两处配置即可:
            1) 在webserver要加载的扩展模块中指定"mod_proxy_backend_fastcgi",示例如下:

    ## modules to load
    # at least mod_access and mod_accesslog should be loaded
    # all other module should only be loaded if really neccesary
    # - saves some time
    # - saves memory
    server.modules = ( 
          "mod_access",
          "mod_expire",
          "mod_accesslog",
          "mod_error_redirect",
          "mod_cookie",
          "mod_firewall",
          "mod_deflate",
          "mod_rewrite",
          "mod_proxy_core",
          "mod_proxy_backend_fastcgi",
          "mod_redirect"
    )

           2) 指定webserver向后端模块转发协议为CGI协议,示例如下:

    $HTTP["url"] =~ ".php" {
          proxy-core.balancer = "static"
          proxy-core.allow-x-sendfile = "enable"
          proxy-core.protocol = "fastcgi"
        }

    【参考资料】
    1. wikipedia - Common Gateway Interface 
    2. RFC3875 - The Common Gateway Interface (CGI) Version 1.1  
    3. CGI Programming Is Simple! 
    4. StackOverflow - I never really understood: what is CGI? 
    5. wikipedia - FastCGI 

    ======================= EOF ========================


  • 相关阅读:
    算法笔记 --- Selection Sort
    算法笔记 --- Radix Sort
    算法笔记 --- Quick Sort
    算法笔记 --- Merge Sort
    算法笔记 --- Insertion Sort
    算法笔记 --- Heap Sort
    算法笔记 --- Counting Sort
    算法笔记 --- Bubble Sort
    算法笔记 --- Tree Travers
    javaweb_JDBC
  • 原文地址:https://www.cnblogs.com/riskyer/p/3397956.html
Copyright © 2011-2022 走看看