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
affd96d4
Commit
affd96d4
authored
Jun 23, 2014
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generalize v1f_pull_chunked() into HTTP1_Chunked() which can also be
used on requests.
parent
b61c2305
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
123 additions
and
73 deletions
+123
-73
cache.h
bin/varnishd/cache/cache.h
+8
-0
cache_http1_fetch.c
bin/varnishd/cache/cache_http1_fetch.c
+10
-73
cache_http1_proto.c
bin/varnishd/cache/cache_http1_proto.c
+105
-0
No files found.
bin/varnishd/cache/cache.h
View file @
affd96d4
...
...
@@ -859,6 +859,14 @@ int HTTP1_CacheReqBody(struct req *req, ssize_t maxsize);
int
HTTP1_IterateReqBody
(
struct
req
*
req
,
req_body_iter_f
*
func
,
void
*
priv
);
extern
const
int
HTTP1_Req
[
3
];
extern
const
int
HTTP1_Resp
[
3
];
enum
http1_chunked_ret
{
H1CR_ERROR
,
H1CR_MORE
,
H1CR_END
,
};
enum
http1_chunked_ret
HTTP1_Chunked
(
struct
http_conn
*
htc
,
intptr_t
*
priv
,
const
char
**
error
,
int64_t
*
statp
,
void
*
ptr
,
ssize_t
*
lp
);
/* cache_http1_deliver.c */
unsigned
V1D_FlushReleaseAcct
(
struct
req
*
req
);
...
...
bin/varnishd/cache/cache_http1_fetch.c
View file @
affd96d4
...
...
@@ -40,7 +40,6 @@
#include "cache_backend.h"
#include "vcli_priv.h"
#include "vct.h"
#include "vtcp.h"
#include "vtim.h"
...
...
@@ -110,10 +109,7 @@ v1f_pull_straight(struct busyobj *bo, void *p, ssize_t *lp, intptr_t *priv)
static
enum
vfp_status
__match_proto__
(
vfp_pull_f
)
v1f_pull_chunked
(
struct
busyobj
*
bo
,
void
*
p
,
ssize_t
*
lp
,
intptr_t
*
priv
)
{
int
i
;
char
buf
[
20
];
/* XXX: 20 is arbitrary */
unsigned
u
;
ssize_t
cl
,
l
,
lr
;
const
char
*
err
;
CHECK_OBJ_NOTNULL
(
bo
,
BUSYOBJ_MAGIC
);
if
(
p
==
vfp_init
)
...
...
@@ -123,77 +119,18 @@ v1f_pull_chunked(struct busyobj *bo, void *p, ssize_t *lp, intptr_t *priv)
AN
(
p
);
AN
(
lp
);
AN
(
priv
);
l
=
*
lp
;
*
lp
=
0
;
if
(
*
priv
==
-
1
)
{
/* Skip leading whitespace */
do
{
lr
=
HTTP1_Read
(
&
bo
->
htc
,
buf
,
1
);
if
(
lr
<=
0
)
return
(
VFP_Error
(
bo
,
"chunked read err"
));
bo
->
acct
.
beresp_bodybytes
+=
lr
;
}
while
(
vct_islws
(
buf
[
0
]));
if
(
!
vct_ishex
(
buf
[
0
]))
return
(
VFP_Error
(
bo
,
"chunked header non-hex"
));
/* Collect hex digits, skipping leading zeros */
for
(
u
=
1
;
u
<
sizeof
buf
;
u
++
)
{
do
{
lr
=
HTTP1_Read
(
&
bo
->
htc
,
buf
+
u
,
1
);
if
(
lr
<=
0
)
return
(
VFP_Error
(
bo
,
"chunked read err"
));
bo
->
acct
.
beresp_bodybytes
+=
lr
;
}
while
(
u
==
1
&&
buf
[
0
]
==
'0'
&&
buf
[
u
]
==
'0'
);
if
(
!
vct_ishex
(
buf
[
u
]))
break
;
}
if
(
u
>=
sizeof
buf
)
return
(
VFP_Error
(
bo
,
"chunked header too long"
));
/* Skip trailing white space */
while
(
vct_islws
(
buf
[
u
])
&&
buf
[
u
]
!=
'\n'
)
{
lr
=
HTTP1_Read
(
&
bo
->
htc
,
buf
+
u
,
1
);
if
(
lr
<=
0
)
return
(
VFP_Error
(
bo
,
"chunked read err"
));
bo
->
acct
.
beresp_bodybytes
+=
lr
;
}
if
(
buf
[
u
]
!=
'\n'
)
return
(
VFP_Error
(
bo
,
"chunked header no NL"
));
buf
[
u
]
=
'\0'
;
cl
=
vbf_fetch_number
(
buf
,
16
);
if
(
cl
<
0
)
return
(
VFP_Error
(
bo
,
"chunked header number syntax"
));
*
priv
=
cl
;
}
if
(
*
priv
>
0
)
{
if
(
*
priv
<
l
)
l
=
*
priv
;
lr
=
HTTP1_Read
(
&
bo
->
htc
,
p
,
l
);
if
(
lr
<=
0
)
return
(
VFP_Error
(
bo
,
"straight insufficient bytes"
));
bo
->
acct
.
beresp_bodybytes
+=
lr
;
*
lp
=
lr
;
*
priv
-=
lr
;
if
(
*
priv
==
0
)
*
priv
=
-
1
;
switch
(
HTTP1_Chunked
(
&
bo
->
htc
,
priv
,
&
err
,
&
bo
->
acct
.
beresp_bodybytes
,
p
,
lp
))
{
case
H1CR_ERROR
:
return
(
VFP_Error
(
bo
,
"%s"
,
err
));
case
H1CR_MORE
:
return
(
VFP_OK
);
case
H1CR_END
:
return
(
VFP_END
);
default:
WRONG
(
"invalid HTTP1_Chunked return"
);
}
AZ
(
*
priv
);
i
=
HTTP1_Read
(
&
bo
->
htc
,
buf
,
1
);
if
(
i
<=
0
)
return
(
VFP_Error
(
bo
,
"chunked read err"
));
bo
->
acct
.
beresp_bodybytes
+=
i
;
if
(
buf
[
0
]
==
'\r'
&&
HTTP1_Read
(
&
bo
->
htc
,
buf
,
1
)
<=
0
)
return
(
VFP_Error
(
bo
,
"chunked read err"
));
if
(
buf
[
0
]
!=
'\n'
)
return
(
VFP_Error
(
bo
,
"chunked tail no NL"
));
return
(
VFP_END
);
}
/*--------------------------------------------------------------------*/
...
...
bin/varnishd/cache/cache_http1_proto.c
View file @
affd96d4
...
...
@@ -45,6 +45,8 @@
#include "config.h"
#include <inttypes.h>
#include "cache.h"
#include "vct.h"
...
...
@@ -524,3 +526,106 @@ HTTP1_Write(const struct worker *w, const struct http *hp, const int *hf)
l
+=
WRW_Write
(
w
,
"
\r\n
"
,
-
1
);
return
(
l
);
}
/*--------------------------------------------------------------------
* Read a chunked body.
*
* XXX: Reading one byte at a time is pretty pessimal.
*/
enum
http1_chunked_ret
HTTP1_Chunked
(
struct
http_conn
*
htc
,
intptr_t
*
priv
,
const
char
**
error
,
int64_t
*
statp
,
void
*
ptr
,
ssize_t
*
lp
)
{
int
i
;
char
buf
[
20
];
/* XXX: 20 is arbitrary */
char
*
q
;
unsigned
u
;
uintmax_t
cll
;
ssize_t
cl
,
l
,
lr
;
#define ERR(x) do { *error = (x); return (H1CR_ERROR); } while (0)
CHECK_OBJ_NOTNULL
(
htc
,
HTTP_CONN_MAGIC
);
AN
(
priv
);
AN
(
error
);
AN
(
statp
);
AN
(
ptr
);
AN
(
lp
);
l
=
*
lp
;
*
lp
=
0
;
if
(
*
priv
==
-
1
)
{
/* Skip leading whitespace */
do
{
lr
=
HTTP1_Read
(
htc
,
buf
,
1
);
if
(
lr
<=
0
)
ERR
(
"chunked read err"
);
*
statp
+=
lr
;
}
while
(
vct_islws
(
buf
[
0
]));
if
(
!
vct_ishex
(
buf
[
0
]))
ERR
(
"chunked header non-hex"
);
/* Collect hex digits, skipping leading zeros */
for
(
u
=
1
;
u
<
sizeof
buf
;
u
++
)
{
do
{
lr
=
HTTP1_Read
(
htc
,
buf
+
u
,
1
);
if
(
lr
<=
0
)
ERR
(
"chunked read err"
);
*
statp
+=
lr
;
}
while
(
u
==
1
&&
buf
[
0
]
==
'0'
&&
buf
[
u
]
==
'0'
);
if
(
!
vct_ishex
(
buf
[
u
]))
break
;
}
if
(
u
>=
sizeof
buf
)
ERR
(
"chunked header too long"
);
/* Skip trailing white space */
while
(
vct_islws
(
buf
[
u
])
&&
buf
[
u
]
!=
'\n'
)
{
lr
=
HTTP1_Read
(
htc
,
buf
+
u
,
1
);
if
(
lr
<=
0
)
ERR
(
"chunked read err"
);
*
statp
+=
lr
;
}
if
(
buf
[
u
]
!=
'\n'
)
ERR
(
"chunked header no NL"
);
buf
[
u
]
=
'\0'
;
cll
=
strtoumax
(
buf
,
&
q
,
16
);
if
(
q
==
NULL
||
*
q
!=
'\0'
)
ERR
(
"chunked header number syntax"
);
cl
=
(
ssize_t
)
cll
;
if
((
uintmax_t
)
cl
!=
cll
)
ERR
(
"bogusly large chunk size"
);
*
priv
=
cl
;
}
if
(
*
priv
>
0
)
{
if
(
*
priv
<
l
)
l
=
*
priv
;
lr
=
HTTP1_Read
(
htc
,
ptr
,
l
);
if
(
lr
<=
0
)
ERR
(
"straight insufficient bytes"
);
*
statp
+=
lr
;
*
lp
=
lr
;
*
priv
-=
lr
;
if
(
*
priv
==
0
)
*
priv
=
-
1
;
return
(
H1CR_MORE
);
}
AZ
(
*
priv
);
i
=
HTTP1_Read
(
htc
,
buf
,
1
);
if
(
i
<=
0
)
ERR
(
"chunked read err"
);
*
statp
+=
i
;
if
(
buf
[
0
]
==
'\r'
&&
HTTP1_Read
(
htc
,
buf
,
1
)
<=
0
)
ERR
(
"chunked read err"
);
if
(
buf
[
0
]
!=
'\n'
)
ERR
(
"chunked tail no NL"
);
return
(
H1CR_END
);
#undef ERR
}
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