29 |
/* local prototypes */ |
/* local prototypes */ |
30 |
int get_cachedir_file(request * req, struct stat *statbuf); |
int get_cachedir_file(request * req, struct stat *statbuf); |
31 |
int index_directory(request * req, char *dest_filename); |
int index_directory(request * req, char *dest_filename); |
32 |
|
static int check_if_stuff( request* req); |
33 |
|
|
34 |
/* |
/* |
35 |
* Name: init_get |
* Name: init_get |
94 |
/* else, data_fd contains the fd of the file... */ |
/* else, data_fd contains the fd of the file... */ |
95 |
} |
} |
96 |
|
|
|
if (req->if_modified_since && |
|
|
!modified_since(&(statbuf.st_mtime), req->if_modified_since)) { |
|
|
send_r_not_modified(req); |
|
|
close(data_fd); |
|
|
return 0; |
|
|
} |
|
97 |
req->filesize = statbuf.st_size; |
req->filesize = statbuf.st_size; |
98 |
req->last_modified = statbuf.st_mtime; |
req->last_modified = statbuf.st_mtime; |
99 |
|
|
100 |
|
/* Check the If-Match, If-Modified etc stuff. |
101 |
|
*/ |
102 |
|
if (check_if_stuff( req)==0) { |
103 |
|
close( data_fd); |
104 |
|
return 0; |
105 |
|
} |
106 |
|
/* Move on */ |
107 |
|
|
108 |
if (req->range_stop == 0) |
if (req->range_stop == 0) |
109 |
req->range_stop = statbuf.st_size; |
req->range_stop = statbuf.st_size; |
110 |
|
|
231 |
return 1; |
return 1; |
232 |
} |
} |
233 |
|
|
234 |
|
/* |
235 |
|
* Name: check_if_stuff |
236 |
|
* Description: Checks the If-Match, If-None-Match headers |
237 |
|
* |
238 |
|
* req->last_modified, and req->filesize MUST have been set |
239 |
|
* before calling this function. |
240 |
|
* |
241 |
|
* Return values: |
242 |
|
* 1: Successful, continue sending the file |
243 |
|
* 0: unsuccessful. We send the appropriate stuff. Close the connection. |
244 |
|
*/ |
245 |
|
|
246 |
|
static int check_if_stuff( request* req) |
247 |
|
{ |
248 |
|
int comp; |
249 |
|
|
250 |
|
if (req->if_modified_since) { |
251 |
|
if ( !modified_since(req->last_modified, req->if_modified_since)) { |
252 |
|
send_r_not_modified(req); |
253 |
|
return 0; |
254 |
|
} |
255 |
|
} |
256 |
|
|
257 |
|
if (req->etag == NULL || req->if_type == 0) |
258 |
|
return 1; |
259 |
|
|
260 |
|
/* In the case of If-Range, we do not accept modification |
261 |
|
* dates. Use the ETag!! |
262 |
|
*/ |
263 |
|
|
264 |
|
if (strcmp( req->etag, "\"*\"") == 0) { |
265 |
|
comp = 0; /* comparison is always ok */ |
266 |
|
} else { |
267 |
|
char buffer[MAX_ETAG_LENGTH + 3]; |
268 |
|
|
269 |
|
sprintf( buffer, "\"%lu-%lu\"", req->last_modified % 10000, |
270 |
|
req->filesize % 10000); |
271 |
|
|
272 |
|
comp = strcmp( req->etag, buffer); |
273 |
|
/* mod 10000 is used to allow no more than 4 characters -- max is 9999 |
274 |
|
*/ |
275 |
|
} |
276 |
|
|
277 |
|
if (req->if_type == IF_MATCH) { |
278 |
|
if (comp == 0) return 1; |
279 |
|
send_r_precondition_failed( req); |
280 |
|
return 0; |
281 |
|
} |
282 |
|
|
283 |
|
if (req->if_type == IF_RANGE) { |
284 |
|
if (comp == 0) return 1; |
285 |
|
|
286 |
|
/* Ok, but send the whole file, because |
287 |
|
* it has been changed. |
288 |
|
*/ |
289 |
|
req->range_start = req->range_stop = 0; |
290 |
|
return 1; |
291 |
|
} |
292 |
|
|
293 |
|
if (req->if_type == IF_NONE_MATCH) { |
294 |
|
if (comp == 0) { |
295 |
|
send_r_precondition_failed( req); |
296 |
|
return 0; |
297 |
|
} |
298 |
|
return 1; |
299 |
|
} |
300 |
|
|
301 |
|
/* Unsupported type ? */ |
302 |
|
|
303 |
|
return 1; /* do the request */ |
304 |
|
} |
305 |
|
|
306 |
/* |
/* |
307 |
* Name: process_get |
* Name: process_get |