You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@hyperreal.org on 1998/08/16 22:21:30 UTC
cvs commit: apache-1.3/src/modules/proxy mod_proxy.c mod_proxy.h proxy_cache.c proxy_connect.c proxy_ftp.c proxy_http.c proxy_util.c
martin 98/08/16 13:21:30
Modified: src CHANGES
src/include ap_mmn.h
src/modules/proxy mod_proxy.c mod_proxy.h proxy_cache.c
proxy_connect.c proxy_ftp.c proxy_http.c
proxy_util.c
Log:
Modify the proxy to use tables instead of array_headers for header lines.
That simplifies some code, but changes many of the proxy-internal interfaces.
It should also prevent the proxy from merging multiple "Set-Cookie:" headers
into one.
Revision Changes Path
1.1027 +3 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1026
retrieving revision 1.1027
diff -u -u -r1.1026 -r1.1027
--- CHANGES 1998/08/15 15:02:44 1.1026
+++ CHANGES 1998/08/16 20:21:24 1.1027
@@ -1,5 +1,8 @@
Changes with Apache 1.3.2
+ *) Change the proxy to use tables instead of array_headers for
+ the header lines. [Martin Kraemer]
+
*) Make sure the config.status file is not overridden when just
``configure --help'' is used. [Ralf S. Engelschall] PR#2844
1.4 +9 -2 apache-1.3/src/include/ap_mmn.h
Index: ap_mmn.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/include/ap_mmn.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -u -r1.3 -r1.4
--- ap_mmn.h 1998/08/14 02:49:09 1.3
+++ ap_mmn.h 1998/08/16 20:21:25 1.4
@@ -66,6 +66,7 @@
*
* MODULE_MAGIC_NUMBER_MINOR
* Minor API changes that do not cause binary compatibility problems.
+ * Should be reset to 0 when upgrading MODULE_MAGIC_NUMBER_MAJOR.
*
* See the MODULE_MAGIC_AT_LEAST macro below for an example.
*/
@@ -164,12 +165,18 @@
* ap_get_limit_req_body() to get its value.
* 19980812 (1.3.2-dev) - split off MODULE_MAGIC_NUMBER
* 19980812.2 - add ap_overlap_tables()
+ * 19980816 (1.3.2-dev) - change proxy to use tables for headers, change
+ * struct cache_req to typedef cache_req.
+ * Delete ap_proxy_get_header(), ap_proxy_add_header(),
+ * ap_proxy_del_header(). Change interface of
+ * ap_proxy_send_fb() and ap_proxy_cache_error().
+ * Add ap_proxy_send_hdr_line() and ap_proxy_bputs2().
*/
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 19980812
+#define MODULE_MAGIC_NUMBER_MAJOR 19980816
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 2
+#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
#define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */
/* Useful for testing for features. */
1.59 +1 -1 apache-1.3/src/modules/proxy/mod_proxy.c
Index: mod_proxy.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/mod_proxy.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -u -r1.58 -r1.59
--- mod_proxy.c 1998/08/06 17:30:40 1.58
+++ mod_proxy.c 1998/08/16 20:21:26 1.59
@@ -292,7 +292,7 @@
array_header *proxies = conf->proxies;
struct proxy_remote *ents = (struct proxy_remote *) proxies->elts;
int i, rc;
- struct cache_req *cr;
+ cache_req *cr;
int direct_connect = 0;
const char *maxfwd_str;
1.38 +26 -17 apache-1.3/src/modules/proxy/mod_proxy.h
Index: mod_proxy.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/mod_proxy.h,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -u -r1.37 -r1.38
--- mod_proxy.h 1998/07/09 19:45:56 1.37
+++ mod_proxy.h 1998/08/16 20:21:27 1.38
@@ -55,6 +55,9 @@
*
*/
+#ifndef MOD_PROXY_H
+#define MOD_PROXY_H
+
/*
* Main include file for the Apache proxy
*/
@@ -218,7 +221,7 @@
};
/* caching information about a request */
-struct cache_req {
+typedef struct {
request_rec *req; /* the request */
char *url; /* the URL requested */
char *filename; /* name of the cache file, or NULL if no cache */
@@ -237,35 +240,41 @@
unsigned int written; /* total *content* bytes written to cache */
float cache_completion; /* specific to this request */
char *resp_line; /* the whole status like (protocol, code + message) */
- array_header *hdrs; /* the HTTP headers of the file */
+ table *hdrs; /* the HTTP headers of the file */
+} cache_req;
+
+/* Additional information passed to the function called by ap_table_do() */
+struct tbl_do_args {
+ request_rec *req;
+ cache_req *cache;
};
/* Function prototypes */
/* proxy_cache.c */
-void ap_proxy_cache_tidy(struct cache_req *c);
+void ap_proxy_cache_tidy(cache_req *c);
int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
- struct cache_req **cr);
-int ap_proxy_cache_update(struct cache_req *c, array_header *resp_hdrs,
+ cache_req **cr);
+int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,
const int is_HTTP1, int nocache);
void ap_proxy_garbage_coll(request_rec *r);
/* proxy_connect.c */
-int ap_proxy_connect_handler(request_rec *r, struct cache_req *c, char *url,
+int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url,
const char *proxyhost, int proxyport);
/* proxy_ftp.c */
int ap_proxy_ftp_canon(request_rec *r, char *url);
-int ap_proxy_ftp_handler(request_rec *r, struct cache_req *c, char *url);
+int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url);
/* proxy_http.c */
int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme,
int def_port);
-int ap_proxy_http_handler(request_rec *r, struct cache_req *c, char *url,
+int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
const char *proxyhost, int proxyport);
/* proxy_util.c */
@@ -277,19 +286,14 @@
char *ap_proxy_canon_netloc(pool *p, char **const urlp, char **userp,
char **passwordp, char **hostp, int *port);
const char *ap_proxy_date_canon(pool *p, const char *x);
-array_header *ap_proxy_read_headers(pool *p, char *buffer, int size, BUFF *f);
-long int ap_proxy_send_fb(BUFF *f, request_rec *r, BUFF *f2, struct cache_req *c);
-struct hdr_entry *ap_proxy_get_header(array_header *hdrs_arr, const char *name);
-struct hdr_entry *ap_proxy_add_header(array_header *hdrs_arr, const char *field,
- const char *value, int rep);
-void ap_proxy_del_header(array_header *hdrs_arr, const char *field);
-void ap_proxy_send_headers(request_rec *r, const char *respline,
- array_header *hdrs_arr);
+table *ap_proxy_read_headers(pool *p, char *buffer, int size, BUFF *f);
+long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c);
+void ap_proxy_send_headers(request_rec *r, const char *respline, table *hdrs);
int ap_proxy_liststr(const char *list, const char *val);
void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength);
int ap_proxy_hex2sec(const char *x);
void ap_proxy_sec2hex(int t, char *y);
-BUFF *ap_proxy_cache_error(struct cache_req *r);
+cache_req *ap_proxy_cache_error(cache_req *r);
int ap_proxyerror(request_rec *r, const char *message);
const char *ap_proxy_host2addr(const char *host, struct hostent *reqhp);
int ap_proxy_is_ipaddr(struct dirconn_entry *This, pool *p);
@@ -298,3 +302,8 @@
int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
int ap_proxy_garbage_init(server_rec *, pool *);
+/* This function is called by ap_table_do() for all header lines */
+int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
+unsigned ap_proxy_bputs2(const char *data, BUFF *client, cache_req *cache);
+
+#endif /*MOD_PROXY_H*/
1.50 +50 -56 apache-1.3/src/modules/proxy/proxy_cache.c
Index: proxy_cache.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_cache.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -u -r1.49 -r1.50
--- proxy_cache.c 1998/08/06 17:30:41 1.49
+++ proxy_cache.c 1998/08/16 20:21:27 1.50
@@ -535,7 +535,7 @@
* 0 on failure (bad file or wrong URL)
* -1 on UNIX error
*/
-static int rdcache(pool *p, BUFF *cachefp, struct cache_req *c)
+static int rdcache(pool *p, BUFF *cachefp, cache_req *c)
{
char urlbuff[1034], *strp;
int len;
@@ -544,7 +544,7 @@
* date SP lastmod SP expire SP count SP content-length CRLF
* dates are stored as hex seconds since 1970
*/
- len = ap_bgets(urlbuff, 1034, cachefp);
+ len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
if (len == -1)
return -1;
if (len == 0 || urlbuff[len - 1] != '\n')
@@ -562,7 +562,7 @@
c->len = ap_proxy_hex2sec(urlbuff + 36);
/* check that we have the same URL */
- len = ap_bgets(urlbuff, 1034, cachefp);
+ len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
if (len == -1)
return -1;
if (len == 0 || strncmp(urlbuff, "X-URL: ", 7) != 0 ||
@@ -573,7 +573,7 @@
return 0;
/* What follows is the message */
- len = ap_bgets(urlbuff, 1034, cachefp);
+ len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);
if (len == -1)
return -1;
if (len == 0 || urlbuff[len - 1] != '\n')
@@ -586,16 +586,13 @@
return 0;
c->status = atoi(strp);
- c->hdrs = ap_proxy_read_headers(p, urlbuff, 1034, cachefp);
+ c->hdrs = ap_proxy_read_headers(p, urlbuff, sizeof urlbuff, cachefp);
if (c->hdrs == NULL)
return -1;
if (c->len != -1) { /* add a content-length header */
- struct hdr_entry *q;
- q = ap_proxy_get_header(c->hdrs, "Content-Length");
- if (q == NULL) {
- strp = ap_palloc(p, 15);
- ap_snprintf(strp, 15, "%lu", (unsigned long)c->len);
- ap_proxy_add_header(c->hdrs, "Content-Length", strp, HDR_REP);
+ if (ap_table_get(c->hdrs, "Content-Length") == NULL) {
+ ap_table_set(c->hdrs, "Content-Length",
+ ap_psprintf(p, "%lu", (unsigned long)c->len));
}
}
return 1;
@@ -617,11 +614,11 @@
* last modified date to request
*/
int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
- struct cache_req **cr)
+ cache_req **cr)
{
char hashfile[66];
const char *imstr, *pragma, *auth;
- struct cache_req *c;
+ cache_req *c;
time_t now;
BUFF *cachefp;
int cfd, i;
@@ -630,7 +627,7 @@
proxy_server_conf *pconf =
(proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
- c = ap_pcalloc(r->pool, sizeof(struct cache_req));
+ c = ap_pcalloc(r->pool, sizeof(cache_req));
*cr = c;
c->req = r;
c->url = ap_pstrdup(r->pool, url);
@@ -696,7 +693,7 @@
/* fixed? in this case, we want to get the headers from the remote server
it will be handled later if we don't do this (I hope ;-)
if (cachefp == NULL)
- c->hdrs = ap_make_array(r->pool, 2, sizeof(struct hdr_entry));
+ c->hdrs = ap_make_table(r->pool, 20);
*/
/* FIXME: Shouldn't we check the URL somewhere? */
now = time(NULL);
@@ -708,16 +705,12 @@
/* has the cached file changed since this request? */
if (c->date == BAD_DATE || c->date > c->ims) {
/* No, but these header values may have changed, so we send them with the
- * 304 response
+ * 304 HTTP_NOT_MODIFIED response
*/
- /* CHECKME: surely this was wrong? (Ben)
- p = table_get(r->headers_in, "Expires");
- */
- struct hdr_entry *q;
-
- q = ap_proxy_get_header(c->hdrs, "Expires");
- if (q != NULL && q->value != NULL)
- ap_table_set(r->headers_out, "Expires", q->value);
+ const char *q;
+
+ if ((q = ap_table_get(c->hdrs, "Expires")) != NULL)
+ ap_table_set(r->headers_out, "Expires", q);
}
ap_pclosef(r->pool, cachefp->fd);
Explain0("Use local copy, cached file hasn't changed");
@@ -736,7 +729,7 @@
ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
if (!r->header_only)
- ap_proxy_send_fb(cachefp, r, NULL, NULL);
+ ap_proxy_send_fb(cachefp, r, NULL);
ap_pclosef(r->pool, cachefp->fd);
return OK;
}
@@ -751,13 +744,11 @@
* from the cache
*/
if (c->ims == BAD_DATE || c->ims < c->lmod) {
- struct hdr_entry *q;
-
- q = ap_proxy_get_header(c->hdrs, "Last-Modified");
+ const char *q;
- if (q != NULL && q->value != NULL)
+ if ((q = ap_table_get(c->hdrs, "Last-Modified")) != NULL)
ap_table_set(r->headers_in, "If-Modified-Since",
- (char *) q->value);
+ (char *) q);
}
}
c->fp = cachefp;
@@ -779,7 +770,7 @@
* from the cache, maybe updating the header line
* otherwise, delete the old cached file and open a new temporary file
*/
-int ap_proxy_cache_update(struct cache_req *c, array_header *resp_hdrs,
+int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,
const int is_HTTP1, int nocache)
{
#ifdef ULTRIX_BRAIN_DEATH
@@ -788,7 +779,7 @@
request_rec *r = c->req;
char *p;
int i;
- struct hdr_entry *expire, *dates, *lmods, *clen;
+ const char *expire, *lmods, *dates, *clen;
time_t expc, date, lmod, now;
char buff[46];
void *sconf = r->server->module_config;
@@ -802,21 +793,20 @@
/* read expiry date; if a bad date, then leave it so the client can
* read it
*/
- expire = ap_proxy_get_header(resp_hdrs, "Expires");
+ expire = ap_table_get(resp_hdrs, "Expires");
if (expire != NULL)
- expc = ap_parseHTTPdate(expire->value);
+ expc = ap_parseHTTPdate(expire);
else
expc = BAD_DATE;
/*
* read the last-modified date; if the date is bad, then delete it
*/
- lmods = ap_proxy_get_header(resp_hdrs, "Last-Modified");
+ lmods = ap_table_get(resp_hdrs, "Last-Modified");
if (lmods != NULL) {
- lmod = ap_parseHTTPdate(lmods->value);
+ lmod = ap_parseHTTPdate(lmods);
if (lmod == BAD_DATE) {
/* kill last modified date */
- lmods->value = NULL;
lmods = NULL;
}
}
@@ -826,16 +816,18 @@
/*
* what responses should we not cache?
* Unknown status responses and those known to be uncacheable
- * 304 response when we have no valid cache file, or
- * 200 response from HTTP/1.0 and up without a Last-Modified header, or
+ * 304 HTTP_NOT_MODIFIED response when we have no valid cache file, or
+ * 200 HTTP_OK response from HTTP/1.0 and up without a Last-Modified header, or
* HEAD requests, or
* requests with an Authorization header, or
* protocol requests nocache (e.g. ftp with user/password)
*/
- if ((r->status != 200 && r->status != 301 && r->status != 304) ||
+/* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" corerct?
+ * or shouldn't it be "is_HTTP_REDIRECT(r->status)" ? -MnKr */
+ if ((r->status != HTTP_OK && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||
(expire != NULL && expc == BAD_DATE) ||
- (r->status == 304 && c->fp == NULL) ||
- (r->status == 200 && lmods == NULL && is_HTTP1) ||
+ (r->status == HTTP_NOT_MODIFIED && (c == NULL || c->fp == NULL)) ||
+ (r->status == HTTP_OK && lmods == NULL && is_HTTP1) ||
r->header_only ||
ap_table_get(r->headers_in, "Authorization") != NULL ||
nocache) {
@@ -855,9 +847,9 @@
/*
* Read the date. Generate one if one is not supplied
*/
- dates = ap_proxy_get_header(resp_hdrs, "Date");
+ dates = ap_table_get(resp_hdrs, "Date");
if (dates != NULL)
- date = ap_parseHTTPdate(dates->value);
+ date = ap_parseHTTPdate(dates);
else
date = BAD_DATE;
@@ -868,8 +860,8 @@
/* add one; N.B. use the time _now_ rather than when we were checking the cache
*/
date = now;
- p = ap_gm_timestr_822(r->pool, now);
- dates = ap_proxy_add_header(resp_hdrs, "Date", p, HDR_REP);
+ dates = ap_gm_timestr_822(r->pool, now);
+ ap_table_set(resp_hdrs, "Date", dates);
Explain0("Added date header");
}
@@ -878,7 +870,7 @@
/* if its in the future, then replace by date */
{
lmod = date;
- lmods->value = dates->value;
+ lmods = dates;
Explain0("Last modified is in the future, replacing with now");
}
/* if the response did not contain the header, then use the cached version */
@@ -889,9 +881,9 @@
/* we now need to calculate the expire data for the object. */
if (expire == NULL && c->fp != NULL) { /* no expiry data sent in response */
- expire = ap_proxy_get_header(c->hdrs, "Expires");
+ expire = ap_table_get(c->hdrs, "Expires");
if (expire != NULL)
- expc = ap_parseHTTPdate(expire->value);
+ expc = ap_parseHTTPdate(expire);
}
/* so we now have the expiry date */
/* if no expiry date then
@@ -915,11 +907,11 @@
}
/* get the content-length header */
- clen = ap_proxy_get_header(resp_hdrs, "Content-Length");
+ clen = ap_table_get(resp_hdrs, "Content-Length");
if (clen == NULL)
c->len = -1;
else
- c->len = atoi(clen->value);
+ c->len = atoi(clen);
ap_proxy_sec2hex(date, buff);
buff[8] = ' ';
@@ -934,7 +926,7 @@
buff[45] = '\0';
/* if file not modified */
- if (r->status == 304) {
+ if (r->status == HTTP_NOT_MODIFIED) {
if (c->ims != BAD_DATE && lmod != BAD_DATE && lmod <= c->ims) {
/* set any changed headers somehow */
/* update dates and version, but not content-length */
@@ -967,7 +959,7 @@
ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
if (!r->header_only)
- ap_proxy_send_fb(c->fp, r, NULL, NULL);
+ ap_proxy_send_fb(c->fp, r, NULL);
/* set any changed headers somehow */
/* update dates and version, but not content-length */
if (lmod != c->lmod || expc != c->expire || date != c->date) {
@@ -1030,13 +1022,15 @@
return DECLINED;
}
-void ap_proxy_cache_tidy(struct cache_req *c)
+void ap_proxy_cache_tidy(cache_req *c)
{
- server_rec *s = c->req->server;
+ server_rec *s;
long int bc;
- if (c->fp == NULL)
+ if (c == NULL || c->fp == NULL)
return;
+
+ s = c->req->server;
/* don't care how much was sent, but rather how much was written to cache
ap_bgetopt(c->req->connection->client, BO_BYTECT, &bc);
1.31 +1 -1 apache-1.3/src/modules/proxy/proxy_connect.c
Index: proxy_connect.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_connect.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -u -r1.30 -r1.31
--- proxy_connect.c 1998/08/06 17:30:42 1.30
+++ proxy_connect.c 1998/08/16 20:21:27 1.31
@@ -97,7 +97,7 @@
* FIXME: no check for r->assbackwards, whatever that is.
*/
-int ap_proxy_connect_handler(request_rec *r, struct cache_req *c, char *url,
+int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url,
const char *proxyhost, int proxyport)
{
struct sockaddr_in server;
1.66 +38 -75 apache-1.3/src/modules/proxy/proxy_ftp.c
Index: proxy_ftp.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_ftp.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -u -r1.65 -r1.66
--- proxy_ftp.c 1998/08/06 17:30:43 1.65
+++ proxy_ftp.c 1998/08/16 20:21:28 1.66
@@ -263,7 +263,7 @@
return status;
}
-static long int send_dir(BUFF *f, request_rec *r, BUFF *f2, struct cache_req *c, char *url)
+static long int send_dir(BUFF *f, request_rec *r, cache_req *c, char *url)
{
char buf[IOBUFSIZE];
char buf2[IOBUFSIZE];
@@ -278,7 +278,6 @@
int hostlen;
conn_rec *con = r->connection;
char *dir, *path, *reldir, *site, *psite;
- const char *sig;
tempurl = ap_pstrdup(r->pool, url);
@@ -318,10 +317,7 @@
"<BODY><H2>Directory of "
"<A HREF=\"/\">%s</A>/",
tempurl, psite, path, site);
- ap_bputs(buf, con->client);
- if (f2 != NULL)
- ap_bputs(buf, f2);
- total_bytes_sent += strlen(buf);
+ total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);
while ((dir = strchr(dir+1, '/')) != NULL)
{
@@ -332,17 +328,12 @@
++reldir;
/* print "path/" component */
ap_snprintf(buf, sizeof(buf), "<A HREF=\"/%s/\">%s</A>/", path+1, reldir);
- ap_bputs(buf, con->client);
- if (f2 != NULL)
- ap_bputs(buf, f2);
+ total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);
total_bytes_sent += strlen(buf);
*dir = '/';
}
ap_snprintf(buf, sizeof(buf), "</H2>\n<HR><PRE>");
- ap_bputs(buf, con->client);
- if (f2 != NULL)
- ap_bputs(buf, f2);
- total_bytes_sent += strlen(buf);
+ total_bytes_sent += ap_proxy_bputs2(buf, con->client, c);
for (hostlen=0; url[hostlen]!='/'; ++hostlen)
continue;
@@ -355,8 +346,8 @@
while (!con->aborted) {
n = ap_bgets(buf, sizeof buf, f);
if (n == -1) { /* input error */
- if (f2 != NULL)
- f2 = ap_proxy_cache_error(c);
+ if (c != NULL)
+ c = ap_proxy_cache_error(c);
break;
}
if (n == 0)
@@ -416,9 +407,8 @@
o = 0;
total_bytes_sent += n;
- if (f2 != NULL)
- if (ap_bwrite(f2, buf, n) != n)
- f2 = ap_proxy_cache_error(c);
+ if (c != NULL && c->fp && ap_bwrite(c->fp, buf, n) != n)
+ c = ap_proxy_cache_error(c);
while (n && !r->connection->aborted) {
w = ap_bwrite(con->client, &buf[o], n);
@@ -429,23 +419,11 @@
o += w;
}
}
- site = "</PRE><HR>\n";
- ap_bputs(site, con->client);
- if (f2 != NULL)
- ap_bputs(site, f2);
- total_bytes_sent += strlen(site);
-
- sig = ap_psignature("", r);
- ap_bputs(sig, con->client);
- if (f2 != NULL)
- ap_bputs(sig, f2);
- total_bytes_sent += strlen(sig);
-
- site = "</BODY></HTML>\n";
- ap_bputs(site, con->client);
- if (f2 != NULL)
- ap_bputs(site, f2);
- total_bytes_sent += strlen(site);
+
+ total_bytes_sent += ap_proxy_bputs2("</PRE><HR>\n", con->client, c);
+ total_bytes_sent += ap_proxy_bputs2(ap_psignature("", r), con->client, c);
+ total_bytes_sent += ap_proxy_bputs2("</BODY></HTML>\n", con->client, c);
+
ap_bflush(con->client);
return total_bytes_sent;
@@ -457,7 +435,7 @@
* Troy Morrison <sp...@zoom.com>
* PASV added by Chuck
*/
-int ap_proxy_ftp_handler(request_rec *r, struct cache_req *c, char *url)
+int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url)
{
char *host, *path, *strp, *user, *password, *parms;
const char *err;
@@ -466,15 +444,15 @@
int csd = 0;
struct sockaddr_in server;
struct hostent server_hp;
- struct hdr_entry *hdr;
struct in_addr destaddr;
- array_header *resp_hdrs;
- BUFF *f, *cache;
+ table *resp_hdrs;
+ BUFF *f;
BUFF *data = NULL;
pool *p = r->pool;
int one = 1;
const long int zero = 0L;
NET_SIZE_T clen;
+ struct tbl_do_args tdo;
void *sconf = r->server->module_config;
proxy_server_conf *conf =
@@ -999,25 +977,24 @@
if (rc != 125 && rc != 150 && rc != 226 && rc != 250)
return HTTP_BAD_GATEWAY;
- r->status = 200;
+ r->status = HTTP_OK;
r->status_line = "200 OK";
- resp_hdrs = ap_make_array(p, 2, sizeof(struct hdr_entry));
+ resp_hdrs = ap_make_table(p, 2);
c->hdrs = resp_hdrs;
if (parms[0] == 'd')
- ap_proxy_add_header(resp_hdrs, "Content-Type", "text/html", HDR_REP);
+ ap_table_set(resp_hdrs, "Content-Type", "text/html");
else {
if (r->content_type != NULL) {
- ap_proxy_add_header(resp_hdrs, "Content-Type", r->content_type,
- HDR_REP);
+ ap_table_set(resp_hdrs, "Content-Type", r->content_type);
Explain1("FTP: Content-Type set to %s", r->content_type);
}
else {
- ap_proxy_add_header(resp_hdrs, "Content-Type", "text/plain", HDR_REP);
+ ap_table_set(resp_hdrs, "Content-Type", "text/plain");
}
if (parms[0] != 'a' && size != NULL) {
- ap_proxy_add_header(resp_hdrs, "Content-Length", size, HDR_REP);
+ ap_table_set(resp_hdrs, "Content-Length", size);
Explain1("FTP: Content-Length set to %s", size);
}
}
@@ -1037,10 +1014,6 @@
return i;
}
- cache = c->fp;
-
- c->hdrs = resp_hdrs;
-
if (!pasvmode) { /* wait for connection */
ap_hard_timeout("proxy ftp data connect", r);
clen = sizeof(struct sockaddr_in);
@@ -1053,7 +1026,8 @@
ap_pclosesocket(p, dsock);
ap_bclose(f);
ap_kill_timeout(r);
- ap_proxy_cache_error(c);
+ if (c != NULL)
+ c = ap_proxy_cache_error(c);
return HTTP_BAD_GATEWAY;
}
ap_note_cleanups_for_socket(p, csd);
@@ -1075,31 +1049,19 @@
/* write status line */
if (!r->assbackwards)
ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL);
- if (cache != NULL)
- if (ap_bvputs(cache, "HTTP/1.0 ", r->status_line, CRLF,
- NULL) == -1)
- cache = ap_proxy_cache_error(c);
+ if (c != NULL && c->fp != NULL &&
+ ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1)
+ c = ap_proxy_cache_error(c);
/* send headers */
- len = resp_hdrs->nelts;
- hdr = (struct hdr_entry *) resp_hdrs->elts;
- for (i = 0; i < len; i++) {
- if (hdr[i].field == NULL || hdr[i].value == NULL ||
- hdr[i].value[0] == '\0')
- continue;
- if (!r->assbackwards)
- ap_rvputs(r, hdr[i].field, ": ", hdr[i].value, CRLF, NULL);
- if (cache != NULL)
- if (ap_bvputs(cache, hdr[i].field, ": ", hdr[i].value, CRLF,
- NULL) == -1)
- cache = ap_proxy_cache_error(c);
- }
+ tdo.req = r;
+ tdo.cache = c;
+ ap_table_do(ap_proxy_send_hdr_line, &tdo, resp_hdrs, NULL);
if (!r->assbackwards)
ap_rputs(CRLF, r);
- if (cache != NULL)
- if (ap_bputs(CRLF, cache) == -1)
- cache = ap_proxy_cache_error(c);
+ if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1)
+ c = ap_proxy_cache_error(c);
ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
@@ -1107,15 +1069,16 @@
if (!r->header_only) {
if (parms[0] != 'd') {
/* we need to set this for ap_proxy_send_fb()... */
- c->cache_completion = 0;
- ap_proxy_send_fb(data, r, cache, c);
+ if (c != NULL)
+ c->cache_completion = 0;
+ ap_proxy_send_fb(data, r, c);
} else
- send_dir(data, r, cache, c, url);
+ send_dir(data, r, c, url);
if (rc == 125 || rc == 150)
rc = ftp_getrc(f);
if (rc != 226 && rc != 250)
- ap_proxy_cache_error(c);
+ c = ap_proxy_cache_error(c);
}
else {
/* abort the transfer */
1.57 +32 -50 apache-1.3/src/modules/proxy/proxy_http.c
Index: proxy_http.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_http.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -u -r1.56 -r1.57
--- proxy_http.c 1998/08/09 17:39:25 1.56
+++ proxy_http.c 1998/08/16 20:21:28 1.57
@@ -165,26 +165,28 @@
* we return DECLINED so that we can try another proxy. (Or the direct
* route.)
*/
-int ap_proxy_http_handler(request_rec *r, struct cache_req *c, char *url,
+int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
const char *proxyhost, int proxyport)
{
const char *strp;
char *strp2;
const char *err, *desthost;
int i, j, sock, len, backasswards;
- array_header *reqhdrs_arr, *resp_hdrs;
+ array_header *reqhdrs_arr;
+ table *resp_hdrs;
table_entry *reqhdrs;
struct sockaddr_in server;
struct in_addr destaddr;
struct hostent server_hp;
- BUFF *f, *cache;
- struct hdr_entry *hdr;
+ BUFF *f;
char buffer[HUGE_STRING_LEN];
pool *p = r->pool;
const long int zero = 0L;
int destport = 0;
char *destportstr = NULL;
const char *urlptr = NULL;
+ const char *datestr;
+ struct tbl_do_args tdo;
void *sconf = r->server->module_config;
proxy_server_conf *conf =
@@ -313,7 +315,7 @@
if (reqhdrs[i].key == NULL || reqhdrs[i].val == NULL
/* Clear out headers not to send */
|| !strcasecmp(reqhdrs[i].key, "Host") /* Already sent */
- ||!strcasecmp(reqhdrs[i].key, "Proxy-Authorization"))
+ || !strcasecmp(reqhdrs[i].key, "Proxy-Authorization"))
continue;
ap_bvputs(f, reqhdrs[i].key, ": ", reqhdrs[i].val, CRLF, NULL);
}
@@ -322,7 +324,7 @@
/* send the request data, if any. N.B. should we trap SIGPIPE ? */
if (ap_should_client_block(r)) {
- while ((i = ap_get_client_block(r, buffer, HUGE_STRING_LEN)) > 0)
+ while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0)
ap_bwrite(f, buffer, i);
}
ap_bflush(f);
@@ -330,7 +332,7 @@
ap_hard_timeout("proxy receive", r);
- len = ap_bgets(buffer, HUGE_STRING_LEN - 1, f);
+ len = ap_bgets(buffer, sizeof buffer - 1, f);
if (len == -1 || len == 0) {
ap_bclose(f);
ap_kill_timeout(r);
@@ -368,7 +370,7 @@
r->status_line = "200 OK";
/* no headers */
- resp_hdrs = ap_make_array(p, 2, sizeof(struct hdr_entry));
+ resp_hdrs = ap_make_table(p, 20);
}
c->hdrs = resp_hdrs;
@@ -379,21 +381,18 @@
* HTTP/1.0 requires us to accept 3 types of dates, but only generate
* one type
*/
+ if ((datestr = ap_table_get(resp_hdrs, "Date")) != NULL)
+ ap_table_set(resp_hdrs, "Date", ap_proxy_date_canon(p, datestr));
+ if ((datestr = ap_table_get(resp_hdrs, "Last-Modified")) != NULL)
+ ap_table_set(resp_hdrs, "Last-Modified", ap_proxy_date_canon(p, datestr));
+ if ((datestr = ap_table_get(resp_hdrs, "Expires")) != NULL)
+ ap_table_set(resp_hdrs, "Expires", ap_proxy_date_canon(p, datestr));
+
+ if ((datestr = ap_table_get(resp_hdrs, "Location")) != NULL)
+ ap_table_set(resp_hdrs, "Location", proxy_location_reverse_map(r, datestr));
+ if ((datestr = ap_table_get(resp_hdrs, "URI")) != NULL)
+ ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, datestr));
- hdr = (struct hdr_entry *) resp_hdrs->elts;
- for (i = 0; i < resp_hdrs->nelts; i++) {
- if (hdr[i].value[0] == '\0')
- continue;
- strp = hdr[i].field;
- if (strcasecmp(strp, "Date") == 0 ||
- strcasecmp(strp, "Last-Modified") == 0 ||
- strcasecmp(strp, "Expires") == 0)
- hdr[i].value = ap_proxy_date_canon(p, hdr[i].value);
- if (strcasecmp(strp, "Location") == 0 ||
- strcasecmp(strp, "URI") == 0)
- hdr[i].value = proxy_location_reverse_map(r, hdr[i].value);
- }
-
/* check if NoCache directive on this host */
for (i = 0; i < conf->nocaches->nelts; i++) {
if ((ncent[i].name != NULL && strstr(desthost, ncent[i].name) != NULL)
@@ -407,49 +406,32 @@
return i;
}
- cache = c->fp;
-
ap_hard_timeout("proxy receive", r);
/* write status line */
if (!r->assbackwards)
ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL);
- if (cache != NULL)
- if (ap_bvputs(cache, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1)
- cache = ap_proxy_cache_error(c);
+ if (c != NULL && c->fp != NULL &&
+ ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1)
+ c = ap_proxy_cache_error(c);
/* send headers */
- for (i = 0; i < resp_hdrs->nelts; i++) {
- if (hdr[i].field == NULL || hdr[i].value == NULL ||
- hdr[i].value[0] == '\0')
- continue;
- if (!r->assbackwards) {
- ap_rvputs(r, hdr[i].field, ": ", hdr[i].value, CRLF, NULL);
- /* XXX: can't this be ap_table_setn? -djg */
- ap_table_set(r->headers_out, hdr[i].field, hdr[i].value);
- /* XXX: regardless, there's an O(n^2) attack here, which
- * could be fixed with ap_overlap_tables */
- }
- if (cache != NULL)
- if (ap_bvputs(cache, hdr[i].field, ": ", hdr[i].value, CRLF,
- NULL) == -1)
- cache = ap_proxy_cache_error(c);
- }
+ tdo.req = r;
+ tdo.cache = c;
+ ap_table_do(ap_proxy_send_hdr_line, &tdo, resp_hdrs, NULL);
if (!r->assbackwards)
ap_rputs(CRLF, r);
- if (cache != NULL)
- if (ap_bputs(CRLF, cache) == -1)
- cache = ap_proxy_cache_error(c);
+ if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1)
+ c = ap_proxy_cache_error(c);
ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
r->sent_bodyct = 1;
/* Is it an HTTP/0.9 respose? If so, send the extra data */
if (backasswards) {
ap_bwrite(r->connection->client, buffer, len);
- if (cache != NULL)
- if (ap_bwrite(f, buffer, len) != len)
- cache = ap_proxy_cache_error(c);
+ if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len)
+ c = ap_proxy_cache_error(c);
}
ap_kill_timeout(r);
@@ -467,7 +449,7 @@
if (!r->header_only) {
/* we need to set this for ap_proxy_send_fb()... */
c->cache_completion = conf->cache.cache_completion;
- ap_proxy_send_fb(f, r, cache, c);
+ ap_proxy_send_fb(f, r, c);
}
ap_proxy_cache_tidy(c);
1.69 +152 -150 apache-1.3/src/modules/proxy/proxy_util.c
Index: proxy_util.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/proxy/proxy_util.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -u -r1.68 -r1.69
--- proxy_util.c 1998/08/09 17:39:25 1.68
+++ proxy_util.c 1998/08/16 20:21:28 1.69
@@ -359,89 +359,118 @@
return q;
}
+
+/* NOTE: This routine is taken from http_protocol::getline()
+ * because the old code found in the proxy module was too
+ * difficult to understand and maintain.
+ */
+/* Get a line of protocol input, including any continuation lines
+ * caused by MIME folding (or broken clients) if fold != 0, and place it
+ * in the buffer s, of size n bytes, without the ending newline.
+ *
+ * Returns -1 on error, or the length of s.
+ *
+ * Note: Because bgets uses 1 char for newline and 1 char for NUL,
+ * the most we can get is (n - 2) actual characters if it
+ * was ended by a newline, or (n - 1) characters if the line
+ * length exceeded (n - 1). So, if the result == (n - 1),
+ * then the actual input line exceeded the buffer length,
+ * and it would be a good idea for the caller to puke 400 or 414.
+ */
+static int proxy_getline(char *s, int n, BUFF *in, int fold)
+{
+ char *pos, next;
+ int retval;
+ int total = 0;
+
+ pos = s;
+
+ do {
+ retval = ap_bgets(pos, n, in); /* retval == -1 if error, 0 if EOF */
+
+ if (retval <= 0)
+ return ((retval < 0) && (total == 0)) ? -1 : total;
+
+ /* retval is the number of characters read, not including NUL */
+
+ n -= retval; /* Keep track of how much of s is full */
+ pos += (retval - 1); /* and where s ends */
+ total += retval; /* and how long s has become */
+
+ if (*pos == '\n') { /* Did we get a full line of input? */
+ *pos = '\0';
+ --total;
+ ++n;
+ }
+ else
+ return total; /* if not, input line exceeded buffer size */
+
+ /* Continue appending if line folding is desired and
+ * the last line was not empty and we have room in the buffer and
+ * the next line begins with a continuation character.
+ */
+ } while (fold && (retval != 1) && (n > 1)
+ && (ap_blookc(&next, in) == 1)
+ && ((next == ' ') || (next == '\t')));
+
+ return total;
+}
+
+
/*
* Reads headers from a buffer and returns an array of headers.
* Returns NULL on file error
- */
-array_header *
- ap_proxy_read_headers(pool *p, char *buffer, int size, BUFF *f)
-{
- int gotcr, len, i, j;
- array_header *resp_hdrs;
- struct hdr_entry *hdr;
- char *strp;
- const char *strcp;
-
- resp_hdrs = ap_make_array(p, 10, sizeof(struct hdr_entry));
- hdr = NULL;
-
- gotcr = 1;
- for (;;) {
- len = ap_bgets(buffer, size, f);
- if (len == -1)
+ * This routine tries to deal with too long lines and continuation lines.
+ * @@@: XXX: FIXME: currently the headers are passed thru un-merged.
+ * Is that okay, or should they be collapsed where possible?
+ */
+table *ap_proxy_read_headers(pool *p, char *buffer, int size, BUFF *f)
+{
+ table *resp_hdrs;
+ int len;
+ char *value, *end;
+ char field[MAX_STRING_LEN];
+
+ resp_hdrs = ap_make_table(p, 20);
+
+ /*
+ * Read header lines until we get the empty separator line, a read error,
+ * the connection closes (EOF), or we timeout.
+ */
+ while ((len = proxy_getline(buffer, size, f, 1)) > 0) {
+
+ if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */
return NULL;
- if (len == 0)
- break;
- if (buffer[len - 1] == '\n') {
- buffer[--len] = '\0';
- i = 1;
}
- else
- i = 0;
- if (!gotcr || buffer[0] == ' ' || buffer[0] == '\t') {
- /* a continuation header */
- if (hdr == NULL) {
- /* error!! */
- if (!i) {
- i = ap_bskiplf(f);
- if (i == -1)
- return NULL;
- }
- gotcr = 1;
- continue;
- }
- hdr->value = ap_pstrcat(p, hdr->value, buffer, NULL);
- }
- else if (gotcr && len == 0)
- break;
- else {
- strp = strchr(buffer, ':');
- if (strp == NULL) {
- /* error!! */
- if (!gotcr) {
- i = ap_bskiplf(f);
- if (i == -1)
- return NULL;
- }
- gotcr = 1;
- hdr = NULL;
- continue;
+ *value = '\0';
+ ++value;
+ /* XXX: RFC2068 defines only SP and HT as whitespace, this test is
+ * wrong... and so are many others probably.
+ */
+ while (ap_isspace(*value))
+ ++value; /* Skip to start of value */
+
+ /* should strip trailing whitespace as well */
+ for (end = &value[strlen(value)-1]; end > value && ap_isspace(*end); --end)
+ *end = '\0';
+
+ ap_table_add(resp_hdrs, buffer, value);
+
+ /* the header was too long; at the least we should skip extra data */
+ if (len >= size - 1) {
+ while ((len = proxy_getline(field, MAX_STRING_LEN, f, 1))
+ >= MAX_STRING_LEN - 1) {
+ /* soak up the extra data */
}
- hdr = ap_push_array(resp_hdrs);
- *(strp++) = '\0';
- hdr->field = ap_pstrdup(p, buffer);
- while (*strp == ' ' || *strp == '\t')
- strp++;
- hdr->value = ap_pstrdup(p, strp);
- gotcr = i;
+ if (len == 0) /* time to exit the larger loop as well */
+ break;
}
}
-
- hdr = (struct hdr_entry *) resp_hdrs->elts;
- for (i = 0; i < resp_hdrs->nelts; i++) {
- strcp = hdr[i].value;
- j = strlen(strcp);
- while (j > 0 && (strcp[j - 1] == ' ' || strcp[j - 1] == '\t'))
- j--;
- /* Note that this is OK, coz we created the header above */
- ((char *)strcp)[j] = '\0';
- }
-
return resp_hdrs;
}
-long int ap_proxy_send_fb(BUFF *f, request_rec *r, BUFF *f2, struct cache_req *c)
+long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c)
{
int ok = 1;
char buf[IOBUFSIZE];
@@ -457,8 +486,8 @@
#ifdef CHARSET_EBCDIC
/* The cache copy is ASCII, not EBCDIC, even for text/html) */
ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
- if (f2 != NULL)
- ap_bsetflag(f2, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
+ if (c != NULL && c->fp != NULL)
+ ap_bsetflag(c->fp, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
ap_bsetflag(con->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);
#endif
@@ -492,10 +521,11 @@
}
#endif
- while (ok && f != NULL) {
+ while (ok) {
if (alt_to)
ap_hard_timeout("proxy send body", r);
+ /* Read block from server */
n = ap_bread(f, buf, IOBUFSIZE);
if (alt_to)
@@ -504,8 +534,8 @@
ap_reset_timeout(r);
if (n == -1) { /* input error */
- if (f2 != NULL)
- f2 = ap_proxy_cache_error(c);
+ if (c != NULL)
+ c = ap_proxy_cache_error(c);
break;
}
if (n == 0)
@@ -513,14 +543,16 @@
o = 0;
total_bytes_rcv += n;
- if (f2 != NULL) {
- if (ap_bwrite(f2, &buf[0], n) != n) {
- f2 = ap_proxy_cache_error(c);
+ /* Write to cache first. */
+ if (c != NULL && c->fp != NULL) {
+ if (ap_bwrite(c->fp, &buf[0], n) != n) {
+ c = ap_proxy_cache_error(c);
} else {
c->written += n;
}
}
+ /* Write the block to the client, detect aborted transfers */
while (n && !con->aborted) {
if (alt_to)
ap_soft_timeout("proxy send body", r);
@@ -533,7 +565,7 @@
ap_reset_timeout(r);
if (w <= 0) {
- if (f2 != NULL) {
+ if (c != NULL) {
/* when a send failure occurs, we need to decide
* whether to continue loading and caching the
* document, or to abort the whole thing
@@ -545,8 +577,8 @@
if (! ok) {
ap_pclosef(c->req->pool, c->fp->fd);
c->fp = NULL;
- f2 = NULL;
unlink(c->tempfile);
+ c = NULL;
}
}
con->aborted = 1;
@@ -565,85 +597,28 @@
}
/*
- * Read a header from the array, returning the first entry
- */
-struct hdr_entry *
- ap_proxy_get_header(array_header *hdrs_arr, const char *name)
-{
- struct hdr_entry *hdrs;
- int i;
-
- hdrs = (struct hdr_entry *) hdrs_arr->elts;
- for (i = 0; i < hdrs_arr->nelts; i++)
- if (hdrs[i].field != NULL && strcasecmp(name, hdrs[i].field) == 0)
- return &hdrs[i];
-
- return NULL;
-}
-
-/*
- * Add to the header reply, either concatenating, or replacing existin
- * headers. It stores the pointers provided, so make sure the data
- * is not subsequently overwritten
- */
-struct hdr_entry *
- ap_proxy_add_header(array_header *hdrs_arr, const char *field, const char *value,
- int rep)
-{
- int i;
- struct hdr_entry *hdrs;
-
- hdrs = (struct hdr_entry *) hdrs_arr->elts;
- if (rep)
- for (i = 0; i < hdrs_arr->nelts; i++)
- if (hdrs[i].field != NULL && strcasecmp(field, hdrs[i].field) == 0) {
- hdrs[i].value = value;
- return hdrs;
- }
-
- hdrs = ap_push_array(hdrs_arr);
- hdrs->field = field;
- hdrs->value = value;
-
- return hdrs;
-}
-
-void ap_proxy_del_header(array_header *hdrs_arr, const char *field)
-{
- int i;
- struct hdr_entry *hdrs;
-
- hdrs = (struct hdr_entry *) hdrs_arr->elts;
-
- for (i = 0; i < hdrs_arr->nelts; i++)
- if (hdrs[i].field != NULL && strcasecmp(field, hdrs[i].field) == 0)
- hdrs[i].value = NULL;
-}
-
-/*
* Sends response line and headers. Uses the client fd and the
* headers_out array from the passed request_rec to talk to the client
* and to properly set the headers it sends for things such as logging.
*
* A timeout should be set before calling this routine.
*/
-void ap_proxy_send_headers(request_rec *r, const char *respline, array_header *hdrs_arr)
+void ap_proxy_send_headers(request_rec *r, const char *respline, table *t)
{
- struct hdr_entry *hdrs;
int i;
BUFF *fp = r->connection->client;
-
- hdrs = (struct hdr_entry *) hdrs_arr->elts;
+ table_entry *elts = (table_entry *) ap_table_elts(t)->elts;
ap_bputs(respline, fp);
ap_bputs(CRLF, fp);
- for (i = 0; i < hdrs_arr->nelts; i++) {
- if (hdrs[i].field == NULL)
- continue;
- ap_bvputs(fp, hdrs[i].field, ": ", hdrs[i].value, CRLF, NULL);
- /* XXX: can't this be ap_table_setn? -djg */
- ap_table_set(r->headers_out, hdrs[i].field, hdrs[i].value);
- /* XXX: another O(n^2) attack, fixed by ap_overlap_tables */
+
+ for (i = 0; i < ap_table_elts(t)->nelts; ++i) {
+ if (elts[i].key != NULL) {
+ ap_bvputs(fp, elts[i].key, ": ", elts[i].val, CRLF, NULL);
+ /* FIXME: @@@ This used to be ap_table_set(), but I think
+ * ap_table_addn() is correct. MnKr */
+ ap_table_addn(r->headers_out, elts[i].key, elts[i].val);
+ }
}
ap_bputs(CRLF, fp);
@@ -829,8 +804,8 @@
y[8] = '\0';
}
-BUFF *
- ap_proxy_cache_error(struct cache_req *c)
+
+cache_req *ap_proxy_cache_error(cache_req *c)
{
ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
"proxy: error writing to cache file %s", c->tempfile);
@@ -1253,3 +1228,30 @@
return i;
}
+
+/* This function is called by ap_table_do() for all header lines */
+/* (from proxy_http.c and proxy_ftp.c) */
+/* It is passed a table_do_args struct pointer and a MIME field and value pair */
+int ap_proxy_send_hdr_line(void *p, const char *key, const char *value)
+{
+ struct tbl_do_args *parm = (struct tbl_do_args *)p;
+
+ if (key == NULL || value == NULL || value[0] == '\0')
+ return 1;
+ if (!parm->req->assbackwards)
+ ap_rvputs(parm->req, key, ": ", value, CRLF, NULL);
+ if (parm->cache != NULL && parm->cache->fp != NULL &&
+ ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1)
+ parm->cache = ap_proxy_cache_error(parm->cache);
+ return 1; /* tell ap_table_do() to continue calling us for more headers */
+}
+
+/* send a text line to one or two BUFF's; return line length */
+unsigned ap_proxy_bputs2(const char *data, BUFF *client, cache_req *cache)
+{
+ unsigned len = ap_bputs(data, client);
+ if (cache != NULL && cache->fp != NULL)
+ ap_bputs(data, cache->fp);
+ return len;
+}
+