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
0679d603
Commit
0679d603
authored
Apr 16, 2012
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Be much more cautious about how much workspace we have to build
predictive vary string. Fixes #1120
parent
26122673
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
102 additions
and
49 deletions
+102
-49
cache.h
bin/varnishd/cache/cache.h
+1
-0
cache_center.c
bin/varnishd/cache/cache_center.c
+2
-13
cache_vary.c
bin/varnishd/cache/cache_vary.c
+75
-36
r01120.vtc
bin/varnishtest/tests/r01120.vtc
+24
-0
No files found.
bin/varnishd/cache/cache.h
View file @
0679d603
...
@@ -956,6 +956,7 @@ void RES_WriteObj(struct sess *sp);
...
@@ -956,6 +956,7 @@ void RES_WriteObj(struct sess *sp);
struct
vsb
*
VRY_Create
(
struct
req
*
sp
,
const
struct
http
*
hp
);
struct
vsb
*
VRY_Create
(
struct
req
*
sp
,
const
struct
http
*
hp
);
int
VRY_Match
(
struct
req
*
,
const
uint8_t
*
vary
);
int
VRY_Match
(
struct
req
*
,
const
uint8_t
*
vary
);
void
VRY_Validate
(
const
uint8_t
*
vary
);
void
VRY_Validate
(
const
uint8_t
*
vary
);
void
VRY_Prep
(
struct
req
*
);
/* cache_vcl.c */
/* cache_vcl.c */
void
VCL_Init
(
void
);
void
VCL_Init
(
void
);
...
...
bin/varnishd/cache/cache_center.c
View file @
0679d603
...
@@ -1081,18 +1081,7 @@ cnt_lookup(struct sess *sp, struct worker *wrk, struct req *req)
...
@@ -1081,18 +1081,7 @@ cnt_lookup(struct sess *sp, struct worker *wrk, struct req *req)
CHECK_OBJ_NOTNULL
(
req
->
vcl
,
VCL_CONF_MAGIC
);
CHECK_OBJ_NOTNULL
(
req
->
vcl
,
VCL_CONF_MAGIC
);
AZ
(
req
->
busyobj
);
AZ
(
req
->
busyobj
);
if
(
req
->
hash_objhead
==
NULL
)
{
VRY_Prep
(
req
);
/* Not a waiting list return */
AZ
(
req
->
vary_b
);
AZ
(
req
->
vary_l
);
AZ
(
req
->
vary_e
);
(
void
)
WS_Reserve
(
req
->
ws
,
0
);
}
else
{
AN
(
req
->
ws
->
r
);
}
req
->
vary_b
=
(
void
*
)
req
->
ws
->
f
;
req
->
vary_e
=
(
void
*
)
req
->
ws
->
r
;
req
->
vary_b
[
2
]
=
'\0'
;
AZ
(
req
->
objcore
);
AZ
(
req
->
objcore
);
oc
=
HSH_Lookup
(
sp
);
oc
=
HSH_Lookup
(
sp
);
...
...
bin/varnishd/cache/cache_vary.c
View file @
0679d603
...
@@ -176,22 +176,61 @@ vry_cmp(const uint8_t *v1, const uint8_t *v2)
...
@@ -176,22 +176,61 @@ vry_cmp(const uint8_t *v1, const uint8_t *v2)
return
(
retval
);
return
(
retval
);
}
}
/**********************************************************************
* Prepare predictive vary string
*/
void
VRY_Prep
(
struct
req
*
req
)
{
if
(
req
->
hash_objhead
==
NULL
)
{
/* Not a waiting list return */
AZ
(
req
->
vary_b
);
AZ
(
req
->
vary_l
);
AZ
(
req
->
vary_e
);
(
void
)
WS_Reserve
(
req
->
ws
,
0
);
}
else
{
AN
(
req
->
ws
->
r
);
}
req
->
vary_b
=
(
void
*
)
req
->
ws
->
f
;
req
->
vary_e
=
(
void
*
)
req
->
ws
->
r
;
if
(
req
->
vary_b
+
2
<
req
->
vary_e
)
req
->
vary_b
[
2
]
=
'\0'
;
}
/**********************************************************************
* Match vary strings, and build a new cached string if possible.
*
* Return zero if there is certainly no match.
* Return non-zero if there could be a match or if we couldn't tell.
*/
int
int
VRY_Match
(
struct
req
*
req
,
const
uint8_t
*
vary
)
VRY_Match
(
struct
req
*
req
,
const
uint8_t
*
vary
)
{
{
uint8_t
*
vsp
=
req
->
vary_b
;
uint8_t
*
vsp
=
req
->
vary_b
;
char
*
h
,
*
e
;
char
*
h
,
*
e
;
unsigned
lh
,
ln
;
unsigned
lh
,
ln
;
int
i
,
retval
=
1
,
oflo
=
0
;
int
i
,
oflo
=
0
;
AN
(
vsp
);
AN
(
vsp
);
while
(
vary
[
2
])
{
while
(
vary
[
2
])
{
if
(
vsp
+
2
>=
req
->
vary_e
)
{
/*
* Too little workspace to find out
*/
oflo
=
1
;
break
;
}
i
=
vry_cmp
(
vary
,
vsp
);
i
=
vry_cmp
(
vary
,
vsp
);
if
(
i
==
1
)
{
if
(
i
==
1
)
{
/* Build a new entry */
/*
* Different header, build a new entry,
* then compare again with that new entry.
*/
i
=
http_GetHdr
(
req
->
http
,
ln
=
2
+
vary
[
2
]
+
2
;
(
const
char
*
)(
vary
+
2
),
&
h
);
i
=
http_GetHdr
(
req
->
http
,
(
const
char
*
)(
vary
+
2
),
&
h
);
if
(
i
)
{
if
(
i
)
{
/* Trim trailing space */
/* Trim trailing space */
e
=
strchr
(
h
,
'\0'
);
e
=
strchr
(
h
,
'\0'
);
...
@@ -199,55 +238,55 @@ VRY_Match(struct req *req, const uint8_t *vary)
...
@@ -199,55 +238,55 @@ VRY_Match(struct req *req, const uint8_t *vary)
e
--
;
e
--
;
lh
=
e
-
h
;
lh
=
e
-
h
;
assert
(
lh
<
0xffff
);
assert
(
lh
<
0xffff
);
ln
+=
lh
;
}
else
{
}
else
{
e
=
h
=
NULL
;
e
=
h
=
NULL
;
lh
=
0xffff
;
lh
=
0xffff
;
}
}
/* Length of the entire new vary entry */
if
(
vsp
+
ln
+
2
>=
req
->
vary_e
)
{
ln
=
2
+
vary
[
2
]
+
2
+
(
lh
==
0xffff
?
0
:
lh
);
if
(
vsp
+
ln
>=
req
->
vary_e
)
{
vsp
=
req
->
vary_b
;
oflo
=
1
;
}
/*
/*
* We MUST have space for one entry and the end marker
* Not enough space to build new entry
* after it, which prevents old junk from confusing us
* and put terminator behind it.
*/
*/
assert
(
vsp
+
ln
+
2
<
req
->
vary_e
);
oflo
=
1
;
break
;
}
vbe16enc
(
vsp
,
(
uint16_t
)
lh
);
vbe16enc
(
vsp
,
(
uint16_t
)
lh
);
memcpy
(
vsp
+
2
,
vary
+
2
,
vary
[
2
]
+
2
);
memcpy
(
vsp
+
2
,
vary
+
2
,
vary
[
2
]
+
2
);
if
(
h
!=
NULL
&&
e
!=
NULL
)
{
if
(
h
!=
NULL
)
memcpy
(
vsp
+
2
+
vsp
[
2
]
+
2
,
h
,
e
-
h
);
memcpy
(
vsp
+
2
+
vsp
[
2
]
+
2
,
h
,
lh
);
vsp
[
2
+
vary
[
2
]
+
2
+
(
e
-
h
)
+
2
]
=
'\0'
;
vsp
[
ln
+
0
]
=
0xff
;
}
else
vsp
[
ln
+
1
]
=
0xff
;
vsp
[
2
+
vary
[
2
]
+
2
+
2
]
=
'\0'
;
vsp
[
ln
+
2
]
=
0
;
VRY_Validate
(
vsp
);
req
->
vary_l
=
vsp
+
3
;
i
=
vry_cmp
(
vary
,
vsp
);
i
=
vry_cmp
(
vary
,
vsp
);
assert
(
i
!=
1
);
/* hdr must be the same now */
assert
(
i
==
0
||
i
==
2
);
}
}
if
(
i
!=
0
)
if
(
i
==
0
)
{
retval
=
0
;
/* Same header, same contents*/
vsp
+=
vry_len
(
vsp
);
vsp
+=
vry_len
(
vsp
);
vary
+=
vry_len
(
vary
);
vary
+=
vry_len
(
vary
);
}
else
if
(
i
==
2
)
{
/* Same header, different contents, cannot match */
return
(
0
);
}
}
}
if
(
vsp
+
3
>
req
->
vary_e
)
oflo
=
1
;
if
(
oflo
)
{
if
(
oflo
)
{
/* XXX: Should log this */
vsp
=
req
->
vary_b
;
vsp
=
req
->
vary_b
;
}
req
->
vary_l
=
NULL
;
if
(
vsp
+
2
<
req
->
vary_e
)
{
vsp
[
0
]
=
0xff
;
vsp
[
0
]
=
0xff
;
vsp
[
1
]
=
0xff
;
vsp
[
1
]
=
0xff
;
vsp
[
2
]
=
0
;
vsp
[
2
]
=
0
;
if
(
oflo
)
}
re
q
->
vary_l
=
NULL
;
re
turn
(
0
)
;
else
}
else
{
re
q
->
vary_l
=
vsp
+
3
;
re
turn
(
1
)
;
return
(
retval
);
}
}
}
void
void
...
...
bin/varnishtest/tests/r01120.vtc
0 → 100644
View file @
0679d603
varnishtest "insanely long vary string"
server s1 {
rxreq
txresp -hdr "Vary: Foo" -body "xxxx"
rxreq
txresp -hdr "Vary: Foo" -body "yyyyy"
} -start
varnish v1 \
-cliok "param.set workspace_client 8k" \
-cliok "param.set workspace_backend 200k" \
-vcl+backend {
} -start
client c1 {
txreq -hdr "Foo: blabla"
rxresp
expect resp.bodylen == 4
#txreq -hdr "Foo: blablaA"
txreq -hdr "Foo: blablaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
rxresp
expect resp.bodylen == 5
} -run
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