Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvfp-brotli
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
libvfp-brotli
Commits
df105a52
Commit
df105a52
authored
Feb 13, 2019
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the decoder object (decompression with custom parameters).
parent
0b3a3c1c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
338 additions
and
29 deletions
+338
-29
README.rst
README.rst
+8
-1
decoder.vtc
src/tests/decoder.vtc
+224
-0
vfp_brotli.c
src/vfp_brotli.c
+105
-27
vfp_brotli.vcc
src/vfp_brotli.vcc
+1
-1
No files found.
README.rst
View file @
df105a52
...
...
@@ -81,7 +81,14 @@ new xencoder = brotli.encoder(STRING name, BYTES bufffer)
XXX ...
# $Object decoder(STRING name, BYTES buffer=32k, BOOL lgwin=0)
.. _vmod_brotli.decoder:
new xdecoder = brotli.decoder(STRING name, BYTES buffer)
--------------------------------------------------------
::
new xdecoder = brotli.decoder(STRING name, BYTES buffer=32768)
XXX ...
...
...
src/tests/decoder.vtc
0 → 100644
View file @
df105a52
# looks like -*- vcl -*-
varnishtest "brotli decompression with custom parameter settings"
# Test vectors from github.com/google/brotli/tests/testdata
server s1 {
rxreq
txresp -hdr "Content-Encoding: br" -hdr "Content-Length: 425"
sendhex "1b 4a 03 00 8c 94 6e de b4 d7 96 b1 78 86 f2 2d"
sendhex "e1 1a bc 0b 1c ba a9 c7 f7 cc 6e b2 42 34 51 44"
sendhex "8b 4e 13 08 a0 cd 6e e8 2c a5 53 a1 9c 5d 2c 1d"
sendhex "23 1a d2 56 be db eb 26 ba 03 65 7c 96 6a a2 76"
sendhex "ec ef 87 47 33 d6 27 0e 63 95 e2 1d 8d 2c c5 d1"
sendhex "28 9f 60 94 6f 02 8b dd aa 64 94 2c 1e 3b 65 7c"
sendhex "07 45 5a b2 e2 fc 49 81 2c 9f 40 ae ef 68 81 ac"
sendhex "16 7a 0f f5 3b 6d 1c b9 1e 2d 5f d5 c8 af 5e 85"
sendhex "aa 05 be 53 75 c2 b0 22 8a 15 c6 a3 b1 e6 42 14"
sendhex "f4 84 54 53 19 5f be c3 f2 1d d1 b7 e5 dd b6 d9"
sendhex "23 c6 f6 9f 9e f6 4d 65 30 fb c0 71 45 04 ad 03"
sendhex "b5 be c9 cb fd e2 50 5a 46 74 04 0d ff 20 04 77"
sendhex "b2 6d 27 bf 47 a9 9d 1b 96 2c 62 90 23 8b e0 f8"
sendhex "1d cf af 1d 3d ee 8a c8 75 23 66 dd de d6 6d e3"
sendhex "2a 82 8a 78 8a db e6 20 4c b7 5c 63 ba 30 e3 3f"
sendhex "b6 ee 8c 22 a2 2a b0 22 0a 99 ff 3d 62 51 ee 08"
sendhex "f6 3d 4a e4 cc ef 22 87 11 e2 83 28 e4 f5 8f 35"
sendhex "19 63 5b e1 5a 92 73 dd a1 50 9d 38 5c eb b5 03"
sendhex "6a 64 90 94 c8 8d fb 2f 8a 86 22 cc 1d 87 e0 48"
sendhex "0a 96 77 90 39 c6 23 23 48 fb 11 47 56 ca 20 e3"
sendhex "42 81 f7 77 32 c1 a5 5c 40 21 65 17 40 29 17 17"
sendhex "6c 56 32 98 38 06 dc 99 4d 33 29 bb 02 df 4c 26"
sendhex "93 6c 17 82 86 20 d7 03 79 7d 9a 00 d7 87 00 e7"
sendhex "0b 66 e3 4c 66 71 67 08 32 f9 08 3e 81 33 cd 17"
sendhex "72 31 f0 b8 94 52 4b 90 31 8e 68 c1 ef 90 c9 e5"
sendhex "f2 61 09 72 25 ad ec c5 62 c0 0b 12 05 f7 91 75"
sendhex "0d ee 61 2e 2e 19 09 c2 03"
rxreq
txresp -nolen -hdr "Content-Encoding: br" -hdr "Content-Length: 69"
sendhex "1b 76 00 00 14 4a ac 9b 7a bd e1 97 9d 7f 8e c2"
sendhex "82 36 0e 9c e0 90 03 f7 8b 9e 38 e6 b6 00 ab c3"
sendhex "ca a0 c2 da 66 36 dc cd 80 8d 2e 21 d7 6e e3 ea"
sendhex "4c b8 f0 d2 b8 c7 c2 70 4d 3a f0 69 7e a1 b8 45"
sendhex "73 ab c4 57 1e"
} -start
varnish v1 -arg "-p vsl_mask=+VfpAcct" -vcl+backend {
import ${vmod_brotli};
sub vcl_init {
new mybr = brotli.decoder("unbr1k", 1k);
}
sub vcl_backend_response {
set beresp.filters = "unbr1k";
set beresp.uncacheable = true;
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.Content-Encoding == <undef>
expect resp.bodylen == 843
expect resp.body == "znxcvnmz,xvnm.,zxcnv.,xcn.z,vn.zvn.zxcvn.,zxcn.vn.v,znm.,vnzx.,vnzxc.vn.z,vnz.,nv.z,nvmzxc,nvzxcvcnm.,vczxvnzxcnvmxc.zmcnvzm.,nvmc,nzxmc,vn.mnnmzxc,vnxcnmv,znvzxcnmv,.xcnvm,zxcnzxv.zx,qweryweurqioweupropqwutioweupqrioweutiopweuriopweuriopqwurioputiopqwuriowuqerioupqweropuweropqwurweuqriopuropqwuriopuqwriopuqweopruioqweurqweuriouqweopruioupqiytioqtyiowtyqptypryoqweutioioqtweqruowqeytiowquiourowetyoqwupiotweuqiorweuqroipituqwiorqwtioweuriouytuioerytuioweryuitoweytuiweyuityeruirtyuqriqweuropqweiruioqweurioqwuerioqwyuituierwotueryuiotweyrtuiwertyioweryrueioqptyioruyiopqwtjkasdfhlafhlasdhfjklashjkfhasjklfhklasjdfhklasdhfjkalsdhfklasdhjkflahsjdkfhklasfhjkasdfhasfjkasdhfklsdhalghhaf;hdklasfhjklashjklfasdhfasdjklfhsdjklafsd;hkldadfjjklasdhfjasddfjklfhakjklasdjfkl;asdjfasfljasdfhjklasdfhjkaghjkashf;djfklasdjfkljasdklfjklasdjfkljasdfkljaklfj"
txreq
rxresp
expect resp.status == 200
expect resp.http.Content-Encoding == <undef>
expect resp.bodylen == 119
expect resp.body == "ukko nooa, ukko nooa oli kunnon mies, kun han meni saunaan, pisti laukun naulaan, ukko nooa, ukko nooa oli kunnon mies."
} -run
varnish v1 -vcl+backend {
import ${vmod_brotli};
sub vcl_init {
new mybr = brotli.decoder("unbr1m", 1m);
}
sub vcl_backend_response {
set beresp.filters = "unbr1m";
set beresp.uncacheable = true;
}
}
# Tests object finalization and DISCARD event.
varnish v1 -cli "vcl.discard vcl1"
varnish v1 -cli "vcl.list"
server s1 -wait
server s1 -start
client c1 -run
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name must be non-empty} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name br already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("br");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name unbr already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("unbr");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name esi already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("esi");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name esi_gzip already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("esi_gzip");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name gunzip already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("gunzip");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name gzip already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("gzip");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: filter name testgunzip already in use by another VFP} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("testgunzip");
}
}
varnish v1 -errvcl {vfp brotli failure: new mybr: buffer size must be > 0b} {
import ${vmod_brotli};
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new mybr = brotli.decoder("empty", 0b);
}
}
# Happens to be the same as the default decoder.
varnish v1 -vcl+backend {
import ${vmod_brotli};
sub vcl_init {
new mybr = brotli.decoder("unbr_default", 32k);
}
sub vcl_backend_response {
set beresp.filters = "unbr_default";
set beresp.uncacheable = true;
}
}
varnish v1 -cli "vcl.discard vcl2"
server s1 -wait
server s1 -start
client c1 -run
logexpect l1 -v v1 -d 1 -g vxid -q "VfpAcct" {
expect 0 * Begin bereq
expect * = VfpAcct {^unbr1k \d+ 843$}
expect * = End
expect 0 * Begin bereq
expect * = VfpAcct {^unbr1k \d+ 119$}
expect * = End
expect 0 * Begin bereq
expect * = VfpAcct {^unbr1m \d+ 843$}
expect * = End
expect 0 * Begin bereq
expect * = VfpAcct {^unbr1m \d+ 119$}
expect * = End
expect 0 * Begin bereq
expect * = VfpAcct {^unbr_default \d+ 843$}
expect * = End
expect 0 * Begin bereq
expect * = VfpAcct {^unbr_default \d+ 119$}
expect * = End
} -run
src/vfp_brotli.c
View file @
df105a52
...
...
@@ -86,6 +86,12 @@ struct vmod_brotli_encoder {
struct
vfp
*
vfp
;
};
struct
vmod_brotli_decoder
{
unsigned
magic
;
#define VMOD_BROTLI_DECODER_MAGIC 0x263b6d01
struct
vfp
*
vfp
;
};
struct
custom_vfp_entry
{
unsigned
magic
;
#define CUSTOM_VFP_MAGIC 0xfc88cb98
...
...
@@ -502,28 +508,27 @@ vmod_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
/* Object encoder */
VCL_VOID
vmod_encoder__init
(
VRT_CTX
,
struct
vmod_brotli_encoder
**
encp
,
const
char
*
vcl_name
,
struct
vmod_priv
*
priv
,
VCL_STRING
filter_name
,
VCL_BYTES
bufsz
)
static
int
coder_init
(
VRT_CTX
,
const
char
*
vcl_name
,
struct
vmod_priv
*
priv
,
VCL_STRING
filter_name
,
VCL_BYTES
bufsz
,
struct
vfp
**
vfpp
,
struct
vbr_settings
**
settingsp
)
{
struct
vmod_brotli_encoder
*
enc
;
struct
vfp
*
vfp
;
struct
vbr_settings
*
settings
;
struct
custom_vfp_head
*
vfph
;
struct
custom_vfp_entry
*
vfpe
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
encp
);
AZ
(
*
encp
);
AN
(
vcl_name
);
AN
(
priv
);
AN
(
filter_name
);
AN
(
vfpp
);
AN
(
settingsp
);
assert
(
bufsz
>=
0
);
if
(
*
filter_name
==
'\0'
)
{
VFAIL
(
ctx
,
"new %s: filter name must be non-empty"
,
vcl_name
);
return
;
return
(
-
1
)
;
}
if
(
strcmp
(
filter_name
,
"br"
)
==
0
||
strcmp
(
filter_name
,
"unbr"
)
==
0
||
strcmp
(
filter_name
,
"esi"
)
==
0
...
...
@@ -534,19 +539,11 @@ vmod_encoder__init(VRT_CTX, struct vmod_brotli_encoder **encp,
VFAIL
(
ctx
,
"new %s: filter name %s already in use by another VFP"
,
vcl_name
,
filter_name
);
return
;
return
(
-
1
)
;
}
if
(
bufsz
==
0
)
{
VFAIL
(
ctx
,
"new %s: buffer size must be > 0b"
,
vcl_name
);
return
;
}
errno
=
0
;
ALLOC_OBJ
(
enc
,
VMOD_BROTLI_ENCODER_MAGIC
);
if
(
enc
==
NULL
)
{
VFAIL
(
ctx
,
"new %s: cannot allocate space for object: %s"
,
vcl_name
,
strerror
(
errno
));
return
;
return
(
-
1
);
}
errno
=
0
;
...
...
@@ -554,39 +551,70 @@ vmod_encoder__init(VRT_CTX, struct vmod_brotli_encoder **encp,
if
(
vfp
==
NULL
)
{
VFAIL
(
ctx
,
"new %s: cannot allocate space for VFP: %s"
,
vcl_name
,
strerror
(
errno
));
return
;
return
(
-
1
)
;
}
*
vfpp
=
vfp
;
errno
=
0
;
ALLOC_OBJ
(
settings
,
VBR_SETTINGS_MAGIC
);
if
(
vfp
==
NULL
)
{
if
(
settings
==
NULL
)
{
VFAIL
(
ctx
,
"new %s: cannot allocate space for settings: %s"
,
vcl_name
,
strerror
(
errno
));
return
;
return
(
-
1
)
;
}
*
settingsp
=
settings
;
errno
=
0
;
ALLOC_OBJ
(
vfpe
,
CUSTOM_VFP_MAGIC
);
if
(
vfpe
==
NULL
)
{
VFAIL
(
ctx
,
"new %s: cannot allocate space
VFP
entry: %s"
,
VFAIL
(
ctx
,
"new %s: cannot allocate space
for VFP list
entry: %s"
,
vcl_name
,
strerror
(
errno
));
return
;
return
(
-
1
)
;
}
settings
->
bufsz
=
bufsz
;
settings
->
which
=
ENC
;
vfp
->
name
=
strdup
(
filter_name
);
vfp
->
init
=
vfp_br_init
;
vfp
->
pull
=
vfp_br_pull
;
vfp
->
fini
=
vfp_br_fini
;
vfp
->
priv1
=
settings
;
enc
->
vfp
=
vfp
;
VRT_AddVFP
(
ctx
,
vfp
);
vfph
=
init_priv_vcl
(
priv
);
vfpe
->
vfp
=
vfp
;
VSLIST_INSERT_HEAD
(
vfph
,
vfpe
,
list
);
return
(
0
);
}
VCL_VOID
vmod_encoder__init
(
VRT_CTX
,
struct
vmod_brotli_encoder
**
encp
,
const
char
*
vcl_name
,
struct
vmod_priv
*
priv
,
VCL_STRING
filter_name
,
VCL_BYTES
bufsz
)
{
struct
vmod_brotli_encoder
*
enc
;
struct
vfp
*
vfp
=
NULL
;
struct
vbr_settings
*
settings
=
NULL
;
AN
(
encp
);
AZ
(
*
encp
);
if
(
coder_init
(
ctx
,
vcl_name
,
priv
,
filter_name
,
bufsz
,
&
vfp
,
&
settings
)
!=
0
)
return
;
AN
(
vfp
);
CHECK_OBJ_NOTNULL
(
settings
,
VBR_SETTINGS_MAGIC
);
errno
=
0
;
ALLOC_OBJ
(
enc
,
VMOD_BROTLI_ENCODER_MAGIC
);
if
(
enc
==
NULL
)
{
VFAIL
(
ctx
,
"new %s: cannot allocate space for object: %s"
,
vcl_name
,
strerror
(
errno
));
return
;
}
vfp
->
pull
=
vfp_br_pull
;
VRT_AddVFP
(
ctx
,
vfp
);
settings
->
which
=
ENC
;
enc
->
vfp
=
vfp
;
}
/*
...
...
@@ -607,6 +635,56 @@ vmod_encoder__fini(struct vmod_brotli_encoder **encp)
FREE_OBJ
(
enc
);
}
/* Object decoder */
VCL_VOID
vmod_decoder__init
(
VRT_CTX
,
struct
vmod_brotli_decoder
**
decp
,
const
char
*
vcl_name
,
struct
vmod_priv
*
priv
,
VCL_STRING
filter_name
,
VCL_BYTES
bufsz
)
{
struct
vmod_brotli_decoder
*
dec
;
struct
vfp
*
vfp
=
NULL
;
struct
vbr_settings
*
settings
=
NULL
;
AN
(
decp
);
AZ
(
*
decp
);
if
(
coder_init
(
ctx
,
vcl_name
,
priv
,
filter_name
,
bufsz
,
&
vfp
,
&
settings
)
!=
0
)
return
;
AN
(
vfp
);
CHECK_OBJ_NOTNULL
(
settings
,
VBR_SETTINGS_MAGIC
);
errno
=
0
;
ALLOC_OBJ
(
dec
,
VMOD_BROTLI_DECODER_MAGIC
);
if
(
dec
==
NULL
)
{
VFAIL
(
ctx
,
"new %s: cannot allocate space for object: %s"
,
vcl_name
,
strerror
(
errno
));
return
;
}
vfp
->
pull
=
vfp_unbr_pull
;
VRT_AddVFP
(
ctx
,
vfp
);
settings
->
which
=
DEC
;
dec
->
vfp
=
vfp
;
}
/*
* As above, free the settings, custom VFP and PRIV_VCL list on DISCARD.
*/
VCL_VOID
vmod_decoder__fini
(
struct
vmod_brotli_decoder
**
decp
)
{
struct
vmod_brotli_decoder
*
dec
;
if
(
decp
==
NULL
||
*
decp
==
NULL
)
return
;
CHECK_OBJ
(
*
decp
,
VMOD_BROTLI_DECODER_MAGIC
);
dec
=
*
decp
;
*
decp
=
NULL
;
FREE_OBJ
(
dec
);
}
/* Version functions */
static
VCL_STRING
...
...
src/vfp_brotli.vcc
View file @
df105a52
...
...
@@ -70,7 +70,7 @@ $Object encoder(PRIV_VCL, STRING name, BYTES bufffer=32768)
XXX ...
# $Object decoder(STRING name, BYTES buffer=32k, BOOL lgwin=0
)
$Object decoder(PRIV_VCL, STRING name, BYTES buffer=32768
)
XXX ...
...
...
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