1 * Updated * (the first version I added here was incomplete, sorry)
3 This patch works around a couple of problems in the stock 1.3.24 apache
4 mod_proxy. The 1.3.24 version would fail to de-chunk a chunked http/1.1
5 response for an http/1.0-client, resulting in mysterious hex digits
6 spread all over the returned document. Especially in a chain of proxies,
7 that would lead to serious problems in the interaction between upstream
8 proxies and apache, and the connections would often hang.
10 The patch is a snapshot of the current development version 1.3.25-dev
11 (as of 18-Apr-2002), and contains a lot of whitespace reformatting.
12 Sorry for that, but the layout was standardized using indent, so as
13 to ease future maintenance.
15 It has been tested in an intranet environment, both using direct
16 connections and ProxyRemote connections, and with both http and
19 The patch should apply cleanly against version apache-1.3.24
21 If you have questions, please contact martin at apache dot org, who
22 supplied this patch file. Thank you.
29 $ gzip -dc apache_1.3.24.tar.gz | tar xvf -
30 $ cd apache_1.3.24/src
31 $ patch -p0 </tmp/proxy_http1.1_chunking.patch
34 Index: main/http_protocol.c
35 ===================================================================
36 RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
37 retrieving revision 1.312
38 retrieving revision 1.314
39 diff -u -b -u -r1.312 -r1.314
40 --- main/http_protocol.c 21 Mar 2002 14:49:46 -0000 1.312
41 +++ main/http_protocol.c 6 Apr 2002 14:31:05 -0000 1.314
43 * then the actual input line exceeded the buffer length,
44 * and it would be a good idea for the caller to puke 400 or 414.
46 -static int getline(char *s, int n, BUFF *in, int fold)
47 +API_EXPORT(int) ap_getline(char *s, int n, BUFF *in, int fold)
53 - /* When getline() is called, the HTTP protocol is in a state
54 + /* When ap_getline() is called, the HTTP protocol is in a state
55 * where we MUST be reading "plain text" protocol stuff,
56 * (Request line, MIME headers, Chunk sizes) regardless of
57 * the MIME type and conversion setting of the document itself.
60 static int read_request_line(request_rec *r)
62 - char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
63 + char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* ap_getline's two extra for \n\0 */
66 conn_rec *conn = r->connection;
68 * have to block during a read.
70 ap_bsetflag(conn->client, B_SAFEREAD, 1);
71 - while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) {
72 + while ((len = ap_getline(l, sizeof(l), conn->client, 0)) <= 0) {
73 if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) {
74 ap_bsetflag(conn->client, B_SAFEREAD, 0);
75 /* this is a hack to make sure that request time is set,
80 - /* getline returns (size of max buffer - 1) if it fills up the
81 + /* ap_getline returns (size of max buffer - 1) if it fills up the
82 * buffer before finding the end-of-line. This is only going to
83 * happen if it exceeds the configured limit for a request-line.
87 static void get_mime_headers(request_rec *r)
89 - char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
90 + char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* ap_getline's two extra */
91 conn_rec *c = r->connection;
95 * Read header lines until we get the empty separator line, a read error,
96 * the connection closes (EOF), reach the server limit, or we timeout.
98 - while ((len = getline(field, sizeof(field), c->client, 1)) > 0) {
99 + while ((len = ap_getline(field, sizeof(field), c->client, 1)) > 0) {
101 if (r->server->limit_req_fields &&
102 (++fields_read > r->server->limit_req_fields)) {
103 @@ -1081,7 +1081,7 @@
104 "this server's limit.<P>\n");
107 - /* getline returns (size of max buffer - 1) if it fills up the
108 + /* ap_getline returns (size of max buffer - 1) if it fills up the
109 * buffer before finding the end-of-line. This is only going to
110 * happen if it exceeds the configured limit for a field size.
112 @@ -1513,7 +1513,6 @@
113 API_EXPORT(void) ap_basic_http_header(request_rec *r)
116 - const char *server;
120 @@ -1542,11 +1541,14 @@
121 /* output the date header */
122 ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
124 - /* keep a previously set server header (possible from proxy), otherwise
125 + /* keep the set-by-proxy server header, otherwise
126 * generate a new server header */
127 - if (server = ap_table_get(r->headers_out, "Server")) {
129 + const char *server = ap_table_get(r->headers_out, "Server");
131 ap_send_header_field(r, "Server", server);
135 ap_send_header_field(r, "Server", ap_get_server_version());
137 @@ -2016,7 +2018,7 @@
141 -static long get_chunk_size(char *b)
142 +API_EXPORT(long) ap_get_chunk_size(char *b)
146 @@ -2098,14 +2100,14 @@
148 if (r->remaining == 0) { /* Start of new chunk */
150 - chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
151 + chunk_start = ap_getline(buffer, bufsiz, r->connection->client, 0);
152 if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
153 || !ap_isxdigit(*buffer)) {
154 r->connection->keepalive = -1;
158 - len_to_read = get_chunk_size(buffer);
159 + len_to_read = ap_get_chunk_size(buffer);
161 if (len_to_read == 0) { /* Last chunk indicated, get footers */
162 if (r->read_body == REQUEST_CHUNKED_DECHUNK) {
163 @@ -2139,7 +2141,7 @@
164 len_read = chunk_start;
166 while ((bufsiz > 1) && ((len_read =
167 - getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
168 + ap_getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {
170 if (len_read != (bufsiz - 1)) {
171 buffer[len_read++] = CR; /* Restore footer line end */
172 Index: modules/proxy/mod_proxy.c
173 ===================================================================
174 RCS file: /home/cvs/apache-1.3/src/modules/proxy/mod_proxy.c,v
175 retrieving revision 1.80
176 retrieving revision 1.81
177 diff -u -b -u -r1.80 -r1.81
178 --- modules/proxy/mod_proxy.c 13 Mar 2002 21:05:32 -0000 1.80
179 +++ modules/proxy/mod_proxy.c 25 Mar 2002 09:21:58 -0000 1.81
182 while (aliasp < end_fakename) {
183 if (*aliasp == '/') {
184 - /* any number of '/' in the alias matches any number in
185 - * the supplied URI, but there must be at least one...
187 + * any number of '/' in the alias matches any number in the
188 + * supplied URI, but there must be at least one...
193 if (aliasp[-1] != '/' && *urip != '\0' && *urip != '/')
196 - /* Return number of characters from URI which matched (may be
197 - * greater than length of alias, since we may have matched
200 + * Return number of characters from URI which matched (may be greater
201 + * than length of alias, since we may have matched doubled slashes)
206 void *sconf = r->server->module_config;
207 proxy_server_conf *conf;
209 - conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
210 + conf = (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
212 if (conf->req && r->parsed_uri.scheme) {
213 /* but it might be something vhosted */
214 @@ -176,20 +177,22 @@
216 void *sconf = r->server->module_config;
217 proxy_server_conf *conf =
218 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
219 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
221 - struct proxy_alias *ent = (struct proxy_alias *) conf->aliases->elts;
222 + struct proxy_alias *ent = (struct proxy_alias *)conf->aliases->elts;
224 if (r->proxyreq != NOT_PROXY) {
225 - /* someone has already set up the proxy, it was possibly ourselves
228 + * someone has already set up the proxy, it was possibly ourselves in
234 - /* XXX: since r->uri has been manipulated already we're not really
235 - * compliant with RFC1945 at this point. But this probably isn't
236 - * an issue because this is a hybrid proxy/origin server.
238 + * XXX: since r->uri has been manipulated already we're not really
239 + * compliant with RFC1945 at this point. But this probably isn't an
240 + * issue because this is a hybrid proxy/origin server.
243 for (i = 0; i < conf->aliases->nelts; i++) {
247 ap_table_set(r->headers_out, "Location", nuri);
248 - ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, r,
249 + ap_log_rerror(APLOG_MARK, APLOG_INFO | APLOG_NOERRNO, r,
250 "Domain missing: %s sent to %s%s%s", r->uri,
251 ap_unparse_uri_components(r->pool, &r->parsed_uri,
254 char *url, *scheme, *p;
255 void *sconf = r->server->module_config;
256 proxy_server_conf *conf =
257 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
258 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
259 array_header *proxies = conf->proxies;
260 struct proxy_remote *ents = (struct proxy_remote *) proxies->elts;
265 ap_table_setn(r->headers_in, "Max-Forwards",
266 - ap_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd-1 : 0));
267 + ap_psprintf(r->pool, "%ld", (maxfwd > 0) ? maxfwd - 1 : 0));
270 if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)))
271 @@ -343,16 +346,16 @@
272 /* Check URI's destination host against NoProxy hosts */
273 /* Bypass ProxyRemote server lookup if configured as NoProxy */
274 /* we only know how to handle communication to a proxy via http */
275 - /*if (strcasecmp(scheme, "http") == 0) */
276 + /* if (strcasecmp(scheme, "http") == 0) */
279 - struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts;
280 + struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts;
282 for (direct_connect = ii = 0; ii < conf->dirconn->nelts && !direct_connect; ii++) {
283 direct_connect = list[ii].matcher(&list[ii], r);
286 - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
287 + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r,
288 (direct_connect) ? "NoProxy for %s" : "UseProxy for %s",
292 (p == NULL && strcasecmp(scheme, ents[i].scheme) == 0) ||
294 strncasecmp(url, ents[i].scheme, strlen(ents[i].scheme)) == 0)) {
295 - /* CONNECT is a special method that bypasses the normal
298 + * CONNECT is a special method that bypasses the normal proxy
301 if (r->method_number == M_CONNECT)
302 rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname,
304 ps->viaopt_set = 0; /* 0 means default */
307 - ps->recv_buffer_size = 0; /* this default was left unset for some reason */
308 + ps->recv_buffer_size = 0; /* this default was left unset for some
310 ps->recv_buffer_size_set = 0;
311 ps->io_buffer_size = IOBUFSIZE;
312 ps->io_buffer_size_set = 0;
316 proxy_server_conf *ps = ap_pcalloc(p, sizeof(proxy_server_conf));
317 - proxy_server_conf *base = (proxy_server_conf *) basev;
318 - proxy_server_conf *overrides = (proxy_server_conf *) overridesv;
319 + proxy_server_conf *base = (proxy_server_conf *)basev;
320 + proxy_server_conf *overrides = (proxy_server_conf *)overridesv;
322 ps->proxies = ap_append_arrays(p, base->proxies, overrides->proxies);
323 ps->aliases = ap_append_arrays(p, base->aliases, overrides->aliases);
326 server_rec *s = cmd->server;
327 proxy_server_conf *conf =
328 - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
329 + (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module);
330 struct proxy_remote *new;
335 server_rec *s = cmd->server;
336 proxy_server_conf *conf =
337 - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
338 + (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module);
339 struct proxy_alias *new;
341 new = ap_push_array(conf->aliases);
344 /* Don't do name lookups on things that aren't dotted */
345 if (strchr(arg, '.') != NULL && ap_proxy_host2addr(new->name, &hp) == NULL)
346 - /*@@@FIXME: This copies only the first of (possibly many) IP addrs */
348 + * @@@FIXME: This copies only the first of (possibly many) IP
351 memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr));
353 new->addr.s_addr = 0;
355 proxy_server_conf *conf =
356 ap_get_module_config(s->module_config, &proxy_module);
357 struct dirconn_entry *New;
358 - struct dirconn_entry *list = (struct dirconn_entry *) conf->dirconn->elts;
359 + struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts;
365 if (sscanf(arg, "%lg", &val) != 1)
366 return "CacheMaxExpire value must be a float";
367 - psf->cache.maxexpire = (int) (val * (double) SEC_ONE_HR);
368 + psf->cache.maxexpire = (int)(val * (double)SEC_ONE_HR);
369 psf->cache.maxexpire_set = 1;
374 if (sscanf(arg, "%lg", &val) != 1)
375 return "CacheDefaultExpire value must be a float";
376 - psf->cache.defaultexpire = (int) (val * (double) SEC_ONE_HR);
377 + psf->cache.defaultexpire = (int)(val * (double)SEC_ONE_HR);
378 psf->cache.defaultexpire_set = 1;
383 if (sscanf(arg, "%lg", &val) != 1)
384 return "CacheGcInterval value must be a float";
385 - psf->cache.gcinterval = (int) (val * (double) SEC_ONE_HR);
386 + psf->cache.gcinterval = (int)(val * (double)SEC_ONE_HR);
387 psf->cache.gcinterval_set = 1;
392 /* Don't do name lookups on things that aren't dotted */
393 if (strchr(arg, '.') != NULL && ap_proxy_host2addr(new->name, &hp) == NULL)
394 - /*@@@FIXME: This copies only the first of (possibly many) IP addrs */
396 + * @@@FIXME: This copies only the first of (possibly many) IP
399 memcpy(&new->addr, hp.h_addr, sizeof(struct in_addr));
401 new->addr.s_addr = 0;
408 set_cache_completion(cmd_parms *parms, void *dummy, char *arg)
410 proxy_server_conf *psf =
417 set_via_opt(cmd_parms *parms, void *dummy, char *arg)
419 proxy_server_conf *psf =
421 NULL, /* child_exit */
422 proxy_detect /* post read-request */
426 Index: modules/proxy/mod_proxy.h
427 ===================================================================
428 RCS file: /home/cvs/apache-1.3/src/modules/proxy/mod_proxy.h,v
429 retrieving revision 1.57
430 retrieving revision 1.58
431 diff -u -b -u -r1.57 -r1.58
432 --- modules/proxy/mod_proxy.h 13 Mar 2002 21:05:32 -0000 1.57
433 +++ modules/proxy/mod_proxy.h 7 Apr 2002 18:57:36 -0000 1.58
435 char **passwordp, char **hostp, int *port);
436 const char *ap_proxy_date_canon(pool *p, const char *x);
437 table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f);
438 -long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite, size_t recv_buffer_size);
439 +long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite, int chunked, size_t recv_buffer_size);
440 void ap_proxy_write_headers(cache_req *c, const char *respline, table *t);
441 int ap_proxy_liststr(const char *list, const char *key, char **val);
442 void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength);
443 Index: modules/proxy/proxy_cache.c
444 ===================================================================
445 RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_cache.c,v
446 retrieving revision 1.81
447 retrieving revision 1.86
448 diff -u -b -u -r1.81 -r1.86
449 --- modules/proxy/proxy_cache.c 13 Mar 2002 21:05:32 -0000 1.81
450 +++ modules/proxy/proxy_cache.c 12 Apr 2002 12:34:46 -0000 1.86
451 @@ -135,14 +135,14 @@
453 static int inside = 0;
455 - (void) ap_acquire_mutex(garbage_mutex);
456 + (void)ap_acquire_mutex(garbage_mutex);
458 - (void) ap_release_mutex(garbage_mutex);
459 + (void)ap_release_mutex(garbage_mutex);
464 - (void) ap_release_mutex(garbage_mutex);
465 + (void)ap_release_mutex(garbage_mutex);
467 ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */
468 if (should_proxy_garbage_coll(r))
469 @@ -153,14 +153,13 @@
473 - (void) ap_acquire_mutex(garbage_mutex);
474 + (void)ap_acquire_mutex(garbage_mutex);
476 - (void) ap_release_mutex(garbage_mutex);
477 + (void)ap_release_mutex(garbage_mutex);
482 -add_long61 (long61_t *accu, long val)
483 +static void add_long61(long61_t *accu, long val)
485 /* Add in lower 30 bits */
486 accu->lower += (val & 0x3FFFFFFFL);
488 accu->lower &= 0x3FFFFFFFL;
492 -sub_long61 (long61_t *accu, long val)
493 +static void sub_long61(long61_t *accu, long val)
495 int carry = (val & 0x3FFFFFFFL) > accu->lower;
496 /* Subtract lower 30 bits */
498 * return 0 when left == right
499 * return >0 when left > right
502 -cmp_long61 (long61_t *left, long61_t *right)
503 +static long cmp_long61(long61_t *left, long61_t *right)
505 return (left->upper == right->upper) ? (left->lower - right->lower)
506 : (left->upper - right->upper);
509 void *sconf = r->server->module_config;
510 proxy_server_conf *pconf =
511 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
512 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
513 const struct cache_conf *conf = &pconf->cache;
515 const char *cachedir = conf->root;
516 @@ -295,27 +292,29 @@
517 if (cachedir == NULL || every == -1)
520 - filename = ap_palloc(r->pool, strlen(cachedir) + strlen( DOT_TIME ) +1);
521 + filename = ap_palloc(r->pool, strlen(cachedir) + strlen(DOT_TIME) + 1);
523 garbage_now = time(NULL);
524 - /* Usually, the modification time of <cachedir>/.time can only increase.
526 + * Usually, the modification time of <cachedir>/.time can only increase.
527 * Thus, even with several child processes having their own copy of
528 - * lastcheck, if time(NULL) still < lastcheck then it's not time
530 + * lastcheck, if time(NULL) still < lastcheck then it's not time for GC
533 if (garbage_now != -1 && lastcheck != BAD_DATE && garbage_now < lastcheck + every)
536 - strcpy(filename,cachedir);
537 - strcat(filename,DOT_TIME);
538 + strcpy(filename, cachedir);
539 + strcat(filename, DOT_TIME);
541 - /* At this point we have a bit of an engineering compromise. We could either
542 - * create and/or mark the .time file (prior to the fork which might
543 - * fail on a resource issue) or wait until we are safely forked. The
544 - * advantage of doing it now in this process is that we get some
545 - * usefull live out of the global last check variable. (XXX which
546 - * should go scoreboard IMHO.) Note that the actual counting is
547 - * at a later moment.
549 + * At this point we have a bit of an engineering compromise. We could
550 + * either create and/or mark the .time file (prior to the fork which
551 + * might fail on a resource issue) or wait until we are safely forked.
552 + * The advantage of doing it now in this process is that we get some
553 + * usefull live out of the global last check variable. (XXX which should
554 + * go scoreboard IMHO.) Note that the actual counting is at a later
557 if (stat(filename, &buf) == -1) { /* does not exist */
558 if (errno != ENOENT) {
560 const char *cachedir;
561 void *sconf = r->server->module_config;
562 proxy_server_conf *pconf =
563 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
564 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
565 const struct cache_conf *conf = &pconf->cache;
569 sub_garbage_coll(r, files, cachedir, "/");
571 if (cmp_long61(&curbytes, &cachesize) < 0L) {
572 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
573 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
574 "proxy GC: Cache is %ld%% full (nothing deleted)",
575 - (long)(((curbytes.upper<<20)|(curbytes.lower>>10))*100/conf->space));
576 + (long)(((curbytes.upper << 20) | (curbytes.lower >> 10)) * 100 / conf->space));
581 for (i = 0; i < files->nelts; i++) {
582 fent = &((struct gc_ent *) files->elts)[i];
583 sprintf(filename, "%s%s", cachedir, fent->file);
584 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "GC Unlinking %s (expiry %ld, garbage_now %ld)", filename, (long)fent->expire, (long)garbage_now);
585 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "GC Unlinking %s (expiry %ld, garbage_now %ld)", filename, (long)fent->expire, (long)garbage_now);
587 fprintf(stderr, "Would unlink %s\n", filename);
589 @@ -403,16 +402,16 @@
593 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
594 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
595 "proxy GC: Cache is %ld%% full (%d deleted)",
596 - (long)(((curbytes.upper<<20)|(curbytes.lower>>10))*100/conf->space), i);
597 + (long)(((curbytes.upper << 20) | (curbytes.lower >> 10)) * 100 / conf->space), i);
601 static int sub_garbage_coll(request_rec *r, array_header *files,
602 const char *cachebasedir, const char *cachesubdir)
605 + char line[17 * (3)];
606 char cachedir[HUGE_STRING_LEN];
611 ap_snprintf(cachedir, sizeof(cachedir), "%s%s", cachebasedir, cachesubdir);
612 filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2);
613 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "GC Examining directory %s", cachedir);
614 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "GC Examining directory %s", cachedir);
615 dir = opendir(cachedir);
617 ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
619 if (ent->d_name[0] == '.')
621 sprintf(filename, "%s%s", cachedir, ent->d_name);
622 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "GC Examining file %s", filename);
623 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "GC Examining file %s", filename);
624 /* is it a temporary file? */
625 if (strncmp(ent->d_name, "tmp", 3) == 0) {
626 /* then stat it to see how old it is; delete temporary files > 1 day old */
629 else if (garbage_now != -1 && buf.st_atime < garbage_now - SEC_ONE_DAY &&
630 buf.st_mtime < garbage_now - SEC_ONE_DAY) {
631 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "GC unlink %s", filename);
632 - ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, r->server,
633 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "GC unlink %s", filename);
634 + ap_log_error(APLOG_MARK, APLOG_INFO | APLOG_NOERRNO, r->server,
635 "proxy gc: deleting orphaned cache file %s", filename);
637 fprintf(stderr, "Would unlink %s\n", filename);
638 @@ -472,15 +471,16 @@
639 #if defined(OS2) || defined(TPF)
640 /* is it a directory? */
642 - if (ent->d_attr & A_DIR) {
643 + if (ent->d_attr & A_DIR)
645 if (stat(filename, &buf) == -1) {
647 ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
648 "proxy gc: stat(%s)", filename);
650 - if (S_ISDIR(buf.st_mode)) {
651 + if (S_ISDIR(buf.st_mode))
654 char newcachedir[HUGE_STRING_LEN];
655 ap_snprintf(newcachedir, sizeof(newcachedir),
656 "%s%s/", cachesubdir, ent->d_name);
661 - /* On WIN32 open does not work for directories,
662 - * so we us stat instead of fstat to determine
663 - * if the file is a directory
665 + * On WIN32 open does not work for directories, so we us stat instead
666 + * of fstat to determine if the file is a directory
668 if (stat(filename, &buf) == -1) {
669 ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
677 /* Directory is not empty. Account for its size: */
678 add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));
684 - /* Since we have determined above that the file is not a directory,
686 + * Since we have determined above that the file is not a directory,
687 * it should be safe to open it now
689 fd = open(filename, O_RDONLY | O_BINARY);
694 - i = read(fd, line, 17*(3)-1);
695 + i = read(fd, line, 17 * (3) - 1);
698 ap_log_error(APLOG_MARK, APLOG_ERR, r->server,
699 @@ -574,13 +576,13 @@
703 - garbage_expire = ap_proxy_hex2sec(line + 17*(2));
704 + garbage_expire = ap_proxy_hex2sec(line + 17 * (2));
705 if (!ap_checkmask(line, "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&") ||
706 garbage_expire == BAD_DATE) {
708 if (garbage_now != -1 && buf.st_atime > garbage_now + SEC_ONE_DAY &&
709 buf.st_mtime > garbage_now + SEC_ONE_DAY) {
710 - ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, r->server,
711 + ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,
712 "proxy: deleting bad cache file with future date: %s", filename);
714 fprintf(stderr, "Would unlink bad file %s\n", filename);
715 @@ -632,29 +634,28 @@
717 /* read the data from the cache file */
723 - * The cache needs to keep track of the following information:
724 - * - Date, LastMod, Version, ReqTime, RespTime, ContentLength
725 - * - The original request headers (for Vary)
726 - * - The original response headers (for returning with a cached response)
727 - * - The body of the message
729 - * date SP lastmod SP expire SP count SP request-time SP response-time SP content-lengthCRLF
730 - * (dates are stored as hex seconds since 1970)
732 - * Original Request Headers
734 - * Original Response Headers
737 + * The cache needs to keep track of the following information: - Date,
738 + * LastMod, Version, ReqTime, RespTime, ContentLength - The original
739 + * request headers (for Vary) - The original response headers (for
740 + * returning with a cached response) - The body of the message
742 + * date SP lastmod SP expire SP count SP request-time SP response-time SP
743 + * content-lengthCRLF (dates are stored as hex seconds since 1970)
744 + * Original URLCRLF Original Request Headers CRLF Original Response
745 + * Headers CRLF Body
749 /* retrieve cachefile information values */
750 len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
753 + /* Delete broken cache file */
754 + unlink(c->filename);
757 if (len == 0 || urlbuff[len - 1] != '\n')
759 urlbuff[len - 1] = '\0';
760 @@ -663,18 +664,21 @@
761 "&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&"))
764 - c->date = ap_proxy_hex2sec(urlbuff + 17*(0));
765 - c->lmod = ap_proxy_hex2sec(urlbuff + 17*(1));
766 - c->expire = ap_proxy_hex2sec(urlbuff + 17*(2));
767 - c->version = ap_proxy_hex2sec(urlbuff + 17*(3));
768 - c->req_time = ap_proxy_hex2sec(urlbuff + 17*(4));
769 - c->resp_time = ap_proxy_hex2sec(urlbuff + 17*(5));
770 - c->len = ap_proxy_hex2sec(urlbuff + 17*(6));
771 + c->date = ap_proxy_hex2sec(urlbuff + 17 * (0));
772 + c->lmod = ap_proxy_hex2sec(urlbuff + 17 * (1));
773 + c->expire = ap_proxy_hex2sec(urlbuff + 17 * (2));
774 + c->version = ap_proxy_hex2sec(urlbuff + 17 * (3));
775 + c->req_time = ap_proxy_hex2sec(urlbuff + 17 * (4));
776 + c->resp_time = ap_proxy_hex2sec(urlbuff + 17 * (5));
777 + c->len = ap_proxy_hex2sec(urlbuff + 17 * (6));
779 /* check that we have the same URL */
780 len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
783 + /* Delete broken cache file */
784 + unlink(c->filename);
787 if (len == 0 || strncmp(urlbuff, "X-URL: ", 7) != 0 ||
788 urlbuff[len - 1] != '\n')
790 @@ -684,13 +688,19 @@
792 /* then the original request headers */
793 c->req_hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);
794 - if (c->req_hdrs == NULL)
795 + if (c->req_hdrs == NULL) {
796 + /* Delete broken cache file */
797 + unlink(c->filename);
801 /* then the original response headers */
802 len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
805 + /* Delete broken cache file */
806 + unlink(c->filename);
809 if (len == 0 || urlbuff[len - 1] != '\n')
811 urlbuff[--len] = '\0';
814 c->status = atoi(strp);
815 c->hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);
816 - if (c->hdrs == NULL)
817 + if (c->hdrs == NULL) {
818 + /* Delete broken cache file */
819 + unlink(c->filename);
822 if (c->len != -1) /* add a content-length header */
823 if (ap_table_get(c->hdrs, "Content-Length") == NULL) {
824 ap_table_set(c->hdrs, "Content-Length",
825 @@ -735,52 +748,53 @@
826 /* check for If-Match, If-Unmodified-Since */
829 - /* check If-Match and If-Unmodified-Since exist
831 + * check If-Match and If-Unmodified-Since exist
833 - * If neither of these exist, the request is not conditional, and
834 - * we serve it normally
835 + * If neither of these exist, the request is not conditional, and we
836 + * serve it normally
838 if (!c->im && BAD_DATE == c->ius) {
846 - * we check if the Etag on the cached file is in the list of Etags
847 - * in the If-Match field. The comparison must be a strong comparison,
848 - * so the Etag cannot be marked as weak. If the comparision fails
849 - * we return 412 Precondition Failed.
851 - * if If-Match is specified AND
852 - * If-Match is not a "*" AND
853 - * Etag is missing or weak or not in the list THEN
854 - * return 412 Precondition Failed
855 + * we check if the Etag on the cached file is in the list of Etags in
856 + * the If-Match field. The comparison must be a strong comparison, so
857 + * the Etag cannot be marked as weak. If the comparision fails we
858 + * return 412 Precondition Failed.
860 + * if If-Match is specified AND If-Match is not a "*" AND Etag is
861 + * missing or weak or not in the list THEN return 412 Precondition
866 if (strcmp(c->im, "*") &&
867 (!etag || (strlen(etag) > 1 && 'W' == etag[0] && '/' == etag[1]) || !ap_proxy_liststr(c->im, etag, NULL))) {
868 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-Match specified, and it didn't - return 412");
869 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it didn't - return 412");
872 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-Match specified, and it matched");
873 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it matched");
878 - /* check If-Unmodified-Since
880 + * check If-Unmodified-Since
882 - * if If-Unmodified-Since is specified AND
883 - * Last-Modified is specified somewhere AND
884 - * If-Unmodified-Since is in the past compared to Last-Modified THEN
885 - * return 412 Precondition Failed
886 + * if If-Unmodified-Since is specified AND Last-Modified is specified
887 + * somewhere AND If-Unmodified-Since is in the past compared to
888 + * Last-Modified THEN return 412 Precondition Failed
890 if (BAD_DATE != c->ius && BAD_DATE != c->lmod) {
891 if (c->ius < c->lmod) {
892 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, but it wasn't - return 412");
893 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, but it wasn't - return 412");
896 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, and it was unmodified");
897 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, and it was unmodified");
901 @@ -788,13 +802,13 @@
902 /* if cache file is being updated */
904 ap_proxy_write_headers(c, c->resp_line, c->hdrs);
905 - ap_proxy_send_fb(c->origfp, r, c, c->len, 1, IOBUFSIZE);
906 + ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);
907 ap_proxy_cache_tidy(c);
910 ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
912 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Use your cached copy, conditional precondition failed.");
913 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use your cached copy, conditional precondition failed.");
914 return HTTP_PRECONDITION_FAILED;
917 @@ -802,53 +816,54 @@
918 /* check for If-None-Match, If-Modified-Since */
921 - /* check for existance of If-None-Match and If-Modified-Since
923 + * check for existance of If-None-Match and If-Modified-Since
925 - * if neither of these headers have been set, then the request
926 - * is not conditional, and we just send the cached response and
928 + * if neither of these headers have been set, then the request is not
929 + * conditional, and we just send the cached response and be done with
932 if (!c->inm && BAD_DATE == c->ims) {
936 - /* check If-None-Match
938 + * check If-None-Match
940 - * we check if the Etag on the cached file is in the list of Etags
941 - * in the If-None-Match field. The comparison must be a strong comparison,
942 - * so the Etag cannot be marked as weak. If the comparision fails
943 - * we return 412 Precondition Failed.
945 - * if If-None-Match is specified:
946 - * if If-None-Match is a "*" THEN 304
947 - * else if Etag is specified AND we get a match THEN 304
948 - * else if Weak Etag is specified AND we get a match THEN 304
949 - * else sent the original object
950 + * we check if the Etag on the cached file is in the list of Etags in
951 + * the If-None-Match field. The comparison must be a strong
952 + * comparison, so the Etag cannot be marked as weak. If the
953 + * comparision fails we return 412 Precondition Failed.
955 + * if If-None-Match is specified: if If-None-Match is a "*" THEN 304
956 + * else if Etag is specified AND we get a match THEN 304 else if Weak
957 + * Etag is specified AND we get a match THEN 304 else sent the
961 if (!strcmp(c->inm, "*")) {
962 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-None-Match: * specified, return 304");
963 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: * specified, return 304");
965 else if (etag && ap_proxy_liststr(c->inm, etag, NULL)) {
966 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-None-Match: specified and we got a strong match - return 304");
967 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: specified and we got a strong match - return 304");
969 else if (wetag && ap_proxy_liststr(c->inm, wetag, NULL)) {
970 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-None-Match specified, and we got a weak match - return 304");
971 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match specified, and we got a weak match - return 304");
977 - /* check If-Modified-Since
979 + * check If-Modified-Since
981 - * if If-Modified-Since is specified AND
982 - * Last-Modified is specified somewhere:
983 - * if last modification date is earlier than If-Modified-Since THEN 304
984 - * else send the original object
985 + * if If-Modified-Since is specified AND Last-Modified is specified
986 + * somewhere: if last modification date is earlier than
987 + * If-Modified-Since THEN 304 else send the original object
989 if (BAD_DATE != c->ims && BAD_DATE != c->lmod) {
990 if (c->ims >= c->lmod) {
991 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "If-Modified-Since specified and not modified, try return 304");
992 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Modified-Since specified and not modified, try return 304");
996 @@ -858,47 +873,43 @@
997 /* are we updating the cache file? */
999 ap_proxy_write_headers(c, c->resp_line, c->hdrs);
1000 - ap_proxy_send_fb(c->origfp, r, c, c->len, 1, IOBUFSIZE);
1001 + ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);
1002 ap_proxy_cache_tidy(c);
1005 ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
1007 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Use local copy, cached file hasn't changed");
1008 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use local copy, cached file hasn't changed");
1009 return HTTP_NOT_MODIFIED;
1013 /* No conditional - just send it cousin! */
1014 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Local copy modified, send it");
1015 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy modified, send it");
1016 r->status_line = strchr(c->resp_line, ' ') + 1;
1017 r->status = c->status;
1019 /* Prepare and send headers to client */
1020 - ap_overlap_tables(r->headers_out, c->hdrs, AP_OVERLAP_TABLES_SET);
1021 + ap_proxy_table_replace(r->headers_out, c->hdrs);
1022 /* make sure our X-Cache header does not stomp on a previous header */
1023 ap_table_mergen(r->headers_out, "X-Cache", c->xcache);
1025 /* content type is already set in the headers */
1026 r->content_type = ap_table_get(r->headers_out, "Content-Type");
1028 - /* cookies are special: they must not be merged (stupid browsers) */
1029 - ap_proxy_table_unmerge(r->pool, r->headers_out, "Set-Cookie");
1030 - ap_proxy_table_unmerge(r->pool, r->headers_out, "Set-Cookie2");
1032 ap_send_http_header(r);
1034 /* are we rewriting the cache file? */
1036 ap_proxy_write_headers(c, c->resp_line, c->hdrs);
1037 - ap_proxy_send_fb(c->origfp, r, c, c->len, r->header_only, IOBUFSIZE);
1038 + ap_proxy_send_fb(c->origfp, r, c, c->len, r->header_only, 0, IOBUFSIZE);
1039 ap_proxy_cache_tidy(c);
1044 if (!r->header_only) {
1045 - ap_proxy_send_fb(cachefp, r, NULL, c->len, 0, IOBUFSIZE);
1046 + ap_proxy_send_fb(cachefp, r, NULL, c->len, 0, 0, IOBUFSIZE);
1049 ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
1050 @@ -922,17 +933,17 @@
1051 * if last modified after if-modified-since then add
1052 * last modified date to request
1054 -int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
1055 +int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf * conf,
1058 - const char *datestr, *pragma_req = NULL, *pragma_cresp = NULL, *cc_req = NULL, *cc_cresp = NULL, *vary = NULL;
1059 + const char *datestr, *pragma_req = NULL, *pragma_cresp = NULL, *cc_req = NULL,
1065 void *sconf = r->server->module_config;
1066 proxy_server_conf *pconf =
1067 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
1068 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
1069 const char *agestr = NULL;
1072 @@ -989,7 +1000,7 @@
1076 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "No CacheRoot, so no caching. Declining.");
1077 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "No CacheRoot, so no caching. Declining.");
1081 @@ -1017,22 +1028,24 @@
1082 unlink(c->filename);
1085 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "no-store forbids caching. Declining.");
1086 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "no-store forbids caching. Declining.");
1090 /* if the cache file exists, open it */
1092 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Request for %s, pragma_req=%s, ims=%ld", url,
1093 - pragma_req, c->ims);
1094 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Request for %s, pragma_req=%s, ims=%ld", url,
1095 + (pragma_req == NULL) ? "(unset)" : pragma_req, c->ims);
1096 /* find out about whether the request can access the cache */
1097 if (c->filename != NULL && r->method_number == M_GET &&
1098 - strlen(url) < 1024 ) {
1099 + strlen(url) < 1024) {
1100 cachefp = ap_proxy_open_cachefile(r, c->filename);
1104 - /* if a cache file exists, try reading body and headers from cache file */
1106 + * if a cache file exists, try reading body and headers from cache file
1108 if (cachefp != NULL) {
1109 i = rdcache(r, cachefp, c);
1111 @@ -1040,7 +1053,7 @@
1112 "proxy: error reading cache file %s",
1115 - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
1116 + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r,
1117 "proxy: bad (short?) cache file: %s", c->filename);
1119 ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));
1120 @@ -1049,7 +1062,6 @@
1122 cc_cresp = ap_table_get(c->hdrs, "Cache-Control");
1123 pragma_cresp = ap_table_get(c->hdrs, "Pragma");
1124 - vary = ap_table_get(c->hdrs, "Vary");
1125 if ((agestr = ap_table_get(c->hdrs, "Age"))) {
1126 age_c = atoi(agestr);
1128 @@ -1065,7 +1077,8 @@
1130 /* FIXME: Shouldn't we check the URL somewhere? */
1132 - /* Check Content-Negotiation - Vary
1134 + * Check Content-Negotiation - Vary
1136 * At this point we need to make sure that the object we found in the cache
1137 * is the same object that would be delivered to the client, when the
1138 @@ -1092,8 +1105,10 @@
1142 - /* is this header in the request and the header in the cached
1143 - * request identical? If not, we give up and do a straight get */
1145 + * is this header in the request and the header in the cached
1146 + * request identical? If not, we give up and do a straight get
1148 h1 = ap_table_get(r->headers_in, name);
1149 h2 = ap_table_get(c->req_hdrs, name);
1151 @@ -1106,42 +1121,43 @@
1153 /* headers do not match, so Vary failed */
1155 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Vary header mismatch - object must be fetched from scratch. Declining.");
1156 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Vary header mismatch - object must be fetched from scratch. Declining.");
1163 - /* We now want to check if our cached data is still fresh. This depends
1165 + * We now want to check if our cached data is still fresh. This depends
1166 * on a few things, in this order:
1168 - * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache
1169 - * no-cache in either the request or the cached response means that
1170 - * we must revalidate the request unconditionally, overriding any
1171 - * expiration mechanism. It's equivalent to max-age=0,must-revalidate.
1173 - * - RFC2616 14.32 Pragma: no-cache
1174 - * This is treated the same as Cache-Control: no-cache.
1176 - * - RFC2616 14.9.3 Cache-Control: max-stale, must-revalidate, proxy-revalidate
1177 - * if the max-stale request header exists, modify the stale calculations
1178 - * below so that an object can be at most <max-stale> seconds stale before
1179 - * we request a revalidation, _UNLESS_ a must-revalidate or
1180 - * proxy-revalidate cached response header exists to stop us doing this.
1182 - * - RFC2616 14.9.3 Cache-Control: s-maxage
1183 - * the origin server specifies the maximum age an object can be before
1184 - * it is considered stale. This directive has the effect of proxy|must
1185 - * revalidate, which in turn means simple ignore any max-stale setting.
1187 - * - RFC2616 14.9.4 Cache-Control: max-age
1188 - * this header can appear in both requests and responses. If both are
1189 - * specified, the smaller of the two takes priority.
1191 - * - RFC2616 14.21 Expires:
1192 - * if this request header exists in the cached entity, and it's value is
1193 - * in the past, it has expired.
1194 + * - RFC2616 14.9.4 End to end reload, Cache-Control: no-cache no-cache in
1195 + * either the request or the cached response means that we must
1196 + * revalidate the request unconditionally, overriding any expiration
1197 + * mechanism. It's equivalent to max-age=0,must-revalidate.
1199 + * - RFC2616 14.32 Pragma: no-cache This is treated the same as
1200 + * Cache-Control: no-cache.
1202 + * - RFC2616 14.9.3 Cache-Control: max-stale, must-revalidate,
1203 + * proxy-revalidate if the max-stale request header exists, modify the
1204 + * stale calculations below so that an object can be at most <max-stale>
1205 + * seconds stale before we request a revalidation, _UNLESS_ a
1206 + * must-revalidate or proxy-revalidate cached response header exists to
1207 + * stop us doing this.
1209 + * - RFC2616 14.9.3 Cache-Control: s-maxage the origin server specifies the
1210 + * maximum age an object can be before it is considered stale. This
1211 + * directive has the effect of proxy|must revalidate, which in turn means
1212 + * simple ignore any max-stale setting.
1214 + * - RFC2616 14.9.4 Cache-Control: max-age this header can appear in both
1215 + * requests and responses. If both are specified, the smaller of the two
1218 + * - RFC2616 14.21 Expires: if this request header exists in the cached
1219 + * entity, and it's value is in the past, it has expired.
1223 @@ -1166,7 +1182,9 @@
1227 - /* if both maxage request and response, the smaller one takes priority */
1229 + * if both maxage request and response, the smaller one takes priority
1231 if (-1 == maxage_req)
1232 maxage = maxage_cresp;
1233 else if (-1 == maxage_cresp)
1234 @@ -1187,37 +1205,35 @@
1237 /* override maxstale if must-revalidate or proxy-revalidate */
1238 - if (maxstale && ( (cc_cresp && ap_proxy_liststr(cc_cresp, "must-revalidate", NULL)) || (cc_cresp && ap_proxy_liststr(cc_cresp, "proxy-revalidate", NULL)) ))
1239 + if (maxstale && ((cc_cresp && ap_proxy_liststr(cc_cresp, "must-revalidate", NULL)) || (cc_cresp && ap_proxy_liststr(cc_cresp, "proxy-revalidate", NULL))))
1243 if (cachefp != NULL &&
1245 /* handle no-cache */
1246 - !( (cc_req && ap_proxy_liststr(cc_req, "no-cache", NULL)) ||
1247 + !((cc_req && ap_proxy_liststr(cc_req, "no-cache", NULL)) ||
1248 (pragma_req && ap_proxy_liststr(pragma_req, "no-cache", NULL)) ||
1249 (cc_cresp && ap_proxy_liststr(cc_cresp, "no-cache", NULL)) ||
1250 - (pragma_cresp && ap_proxy_liststr(pragma_cresp, "no-cache", NULL)) ) &&
1251 + (pragma_cresp && ap_proxy_liststr(pragma_cresp, "no-cache", NULL))) &&
1253 /* handle expiration */
1254 - ( (-1 < smaxage && age < (smaxage - minfresh)) ||
1255 + ((-1 < smaxage && age < (smaxage - minfresh)) ||
1256 (-1 < maxage && age < (maxage + maxstale - minfresh)) ||
1257 - (c->expire != BAD_DATE && age < (c->expire - c->date + maxstale - minfresh)) )
1259 + (c->expire != BAD_DATE && age < (c->expire - c->date + maxstale - minfresh)))
1262 /* it's fresh darlings... */
1264 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Unexpired data available");
1265 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Unexpired data available");
1267 /* set age header on response */
1268 ap_table_set(c->hdrs, "Age",
1269 ap_psprintf(r->pool, "%lu", (unsigned long)age));
1271 /* add warning if maxstale overrode freshness calculation */
1272 - if (!( (-1 < smaxage && age < smaxage) ||
1273 + if (!((-1 < smaxage && age < smaxage) ||
1274 (-1 < maxage && age < maxage) ||
1275 - (c->expire != BAD_DATE && (c->expire - c->date) > age) )) {
1276 + (c->expire != BAD_DATE && (c->expire - c->date) > age))) {
1277 /* make sure we don't stomp on a previous warning */
1278 ap_table_merge(c->hdrs, "Warning", "110 Response is stale");
1280 @@ -1229,11 +1245,12 @@
1284 - /* at this point we have determined our cached data needs revalidation
1286 + * at this point we have determined our cached data needs revalidation
1287 * but first - we check 1 thing:
1289 - * RFC2616 14.9.4 - if "only-if-cached" specified, send a
1290 - * 504 Gateway Timeout - we're not allowed to revalidate the object
1291 + * RFC2616 14.9.4 - if "only-if-cached" specified, send a 504 Gateway
1292 + * Timeout - we're not allowed to revalidate the object
1294 if (ap_proxy_liststr(cc_req, "only-if-cached", NULL)) {
1296 @@ -1242,11 +1259,12 @@
1300 - /* If we already have cached data and a last-modified date, and it is
1301 - * not a head request, then add an If-Modified-Since.
1303 + * If we already have cached data and a last-modified date, and it is not
1304 + * a head request, then add an If-Modified-Since.
1306 - * If we also have an Etag, then the object must have come from
1307 - * an HTTP/1.1 server. Add an If-None-Match as well.
1308 + * If we also have an Etag, then the object must have come from an HTTP/1.1
1309 + * server. Add an If-None-Match as well.
1311 * See RFC2616 13.3.4
1313 @@ -1257,13 +1275,15 @@
1315 /* If-Modified-Since */
1316 if (c->lmod != BAD_DATE) {
1317 - /* use the later of the one from the request and the last-modified date
1318 - * from the cache */
1320 + * use the later of the one from the request and the
1321 + * last-modified date from the cache
1323 if (c->ims == BAD_DATE || c->ims < c->lmod) {
1326 if ((q = ap_table_get(c->hdrs, "Last-Modified")) != NULL)
1327 - ap_table_set(r->headers_in, "If-Modified-Since", (char *) q);
1328 + ap_table_set(r->headers_in, "If-Modified-Since", (char *)q);
1332 @@ -1277,7 +1297,7 @@
1336 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Local copy not present or expired. Declining.");
1337 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy not present or expired. Declining.");
1341 @@ -1304,10 +1324,10 @@
1343 const char *expire, *lmods, *dates, *clen;
1344 time_t expc, date, lmod, now;
1345 - char buff[17*7+1];
1346 + char buff[17 * 7 + 1];
1347 void *sconf = r->server->module_config;
1348 proxy_server_conf *conf =
1349 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
1350 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
1351 const char *cc_resp;
1354 @@ -1317,8 +1337,10 @@
1356 /* we've received the response from the origin server */
1358 - /* read expiry date; if a bad date, then leave it so the client can
1361 + * read expiry date; if a bad date, then leave it so the client can read
1364 expire = ap_table_get(resp_hdrs, "Expires");
1366 expc = ap_parseHTTPdate(expire);
1367 @@ -1341,44 +1363,55 @@
1369 * what responses should we not cache?
1371 - * At this point we decide based on the response headers whether it
1372 - * is appropriate _NOT_ to cache the data from the server. There are
1373 - * a whole lot of conditions that prevent us from caching this data.
1374 - * They are tested here one by one to be clear and unambiguous. */
1376 - /* RFC2616 13.4 we are allowed to cache 200, 203, 206, 300, 301 or 410
1377 - * We don't cache 206, because we don't (yet) cache partial responses.
1378 - * We include 304 Not Modified here too as this is the origin server
1379 - * telling us to serve the cached copy. */
1380 + * At this point we decide based on the response headers whether it is
1381 + * appropriate _NOT_ to cache the data from the server. There are a whole
1382 + * lot of conditions that prevent us from caching this data. They are
1383 + * tested here one by one to be clear and unambiguous.
1387 + * RFC2616 13.4 we are allowed to cache 200, 203, 206, 300, 301 or 410 We
1388 + * don't cache 206, because we don't (yet) cache partial responses. We
1389 + * include 304 Not Modified here too as this is the origin server telling
1390 + * us to serve the cached copy.
1392 if ((r->status != HTTP_OK && r->status != HTTP_NON_AUTHORITATIVE && r->status != HTTP_MULTIPLE_CHOICES && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||
1394 /* if a broken Expires header is present, don't cache it */
1395 (expire != NULL && expc == BAD_DATE) ||
1397 - /* if the server said 304 Not Modified but we have no cache file - pass
1398 - * this untouched to the user agent, it's not for us. */
1400 + * if the server said 304 Not Modified but we have no cache file - pass
1401 + * this untouched to the user agent, it's not for us.
1403 (r->status == HTTP_NOT_MODIFIED && (c == NULL || c->fp == NULL)) ||
1405 - /* 200 OK response from HTTP/1.0 and up without a Last-Modified header */
1407 + * 200 OK response from HTTP/1.0 and up without a Last-Modified header
1409 (r->status == HTTP_OK && lmods == NULL && is_HTTP1) ||
1414 - /* RFC2616 14.9.2 Cache-Control: no-store response indicating do not
1415 - * cache, or stop now if you are trying to cache it */
1417 + * RFC2616 14.9.2 Cache-Control: no-store response indicating do not
1418 + * cache, or stop now if you are trying to cache it
1420 ap_proxy_liststr(cc_resp, "no-store", NULL) ||
1422 - /* RFC2616 14.9.1 Cache-Control: private
1423 - * this object is marked for this user's eyes only. Behave as a tunnel. */
1425 + * RFC2616 14.9.1 Cache-Control: private this object is marked for this
1426 + * user's eyes only. Behave as a tunnel.
1428 ap_proxy_liststr(cc_resp, "private", NULL) ||
1430 - /* RFC2616 14.8 Authorisation:
1431 - * if authorisation is included in the request, we don't cache, but we
1432 - * can cache if the following exceptions are true:
1433 - * 1) If Cache-Control: s-maxage is included
1434 - * 2) If Cache-Control: must-revalidate is included
1435 - * 3) If Cache-Control: public is included
1437 + * RFC2616 14.8 Authorisation: if authorisation is included in the
1438 + * request, we don't cache, but we can cache if the following exceptions
1439 + * are true: 1) If Cache-Control: s-maxage is included 2) If
1440 + * Cache-Control: must-revalidate is included 3) If Cache-Control: public
1443 (ap_table_get(r->headers_in, "Authorization") != NULL
1445 @@ -1388,7 +1421,7 @@
1446 /* or we've been asked not to cache it above */
1449 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Response is not cacheable, unlinking %s", c->filename);
1450 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Response is not cacheable, unlinking %s", c->filename);
1452 /* close the file */
1453 if (c->fp != NULL) {
1454 @@ -1403,15 +1436,15 @@
1458 - /* It's safe to cache the response.
1460 + * It's safe to cache the response.
1462 - * We now want to update the cache file header information with
1463 - * the new date, last modified, expire and content length and write
1464 - * it away to our cache file. First, we determine these values from
1465 - * the response, using heuristics if appropriate.
1466 + * We now want to update the cache file header information with the new
1467 + * date, last modified, expire and content length and write it away to
1468 + * our cache file. First, we determine these values from the response,
1469 + * using heuristics if appropriate.
1471 - * In addition, we make HTTP/1.1 age calculations and write them away
1473 + * In addition, we make HTTP/1.1 age calculations and write them away too.
1476 /* Read the date. Generate one if one is not supplied */
1477 @@ -1430,7 +1463,7 @@
1479 dates = ap_gm_timestr_822(r->pool, now);
1480 ap_table_set(resp_hdrs, "Date", dates);
1481 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Added date header");
1482 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Added date header");
1485 /* set response_time for HTTP/1.1 age calculations */
1486 @@ -1442,16 +1475,17 @@
1490 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Last modified is in the future, replacing with now");
1491 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Last modified is in the future, replacing with now");
1493 /* if the response did not contain the header, then use the cached version */
1494 if (lmod == BAD_DATE && c->fp != NULL) {
1496 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Reusing cached last modified");
1497 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Reusing cached last modified");
1500 /* we now need to calculate the expire data for the object. */
1501 - if (expire == NULL && c->fp != NULL) { /* no expiry data sent in response */
1502 + if (expire == NULL && c->fp != NULL) { /* no expiry data sent in
1504 expire = ap_table_get(c->hdrs, "Expires");
1506 expc = ap_parseHTTPdate(expire);
1507 @@ -1463,18 +1497,18 @@
1509 * expire date = now + defaultexpire
1511 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Expiry date is %ld", (long)expc);
1512 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date is %ld", (long)expc);
1513 if (expc == BAD_DATE) {
1514 if (lmod != BAD_DATE) {
1515 - double x = (double) (date - lmod) * conf->cache.lmfactor;
1516 + double x = (double)(date - lmod) * conf->cache.lmfactor;
1517 double maxex = conf->cache.maxexpire;
1520 - expc = now + (int) x;
1521 + expc = now + (int)x;
1524 expc = now + conf->cache.defaultexpire;
1525 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Expiry date calculated %ld", (long)expc);
1526 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date calculated %ld", (long)expc);
1529 /* get the content-length header */
1530 @@ -1486,21 +1520,21 @@
1532 /* we have all the header information we need - write it to the cache file */
1534 - ap_proxy_sec2hex(date, buff + 17*(0));
1535 - buff[17*(1)-1] = ' ';
1536 - ap_proxy_sec2hex(lmod, buff + 17*(1));
1537 - buff[17*(2)-1] = ' ';
1538 - ap_proxy_sec2hex(expc, buff + 17*(2));
1539 - buff[17*(3)-1] = ' ';
1540 - ap_proxy_sec2hex(c->version, buff + 17*(3));
1541 - buff[17*(4)-1] = ' ';
1542 - ap_proxy_sec2hex(c->req_time, buff + 17*(4));
1543 - buff[17*(5)-1] = ' ';
1544 - ap_proxy_sec2hex(c->resp_time, buff + 17*(5));
1545 - buff[17*(6)-1] = ' ';
1546 - ap_proxy_sec2hex(c->len, buff + 17*(6));
1547 - buff[17*(7)-1] = '\n';
1548 - buff[17*(7)] = '\0';
1549 + ap_proxy_sec2hex(date, buff + 17 * (0));
1550 + buff[17 * (1) - 1] = ' ';
1551 + ap_proxy_sec2hex(lmod, buff + 17 * (1));
1552 + buff[17 * (2) - 1] = ' ';
1553 + ap_proxy_sec2hex(expc, buff + 17 * (2));
1554 + buff[17 * (3) - 1] = ' ';
1555 + ap_proxy_sec2hex(c->version, buff + 17 * (3));
1556 + buff[17 * (4) - 1] = ' ';
1557 + ap_proxy_sec2hex(c->req_time, buff + 17 * (4));
1558 + buff[17 * (5) - 1] = ' ';
1559 + ap_proxy_sec2hex(c->resp_time, buff + 17 * (5));
1560 + buff[17 * (6) - 1] = ' ';
1561 + ap_proxy_sec2hex(c->len, buff + 17 * (6));
1562 + buff[17 * (7) - 1] = '\n';
1563 + buff[17 * (7)] = '\0';
1565 /* Was the server response a 304 Not Modified?
1567 @@ -1570,7 +1604,7 @@
1568 c = ap_proxy_cache_error(c);
1571 - c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) +1+ L_tmpnam);
1572 + c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + 1 + L_tmpnam);
1573 strcpy(c->tempfile, conf->cache.root);
1574 strcat(c->tempfile, "/");
1576 @@ -1581,7 +1615,7 @@
1580 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Create temporary file %s", c->tempfile);
1581 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Create temporary file %s", c->tempfile);
1583 /* create the new file */
1584 c->fp = ap_proxy_create_cachefile(r, c->tempfile);
1585 @@ -1677,7 +1711,7 @@
1588 ap_proxy_sec2hex(c->len, buff);
1589 - curpos = lseek(ap_bfileno(c->fp, B_WR), 17*6, SEEK_SET);
1590 + curpos = lseek(ap_bfileno(c->fp, B_WR), 17 * 6, SEEK_SET);
1592 ap_log_error(APLOG_MARK, APLOG_ERR, s,
1593 "proxy: error seeking on cache file %s", c->tempfile);
1594 @@ -1695,7 +1729,7 @@
1598 - if (ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR)) == -1) {
1599 + if (ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR))== -1) {
1600 ap_log_error(APLOG_MARK, APLOG_ERR, s,
1601 "proxy: error closing cache file %s", c->tempfile);
1602 unlink(c->tempfile);
1603 @@ -1705,12 +1739,13 @@
1604 if (unlink(c->filename) == -1 && errno != ENOENT) {
1605 ap_log_error(APLOG_MARK, APLOG_ERR, s,
1606 "proxy: error deleting old cache file %s",
1609 + (void)unlink(c->tempfile);
1613 proxy_server_conf *conf =
1614 - (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
1615 + (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module);
1617 for (p = c->filename + strlen(conf->cache.root) + 1;;) {
1619 @@ -1732,10 +1767,11 @@
1621 #if defined(OS2) || defined(WIN32) || defined(NETWARE) || defined(MPE)
1622 /* Under OS/2 use rename. */
1623 - if (rename(c->tempfile, c->filename) == -1)
1624 + if (rename(c->tempfile, c->filename) == -1) {
1625 ap_log_error(APLOG_MARK, APLOG_ERR, s,
1626 "proxy: error renaming cache file %s to %s",
1627 c->tempfile, c->filename);
1628 + (void)unlink(c->tempfile);
1632 @@ -1743,11 +1779,9 @@
1633 ap_log_error(APLOG_MARK, APLOG_ERR, s,
1634 "proxy: error linking cache file %s to %s",
1635 c->tempfile, c->filename);
1638 if (unlink(c->tempfile) == -1)
1639 ap_log_error(APLOG_MARK, APLOG_ERR, s,
1640 "proxy: error deleting temp file %s", c->tempfile);
1645 Index: modules/proxy/proxy_connect.c
1646 ===================================================================
1647 RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_connect.c,v
1648 retrieving revision 1.48
1649 retrieving revision 1.49
1650 diff -u -b -u -r1.48 -r1.49
1651 --- modules/proxy/proxy_connect.c 13 Mar 2002 21:05:32 -0000 1.48
1652 +++ modules/proxy/proxy_connect.c 25 Mar 2002 09:21:58 -0000 1.49
1654 * FIXME: no check for r->assbackwards, whatever that is.
1658 -allowed_port(proxy_server_conf *conf, int port)
1659 +static int allowed_port(proxy_server_conf *conf, int port)
1662 - int *list = (int *) conf->allowed_connect_ports->elts;
1663 + int *list = (int *)conf->allowed_connect_ports->elts;
1665 - for(i = 0; i < conf->allowed_connect_ports->nelts; i++) {
1666 - if(port == list[i])
1667 + for (i = 0; i < conf->allowed_connect_ports->nelts; i++) {
1668 + if (port == list[i])
1674 void *sconf = r->server->module_config;
1675 proxy_server_conf *conf =
1676 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
1677 - struct noproxy_entry *npent = (struct noproxy_entry *)conf->noproxies->elts;
1678 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
1679 + struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
1681 memset(&server, '\0', sizeof(server));
1682 server.sin_family = AF_INET;
1683 @@ -162,15 +161,16 @@
1685 return HTTP_FORBIDDEN;
1687 - } else if(!allowed_port(conf, port))
1689 + else if (!allowed_port(conf, port))
1690 return HTTP_FORBIDDEN;
1693 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1694 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1695 "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
1698 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1699 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1700 "CONNECT to %s on port %d", host, port);
1705 #ifdef CHECK_FD_SETSIZE
1706 if (sock >= FD_SETSIZE) {
1707 - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
1708 + ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, NULL,
1709 "proxy_connect_handler: filedescriptor (%u) "
1710 "larger than FD_SETSIZE (%u) "
1711 "found, you probably need to rebuild Apache with a "
1712 @@ -215,61 +215,64 @@
1713 "Could not connect to remote machine:<br>", strerror(errno), NULL));
1716 - /* If we are connecting through a remote proxy, we need to pass
1717 - * the CONNECT request on to it.
1719 + * If we are connecting through a remote proxy, we need to pass the
1720 + * CONNECT request on to it.
1723 - /* FIXME: We should not be calling write() directly, but we currently
1724 - * have no alternative. Error checking ignored. Also, we force
1725 - * a HTTP/1.0 request to keep things simple.
1727 + * FIXME: We should not be calling write() directly, but we currently
1728 + * have no alternative. Error checking ignored. Also, we force a
1729 + * HTTP/1.0 request to keep things simple.
1731 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1732 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1733 "Sending the CONNECT request to the remote proxy");
1734 ap_snprintf(buffer, sizeof(buffer), "CONNECT %s HTTP/1.0" CRLF, r->uri);
1735 - send(sock, buffer, strlen(buffer),0);
1736 + send(sock, buffer, strlen(buffer), 0);
1737 ap_snprintf(buffer, sizeof(buffer),
1738 "Proxy-agent: %s" CRLF CRLF, ap_get_server_version());
1739 - send(sock, buffer, strlen(buffer),0);
1740 + send(sock, buffer, strlen(buffer), 0);
1743 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1744 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1745 "Returning 200 OK Status");
1746 ap_rvputs(r, "HTTP/1.0 200 Connection established" CRLF, NULL);
1747 ap_rvputs(r, "Proxy-agent: ", ap_get_server_version(), CRLF CRLF, NULL);
1748 ap_bflush(r->connection->client);
1751 - while (1) { /* Infinite loop until error (one side closes the connection) */
1752 + while (1) { /* Infinite loop until error (one side closes
1753 + * the connection) */
1756 FD_SET(ap_bfileno(r->connection->client, B_WR), &fds);
1758 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1759 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1760 "Going to sleep (select)");
1761 i = ap_select((ap_bfileno(r->connection->client, B_WR) > sock ?
1762 ap_bfileno(r->connection->client, B_WR) + 1 :
1763 sock + 1), &fds, NULL, NULL, NULL);
1764 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1765 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1766 "Woke from select(), i=%d", i);
1769 if (FD_ISSET(sock, &fds)) {
1770 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1771 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1773 - if ((nbytes = recv(sock, buffer, HUGE_STRING_LEN,0)) != 0) {
1774 + if ((nbytes = recv(sock, buffer, HUGE_STRING_LEN, 0)) != 0) {
1777 if (send(ap_bfileno(r->connection->client, B_WR), buffer,
1779 + nbytes, 0) == EOF)
1781 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO,
1782 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO,
1783 r->server, "Wrote %d bytes to client", nbytes);
1788 else if (FD_ISSET(ap_bfileno(r->connection->client, B_WR), &fds)) {
1789 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
1790 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
1791 "client->fd was set");
1792 if ((nbytes = recv(ap_bfileno(r->connection->client, B_WR),
1793 buffer, HUGE_STRING_LEN, 0)) != 0) {
1796 if (send(sock, buffer, nbytes, 0) == EOF)
1798 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO,
1799 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO,
1800 r->server, "Wrote %d bytes to server", nbytes);
1803 Index: modules/proxy/proxy_ftp.c
1804 ===================================================================
1805 RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_ftp.c,v
1806 retrieving revision 1.96
1807 retrieving revision 1.98
1808 diff -u -b -u -r1.96 -r1.98
1809 --- modules/proxy/proxy_ftp.c 13 Mar 2002 21:05:32 -0000 1.96
1810 +++ modules/proxy/proxy_ftp.c 7 Apr 2002 18:57:36 -0000 1.98
1814 char linebuff[100], buff[5];
1815 - char *mb = msgbuf,
1816 - *me = &msgbuf[msglen];
1817 + char *mb = msgbuf, *me = &msgbuf[msglen];
1819 len = ap_bgets(linebuff, sizeof linebuff, ctrl);
1823 status = 100 * linebuff[0] + 10 * linebuff[1] + linebuff[2] - 111 * '0';
1825 - mb = ap_cpystrn(mb, linebuff+4, me - mb);
1826 + mb = ap_cpystrn(mb, linebuff + 4, me - mb);
1828 if (linebuff[len - 1] != '\n')
1829 (void)ap_bskiplf(ctrl);
1831 if (linebuff[len - 1] != '\n') {
1832 (void)ap_bskiplf(ctrl);
1834 - mb = ap_cpystrn(mb, linebuff+4, me - mb);
1835 + mb = ap_cpystrn(mb, linebuff + 4, me - mb);
1836 } while (memcmp(linebuff, buff, 4) != 0);
1840 conn_rec *con = r->connection;
1842 char *dir, *path, *reldir, *site, *type = NULL;
1843 - char *basedir = ""; /* By default, path is relative to the $HOME dir */
1844 + char *basedir = ""; /* By default, path is relative to the $HOME
1847 /* create default sized buffers for the stuff below */
1848 buf_size = IOBUFSIZE;
1850 buf2 = ap_palloc(r->pool, buf_size);
1852 /* Save "scheme://site" prefix without password */
1853 - site = ap_unparse_uri_components(p, &r->parsed_uri, UNP_OMITPASSWORD|UNP_OMITPATHINFO);
1854 + site = ap_unparse_uri_components(p, &r->parsed_uri, UNP_OMITPASSWORD | UNP_OMITPATHINFO);
1855 /* ... and path without query args */
1856 - path = ap_unparse_uri_components(p, &r->parsed_uri, UNP_OMITSITEPART|UNP_OMITQUERY);
1857 + path = ap_unparse_uri_components(p, &r->parsed_uri, UNP_OMITSITEPART | UNP_OMITQUERY);
1859 /* If path began with /%2f, change the basedir */
1860 if (strncasecmp(path, "/%2f", 4) == 0) {
1862 /* Copy path, strip (all except the last) trailing slashes */
1863 /* (the trailing slash is needed for the dir component loop below) */
1864 path = dir = ap_pstrcat(r->pool, path, "/", NULL);
1865 - for (n = strlen(path); n > 1 && path[n-1] == '/' && path[n-2] == '/'; --n)
1867 + for (n = strlen(path); n > 1 && path[n - 1] == '/' && path[n - 2] == '/'; --n)
1868 + path[n - 1] = '\0';
1870 /* print "ftp://host/" */
1871 n = ap_snprintf(buf, buf_size, DOCTYPE_HTML_3_2
1873 "<base href=\"%s%s%s\"></head>\n"
1874 "<body><h2>Directory of "
1875 "<a href=\"/\">%s</a>/",
1876 - site, basedir, ap_escape_html(p,path),
1877 - site, basedir, ap_escape_uri(p,path),
1878 + site, basedir, ap_escape_html(p, path),
1879 + site, basedir, ap_escape_uri(p, path),
1881 total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);
1883 @@ -323,11 +323,10 @@
1884 total_bytes_sent += ap_proxy_bputs2("<a href=\"/%2f/\">%2f</a>/", con->client, c);
1887 - for (dir = path+1; (dir = strchr(dir, '/')) != NULL; )
1889 + for (dir = path + 1; (dir = strchr(dir, '/')) != NULL;) {
1891 - if ((reldir = strrchr(path+1, '/'))==NULL) {
1893 + if ((reldir = strrchr(path + 1, '/')) == NULL) {
1894 + reldir = path + 1;
1898 @@ -344,9 +343,10 @@
1900 /* If the caller has determined the current directory, and it differs */
1901 /* from what the client requested, then show the real name */
1902 - if (cwd == NULL || strncmp (cwd, path, strlen(cwd)) == 0) {
1903 + if (cwd == NULL || strncmp(cwd, path, strlen(cwd)) == 0) {
1904 ap_snprintf(buf, buf_size, "</h2>\n<hr /><pre>");
1908 ap_snprintf(buf, buf_size, "</h2>\n(%s)\n<hr /><pre>",
1909 ap_escape_html(p, cwd));
1911 @@ -365,13 +365,13 @@
1915 - if (buf[n-1] == '\n') /* strip trailing '\n' */
1916 + if (buf[n - 1] == '\n') /* strip trailing '\n' */
1918 - if (buf[n-1] == '\r') /* strip trailing '\r' if present */
1919 + if (buf[n - 1] == '\r') /* strip trailing '\r' if present */
1922 /* Handle unix-style symbolic link */
1923 - if (buf[0] == 'l' && (filename=strstr(buf, " -> ")) != NULL) {
1924 + if (buf[0] == 'l' && (filename = strstr(buf, " -> ")) != NULL) {
1925 char *link_ptr = filename;
1929 *(link_ptr++) = '\0';
1930 ap_snprintf(buf2, buf_size, "%s <a href=\"%s\">%s %s</a>\n",
1931 ap_escape_html(p, buf),
1932 - ap_escape_uri(p,filename),
1933 + ap_escape_uri(p, filename),
1934 ap_escape_html(p, filename),
1935 ap_escape_html(p, link_ptr));
1936 ap_cpystrn(buf, buf2, buf_size);
1937 @@ -416,13 +416,13 @@
1938 /* Special handling for '.' and '..': append slash to link */
1939 if (!strcmp(filename, ".") || !strcmp(filename, "..") || buf[0] == 'd') {
1940 ap_snprintf(buf2, buf_size, "%s <a href=\"%s/\">%s</a>\n",
1941 - ap_escape_html(p, buf), ap_escape_uri(p,filename),
1942 + ap_escape_html(p, buf), ap_escape_uri(p, filename),
1943 ap_escape_html(p, filename));
1946 ap_snprintf(buf2, buf_size, "%s <a href=\"%s\">%s</a>\n",
1947 ap_escape_html(p, buf),
1948 - ap_escape_uri(p,filename),
1949 + ap_escape_uri(p, filename),
1950 ap_escape_html(p, filename));
1952 ap_cpystrn(buf, buf2, buf_size);
1953 @@ -457,14 +457,15 @@
1954 * Note that we "invent" a realm name which consists of the
1955 * ftp://user@host part of the reqest (sans password -if supplied but invalid-)
1957 -static int ftp_unauthorized (request_rec *r, int log_it)
1958 +static int ftp_unauthorized(request_rec *r, int log_it)
1960 r->proxyreq = NOT_PROXY;
1961 - /* Log failed requests if they supplied a password
1962 - * (log username/password guessing attempts)
1964 + * Log failed requests if they supplied a password (log username/password
1965 + * guessing attempts)
1968 - ap_log_rerror(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, r,
1969 + ap_log_rerror(APLOG_MARK, APLOG_INFO | APLOG_NOERRNO, r,
1970 "proxy: missing or failed auth to %s",
1971 ap_unparse_uri_components(r->pool,
1972 &r->parsed_uri, UNP_OMITPATHINFO));
1974 ap_table_setn(r->err_headers_out, "WWW-Authenticate",
1975 ap_pstrcat(r->pool, "Basic realm=\"",
1976 ap_unparse_uri_components(r->pool, &r->parsed_uri,
1977 - UNP_OMITPASSWORD|UNP_OMITPATHINFO),
1978 + UNP_OMITPASSWORD | UNP_OMITPATHINFO),
1981 return HTTP_UNAUTHORIZED;
1983 /* Set ftp server to TYPE {A,I,E} before transfer of a directory or file */
1984 static int ftp_set_TYPE(request_rec *r, BUFF *ctrl, char xfer_type)
1986 - static char old_type[2] = { 'A', '\0' }; /* After logon, mode is ASCII */
1987 + static char old_type[2] = {'A', '\0'}; /* After logon, mode is ASCII */
1992 old_type[0] = xfer_type;
1993 ap_bvputs(ctrl, "TYPE ", old_type, CRLF, NULL);
1995 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: TYPE %s", old_type);
1996 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: TYPE %s", old_type);
1998 /* responses: 200, 421, 500, 501, 504, 530 */
1999 /* 200 Command okay. */
2001 /* 504 Command not implemented for that parameter. */
2002 /* 530 Not logged in. */
2003 rc = ftp_getrc(ctrl);
2004 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2005 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2006 if (rc == -1 || rc == 421) {
2008 ret = ap_proxyerror(r, HTTP_BAD_GATEWAY,
2009 @@ -515,14 +516,13 @@
2011 /* Allow not implemented */
2013 - /* ignore it silently */;
2014 + /* ignore it silently */ ;
2019 /* Common cleanup routine: close open BUFFers or sockets, and return an error */
2021 -ftp_cleanup_and_return(request_rec *r, BUFF *ctrl, BUFF *data, int csock, int dsock, int rc)
2022 +static int ftp_cleanup_and_return(request_rec *r, BUFF *ctrl, BUFF *data, int csock, int dsock, int rc)
2028 void *sconf = r->server->module_config;
2029 proxy_server_conf *conf =
2030 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
2031 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
2032 struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
2033 struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
2035 @@ -604,25 +604,27 @@
2036 while (*path == '/')
2039 - /* The "Authorization:" header must be checked first.
2040 - * We allow the user to "override" the URL-coded user [ & password ]
2041 - * in the Browsers' User&Password Dialog.
2042 - * NOTE that this is only marginally more secure than having the
2043 - * password travel in plain as part of the URL, because Basic Auth
2044 - * simply uuencodes the plain text password.
2045 - * But chances are still smaller that the URL is logged regularly.
2047 + * The "Authorization:" header must be checked first. We allow the user
2048 + * to "override" the URL-coded user [ & password ] in the Browsers'
2049 + * User&Password Dialog. NOTE that this is only marginally more secure
2050 + * than having the password travel in plain as part of the URL, because
2051 + * Basic Auth simply uuencodes the plain text password. But chances are
2052 + * still smaller that the URL is logged regularly.
2054 if ((password = ap_table_get(r->headers_in, "Authorization")) != NULL
2055 && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0
2056 && (password = ap_pbase64decode(r->pool, password))[0] != ':') {
2057 - /* Note that this allocation has to be made from r->connection->pool
2058 - * because it has the lifetime of the connection. The other allocations
2059 - * are temporary and can be tossed away any time.
2061 + * Note that this allocation has to be made from r->connection->pool
2062 + * because it has the lifetime of the connection. The other
2063 + * allocations are temporary and can be tossed away any time.
2065 - user = ap_getword_nulls (r->connection->pool, &password, ':');
2066 + user = ap_getword_nulls(r->connection->pool, &password, ':');
2067 r->connection->ap_auth_type = "Basic";
2068 r->connection->user = r->parsed_uri.user = user;
2069 - nocache = 1; /* This resource only accessible with username/password */
2070 + nocache = 1; /* This resource only accessible with
2071 + * username/password */
2073 else if ((user = r->parsed_uri.user) != NULL) {
2074 user = ap_pstrdup(p, user);
2079 - nocache = 1; /* This resource only accessible with username/password */
2080 + nocache = 1; /* This resource only accessible with
2081 + * username/password */
2086 "Connect to remote machine blocked");
2089 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: connect to %s:%d", host, port);
2090 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: connect to %s:%d", host, port);
2092 parms = strchr(path, ';');
2094 @@ -672,26 +675,26 @@
2095 #if !defined(TPF) && !defined(BEOS)
2096 if (conf->recv_buffer_size > 0
2097 && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
2098 - (const char *) &conf->recv_buffer_size, sizeof(int))
2099 + (const char *)&conf->recv_buffer_size, sizeof(int))
2101 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
2102 "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
2106 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
2107 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
2108 sizeof(one)) == -1) {
2109 #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
2110 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
2111 "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
2112 ap_pclosesocket(p, sock);
2113 return HTTP_INTERNAL_SERVER_ERROR;
2114 -#endif /*_OSD_POSIX*/
2115 +#endif /* _OSD_POSIX */
2118 #ifdef SINIX_D_RESOLVER_BUG
2120 - struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
2121 + struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
2123 for (; ip_addr->s_addr != 0; ++ip_addr) {
2124 memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
2126 /* shouldn't we implement telnet control options here? */
2128 #ifdef CHARSET_EBCDIC
2129 - ap_bsetflag(ctrl, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
2130 -#endif /*CHARSET_EBCDIC*/
2131 + ap_bsetflag(ctrl, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 1);
2132 +#endif /* CHARSET_EBCDIC */
2134 /* possible results: */
2135 /* 120 Service ready in nnn minutes. */
2137 /* 421 Service not available, closing control connection. */
2138 ap_hard_timeout("proxy ftp", r);
2139 i = ftp_getrc_msg(ctrl, resp, sizeof resp);
2140 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2141 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2142 if (i == -1 || i == 421) {
2143 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2144 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2145 @@ -743,17 +746,18 @@
2149 - /* RFC2068 states:
2150 - * 14.38 Retry-After
2152 + * RFC2068 states: 14.38 Retry-After
2154 * The Retry-After response-header field can be used with a 503 (Service
2155 - * Unavailable) response to indicate how long the service is expected to
2156 - * be unavailable to the requesting client. The value of this field can
2157 - * be either an HTTP-date or an integer number of seconds (in decimal)
2158 - * after the time of the response.
2159 - * Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
2160 + * Unavailable) response to indicate how long the service is expected
2161 + * to be unavailable to the requesting client. The value of this
2162 + * field can be either an HTTP-date or an integer number of seconds
2163 + * (in decimal) after the time of the response. Retry-After =
2164 + * "Retry-After" ":" ( HTTP-date | delta-seconds )
2166 - ap_set_header("Retry-After", ap_psprintf(p, "%u", 60*wait_mins);
2167 +/**INDENT** Error@756: Unbalanced parens */
2168 + ap_set_header("Retry-After", ap_psprintf(p, "%u", 60 * wait_mins);
2169 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2170 ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, resp));
2172 @@ -763,11 +767,11 @@
2173 ap_proxyerror(r, HTTP_BAD_GATEWAY, resp));
2176 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: connected.");
2177 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: connected.");
2179 ap_bvputs(ctrl, "USER ", user, CRLF, NULL);
2180 ap_bflush(ctrl); /* capture any errors */
2181 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: USER %s", user);
2182 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: USER %s", user);
2184 /* possible results; 230, 331, 332, 421, 500, 501, 530 */
2185 /* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */
2187 /* 501 Syntax error in parameters or arguments. */
2188 /* 530 Not logged in. */
2189 i = ftp_getrc(ctrl);
2190 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2191 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2192 if (i == -1 || i == 421) {
2193 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2194 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2198 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2199 - ftp_unauthorized (r, 1));
2200 + ftp_unauthorized(r, 1));
2202 if (i != 230 && i != 331) {
2203 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2204 @@ -798,11 +802,11 @@
2205 if (i == 331) { /* send password */
2206 if (password == NULL) {
2207 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2208 - ftp_unauthorized (r, 0));
2209 + ftp_unauthorized(r, 0));
2211 ap_bvputs(ctrl, "PASS ", password, CRLF, NULL);
2213 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PASS %s", password);
2214 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PASS %s", password);
2215 /* possible results 202, 230, 332, 421, 500, 501, 503, 530 */
2216 /* 230 User logged in, proceed. */
2217 /* 332 Need account for login. */
2219 /* 503 Bad sequence of commands. */
2220 /* 530 Not logged in. */
2221 i = ftp_getrc(ctrl);
2222 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2223 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2224 if (i == -1 || i == 421) {
2225 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2226 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2227 @@ -826,14 +830,15 @@
2228 /* @@@ questionable -- we might as well return a 403 Forbidden here */
2229 if (i == 530) /* log it: passwd guessing attempt? */
2230 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2231 - ftp_unauthorized (r, 1));
2232 + ftp_unauthorized(r, 1));
2233 if (i != 230 && i != 202)
2234 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2238 - /* Special handling for leading "%2f": this enforces a "cwd /"
2239 - * out of the $HOME directory which was the starting point after login
2241 + * Special handling for leading "%2f": this enforces a "cwd /" out of the
2242 + * $HOME directory which was the starting point after login
2244 if (strncasecmp(path, "%2f", 3) == 0) {
2248 ap_bputs("CWD /" CRLF, ctrl);
2250 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: CWD /");
2251 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: CWD /");
2253 /* possible results: 250, 421, 500, 501, 502, 530, 550 */
2254 /* 250 Requested file action okay, completed. */
2256 /* 530 Not logged in. */
2257 /* 550 Requested action not taken. */
2258 i = ftp_getrc(ctrl);
2259 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2260 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2261 if (i == -1 || i == 421)
2262 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2263 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2265 * this is what we must do if we don't know the OS type of the remote
2268 - for ( ; (strp = strchr(path, '/')) != NULL ; path = strp + 1) {
2269 + for (; (strp = strchr(path, '/')) != NULL; path = strp + 1) {
2275 ap_bvputs(ctrl, "CWD ", path, CRLF, NULL);
2277 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: CWD %s", path);
2278 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: CWD %s", path);
2281 /* responses: 250, 421, 500, 501, 502, 530, 550 */
2283 /* 530 Not logged in. */
2284 /* 550 Requested action not taken. */
2285 i = ftp_getrc(ctrl);
2286 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2287 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2288 if (i == -1 || i == 421)
2289 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2290 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2291 @@ -919,10 +924,11 @@
2293 if (parms != NULL && strncmp(parms, "type=", 5) == 0
2294 && ap_isalpha(parms[5])) {
2295 - /* "type=d" forces a dir listing.
2296 - * The other types (i|a|e) are directly used for the ftp TYPE command
2298 + * "type=d" forces a dir listing. The other types (i|a|e) are
2299 + * directly used for the ftp TYPE command
2301 - if ( ! (get_dirlisting = (parms[5] == 'd')))
2302 + if (!(get_dirlisting = (parms[5] == 'd')))
2303 xfer_type = ap_toupper(parms[5]);
2305 /* Check valid types, rather than ignoring invalid types silently: */
2307 #if !defined (TPF) && !defined(BEOS)
2308 if (conf->recv_buffer_size) {
2309 if (setsockopt(dsock, SOL_SOCKET, SO_RCVBUF,
2310 - (const char *) &conf->recv_buffer_size, sizeof(int)) == -1) {
2311 + (const char *)&conf->recv_buffer_size, sizeof(int)) == -1) {
2312 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
2313 "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
2317 ap_bputs("PASV" CRLF, ctrl);
2319 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PASV command issued");
2320 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PASV command issued");
2321 /* possible results: 227, 421, 500, 501, 502, 530 */
2322 /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
2323 /* 421 Service not available, closing control connection. */
2325 presult = atoi(pstr);
2326 if (*(pstr + strlen(pstr) + 1) == '=')
2327 pstr += strlen(pstr) + 2;
2330 - pstr = strtok(NULL, "("); /* separate address & port params */
2332 + pstr = strtok(NULL, "("); /* separate address & port
2335 pstr = strtok(NULL, ")");
2337 @@ -989,14 +995,14 @@
2339 presult = atoi(pasv);
2341 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", presult);
2342 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", presult);
2344 if (presult == 227 && pstr != NULL && (sscanf(pstr,
2345 "%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) {
2346 /* pardon the parens, but it makes gcc happy */
2347 paddr = (((((h3 << 8) + h2) << 8) + h1) << 8) + h0;
2348 pport = (p1 << 8) + p0;
2349 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
2350 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
2351 h3, h2, h1, h0, pport);
2352 data_addr.sin_family = AF_INET;
2353 data_addr.sin_addr.s_addr = htonl(paddr);
2354 @@ -1020,7 +1026,7 @@
2356 if (!pasvmode) { /* set up data connection */
2357 clen = sizeof(struct sockaddr_in);
2358 - if (getsockname(sock, (struct sockaddr *) &server, &clen) < 0) {
2359 + if (getsockname(sock, (struct sockaddr *)&server, &clen) < 0) {
2360 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2361 ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
2362 "proxy: error getting socket address"));
2363 @@ -1033,16 +1039,16 @@
2364 "proxy: error creating socket"));
2367 - if (setsockopt(dsock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
2368 + if (setsockopt(dsock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
2369 sizeof(one)) == -1) {
2370 #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
2371 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2372 ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
2373 "proxy: error setting reuseaddr option"));
2374 -#endif /*_OSD_POSIX*/
2375 +#endif /* _OSD_POSIX */
2378 - if (bind(dsock, (struct sockaddr *) &server,
2379 + if (bind(dsock, (struct sockaddr *)&server,
2380 sizeof(struct sockaddr_in)) == -1) {
2382 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2383 @@ -1068,16 +1074,16 @@
2385 ap_bvputs(ctrl, "SIZE ", path, CRLF, NULL);
2387 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: SIZE %s", path);
2388 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: SIZE %s", path);
2389 i = ftp_getrc_msg(ctrl, resp, sizeof resp);
2390 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d with response %s", i, resp);
2391 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d with response %s", i, resp);
2392 if (i != 500) { /* Size command not recognized */
2393 if (i == 550) { /* Not a regular file */
2394 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: SIZE shows this is a directory");
2395 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: SIZE shows this is a directory");
2397 ap_bvputs(ctrl, "CWD ", path, CRLF, NULL);
2399 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: CWD %s", path);
2400 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: CWD %s", path);
2402 /* possible results: 250, 421, 500, 501, 502, 530, 550 */
2403 /* 250 Requested file action okay, completed. */
2404 @@ -1088,7 +1094,7 @@
2405 /* 530 Not logged in. */
2406 /* 550 Requested action not taken. */
2407 i = ftp_getrc(ctrl);
2408 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2409 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2410 if (i == -1 || i == 421)
2411 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2412 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2413 @@ -1102,9 +1108,8 @@
2417 - else if (i == 213) { /* Size command ok */
2418 - for (j = 0; j < sizeof resp && ap_isdigit(resp[j]); j++)
2420 + else if (i == 213) {/* Size command ok */
2421 + for (j = 0; j < sizeof resp && ap_isdigit(resp[j]); j++);
2423 if (resp[0] != '\0')
2424 size = ap_pstrdup(p, resp);
2425 @@ -1115,7 +1120,7 @@
2426 #ifdef AUTODETECT_PWD
2427 ap_bvputs(ctrl, "PWD", CRLF, NULL);
2429 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PWD");
2430 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PWD");
2431 /* responses: 257, 500, 501, 502, 421, 550 */
2432 /* 257 "<directory-name>" <commentary> */
2433 /* 421 Service not available, closing control connection. */
2434 @@ -1124,7 +1129,7 @@
2435 /* 502 Command not implemented. */
2436 /* 550 Requested action not taken. */
2437 i = ftp_getrc_msg(ctrl, resp, sizeof resp);
2438 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PWD returned status %d", i);
2439 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PWD returned status %d", i);
2440 if (i == -1 || i == 421)
2441 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2442 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2443 @@ -1136,19 +1141,19 @@
2444 const char *dirp = resp;
2445 cwd = ap_getword_conf(r->pool, &dirp);
2447 -#endif /*AUTODETECT_PWD*/
2448 +#endif /* AUTODETECT_PWD */
2450 if (get_dirlisting) {
2452 ap_bvputs(ctrl, "LIST ", path, CRLF, NULL);
2454 ap_bputs("LIST -lag" CRLF, ctrl);
2455 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: LIST %s", (len == 0 ? "" : path));
2456 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: LIST %s", (len == 0 ? "" : path));
2459 ftp_set_TYPE(r, ctrl, xfer_type);
2460 ap_bvputs(ctrl, "RETR ", path, CRLF, NULL);
2461 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: RETR %s", path);
2462 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: RETR %s", path);
2465 /* RETR: 110, 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 530, 550
2466 @@ -1168,19 +1173,20 @@
2467 /* 530 Not logged in. */
2468 /* 550 Requested action not taken. */
2469 rc = ftp_getrc(ctrl);
2470 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2471 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2472 if (rc == -1 || rc == 421)
2473 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2474 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2475 "Error reading from remote server"));
2477 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: RETR failed, trying LIST instead");
2478 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: RETR failed, trying LIST instead");
2480 - ftp_set_TYPE(r, ctrl, 'A'); /* directories must be transferred in ASCII */
2481 + ftp_set_TYPE(r, ctrl, 'A'); /* directories must be transferred in
2484 ap_bvputs(ctrl, "CWD ", path, CRLF, NULL);
2486 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: CWD %s", path);
2487 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: CWD %s", path);
2488 /* possible results: 250, 421, 500, 501, 502, 530, 550 */
2489 /* 250 Requested file action okay, completed. */
2490 /* 421 Service not available, closing control connection. */
2491 @@ -1190,7 +1196,7 @@
2492 /* 530 Not logged in. */
2493 /* 550 Requested action not taken. */
2494 rc = ftp_getrc(ctrl);
2495 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2496 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2497 if (rc == -1 || rc == 421)
2498 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2499 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2500 @@ -1205,7 +1211,7 @@
2501 #ifdef AUTODETECT_PWD
2502 ap_bvputs(ctrl, "PWD", CRLF, NULL);
2504 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PWD");
2505 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PWD");
2506 /* responses: 257, 500, 501, 502, 421, 550 */
2507 /* 257 "<directory-name>" <commentary> */
2508 /* 421 Service not available, closing control connection. */
2509 @@ -1214,7 +1220,7 @@
2510 /* 502 Command not implemented. */
2511 /* 550 Requested action not taken. */
2512 i = ftp_getrc_msg(ctrl, resp, sizeof resp);
2513 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PWD returned status %d", i);
2514 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PWD returned status %d", i);
2515 if (i == -1 || i == 421)
2516 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2517 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2518 @@ -1226,13 +1232,13 @@
2519 const char *dirp = resp;
2520 cwd = ap_getword_conf(r->pool, &dirp);
2522 -#endif /*AUTODETECT_PWD*/
2523 +#endif /* AUTODETECT_PWD */
2525 ap_bputs("LIST -lag" CRLF, ctrl);
2527 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: LIST -lag");
2528 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: LIST -lag");
2529 rc = ftp_getrc(ctrl);
2530 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2531 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", rc);
2532 if (rc == -1 || rc == 421)
2533 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
2534 ap_proxyerror(r, HTTP_BAD_GATEWAY,
2535 @@ -1260,11 +1266,12 @@
2538 #ifdef CHARSET_EBCDIC
2539 - r->ebcdic.conv_out = 0; /* do not convert what we read from the ftp server */
2540 + r->ebcdic.conv_out = 0; /* do not convert what we read from the ftp
2543 if (r->content_type != NULL) {
2544 ap_table_setn(resp_hdrs, "Content-Type", r->content_type);
2545 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: Content-Type set to %s", r->content_type);
2546 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: Content-Type set to %s", r->content_type);
2549 ap_table_setn(resp_hdrs, "Content-Type", ap_default_type(r));
2550 @@ -1272,11 +1279,11 @@
2551 if (xfer_type != 'A' && size != NULL) {
2552 /* We "trust" the ftp server to really serve (size) bytes... */
2553 ap_table_set(resp_hdrs, "Content-Length", size);
2554 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: Content-Length set to %s", size);
2555 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: Content-Length set to %s", size);
2558 if (r->content_encoding != NULL && r->content_encoding[0] != '\0') {
2559 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: Content-Encoding set to %s", r->content_encoding);
2560 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: Content-Encoding set to %s", r->content_encoding);
2561 ap_table_setn(resp_hdrs, "Content-Encoding", r->content_encoding);
2564 @@ -1303,7 +1310,7 @@
2565 ap_hard_timeout("proxy ftp data connect", r);
2566 clen = sizeof(struct sockaddr_in);
2568 - csd = accept(dsock, (struct sockaddr *) &server, &clen);
2569 + csd = accept(dsock, (struct sockaddr *)&server, &clen);
2570 while (csd == -1 && errno == EINTR);
2572 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
2573 @@ -1335,7 +1342,7 @@
2574 ap_pstrcat(r->pool, "MISS from ",
2575 ap_get_server_name(r), NULL));
2576 /* The Content-Type of this response is the upstream one. */
2577 - r->content_type = ap_table_get (r->headers_out, "Content-Type");
2578 + r->content_type = ap_table_get(r->headers_out, "Content-Type");
2579 /* finally output the headers to the client */
2580 ap_send_http_header(r);
2582 @@ -1348,7 +1355,7 @@
2583 /* we need to set this for ap_proxy_send_fb()... */
2585 c->cache_completion = 0;
2586 - ap_proxy_send_fb(data, r, c, -1, 0, conf->io_buffer_size);
2587 + ap_proxy_send_fb(data, r, c, -1, 0, 0, conf->io_buffer_size);
2590 send_dir(data, r, c, cwd);
2591 @@ -1357,8 +1364,9 @@
2595 - /* We checked for 125||150||226||250 above.
2596 - * See if another rc is pending, and fetch it:
2598 + * We checked for 125||150||226||250 above. See if another rc is
2599 + * pending, and fetch it:
2601 if (rc == 125 || rc == 150)
2602 rc = ftp_getrc(ctrl);
2603 @@ -1372,7 +1380,7 @@
2607 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: ABOR");
2608 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: ABOR");
2609 /* responses: 225, 226, 421, 500, 501, 502 */
2610 /* 225 Data connection open; no transfer in progress. */
2611 /* 226 Closing data connection. */
2612 @@ -1381,7 +1389,7 @@
2613 /* 501 Syntax error in parameters or arguments. */
2614 /* 502 Command not implemented. */
2615 i = ftp_getrc(ctrl);
2616 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2617 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: returned status %d", i);
2621 @@ -1390,12 +1398,12 @@
2623 ap_bputs("QUIT" CRLF, ctrl);
2625 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: QUIT");
2626 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: QUIT");
2627 /* responses: 221, 500 */
2628 /* 221 Service closing control connection. */
2629 /* 500 Syntax error, command unrecognized. */
2630 i = ftp_getrc(ctrl);
2631 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: QUIT: status %d", i);
2632 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: QUIT: status %d", i);
2636 Index: modules/proxy/proxy_http.c
2637 ===================================================================
2638 RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_http.c,v
2639 retrieving revision 1.88
2640 retrieving revision 1.95
2641 diff -u -b -u -r1.88 -r1.95
2642 --- modules/proxy/proxy_http.c 21 Mar 2002 11:38:03 -0000 1.88
2643 +++ modules/proxy/proxy_http.c 17 Apr 2002 16:04:32 -0000 1.95
2648 - /* do syntatic check.
2649 - * We break the URL into host, port, path, search
2651 + * do syntatic check. We break the URL into host, port, path, search
2654 err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
2656 return HTTP_BAD_REQUEST;
2658 /* now parse path/search args, according to rfc1738 */
2659 - /* N.B. if this isn't a true proxy request, then the URL _path_
2660 - * has already been decoded. True proxy requests have r->uri
2661 - * == r->unparsed_uri, and no others have that property.
2663 + * N.B. if this isn't a true proxy request, then the URL _path_ has
2664 + * already been decoded. True proxy requests have r->uri ==
2665 + * r->unparsed_uri, and no others have that property.
2667 if (r->uri == r->unparsed_uri) {
2668 search = strchr(url, '?');
2669 @@ -163,18 +164,21 @@
2674 char *destportstr = NULL;
2675 const char *urlptr = NULL;
2676 const char *datestr, *urlstr;
2677 + const char *content_length;
2679 void *sconf = r->server->module_config;
2680 proxy_server_conf *conf =
2681 - (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
2682 + (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
2683 struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
2684 struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
2687 - if (conf->cache.root == NULL) nocache = 1;
2688 + if (conf->cache.root == NULL)
2691 memset(&server, '\0', sizeof(server));
2692 server.sin_family = AF_INET;
2697 - /* we have worked out who exactly we are going to connect to, now
2698 - * make that connection...
2700 + * we have worked out who exactly we are going to connect to, now make
2701 + * that connection...
2703 sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
2706 #if !defined(TPF) && !defined(BEOS)
2707 if (conf->recv_buffer_size) {
2708 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
2709 - (const char *) &conf->recv_buffer_size, sizeof(int))
2710 + (const char *)&conf->recv_buffer_size, sizeof(int))
2712 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
2713 "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
2716 #ifdef SINIX_D_RESOLVER_BUG
2718 - struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
2719 + struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
2721 for (; ip_addr->s_addr != 0; ++ip_addr) {
2722 memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
2723 @@ -287,16 +292,17 @@
2724 /* record request_time for HTTP/1.1 age calculation */
2725 c->req_time = time(NULL);
2727 - /* build upstream-request headers by stripping r->headers_in from
2728 - * connection specific headers.
2729 - * We must not remove the Connection: header from r->headers_in,
2730 - * we still have to react to Connection: close
2732 + * build upstream-request headers by stripping r->headers_in from
2733 + * connection specific headers. We must not remove the Connection: header
2734 + * from r->headers_in, we still have to react to Connection: close
2736 req_hdrs = ap_copy_table(r->pool, r->headers_in);
2737 ap_proxy_clear_connection(r->pool, req_hdrs);
2739 - /* At this point, we start sending the HTTP/1.1 request to the
2740 - * remote server (proxy or otherwise).
2742 + * At this point, we start sending the HTTP/1.1 request to the remote
2743 + * server (proxy or otherwise).
2745 f = ap_bcreate(p, B_RDWR | B_SOCKET);
2746 ap_bpushfd(f, sock, sock);
2747 @@ -313,12 +319,14 @@
2748 if (conf->viaopt == via_block) {
2749 /* Block all outgoing Via: headers */
2750 ap_table_unset(req_hdrs, "Via");
2751 - } else if (conf->viaopt != via_off) {
2753 + else if (conf->viaopt != via_off) {
2754 /* Create a "Via:" request header entry and merge it */
2755 i = ap_get_server_port(r);
2756 - if (ap_is_default_port(i,r)) {
2757 - strcpy(portstr,"");
2759 + if (ap_is_default_port(i, r)) {
2760 + strcpy(portstr, "");
2763 ap_snprintf(portstr, sizeof portstr, ":%d", i);
2765 /* Generate outgoing Via: header with/without server comment: */
2766 @@ -336,20 +344,23 @@
2770 - /* Add X-Forwarded-For: so that the upstream has a chance to
2771 - determine, where the original request came from. */
2773 + * Add X-Forwarded-For: so that the upstream has a chance to determine,
2774 + * where the original request came from.
2776 ap_table_mergen(req_hdrs, "X-Forwarded-For", r->connection->remote_ip);
2778 /* we don't yet support keepalives - but we will soon, I promise! */
2779 ap_table_set(req_hdrs, "Connection", "close");
2781 reqhdrs_arr = ap_table_elts(req_hdrs);
2782 - reqhdrs_elts = (table_entry *) reqhdrs_arr->elts;
2783 + reqhdrs_elts = (table_entry *)reqhdrs_arr->elts;
2784 for (i = 0; i < reqhdrs_arr->nelts; i++) {
2785 if (reqhdrs_elts[i].key == NULL || reqhdrs_elts[i].val == NULL
2787 - /* Clear out hop-by-hop request headers not to send:
2788 - * RFC2616 13.5.1 says we should strip these headers:
2790 + * Clear out hop-by-hop request headers not to send: RFC2616 13.5.1
2791 + * says we should strip these headers:
2793 || !strcasecmp(reqhdrs_elts[i].key, "Host") /* Already sent */
2794 || !strcasecmp(reqhdrs_elts[i].key, "Keep-Alive")
2795 @@ -357,15 +368,15 @@
2796 || !strcasecmp(reqhdrs_elts[i].key, "Trailer")
2797 || !strcasecmp(reqhdrs_elts[i].key, "Transfer-Encoding")
2798 || !strcasecmp(reqhdrs_elts[i].key, "Upgrade")
2800 - /* XXX: @@@ FIXME: "Proxy-Authorization" should *only* be
2801 - * suppressed if THIS server requested the authentication,
2802 - * not when a frontend proxy requested it!
2804 + * XXX: @@@ FIXME: "Proxy-Authorization" should *only* be suppressed
2805 + * if THIS server requested the authentication, not when a frontend
2806 + * proxy requested it!
2808 - * The solution to this problem is probably to strip out
2809 - * the Proxy-Authorisation header in the authorisation
2810 - * code itself, not here. This saves us having to signal
2811 - * somehow whether this request was authenticated or not.
2812 + * The solution to this problem is probably to strip out the
2813 + * Proxy-Authorisation header in the authorisation code itself, not
2814 + * here. This saves us having to signal somehow whether this request
2815 + * was authenticated or not.
2817 || !strcasecmp(reqhdrs_elts[i].key, "Proxy-Authorization"))
2819 @@ -377,14 +388,17 @@
2821 /* send the request data, if any. */
2822 if (ap_should_client_block(r)) {
2823 - while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0)
2824 + while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) {
2825 + ap_reset_timeout(r);
2826 ap_bwrite(f, buffer, i);
2833 - /* Right - now it's time to listen for a response.
2835 + * Right - now it's time to listen for a response.
2837 ap_hard_timeout("proxy receive", r);
2839 @@ -397,16 +411,17 @@
2840 proxyhost ? proxyhost : desthost, len);
2841 return ap_proxyerror(r, HTTP_BAD_GATEWAY,
2842 "Error reading from remote server");
2843 - } else if (len == 0) {
2845 + else if (len == 0) {
2848 return ap_proxyerror(r, HTTP_BAD_GATEWAY,
2849 "Document contains no data");
2852 - /* Is it an HTTP/1 response?
2853 - * Do some sanity checks on the response.
2854 - * (This is buggy if we ever see an HTTP/1.10)
2856 + * Is it an HTTP/1 response? Do some sanity checks on the response. (This
2857 + * is buggy if we ever see an HTTP/1.10)
2859 if (ap_checkmask(buffer, "HTTP/#.# ###*")) {
2863 resp_hdrs = ap_proxy_read_headers(r, buffer, HUGE_STRING_LEN, f);
2864 if (resp_hdrs == NULL) {
2865 - ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, r->server,
2866 + ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,
2867 "proxy: Bad HTTP/%d.%d header returned by %s (%s)",
2868 major, minor, r->uri, r->method);
2869 resp_hdrs = ap_make_table(p, 20);
2870 @@ -447,9 +462,10 @@
2871 if (conf->viaopt != via_off && conf->viaopt != via_block) {
2872 /* Create a "Via:" response header entry and merge it */
2873 i = ap_get_server_port(r);
2874 - if (ap_is_default_port(i,r)) {
2875 - strcpy(portstr,"");
2877 + if (ap_is_default_port(i, r)) {
2878 + strcpy(portstr, "");
2881 ap_snprintf(portstr, sizeof portstr, ":%d", i);
2883 ap_table_mergen((table *)resp_hdrs, "Via",
2884 @@ -464,11 +480,21 @@
2888 - /* strip hop-by-hop headers defined by Connection */
2889 + /* is this content chunked? */
2890 + chunked = ap_find_last_token(r->pool,
2891 + ap_table_get(resp_hdrs, "Transfer-Encoding"),
2894 + /* strip hop-by-hop headers defined by Connection and RFC2616 */
2895 ap_proxy_clear_connection(p, resp_hdrs);
2897 + content_length = ap_table_get(resp_hdrs, "Content-Length");
2898 + if (content_length != NULL)
2899 + c->len = strtol(content_length, NULL, 10);
2901 /* Now add out bound headers set by other modules */
2902 resp_hdrs = ap_overlay_tables(r->pool, r->err_headers_out, resp_hdrs);
2906 /* an http/0.9 response */
2908 @@ -482,10 +508,11 @@
2912 - * HTTP/1.1 requires us to accept 3 types of dates, but only generate
2914 + * HTTP/1.1 requires us to accept 3 types of dates, but only generate one
2917 - /* we SET the dates here, obliterating possible multiple dates, as only
2919 + * we SET the dates here, obliterating possible multiple dates, as only
2920 * one of each date makes sense in each response.
2922 if ((datestr = ap_table_get(resp_hdrs, "Date")) != NULL)
2924 if ((urlstr = ap_table_get(resp_hdrs, "URI")) != NULL)
2925 ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, urlstr));
2926 if ((urlstr = ap_table_get(resp_hdrs, "Content-Location")) != NULL)
2927 - ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r , urlstr));
2928 + ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));
2930 /* check if NoCache directive on this host */
2936 - /* update the cache file, possibly even fulfilling the request if
2937 - * it turns out a conditional allowed us to serve the object from the
2939 + * update the cache file, possibly even fulfilling the request if it
2940 + * turns out a conditional allowed us to serve the object from the
2943 i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
2944 @@ -530,20 +558,22 @@
2947 /* Setup the headers for our client from upstreams response-headers */
2948 - ap_overlap_tables(r->headers_out, resp_hdrs, AP_OVERLAP_TABLES_SET);
2949 + ap_proxy_table_replace(r->headers_out, resp_hdrs);
2950 /* Add X-Cache header - be careful not to obliterate any upstream headers */
2951 ap_table_mergen(r->headers_out, "X-Cache",
2952 ap_pstrcat(r->pool, "MISS from ",
2953 ap_get_server_name(r), NULL));
2954 /* The Content-Type of this response is the upstream one. */
2955 - r->content_type = ap_table_get (r->headers_out, "Content-Type");
2956 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "Content-Type: %s", r->content_type);
2957 + r->content_type = ap_table_get(r->headers_out, "Content-Type");
2958 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Content-Type: %s", r->content_type);
2960 /* finally output the headers to the client */
2961 ap_send_http_header(r);
2963 - /* Is it an HTTP/0.9 respose? If so, send the extra data we read
2964 - from upstream as the start of the reponse to client */
2966 + * Is it an HTTP/0.9 respose? If so, send the extra data we read from
2967 + * upstream as the start of the reponse to client
2970 ap_hard_timeout("proxy send assbackward", r);
2972 @@ -558,11 +588,13 @@
2975 #ifdef CHARSET_EBCDIC
2976 - /* What we read/write after the header should not be modified
2977 - * (i.e., the cache copy is ASCII, not EBCDIC, even for text/html)
2979 + * What we read/write after the header should not be modified (i.e., the
2980 + * cache copy is ASCII, not EBCDIC, even for text/html)
2982 - ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
2983 - ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
2984 + r->ebcdic.conv_in = r->ebcdic.conv_out = 0;
2985 + ap_bsetflag(f, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 0);
2986 + ap_bsetflag(r->connection->client, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 0);
2991 * content length is not known. We need to make 100% sure c->len is always
2992 * set correctly before we get here to correctly do keepalive.
2994 - ap_proxy_send_fb(f, r, c, c->len, 0, conf->io_buffer_size);
2995 + ap_proxy_send_fb(f, r, c, c->len, 0, chunked, conf->io_buffer_size);
2998 /* ap_proxy_send_fb() closes the socket f for us */
2999 Index: modules/proxy/proxy_util.c
3000 ===================================================================
3001 RCS file: /home/cvs/apache-1.3/src/modules/proxy/proxy_util.c,v
3002 retrieving revision 1.109
3003 retrieving revision 1.119
3004 diff -u -b -u -r1.109 -r1.119
3005 --- modules/proxy/proxy_util.c 21 Mar 2002 11:38:03 -0000 1.109
3006 +++ modules/proxy/proxy_util.c 15 Apr 2002 09:41:22 -0000 1.119
3008 /* already called in the knowledge that the characters are hex digits */
3009 int ap_proxy_hex2c(const char *x)
3014 #ifndef CHARSET_EBCDIC
3022 i += ch - ('a' - 10);
3024 -#else /*CHARSET_EBCDIC*/
3025 - return (1 == sscanf(x, "%2x", &i)) ? os_toebcdic[i&0xFF] : 0;
3026 -#endif /*CHARSET_EBCDIC*/
3027 +#else /* CHARSET_EBCDIC */
3028 + return (1 == sscanf(x, "%2x", &i)) ? os_toebcdic[i & 0xFF] : 0;
3029 +#endif /* CHARSET_EBCDIC */
3032 void ap_proxy_c2hex(int ch, char *x)
3033 @@ -115,14 +116,14 @@
3034 x[2] = ('A' - 10) + i;
3037 -#else /*CHARSET_EBCDIC*/
3038 - static const char ntoa[] = { "0123456789ABCDEF" };
3039 +#else /* CHARSET_EBCDIC */
3040 + static const char ntoa[] = {"0123456789ABCDEF"};
3041 ch = os_toascii[ch & 0xFF];
3043 - x[1] = ntoa[(ch>>4)&0x0F];
3044 - x[2] = ntoa[ch&0x0F];
3045 + x[1] = ntoa[(ch >> 4) & 0x0F];
3046 + x[2] = ntoa[ch & 0x0F];
3048 -#endif /*CHARSET_EBCDIC*/
3049 +#endif /* CHARSET_EBCDIC */
3054 /* if (i == 0) the no port was given; keep default */
3055 if (strp[i] != '\0') {
3056 return "Bad port number in URL";
3057 - } else if (i > 0) {
3062 return "Port number in URL > 65535";
3067 -static const char * const lwday[7] =
3068 +static const char *const lwday[7] =
3069 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
3072 @@ -365,63 +367,6 @@
3076 -/* NOTE: This routine is taken from http_protocol::getline()
3077 - * because the old code found in the proxy module was too
3078 - * difficult to understand and maintain.
3080 -/* Get a line of protocol input, including any continuation lines
3081 - * caused by MIME folding (or broken clients) if fold != 0, and place it
3082 - * in the buffer s, of size n bytes, without the ending newline.
3084 - * Returns -1 on error, or the length of s.
3086 - * Note: Because bgets uses 1 char for newline and 1 char for NUL,
3087 - * the most we can get is (n - 2) actual characters if it
3088 - * was ended by a newline, or (n - 1) characters if the line
3089 - * length exceeded (n - 1). So, if the result == (n - 1),
3090 - * then the actual input line exceeded the buffer length,
3091 - * and it would be a good idea for the caller to puke 400 or 414.
3093 -static int proxy_getline(char *s, int n, BUFF *in, int fold)
3102 - retval = ap_bgets(pos, n, in); /* retval == -1 if error, 0 if EOF */
3105 - return ((retval < 0) && (total == 0)) ? -1 : total;
3107 - /* retval is the number of characters read, not including NUL */
3109 - n -= retval; /* Keep track of how much of s is full */
3110 - pos += (retval - 1); /* and where s ends */
3111 - total += retval; /* and how long s has become */
3113 - if (*pos == '\n') { /* Did we get a full line of input? */
3119 - return total; /* if not, input line exceeded buffer size */
3121 - /* Continue appending if line folding is desired and
3122 - * the last line was not empty and we have room in the buffer and
3123 - * the next line begins with a continuation character.
3125 - } while (fold && (retval != 1) && (n > 1)
3126 - && (ap_blookc(&next, in) == 1)
3127 - && ((next == ' ') || (next == '\t')));
3134 * Reads headers from a buffer and returns an array of headers.
3135 * Returns NULL on file error
3136 @@ -445,37 +390,40 @@
3137 * Read header lines until we get the empty separator line, a read error,
3138 * the connection closes (EOF), or we timeout.
3140 - while ((len = proxy_getline(buffer, size, f, 1)) > 0) {
3141 + while ((len = ap_getline(buffer, size, f, 1)) > 0) {
3143 if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
3145 - /* Buggy MS IIS servers sometimes return invalid headers
3146 - * (an extra "HTTP/1.0 200, OK" line sprinkled in between
3147 - * the usual MIME headers). Try to deal with it in a sensible
3148 - * way, but log the fact.
3149 - * XXX: The mask check is buggy if we ever see an HTTP/1.10 */
3151 + * Buggy MS IIS servers sometimes return invalid headers (an
3152 + * extra "HTTP/1.0 200, OK" line sprinkled in between the usual
3153 + * MIME headers). Try to deal with it in a sensible way, but log
3154 + * the fact. XXX: The mask check is buggy if we ever see an
3158 if (!ap_checkmask(buffer, "HTTP/#.# ###*")) {
3159 /* Nope, it wasn't even an extra HTTP header. Give up. */
3163 - ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, r->server,
3164 - "proxy: Ignoring duplicate HTTP header "
3165 - "returned by %s (%s)", r->uri, r->method);
3166 + ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,
3167 + "proxy: Ignoring duplicate HTTP status line "
3168 + "returned by buggy server %s (%s)", r->uri, r->method);
3174 - /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
3176 + * XXX: RFC2068 defines only SP and HT as whitespace, this test is
3177 * wrong... and so are many others probably.
3179 while (ap_isspace(*value))
3180 ++value; /* Skip to start of value */
3182 /* should strip trailing whitespace as well */
3183 - for (end = &value[strlen(value)-1]; end > value && ap_isspace(*end); --end)
3184 + for (end = &value[strlen(value) - 1]; end > value && ap_isspace(*end); --end)
3187 /* make sure we add so as not to destroy duplicated headers */
3190 /* the header was too long; at the least we should skip extra data */
3191 if (len >= size - 1) {
3192 - while ((len = proxy_getline(field, MAX_STRING_LEN, f, 1))
3193 + while ((len = ap_getline(field, MAX_STRING_LEN, f, 1))
3194 >= MAX_STRING_LEN - 1) {
3195 /* soak up the extra data */
3197 @@ -494,23 +442,28 @@
3201 -/* read data from f, write it to:
3202 +/* read data from (socket BUFF*) f, write it to:
3203 * - c->fp, if it is open
3204 * - r->connection->client, if nowrite == 0
3207 -long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite, size_t recv_buffer_size)
3208 +long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite, int chunked, size_t recv_buffer_size)
3211 + int ok, end_of_chunk;
3214 + size_t remaining = 0;
3215 long total_bytes_rcvd;
3216 - register int n, o, w;
3217 + register int n = 0, o, w;
3218 conn_rec *con = r->connection;
3219 - int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */
3220 + int alternate_timeouts = 1; /* 1 if we alternate between soft & hard
3223 /* allocate a buffer to store the bytes in */
3224 - /* make sure it is at least IOBUFSIZE, as recv_buffer_size may be zero for system default */
3226 + * make sure it is at least IOBUFSIZE, as recv_buffer_size may be zero
3227 + * for system default
3229 buf_size = MAX(recv_buffer_size, IOBUFSIZE);
3230 buf = ap_palloc(r->pool, buf_size);
3232 @@ -520,15 +473,14 @@
3234 #ifdef CHARSET_EBCDIC
3235 /* The cache copy is ASCII, not EBCDIC, even for text/html) */
3236 - ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
3237 - if (c != NULL && c->fp != NULL)
3238 - ap_bsetflag(c->fp, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
3239 - ap_bsetflag(con->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
3240 + ap_bsetflag(f, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 0);
3241 + ap_bsetflag(con->client, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 0);
3244 - /* Since we are reading from one buffer and writing to another,
3245 - * it is unsafe to do a soft_timeout here, at least until the proxy
3246 - * has its own timeout handler which can set both buffers to EOUT.
3248 + * Since we are reading from one buffer and writing to another, it is
3249 + * unsafe to do a soft_timeout here, at least until the proxy has its own
3250 + * timeout handler which can set both buffers to EOUT.
3254 @@ -538,12 +490,13 @@
3255 ap_hard_timeout("proxy send body", r);
3256 alternate_timeouts = 0;
3258 - /* CHECKME! Since hard_timeout won't work in unix on sends with partial
3259 - * cache completion, we have to alternate between hard_timeout
3260 - * for reads, and soft_timeout for send. This is because we need
3261 - * to get a return from ap_bwrite to be able to continue caching.
3262 - * BUT, if we *can't* continue anyway, just use hard_timeout.
3263 - * (Also, if no cache file is written, use hard timeouts)
3265 + * CHECKME! Since hard_timeout won't work in unix on sends with partial
3266 + * cache completion, we have to alternate between hard_timeout for reads,
3267 + * and soft_timeout for send. This is because we need to get a return
3268 + * from ap_bwrite to be able to continue caching. BUT, if we *can't*
3269 + * continue anyway, just use hard_timeout. (Also, if no cache file is
3270 + * written, use hard timeouts)
3273 if (c == NULL || c->len <= 0 || c->cache_completion == 1.0) {
3274 @@ -552,22 +505,92 @@
3278 - /* Loop and ap_bread() while we can successfully read and write,
3279 - * or (after the client aborted) while we can successfully
3280 - * read and finish the configured cache_completion.
3282 + * Loop and ap_bread() while we can successfully read and write, or
3283 + * (after the client aborted) while we can successfully read and finish
3284 + * the configured cache_completion.
3286 - for (ok = 1; ok; ) {
3287 + for (end_of_chunk = ok = 1; ok;) {
3288 if (alternate_timeouts)
3289 ap_hard_timeout("proxy recv body from upstream server", r);
3291 - /* Read block from server */
3293 + /* read a chunked block */
3295 + long chunk_start = 0;
3298 + /* start of a new chunk */
3299 + if (end_of_chunk) {
3301 + /* get the chunk size from the stream */
3302 + chunk_start = ap_getline(buf, buf_size, f, 0);
3303 + if ((chunk_start <= 0) || ((size_t)chunk_start + 1 >= buf_size) || !ap_isxdigit(*buf)) {
3306 + /* parse the chunk size */
3308 + remaining = ap_get_chunk_size(buf);
3309 + if (remaining == 0) { /* Last chunk indicated, get footers */
3310 + /* as we are a proxy, we discard the footers, as the headers
3311 + * have already been sent at this point.
3313 + if (NULL == ap_proxy_read_headers(r, buf, buf_size, f)) {
3320 + /* read the chunk */
3321 + if (remaining > 0) {
3322 + n = ap_bread(f, buf, MIN((int)buf_size, (int)remaining));
3325 + end_of_chunk = (remaining == 0);
3329 + /* soak up trailing CRLF */
3330 + if (end_of_chunk) {
3331 + int ch; /* int because it may hold an EOF */
3333 + * For EBCDIC, the proxy has configured the BUFF layer to
3334 + * transparently pass the ascii characters thru (also writing
3335 + * an ASCII copy to the cache, where appropriate).
3336 + * Therefore, we see here an ASCII-CRLF (\015\012),
3337 + * not an EBCDIC-CRLF (\r\n).
3339 + if ((ch = ap_bgetc(f)) == EOF) {
3340 + /* Protocol error: EOF detected within chunk */
3342 + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r,
3343 + "proxy: remote protocol error, eof while reading chunked from proxy");
3347 + if (ch == '\015') { /* _ASCII_ CR */
3350 + if (ch != '\012') {
3357 + /* otherwise read block normally */
3360 n = ap_bread(f, buf, buf_size);
3363 - n = ap_bread(f, buf, MIN((off_t)buf_size, len - total_bytes_rcvd));
3364 + n = ap_bread(f, buf, MIN((int)buf_size,
3365 + (int)(len - total_bytes_rcvd)));
3370 if (alternate_timeouts)
3373 @@ -587,11 +610,12 @@
3374 total_bytes_rcvd += n;
3376 /* if we've received everything... */
3377 - /* in the case of slow frontends and expensive backends,
3378 - * we want to avoid leaving a backend connection hanging
3379 - * while the frontend takes it's time to absorb the bytes.
3380 - * so: if we just read the last block, we close the backend
3381 - * connection now instead of later - it's no longer needed.
3383 + * in the case of slow frontends and expensive backends, we want to
3384 + * avoid leaving a backend connection hanging while the frontend
3385 + * takes it's time to absorb the bytes. so: if we just read the last
3386 + * block, we close the backend connection now instead of later - it's
3387 + * no longer needed.
3389 if (total_bytes_rcvd == len) {
3391 @@ -599,13 +623,17 @@
3394 /* Write to cache first. */
3395 - /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */
3397 + * @@@ XXX FIXME: Assuming that writing the cache file won't time
3400 if (c != NULL && c->fp != NULL) {
3401 if (ap_bwrite(c->fp, &buf[0], n) != n) {
3402 ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
3403 "proxy: error writing to %s", c->tempfile);
3404 c = ap_proxy_cache_error(c);
3411 @@ -624,16 +652,17 @@
3415 - /* when a send failure occurs, we need to decide
3416 - * whether to continue loading and caching the
3417 - * document, or to abort the whole thing
3419 + * when a send failure occurs, we need to decide whether
3420 + * to continue loading and caching the document, or to
3421 + * abort the whole thing
3423 ok = (c->len > 0) &&
3424 (c->cache_completion > 0) &&
3425 (c->len * c->cache_completion < total_bytes_rcvd);
3428 - if (c->fp!=NULL) {
3430 + if (c->fp != NULL) {
3431 ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));
3437 char valbuf[HUGE_STRING_LEN];
3438 - valbuf[sizeof(valbuf)-1] = 0; /* safety terminating zero */
3439 + valbuf[sizeof(valbuf) - 1] = 0; /* safety terminating zero */
3444 while (ap_isspace(*list)) {
3447 - strncpy(valbuf, list, MIN(p-list, sizeof(valbuf)-1));
3448 + strncpy(valbuf, list, MIN(p - list, sizeof(valbuf) - 1));
3453 static const char enc_table[32] = "abcdefghijklmnopqrstuvwxyz012345";
3455 ap_MD5Init(&context);
3456 - ap_MD5Update(&context, (const unsigned char *) it, strlen(it));
3457 + ap_MD5Update(&context, (const unsigned char *)it, strlen(it));
3458 ap_MD5Final(digest, &context);
3460 /* encode 128 bits as 26 characters, using a modified uuencoding */
3461 @@ -805,8 +834,10 @@
3464 #if defined(MPE) || (defined(AIX) && defined(__ps2__))
3465 - /* Believe it or not, AIX 1.x does not allow you to name a file '@',
3466 - * so hack around it in the encoding. */
3468 + * Believe it or not, AIX 1.x does not allow you to name a file '@', so
3469 + * hack around it in the encoding.
3471 static const char enc_table[64] =
3472 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_%";
3477 ap_MD5Init(&context);
3478 - ap_MD5Update(&context, (const unsigned char *) it, strlen(it));
3479 + ap_MD5Update(&context, (const unsigned char *)it, strlen(it));
3480 ap_MD5Final(digest, &context);
3482 /* encode 128 bits as 22 characters, using a modified uuencoding */
3485 /* no longer necessary, as the source hex is 8-byte int */
3486 /* if (j == 0xffffffff)*/
3487 -/* return -1;*/ /* so that it works with 8-byte ints */
3488 + /* return -1;*//* so that it works with 8-byte ints */
3493 * This routine returns its own error message
3496 - ap_proxy_host2addr(const char *host, struct hostent *reqhp)
3497 + ap_proxy_host2addr(const char *host, struct hostent * reqhp)
3501 @@ -955,14 +986,14 @@
3504 ptd->ipaddr = ap_inet_addr(host);
3505 - hp = gethostbyaddr((char *) &ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
3506 + hp = gethostbyaddr((char *)&ptd->ipaddr, sizeof(ptd->ipaddr), AF_INET);
3508 memset(&ptd->hpbuf, 0, sizeof(ptd->hpbuf));
3509 ptd->hpbuf.h_name = 0;
3510 ptd->hpbuf.h_addrtype = AF_INET;
3511 ptd->hpbuf.h_length = sizeof(ptd->ipaddr);
3512 ptd->hpbuf.h_addr_list = ptd->charpbuf;
3513 - ptd->hpbuf.h_addr_list[0] = (char *) &ptd->ipaddr;
3514 + ptd->hpbuf.h_addr_list[0] = (char *)&ptd->ipaddr;
3515 ptd->hpbuf.h_addr_list[1] = 0;
3518 @@ -985,12 +1016,13 @@
3519 || url[1] != '/' || url[2] != '/')
3522 - url = ap_pstrdup(r->pool, &url[1]); /* make it point to "//", which is what proxy_canon_netloc expects */
3523 + url = ap_pstrdup(r->pool, &url[1]); /* make it point to "//", which is
3524 + * what proxy_canon_netloc expects */
3526 err = ap_proxy_canon_netloc(r->pool, &url, &user, &password, &host, &port);
3529 - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
3530 + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r,
3534 @@ -1011,9 +1043,12 @@
3535 /* "partial" addresses (with less than 4 quads) correctly, i.e. */
3536 /* 192.168.123 is parsed as 192.168.0.123, which is not what I want. */
3537 /* I therefore have to parse the IP address manually: */
3538 - /*if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr) == 0) */
3540 + * if (proxy_readmask(This->name, &This->addr.s_addr, &This->mask.s_addr)
3543 /* addr and mask were set by proxy_readmask() */
3547 /* Parse IP addr manually, optionally allowing */
3548 /* abbreviated net addresses like 192.168. */
3549 @@ -1070,7 +1105,10 @@
3550 while (quads > 0 && ip_addr[quads - 1] == 0)
3553 - /* "IP Address should be given in dotted-quad form, optionally followed by a netmask (e.g., 192.168.111.0/24)"; */
3555 + * "IP Address should be given in dotted-quad form, optionally
3556 + * followed by a netmask (e.g., 192.168.111.0/24)";
3561 @@ -1157,7 +1195,7 @@
3563 /* Try to deal with multiple IP addr's for a host */
3564 for (ip_listptr = the_host.h_addr_list; *ip_listptr; ++ip_listptr) {
3565 - ip_list = (struct in_addr *) *ip_listptr;
3566 + ip_list = (struct in_addr *)*ip_listptr;
3567 if (This->addr.s_addr == (ip_list->s_addr & This->mask.s_addr)) {
3569 fprintf(stderr, "3)IP-Match: %s[%s] <-> ", found, inet_ntoa(*ip_list));
3570 @@ -1256,7 +1294,7 @@
3571 if (addr[i] != '\0' || ap_proxy_host2addr(addr, &host) != NULL)
3574 - This->hostentry = ap_pduphostent (p, &host);
3575 + This->hostentry = ap_pduphostent(p, &host);
3577 /* Strip trailing dots */
3578 for (i = strlen(addr) - 1; i > 0 && addr[i] == '.'; --i)
3579 @@ -1318,7 +1356,7 @@
3581 ap_hard_timeout("proxy connect", r);
3583 - i = connect(sock, (struct sockaddr *) addr, sizeof(struct sockaddr_in));
3584 + i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
3585 #if defined(WIN32) || defined(NETWARE)
3586 if (i == SOCKET_ERROR)
3587 errno = WSAGetLastError();
3588 @@ -1351,7 +1389,8 @@
3589 c = ap_proxy_cache_error(c);
3590 return 0; /* no need to continue, it failed already */
3592 - return 1; /* tell ap_table_do() to continue calling us for more headers */
3593 + return 1; /* tell ap_table_do() to continue calling us
3594 + * for more headers */
3597 /* send a text line to one or two BUFF's; return line length */
3598 @@ -1366,7 +1405,8 @@
3599 /* do a HTTP/1.1 age calculation */
3600 time_t ap_proxy_current_age(cache_req *c, const time_t age_value)
3602 - time_t apparent_age, corrected_received_age, response_delay, corrected_initial_age, resident_time, current_age;
3603 + time_t apparent_age, corrected_received_age, response_delay, corrected_initial_age,
3604 + resident_time, current_age;
3606 /* Perform an HTTP/1.1 age calculation. (RFC2616 13.2.3) */
3608 @@ -1398,7 +1438,7 @@
3609 "proxy: error opening cache file %s",
3612 - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "File %s not found", filename);
3613 + ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "File %s not found", filename);
3617 @@ -1431,10 +1471,10 @@
3619 char *next = ap_pstrdup(p, ap_table_get(headers, "Connection"));
3621 + /* Some proxies (Squid, ICS) use the non-standard "Proxy-Connection" header. */
3622 ap_table_unset(headers, "Proxy-Connection");
3626 + if (next != NULL) {
3629 while (*next && !ap_isspace(*next) && (*next != ','))
3630 @@ -1446,6 +1486,30 @@
3631 ap_table_unset(headers, name);
3633 ap_table_unset(headers, "Connection");
3636 + /* unset hop-by-hop headers defined in RFC2616 13.5.1 */
3637 + ap_table_unset(headers,"Keep-Alive");
3639 + * XXX: @@@ FIXME: "Proxy-Authenticate" should IMO *not* be stripped
3640 + * because in a chain of proxies some "front" proxy might need
3641 + * proxy authentication, while a "back-end" proxy which needs none can
3642 + * simply pass the "Proxy-Authenticate" back to the client, and pass
3643 + * the client's "Proxy-Authorization" to the front-end proxy.
3644 + * (See the note in proxy_http.c for the "Proxy-Authorization" case.)
3648 + ap_table_unset(headers,"Proxy-Authenticate");
3649 + ap_table_unset(headers,"TE");
3650 + ap_table_unset(headers,"Trailer");
3651 + /* it is safe to just chop the transfer-encoding header
3652 + * here, because proxy doesn't support any other encodings
3653 + * to the backend other than chunked.
3655 + ap_table_unset(headers,"Transfer-Encoding");
3656 + ap_table_unset(headers,"Upgrade");
3660 /* overlay one table on another
3661 @@ -1467,7 +1531,7 @@
3663 int ap_proxy_table_replace(table *base, table *overlay)
3665 - table_entry *elts = (table_entry *) overlay->a.elts;
3666 + table_entry *elts = (table_entry *)overlay->a.elts;
3670 @@ -1490,40 +1554,11 @@
3674 -/* unmerge an element in the table */
3675 -void ap_proxy_table_unmerge(pool *p, table *t, char *key)
3677 - long int offset = 0;
3678 - long int count = 0;
3679 - char *value = NULL;
3681 - /* get the value to unmerge */
3682 - const char *initial = ap_table_get(t, key);
3686 - value = ap_pstrdup(p, initial);
3688 - /* remove the value from the headers */
3689 - ap_table_unset(t, key);
3691 - /* find each comma */
3692 - while (value[count]) {
3693 - if (value[count] == ',') {
3695 - ap_table_add(t, key, value + offset);
3696 - offset = count + 1;
3700 - ap_table_add(t, key, value + offset);
3705 static DWORD tls_index;
3707 -BOOL WINAPI DllMain (HINSTANCE dllhandle, DWORD reason, LPVOID reserved)
3708 +BOOL WINAPI DllMain(HINSTANCE dllhandle, DWORD reason, LPVOID reserved)
3712 @@ -1531,13 +1566,13 @@
3713 case DLL_PROCESS_ATTACH:
3714 tls_index = TlsAlloc();
3715 case DLL_THREAD_ATTACH: /* intentional no break */
3716 - TlsSetValue (tls_index, malloc (sizeof (struct per_thread_data)));
3717 + TlsSetValue(tls_index, malloc(sizeof(struct per_thread_data)));
3719 case DLL_THREAD_DETACH:
3720 - memptr = TlsGetValue (tls_index);
3721 + memptr = TlsGetValue(tls_index);
3724 - TlsSetValue (tls_index, 0);
3726 + TlsSetValue(tls_index, 0);
3730 @@ -1551,7 +1586,7 @@
3734 - return (struct per_thread_data *) TlsGetValue (tls_index);
3735 + return (struct per_thread_data *)TlsGetValue(tls_index);