嵌入式Web服务器BOA移植

时间:2021-03-22 18:38:29

BOA工作流程:

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

嵌入式Web服务器BOA移植嵌入式Web服务器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配置文件。

嵌入式Web服务器BOA移植嵌入式Web服务器BOA移植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.写日志文件。

嵌入式Web服务器BOA移植嵌入式Web服务器BOA移植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服务器。

嵌入式Web服务器BOA移植嵌入式Web服务器BOA移植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配置信息:

嵌入式Web服务器BOA移植嵌入式Web服务器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

嵌入式Web服务器BOA移植嵌入式Web服务器BOA移植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