Skip to content

Commit 312da8b

Browse files
author
Valtteri Heikkila
committed
First WIP of Linux HTTP client cancellation token support.
1 parent 9334f8e commit 312da8b

File tree

3 files changed

+46
-16
lines changed

3 files changed

+46
-16
lines changed

Release/src/http/client/http_linux.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ namespace web { namespace http
250250

251251
void send_request(std::shared_ptr<request_context> request_ctx)
252252
{
253+
if (request_ctx->m_request._cancellation_token().is_canceled())
254+
{
255+
request_ctx->report_error(make_error_code(std::errc::operation_canceled).value(), "Request cancelled by user.");
256+
return;
257+
}
258+
253259
auto ctx = std::static_pointer_cast<linux_client_request_context>(request_ctx);
254260

255261
if (m_uri.scheme() == "https")
@@ -341,6 +347,19 @@ namespace web { namespace http
341347

342348
m_resolver.async_resolve(query, boost::bind(&linux_client::handle_resolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator, ctx));
343349
}
350+
351+
// Register for notification on cancellation to abort this request.
352+
if(request_ctx->m_request._cancellation_token() != pplx::cancellation_token::none())
353+
{
354+
ctx->m_cancellationRegistration = request_ctx->m_request._cancellation_token().register_callback([ctx]()
355+
{
356+
boost::system::error_code error;
357+
ctx->m_connection->m_socket.cancel(error);
358+
ctx->m_connection->m_socket.shutdown(tcp::socket::shutdown_both, error);
359+
ctx->m_connection->m_socket.close(error);
360+
ctx->m_close_socket_in_destructor = true;
361+
});
362+
}
344363
}
345364

346365
boost::asio::io_service& m_io_service;
@@ -501,15 +520,29 @@ namespace web { namespace http
501520
ctx->m_uploaded += (size64_t)readSize;
502521
if (ctx->m_ssl_stream)
503522
{
504-
boost::asio::async_write(*ctx->m_ssl_stream, ctx->m_body_buf,
505-
boost::bind(readSize != 0 ? &linux_client::handle_write_chunked_body : &linux_client::handle_write_body,
506-
shared_from_this(), boost::asio::placeholders::error, ctx));
523+
if (readSize != 0)
524+
{
525+
boost::asio::async_write(*ctx->m_ssl_stream, ctx->m_body_buf,
526+
boost::bind(&linux_client::handle_write_chunked_body, shared_from_this(), boost::asio::placeholders::error, ctx));
527+
}
528+
else
529+
{
530+
boost::asio::async_write(*ctx->m_ssl_stream, ctx->m_body_buf,
531+
boost::bind(&linux_client::handle_write_body, shared_from_this(), boost::asio::placeholders::error, ctx));
532+
}
507533
}
508534
else
509535
{
510-
boost::asio::async_write(ctx->m_connection->m_socket, ctx->m_body_buf,
511-
boost::bind(readSize != 0 ? &linux_client::handle_write_chunked_body : &linux_client::handle_write_body,
512-
shared_from_this(), boost::asio::placeholders::error, ctx));
536+
if (readSize != 0)
537+
{
538+
boost::asio::async_write(ctx->m_connection->m_socket, ctx->m_body_buf,
539+
boost::bind(&linux_client::handle_write_chunked_body, shared_from_this(), boost::asio::placeholders::error, ctx));
540+
}
541+
else
542+
{
543+
boost::asio::async_write(ctx->m_connection->m_socket, ctx->m_body_buf,
544+
boost::bind(&linux_client::handle_write_body, shared_from_this(), boost::asio::placeholders::error, ctx));
545+
}
513546
}
514547
});
515548
}
@@ -616,7 +649,7 @@ namespace web { namespace http
616649
else
617650
{
618651
boost::asio::async_read_until(ctx->m_connection->m_socket, ctx->m_body_buf, CRLF+CRLF,
619-
boost::bind(&linux_client::handle_status_line, shared_from_this(), boost::asio::placeholders::error, ctx));
652+
boost::bind(&linux_client::handle_status_line, shared_from_this(), boost::asio::placeholders::error, ctx));
620653
}
621654
}
622655
else

Release/tests/Functional/http/client/connections_and_errors.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ TEST_FIXTURE(uri_address, stream_timeout, "Ignore:Apple", "Bug 885080")
245245

