Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
c94a88e4
Unverified
Commit
c94a88e4
authored
Jun 08, 2018
by
Kenton Varda
Committed by
GitHub
Jun 08, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #688 from capnproto/harris/http-chunked-body-fixes
Chunked body fixes in kj-http
parents
50fb6e51
79a3ff0d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
85 additions
and
5 deletions
+85
-5
async-io.c++
c++/src/kj/async-io.c++
+1
-1
http-test.c++
c++/src/kj/compat/http-test.c++
+80
-0
http.c++
c++/src/kj/compat/http.c++
+3
-3
http.h
c++/src/kj/compat/http.h
+1
-1
No files found.
c++/src/kj/async-io.c++
View file @
c94a88e4
...
...
@@ -376,7 +376,7 @@ private:
// Write the first piece.
auto
promise
=
output
.
write
(
writeBuffer
.
begin
(),
writeBuffer
.
size
());
// Write full pieces as a sing
c
le gather-write.
// Write full pieces as a single gather-write.
if
(
i
>
0
)
{
auto
more
=
morePieces
.
slice
(
0
,
i
);
promise
=
promise
.
then
([
&
output
,
more
]()
{
return
output
.
write
(
more
);
});
...
...
c++/src/kj/compat/http-test.c++
View file @
c94a88e4
...
...
@@ -903,6 +903,86 @@ KJ_TEST("HttpClient canceled write") {
KJ_EXPECT
(
text
==
"POST / HTTP/1.1
\r\n
Content-Length: 4096
\r\n\r\n
"
,
text
);
}
KJ_TEST
(
"HttpClient chunked body gather-write"
)
{
kj
::
EventLoop
eventLoop
;
kj
::
WaitScope
waitScope
(
eventLoop
);
auto
pipe
=
kj
::
newTwoWayPipe
();
auto
serverPromise
=
pipe
.
ends
[
1
]
->
readAllText
();
{
HttpHeaderTable
table
;
auto
client
=
newHttpClient
(
table
,
*
pipe
.
ends
[
0
]);
auto
req
=
client
->
request
(
HttpMethod
::
POST
,
"/"
,
HttpHeaders
(
table
));
kj
::
ArrayPtr
<
const
byte
>
bodyParts
[]
=
{
{
'f'
,
'o'
,
'o'
},
{
' '
},
{
'b'
,
'a'
,
'r'
},
{
' '
},
{
'b'
,
'a'
,
'z'
}
};
req
.
body
->
write
(
kj
::
arrayPtr
(
bodyParts
,
kj
::
size
(
bodyParts
))).
wait
(
waitScope
);
req
.
body
=
nullptr
;
// Wait for a response so the client has a chance to end the request body with a 0-chunk.
kj
::
StringPtr
responseText
=
"HTTP/1.1 204 No Content
\r\n\r\n
"
;
pipe
.
ends
[
1
]
->
write
(
responseText
.
begin
(),
responseText
.
size
()).
wait
(
waitScope
);
auto
response
=
req
.
response
.
wait
(
waitScope
);
}
pipe
.
ends
[
0
]
->
shutdownWrite
();
auto
text
=
serverPromise
.
wait
(
waitScope
);
KJ_EXPECT
(
text
==
"POST / HTTP/1.1
\r\n
Transfer-Encoding: chunked
\r\n\r\n
"
"b
\r\n
foo bar baz
\r\n
0
\r\n\r\n
"
,
text
);
}
KJ_TEST
(
"HttpClient chunked body pump from fixed length stream"
)
{
class
FixedBodyStream
final
:
public
kj
::
AsyncInputStream
{
Promise
<
size_t
>
tryRead
(
void
*
buffer
,
size_t
minBytes
,
size_t
maxBytes
)
override
{
auto
n
=
kj
::
min
(
body
.
size
(),
maxBytes
);
n
=
kj
::
max
(
n
,
minBytes
);
n
=
kj
::
min
(
n
,
body
.
size
());
memcpy
(
buffer
,
body
.
begin
(),
n
);
body
=
body
.
slice
(
n
);
return
n
;
}
Maybe
<
uint64_t
>
tryGetLength
()
override
{
return
body
.
size
();
}
kj
::
StringPtr
body
=
"foo bar baz"
;
};
kj
::
EventLoop
eventLoop
;
kj
::
WaitScope
waitScope
(
eventLoop
);
auto
pipe
=
kj
::
newTwoWayPipe
();
auto
serverPromise
=
pipe
.
ends
[
1
]
->
readAllText
();
{
HttpHeaderTable
table
;
auto
client
=
newHttpClient
(
table
,
*
pipe
.
ends
[
0
]);
auto
req
=
client
->
request
(
HttpMethod
::
POST
,
"/"
,
HttpHeaders
(
table
));
FixedBodyStream
bodyStream
;
bodyStream
.
pumpTo
(
*
req
.
body
).
wait
(
waitScope
);
req
.
body
=
nullptr
;
// Wait for a response so the client has a chance to end the request body with a 0-chunk.
kj
::
StringPtr
responseText
=
"HTTP/1.1 204 No Content
\r\n\r\n
"
;
pipe
.
ends
[
1
]
->
write
(
responseText
.
begin
(),
responseText
.
size
()).
wait
(
waitScope
);
auto
response
=
req
.
response
.
wait
(
waitScope
);
}
pipe
.
ends
[
0
]
->
shutdownWrite
();
auto
text
=
serverPromise
.
wait
(
waitScope
);
KJ_EXPECT
(
text
==
"POST / HTTP/1.1
\r\n
Transfer-Encoding: chunked
\r\n\r\n
"
"b
\r\n
foo bar baz
\r\n
0
\r\n\r\n
"
,
text
);
}
KJ_TEST
(
"HttpServer requests"
)
{
HttpResponseTestCase
RESPONSE
=
{
"HTTP/1.1 200 OK
\r\n
"
...
...
c++/src/kj/compat/http.c++
View file @
c94a88e4
...
...
@@ -1879,8 +1879,8 @@ public:
if
(
size
==
0
)
return
kj
::
READY_NOW
;
// can't encode zero-size chunk since it indicates EOF.
auto
header
=
kj
::
str
(
size
,
"
\r\n
"
);
auto
partsBuilder
=
kj
::
heapArrayBuilder
<
ArrayPtr
<
const
byte
>>
(
pieces
.
size
());
auto
header
=
kj
::
str
(
kj
::
hex
(
size
)
,
"
\r\n
"
);
auto
partsBuilder
=
kj
::
heapArrayBuilder
<
ArrayPtr
<
const
byte
>>
(
pieces
.
size
()
+
2
);
partsBuilder
.
add
(
header
.
asBytes
());
for
(
auto
&
piece
:
pieces
)
{
partsBuilder
.
add
(
piece
);
...
...
@@ -1897,7 +1897,7 @@ public:
// Hey, we know exactly how large the input is, so we can write just one chunk.
uint64_t
length
=
kj
::
min
(
amount
,
*
l
);
inner
.
writeBodyData
(
kj
::
str
(
length
,
"
\r\n
"
));
inner
.
writeBodyData
(
kj
::
str
(
kj
::
hex
(
length
)
,
"
\r\n
"
));
return
inner
.
pumpBodyFrom
(
input
,
length
)
.
then
([
this
,
length
](
uint64_t
actual
)
{
if
(
actual
<
length
)
{
...
...
c++/src/kj/compat/http.h
View file @
c94a88e4
...
...
@@ -667,7 +667,7 @@ struct HttpServerSettings {
// completes, we'll let the connection stay open to handle more requests.
};
class
HttpServer
:
private
kj
::
TaskSet
::
ErrorHandler
{
class
HttpServer
final
:
private
kj
::
TaskSet
::
ErrorHandler
{
// Class which listens for requests on ports or connections and sends them to an HttpService.
public
:
...
...
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