zoukankan      html  css  js  c++  java
  • 用 c 写 CGI 程序简要指南

    文章摘要
      CGI规定了Web服务器调用其他可执行程序(CGI程 序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互。CGI程序可以用任何程序设计语言编写,如Shell脚本语言、Perl、Fortran、Pascal、C语言等。但是用C语言编写的CGI程序具有执行速度快、安全性高等特点。本文详细分析了用C语言进行CGI程序设计的方法、过程和技巧。 

    正文: 用C语言进行CGI程序设计   

    一、CGI概述 

      CGI(Common Gateway Interface: 公用网关接口)规定了Web服务器调用其他可执行程序(CGI程 序)的接口协议标准。Web服务器通过调用CGI程序实现和Web浏览器的交互,也就是CGI程序接受Web浏览器发送给Web服务器的信息,进行处理,将响应结果再回送给Web服务器及Web浏览器。CGI程序一般完成Web网页中表单(Form)数据的处理、数据库查询和实现与传统应用系统的集成等工作。CGI程序可以用任何程序设计语言编写,如Shell脚本语言、Perl、Fortran、Pascal、C语言等。但是用C语言编写的CGI程序具有执行速度快、安全性高(因为C语言程序是编译执行且不可被修改)等特点。 

      CGI接口标准包括标准输入、环境变量、标准输出三部分。 
      1.标准输入 
      CGI程序像其他可执行程序一样,可通过标准输入(stdin)从Web服务器得到输入信息,如Form中的数据,这就是所谓的向CGI程序传递数据的POST方法。这意味着在操作系统命令行状态可执行CGI程序,对CGI程序进行调试。POST方法是常用的方法,本文将以此方法为例,分析CGI程序设计的方法、过程和技巧。 

      2.环境变量 
    操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了自己的一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过 环境变量QUERY-STRING向CGI程序传递Form中的数据。 

      3.标准输出 
      CGI程序通过标准输出(stdout)将输出信息传送给Web服务器。传送给Web服务器的信息可以用各种格式,通常是以纯文本或者HTML文本的形式,这样我们就可以在命令行状态调试CGI程序,并且得到它们的输出。 

      下面是一个简单的CGI程序,它将HTML中Form的信息直接输出到We b浏览器。 

      # include 
      # include 
      main() 
      { 
      int i , n ; 
      printf (″Content type: text/plain ″); 
      n=0; 
      if(getenv(″CONTENT-LENGTH″)) 
      n=atoi(getenv(CONTENT-LENGTH″)); 
      for (i=0;i<n;i++) <br="">  putchar(getchar()); 
      putchar (′ ′); 
      fflush(stdout); 
      }



      下面对此程序作一下简要的分析。 

      prinft (″Content type :text/plain ″);


      此行通过标准输出将字符串″Content type :text/plain ″传送给Web服务器。它是一个MIME头信息,它告诉Web服务器随后的输出是以纯ASCII文本的形式。请注意在这个头信息中有两个新行符,这是因为Web服务器需要在实际的文本信息开始之前先看见一个空行。 

      if (getenv(″CONTENT-LENGTH″)) 
      n=atoi (getenv(″CONTENT-LENGTH″));


      此行首先检查环境变量CONTENT-LENGTH是否存在。Web服务器在调用使用POST方法的CGI程序时设置此环境变量,它的文本值表示Web服务器传送给CGI程序的输入中的字符数目,因此我们使用函数atoi() 将此环境变量的值转换成整数,并赋给变量n。请注意Web服务器并不以文件结束符来终止它的输出,所以如果不检查环境变量CONTENT-LENGTH,CGI程序就无法知道什么时候输入结束了。 

      for (i=0;i<n;i++) <br="">  putchar(getchar());


      此行从0循环到(CONTENT-LENGTH-1)次将标准输入中读到的每一个字符直接拷贝到标准输出,也就是将所有的输入以ASCII的形式回送给Web服务器。 
      通过此例,我们可将CGI程序的一般工作过程总结为如下几点。 
      1.通过检查环境变量CONTENT-LENGTH,确定有多少输入; 
      2.循环使用getchar()或者其他文件读函数得到所有的输入; 
      3.以相应的方法处理输入; 
      4.通过″Contenttype:″头信息,将输出信息的格式告诉Web服务器; 
      5.通过使用printf()或者putchar()或者其他的文件写函数,将输出传送给Web服务器。 
      总之,CGI程序的主要任务就是从Web服务器得到输入信息,进行处理,然后将输出结果再送回给Web服务器。 


    二、环境变量 

      环境变量是文本串(名字/值对),可以被OS Shell或其他程序设置 ,也可以被其他程序访问。它们是Web服务器传递数据给CGI程序的简单手段,之所以称为环境变量是因为它们是全局变量,任何程序都可以存取它们。 

      下面是CGI程序设计中常常要用到的一些环境变量。 
      HTTP-REFERER:调用该CGI程序的网页的URL。 
      REMOTE-HOST:调用该CGI程序的Web浏览器的机器名和域名。 
      REQUEST-METHOD:指的是当Web服务器传递数据给CGI程序时所采用的方法,分为GET和POST两种方法。GET方法仅通过环境变量(如QUERY-STRING)传递数据给CGI程序,而POST方法通过环境变量和标准输入传递数据给CGI程序,因此POST方法可较方便地传递较多的数据给CGI程序。 

      SCRIPT-NAME:该CGI程序的名称。 
      QUERY-STRING:当使用POST方法时,Form中的数据最后放在QUERY-STRING中,传递给CGI程序。 
      CONTENT-TYPE:传递给CGI程序数据的MIME类型,通常为″applica tion/x-www-form-url encodede″,它是从HTML Form中以POST方法传递数据给CGI程序的数据编码类型,称为URL编码类型。 
      CONTENT-LENGTH:传递给CGI程序的数据字符数(字节数)。 
      在C语言程序中,要访向环境变量,可使用getenv()库函数。例如: 

      if (getenv (″CONTENT-LENGTH″)) 
       n=atoi(getenv (″CONTENT-LENGTH″));


      请注意程序中最好调用两次getenv():第一次检查是否存在该环境变量,第二次再使用该环境变量。这是因为函数getenv()在给定的环境变量名不存在时,返回一个NULL(空)指针,如果你不首先检查而直接引用它,当该环境变量不存在时会引起CGI程序崩溃。 

     


    三、From输入的分析和解码 

      1.分析名字/值对 
      当用户提交一个HTML Form时,Web浏览器首先对Form中的数据以名字/值对的形式进行编码,并发送给Web服务器,然后由Web服务器传递给CGI程序。其格式如下: 
      name1=value1&name2=value2&name3=value3&name4=value4&... 
      其中名字是Form中定义的INPUT、SELECT或TEXTAREA等标置(Tag)名字,值是用户输入或选择的标置值。这种格式即为URL编码,程序中需要对其进行分析和解码。要分析这种数据流,CGI程序必须首先将数据流分解成一组组的名字/值对。这可以通过在输入流中查找下面的两个字符来完成。 
      每当找到字符=,标志着一个Form变量名字的结束;每当找到字符& ,标志着一个Form变量值的结束。请注意输入数据的最后一个变量的值不以&结束。 
      一旦名字/值对分解后,还必须将输入中的一些特殊字符转换成相应的ASCII字符。这些特殊字符是: 
      +:将+转换成空格符; 
      %xx:用其十六进制ASCII码值表示的特殊字符。根据值xx将其转换成相应的ASCII字符。 
      对Form变量名和变量值都要进行这种转换。下面是一个对Form数据进行分析并将结果回送给Web服务器的CGI程序。 

      #include 
      #include 
      #include 
      int htoi(char *); 
      main() 
      { 
       int i,n; 
      char c; 
      printf (″Contenttype: text/plain ″); 
      n=0; 
      if (getenv(″CONTENT-LENGTH″)) 
       n=atoi(getenv(″CONTENT-LENGTH″)); 
      for (i=0; i<n;i++){ <br="">   int is-eq=0; 
      c=getchar(); 
      switch (c){ 
       case ′&′: 
        c=′ ′; 
        break; 
       case ′+′: 
        c=′ ′; 
        break; 
       case ′%′:{ 
        char s[3]; 
        s[0]=getchar(); 
        s[1]=getchar(); 
        s[2]=0; 
        c=htoi(s); 
        i+=2; 
       } 
       break; 
      case ′=′: 
       c=′:′; 
       is-eq=1; 
       break; 
      }; 
      putchar(c); 
      if (is-eq) putchar(′ ′); 
      } 
      putchar (′ ′); 
      fflush(stdout); 
      } 
      /* convert hex string to int */ 
      int htoi(char *s) 
      { 
       char *digits=″0123456789ABCDEF″; 
      if (islower (s[0])) s[0]=toupper(s[0]); 
      if (islower (s[1])) s[1]=toupper(s[1]); 
      return 16 * (strchr(digits, s[0]) -strchr (digits,′0′) 

      +(strchr(digits,s[1])-strchr(digits,′0′)); 
      }


      上面的程序首先输出一个MIME头信息给Web服务器,检查输入中的字符数,并循环检查每一个字符。当发现字符为&时,意味着一个名字/值对的结束,程序输出一个空行;当发现字符为+时,将它转换成空格; 当发现字符为%时,意味着一个两字符的十六进制值的开始,调用htoi()函数将随后的两个字符转换为相应的ASCII字符;当发现字符为=时,意味着一个名字/值对的名字部分的结束,并将它转换成字符:。最后将转换后的字符输出给Web服务器。 


    四、产生HTML输出 

      CGI程序产生的输出由两部分组成:MIME头信息和实际的信息。两部分之间以一个空行分开。我们已经看到怎样使用MIME头信息″Content type :text/plain ″和printf()、put char()等函数调用来输 出纯ASCII文本给Web服务器。实际上,我们也可以使用MIME头信息″Content type :text/html ″来输出HTML源代码给Web服务器。请注意任何MIME头信息后必须有一个空行。一旦发送这个MIME头信息给We b服务器后,Web浏览器将认为随后的文本输出为HTML源代码,在HTML源代码中可以使用任何HTML结构,如超链、图像、Form,及对其他CGI程 序的调用。也就是说,我们可以在CGI程序中动态产生HTML源代码输出 ,下面是一个简单的例子。 

      #include 
      #include 
      main() 
      { 
       printf(″Contenttype:text/html ″); 
      printf(″<html> ″); 

      printf(″<head><title>An HTML Page From a CGI</title></head> ″); 

      printf(″<body><br> ″); 

      printf(″<h2> This is an HTML page generated from with i n a CGI program.. .</h2> ″); 

      printf(″<hr><p> ″); 

      printf(″<a href="../output.html#two"><b> Go back to output.html page </b></a> ″); 

      printf(″</body> ″); 

      printf(″</html> ″); 

      fflush(stdout); 

      }


      上面的CGI程序简单地用printf()函数来产生HTML源代码。请注意在输出的字符串中如果有双引号,在其前面必须有一个后斜字符\, 这是因为整个HTML代码串已经在双引号内,所以HTML代码串中的双引号符必须用一个后斜字符来转义。 

    五、结束语 

      本文详细分析了用C语言进行CGI程序设计的方法、过程和技巧。C语言的CGI程序虽然执行速度快、可靠性高,但是相对于Perl语言来说,C语言缺乏强有力的字符串处理能力,因此在实际应用中,应根据需 要和个人爱好来选择合适的CGI程序设计语言。

    出处:http://pcedu.pconline.com.cn/empolder/gj/c/0506/650480_all.html#content_page_1

  • 相关阅读:
    This counter can increment, decrement or skip ahead by an arbitrary amount
    LUT4/MUXF5/MUXF6 logic : Multiplexer 8:1
    synthesisable VHDL for a fixed ratio frequency divider
    Bucket Brigade FIFO SRL16E ( VHDL )
    srl16e fifo verilog
    DualPort Block RAM with Two Write Ports and Bytewide Write Enable in ReadFirst Mode
    Parametrilayze based on SRL16 shift register FIFO
    stm32 spi sdcard fatfs
    SPI bus master for System09 (2)
    SQLSERVER中的自旋锁
  • 原文地址:https://www.cnblogs.com/mq0036/p/3427108.html
Copyright © 2011-2022 走看看