• 用C/C++写CGI程序


     
     
     
     
    使用CGIC库的简要:
    库的函数说明: http://www.boutell.com/cgic/#cgiFormStringNoNewlines
    1. 打印CGI标准输出头部:
    cgiHeaderContentType("text/plain");
    或者:
    fprintf( stdout, "Content-type:text/plain\n\n");红色部分不能写出“Contenttype”,否则浏览器显示网页会不正常。
    2. 处理Request Method:
    //deal with "GET"/"POST" method
        if (strncmp(cgiRequestMethod, "post",4) == 0)
        {
            handlePostRequest();
        }
        else //"GET"
        {
            handleGetRequest();
        }
    3. 获取QueryString中的各个字段值:
        cgiFormStringNoNewlines("query1", cmdstr, sizeof(cmdstr));
        if (strcmp(cmdStr, "ip_address") == 0)
        {
            ...
        }
        else
         ...
    4. CGI输出:
    fprintf(cgiOut, "%s\n", cgi_Output);
    以下是一些细节:
    一、 C/C++编写CGI程序之form处理
    1. GET
    2. POST
    3. 结束
    我们有一张web
    test.html
    form test
    1. GET
    首先我们来获取GET方式的form
    在环境变量QUERY_STRING里面,存储着GET提交的字符串
    cgi-get.c
    #include 
    #include 
    int main( void )
    {
            fprintf( stdout, "Content-type:text/html\n\n");
            fprintf( stdout, "get\n");
            if( getenv("QUERY_STRING" ) )
            {
                    fprintf( stdout, getenv("QUERY_STRING" ) );
            }
            else
            {
                    fprintf( stdout, "(NULL)\n" );
            }
            fprintf( stdout, "\n" );
            return 0;
    };
    编译后,复制到cgi-bin目录下,名为test-get.cgi,确保apache用户拥有执行权限
    然后登陆test.html,填写dorainm和linux测试get提交方式,获得
    name=dorainm&pswd=linux
    2. POST
    POST是通过标准输入来获取form提交的字符串的
    环境变量CONTENT_LENGTH里面,存储着POST提交的字符串的长度
    看 test-post.c 的源码
    #include 
    #include 
    int main( void )
    {
            int i, n;
            fprintf( stdout, "Content-type:text/html\n\n" );
            fprintf( stdout, "post" );
            if( getenv("CONTENT_LENGTH") )
            {
                    n = atoi( getenv("CONTENT_LENGTH") );
            }
            else
            {
                    n = 0;
            fprintf( stdout, "(NULL)" );
            }
            for( i=0; i\n" );
            return 0;
    }
    同样,编译后复制到cgi-bin目录下,名为test-post.cgi
    测试以POST方式提交guaicat和gnu,可以看到
    name=guaicat&pswd=gnu
    二、用 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\n″);
      n=0;
      if(getenv(″CONTENT-LENGTH″))
      n=atoi(getenv(CONTENT-LENGTH″));
      for (i=0;i
      putchar(getchar());
      putchar (′\n′);
      fflush(stdout);
      }
      下面对此程序作一下简要的分析。
      prinft (″Content type :text/plain\n\n″);
      此行通过标准输出将字符串″Content type :text/plain\n\n″传送给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
      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\n″);
      n=0;
      if (getenv(″CONTENT-LENGTH″))
       n=atoi(getenv(″CONTENT-LENGTH″));
      for (i=0; i
       int is-eq=0;
      c=getchar();
      switch (c){
       case ′&′:
        c=′\n′;
        break;
       case ′+′:
        c=′ ′;
        break;
       case ′%′:{
        char s;
        s[0]=getchar();
        s=getchar();
        s=0;
        c=htoi(s);
        i+=2;
       }
       break;
      case ′=′:
       c=′:′;
       is-eq=1;
       break;
      };
      putchar(c);
      if (is-eq) putchar(′ ′);
      }
      putchar (′\n′);
      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)) s=toupper(s);
      return 16 * (strchr(digits, s[0]) -strchr (digits,′0′)
    )
      +(strchr(digits,s)-strchr(digits,′0′));
      }
      上面的程序首先输出一个MIME头信息给Web服务器,检查输入中的字符数,并循环检查每一个字符。当发现字符为&时,意味着一个名字/值对的结束,程序输出一个空行;当发现字符为+时,将它转换成空格; 当发现字符为%时,意味着一个两字符的十六进制值的开始,调用htoi()函数将随后的两个字符转换为相应的ASCII字符;当发现字符为=时,意味着一个名字/值对的名字部分的结束,并将它转换成字符:。最后将转换后的字符输出给Web服务器。
      四、产生HTML输出
      CGI程序产生的输出由两部分组成:MIME ...
  • 相关阅读:
    java Activiti 工作流引擎 SSM 框架模块设计方案
    自定义表单 Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    数据库设计的十个最佳实践
    activiti 汉化 stencilset.json 文件内容
    JAVA oa 办公系统模块 设计方案
    java 考试系统 在线学习 视频直播 人脸识别 springboot框架 前后分离 PC和手机端
    集成 nacos注册中心配置使用
    “感恩节 ”怼记
    仓颉编程语言的一点期望
    关于System.out.println()与System.out.print("\n")的区别
  • 原文地址:https://www.cnblogs.com/mfryf/p/2394315.html
Copyright © 2020-2023  润新知