CGI运行机制和基本环境变量备忘

前言

     读了三年的研究生,没有碰过web相关开发了。本科的三年的web开发经验都忘记完了。工作找好了,最近准备开始重新复习一下C和web相关的知识,以前做web开发的时候主要是主要是用PHP那几十个API来做系统开发,对PHP底层没有去学习过,最近打算从CGI出发,从本质上来了解一下web底层相关技术。

今天主要看了下面几个CGI入门的知识,还不错。

FastCGI实战:http://blog.csdn.net/huangyaoshifog/article/details/335433。

CGI入门:http://blog.csdn.net/conquerwave/article/details/7029864


CGI运行机制以及优缺点

CGI以可执行程序(例如exe)的形式,以独立进程运行在http服务器中。当http接受到请求,通过创建一个CGI进程,CGI通过标准输入输出IO同HTTP服务器之间进行交互,从而处理各种请求。处理完以后释放CGI进程。

CGI的优点:

  • CGI是以独立进程的方式来运行,所以如果一个CGI处理失败退出,不影响后面CGI处理,保证服务器的稳定性
  • CGI相对脚本来说,具有高安全性

CGI缺点:

  • CGI处理进程的创建开销较大,无法在高密度请求环境下使用。
  • 相对脚本来说,编辑HTML比较麻烦

下面主要列一下CGI的基本环境变量,作为以后查询用吧。

基本环境变量

         服务器与CGI程序交换信息的协作方式是通过环境变量实现的。无论什么请求,CGI程序总能在特定位置找到某些信息。无论环境变量怎样定义,总有一些变量有着特定含义。环境变量是一写保存用户信息的内存区。例如,所有的机器都有一个PATH环境变量,当在当前目录找布道文件时就要查找PATH变量。当服务器收到一个请求后,它首先要收集它能得到的所有相关信息,并把它放入内存。那么,服务器要收集什么信息呢?

  • 关于服务器自身的详细信息
  • 关于用户的信息信息
  • 关于用户请求的信息

        服务器不知道CGI程序到底需要那些信息,所以它把这些信息一起收集,那么如果有什么重要的东西就不会遗漏了。

环境变量的存储

在写C语言的时候完整的main函数的写法应该如下:

int main(int argc, char **argv, char **envp);

其中 argc表示参数个数,argv表示参数字符串,而这个envp就表示环境变量字符串。参数和环境变量都可以不止一个,所以,用指向字符串指针的指针来表示。
比如我们用C语言写了一个程序,运行在命令行下,带有2个参数

C:> cpfile.exe c:\test.txt d:\test.txt
argc=3;
argv[0] = "cpfile.exe";
argv[1] = "c:\test.txt";
argv[2] = "d:\test.txt";

在c语言中的stdlib.h中有一个extern char **environ; 或者extern char **_environ;的声明这个envp的参数实际上就是environ。

好,我们看看在cgi程序(其实就是一个C语言程序)里面怎么枚举这些环境变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_CONTENT_LEN        1024

int main()
{
    extern char   **environ;
    int nlen = 0;
    int i;
    char szContent[MAX_CONTENT_LEN];
    char **penv;
    char *req = NULL;

    memset(szContent, 0, MAX_CONTENT_LEN);
        
    printf("Content-type: text/html\n\n");
    
    for ( penv = environ; *penv; penv++ )
        printf("%s<br>", *penv);
    return 0;
}

输出结果如下:

SERVER_SOFTWARE=lighttpd/1.4.28
SERVER_NAME=127.0.0.1
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.1
SERVER_PORT=3000
SERVER_ADDR=0.0.0.0
REQUEST_METHOD=GET
REDIRECT_STATUS=200
REQUEST_URI=/cgi/testEnv.cgi
REMOTE_ADDR=127.0.0.1
REMOTE_PORT=52218
CONTENT_LENGTH=0
SCRIPT_FILENAME=/home/gss/workspace_c/web/cgi/testEnv.cgi
SCRIPT_NAME=/cgi/testEnv.cgi
DOCUMENT_ROOT=/home/gss/workspace_c/web/
HTTP_HOST=127.0.0.1:3000
HTTP_CONNECTION=keep-alive
HTTP_CACHE_CONTROL=max-age=0
HTTP_USER_AGENT=Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4
HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_ENCODING=gzip,deflate,sdch
HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.8
HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q=0.7,*;q=0.3

上面输出分别对应下面三种类型

与服务器自身相关的环境的变量

GATEWAY_INTERFACE 服务器遵守的CGI版本
SERVER_NAME 服务器的IP或名字
SERVER_PORT 主机的端口号
SERVER_SOFTWARE 服务器软件的名字

SERVER_NAME:127.0.0.1
SERVER_PORT:3000
GATEWAY_INTERFACE:CGI/1.1
SERVER_SOFTWARE:lighttpd/1.4.28

与客户端相关的环境的变量

服务器了解你的CGI程序,但它一定不知道你的客户机环境。正因为如此,同客户机有关的变量才是最重要的。因为它涉及到你的浏览器等等。

HTTP_ACCEPT 例出能被次请求接受的应答方式
HTTP_ACCEPT_ENCODING 列出客户机支持的编码方式
HTTP_ACCEPT_LANGUAGE 表明客户机可接受语言的ISO代码
HTTP_USER_AGENT 标明客户使用的软件

HTTP_ACCEPT:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_ENCODING:gzip,deflate,sdch
HTTP_ACCEPT_LANGUAGE:en-US,en;q=0.8
HTTP_USER_AGENT:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4

请求相关的环境的变量

       每次服务器受到的请求都不可能是一样的。这意味着有许多CGI程序必须注意的信息。这些与请求相关的信息包含有用户调用的信息,用户如何发送请求,以及作为请求的一部分传送了多少(什么)信息。这些对你的程序来说是非常重要的,因此我们将化些时间详细地讨论一下其中的一些变量。特别是下面写出的三个变量。这三个变量相当重要。

  • REQUEST_METHOD
  • QUERY_STRING
  • CONTENT_LENGTH
     你必须熟悉这三个变量,因为它们用来表示数据是如何送到CGI程序的;然后你所要要做的事情就是在这三个变量里取出数据,进行下一步的编程。其他的一些变量的用处很多,你可以了解你的竞争对手正在调用你的程序,你可以辨别用户是否注册,或者你可以设置连接到你的CGI程序以便要求附加路径信息包含在请求之中----因此你不必猜测你的用户正在你的服务器的哪个页面上。
CONTENT_LENGTH POST请求中向标准输入(STDIN)发送的字节数
QUERY_STRING 传送给CGI程序的URL的问号(?)之后的那一部分
REMOTE_ADDR 最终用户的IP或主机名
REMOTE_USER 如果用户合法,则是用户的组名
REQUEST_METHOD 作为HTTP的一部分请求而传送数据的方法,比如get。
SCRPT_NAME 运行的脚本名字
REQUEST_METHOD=GET
REDIRECT_STATUS=200
REQUEST_URI=/cgi/testEnv.cgi
REMOTE_ADDR=127.0.0.1
REMOTE_PORT=52218
CONTENT_LENGTH=0
SCRIPT_FILENAME=/home/gss/workspace_c/web/cgi/testEnv.cgi
SCRIPT_NAME=/cgi/testEnv.cgi

上面的参数都可以通过getenv函数进行获取

data = getenv("QUERY_STRING"); 



你可能感兴趣的:(web开发,server,服务器,cgi,Path,服务器软件)