Commit 5c36191f authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Beat a path through, where we can successfully ungzip an trivial object,

when the client does not support gzip.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5680 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ee8ad9e3
......@@ -741,6 +741,7 @@ void WSL_Flush(struct worker *w, int overflow);
/* cache_response.c */
void RES_BuildHttp(struct sess *sp);
void RES_WriteObj(struct sess *sp);
void RES_WriteGunzipObj(struct sess *sp);
/* cache_vary.c */
struct vsb *VRY_Create(const struct sess *sp, const struct http *hp);
......
......@@ -210,7 +210,14 @@ cnt_deliver(struct sess *sp)
sp->director = NULL;
sp->restarts = 0;
RES_WriteObj(sp);
if (params->http_gzip_support &&
http_HdrIs(sp->wrk->resp, H_Content_Encoding, "gzip") &&
!RFC2616_Req_Gzip(sp) &&
sp->wantbody)
RES_WriteGunzipObj(sp);
else
RES_WriteObj(sp);
AZ(sp->wrk->wfd);
(void)HSH_Deref(sp->wrk, NULL, &sp->obj);
sp->wrk->resp = NULL;
......@@ -879,6 +886,15 @@ cnt_miss(struct sess *sp)
http_Setup(sp->wrk->bereq, sp->wrk->ws);
http_FilterHeader(sp, HTTPH_R_FETCH);
http_ForceGet(sp->wrk->bereq);
if (params->http_gzip_support) {
/*
* We always ask the backend for gzip, even if the
* client doesn't grok it. We will uncompress for
* the minority of clients which don't.
*/
http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq,
"Accept-Encoding: gzip");
}
sp->wrk->connect_timeout = 0;
sp->wrk->first_byte_timeout = 0;
sp->wrk->between_bytes_timeout = 0;
......
......@@ -245,7 +245,6 @@ RES_WriteObj(struct sess *sp)
char *r;
unsigned low, high, ptr, off, len;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
WRW_Reserve(sp->wrk, &sp->fd);
......@@ -274,7 +273,7 @@ RES_WriteObj(struct sess *sp)
high = sp->obj->len - 1;
if (sp->disable_esi || sp->esis == 0) {
/* For none ESI and non ESI-included objects, try Range */
/* For non-ESI and non ESI-included objects, try Range */
if (params->http_range_support &&
(sp->disable_esi || sp->esis == 0) &&
sp->obj->response == 200 &&
......@@ -358,3 +357,109 @@ RES_WriteObj(struct sess *sp)
if (WRW_FlushRelease(sp->wrk))
vca_close_session(sp, "remote closed");
}
/*--------------------------------------------------------------------
* We have a gzip'ed object and need to ungzip it for a client which
* does not understand gzip.
*/
void
RES_WriteGunzipObj(struct sess *sp)
{
struct storage *st;
unsigned u = 0;
#if 0
char lenbuf[20];
#endif
struct vgz *vg;
const void *dp;
size_t dl;
int i;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
AN(sp->wantbody);
WRW_Reserve(sp->wrk, &sp->fd);
/* We don't know the length (XXX: Cache once we do ?) */
http_Unset(sp->wrk->resp, H_Content_Length);
http_Unset(sp->wrk->resp, H_Content_Encoding);
http_Unset(sp->wrk->resp, H_Connection);
http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp, "Connection: %s",
"close");
sp->doclose = "Gunzip EOF";
/*
* ESI objects get special delivery
*/
if (!sp->disable_esi && sp->obj->esidata != NULL) {
INCOMPL();
#if 0
if (sp->esis == 0)
/* no headers for interior ESI includes */
sp->acct_tmp.hdrbytes +=
http_Write(sp->wrk, sp->wrk->resp, 1);
if (WRW_FlushRelease(sp->wrk)) {
vca_close_session(sp, "remote closed");
} else
ESI_Deliver(sp);
return;
#endif
}
if (sp->disable_esi || sp->esis == 0) {
sp->acct_tmp.hdrbytes += http_Write(sp->wrk, sp->wrk->resp, 1);
} else if (!sp->disable_esi &&
sp->esis > 0 &&
sp->http->protover >= 1.1 &&
sp->obj->len > 0) {
INCOMPL();
#if 0
/*
* Interior ESI includes (which are not themselves ESI
* objects) use chunked encoding (here) or EOF (nothing)
*/
sprintf(lenbuf, "%x\r\n", sp->obj->len);
(void)WRW_Write(sp->wrk, lenbuf, -1);
#endif
}
vg = VGZ_NewUnzip(sp, sp->ws, sp->wrk->ws);
AN(vg);
VTAILQ_FOREACH(st, &sp->obj->store, list) {
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
u += st->len;
sp->acct_tmp.bodybytes += st->len;
VSC_main->n_objwrite++;
VGZ_Feed(vg, st->ptr, st->len);
do {
i = VGZ_Produce(vg, &dp, &dl);
if (dl != 0) {
(void)WRW_Write(sp->wrk, dp, dl);
if (WRW_Flush(sp->wrk))
break;
}
} while (i == 0);
}
VGZ_Destroy(&vg);
assert(u == sp->obj->len);
if (!sp->disable_esi &&
sp->esis > 0 &&
sp->http->protover >= 1.1 &&
sp->obj->len > 0) {
INCOMPL();
#if 0
/* post-chunk new line */
(void)WRW_Write(sp->wrk, "\r\n", -1);
#endif
}
if (WRW_FlushRelease(sp->wrk))
vca_close_session(sp, "remote closed");
}
# $Id$
test "test basic gunzip for client"
server s1 {
rxreq
expect req.http.accept-encoding == "gzip"
txresp -gzipbody FOO
} -start
varnish v1 -cliok "param.set http_gzip_support true" -vcl+backend {
} -start
client c1 {
txreq
rxresp
expect resp.bodylen == "3"
expect resp.http.content-encoding == "resp.http.content-encoding"
} -run
client c1 {
txreq -hdr "Accept-encoding: gzip;q=0.1"
rxresp
expect resp.http.content-encoding == "gzip"
gunzip
expect resp.bodylen == "3"
} -run
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment