Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
U
unique-xids
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
unique-xids
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
Show 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);
char
*
VRT_StringList
(
char
*
d
,
unsigned
dl
,
const
char
*
p
,
va_list
ap
);
void
ESI_Deliver
(
struct
sess
*
);
void
ESI_DeliverChild
(
struct
sess
*
);
void
ESI_DeliverChild
(
const
struct
sess
*
);
/* cache_vrt_vmod.c */
void
VMOD_Init
(
void
);
...
...
bin/varnishd/cache_esi_deliver.c
View file @
58461688
...
...
@@ -195,32 +195,33 @@ ved_decode_len(uint8_t **pp)
*/
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
];
char
chunk
[
20
];
uint16_t
lx
;
while
(
l
>
0
)
{
ll
=
l
;
if
(
ll
>
65535
)
ll
=
65535
;
if
(
l
>
65535
)
lx
=
65535
;
else
lx
=
(
uint16_t
)
l
;
buf
[
0
]
=
0
;
vle16enc
(
buf
+
1
,
l
l
);
vle16enc
(
buf
+
3
,
~
l
l
);
vle16enc
(
buf
+
1
,
l
x
);
vle16enc
(
buf
+
3
,
~
l
x
);
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
,
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
)
(
void
)
WRW_Write
(
sp
->
wrk
,
"
\r\n
"
,
-
1
);
(
void
)
WRW_Flush
(
sp
->
wrk
);
sp
->
wrk
->
crc
=
crc32
(
sp
->
wrk
->
crc
,
p
,
l
l
);
sp
->
wrk
->
l_crc
+=
l
l
;
l
-=
l
l
;
p
+=
l
l
;
sp
->
wrk
->
crc
=
crc32
(
sp
->
wrk
->
crc
,
p
,
l
x
);
sp
->
wrk
->
l_crc
+=
l
x
;
l
-=
l
x
;
p
+=
l
x
;
}
}
...
...
@@ -233,14 +234,24 @@ ESI_Deliver(struct sess *sp)
struct
storage
*
st
;
uint8_t
*
p
,
*
e
,
*
q
,
*
r
;
unsigned
off
;
ssize_t
l
,
l_icrc
;
uint32_t
icrc
;
ssize_t
l
,
l_icrc
=
0
;
uint32_t
icrc
=
0
;
uint8_t
tailbuf
[
8
+
5
];
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
);
st
=
sp
->
obj
->
esidata
;
AN
(
st
);
assert
(
sizeof
obuf
>=
1024
);
obuf
[
0
]
=
0
;
/* For flexelint */
p
=
st
->
ptr
;
e
=
st
->
ptr
+
st
->
len
;
...
...
@@ -252,13 +263,21 @@ ESI_Deliver(struct sess *sp)
}
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
->
crc
=
crc32
(
0L
,
Z_NULL
,
0
);
}
else
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
);
off
=
0
;
...
...
@@ -271,39 +290,65 @@ ESI_Deliver(struct sess *sp)
r
=
p
;
q
=
(
void
*
)
strchr
((
const
char
*
)
p
,
'\0'
);
p
=
q
+
1
;
if
(
sp
->
wrk
->
gzip_resp
)
{
if
(
isgzip
)
{
assert
(
*
p
==
VEC_C1
||
*
p
==
VEC_C2
||
*
p
==
VEC_C8
);
l_icrc
=
ved_decode_len
(
&
p
);
icrc
=
vbe32dec
(
p
);
p
+=
4
;
}
if
(
sp
->
wrk
->
gzip_resp
&&
isgzip
)
{
/*
* We have a gzip'ed VEC and delivers a
* gzip'ed ESI response.
*/
sp
->
wrk
->
crc
=
crc32_combine
(
sp
->
wrk
->
crc
,
icrc
,
l_icrc
);
sp
->
wrk
->
l_crc
+=
l_icrc
;
if
(
sp
->
esi_level
>
0
&&
off
==
0
)
{
assert
(
l
>
10
);
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
,
st
->
ptr
+
off
+
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
();
st
->
ptr
+
10
,
l
-
10
);
}
else
{
ved_sendchunk
(
sp
,
r
,
q
-
r
,
st
->
ptr
+
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
;
case
VEC_S1
:
case
VEC_S2
:
...
...
@@ -329,6 +374,11 @@ assert(l > 10);
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
)
{
/* Emit a gzip literal block with finish bit set */
tailbuf
[
0
]
=
0x01
;
...
...
@@ -352,8 +402,8 @@ assert(l > 10);
* Include an object in a gzip'ed ESI object delivery
*/
static
u
nsigned
ved_deliver_byterange
(
struct
sess
*
sp
,
ssize_t
low
,
ssize_t
high
)
static
u
int8_t
ved_deliver_byterange
(
const
struct
sess
*
sp
,
ssize_t
low
,
ssize_t
high
)
{
struct
storage
*
st
;
ssize_t
l
,
lx
;
...
...
@@ -392,7 +442,7 @@ ved_deliver_byterange(struct sess *sp, ssize_t low, ssize_t high)
}
void
ESI_DeliverChild
(
struct
sess
*
sp
)
ESI_DeliverChild
(
const
struct
sess
*
sp
)
{
struct
storage
*
st
;
struct
object
*
obj
;
...
...
@@ -400,7 +450,7 @@ ESI_DeliverChild(struct sess *sp)
u_char
*
p
,
cc
;
uint32_t
icrc
;
uint32_t
ilen
;
uint8_t
pad
[
6
];
uint8_t
pad
[
6
]
=
{
0
}
;
if
(
!
sp
->
obj
->
gziped
)
{
VTAILQ_FOREACH
(
st
,
&
sp
->
obj
->
store
,
list
)
...
...
@@ -433,7 +483,7 @@ ESI_DeliverChild(struct sess *sp)
*/
cc
=
ved_deliver_byterange
(
sp
,
start
/
8
,
last
/
8
);
//printf("CC_LAST %x\n", cc);
cc
&=
~
(
1
<<
(
start
&
7
));
cc
&=
~
(
1
U
<<
(
start
&
7
));
ved_sendchunk
(
sp
,
NULL
,
0
,
&
cc
,
1
);
cc
=
ved_deliver_byterange
(
sp
,
1
+
last
/
8
,
stop
/
8
);
//printf("CC_STOP %x (%d)\n", cc, (int)(stop & 7));
...
...
@@ -474,7 +524,7 @@ ESI_DeliverChild(struct sess *sp)
lpad
=
6
;
break
;
default
:
AZ
(
stop
&
7
);
INCOMPL
(
);
}
if
(
lpad
>
0
)
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)
CHECK_OBJ_NOTNULL
(
sp
,
SESS_MAGIC
);
vef
=
sp
->
wrk
->
vef_priv
;
CHECK_OBJ_NOTNULL
(
vef
,
VEF_MAGIC
);
assert
(
sizeof
ibuf
>=
1024
);
ibuf2
[
0
]
=
0
;
/* For Flexelint */
while
(
bytes
>
0
)
{
w
=
vef_read
(
htc
,
ibuf
,
sizeof
ibuf
,
bytes
);
...
...
bin/varnishd/flint.sh
View file @
58461688
...
...
@@ -5,6 +5,7 @@ flexelint \
flint.lnt
\
-I
.
\
-I
../../include
\
-I
../../lib/libvgz
\
-I
../..
\
-I
/usr/local/include
\
-DVARNISH_STATE_DIR
=
\"
foo
\"
\
...
...
bin/varnishtest/tests/e00024.vtc
View file @
58461688
...
...
@@ -80,6 +80,12 @@ client c1 {
gunzip
expect resp.status == 200
expect resp.bodylen == 252
txreq
rxresp
expect resp.http.content-encoding == resp.http.content-encoding
expect resp.status == 200
expect resp.bodylen == 252
} -run
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