• lighttpd fastcgi的搭建


    公司很久以前有个task需要在板子上搭建个webserver以响应局域网内手机的请求。

    以前是用lighttpd plugin实现的,后来仔细想想用fast cgi来弄也可以。

    在install lighttpd之前,先要install pcre和fcgi。我习惯install到/usr/local/pcre和/usr/local/libfcgi.

    写个简单的配置文件,如下:

    server.document-root = "/mnt/hgfs/share/test/fcgi/"
    server.port = 9090
    socket_dir = "/tmp/"
    server.username = "weifeilong"
    server.groupname = "weifeilong"
    server.errorlog = "/mnt/hgfs/share/test/fcgi/err.log"
    mimetype.assign = (
    ".html" => "text/html",
    ".txt" => "text/plain",
    ".jpg" => "image/jpeg",
    ".png" => "image/png"
    )

    static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc" )
    index-file.names = ( "index.html" )
    server.modules += ("mod_fastcgi")
    fastcgi.server = (
       "/fellow" => (
        "test.fastcgi.handler" => (
        "socket" => socket_dir + "test.fastcgi.socket",
        "check-local" => "disable",
        "bin-path" => "/mnt/hgfs/share/test/fcgi/test.fastcgi",
        "max-procs" => 10,
      )
      )
    )

    这里fastcgi程序就用官网的sample,

    #include <stdlib.h>
    #include <string.h>
    #include <syslog.h>
    #include <alloca.h>
    #include <fcgiapp.h>
    #define LISTENSOCK_FILENO 0
    #define LISTENSOCK_FLAGS 0
    int main(int argc, char** argv) {
      openlog("testfastcgi", LOG_CONS|LOG_NDELAY, LOG_USER);
      int err = FCGX_Init(); /* call before Accept in multithreaded apps */
      if (err) { syslog (LOG_INFO, "FCGX_Init failed: %d", err); return 1; }
      FCGX_Request cgi;
      err = FCGX_InitRequest(&cgi, LISTENSOCK_FILENO, LISTENSOCK_FLAGS);
      if (err) { syslog(LOG_INFO, "FCGX_InitRequest failed: %d", err); return 2; }

      while (1) {
        err = FCGX_Accept_r(&cgi);
        if (err) { syslog(LOG_INFO, "FCGX_Accept_r stopped: %d", err); break; }
        char** envp;
        int size = 200;
        for (envp = cgi.envp; *envp; ++envp) size += strlen(*envp) + 11;
        char* result = (char*) alloca(size);
        strcpy(result, "Status: 200 OK Content-Type: text/html ");
        strcat(result, "<html><head><title>testcgi</title></head><body><ul> ");

        for (envp = cgi.envp; *envp; ++envp) {
        strcat(result, "<li>");
        strcat(result, *envp);
        strcat(result, "</li> ");
        }

        strcat(result, "</ul></body></html> ");
        FCGX_PutStr(result, strlen(result), cgi.out);
      }

      return 0;
    }

    gcc -I/usr/local/libfcgi testfastcgi.c -L/usr/local/libfcgi/lib -lfcgi -o test.fastcgi

    启动lighttpd:/usr/local/lighttpd/sbin/lighttpd -f /mnt/hgfs/share/test/fcgi/lighttpd.conf(运行前需要export LD_LIBRARY_PATH=/usr/local/libfcgi/lib)

    通过curl -v http://localhost:9090/fellow

    就可返回结果:

    对上面sample 稍作修改,以处理GET和POST请求。

    #include <stdlib.h>
    #include <string.h>
    #include <syslog.h>
    #include <alloca.h>
    #include <fcgiapp.h>
    #include <stdio.h>
    #define LISTENSOCK_FILENO 0
    #define LISTENSOCK_FLAGS 0
    int main(int argc, char** argv) {
      openlog("testfastcgi", LOG_CONS|LOG_NDELAY, LOG_USER);
      int err = FCGX_Init(); /* call before Accept in multithreaded apps */
      if (err) { syslog (LOG_INFO, "FCGX_Init failed: %d", err); return 1; }
      FCGX_Request cgi;
      err = FCGX_InitRequest(&cgi, LISTENSOCK_FILENO, LISTENSOCK_FLAGS);
      if (err) { syslog(LOG_INFO, "FCGX_InitRequest failed: %d", err); return 2; }

      while (1) {
        err = FCGX_Accept_r(&cgi);
        if (err) { syslog(LOG_INFO, "FCGX_Accept_r stopped: %d", err); break; }

        #if 1
        char* header = (char*) alloca(200);
        strcpy(header, "Status: 200 OK Content-Type: text/html ");
        FCGX_PutStr(header, strlen(header), cgi.out);
        char response[1024];
        if(!strncmp("GET", FCGX_GetParam("REQUEST_METHOD", cgi.envp), strlen("GET")))
        {
          FCGX_PutStr("GET", strlen("GET"), cgi.err);
          if(!strncmp("action=getInfo", FCGX_GetParam("QUERY_STRING", cgi.envp), strlen("action=getInfo")))
          {
            snprintf(response, sizeof(response), "{"action": "getInfo"} ");
          }
        }
        else if(!strncmp("POST", FCGX_GetParam("REQUEST_METHOD", cgi.envp), strlen("POST")))
        {
          char *post_data = (char*)malloc(1024);
          FCGX_GetStr(post_data, 1024, cgi.in);
          FCGX_PutStr(post_data, 1024, cgi.err);
          if(!strncmp("action=resetInfo", post_data, strlen("action=resetInfo")))
          {
            snprintf(response, sizeof(response), "{"action": "resetInfo"} ");
          }
        }
        FCGX_PutStr(response, strlen(response), cgi.out);
        #endif
      }
      return 0;
    }

     curl -v http://localhost:9090/fellow?action=getInfo

    结果如下:

    curl -v -d "action=resetInfo" http://localhost:9090/fellow

    结果如下:

  • 相关阅读:
    Spark技术栈
    Linux rm -rf删除文件不释放空间的解决办法
    MySQL 5.6.35 索引优化导致的死锁案例解析
    亲历者说 | 完整记录一年多考拉海购的云原生之路 转
    Spark实战(八)spark的几种启动方式
    Spark实战(七)spark streaming +kafka(Python版)
    stm32 IAP + APP ==>双剑合一
    Flask-APScheduler定时任务查询操作数据库(多文件/模块)
    flask框架开启定时任务简单案例flask_apscheduler
    Flask数据的增删改查(CRUD)
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6135756.html
Copyright © 2020-2023  润新知