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
14b70079
Commit
14b70079
authored
Dec 10, 2013
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve error reporting in VCL::ban() by emitting the errors as
VCL_Error SLTs.
parent
f29735ee
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
147 additions
and
62 deletions
+147
-62
cache.h
bin/varnishd/cache/cache.h
+2
-3
cache_ban.c
bin/varnishd/cache/cache_ban.c
+83
-34
cache_vrt.c
bin/varnishd/cache/cache_vrt.c
+42
-23
v00011.vtc
bin/varnishtest/tests/v00011.vtc
+18
-0
vrt.h
include/vrt.h
+1
-1
vcc_action.c
lib/libvcc/vcc_action.c
+1
-1
No files found.
bin/varnishd/cache/cache.h
View file @
14b70079
...
...
@@ -827,10 +827,9 @@ void VBP_Init(void);
/* cache_ban.c */
struct
ban
*
BAN_New
(
void
);
int
BAN_AddTest
(
struct
cli
*
,
struct
ban
*
,
const
char
*
,
const
char
*
,
const
char
*
);
int
BAN_AddTest
(
struct
ban
*
,
const
char
*
,
const
char
*
,
const
char
*
);
void
BAN_Free
(
struct
ban
*
b
);
int
BAN_Insert
(
struct
ban
*
b
);
char
*
BAN_Insert
(
struct
ban
*
b
);
void
BAN_Init
(
void
);
void
BAN_Shutdown
(
void
);
void
BAN_NewObjCore
(
struct
objcore
*
oc
);
...
...
bin/varnishd/cache/cache_ban.c
View file @
14b70079
...
...
@@ -64,6 +64,7 @@
#include <math.h>
#include <pcre.h>
#include <stdarg.h>
#include <stdio.h>
#include "cache.h"
...
...
@@ -83,6 +84,7 @@ struct ban {
int
refcount
;
unsigned
flags
;
#define BAN_F_GONE (1 << 0)
#define BAN_F_ERROR (1 << 1)
/* sticky error marker */
#define BAN_F_REQ (1 << 2)
#define BAN_F_LURK (3 << 6)
/* ban-lurker-color */
VTAILQ_HEAD
(,
objcore
)
objcore
;
...
...
@@ -324,6 +326,30 @@ ban_iter(const uint8_t **bs, struct ban_test *bt)
bt
->
arg2_spec
=
ban_get_lump
(
bs
);
}
/*--------------------------------------------------------------------
*/
static
int
ban_error
(
struct
ban
*
b
,
const
char
*
fmt
,
...)
{
va_list
ap
;
CHECK_OBJ_NOTNULL
(
b
,
BAN_MAGIC
);
AN
(
b
->
vsb
);
/* First error is sticky */
if
(
!
(
b
->
flags
&
BAN_F_ERROR
))
{
b
->
flags
|=
BAN_F_ERROR
;
/* Record the error message in the vsb */
VSB_clear
(
b
->
vsb
);
va_start
(
ap
,
fmt
);
(
void
)
VSB_vprintf
(
b
->
vsb
,
fmt
,
ap
);
va_end
(
ap
);
}
return
(
-
1
);
}
/*--------------------------------------------------------------------
* Parse and add a http argument specification
* Output something which HTTP_GetHdr understands
...
...
@@ -347,7 +373,7 @@ ban_parse_http(const struct ban *b, const char *a1)
*/
static
int
ban_parse_regexp
(
struct
cli
*
cli
,
const
struct
ban
*
b
,
const
char
*
a3
)
ban_parse_regexp
(
struct
ban
*
b
,
const
char
*
a3
)
{
const
char
*
error
;
int
erroroffset
,
rc
;
...
...
@@ -355,12 +381,8 @@ ban_parse_regexp(struct cli *cli, const struct ban *b, const char *a3)
pcre
*
re
;
re
=
pcre_compile
(
a3
,
0
,
&
error
,
&
erroroffset
,
NULL
);
if
(
re
==
NULL
)
{
VSL
(
SLT_Debug
,
0
,
"REGEX: <%s>"
,
error
);
VCLI_Out
(
cli
,
"%s"
,
error
);
VCLI_SetResult
(
cli
,
CLIS_PARAM
);
return
(
-
1
);
}
if
(
re
==
NULL
)
return
(
ban_error
(
b
,
"Regex compile error: %s"
,
error
));
rc
=
pcre_fullinfo
(
re
,
NULL
,
PCRE_INFO_SIZE
,
&
sz
);
AZ
(
rc
);
ban_add_lump
(
b
,
re
,
sz
);
...
...
@@ -372,22 +394,27 @@ ban_parse_regexp(struct cli *cli, const struct ban *b, const char *a3)
*/
int
BAN_AddTest
(
struct
cli
*
cli
,
struct
ban
*
b
,
const
char
*
a1
,
const
char
*
a2
,
const
char
*
a3
)
BAN_AddTest
(
struct
ban
*
b
,
const
char
*
a1
,
const
char
*
a2
,
const
char
*
a3
)
{
const
struct
pvar
*
pv
;
int
i
;
CHECK_OBJ_NOTNULL
(
b
,
BAN_MAGIC
);
AN
(
b
->
vsb
);
AN
(
a1
);
AN
(
a2
);
AN
(
a3
);
if
(
b
->
flags
&
BAN_F_ERROR
)
return
(
-
1
);
for
(
pv
=
pvars
;
pv
->
name
!=
NULL
;
pv
++
)
if
(
!
strncmp
(
a1
,
pv
->
name
,
strlen
(
pv
->
name
)))
break
;
if
(
pv
->
name
==
NULL
)
{
VCLI_Out
(
cli
,
"unknown or unsupported field
\"
%s
\"
"
,
a1
);
VCLI_SetResult
(
cli
,
CLIS_PARAM
);
return
(
-
1
);
}
if
(
pv
->
name
==
NULL
)
return
(
ban_error
(
b
,
"Unknown or unsupported field
\"
%s
\"
"
,
a1
));
if
(
pv
->
flag
&
PVAR_REQ
)
b
->
flags
|=
BAN_F_REQ
;
...
...
@@ -399,12 +426,12 @@ BAN_AddTest(struct cli *cli, struct ban *b, const char *a1, const char *a2,
ban_add_lump
(
b
,
a3
,
strlen
(
a3
)
+
1
);
if
(
!
strcmp
(
a2
,
"~"
))
{
VSB_putc
(
b
->
vsb
,
BANS_OPER_MATCH
);
i
=
ban_parse_regexp
(
cli
,
b
,
a3
);
i
=
ban_parse_regexp
(
b
,
a3
);
if
(
i
)
return
(
i
);
}
else
if
(
!
strcmp
(
a2
,
"!~"
))
{
VSB_putc
(
b
->
vsb
,
BANS_OPER_NMATCH
);
i
=
ban_parse_regexp
(
cli
,
b
,
a3
);
i
=
ban_parse_regexp
(
b
,
a3
);
if
(
i
)
return
(
i
);
}
else
if
(
!
strcmp
(
a2
,
"=="
))
{
...
...
@@ -412,10 +439,8 @@ BAN_AddTest(struct cli *cli, struct ban *b, const char *a1, const char *a2,
}
else
if
(
!
strcmp
(
a2
,
"!="
))
{
VSB_putc
(
b
->
vsb
,
BANS_OPER_NEQ
);
}
else
{
VCLI_Out
(
cli
,
"expected conditional (~, !~, == or !=) got
\"
%s
\"
"
,
a2
);
VCLI_SetResult
(
cli
,
CLIS_PARAM
);
return
(
-
1
);
return
(
ban_error
(
b
,
"expected conditional (~, !~, == or !=) got
\"
%s
\"
"
,
a2
));
}
return
(
0
);
}
...
...
@@ -432,26 +457,50 @@ BAN_AddTest(struct cli *cli, struct ban *b, const char *a1, const char *a2,
* deleted.
*/
int
static
char
*
ban_ins_error
(
const
char
*
p
)
{
char
*
r
=
NULL
;
static
char
nomem
[]
=
"Could not get memory"
;
if
(
p
!=
NULL
)
r
=
strdup
(
p
);
if
(
r
==
NULL
)
r
=
nomem
;
return
(
r
);
}
char
*
BAN_Insert
(
struct
ban
*
b
)
{
struct
ban
*
bi
,
*
be
;
ssize_t
ln
;
double
t0
;
char
*
p
;
CHECK_OBJ_NOTNULL
(
b
,
BAN_MAGIC
);
AN
(
b
->
vsb
);
if
(
ban_shutdown
)
{
BAN_Free
(
b
);
return
(
-
1
);
return
(
ban_ins_error
(
"Shutting down"
)
);
}
AZ
(
VSB_finish
(
b
->
vsb
));
ln
=
VSB_len
(
b
->
vsb
);
assert
(
ln
>=
0
);
if
(
b
->
flags
&
BAN_F_ERROR
)
{
p
=
ban_ins_error
(
VSB_data
(
b
->
vsb
));
BAN_Free
(
b
);
return
(
p
);
}
b
->
spec
=
malloc
(
ln
+
BANS_HEAD_LEN
);
XXXAN
(
b
->
spec
);
if
(
b
->
spec
==
NULL
)
{
BAN_Free
(
b
);
return
(
ban_ins_error
(
NULL
));
}
t0
=
VTIM_real
();
memcpy
(
b
->
spec
+
BANS_TIMESTAMP
,
&
t0
,
sizeof
t0
);
...
...
@@ -468,7 +517,7 @@ BAN_Insert(struct ban *b)
/* Check again, we might have raced */
Lck_Unlock
(
&
ban_mtx
);
BAN_Free
(
b
);
return
(
-
1
);
return
(
ban_ins_error
(
"Shutting down"
)
);
}
VTAILQ_INSERT_HEAD
(
&
ban_head
,
b
,
list
);
ban_start
=
b
;
...
...
@@ -496,7 +545,7 @@ BAN_Insert(struct ban *b)
Lck_Unlock
(
&
ban_mtx
);
if
(
be
==
NULL
)
return
(
0
);
return
(
NULL
);
/* Hunt down duplicates, and mark them as gone */
bi
=
b
;
...
...
@@ -513,7 +562,7 @@ BAN_Insert(struct ban *b)
be
->
refcount
--
;
Lck_Unlock
(
&
ban_mtx
);
return
(
0
);
return
(
NULL
);
}
/*--------------------------------------------------------------------
...
...
@@ -1140,6 +1189,7 @@ ccf_ban(struct cli *cli, const char * const *av, void *priv)
{
int
narg
,
i
;
struct
ban
*
b
;
char
*
p
;
(
void
)
priv
;
...
...
@@ -1166,14 +1216,13 @@ ccf_ban(struct cli *cli, const char * const *av, void *priv)
return
;
}
for
(
i
=
0
;
i
<
narg
;
i
+=
4
)
if
(
BAN_AddTest
(
cli
,
b
,
av
[
i
+
2
],
av
[
i
+
3
],
av
[
i
+
4
]))
{
BAN_Free
(
b
);
return
;
}
if
(
BAN_Insert
(
b
)
<
0
)
{
VCLI_Out
(
cli
,
"Shutdown in progress"
);
VCLI_SetResult
(
cli
,
CLIS_CANT
);
return
;
if
(
BAN_AddTest
(
b
,
av
[
i
+
2
],
av
[
i
+
3
],
av
[
i
+
4
]))
break
;
p
=
BAN_Insert
(
b
);
if
(
p
!=
NULL
)
{
VCLI_Out
(
cli
,
"%s"
,
p
);
free
(
p
);
VCLI_SetResult
(
cli
,
CLIS_PARAM
);
}
}
...
...
bin/varnishd/cache/cache_vrt.c
View file @
14b70079
...
...
@@ -406,46 +406,65 @@ VRT_synth_page(const struct vrt_ctx *ctx, unsigned flags, const char *str, ...)
/*--------------------------------------------------------------------*/
void
VRT_ban_string
(
const
char
*
str
)
VRT_ban_string
(
const
struct
vrt_ctx
*
ctx
,
const
char
*
str
)
{
char
*
a1
,
*
a2
,
*
a3
;
char
**
av
;
struct
ban
*
b
;
int
good
;
int
i
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
ctx
->
vsl
);
AN
(
str
);
b
=
BAN_New
();
if
(
b
==
NULL
)
{
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): Out of Memory"
);
return
;
}
av
=
VAV_Parse
(
str
,
NULL
,
ARGV_NOESC
);
AN
(
av
);
if
(
av
[
0
]
!=
NULL
)
{
/* XXX: report error how ? */
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): %s"
,
av
[
0
]);
VAV_Free
(
av
);
BAN_Free
(
b
);
return
;
}
b
=
BAN_New
();
good
=
0
;
for
(
i
=
1
;
;
)
{
a1
=
av
[
i
++
];
if
(
a1
==
NULL
)
for
(
i
=
0
;
;)
{
a1
=
av
[
++
i
]
;
if
(
a1
==
NULL
)
{
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): No ban conditions found."
);
break
;
good
=
0
;
a2
=
av
[
i
++
];
if
(
a2
==
NULL
)
break
;
a3
=
av
[
i
++
];
if
(
a3
==
NULL
)
}
a2
=
av
[
++
i
];
if
(
a2
==
NULL
)
{
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): Expected comparison operator."
);
break
;
if
(
BAN_AddTest
(
NULL
,
b
,
a1
,
a2
,
a3
))
}
a3
=
av
[
++
i
];
if
(
a3
==
NULL
)
{
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): Expected second operand."
);
break
;
good
=
1
;
if
(
av
[
i
]
==
NULL
)
}
if
(
BAN_AddTest
(
b
,
a1
,
a2
,
a3
)
||
av
[
++
i
]
==
NULL
)
{
a1
=
BAN_Insert
(
b
);
if
(
a1
!=
NULL
)
{
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): %s"
,
a1
);
free
(
a1
);
}
break
;
good
=
0
;
if
(
strcmp
(
av
[
i
++
],
"&&"
))
}
if
(
strcmp
(
av
[
i
],
"&&"
))
{
VSLb
(
ctx
->
vsl
,
SLT_VCL_Error
,
"ban(): Expected && between conditions,"
" found
\"
%s
\"
"
,
av
[
i
]);
break
;
}
}
if
(
!
good
)
BAN_Free
(
b
);
/* XXX: report error how ? */
else
(
void
)
BAN_Insert
(
b
);
/* XXX: report error how ? */
VAV_Free
(
av
);
}
...
...
bin/varnishtest/tests/v00011.vtc
View file @
14b70079
...
...
@@ -11,6 +11,12 @@ server s1 {
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.method == "PURGE") {
ban("");
ban("req.url");
ban("req.url //");
ban("req.url // bar");
ban("req.url == bar //");
ban("foo == bar //");
ban("req.url ~ ^/$");
return (error(209,"foo"));
}
...
...
@@ -24,6 +30,16 @@ client c1 {
expect resp.http.X-Varnish == "1001"
} -run
logexpect l1 -v v1 -d 1 -g vxid {
expect * 1004 VCL_Error {ban[(][)]: No ban conditions found[.]}
expect * 1004 VCL_Error {ban[(][)]: Expected comparison operator[.]}
expect * 1004 VCL_Error {ban[(][)]: Expected second operand[.]}
expect * 1004 VCL_Error {ban[(][)]: expected conditional [(]~, !~, == or !=[)] got "//"}
expect * 1004 VCL_Error {ban[(][)]: Expected && between conditions, found .//.}
expect * 1004 VCL_Error {ban[(][)]: Unknown or unsupported field .foo.}
} -start
client c1 {
txreq -req "PURGE"
rxresp
...
...
@@ -31,6 +47,8 @@ client c1 {
expect resp.status == 209
} -run
logexpect l1 -wait
client c1 {
txreq
rxresp
...
...
include/vrt.h
View file @
14b70079
...
...
@@ -199,7 +199,7 @@ int VRT_re_match(const struct vrt_ctx *, const char *, void *re);
const
char
*
VRT_regsub
(
const
struct
vrt_ctx
*
,
int
all
,
const
char
*
,
void
*
,
const
char
*
);
void
VRT_ban_string
(
const
char
*
);
void
VRT_ban_string
(
const
struct
vrt_ctx
*
,
const
char
*
);
void
VRT_purge
(
const
struct
vrt_ctx
*
,
double
ttl
,
double
grace
);
void
VRT_count
(
const
struct
vrt_ctx
*
,
unsigned
);
...
...
lib/libvcc/vcc_action.c
View file @
14b70079
...
...
@@ -263,7 +263,7 @@ parse_ban(struct vcc *tl)
ExpectErr
(
tl
,
'('
);
vcc_NextToken
(
tl
);
Fb
(
tl
,
1
,
"VRT_ban_string(
\n
"
);
Fb
(
tl
,
1
,
"VRT_ban_string(
ctx,
\n
"
);
tl
->
indent
+=
INDENT
;
vcc_Expr
(
tl
,
STRING
);
tl
->
indent
-=
INDENT
;
...
...
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