`
wangyihust
  • 浏览: 436628 次
文章分类
社区版块
存档分类
最新评论

CGI(Common Gateway Interface)技术

阅读更多

一.提出
  CGI是外部扩展应用程序与WWW服务器交互的一个标准接口。按照CGI标准编写的外部扩展应用程序可以处理客户端(一般是WWW浏览器)输入的协同工作数据,完成 客户端与服务器的交互操作。这在实际应用中非常有用,如可以编写CGI外部扩展 程序来访问外部数据库,客户端用户可以通过它和WWW服务器来进行数据查询。CGI 一般分两种:标准CGI和缓冲CGI。所有的WWW服务器均应支持标准CGI,按标准CGI 编写的程序与具体的WWW服务器无关。而按缓冲CGI编写的程序与WWW服务器有关。

什么是CGI
1. 定义:
CGI(Common Gateway Interface)是HTTP服务器与你的或其它机器
上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。

2. 功能:
绝大多数的CGI程序被用来解释处理杰自表单的输入信息,并在服
务器产生相应的处理,或将相应的信息反馈给浏览器。CGI程序使
网页具有交互功能。

3. 运行环境:
CGI程序在UNIX操作系统上CERN或NCSA格式的服务器上运行。
在其它操作系统(如:windows NT及windows95等)的服务器上
也广泛地使用CGI程序,同时它也适用于各种类型机器。

4. CGI处理步骤:
⑴通过Internet把用户请求送到服务器。
⑵服务器接收用户请求并交给CGI程序处理。
⑶CGI程序把处理结果传送给服务器。
⑷服务器把结果送回到用户。

5. CGI服务器配置:
CGI程序不是放在服务器上就能顺利运行,如果要想使其在服务器
上顺利的运行并准确的处理用户的请求,则须对所使用的服务器进
行必要的设置。
配置:根据所使用的服务器类型以及它的设置把CGI程序放在某一
特定的目录中或使其带有特定的扩展名。
⑴CREN格式服务器的配置:
编辑CREN格式服务器的配置文件通常为/etc/httpd.conf/
在文件中加入:Exec cgi-bin/*/home/www/cgi-bin/*.exec
命令中出现的第一个参数cgi-bin/*指出了在URL中出现的目录
名字,并表示它出
现在系统主机后的第一个目录中,如:
http://edgar.stern.nyn.edu/cgi-bin/
命令中的第二个参数表示CGI程序目录放在系统中的真实路径。
CGI目录除了可以点网络文件放在同一目录中,也可以放在系统
的其它目录中,但必须保证在你的系统中也具有同样的目录。在
对服务器完成设置后,须重新启动服务器(除非HTTP服务器是用
inetd启动的)。
⑵NCSA格式服务器的配置
在NCSA格式服务器上有两种方法进行设置:
①在srm.conf文件(通常在conf目录下)中加入:
Script Alias/cgi-bin/cgi-bin/
Script Alias命令指出某一目录下的文件是可执行程序,且这
个命令是用来执行
这些程序的;此命令的两个参数与CERN格式服务器中的Exec命
令的参数的含意一样。
②在srm.conf文件加入:
Add type application/x-httpd-cgi.cgi
此命令表示在服务器上增加了一种新的文件类型,其后第一个
参数为CGI程序的MIME类型,第二个参数是文件的扩展名,表
示以这一扩展名为扩展名的文件是CGI程序。
在用上述方法之一设置服务器后,都得重新启动服务器(除非
HTTP服务器是用inetd启动的)。

6. CGI的编写语言
CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和
环境变量。对初学者来说,最好选用易于归档和能有效表示大量数据
结构的语言,例如
UNIX环境中:
· Perl (Practical Extraction and Reporting Language)
· Bourne Shed或者Tcl (Tool Command Language)
Windows环境中:
· C和C++
由于Internet上大部分服务器使用的是UNIX操作系统,且几乎任
一UNIX操作系统中都有Bourne Shell,因而后面讲述的例子中大部
分是用Bourne Shell编写的。

7. CGI环境变量列表
用 好易环境变量探针 来查看CGI环境变量
SERVER-NAME:运行CGI序为机器名或IP地址。
SEUVER-INTERFACE:WWW服务器的类型,如:CERN型或NCSA型。
SERVER-PROTOCOL:通信协议,应当是HTTP/1.0。
SERVER-PORT:TCP端口,一般说来web端口是80。
HTTP-ACCEPT:HTTP定义的浏览器能够接受的数据类型。
HTTP-REFERER: 发送表单的文件URL。
(并非所有的浏览器都传送这一变量)
HTTP-USER-AGENT:发送表单的浏览器的有关信息。
GETWAY-INTERFACE:CGI程序的版本,在UNIX下为 CGI/1.1。
PATH-TRANSLATED: PATH-INFO中包含的实际路径名。
PATH-INFO:浏览器用GET方式发送数据时的附加路径。
SCRIPT-NAME: CGI程序的路径名。
QUERY-STRING:表单输入的数据,URL中间号后的内容。
REMOTE-NOST:发送程序的主机名,不能确定该值。
REMOTE-ADDR:发送程序的机器的IP地址。
REMOTE-USBR:发送程序的人名。
CONTENT-TYPE:POST发送,一般为applioation/xwww-form-urlencoded。
CONTENT-LENGTH:POST方法输入的数据的字节数。

二 ASP、CGI、ISAPI、ODBC之间的差别

ASP赋予你在标准的HTML文档中嵌入脚本的能力。使用这些脚本可执行应用程序逻辑和调用执行特定任务的软件组件,如数据库查询、文件输入/输出(I/O)、交易规则和工作流程。ASP将INTERNET数据库连接器(IDC)的简单性与ISAPI的灵活性结合在一起,而且由于支持JAVA虚拟主机,因此可以用多种编程语言编写ASP应用组件。

CGI是最常用的WEB服务器扩展。CGI可以使你能够运行在不属于WEB服务器的应用程序。许多CGI应用程序是用脚本语言编写的。由于这种语言的可移植性,因此这些语言是扩展WEB服务器性能的流行方法。经过CGI具有灵活性和可移植性,但是由于CGI必须对每个CGI请求重新启动一个新的进程,所以,PERL应用程序对大流量的WEB站点不是最佳解决方案。在CGI完成对该请求的服务后,将取消该进程以及与它相关的任何信息。现在国内外的虚拟主机服务商,在NT SERVER下已经不提供支持PERL的服务。

ISAPI是由MS创建的作为CGI补充的INTERNET服务器应用程序编程接口,是一组常规可扩展例程,用于调用外部应用程序并处理浏览器和服务器之间的数据流。
ISAPI是一个开放式规范,WINDOWNS NT和其他操作系统上的第三方WEB服务器支持该规范。通过将ISAPI与IIS和NT SERVER结合,可以创建一个高性能、低成本并且可扩展的超文本传输协议(HTTP)平台。ISAPI开发以ISAPI应用程序的形式出现,用于克服CGI性能不足的问题。ISAPI的过滤器可以对传入和传出IIS的信息进行预处理和后处理。虽然ISAPI比CGI更快更灵活,但是程序员必须十分熟悉MS VC++开发系统才行。

ODBC IDC是IIS中的另一个可扩展的选项。IDC是一个ISAPI应用程序,它使你可以把WEB页面与支持ODBC的任何后端数据库结合。IDC使用简单的脚本语言创建数据库连接这个事实使IDC成为特别受欢迎的服务器扩展。了解结构化查询语言(SQL)可以帮助你创建IDC应用程序。

三.在CGI中实现session的想法和实现

对于客户端的每一次登陆,在服务器生成一个session,作为一个文件存储在服务器上,例如在“/tmp”下。
文件命名为sess_开头,在加上一个随机的字符串,这个字符串称之为session_id。
   在文件中存储的内容包括:
   1、用户的最后一次活动时间。(用来检查用户是否长时间没有操作,视为已经退出登陆)。
   2、一个随机的字符串。(用来验证客户端的身份,这个字符串同时作为cookie发往客户端)。
   3、客户端的IP.
   4、实际要存储的数据。例如用户的ID,密码等。

   在用户登陆时,生成这个文件,并且,将那个随机字符串发到客户端的cookie.  
   在以后的每个页面的超连接,或是FORM中的要跟入session_id.
   每个页面开始,要:
   1、检查是否超时。
   2、对比cookie中的字符串和session文件中的,验证客户身份。
   3、对比客户端IP和session文件中的IP,验证客户身份。
   4、读出数据,供下面程序使用

   5、刷新最后活动时间
   6、生成新的随机字符串,刷新session中对应部分,并将其作为cookie发往客户端。

   下面是我的部分实现代码:
  
   set_session()在登陆是调用。
   start_session()在每个页面的前面调用。
   kill_session()在退出登陆是调用。
   clean_session() 用来删除过期的session文件。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>

#define REMOTE_ADDR1 getenv("REMOTE_ADDR")
#define HTTP_COOKIE getenv("HTTP_COOKIE")

char *sess_user_name;
char *sess_user_pwd;

static void print_session_error(char *);
static void clean_session_file();

char *set_session(char *name,char *pwd)
{
  char str_now[11];
  char hash_key[17];
  char *session_id;
  time_t now;

  FILE *sf;
  char sfp[32];

  int i,temp,r;

  time(&now);
/**
  *  clean time out session file
  */
  clean_session_file();
 
/**
  * get str_now
  */
  sprintf(str_now,"%10d",now);

/**
  * get random hash_key
  */
  srand(now); 
  r = rand();
  for(i=0;i<16;i++)
  {
    srand(r);
    r = rand();
    hash_key[i] = r%26 + 'a';
  }
  hash_key[16] = '\0';
 
/**
  * get more random session_id;
  */
  temp = rand();
  srand(temp);
  r = rand();
  session_id = (char*) malloc(17*sizeof(char));
  for(i=0;i<16; i++)
  {
    srand(r);
    r = rand();
    session_id[i] = r%26 + 'A';
  }
  session_id[16] = '\0';
/**
  * create session file
  */
  strcpy(sfp,"/tmp");
  strcat(sfp,"/sess_");
  strcat(sfp,session_id);

  sf = fopen(sfp,"w");
  chmod(sfp,06777);

  if( sf == NULL )
  {
     tc_error_page("can't creat session file");
  }

/**
  * fputs session file
  */
  fputs(str_now,sf);
  fputs("\n",sf);
  fputs(hash_key,sf);
  fputs("\n",sf);
  fputs(REMOTE_ADDR1,sf);
  fputs("\n",sf);
  fputs(name,sf);    //sess_user_name
  fputs("\n",sf);
  fputs(pwd,sf);     // sess_user_pwd_
  fputs("\n",sf);   
  fclose(sf);

/**
  *  set cookie
  */
  printf("Set-Cookie:hash_key=%s\n",hash_key);
 
  return session_id;
}

void start_session()
{
   int i,j,k;

   char *session_id;
   FILE *sf;
   char sfp[32];
   time_t now;
   int    r;

   char buffer[256];
   char temp[64];
   char str_time[16];
   char str_hash_key[20];
   char str_client_ip[20];
   char *str_array[6];
   sess_user_name = (char*)malloc(32*sizeof(char));
   sess_user_pwd  = (char*)malloc(32*sizeof(char));


   str_array[0] = str_time;
   str_array[1] = str_hash_key;
   str_array[2] = str_client_ip;
   str_array[3] = sess_user_name;
   str_array[4] = sess_user_pwd;


   session_id = cgi_val(entries,"session_id");
/**
  * open session file
  */
   strcpy(sfp,"/tmp");
   strcat(sfp,"/sess_");
   strcat(sfp,session_id);
   sf = fopen(sfp,"rb+");
   if(  sf == NULL )
            /** can't open session file,maybe session has time out **/
   {
       print_session_error("1");
       exit(1);
   }
/**
  * read session var
  */
  bzero(buffer,256);
  fread(buffer,1,256,sf);
  for(i=0,j=0,k=0;k<5 && i<strlen(buffer);i++)
  {
     if( buffer[i] == '\n'  )
     {
        temp[j] = '\0';
        strcpy(str_array[k],temp);
        j = 0;
        k ++;
     }
     else
     {
       temp[j++] = buffer[i];
     }
  }
/**
  * check active time
  */
  time(&now);
  if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )
  {
     print_session_error("2");
     exit(1);
  }

/**
  * compare client hash_key to session hash_key
  */
  if( HTTP_COOKIE == "" || strcmp( HTTP_COOKIE+9 , str_hash_key ) != 0 )
  {
     print_session_error("3");
     exit(1);
  }

/**
  * compare client ip to session ip
  */
  if( strcmp( REMOTE_ADDR, str_client_ip ) != 0 )
  {
     print_session_error("4");
     exit(1);
  }

/** 
  * refresh session active time
  */
  time(&now);
  sprintf(str_time,"%10d\n",now);
  fseek(sf,0,SEEK_SET);
  fputs(str_time,sf); 

/**
  * get new hash_key
  */
  srand(now);
  r = rand();
  for(i=0;i<16;i++)
  {
     srand(r);
     r = rand();
     str_hash_key[i] = r % 26 + 'a';
  }
  str_hash_key[16] = '\n';
  str_hash_key[17] = '\0';
 

/**
  * refresh session hash_key
  */
  fseek(sf,11,SEEK_SET);
  fputs(str_hash_key,sf);

  fclose(sf);

/** 
  * send cookie refresh client hash_key
  */
  printf("Set-Cookie:hash_key=%s",str_hash_key); 
}

void kill_session()
{
  char *session_id;
  char *session_path;
  char sfp[128];

  session_id   = cgi_val(entries,"session_id");

  strcpy(sfp,"/tmp");
  strcat(sfp,"/sess_");
  strcat(sfp,session_id);

  remove(sfp);
}

void clean_session_file()
{
  DIR *pdir;
  struct dirent *ent;
  char *path;
  char *filename;
  char filepath[64];
  int fd;
  char str_time[11];
  time_t  now;

  path = "/tmp";
  pdir = opendir(path);
  if(pdir != NULL)
  {
    while( ent =readdir(pdir) )
    {
       filename = ent->d_name;
       if( strncmp(filename,"sess_",5)==0 )
       {
          strcpy(filepath,path);
          strcat(filepath,"/");
          strcat(filepath,filename);

          fd = open(filepath,O_RDONLY);
          read(fd,str_time,10);
          time(&now);
          if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )
          {
            remove(filepath);
          }
          close(fd);
       }
    }
  }
  closedir(pdir);
}

void print_session_error(char *n)
{
   printf("Content-type:text/html\n\n");
   printf("<html><head>";
   print_title("请重新登陆!");
   printf("</head>\n");

   printf("<body>\n");
   printf("对不起,请重新登陆。<p>\n");
   printf("你长时间没有操作,登陆已经超时。或者是系统发生了错误。<p>\n");
   printf("如果是后者,请与管理人员联系。\n");
   printf("<!--%s-->",n);
   printf("</body>");
   printf("</html>\n");
}



分享到:
评论

相关推荐

    CGI入门 Common Gateway Interface

    ### CGI入门:Common Gateway Interface详解 #### CGI概念与工作原理 **Common Gateway Interface(CGI)**是一种标准接口,用于让Web服务器与外部程序(即CGI脚本)进行通信,以便处理用户提交的表单数据或其他...

    The Common Gateway Interface (CGI) Version 1.1.pdf

    CGI(Common Gateway Interface)是一种标准的协议,它定义了Web服务器与执行在服务器上的程序(比如Perl脚本、C/C++程序等)之间交互的方法。CGI规范允许用户输入数据,然后由服务器上的程序处理这些数据,并将结果...

    cgic 原代码,CGI(Common Gateway Interface)是一种用于在Web服务器和应用程序之间传输数据的标准

    CGI程序运行在Web服务器的特定目录下(通常是cgi-bin目录),当Web服务器接收到来自客户端的CGI请求时,会调用相应的CGI程序来处理请求,并将结果返回给客户端。 CGI程序的基本工作流程如下: Web服务器接收到...

    cgi.rar_cgi_cgi common gate_cgi html

    CGI(Common Gateway Interface)是Web服务器与外部应用程序之间交互的一种标准协议,它允许Web服务器动态生成内容,而不仅仅是静态HTML页面。CGI为开发者提供了一种方式,使得Web服务器可以调用外部程序来处理用户...

    Camera_CGI_Interface_v3.51.zip_cgi_interface

    在现代网络应用中,CGI(Common Gateway Interface)是一种通用的接口技术,它允许Web服务器与各种脚本语言交互,如Perl,来处理客户端的请求。在"Camera_CGI_Interface_v3.51.zip"这个压缩包中,我们主要关注的是一...

    CGI.rar_cgi_cgi pdf_gateway

    C G I又称通用网关接口(Common Gateway Interface),是外部程序和We b服务器之间的标 准编程接口, P H P隐藏了其中的大部分复杂性,但是,了解一些它的基本内容对设计应用程 序和进行调试都有很大帮助。

    CGI-Perl实例起步

    CGI(Common Gateway Interface,通用网关接口)是一种标准,允许Web服务器与各种脚本语言交互,以便动态生成网页内容。Perl是其中一种常见的CGI脚本语言,因其强大的文本处理能力和灵活性而受到青睐。本篇文章将...

    Linux开发基础-c-c -CGI.ppt

    CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI 程序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,也就是CGI程序接受Web浏览器发送给Web服务器的信息,进行...

    CGI技术全面接触,不错!

    CGI(Common Gateway Interface,通用网关接口)是一种在Web服务器和动态生成内容的程序之间进行交互的标准协议。它的出现使得网页可以展示实时更新、动态生成的信息,而非仅仅局限于静态HTML页面。CGI技术的全面...

    CGI技术全面接触(PDG)

    CGI(Common Gateway Interface,通用网关接口)是一种标准,允许Web服务器与外部应用程序交互,以动态生成网页内容。在互联网发展的初期,CGI扮演了关键角色,为静态HTML页面提供了动态内容的能力。CGI技术的全面...

    CGI编程学习简介对初学者了解CGI概念有用

    #### 一、CGI(Common Gateway Interface)概述 CGI,全称为Common Gateway Interface,即通用网关接口,是一种标准协议,用于在Web服务器与外部应用程序之间传递数据。通过CGI,Web服务器可以调用外部程序处理HTTP...

    动态网页技术的发展

    (1)cgi(common gateway interface) 特点: a:cgi技术是早期动态技术使用最多,发展比较成熟并且功能强大 b:效率比较低,编程比较困难 c:cgi可以用不同的语言编写(vb,delphi,c/c++,perl)常用的c/c++和...

    嵌入式ARM-Linux环境下CGI的实现.pdf

    该资源是关于在嵌入式ARM-Linux环境下实现CGI(Common Gateway Interface)的技术论文。CGI是一种外部应用与信息服务器之间的标准接口,它允许Web服务器和客户端之间进行交互式通信。在嵌入式系统中,CGI的实现可以...

    CGI编程指南

    CGI(Common Gateway Interface)HTTP服务器与或其机器 上程序进行交谈种工具其程序须运行网络服务器上.

    CGI 开发使用手册 CGI编程

    CGI(Common Gateway Interface,通用网关接口)是Web服务器与外部应用程序进行交互的一种标准协议。这个手册将深入探讨CGI编程,帮助开发者理解和利用CGI来创建动态、交互式的Web页面。 一、CGI的基本概念 CGI是...

    ASP技术详解

    ASP(Active Server Pages)动态网页,是微软公司推出的一种用以取代CGI(Common Gateway Interface)通用网关接口的技术。我们可以通过ASP结合HTML语言、ASP指令和ActiveX组件以及数据库等方面知识,使用自己的 Web ...

    网络渗透--《CGI渗透测试技术》

    CGI(Common Gateway Interface,通用网关接口)是一种在Web服务器上运行外部程序并交互数据的标准方法。在网络安全领域,CGI渗透测试是评估Web应用程序安全性的重要部分,因为它可能导致严重的漏洞,如命令注入、...

    让 Nginx 支持 cgi

    **Nginx 支持 CGI (Common Gateway Interface)** CGI(Common Gateway Interface)是一种标准,允许Web服务器执行外部程序并返回结果给浏览器。在Nginx中支持CGI,可以使我们运行各种脚本语言(如Perl、Python、PHP...

Global site tag (gtag.js) - Google Analytics