Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
58461688
Commit
58461688
authored
Jan 24, 2011
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add code to gunzip an ESI VEC string, if a gzip'ed ESI object is included
from a non-gzip ESI object or during gunzip delivery.
parent
1b9e19cb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
110 additions
and
51 deletions
+110
-51
cache.h
bin/varnishd/cache.h
+1
-1
cache_esi_deliver.c
bin/varnishd/cache_esi_deliver.c
+100
-50
cache_esi_fetch.c
bin/varnishd/cache_esi_fetch.c
+2
-0
flint.sh
bin/varnishd/flint.sh
+1
-0
e00024.vtc
bin/varnishtest/tests/e00024.vtc
+6
-0
No files found.
bin/varnishd/cache.h
View file @
58461688
...
@@ -822,7 +822,7 @@ char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
...
@@ -822,7 +822,7 @@ char *VRT_String(struct ws *ws, const char *h, const char *p, va_list ap);
char
*
VRT_StringList
(
char
*
d
,
unsigned
dl
,
const
char
*
p
,
va_list
ap
);
char
*
VRT_StringList
(
char
*
d
,
unsigned
dl
,
const
char
*
p
,
va_list
ap
);
void
ESI_Deliver
(
struct
sess
*
);
void
ESI_Deliver
(
struct
sess
*
);
void
ESI_DeliverChild
(
struct
sess
*
);
void
ESI_DeliverChild
(
const
struct
sess
*
);
/* cache_vrt_vmod.c */
/* cache_vrt_vmod.c */
void
VMOD_Init
(
void
);
void
VMOD_Init
(
void
);
...
...
bin/varnishd/cache_esi_deliver.c
View file @
58461688
...
@@ -195,32 +195,33 @@ ved_decode_len(uint8_t **pp)
...
@@ -195,32 +195,33 @@ ved_decode_len(uint8_t **pp)
*/
*/
static
void
static
void
ved_pretend_gzip
(
struct
sess
*
sp
,
uint8_t
*
p
,
ssize_t
l
)
ved_pretend_gzip
(
const
struct
sess
*
sp
,
const
uint8_t
*
p
,
ssize_t
l
)
{
{
ssize_t
ll
;
uint8_t
buf
[
5
];
uint8_t
buf
[
5
];
char
chunk
[
20
];
char
chunk
[
20
];
uint16_t
lx
;
while
(
l
>
0
)
{
while
(
l
>
0
)
{
ll
=
l
;
if
(
l
>
65535
)
if
(
ll
>
65535
)
lx
=
65535
;
ll
=
65535
;
else
lx
=
(
uint16_t
)
l
;
buf
[
0
]
=
0
;
buf
[
0
]
=
0
;
vle16enc
(
buf
+
1
,
l
l
);
vle16enc
(
buf
+
1
,
l
x
);
vle16enc
(
buf
+
3
,
~
l
l
);
vle16enc
(
buf
+
3
,
~
l
x
);
if
(
sp
->
wrk
->
res_mode
&
RES_CHUNKED
)
{
if
(
sp
->
wrk
->
res_mode
&
RES_CHUNKED
)
{
bprintf
(
chunk
,
"%
jx
\r\n
"
,
(
intmax_t
)
ll
+
5
);
bprintf
(
chunk
,
"%
x
\r\n
"
,
lx
+
5
);
(
void
)
WRW_Write
(
sp
->
wrk
,
chunk
,
-
1
);
(
void
)
WRW_Write
(
sp
->
wrk
,
chunk
,
-
1
);
}
}
(
void
)
WRW_Write
(
sp
->
wrk
,
buf
,
sizeof
buf
);
(
void
)
WRW_Write
(
sp
->
wrk
,
buf
,
sizeof
buf
);
(
void
)
WRW_Write
(
sp
->
wrk
,
p
,
l
l
);
(
void
)
WRW_Write
(
sp
->
wrk
,
p
,
l
x
);
if
(
sp
->
wrk
->
res_mode
&
RES_CHUNKED
)
if
(
sp
->
wrk
->
res_mode
&
RES_CHUNKED
)
(
void
)
WRW_Write
(
sp
->
wrk
,
"
\r\n
"
,
-
1
);
(
void
)
WRW_Write
(
sp
->
wrk
,
"
\r\n
"
,
-
1
);
(
void
)
WRW_Flush
(
sp
->
wrk
);
(
void
)
WRW_Flush
(
sp
->
wrk
);
sp
->
wrk
->
crc
=
crc32
(
sp
->
wrk
->
crc
,
p
,
l
l
);
sp
->
wrk
->
crc
=
crc32
(
sp
->
wrk
->
crc
,
p
,
l
x
);
sp
->
wrk
->
l_crc
+=
l
l
;
sp
->
wrk
->
l_crc
+=
l
x
;
l
-=
l
l
;
l
-=
l
x
;
p
+=
l
l
;
p
+=
l
x
;
}
}
}
}
...
@@ -233,14 +234,24 @@ ESI_Deliver(struct sess *sp)
...
@@ -233,14 +234,24 @@ ESI_Deliver(struct sess *sp)
struct
storage
*
st
;
struct
storage
*
st
;
uint8_t
*
p
,
*
e
,
*
q
,
*
r
;
uint8_t
*
p
,
*
e
,
*
q
,
*
r
;
unsigned
off
;
unsigned
off
;
ssize_t
l
,
l_icrc
;
ssize_t
l
,
l_icrc
=
0
;
uint32_t
icrc
;
uint32_t
icrc
=
0
;
uint8_t
tailbuf
[
8
+
5
];
uint8_t
tailbuf
[
8
+
5
];
int
isgzip
;
int
isgzip
;
struct
vgz
*
vgz
=
NULL
;
char
obuf
[
1024
*
params
->
gzip_stack_buffer
];
ssize_t
obufl
=
0
;
size_t
dl
;
const
void
*
dp
;
int
i
;
CHECK_OBJ_NOTNULL
(
sp
,
SESS_MAGIC
);
CHECK_OBJ_NOTNULL
(
sp
,
SESS_MAGIC
);
st
=
sp
->
obj
->
esidata
;
st
=
sp
->
obj
->
esidata
;
AN
(
st
);
AN
(
st
);
assert
(
sizeof
obuf
>=
1024
);
obuf
[
0
]
=
0
;
/* For flexelint */
p
=
st
->
ptr
;
p
=
st
->
ptr
;
e
=
st
->
ptr
+
st
->
len
;
e
=
st
->
ptr
+
st
->
len
;
...
@@ -252,16 +263,24 @@ ESI_Deliver(struct sess *sp)
...
@@ -252,16 +263,24 @@ ESI_Deliver(struct sess *sp)
}
}
if
(
sp
->
esi_level
==
0
)
{
if
(
sp
->
esi_level
==
0
)
{
if
(
isgzip
)
{
/*
* Only the top level document gets to decide this.
*/
if
(
isgzip
&&
!
(
sp
->
wrk
->
res_mode
&
RES_GUNZIP
))
{
sp
->
wrk
->
gzip_resp
=
1
;
sp
->
wrk
->
gzip_resp
=
1
;
sp
->
wrk
->
crc
=
crc32
(
0L
,
Z_NULL
,
0
);
sp
->
wrk
->
crc
=
crc32
(
0L
,
Z_NULL
,
0
);
}
else
}
else
sp
->
wrk
->
gzip_resp
=
0
;
sp
->
wrk
->
gzip_resp
=
0
;
}
}
if
(
isgzip
&&
!
sp
->
wrk
->
gzip_resp
)
{
vgz
=
VGZ_NewUngzip
(
sp
,
sp
->
wrk
->
ws
);
obufl
=
0
;
}
st
=
VTAILQ_FIRST
(
&
sp
->
obj
->
store
);
st
=
VTAILQ_FIRST
(
&
sp
->
obj
->
store
);
off
=
0
;
off
=
0
;
while
(
p
<
e
)
{
while
(
p
<
e
)
{
switch
(
*
p
)
{
switch
(
*
p
)
{
case
VEC_V1
:
case
VEC_V1
:
...
@@ -271,39 +290,65 @@ ESI_Deliver(struct sess *sp)
...
@@ -271,39 +290,65 @@ ESI_Deliver(struct sess *sp)
r
=
p
;
r
=
p
;
q
=
(
void
*
)
strchr
((
const
char
*
)
p
,
'\0'
);
q
=
(
void
*
)
strchr
((
const
char
*
)
p
,
'\0'
);
p
=
q
+
1
;
p
=
q
+
1
;
if
(
sp
->
wrk
->
gzip_resp
)
{
if
(
isgzip
)
{
if
(
isgzip
)
{
assert
(
*
p
==
VEC_C1
||
*
p
==
VEC_C2
||
assert
(
*
p
==
VEC_C1
||
*
p
==
VEC_C2
||
*
p
==
VEC_C8
);
*
p
==
VEC_C8
);
l_icrc
=
ved_decode_len
(
&
p
);
l_icrc
=
ved_decode_len
(
&
p
);
icrc
=
vbe32dec
(
p
);
icrc
=
vbe32dec
(
p
);
p
+=
4
;
p
+=
4
;
}
sp
->
wrk
->
crc
=
crc32_combine
(
if
(
sp
->
wrk
->
gzip_resp
&&
isgzip
)
{
sp
->
wrk
->
crc
,
icrc
,
l_icrc
);
/*
sp
->
wrk
->
l_crc
+=
l_icrc
;
* We have a gzip'ed VEC and delivers a
if
(
sp
->
esi_level
>
0
&&
off
==
0
)
{
* gzip'ed ESI response.
assert
(
l
>
10
);
*/
sp
->
wrk
->
crc
=
crc32_combine
(
sp
->
wrk
->
crc
,
icrc
,
l_icrc
);
sp
->
wrk
->
l_crc
+=
l_icrc
;
if
(
sp
->
esi_level
>
0
&&
off
==
0
)
{
/*
* Skip the GZ header, we know it is
* 10 bytes: we made it ourself.
*/
assert
(
l
>
10
);
ved_sendchunk
(
sp
,
NULL
,
0
,
ved_sendchunk
(
sp
,
NULL
,
0
,
st
->
ptr
+
off
+
10
,
l
-
10
);
st
->
ptr
+
10
,
l
-
10
);
}
else
{
ved_sendchunk
(
sp
,
r
,
q
-
r
,
st
->
ptr
+
off
,
l
);
}
off
+=
l
;
}
else
{
ved_pretend_gzip
(
sp
,
st
->
ptr
+
off
,
l
);
off
+=
l
;
}
}
else
{
if
(
isgzip
)
{
INCOMPL
();
}
else
{
}
else
{
ved_sendchunk
(
sp
,
r
,
q
-
r
,
ved_sendchunk
(
sp
,
r
,
q
-
r
,
st
->
ptr
+
off
,
l
);
st
->
ptr
+
off
,
l
);
off
+=
l
;
}
}
}
else
if
(
sp
->
wrk
->
gzip_resp
)
{
/*
* A gzip'ed ESI response, but the VEC was
* not gzip'ed.
*/
ved_pretend_gzip
(
sp
,
st
->
ptr
+
off
,
l
);
off
+=
l
;
}
else
if
(
isgzip
)
{
/*
* A gzip'ed VEC, but ungzip'ed ESI response
*/
AN
(
vgz
);
VGZ_Ibuf
(
vgz
,
st
->
ptr
+
off
,
l
);
do
{
if
(
obufl
==
sizeof
obuf
)
{
ved_sendchunk
(
sp
,
NULL
,
0
,
obuf
,
obufl
);
obufl
=
0
;
}
VGZ_Obuf
(
vgz
,
obuf
+
obufl
,
sizeof
obuf
-
obufl
);
i
=
VGZ_Gunzip
(
vgz
,
&
dp
,
&
dl
);
assert
(
i
==
Z_OK
||
i
==
Z_STREAM_END
);
obufl
+=
dl
;
}
while
(
!
VGZ_IbufEmpty
(
vgz
));
}
else
{
/*
* Ungzip'ed VEC, ungzip'ed ESI response
*/
ved_sendchunk
(
sp
,
r
,
q
-
r
,
st
->
ptr
+
off
,
l
);
}
}
off
+=
l
;
break
;
break
;
case
VEC_S1
:
case
VEC_S1
:
case
VEC_S2
:
case
VEC_S2
:
...
@@ -329,6 +374,11 @@ assert(l > 10);
...
@@ -329,6 +374,11 @@ assert(l > 10);
INCOMPL
();
INCOMPL
();
}
}
}
}
if
(
vgz
!=
NULL
)
{
if
(
obufl
>
0
)
ved_sendchunk
(
sp
,
NULL
,
0
,
obuf
,
obufl
);
VGZ_Destroy
(
&
vgz
);
}
if
(
sp
->
wrk
->
gzip_resp
&&
sp
->
esi_level
==
0
)
{
if
(
sp
->
wrk
->
gzip_resp
&&
sp
->
esi_level
==
0
)
{
/* Emit a gzip literal block with finish bit set */
/* Emit a gzip literal block with finish bit set */
tailbuf
[
0
]
=
0x01
;
tailbuf
[
0
]
=
0x01
;
...
@@ -352,8 +402,8 @@ assert(l > 10);
...
@@ -352,8 +402,8 @@ assert(l > 10);
* Include an object in a gzip'ed ESI object delivery
* Include an object in a gzip'ed ESI object delivery
*/
*/
static
u
nsigned
static
u
int8_t
ved_deliver_byterange
(
struct
sess
*
sp
,
ssize_t
low
,
ssize_t
high
)
ved_deliver_byterange
(
const
struct
sess
*
sp
,
ssize_t
low
,
ssize_t
high
)
{
{
struct
storage
*
st
;
struct
storage
*
st
;
ssize_t
l
,
lx
;
ssize_t
l
,
lx
;
...
@@ -392,7 +442,7 @@ ved_deliver_byterange(struct sess *sp, ssize_t low, ssize_t high)
...
@@ -392,7 +442,7 @@ ved_deliver_byterange(struct sess *sp, ssize_t low, ssize_t high)
}
}
void
void
ESI_DeliverChild
(
struct
sess
*
sp
)
ESI_DeliverChild
(
const
struct
sess
*
sp
)
{
{
struct
storage
*
st
;
struct
storage
*
st
;
struct
object
*
obj
;
struct
object
*
obj
;
...
@@ -400,7 +450,7 @@ ESI_DeliverChild(struct sess *sp)
...
@@ -400,7 +450,7 @@ ESI_DeliverChild(struct sess *sp)
u_char
*
p
,
cc
;
u_char
*
p
,
cc
;
uint32_t
icrc
;
uint32_t
icrc
;
uint32_t
ilen
;
uint32_t
ilen
;
uint8_t
pad
[
6
];
uint8_t
pad
[
6
]
=
{
0
}
;
if
(
!
sp
->
obj
->
gziped
)
{
if
(
!
sp
->
obj
->
gziped
)
{
VTAILQ_FOREACH
(
st
,
&
sp
->
obj
->
store
,
list
)
VTAILQ_FOREACH
(
st
,
&
sp
->
obj
->
store
,
list
)
...
@@ -433,7 +483,7 @@ ESI_DeliverChild(struct sess *sp)
...
@@ -433,7 +483,7 @@ ESI_DeliverChild(struct sess *sp)
*/
*/
cc
=
ved_deliver_byterange
(
sp
,
start
/
8
,
last
/
8
);
cc
=
ved_deliver_byterange
(
sp
,
start
/
8
,
last
/
8
);
//printf("CC_LAST %x\n", cc);
//printf("CC_LAST %x\n", cc);
cc
&=
~
(
1
<<
(
start
&
7
));
cc
&=
~
(
1
U
<<
(
start
&
7
));
ved_sendchunk
(
sp
,
NULL
,
0
,
&
cc
,
1
);
ved_sendchunk
(
sp
,
NULL
,
0
,
&
cc
,
1
);
cc
=
ved_deliver_byterange
(
sp
,
1
+
last
/
8
,
stop
/
8
);
cc
=
ved_deliver_byterange
(
sp
,
1
+
last
/
8
,
stop
/
8
);
//printf("CC_STOP %x (%d)\n", cc, (int)(stop & 7));
//printf("CC_STOP %x (%d)\n", cc, (int)(stop & 7));
...
@@ -474,7 +524,7 @@ ESI_DeliverChild(struct sess *sp)
...
@@ -474,7 +524,7 @@ ESI_DeliverChild(struct sess *sp)
lpad
=
6
;
lpad
=
6
;
break
;
break
;
default
:
default
:
AZ
(
stop
&
7
);
INCOMPL
(
);
}
}
if
(
lpad
>
0
)
if
(
lpad
>
0
)
ved_sendchunk
(
sp
,
NULL
,
0
,
pad
,
lpad
);
ved_sendchunk
(
sp
,
NULL
,
0
,
pad
,
lpad
);
...
...
bin/varnishd/cache_esi_fetch.c
View file @
58461688
...
@@ -257,6 +257,8 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes)
...
@@ -257,6 +257,8 @@ vfp_esi_bytes_gg(struct sess *sp, struct http_conn *htc, size_t bytes)
CHECK_OBJ_NOTNULL
(
sp
,
SESS_MAGIC
);
CHECK_OBJ_NOTNULL
(
sp
,
SESS_MAGIC
);
vef
=
sp
->
wrk
->
vef_priv
;
vef
=
sp
->
wrk
->
vef_priv
;
CHECK_OBJ_NOTNULL
(
vef
,
VEF_MAGIC
);
CHECK_OBJ_NOTNULL
(
vef
,
VEF_MAGIC
);
assert
(
sizeof
ibuf
>=
1024
);
ibuf2
[
0
]
=
0
;
/* For Flexelint */
while
(
bytes
>
0
)
{
while
(
bytes
>
0
)
{
w
=
vef_read
(
htc
,
ibuf
,
sizeof
ibuf
,
bytes
);
w
=
vef_read
(
htc
,
ibuf
,
sizeof
ibuf
,
bytes
);
...
...
bin/varnishd/flint.sh
View file @
58461688
...
@@ -5,6 +5,7 @@ flexelint \
...
@@ -5,6 +5,7 @@ flexelint \
flint.lnt
\
flint.lnt
\
-I
.
\
-I
.
\
-I
../../include
\
-I
../../include
\
-I
../../lib/libvgz
\
-I
../..
\
-I
../..
\
-I
/usr/local/include
\
-I
/usr/local/include
\
-DVARNISH_STATE_DIR
=
\"
foo
\"
\
-DVARNISH_STATE_DIR
=
\"
foo
\"
\
...
...
bin/varnishtest/tests/e00024.vtc
View file @
58461688
...
@@ -80,6 +80,12 @@ client c1 {
...
@@ -80,6 +80,12 @@ client c1 {
gunzip
gunzip
expect resp.status == 200
expect resp.status == 200
expect resp.bodylen == 252
expect resp.bodylen == 252
txreq
rxresp
expect resp.http.content-encoding == resp.http.content-encoding
expect resp.status == 200
expect resp.bodylen == 252
} -run
} -run
varnish v1 -expect esi_errors == 0
varnish v1 -expect esi_errors == 0
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment