zoukankan      html  css  js  c++  java
  • 嵌入式Web服务器BOA移植

    BOA工作流程:

    1.修正BOA服务器的更目录。

    View Code
    static void fixup_server_root()
    {
        if (!server_root) {
    #ifdef SERVER_ROOT
            server_root = strdup(SERVER_ROOT);
            if (!server_root) {
                perror("strdup (SERVER_ROOT)");
                exit(EXIT_FAILURE);
            }
    #else
            fputs("boa: don't know where server root is.  Please #define "
                  "SERVER_ROOT in boa.h\n"
                  "and recompile, or use the -c command line option to "
                  "specify it.\n", stderr);
            exit(EXIT_FAILURE);
    #endif
        }
    
        if (chdir(server_root) == -1) {
            fprintf(stderr, "Could not chdir to \"%s\": aborting\n",
                    server_root);
            exit(EXIT_FAILURE);
        }
    }

    2.读boa .conf配置文件。

    View Code
      1 /*
      2  * Name: read_config_files
      3  *
      4  * Description: Reads config files, then makes sure that
      5  * all required variables were set properly.
      6  */
      7 void read_config_files(void)
      8 {
      9     FILE *config;
     10 
     11     current_uid = getuid();
     12 
     13     if (!config_file_name) {
     14         config_file_name = DEFAULT_CONFIG_FILE;
     15     }
     16 #ifdef ACCESS_CONTROL
     17     access_init();
     18 #endif                          /* ACCESS_CONTROL */
     19 
     20     config = fopen(config_file_name, "r");  //已只读方式打开配置文件boa.conf
     21     if (!config) {
     22         fputs("Could not open boa.conf for reading.\n", stderr);  //打印打开文件失败的信息
     23         exit(EXIT_FAILURE);
     24     }
     25     parse(config);
     26     fclose(config);
     27 
     28     if (!server_name) {            //如果没有指定服务器名字则指定服务器名字
     29         struct hostent *he;
     30         char temp_name[100];
     31 
     32         if (gethostname(temp_name, 100) == -1) {  //获取服务器名字
     33             perror("gethostname:");
     34             exit(EXIT_FAILURE);
     35         }
     36 
     37         he = gethostbyname(temp_name);     //获取主机
     38         if (he == NULL) {
     39             perror("gethostbyname:");
     40             exit(EXIT_FAILURE);
     41         }
     42 
     43         server_name = strdup(he->h_name);      //获取主机名
     44         if (server_name == NULL) {
     45             perror("strdup:");
     46             exit(EXIT_FAILURE);
     47         }
     48     }
     49     tempdir = getenv("TMP");
     50     if (tempdir == NULL)
     51         tempdir = "/tmp";
     52 
     53     if (single_post_limit < 0) {
     54         fprintf(stderr, "Invalid value for single_post_limit: %d\n",
     55                 single_post_limit);
     56         exit(EXIT_FAILURE);
     57     }
     58 
     59     if (vhost_root && virtualhost) {
     60         fprintf(stderr, "Both VHostRoot and VirtualHost were enabled, and "
     61                 "they are mutually exclusive.\n");
     62         exit(EXIT_FAILURE);
     63     }
     64 
     65     if (vhost_root && document_root) {
     66         fprintf(stderr,
     67                 "Both VHostRoot and DocumentRoot were enabled, and "
     68                 "they are mutually exclusive.\n");
     69         exit(EXIT_FAILURE);
     70     }
     71 
     72     if (!default_vhost) {
     73         default_vhost = DEFAULT_VHOST;
     74     }
     75 
     76 #ifdef USE_SETRLIMIT
     77     if (cgi_rlimit_cpu < 0)
     78         cgi_rlimit_cpu = 0;
     79 
     80     if (cgi_rlimit_data < 0)
     81         cgi_rlimit_data = 0;
     82 
     83     if (cgi_nice < 0)
     84         cgi_nice = 0;
     85 #endif
     86 
     87     if (max_connections < 1) {
     88         struct rlimit rl;
     89         int c;
     90 
     91         /* has not been set explicitly */
     92         c = getrlimit(RLIMIT_NOFILE, &rl);
     93         if (c < 0) {
     94             DIE("getrlimit");
     95         }
     96         max_connections = rl.rlim_cur;
     97     }
     98     if (max_connections > FD_SETSIZE - 20)
     99         max_connections = FD_SETSIZE - 20;
    100 
    101     if (ka_timeout < 0) ka_timeout=0;  /* not worth a message */
    102     /* save some time */
    103     default_timeout = (ka_timeout ? ka_timeout : REQUEST_TIMEOUT);
    104 #ifdef HAVE_POLL
    105     default_timeout *= 1000;
    106 #endif
    107 
    108     if (default_type == NULL) {
    109         DIE("DefaultType *must* be set!");
    110     }
    111 }

    3.写日志文件。

    View Code
     1 /*
     2  * Name: open_logs
     3  *
     4  * Description: Opens access log, error log, and if specified, CGI log
     5  * Ties stderr to error log, except during CGI execution, at which
     6  * time CGI log is the stderr for CGIs.
     7  *
     8  * Access log is line buffered, error log is not buffered.
     9  *
    10  */
    11 
    12 void open_logs(void)
    13 {
    14     int access_log;
    15 
    16     /* if error_log_name is set, dup2 stderr to it */
    17     /* otherwise, leave stderr alone */
    18     /* we don't want to tie stderr to /dev/null */
    19     if (error_log_name) {
    20         int error_log;
    21 
    22         /* open the log file */
    23         error_log = open_gen_fd(error_log_name);
    24         if (error_log < 0) {
    25             DIE("unable to open error log");
    26         }
    27 
    28         /* redirect stderr to error_log */
    29         if (dup2(error_log, STDERR_FILENO) == -1) {
    30             DIE("unable to dup2 the error log");
    31         }
    32         close(error_log);
    33     }
    34 
    35     if (access_log_name) {
    36         access_log = open_gen_fd(access_log_name);
    37     } else {
    38         access_log = open("/dev/null", 0);
    39     }
    40     if (access_log < 0) {
    41         DIE("unable to open access log");
    42     }
    43 
    44     if (dup2(access_log, STDOUT_FILENO) == -1) {
    45         DIE("can't dup2 /dev/null to STDOUT_FILENO");
    46     }
    47     if (fcntl(access_log, F_SETFD, 1) == -1) {
    48         DIE("unable to set close-on-exec flag for access_log");
    49     }
    50 
    51     close(access_log);
    52 
    53     if (cgi_log_name) {
    54         cgi_log_fd = open_gen_fd(cgi_log_name);
    55         if (cgi_log_fd == -1) {
    56             WARN("open cgi_log");
    57             free(cgi_log_name);
    58             cgi_log_name = NULL;
    59             cgi_log_fd = 0;
    60         } else {
    61             if (fcntl(cgi_log_fd, F_SETFD, 1) == -1) {
    62                 WARN("unable to set close-on-exec flag for cgi_log");
    63                 free(cgi_log_name);
    64                 cgi_log_name = NULL;
    65                 close(cgi_log_fd);
    66                 cgi_log_fd = 0;
    67             }
    68         }
    69     }
    70 #ifdef SETVBUF_REVERSED
    71     setvbuf(stderr, _IONBF, (char *) NULL, 0);
    72     setvbuf(stdout, _IOLBF, (char *) NULL, 0);
    73 #else
    74     setvbuf(stderr, (char *) NULL, _IONBF, 0);
    75     setvbuf(stdout, (char *) NULL, _IOLBF, 0);
    76 #endif
    77 }

    4.初始化Web服务器。

    View Code
     1 static int create_server_socket(void)
     2 {
     3     int server_s;
     4 
     5     server_s = socket(SERVER_PF, SOCK_STREAM, IPPROTO_TCP);
     6     if (server_s == -1) {
     7         DIE("unable to create socket");
     8     }
     9 
    10     /* server socket is nonblocking */
    11     if (set_nonblock_fd(server_s) == -1) {
    12         DIE("fcntl: unable to set server socket to nonblocking");
    13     }
    14 
    15     /* close server socket on exec so CGIs can't write to it */
    16     if (fcntl(server_s, F_SETFD, 1) == -1) {
    17         DIE("can't set close-on-exec on server socket!");
    18     }
    19 
    20     /* reuse socket addr */
    21     if ((setsockopt(server_s, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt,
    22                     sizeof (sock_opt))) == -1) {
    23         DIE("setsockopt");
    24     }
    25 
    26     /* Internet family-specific code encapsulated in bind_server()  */
    27     if (bind_server(server_s, server_ip, server_port) == -1) {
    28         DIE("unable to bind");
    29     }
    30 
    31     /* listen: large number just in case your kernel is nicely tweaked */
    32     if (listen(server_s, backlog) == -1) {
    33         DIE("unable to listen");
    34     }
    35     return server_s;
    36 }

    5.当有客户端连接请求到达时,Web服务器(BOA)负责接收客户端请求,并保存相关请求信息。

    6.当收到客户端的连接请求之后,Web服务器分析客户端请求,解析出请求的方法、URL目标、可选的查询信息及表单信息,同时根据客户端的请求做出相应的处理。

    7.Web服务器处理完客户端的请求后,向客户端发送响应信息,最后关闭与客户机的TCP连接。

    BOA配置信息:

    boa.conf
      1 # Boa v0.94 configuration file
      2 # File format has not changed from 0.93
      3 # File format has changed little from 0.92
      4 # version changes are noted in the comments
      5 #
      6 # The Boa configuration file is parsed with a custom parser.  If it
      7 # reports an error, the line number will be provided; it should be easy
      8 # to spot.  The syntax of each of these rules is very simple, and they
      9 # can occur in any order.  Where possible these directives mimic those
     10 # of NCSA httpd 1.3; I saw no reason to introduce gratuitous
     11 # differences.
     12 
     13 # $Id: boa.conf,v 1.3.2.6 2003/02/02 05:02:22 jnelson Exp $
     14 
     15 # The "ServerRoot" is not in this configuration file.  It can be
     16 # compiled into the server (see defines.h) or specified on the command
     17 # line with the -c option, for example:
     18 #
     19 # boa -c /usr/local/boa
     20 
     21 
     22 # Port: The port Boa runs on.  The default port for http servers is 80.
     23 # If it is less than 1024, the server must be started as root.
     24 
     25 Port 80
     26 
     27 # Listen: the Internet address to bind(2) to.  If you leave it out,
     28 # it takes the behavior before 0.93.17.2, which is to bind to all
     29 # addresses (INADDR_ANY).  You only get one "Listen" directive,
     30 # if you want service on multiple IP addresses, you have three choices:
     31 #    1. Run boa without a "Listen" directive
     32 #       a. All addresses are treated the same; makes sense if the addresses
     33 #          are localhost, ppp, and eth0.
     34 #       b. Use the VirtualHost directive below to point requests to different
     35 #          files.  Should be good for a very large number of addresses (web
     36 #          hosting clients).
     37 #    2. Run one copy of boa per IP address, each has its own configuration
     38 #       with a "Listen" directive.  No big deal up to a few tens of addresses.
     39 #       Nice separation between clients.
     40 # The name you provide gets run through inet_aton(3), so you have to use dotted
     41 # quad notation.  This configuration is too important to trust some DNS.
     42 
     43 #Listen 192.68.0.5
     44 
     45 #  User: The name or UID the server should run as.
     46 # Group: The group name or GID the server should run as.
     47 
     48 User nobody
     49 Group nogroup
     50 
     51 # ServerAdmin: The email address where server problems should be sent.
     52 # Note: this is not currently used, except as an environment variable
     53 # for CGIs.
     54 
     55 #ServerAdmin root@localhost
     56 
     57 # PidFile: where to put the pid of the process.
     58 # Comment out to write no pid file.
     59 # Note: Because Boa drops privileges at startup, and the
     60 # pid file is written by the UID/GID before doing so, Boa
     61 # does not attempt removal of the pid file.
     62 # PidFile /var/run/boa.pid
     63 
     64 # ErrorLog: The location of the error log file. If this does not start
     65 # with /, it is considered relative to the server root.
     66 # Set to /dev/null if you don't want errors logged.
     67 # If unset, defaults to /dev/stderr
     68 # Please NOTE: Sending the logs to a pipe ('|'), as shown below,
     69 #  is somewhat experimental and might fail under heavy load.
     70 # "Usual libc implementations of printf will stall the whole
     71 #  process if the receiving end of a pipe stops reading."
     72 #ErrorLog "|/usr/sbin/cronolog --symlink=/var/log/boa/error_log /var/log/boa/error-%Y%m%d.log"
     73 
     74 ErrorLog /var/log/boa/error_log
     75 
     76 # AccessLog: The location of the access log file. If this does not
     77 # start with /, it is considered relative to the server root.
     78 # Comment out or set to /dev/null (less effective) to disable.
     79 # Useful to set to /dev/stdout for use with daemontools.
     80 # Access logging.  
     81 # Please NOTE: Sending the logs to a pipe ('|'), as shown below,
     82 #  is somewhat experimental and might fail under heavy load.
     83 # "Usual libc implementations of printf will stall the whole
     84 #  process if the receiving end of a pipe stops reading."
     85 #AccessLog  "|/usr/sbin/cronolog --symlink=/var/log/boa/access_log /var/log/boa/access-%Y%m%d.log"
     86 
     87 AccessLog /var/log/boa/access_log
     88 
     89 # CGILog /var/log/boa/cgi_log
     90 # CGILog: The location of the CGI stderr log file. If this does not
     91 # start with /, it is considered relative to the server root.
     92 # The log file would contain any contents send to /dev/stderr
     93 # by the CGI. If this is commented out, it defaults to whatever 
     94 # ErrorLog points.  Set to /dev/null to disable CGI stderr logging.
     95 # Please NOTE: Sending the logs to a pipe ('|'), as shown below,
     96 #  is somewhat experimental and might fail under heavy load.
     97 # "Usual libc implementations of printf will stall the whole
     98 #  process if the receiving end of a pipe stops reading."
     99 #CGILog  "|/usr/sbin/cronolog --symlink=/var/log/boa/cgi_log /var/log/boa/cgi-%Y%m%d.log"
    100 
    101 # CGIumask 027 (no mask for user, read-only for group, and nothing for user)
    102 # CGIumask 027
    103 # The CGIumask is set immediately before execution of the CGI.
    104 
    105 # UseLocaltime: Logical switch.  Uncomment to use localtime 
    106 # instead of UTC time
    107 #UseLocaltime
    108 
    109 # VerboseCGILogs: this is just a logical switch.
    110 #  It simply notes the start and stop times of cgis in the error log
    111 # Comment out to disable.
    112 
    113 #VerboseCGILogs
    114 
    115 # ServerName: the name of this server that should be sent back to 
    116 # clients if different than that returned by gethostname + gethostbyname 
    117 
    118 #ServerName www.your.org.here
    119 
    120 # VirtualHost: a logical switch.
    121 # Comment out to disable.
    122 # Given DocumentRoot /var/www, requests on interface 'A' or IP 'IP-A'
    123 # become /var/www/IP-A.
    124 # Example: http://localhost/ becomes /var/www/127.0.0.1
    125 #
    126 # Not used until version 0.93.17.2.  This "feature" also breaks commonlog
    127 # output rules, it prepends the interface number to each access_log line.
    128 # You are expected to fix that problem with a postprocessing script.
    129 
    130 #VirtualHost 
    131 
    132 
    133 # VHostRoot: the root location for all virtually hosted data
    134 # Comment out to disable.
    135 # Incompatible with 'Virtualhost' and 'DocumentRoot'!!
    136 # Given VHostRoot /var/www, requests to host foo.bar.com,
    137 # where foo.bar.com is ip a.b.c.d,
    138 # become /var/www/a.b.c.d/foo.bar.com 
    139 # Hostnames are "cleaned", and must conform to the rules
    140 # specified in rfc1034, which are be summarized here:
    141 # 
    142 # Hostnames must start with a letter, end with a letter or digit, 
    143 # and have as interior characters only letters, digits, and hyphen.
    144 # Hostnames must not exceed 63 characters in length.
    145 
    146 #VHostRoot /var/www
    147 
    148 # DefaultVHost
    149 # Define this in order to have a default hostname when the client does not
    150 # specify one, if using VirtualHostName. If not specified, the word
    151 # "default" will be used for compatibility with older clients.
    152 
    153 #DefaultVHost foo.bar.com
    154 
    155 # DocumentRoot: The root directory of the HTML documents.
    156 # Comment out to disable server non user files.
    157 
    158 DocumentRoot /var/www
    159 
    160 # UserDir: The name of the directory which is appended onto a user's home
    161 # directory if a ~user request is received.
    162 
    163 UserDir public_html
    164 
    165 # DirectoryIndex: Name of the file to use as a pre-written HTML
    166 # directory index.  Please MAKE AND USE THESE FILES.  On the
    167 # fly creation of directory indexes can be _slow_.
    168 # Comment out to always use DirectoryMaker
    169 
    170 DirectoryIndex index.html
    171 
    172 # DirectoryMaker: Name of program used to create a directory listing.
    173 # Comment out to disable directory listings.  If both this and
    174 # DirectoryIndex are commented out, accessing a directory will give
    175 # an error (though accessing files in the directory are still ok).
    176 
    177 DirectoryMaker /usr/lib/boa/boa_indexer
    178 
    179 # DirectoryCache: If DirectoryIndex doesn't exist, and DirectoryMaker
    180 # has been commented out, the the on-the-fly indexing of Boa can be used
    181 # to generate indexes of directories. Be warned that the output is 
    182 # extremely minimal and can cause delays when slow disks are used.
    183 # Note: The DirectoryCache must be writable by the same user/group that 
    184 # Boa runs as.
    185 
    186 # DirectoryCache /var/spool/boa/dircache
    187 
    188 # KeepAliveMax: Number of KeepAlive requests to allow per connection
    189 # Comment out, or set to 0 to disable keepalive processing
    190 
    191 KeepAliveMax 1000
    192 
    193 # KeepAliveTimeout: seconds to wait before keepalive connection times out
    194 
    195 KeepAliveTimeout 10
    196 
    197 # MimeTypes: This is the file that is used to generate mime type pairs
    198 # and Content-Type fields for boa.
    199 # Set to /dev/null if you do not want to load a mime types file.
    200 # Do *not* comment out (better use AddType!)
    201 
    202 MimeTypes /etc/mime.types
    203 
    204 # DefaultType: MIME type used if the file extension is unknown, or there
    205 # is no file extension.
    206 
    207 DefaultType text/plain
    208 
    209 # CGIPath: The value of the $PATH environment variable given to CGI progs.
    210 
    211 CGIPath /bin:/usr/bin:/usr/local/bin
    212 
    213 # SinglePostLimit: The maximum allowable number of bytes in 
    214 # a single POST.  Default is normally 1MB.
    215 
    216 # AddType: adds types without editing mime.types
    217 # Example: AddType type extension [extension ...]
    218 
    219 # Uncomment the next line if you want .cgi files to execute from anywhere
    220 #AddType application/x-httpd-cgi cgi
    221 
    222 # Redirect, Alias, and ScriptAlias all have the same semantics -- they
    223 # match the beginning of a request and take appropriate action.  Use
    224 # Redirect for other servers, Alias for the same server, and ScriptAlias
    225 # to enable directories for script execution.
    226 
    227 # Redirect allows you to tell clients about documents which used to exist in
    228 # your server's namespace, but do not anymore. This allows you to tell the
    229 # clients where to look for the relocated document.
    230 # Example: Redirect /bar http://elsewhere/feh/bar
    231 
    232 # Aliases: Aliases one path to another.
    233 # Example: Alias /path1/bar /path2/foo
    234 
    235 Alias /doc /usr/doc
    236 
    237 # ScriptAlias: Maps a virtual path to a directory for serving scripts
    238 # Example: ScriptAlias /htbin/ /www/htbin/
    239 
    240 ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

    BOA源码:

    http://www.boa.org/

    编译BOA源码:

    #tar zxvf boa-0.94.14.tar.gz

    #cd boa-0.94.tar.gz/src/

    #./configure

    #make

    设置BOA配置信息

    1.建立boa.conf配置文件的路径,并复制boa.conf文件到该目录下。

    #mkdir /etc/toa

    #cp boa.conf /etc/boa

    2.建立日志目录/var/log/boa。

    #mkdir /var/log/boa

    3.修改配置信息:

    #  User: The name or UID the server should run as.
    # Group: The group name or GID the server should run as. 
    User nobody
    Group nogroup 改为 Group 0

     # CGIPath: The value of the $PATH environment variable given to CGI progs. 
    CGIPath /bin:/usr/bin:/usr/local/bin  修改为:CGIPath /bin:/usr/bin:/var/lwww/cgi-bin

    # DirectoryMaker: Name of program used to create a directory listing.
    # Comment out to disable directory listings.  If both this and
    # DirectoryIndex are commented out, accessing a directory will give
    # an error (though accessing files in the directory are still ok). 
    DirectoryMaker /usr/lib/boa/boa_indexer

    # ScriptAlias: Maps a virtual path to a directory for serving scripts
    # Example: ScriptAlias /htbin/ /www/htbin/ 
    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/  修改为ScripAlias /cgi-bin/   /var/www/cgi-bin


    # ServerName: the name of this server that should be sent back to  
    # clients if different than that returned by gethostname + gethostbyname  
    ServerName www.your.org.here

     测试BOA

    1.编写测试主页index.html

    View Code
    <% page contentType="text/html; charset=gb2313" %》
    <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <title> boa test page! </title>
    <head><font color="#cc2200"><b></b>欢迎大家测试BOA服务器</font><p>
    </head>
    <body>
    测试BOA服务器测试页。
    </body>
    </html>

    2.启动Web服务器

    #./boa

    #ps

     

  • 相关阅读:
    Symmetric Tree
    Sort Colors
    Convert Sorted Array to Binary Search Tree
    视频流媒体平台EasyDSS点播模块添加管理员新增点播目录权限判定功能
    视频流媒体服务EasyDSS点播模块根据用户权限开放点播资源的优化
    EasyDSS如何通过postman调用上传点播文件的接口?
    EasyDSS视频平台Dash版本修改匿名直播页面的直播展示
    EasyDSS视频平台DASH版本发现日志打印panic排查及解决方式
    编码器+EasyDSS平台如何实现异地公网大屏同屏直播?
    【解决方案】严防夏天溺水,开启EasyDSS+无人机的智能安防监控新时代
  • 原文地址:https://www.cnblogs.com/panxihua/p/2591705.html
Copyright © 2011-2022 走看看