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

Annotation of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide 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 nmav 1.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 nmav 1.2 /* 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 nmav 1.1 #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 nmav 1.3 hic_module_st * hst;
112    
113 nmav 1.4 hst = find_hic_appr_module( get_mime_type(cmd->path_translated), 0);
114 nmav 1.3 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 nmav 1.1 close( cmd->out_fd);
123    
124 nmav 1.3 /*
125 nmav 1.1 log_error_time();
126     fprintf(stderr, "HIC status: %d wrote: %d\n", cmd->status, cmd->bytes_sent);
127 nmav 1.3 */
128 nmav 1.1
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