• Openwrt自定义CGI实现


    此文已由作者吴志勐授权网易云社区发布。

    欢迎访问网易云社区,了解更多网易技术产品运营经验。

    安装uhttpd。

    在编译openwrt前,输入make memuconfig,查找Network -> Web Servers/Proxies -> uhttpd,如果没勾选则勾选。然后编译固件。


    修改uhttpd配置。

    安装运行openwrt后,通过ssh登陆,修改/etc/config/uhttpd配置文件,在文件末尾添加新的web服务。添加数据基本格式如下:

    config 'uhttpd' 'ServerName' 
    
     option 'home' '/root/' 
    
     list 'listen_http' '0.0.0.0:8080' 
    
     option 'cgi_prefix' '/cgi-bin'

    其中:


    名称说明
    uhttpd服务名称,不要和系统的重名即可
    home服务的根目录
    listen_httpCGI前缀,用来区分是否调用的CGI
    cgi_prefixCGI前缀,用来区分是否调用的CGI


    还有其他配置,不一一列举,比如index_page 、error_page 、listen_https、cert、key、script_timeout、network_timeout、tcp_keepalive等。
    修改后需要重启uhttpd,使用命令:

    /etc/init.d/uhttpd restart

    配置静态页面。

    在服务的根目录下配置web页面,比如index.html(如果uhttpd配置未指定,则为默认页面)。如下是一个网上找到的登陆网页:

    <html> 
    <head><title>..................</title></head> 
    <body> 
    <form name="form1" action="/cgi-bin/helloworld"> 
    <table align="center"> 
    <tr><td align="center" colspan="2"></td></tr> 
    <tr> 
    <td align="right">.........</td> 
    <td><input type="text" name="Username"></td> 
    </tr> 
    <tr> 
    <td align="right">...  ...</td> 
    <td><input type="password" name="Password"></td> 
    </tr> 
    <tr> 
    <td><input type="submit" value="...  ..."></td> 
    <td><input type="reset" value="...  ..."></td> 
    </tr> 
    </table> 
    </form> 
    </body> 
    </html>

    当用户点击登陆时,会跳转访问当前目录下的/cgi-bin/helloworld。


    编写CGI程序。

    例如上一步的/cgi-bin/helloworld即为web服务的CGI程序。本文介绍通过ipk的方式安装CGI程序的方法。
    生成ipk需要借助openwrt的交叉编译,首先在openwrt目录下的package目录下建立一个目录,本例为:helloworld。然后在helloworld目录下建立Makefile文件和src目录。其中Makefile文件的内如如下:

    include (TOPDIR)/rules.mkPKGNAME:=helloworldPKGRELEASE:=1PKGBUILDDIR:=(BUILD_DIR)/(PKGNAME)include(INCLUDE_DIR)/package.mk 
    define Package/helloworld 
    
     SECTION:=utils 
    
     CATEGORY:=Utilities 
    
     TITLE:=Helloworld – prints a snarky message 
    endef 
    define Package/helloworld/description 
    
     If you can't figure out what this program does, you're  probablybrain-dead and need immediate medical attention. 
    endef 
    define Build/Prepare 
    
     mkdir -p (PKGBUILDDIR)(CP) ./src/* $(PKG_BUILD_DIR)/ 
    endef 
    define Package/helloworld/install 
    
     (INSTALLDIR)(1)/root/cgi-bin/ 
    
     $(INSTALL_BIN) (PKGBUILDDIR)/helloworld(1)/root/cgi-bin/ 
    endef 
    (eval(call BuildPackage,helloworld))

    其中制定安装路径为web服务的CGI路径。
    src目录下放入自己的程序及Makefile,本例中有:
    helloworld.c内容如下:

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
     void list_argument(void) 
    { 
    
      char *env_var[] = { 
    
        "COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", 
    
        "HTTP_ACCEPT", "HTTP_ACCEPT_ENCODING", 
    
        "HTTP_ACCEPT_LANGUAGE", "HTTP_CONNECTION", 
    
        "HTTP_HOST", "HTTP_USER_AGENT", "PATH", 
    
        "QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT", 
    
        "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_FILENAME", 
    
        "SCRIPT_NAME", "SERVER_ADDR", "SERVER_ADMIN", 
    
        "SERVER_NAME","SERVER_PORT","SERVER_PROTOCOL", 
    
        "SERVER_SIGNATURE","SERVER_SOFTWARE", "CONTENT_LENGTH" }; 
    
      char *value, i; 
    
     
    
      for (i=0; i<25; i++) { 
    
        value = getenv(env_var[i]); 
    
     
    
        if (value) 
    
        { 
    
     printf("<p>"); 
    
            printf ( "%s = %s 
    ", env_var[i], value); 
    
     printf("<p>"); 
    
        } 
    
      } 
    } 
    
     
    int main(){ 
    printf("Content-Type:text/html;charset=utf-8
    
    "); 
    printf("<html>
    "); 
    printf("<head>
    <title>test</title>
    </head>
    "); 
    printf("<body>
    "); 
    printf("<p>"); 
    printf("hello~
    "); 
    printf("</p>"); 
    list_argument(); 
    printf("</body>
    "); 
    printf("</html>
    "); 
    }

    Makefile内容如下:

    helloworld: helloworld.o 
    
     (CC)(LDFLAGS) helloworld.o -o helloworld 
    helloworld.o: helloworld.c 
    
     (CC)(CFLAGS) -c helloworld.c 
    clean: 
    
     rm *.o helloworldo

    使用openwrt编译好后,把ipa通过scp上传到路由器下(或直接编译到固件中),安装:

    opkg install helloworld_1_x86.ipk

    之后就会在/root/cgi-bin下看见helloworld程序。调用程序能正常输出网页:

    root@OpenWrt:~/cgi-bin# ./helloworld 
    Content-Type:text/html;charset=utf-8 
    
     
    <html> 
    <head> 
    <title>test</title> 
    </head> 
    <body> 
    <P>hello</p></body> 
    </html>

    结果输出

    浏览器就会打开默认页面(192.168.8.106是测试路由器地址),点击默认页面的确定按钮,就会返回CGI的输出,如下图:

    hello~  
    DOCUMENT_ROOT = /root  
    GATEWAY_INTERFACE = CGI/1.1  
    HTTP_ACCEPT = text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8  
    HTTP_ACCEPT_ENCODING = gzip, deflate  
    HTTP_ACCEPT_LANGUAGE = zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3  
    HTTP_CONNECTION = keep-alive  
    HTTP_HOST = 192.168.8.106:8080  
    HTTP_USER_AGENT = Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:29.0) Gecko/20100101 Firefox/29.0  
    PATH = /sbin:/usr/sbin:/bin:/usr/bin  
    QUERY_STRING = Username=11&Password=222  
    REMOTE_ADDR = 192.168.8.103  
    REMOTE_PORT = 53874  
    REQUEST_METHOD = GET  
    REQUEST_URI = /cgi-bin/helloworld?Username=11&Password=222  
    SCRIPT_FILENAME = /root/cgi-bin/helloworld  
    SCRIPT_NAME = /cgi-bin/helloworld  
    SERVER_ADDR = 192.168.8.106  
    SERVER_NAME = 192.168.8.106  
    SERVER_PORT = 8080  
    SERVER_PROTOCOL = HTTP/1.1  
    SERVER_SOFTWARE = uHTTPd



    网易云免费体验馆,0成本体验20+款云产品! 

    更多网易技术、产品、运营经验分享请点击


    相关文章:
    【推荐】 Wireshark对HTTPS数据的解密
    【推荐】 Kubernetes 在网易云中的落地优化实践

  • 相关阅读:
    熔断器Hystrix
    面向对象
    基础语法
    为什么需要定义数据类型???
    集成Ribbon的客户端调用工具——Feign
    Ribbon实现客户端负载均衡
    入门神经网络-Python 实现(下)
    代码视角-神经网络-Python 实现(上)
    归纳方法
    神经网络-反向传播BP算法推导
  • 原文地址:https://www.cnblogs.com/163yun/p/9834993.html
Copyright © 2020-2023  润新知