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

Annotation of /hydra/src/hic.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (hide annotations)
Tue Oct 1 22:38:24 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
Changes since 1.8: +0 -1 lines
File MIME type: text/plain
Several changes to allow Cookies and POST data, to work in HIC CGIs.
Check if a CGI is accessible before trying to execute it, and send not
found if it is not accesible.

1 nmav 1.1 /*
2     * Copyright (C) 2002 Nikos Mavroyanopoulos
3     *
4     * This file is part of BOA webserver.
5     *
6 nmav 1.7 * Hydra is free software; you can redistribute it and/or modify
7 nmav 1.1 * 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 nmav 1.7 * Hydra is distributed in the hope that it will be useful,
12 nmav 1.1 * 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 nmav 1.5 #include <signal.h> /* signal */
23 nmav 1.1
24 nmav 1.2 /* Hydra Internally handled CGIs (HIC HIC)
25     *
26     * How does it work?
27     *
28     * A special thread (maybe more than one), is used for CGIs. This tread
29     * uses one pipe to communicate with the others via hic_send_command().
30     *
31     * If a request for a HIC file arrives, the server goes as a normal CGI
32 nmav 1.5 * creates a pipe, but does not fork. It enqueues a hic_request
33     * for this (HIC) thread, and sends a SIGUSR2 signal. The HIC thread is then
34     * waken up, and handles all pending requests.
35 nmav 1.2 *
36 nmav 1.5 * The HIC thread, when receives the message, parses the CGIs,
37     * one CGI at the time, and sends the output to fd.
38 nmav 1.2 *
39     * The benefit is that in no case the server is blocked. We may have
40 nmav 1.5 * a performance problem, if the server only uses parsed CGIs.
41     *
42 nmav 1.2 */
43    
44 nmav 1.1 #ifdef ENABLE_HIC
45    
46     #include "hic.h"
47    
48 nmav 1.8 static int process_hic_request(hic_params*, hic_request * cmd);
49 nmav 1.5 void hic_dequeue(hic_request ** head, hic_request * req);
50     void hic_enqueue(hic_request ** head, hic_request * req);
51     int hic_sigchld_flag = 0; /* if we received a SIGCHLD signal, then this flag
52     * is non zero */
53 nmav 1.1
54 nmav 1.8 void *hic_main_loop(void *_hic_params)
55 nmav 1.1 {
56 nmav 1.5 hic_request* current, *next;
57 nmav 1.8 hic_params *params = _hic_params;
58    
59     #ifdef ENABLE_SMP
60     pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL);
61     pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
62     #endif
63 nmav 1.1
64     while (1) {
65 nmav 1.8 for (current = params->request_head;current;current=next) {
66 nmav 1.1
67 nmav 1.5 #ifdef ENABLE_SMP
68 nmav 1.8 pthread_mutex_lock(&params->lock);
69 nmav 1.5 #endif
70     next = current->next;
71     #ifdef ENABLE_SMP
72 nmav 1.8 pthread_mutex_unlock(&params->lock);
73 nmav 1.5 #endif
74 nmav 1.1
75 nmav 1.8 if (process_hic_request( params, current) == -1) {
76 nmav 1.1 log_error_time();
77     fprintf(stderr, "hic: Error while processing command.\n");
78     exit(1);
79     }
80     }
81 nmav 1.5
82     /* If somebody sends a command, then he should
83     * send a sigusr2 as well.
84     */
85 nmav 1.6 unblock_sigusr2();
86 nmav 1.8 if (!params->request_head) pause();
87 nmav 1.6 block_sigusr2();
88 nmav 1.5
89 nmav 1.8 if (params->sigchld_flag)
90 nmav 1.5 sigchld_run();
91    
92 nmav 1.1
93     }
94    
95     }
96    
97 nmav 1.8 static int process_hic_request(hic_params* params, hic_request * req)
98 nmav 1.1 {
99 nmav 1.5 hic_module_st *hst;
100     hic_stuff* cmd = &req->command;
101    
102     #ifdef ENABLE_SMP
103 nmav 1.8 pthread_mutex_lock(&params->lock);
104 nmav 1.5 #endif
105 nmav 1.8 hic_dequeue( &params->request_head, req);
106 nmav 1.5 #ifdef ENABLE_SMP
107 nmav 1.8 pthread_mutex_unlock(&params->lock);
108 nmav 1.5 #endif
109 nmav 1.3
110 nmav 1.5 hst = find_hic_appr_module(get_mime_type(cmd->path_translated), 0);
111 nmav 1.3 if (hst == NULL) {
112     log_error_time();
113 nmav 1.5 fprintf(stderr, "Could not find HIC handler for '%s'\n",
114     cmd->path_translated);
115     close(cmd->out_fd);
116     free( req);
117 nmav 1.3 return 0;
118     }
119    
120 nmav 1.5 hst->request(cmd);
121     close(cmd->out_fd);
122     free( req);
123 nmav 1.1
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 nmav 1.8 #ifdef ENABLE_SMP
133     /* We use this index, to send messages to different
134     * HIC thread every time.
135     */
136     static pthread_mutex_t index_lock = PTHREAD_MUTEX_INITIALIZER;
137     static int index;
138     #endif
139    
140 nmav 1.5 /* Sends a command to a HIC thread.
141     */
142     int hic_send_command(request * req, int out_fd)
143 nmav 1.1 {
144 nmav 1.5 hic_request *x;
145 nmav 1.8 hic_params *params;
146    
147     /* choose a random hic thread */
148     if (global_hic_params_size > 1) {
149     #ifdef ENABLE_SMP
150     pthread_mutex_lock( &index_lock);
151     #endif
152     params = &global_hic_params[ index];
153     index++;
154     index %= global_hic_params_size;
155     #ifdef ENABLE_SMP
156     pthread_mutex_unlock( &index_lock);
157     #endif
158     } else {
159     params = &global_hic_params[0];
160     }
161 nmav 1.1
162 nmav 1.5 x = malloc( sizeof( hic_request));
163     if (x==NULL)
164     return -1;
165    
166     x->next = x->prev = NULL;
167     x->command.cgi_env = req->cgi_env;
168     x->command.cgi_env_max = req->cgi_env_index;
169     x->command.one_one = 0;
170     x->command.post_data_fd = req->post_data_fd;
171     x->command.out_fd = out_fd;
172     x->command.path_translated = req->path_translated;
173 nmav 1.1
174 nmav 1.8 if (!req->secure)
175     x->command.server_version = boa_version;
176     else
177     x->command.server_version = boa_tls_version;
178    
179 nmav 1.1 #ifdef ENABLE_SMP
180 nmav 1.8 pthread_mutex_lock(&params->lock);
181 nmav 1.1 #endif
182 nmav 1.5
183 nmav 1.8 hic_enqueue( &params->request_head, x);
184 nmav 1.1 #ifdef ENABLE_SMP
185 nmav 1.8 /* Notify the HIC thread about the pending request
186     */
187     pthread_kill( params->tid, SIGUSR2);
188 nmav 1.1 #endif
189    
190     #ifdef ENABLE_SMP
191 nmav 1.8 pthread_mutex_unlock(&params->lock);
192 nmav 1.1 #endif
193    
194 nmav 1.5 return 1;
195 nmav 1.1
196     }
197    
198 nmav 1.5 /* Implement a basic queue for HIC stuff. This is created after
199     * queue.c.
200     */
201 nmav 1.1
202 nmav 1.5 #include "queue.h"
203 nmav 1.1
204 nmav 1.5 ENQUEUE_FUNCTION( hic_enqueue, hic_request)
205     DEQUEUE_FUNCTION( hic_dequeue, hic_request)
206 nmav 1.1
207 nmav 1.5 #endif /* ENABLE_HIC */

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26