/[hydra]/hydra/src/hic.c
ViewVC logotype

Contents of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Sat Sep 28 08:50:07 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
Changes since 1.3: +1 -1 lines
File MIME type: text/plain
Updated the way HICModule works. Now accepts a content-type instead of a file extension. I think it is much cleaner.

1 /*
2 * Copyright (C) 2002 Nikos Mavroyanopoulos
3 *
4 * This file is part of BOA webserver.
5 *
6 * Boa is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Boa is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include "boa.h"
22
23 /* Hydra Internally handled CGIs (HIC HIC)
24 *
25 * How does it work?
26 *
27 * A special thread (maybe more than one), is used for CGIs. This tread
28 * uses one pipe to communicate with the others via hic_send_command().
29 *
30 * If a request for a HIC file arrives, the server goes as a normal CGI
31 * creates a pipe, but does not fork. It sends instead a message to this
32 * (HIC) thread to handle the request which includes the output fd.
33 *
34 * The HIC thread, when receives the message, parses the CGI in
35 * FIFO mode (one CGI at the time), and sends the output to fd.
36 *
37 * The benefit is that in no case the server is blocked. We may have
38 * a problem, if the server only uses parsed CGIs.
39 */
40
41 #ifdef ENABLE_HIC
42
43 #include "hic.h"
44
45 static ssize_t full_read(int fd, void *buf, size_t count);
46 static ssize_t full_write(int fd, const void *buf, size_t count);
47 static int process_command(hic_stuff * cmd);
48
49 void* hic_main_loop( void* cml)
50 {
51 int max_fd, ret;
52 struct timeval req_timeout;
53 fd_set read_fdset;
54 hic_stuff cmd;
55 int *command_line = cml; /* this is an int[2] */
56
57 FD_ZERO(&read_fdset);
58
59 while (1) {
60
61 time(&current_time);
62
63 req_timeout.tv_sec = REQUEST_TIMEOUT;
64 req_timeout.tv_usec = 0l; /* reset timeout */
65
66 max_fd = -1;
67
68 FD_SET(command_line[0], &read_fdset);
69 max_fd = command_line[0];
70
71 if (select(max_fd + 1, &read_fdset, NULL, NULL, &req_timeout) == -1) {
72 if (errno == EINTR)
73 continue; /* while(1) */
74 else if (errno != EBADF) {
75 log_error_time();
76 fprintf(stderr, "hic: Error while processing command. %s.\n", strerror(errno));
77 exit(1);
78 }
79 }
80
81 if (FD_ISSET(command_line[0], &read_fdset)) {
82 /* read a command */
83 if ((ret =
84 full_read(command_line[0], &cmd,
85 sizeof(cmd))) < sizeof(cmd)) {
86 log_error_time();
87 if (ret == 0) { /* normal shutdown */
88 log_error_time();
89 fprintf(stderr, "Shutting down...");
90 close(command_line[0]);
91 return NULL;
92 }
93 fprintf(stderr, "hic: Error while receiving command. %s.\n",
94 strerror(errno));
95 exit(1);
96 }
97
98 if (process_command(&cmd) == -1) {
99 log_error_time();
100 fprintf(stderr, "hic: Error while processing command.\n");
101 exit(1);
102 }
103 }
104
105 }
106
107 }
108
109 static int process_command(hic_stuff * cmd)
110 {
111 hic_module_st * hst;
112
113 hst = find_hic_appr_module( get_mime_type(cmd->path_translated), 0);
114 if (hst == NULL) {
115 log_error_time();
116 fprintf(stderr, "Could not find HIC handler for '%s'\n", cmd->path_translated);
117 close( cmd->out_fd);
118 return 0;
119 }
120
121 hst->request( cmd);
122 close( cmd->out_fd);
123
124 /*
125 log_error_time();
126 fprintf(stderr, "HIC status: %d wrote: %d\n", cmd->status, cmd->bytes_sent);
127 */
128
129 return 0;
130 }
131
132 static ssize_t full_read(int fd, void *buf, size_t count)
133 {
134 size_t nleft;
135 ssize_t nread;
136 char *ptr;
137
138 ptr = buf;
139 nleft = count;
140 while (nleft > 0) {
141 if ((nread = read(fd, ptr, nleft)) == -1) {
142 if (errno == EINTR) {
143 nread = 0;
144 } else
145 return -1;
146 } else if (nread == 0)
147 break;
148
149 nleft -= nread;
150 ptr += nread;
151 }
152
153 return count - nleft;
154
155 }
156
157 static ssize_t full_write(int fd, const void *buf, size_t count)
158 {
159 size_t nleft;
160 ssize_t nwritten;
161 const char *ptr;
162
163 ptr = buf;
164 nleft = count;
165 while (nleft > 0) {
166 if ((nwritten = write(fd, ptr, nleft)) == -1) {
167 if (errno == EINTR) {
168 nwritten = 0;
169 } else
170 return -1;
171 }
172
173 nleft -= nwritten;
174 ptr += nwritten;
175 }
176
177 return count;
178
179 }
180
181 #ifdef ENABLE_SMP
182 pthread_mutex_t hic_lock = PTHREAD_MUTEX_INITIALIZER;
183 #endif
184
185 extern int hic_write_fd;
186
187 /* Sends a command to a HIC thread.
188 */
189 int hic_send_command( request *req, int out_fd)
190 {
191 hic_stuff x;
192 int ret;
193
194 x.cgi_env = req->cgi_env;
195 x.cgi_env_max = req->cgi_env_index;
196 x.one_one = 0;
197 x.post_data_fd = req->post_data_fd;
198 x.out_fd = out_fd;
199 x.request_uri = req->request_uri;
200 x.path_translated = req->path_translated;
201
202 #ifdef ENABLE_SMP
203 pthread_mutex_lock( &hic_lock);
204 #endif
205
206 ret = full_write( hic_write_fd, &x, sizeof(x));
207
208 #ifdef ENABLE_SMP
209 pthread_mutex_unlock( &hic_lock);
210 #endif
211
212 if (ret==sizeof(x)) return 1;
213
214 log_error_time();
215 fprintf(stderr, "Error sending to HIC thread.\n");
216 /* this should be a fatal error */
217
218 return -1;
219
220 }
221
222
223 #endif /* ENABLE_HIC */
224
225
226 #ifdef TEST
227
228 int main()
229 {
230 int fd[2];
231 hic_stuff x;
232 pthread_t tid;
233
234 _php_hic_init();
235
236 memset( &x, 0, sizeof(x));
237
238
239 x.remote_address="127.0.0.1";
240 x.server_port = 8080;
241 x.out_fd = STDOUT_FILENO;
242 x.script_name = "/test.php";
243 x.content_type = "text/html; charset=ISO-8859-7";
244 x.query_string = "STRING";
245 x.path_translated = "/tmp/test.php";
246 x.request_uri = "/test.php";
247 x.path_info = "/tmp/test.php";
248 x.str_method = "GET";
249 x.server_name = "Hydra.localhost";
250 x.server_port = 80;
251 x.http_version = "HTTP/1.1";
252 x.post_data_fd = -1;
253
254 if (pipe( fd) < 0) {
255 fprintf(stderr, "ERROR IN PIPE\n");
256 exit(1);
257 }
258
259 pthread_create( &tid, NULL, &hic_main_loop, (void*)fd);
260
261 fprintf(stderr, "Spawned %u\n", tid);
262 sleep(2);
263
264 fprintf(stderr, "Written command\n");
265 write( fd[1], &x, sizeof(x));
266
267 sleep(5);
268
269 close(fd[1]);
270
271 pause();
272
273 return 0;
274 }
275
276 #endif
277

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26