Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
pistache
Commits
a61d3be1
Unverified
Commit
a61d3be1
authored
Jul 20, 2020
by
Igor [hyperxor]
Committed by
GitHub
Jul 20, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix inssue #803 (#804)
parent
4d60787d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
12 deletions
+61
-12
tests/streaming_test.cc
tests/streaming_test.cc
+61
-12
No files found.
tests/streaming_test.cc
View file @
a61d3be1
...
...
@@ -12,6 +12,8 @@
#include <queue>
#include <thread>
#include <vector>
#include <string>
#include <condition_variable>
using
namespace
std
;
using
namespace
Pistache
;
...
...
@@ -85,13 +87,33 @@ void dumpData(const Rest::Request & /*req*/, Http::ResponseWriter response) {
stream
.
ends
();
}
namespace
{
struct
SyncContext
{
std
::
mutex
m
;
std
::
condition_variable
cv
;
bool
flag
=
false
;
};
using
Chunks
=
std
::
vector
<
std
::
string
>
;
std
::
string
chunksToString
(
const
Chunks
&
chunks
)
{
std
::
string
result
;
for
(
const
auto
&
chunk
:
chunks
)
{
result
+=
chunk
;
}
return
result
;
}
}
// from
// https://stackoverflow.com/questions/6624667/can-i-use-libcurls-curlopt-writefunction-with-a-c11-lambda-expression#14720398
typedef
size_t
(
*
CURL_WRITEFUNCTION_PTR
)(
void
*
,
size_t
,
size_t
,
void
*
);
auto
curl_callback
=
[](
void
*
ptr
,
size_t
size
,
size_t
nmemb
,
void
*
stream
)
->
size_t
{
auto
ss
=
static_cast
<
std
::
stringstream
*>
(
stream
);
ss
->
write
(
static_cast
<
char
*>
(
ptr
),
size
*
nmemb
);
void
*
userdata
)
->
size_t
{
auto
chunks
=
static_cast
<
Chunks
*>
(
userdata
);
chunks
->
emplace_back
(
static_cast
<
char
*>
(
ptr
),
size
*
nmemb
);
return
size
*
nmemb
;
};
...
...
@@ -122,7 +144,7 @@ public:
curl_easy_setopt
(
curl
,
CURLOPT_URL
,
url
.
c_str
());
curl_easy_setopt
(
curl
,
CURLOPT_WRITEFUNCTION
,
static_cast
<
CURL_WRITEFUNCTION_PTR
>
(
curl_callback
));
curl_easy_setopt
(
curl
,
CURLOPT_WRITEDATA
,
&
s
s
);
curl_easy_setopt
(
curl
,
CURLOPT_WRITEDATA
,
&
chunk
s
);
curl_easy_setopt
(
curl
,
CURLOPT_VERBOSE
,
1L
);
}
...
...
@@ -131,7 +153,7 @@ public:
CURL
*
curl
;
std
::
string
url
;
std
::
stringstream
s
s
;
Chunks
chunk
s
;
static
constexpr
std
::
size_t
threads
=
20
;
};
...
...
@@ -152,40 +174,67 @@ TEST_F(StreamingTests, FromDescription) {
std
::
cerr
<<
curl_easy_strerror
(
res
)
<<
std
::
endl
;
ASSERT_EQ
(
res
,
CURLE_OK
);
ASSERT_EQ
(
ss
.
str
(
).
size
(),
SET_REPEATS
*
LETTER_REPEATS
*
N_LETTERS
);
ASSERT_EQ
(
chunksToString
(
chunks
).
size
(),
SET_REPEATS
*
LETTER_REPEATS
*
N_LETTERS
);
}
class
HelloHandler
:
public
Http
::
Handler
{
public:
HTTP_PROTOTYPE
(
HelloHandler
)
explicit
HelloHandler
(
SyncContext
&
ctx
)
:
ctx_
{
ctx
}
{}
void
onRequest
(
const
Http
::
Request
&
,
Http
::
ResponseWriter
response
)
override
{
std
::
unique_lock
<
std
::
mutex
>
lk
(
ctx_
.
m
);
auto
stream
=
response
.
stream
(
Http
::
Code
::
Ok
);
stream
<<
"Hello "
;
stream
.
flush
();
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
seconds
(
2
));
stream
<<
"world!"
;
stream
<<
"world"
;
stream
.
flush
();
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
seconds
(
2
));
stream
<<
"!"
;
stream
.
ends
();
ctx_
.
flag
=
true
;
lk
.
unlock
();
ctx_
.
cv
.
notify_one
();
}
private:
SyncContext
&
ctx_
;
};
TEST_F
(
StreamingTests
,
ChunkedStream
)
{
SyncContext
ctx
;
// force unbuffered
curl_easy_setopt
(
curl
,
CURLOPT_BUFFERSIZE
,
1
);
Init
(
std
::
make_shared
<
HelloHandler
>
());
Init
(
std
::
make_shared
<
HelloHandler
>
(
ctx
));
std
::
thread
thread
([
&
]()
{
curl_easy_perform
(
curl
);
});
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
500
));
EXPECT_EQ
(
"Hello "
,
ss
.
str
());
std
::
unique_lock
<
std
::
mutex
>
lk
{
ctx
.
m
};
ctx
.
cv
.
wait
(
lk
,
[
&
ctx
]{
return
ctx
.
flag
;
});
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
2000
));
EXPECT_EQ
(
"Hello world!"
,
ss
.
str
());
thread
.
join
();
if
(
thread
.
joinable
())
{
thread
.
join
();
}
ASSERT_EQ
(
chunks
.
size
(),
3u
);
EXPECT_EQ
(
chunks
[
0
],
"Hello "
);
EXPECT_EQ
(
chunks
[
1
],
"world"
);
EXPECT_EQ
(
chunks
[
2
],
"!"
);
}
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