美文网首页
3 . boa webserver服务器(2)

3 . boa webserver服务器(2)

作者: wit_yuan | 来源:发表于2017-08-14 21:35 被阅读0次

    1 说明

    本节主要是说明一些比较实用的功能,如文件的上传与下载等,这里不涉及到多用户的概念。

    而这节最重要的内容是cgic程序。

    CGIC是由Thomas Boutell 开发,为C语言编写CGI的C函数库 。它有以下特点:

    • 能对数据进行语法分析
    • 接收以 GET 和 PSOT 两种方式发送的数据
    • 把 FORM 中的不同域连接成连续的串
    • 为检索 FORM 数据而提供字符串 , 整数 , 浮点以及单项和多项选择功能
    • 为数字字段提供边界检测
    • 把 CGI 环境变量加载到非空的 C 串中
    • 为调试而捕捉 CGI 状态
    • 提供相对安全的系统调用功能

    2 资源

    2.1 CGIC

    CGIC官网:链接
    CGIC下载地址:链接

    链接如图所示:


    下载位置

    我下载的文件为cgic207.tar.gz。

    2.2 编译与测试

    编译:

    $ tar xzf cgic207.tar.gz 
    $ cd cgic207/
    $ make
    $ sudo cp cgictest.cgi capture /var/www/cgi-bin/ 
    

    测试:
    网络端ip地址为192.168.1.16,可以在浏览器中输入:

    http://192.168.1.16/cgi-bin/cgictest.cgi
    

    效果如下图所示:


    cgic测试效果图

    3 实践

    3.1 简单测试cgic程序

    我们写一个cgic程序,命名为testcgi.c,如下所示:

    #include <stdio.h>
    #include "cgic.h"
    #include <string.h>
    #include <stdlib.h>
    int cgiMain() {
        cgiHeaderContentType("text/html");
        fprintf(cgiOut, "<HTML><HEAD>\n");
        fprintf(cgiOut, "<TITLE>My First CGIC</TITLE></HEAD>\n");
        fprintf(cgiOut, "<BODY><H1>wit_yuan say CGIC</H1></BODY>\n");
        fprintf(cgiOut, "</HTML>\n");
        return 0;
    }
    

    执行编译,拷贝文件等操作:

    $ gcc cgic.c cgic.h testcgi.c -o testcgi.cgi
    $ sudo cp testcgi.cgi /var/www/cgi-bin/
    

    在浏览器中输入:

    http://192.168.1.16/cgi-bin/testcgi.cgi
    

    即可看到如下图所示效果:


    测试CGIC程序

    3.2 获取textview的数据

    先编写一个名为index1.html的文件,内容如下所示:

    <html>
    <head>
    <title>Test</title>
    </head>
    <body>
    <form action="cgi-bin/testcgi.cgi" method="get">
    <input type="text" name="theText">
    <input type="submit" value="Continue">
    </form>
    </body>
    </html>
    

    然后将这个文件放到/var/www/下:

    $ sudo cp index1.html /var/www/
    

    接着编写我们的testcgi.c程序:

    #include <stdio.h>
    #include "cgic.h"
    #include <string.h>
    #include <stdlib.h>
    
    extern char *cgiQueryString;
    
    int cgiMain() {
        cgiHeaderContentType("text/html");
        fprintf(cgiOut, "<HTML><HEAD>\n");
        fprintf(cgiOut, "<TITLE>My First CGIC</TITLE></HEAD>\n");
        fprintf(cgiOut, "<BODY><H1>%s</H1></BODY>\n",cgiQueryString);
        fprintf(cgiOut, "</HTML>\n");
        return 0;
    }
    

    在浏览器中输入:

    http://192.168.1.16/index1.html
    

    可以看到页面:


    测试页面

    在方框中输入内容,然后进入,可以看到如下图所示:


    页面跳转

    3.3 文件上传

    先写一个html代码,命名为index1.html,能实现基本的网页文件传输功能。

    <!DOCTYPE html>
    
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Test</title>
    </head>
    <body>
    <form target="_blank" action="cgi-bin/testcgi.cgi" enctype="multipart/form-data" method="post">
            <input name="file" type="file" value="" />
            <input type="submit" name="submit" value="ok" />
    </form>
    </body>
    </html>
    

    需要知道的是,对于post形式的文件上传,是需要设置multipart/form-data的,具体可以参考文档:链接

    网页效果图如下:


    文件上传界面

    再来编写基本的CGI程序:
    我先一点点来,比如获取文件名,获取文件大小等。

    #include <stdio.h>
    #include "cgic.h"
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <unistd.h>
    unsigned char array[100];
    char name[128];
    int filesize;
    
    int cgiMain() {
        char *request_method=NULL;
        cgiHeaderContentType("text/html;charset=utf-8\n");
        if(!getenv("REQUEST_METHOD"))
         {
           printf("No client request from user !\n");
           return -1;
         }
         request_method = getenv("REQUEST_METHOD");
    
         if(cgiFormFileName("file", name, sizeof(name)) !=cgiFormSuccess) {
            memcpy(name,"err get file",20);
    //      return -1;
        }
         cgiFormFileSize("file", &filesize);
        fprintf(cgiOut,"<!DOCTYPE html>\n");
        fprintf(cgiOut, "<HTML><HEAD>\n");
        fprintf(cgiOut, "<TITLE>My First CGIC</TITLE></HEAD>\n");
        fprintf(cgiOut, "<BODY><H1>wit_yuan say CGIC %s,%s,size:%d</H1></BODY>\n",name,
                    request_method,filesize);
        fprintf(cgiOut, "</HTML>\n");
        return 0;
    }
    

    我们可以在windows下看到如下的网页内容:


    index1.html内容 文件信息

    在linux下可以看到如下网页内容:


    index.html
    文件信息

    继续写文件:

    #include <stdio.h>
    #include "cgic.h"
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <unistd.h>
    unsigned char openfileerror[100];
    unsigned char array[100];
    char name[128];
    int filesize;
    char contentType[1024];
    cgiFilePtr file;
    char rawfile[64];
    int mode = 0;
    int targetFd;
    char buffer[1024];
    
    int cgiMain() {
        char *request_method=NULL;
        int t ;
        int got;
        char *tempStr=NULL;
        cgiHeaderContentType("text/html;charset=utf-8\n");
        if(!getenv("REQUEST_METHOD"))
        {
           printf("No client request from user !\n");
           return -1;
        }
        request_method = getenv("REQUEST_METHOD");
        if(cgiFormFileName("file", name, sizeof(name)) !=cgiFormSuccess) {
            memcpy(name,"err get file",20);
        }  
        cgiFormFileSize("file", &filesize);
        cgiFormFileContentType("file", contentType, sizeof(contentType));
        if (cgiFormFileOpen("file", &file) != cgiFormSuccess) {
           fprintf(stderr,"could not open the file\n");
           return -1;
        }
        t = -1;
        while(1)
        {
           tempStr = strstr(name+t+1,"\\");
           if(tempStr == NULL){
              tempStr = strstr(name+t+1,"/");
           }
           if(tempStr!=NULL){
             t = (tempStr-name);
           }
           else
             break;
        }
        strcpy(rawfile,name+t+1);
        targetFd = open("/home/wityuan/Desktop/abc",O_WRONLY | O_TRUNC);
        if(targetFd < 0){
           memcpy(openfileerror,"open file error",40);
        }
        while(cgiFormFileRead(file,buffer,1024,&got)==cgiFormSuccess){
          if(got>0){
             write(targetFd,buffer,got);
          }
        }
        cgiFormFileClose(file);
        close(targetFd);
        fprintf(cgiOut,"<!DOCTYPE html>\n");
        fprintf(cgiOut, "<HTML><HEAD>\n");
        fprintf(cgiOut, "<TITLE>My First CGIC</TITLE></HEAD>\n");
        fprintf(cgiOut, "<BODY><H1>wit_yuan say CGIC %s,%s,size:%d,type:%s,rawfile:%s,%s</H1></BODY>\n",name,
            request_method,filesize,contentType,rawfile,openfileerror);
        fprintf(cgiOut, "</HTML>\n");
        return 0;
    }
    

    需要注意的是,我们在open文件之前,手动在主机或者树莓派A20上创建如abc这个文件,然后提升读写权限,在程序里面设置的话,根据测试,open会返回错误。
    提升权限:

    $ chmod 777 abc
    

    测试效果如下:

    访问index1.html

    返回效果图:


    返回效果图
    生成文件

    4 将boa webserver移植到开发板上

    4.1 修改处理文件

    1.修改Makefile文件,修改内容:

    修改src/Makefile文件内容

    2.执行Make

    $ make
    

    如果想要去掉调试信息等,可以使用如下:

    $ arm-linux-gnueabihf-strip boa
    

    3.将make生成的boa文件拷贝到树莓派A20的/bin目录下。
    4.将boa.conf文件拷贝到树莓派A20的/etc/boa(需要新建)下。
    其中boa.conf的内容为:

    Port 80
    User nobody
    Group 0
    ErrorLog /var/log/boa/error_log
    DocumentRoot /var/www
    UserDir public_html
    DirectoryIndex index.html
    DirectoryMaker /usr/lib/boa/boa_indexer
    KeepAliveMax 1000
    KeepAliveTimeout 10
    MimeTypes /etc/mime.types
    ServerName www.your.org.here
    DefaultType text/plain
    CGIPath /bin:/usr/bin:/usr/local/bin
    Alias /doc /usr/doc
    ScriptAlias /cgi-bin/ /var/www/cgi-bin/
    

    注意:

    ServerName www.your.org.here
    

    如果不添加,会在开发板上运行boa的时候提示:gethostbyname:: Resource temporarily unavailable"。

    在开发板上如果有apache2运行,我们需要先将apache相关内容取消掉:

    取消掉文件夹apache2

    5.创建日志文件所在目录/var/log/boa,创建HTML文档的主目录/var/www,创建CGI脚本所在目录/var/www/cgi-bin/,在/var/www中放置一个index.html文件
    6.拷贝主机上的/etc/mime.types文件到开发板/etc目录下。

    完成以上步骤,就可以实现文件的上传了。

    上面所说的一些配置文件与运行程序,可以在链接获取。

    最后,要说一件事情,就是在boa的src目录下,修改defines.h内容,否则一次上传文件打小就只能为1MB了。这里我们修改为5MB。

    如下图所示:


    boa一次上传的文件大小

    5 文件的下载

    5.1 待续

    相关文章

      网友评论

          本文标题:3 . boa webserver服务器(2)

          本文链接:https://www.haomeiwen.com/subject/qvhyrxtx.html