You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by "Roy T. Fielding" <fi...@kiwi.ics.uci.edu> on 1997/08/13 05:56:59 UTC
[PATCH] for 1.2.X: proxy screwup
This fixes most of the proxy problems mentioned on http-wg. It prevents
the proxy responses from returning as HTTP/1.1 on errors or when the
response is from the cache. The only thing I haven't figured out is
how to handle
OPTIONS * HTTP/1.1
Right now, http_core always handles it. It would probably be better
if it was handled within mod_proxy as well, which would give it a
different response only if the proxy was enabled.
BTW, our proxy won't cache pages without a Last-Modified date, even
if the page has an Expires. The CacheNegotiatedDocs and XBitHack things
should be adding their own Last-Modified, with the same value as Date.
....Roy
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.126.2.5
diff -c -r1.126.2.5 http_protocol.c
*** http_protocol.c 1997/07/31 08:19:48 1.126.2.5
--- http_protocol.c 1997/08/13 03:42:23
***************
*** 1044,1052 ****
if (!r->status_line)
r->status_line = status_lines[index_of_response(r->status)];
! if (r->proto_num == 1000
! && table_get(r->subprocess_env,"force-response-1.0"))
protocol = "HTTP/1.0";
else
protocol = SERVER_PROTOCOL;
--- 1044,1059 ----
if (!r->status_line)
r->status_line = status_lines[index_of_response(r->status)];
! /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
! * kluge around broken browsers when indicated by force-response-1.0
! */
! if (r->proxyreq
! || (r->proto_num == 1000
! && table_get(r->subprocess_env,"force-response-1.0"))) {
!
protocol = "HTTP/1.0";
+ r->connection->keepalive = -1;
+ }
else
protocol = SERVER_PROTOCOL;
Index: modules/proxy/mod_proxy.h
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/mod_proxy.h,v
retrieving revision 1.11
diff -c -r1.11 mod_proxy.h
*** mod_proxy.h 1997/04/16 00:13:05 1.11
--- mod_proxy.h 1997/08/13 03:42:23
***************
*** 225,231 ****
int proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
struct cache_req **cr);
int proxy_cache_update(struct cache_req *c, array_header *resp_hdrs,
! const char *protocol, int nocache);
void proxy_garbage_coll(request_rec *r);
/* proxy_connect.c */
--- 225,231 ----
int proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
struct cache_req **cr);
int proxy_cache_update(struct cache_req *c, array_header *resp_hdrs,
! const int is_HTTP1, int nocache);
void proxy_garbage_coll(request_rec *r);
/* proxy_connect.c */
Index: modules/proxy/proxy_cache.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_cache.c,v
retrieving revision 1.13
diff -c -r1.13 proxy_cache.c
*** proxy_cache.c 1997/05/29 15:16:01 1.13
--- proxy_cache.c 1997/08/13 03:42:23
***************
*** 581,587 ****
*/
int
proxy_cache_update(struct cache_req *c, array_header *resp_hdrs,
! const char *protocol, int nocache)
{
request_rec *r=c->req;
char *p;
--- 581,587 ----
*/
int
proxy_cache_update(struct cache_req *c, array_header *resp_hdrs,
! const int is_HTTP1, int nocache)
{
request_rec *r=c->req;
char *p;
***************
*** 632,639 ****
if ((r->status != 200 && r->status != 301 && r->status != 304) ||
(expire != NULL && expc == BAD_DATE) ||
(r->status == 304 && c->fp == NULL) ||
! (r->status == 200 && lmods == NULL &&
! strncmp(protocol, "HTTP/1.", 7) == 0) ||
r->header_only ||
table_get(r->headers_in, "Authorization") != NULL ||
nocache)
--- 632,638 ----
if ((r->status != 200 && r->status != 301 && r->status != 304) ||
(expire != NULL && expc == BAD_DATE) ||
(r->status == 304 && c->fp == NULL) ||
! (r->status == 200 && lmods == NULL && is_HTTP1) ||
r->header_only ||
table_get(r->headers_in, "Authorization") != NULL ||
nocache)
Index: modules/proxy/proxy_ftp.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_ftp.c,v
retrieving revision 1.21
diff -c -r1.21 proxy_ftp.c
*** proxy_ftp.c 1997/04/22 03:29:37 1.21
--- proxy_ftp.c 1997/08/13 03:42:23
***************
*** 908,914 ****
nocache = 1;
}
! i = proxy_cache_update(c, resp_hdrs, "FTP", nocache);
if (i != DECLINED)
{
--- 908,914 ----
nocache = 1;
}
! i = proxy_cache_update(c, resp_hdrs, 0, nocache);
if (i != DECLINED)
{
Index: modules/proxy/proxy_http.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_http.c,v
retrieving revision 1.17.2.1
diff -c -r1.17.2.1 proxy_http.c
*** proxy_http.c 1997/07/20 18:36:03 1.17.2.1
--- proxy_http.c 1997/08/13 03:42:23
***************
*** 143,149 ****
{
char *p;
const char *err, *desthost;
! int i, j, sock, len;
array_header *reqhdrs_arr, *resp_hdrs;
table_entry *reqhdrs;
struct sockaddr_in server;
--- 143,149 ----
{
char *p;
const char *err, *desthost;
! int i, j, sock, len, backasswards;
array_header *reqhdrs_arr, *resp_hdrs;
table_entry *reqhdrs;
struct sockaddr_in server;
***************
*** 151,157 ****
struct hostent server_hp;
BUFF *f, *cache;
struct hdr_entry *hdr;
! char buffer[HUGE_STRING_LEN], inprotocol[9], outprotocol[9];
pool *pool=r->pool;
const long int zero=0L;
int destport = 0;
--- 151,157 ----
struct hostent server_hp;
BUFF *f, *cache;
struct hdr_entry *hdr;
! char buffer[HUGE_STRING_LEN];
pool *pool=r->pool;
const long int zero=0L;
int destport = 0;
***************
*** 286,292 ****
return proxyerror(r, "Error reading from remote server");
}
! /* Is it an HTTP/1 response? */
if (checkmask(buffer, "HTTP/#.# ###*"))
{
/* If not an HTTP/1 messsage or if the status line was > 8192 bytes */
--- 286,292 ----
return proxyerror(r, "Error reading from remote server");
}
! /* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */
if (checkmask(buffer, "HTTP/#.# ###*"))
{
/* If not an HTTP/1 messsage or if the status line was > 8192 bytes */
***************
*** 296,307 ****
kill_timeout(r);
return BAD_GATEWAY;
}
buffer[--len] = '\0';
- memcpy(inprotocol, buffer, 8);
- inprotocol[8] = '\0';
- /* we use the same protocol on output as on input */
- strcpy(outprotocol, inprotocol);
buffer[12] = '\0';
r->status = atoi(&buffer[9]);
buffer[12] = ' ';
--- 296,304 ----
kill_timeout(r);
return BAD_GATEWAY;
}
+ backasswards = 0;
buffer[--len] = '\0';
buffer[12] = '\0';
r->status = atoi(&buffer[9]);
buffer[12] = ' ';
***************
*** 312,322 ****
/* Also, take care with headers with multiple occurences. */
resp_hdrs = proxy_read_headers(pool, buffer, HUGE_STRING_LEN, f);
! } else
{
/* an http/0.9 response */
! strcpy(inprotocol, "HTTP/0.9");
! strcpy(outprotocol, "HTTP/1.0");
r->status = 200;
r->status_line = "200 OK";
--- 309,321 ----
/* Also, take care with headers with multiple occurences. */
resp_hdrs = proxy_read_headers(pool, buffer, HUGE_STRING_LEN, f);
!
! clear_connection((table *)resp_hdrs); /* Strip Connection hdrs */
! }
! else
{
/* an http/0.9 response */
! backasswards = 1;
r->status = 200;
r->status_line = "200 OK";
***************
*** 350,356 ****
nocache = 1;
}
! i = proxy_cache_update(c, resp_hdrs, inprotocol, nocache);
if (i != DECLINED)
{
pclosef(pool, sock);
--- 349,355 ----
nocache = 1;
}
! i = proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
if (i != DECLINED)
{
pclosef(pool, sock);
***************
*** 365,372 ****
if (!r->assbackwards)
rvputs(r, "HTTP/1.0 ", r->status_line, "\015\012", NULL);
if (cache != NULL)
! if (bvputs(cache, outprotocol, " ", r->status_line, "\015\012", NULL)
! == -1)
cache = proxy_cache_error(c);
/* send headers */
--- 364,370 ----
if (!r->assbackwards)
rvputs(r, "HTTP/1.0 ", r->status_line, "\015\012", NULL);
if (cache != NULL)
! if (bvputs(cache, "HTTP/1.0 ", r->status_line, "\015\012", NULL) == -1)
cache = proxy_cache_error(c);
/* send headers */
***************
*** 389,395 ****
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 (strcmp(inprotocol, "HTTP/0.9") == 0)
{
bwrite(r->connection->client, buffer, len);
if (cache != NULL)
--- 387,393 ----
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)
{
bwrite(r->connection->client, buffer, len);
if (cache != NULL)
Re: [PATCH] for 1.2.X: proxy screwup
Posted by Marc Slemko <ma...@worldgate.com>.
On Tue, 12 Aug 1997, Roy T. Fielding wrote:
> This fixes most of the proxy problems mentioned on http-wg. It prevents
> the proxy responses from returning as HTTP/1.1 on errors or when the
> response is from the cache. The only thing I haven't figured out is
> how to handle
I haven't looked at the patch in detail but, but it looks simple (the
patch looks simple; the ideas behind it aren't necessarily and the
completeness isn't obvious without a good look at the code).
Do we want to hold 1.2.3 for this? I would say yes.
Roy, are you reasonably confident that this patch fixes everything
involved in this problem and will conform to the way things should
be?
Re: [PATCH] for 1.2.X: proxy screwup
Posted by Brian Behlendorf <br...@organic.com>.
At 08:56 PM 8/12/97 -0700, Roy T. Fielding wrote:
>This fixes most of the proxy problems mentioned on http-wg.
+1 on holding 1.2.3 for consideration of this patch.
Brian
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
"Why not?" - TL brian@organic.com - hyperreal.org - apache.org