246246
#pragma region Cancellation tests
247247

248-
TEST_FIXTURE(uri_address, cancel_before_request, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI")
248+
TEST_FIXTURE(uri_address, cancel_before_request)
249249
{
250250
test_http_server::scoped_server scoped(m_uri);
251251
http_client c(m_uri);
@@ -258,7 +258,7 @@ TEST_FIXTURE(uri_address, cancel_before_request, "Ignore:Linux", "NYI", "Ignore:
258258

259259
// This test can't be implemented with our test server so isn't avaliable on WinRT.
260260
#ifndef __cplusplus_winrt
261-
TEST_FIXTURE(uri_address, cancel_after_headers, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI")
261+
TEST_FIXTURE(uri_address, cancel_after_headers)
262262
{
263263
web::http::experimental::listener::http_listener listener(m_uri);
264264
listener.open().wait();
@@ -290,7 +290,7 @@ TEST_FIXTURE(uri_address, cancel_after_headers, "Ignore:Linux", "NYI", "Ignore:A
290290
}
291291
#endif
292292

293-
TEST_FIXTURE(uri_address, cancel_after_body, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI")
293+
TEST_FIXTURE(uri_address, cancel_after_body)
294294
{
295295
test_http_server::scoped_server scoped(m_uri);
296296
test_http_server * p_server = scoped.server();
@@ -311,7 +311,7 @@ TEST_FIXTURE(uri_address, cancel_after_body, "Ignore:Linux", "NYI", "Ignore:Appl
311311
response.content_ready().wait();
312312
}
313313

314-
TEST_FIXTURE(uri_address, cancel_with_error, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI")
314+
TEST_FIXTURE(uri_address, cancel_with_error)
315315
{
316316
test_http_server server(m_uri);
317317
VERIFY_ARE_EQUAL(0, server.open());
@@ -326,7 +326,7 @@ TEST_FIXTURE(uri_address, cancel_with_error, "Ignore:Linux", "NYI", "Ignore:Appl
326326
VERIFY_THROWS_HTTP_ERROR_CODE(responseTask.get(), std::errc::operation_canceled);
327327
}
328328

329-
TEST_FIXTURE(uri_address, cancel_while_uploading_data, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI")
329+
TEST_FIXTURE(uri_address, cancel_while_uploading_data)
330330
{
331331
test_http_server::scoped_server scoped(m_uri);
332332
http_client c(m_uri);
@@ -343,7 +343,7 @@ TEST_FIXTURE(uri_address, cancel_while_uploading_data, "Ignore:Linux", "NYI", "I
343343

344344
// This test can't be implemented with our test server since it doesn't stream data so isn't avaliable on WinRT.
345345
#ifndef __cplusplus_winrt
346-
TEST_FIXTURE(uri_address, cancel_while_downloading_data, "Ignore:Linux", "NYI", "Ignore:Apple", "NYI")
346+
TEST_FIXTURE(uri_address, cancel_while_downloading_data)
347347
{
348348
web::http::experimental::listener::http_listener listener(m_uri);
349349
listener.open().wait();

Release/tests/Functional/http/client/request_stream_tests.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,6 @@ TEST_FIXTURE(uri_address, stream_close_early)
362362

363363
TEST_FIXTURE(uri_address, stream_close_early_with_exception,
364364
"Ignore", "825361",
365-
"Ignore:Linux", "TBD",
366365
"Ignore:Apple", "The test server has trouble closing.")
367366
{
368367
http_client client(m_uri);
@@ -385,7 +384,6 @@ TEST_FIXTURE(uri_address, stream_close_early)
385384

386385
TEST_FIXTURE(uri_address, stream_close_early_with_exception_and_contentlength,
387386
"Ignore", "825361",
388-
"Ignore:Linux", "TBD",
389387
"Ignore:Apple", "The test server has trouble closing.")
390388
{
391389
http_client client(m_uri);
@@ -407,7 +405,6 @@ TEST_FIXTURE(uri_address, stream_close_early_with_exception_and_contentlength,
407405

408406
TEST_FIXTURE(uri_address, stream_close_early_with_contentlength,
409407
"Ignore", "825361",
410-
"Ignore:Linux", "TBD",
411408
"Ignore:Apple", "The test server has trouble closing.")
412409
{
413410
http_client client(m_uri);

0 commit comments

Comments
 (0)