Commit 26304546 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

[WIP] Add asio client interface

parent 838fb338
......@@ -58,10 +58,17 @@ endif # ENABLE_TINY_NGHTTPD
if ENABLE_ASIO_LIB
noinst_PROGRAMS += asio-sv asio-sv2 asio-sv3
noinst_PROGRAMS += asio-sv asio-sv2 asio-sv3 asio-cl
ASIOCPPFLAGS = ${BOOST_CPPFLAGS} ${AM_CPPFLAGS}
ASIOLDADD = $(top_builddir)/src/libnghttp2_asio.la @JEMALLOC_LIBS@
ASIOLDADD = $(top_builddir)/lib/libnghttp2.la \
$(top_builddir)/src/libnghttp2_asio.la @JEMALLOC_LIBS@ \
${BOOST_LDFLAGS} \
${BOOST_ASIO_LIB} \
${BOOST_THREAD_LIB} \
${BOOST_SYSTEM_LIB} \
@OPENSSL_LIBS@ \
@APPLDFLAGS@
asio_sv_SOURCES = asio-sv.cc
asio_sv_CPPFLAGS = ${ASIOCPPFLAGS}
......@@ -75,6 +82,10 @@ asio_sv3_SOURCES = asio-sv3.cc
asio_sv3_CPPFLAGS = ${ASIOCPPFLAGS}
asio_sv3_LDADD = ${ASIOLDADD}
asio_cl_SOURCES = asio-cl.cc
asio_cl_CPPFLAGS = ${ASIOCPPFLAGS}
asio_cl_LDADD = ${ASIOLDADD}
endif # ENABLE_ASIO_LIB
endif # ENABLE_EXAMPLES
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <nghttp2/nghttp2.h>
#include <nghttp2/asio_http2.h>
using boost::asio::ip::tcp;
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::client;
void print_header(const http_header &h) {
for (auto &kv : h.items()) {
std::cerr << kv.first << ": " << kv.second.value << "\n";
}
std::cerr << std::endl;
}
void print_header(const response &res) {
std::cerr << "HTTP/2 " << res.status_code() << "\n";
print_header(res.header());
}
void print_header(const request &req) {
std::cerr << req.method() << " " << req.scheme() << "://" << req.authority()
<< req.path() << " "
<< "HTTP/2\n";
print_header(req.header());
}
int main(int argc, char *argv[]) {
try {
boost::asio::io_service io_service;
boost::asio::ssl::context tls_ctx(boost::asio::ssl::context::sslv23);
configure_tls_context(tls_ctx);
tcp::resolver resolver(io_service);
auto endpoint_it = resolver.resolve({"localhost", "3000"});
session sess(io_service, tls_ctx, endpoint_it);
sess.on_connect([&sess]() {
std::cerr << "connected" << std::endl;
boost::system::error_code ec;
auto req = sess.submit(ec, "GET", "https://localhost:3000/",
"hello world", {{"cookie", {"foobar", true}}});
if (ec) {
std::cerr << "error: " << ec.message() << std::endl;
return;
}
req->on_response([&sess, req](response &res) {
std::cerr << "response header was received" << std::endl;
print_header(res);
res.on_data([&sess](const uint8_t *data, std::size_t len) {
std::cerr.write(reinterpret_cast<const char *>(data), len);
std::cerr << std::endl;
});
});
req->on_close([&sess](uint32_t error_code) {
std::cerr << "request done with error_code=" << error_code << std::endl;
});
req->on_push([](request &push_req) {
std::cerr << "push request was received" << std::endl;
print_header(push_req);
push_req.on_response([](response &res) {
std::cerr << "push response header was received" << std::endl;
res.on_data([](const uint8_t *data, std::size_t len) {
// std::cerr.write(reinterpret_cast<const char *>(data), len);
// std::cerr << std::endl;
});
});
});
});
sess.on_error([](const std::string &error) {
std::cerr << "error: " << error << std::endl;
});
io_service.run();
} catch (std::exception &e) {
std::cerr << "exception: " << e.what() << "\n";
}
return 0;
}
......@@ -179,7 +179,18 @@ libnghttp2_asio_la_SOURCES = \
asio_http2_handler.cc asio_http2_handler.h \
asio_http2_impl.cc asio_http2_impl.h \
util.cc util.h http2.cc http2.h \
ssl.cc ssl.h
ssl.cc ssl.h \
asio_common.cc asio_common.h \
asio_client_session.cc \
asio_client_session_impl.cc asio_client_session_impl.h \
asio_client_session_tcp_impl.cc asio_client_session_tcp_impl.h \
asio_client_session_tls_impl.cc asio_client_session_tls_impl.h \
asio_client_response.cc \
asio_client_response_impl.cc asio_client_response_impl.h \
asio_client_request.cc \
asio_client_request_impl.cc asio_client_request_impl.h \
asio_client_stream.cc asio_client_stream.h \
asio_client_tls_context.cc asio_client_tls_context.h
libnghttp2_asio_la_CPPFLAGS = ${AM_CPPFLAGS} ${BOOST_CPPFLAGS}
libnghttp2_asio_la_LDFLAGS = -no-undefined -version-info 0:0:0
......
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <nghttp2/asio_http2.h>
#include "asio_client_request_impl.h"
#include "template.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
request::request() : impl_(make_unique<request_impl>()) {}
request::~request() {}
void request::cancel() { impl_->cancel(); }
void request::on_response(response_cb cb) { impl_->on_response(std::move(cb)); }
void request::on_push(request_cb cb) { impl_->on_push(std::move(cb)); }
void request::on_close(close_cb cb) { impl_->on_close(std::move(cb)); }
const std::string &request::method() const { return impl_->method(); }
const std::string &request::scheme() const { return impl_->scheme(); }
const std::string &request::path() const { return impl_->path(); }
const std::string &request::authority() const { return impl_->authority(); }
const std::string &request::host() const { return impl_->host(); }
const http_header &request::header() const { return impl_->header(); }
request_impl &request::impl() { return *impl_; }
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_client_request_impl.h"
#include "asio_client_stream.h"
#include "template.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
request_impl::request_impl() : strm_(nullptr) {}
void request_impl::cancel() { strm_->cancel(); }
void request_impl::on_response(response_cb cb) { response_cb_ = std::move(cb); }
void request_impl::call_on_response(response &res) {
if (response_cb_) {
response_cb_(res);
}
}
void request_impl::on_push(request_cb cb) { push_request_cb_ = std::move(cb); }
void request_impl::call_on_push(request &push_req) {
if (push_request_cb_) {
push_request_cb_(push_req);
}
};
void request_impl::on_close(close_cb cb) { close_cb_ = std::move(cb); }
void request_impl::call_on_close(uint32_t error_code) {
if (close_cb_) {
close_cb_(error_code);
}
}
void request_impl::on_read(read_cb cb) { read_cb_ = std::move(cb); }
read_cb::result_type request_impl::call_on_read(uint8_t *buf, std::size_t len) {
if (read_cb_) {
return read_cb_(buf, len);
}
return read_cb::result_type{};
}
void request_impl::header(http_header h) { header_ = std::move(h); }
http_header &request_impl::header() { return header_; }
const http_header &request_impl::header() const { return header_; }
void request_impl::stream(class stream *strm) { strm_ = strm; }
void request_impl::method(std::string s) { method_ = std::move(s); }
const std::string &request_impl::method() const { return method_; }
void request_impl::scheme(std::string s) { scheme_ = std::move(s); }
const std::string &request_impl::scheme() const { return scheme_; }
void request_impl::path(std::string s) { path_ = std::move(s); }
const std::string &request_impl::path() const { return path_; }
void request_impl::authority(std::string s) { authority_ = std::move(s); }
const std::string &request_impl::authority() const { return authority_; }
void request_impl::host(std::string s) { host_ = std::move(s); }
const std::string &request_impl::host() const { return host_; }
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_REQUEST_IMPL_H
#define ASIO_CLIENT_REQUEST_IMPL_H
#include "nghttp2_config.h"
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
namespace client {
class response;
class stream;
class request_impl {
public:
request_impl();
request_impl(const request_impl &) = delete;
request_impl &operator=(const request_impl &) = delete;
void cancel();
void on_response(response_cb cb);
void call_on_response(response &res);
void on_push(request_cb cb);
void call_on_push(request &push_req);
void on_close(close_cb cb);
void call_on_close(uint32_t error_code);
void on_read(read_cb cb);
read_cb::result_type call_on_read(uint8_t *buf, std::size_t len);
void header(http_header h);
http_header &header();
const http_header &header() const;
void stream(class stream *strm);
void method(std::string s);
const std::string &method() const;
void scheme(std::string s);
const std::string &scheme() const;
void path(std::string s);
const std::string &path() const;
void authority(std::string s);
const std::string &authority() const;
void host(std::string s);
const std::string &host() const;
private:
http_header header_;
response_cb response_cb_;
request_cb push_request_cb_;
close_cb close_cb_;
read_cb read_cb_;
class stream *strm_;
std::string method_;
std::string scheme_;
std::string path_;
std::string authority_;
std::string host_;
};
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_CLIENT_REQUEST_IMPL_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <nghttp2/asio_http2.h>
#include "asio_client_response_impl.h"
#include "template.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
response::response() : impl_(make_unique<response_impl>()) {}
response::~response() {}
void response::on_data(data_cb cb) { impl_->on_data(std::move(cb)); }
int response::status_code() const { return impl_->status_code(); }
int64_t response::content_length() const { return impl_->content_length(); }
const http_header &response::header() const { return impl_->header(); }
response_impl &response::impl() { return *impl_; }
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_client_response_impl.h"
#include "template.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
response_impl::response_impl() : content_length_(-1), status_code_(0) {}
void response_impl::on_data(data_cb cb) { data_cb_ = std::move(cb); }
void response_impl::call_on_data(const uint8_t *data, std::size_t len) {
if (data_cb_) {
data_cb_(data, len);
}
}
void response_impl::status_code(int sc) { status_code_ = sc; }
int response_impl::status_code() const { return status_code_; }
void response_impl::content_length(int64_t n) { content_length_ = n; }
int64_t response_impl::content_length() const { return content_length_; }
http_header &response_impl::header() { return header_; }
const http_header &response_impl::header() const { return header_; }
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_RESPONSE_IMPL_H
#define ASIO_CLIENT_RESPONSE_IMPL_H
#include "nghttp2_config.h"
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
namespace client {
class response_impl {
public:
response_impl();
response_impl(const response_impl &) = delete;
response_impl &operator=(const response_impl &) = delete;
void on_data(data_cb cb);
void call_on_data(const uint8_t *data, std::size_t len);
void status_code(int sc);
int status_code() const;
void content_length(int64_t n);
int64_t content_length() const;
http_header &header();
const http_header &header() const;
private:
data_cb data_cb_;
http_header header_;
int64_t content_length_;
int status_code_;
};
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_CLIENT_RESPONSE_IMPL_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nghttp2_config.h"
#include <nghttp2/asio_http2.h>
#include "asio_client_session_tcp_impl.h"
#include "asio_client_session_tls_impl.h"
#include "asio_common.h"
#include "template.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
using boost::asio::ip::tcp;
session::session(boost::asio::io_service &io_service,
tcp::resolver::iterator endpoint_it)
: impl_(make_unique<session_tcp_impl>(io_service, endpoint_it)) {}
session::session(boost::asio::io_service &io_service,
boost::asio::ssl::context &tls_ctx,
tcp::resolver::iterator endpoint_it)
: impl_(make_unique<session_tls_impl>(io_service, tls_ctx, endpoint_it)) {}
session::~session() {}
void session::on_connect(void_cb cb) { impl_->on_connect(std::move(cb)); }
void session::on_error(error_cb cb) { impl_->on_error(std::move(cb)); }
void session::shutdown() { impl_->shutdown(); }
request *session::submit(boost::system::error_code &ec,
const std::string &method, const std::string &uri,
http_header h) {
return impl_->submit(ec, method, uri, read_cb(), std::move(h));
}
request *session::submit(boost::system::error_code &ec,
const std::string &method, const std::string &uri,
std::string data, http_header h) {
return impl_->submit(ec, method, uri, string_reader(std::move(data)),
std::move(h));
}
request *session::submit(boost::system::error_code &ec,
const std::string &method, const std::string &uri,
read_cb cb, http_header h) {
return impl_->submit(ec, method, uri, std::move(cb), std::move(h));
}
} // namespace client
} // namespace asio_http2
} // nghttp2
This diff is collapsed.
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_SESSION_IMPL_H
#define ASIO_CLIENT_SESSION_IMPL_H
#include "nghttp2_config.h"
#include <map>
#include <boost/asio.hpp>
#include <nghttp2/nghttp2.h>
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
namespace client {
class stream;
using boost::asio::ip::tcp;
class session_impl {
public:
session_impl();
virtual ~session_impl();
void connected();
void not_connected(const boost::system::error_code &ec);
void on_connect(void_cb cb);
void on_error(error_cb cb);
const void_cb &on_connect() const;
const error_cb &on_error() const;
void cancel(stream &strm);
std::unique_ptr<stream> create_stream();
std::unique_ptr<stream> pop_stream(int32_t stream_id);
stream *create_push_stream(int32_t stream_id);
stream *find_stream(int32_t stream_id);
request *submit(boost::system::error_code &ec, const std::string &method,
const std::string &uri, read_cb cb, http_header h);
virtual tcp::socket &socket() = 0;
virtual void read_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
virtual void write_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
virtual void shutdown_socket() = 0;
void shutdown();
void signal_write();
void enter_callback();
void leave_callback();
void do_read();
void do_write();
protected:
boost::array<uint8_t, 8192> rb_;
boost::array<uint8_t, 65536> wb_;
std::size_t wblen_;
private:
bool should_stop() const;
bool setup_session();
std::map<int32_t, std::unique_ptr<stream>> streams_;
void_cb connect_cb_;
error_cb error_cb_;
nghttp2_session *session_;
const uint8_t *data_pending_;
std::size_t data_pendinglen_;
bool writing_;
bool inside_callback_;
};
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_CLIENT_SESSION_IMPL_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_client_session_tcp_impl.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
session_tcp_impl::session_tcp_impl(boost::asio::io_service &io_service,
tcp::resolver::iterator endpoint_it)
: socket_(io_service) {
boost::asio::async_connect(socket_, endpoint_it,
[this](boost::system::error_code ec,
tcp::resolver::iterator endpoint_it) {
if (!ec) {
connected();
return;
}
not_connected(ec);
});
}
session_tcp_impl::~session_tcp_impl() {}
tcp::socket &session_tcp_impl::socket() { return socket_; }
void session_tcp_impl::read_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)> h) {
socket_.async_read_some(boost::asio::buffer(rb_), h);
}
void session_tcp_impl::write_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)> h) {
boost::asio::async_write(socket_, boost::asio::buffer(wb_, wblen_), h);
}
void session_tcp_impl::shutdown_socket() { socket_.close(); }
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_SESSION_TCP_IMPL_H
#define ASIO_CLIENT_SESSION_TCP_IMPL_H
#include "asio_client_session_impl.h"
#include <boost/asio.hpp>
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
namespace client {
using boost::asio::ip::tcp;
class session_tcp_impl : public session_impl {
public:
session_tcp_impl(boost::asio::io_service &io_service,
tcp::resolver::iterator endpoint_it);
virtual ~session_tcp_impl();
virtual tcp::socket &socket();
virtual void read_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void write_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void shutdown_socket();
private:
tcp::socket socket_;
};
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_CLIENT_SESSION_TCP_IMPL_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_client_session_tls_impl.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
session_tls_impl::session_tls_impl(boost::asio::io_service &io_service,
boost::asio::ssl::context &tls_ctx,
tcp::resolver::iterator endpoint_it)
: socket_(io_service, tls_ctx) {
boost::asio::async_connect(socket(), endpoint_it,
[this](boost::system::error_code ec,
tcp::resolver::iterator endpoint_it) {
if (ec) {
not_connected(ec);
return;
}
socket_.async_handshake(boost::asio::ssl::stream_base::client,
[this](const boost::system::error_code &ec) {
if (ec) {
not_connected(ec);
return;
}
connected();
});
});
}
session_tls_impl::~session_tls_impl() {}
tcp::socket &session_tls_impl::socket() { return socket_.next_layer(); }
void session_tls_impl::read_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)> h) {
socket_.async_read_some(boost::asio::buffer(rb_), h);
}
void session_tls_impl::write_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)> h) {
boost::asio::async_write(socket_, boost::asio::buffer(wb_, wblen_), h);
}
void session_tls_impl::shutdown_socket() {
socket_.async_shutdown([](const boost::system::error_code &ec) {});
}
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_SESSION_TLS_IMPL_H
#define ASIO_CLIENT_SESSION_TLS_IMPL_H
#include "asio_client_session_impl.h"
#include <boost/asio.hpp>
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
namespace client {
using boost::asio::ip::tcp;
using ssl_socket = boost::asio::ssl::stream<tcp::socket>;
class session_tls_impl : public session_impl {
public:
session_tls_impl(boost::asio::io_service &io_service,
boost::asio::ssl::context &tls_ctx,
tcp::resolver::iterator endpoint_it);
virtual ~session_tls_impl();
virtual tcp::socket &socket();
virtual void read_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void write_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void shutdown_socket();
private:
ssl_socket socket_;
};
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_CLIENT_SESSION_TLS_IMPL_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_client_stream.h"
#include "asio_client_request_impl.h"
#include "asio_client_response_impl.h"
#include "asio_client_session_impl.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
stream::stream(session_impl *sess) : sess_(sess), stream_id_(0) {}
void stream::cancel() { sess_->cancel(*this); }
void stream::stream_id(int32_t stream_id) { stream_id_ = stream_id; }
int32_t stream::stream_id() const { return stream_id_; }
request &stream::request() { return request_; }
response &stream::response() { return response_; }
bool stream::expect_final_response() const {
return response_.status_code() / 100 == 1;
}
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_STREAM_H
#define ASIO_CLIENT_STREAM_H
#include "nghttp2_config.h"
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
namespace client {
class request;
class response;
class session_impl;
class stream {
public:
stream(session_impl *sess);
stream(const stream &) = delete;
stream &operator=(const stream &) = delete;
void cancel();
void stream_id(int32_t stream_id);
int32_t stream_id() const;
request &request();
response &response();
bool expect_final_response() const;
private:
nghttp2::asio_http2::client::request request_;
nghttp2::asio_http2::client::response response_;
session_impl *sess_;
uint32_t stream_id_;
};
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_CLIENT_STREAM_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_client_tls_context.h"
#include <openssl/ssl.h>
#include <boost/asio/ssl.hpp>
#include "ssl.h"
#include "util.h"
namespace nghttp2 {
namespace asio_http2 {
namespace client {
namespace {
int client_select_next_proto_cb(SSL *ssl, unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg) {
if (!util::select_h2(const_cast<const unsigned char **>(out), outlen, in,
inlen)) {
return SSL_TLSEXT_ERR_NOACK;
}
return SSL_TLSEXT_ERR_OK;
}
} // namespace
void configure_tls_context(boost::asio::ssl::context &tls_ctx) {
auto ctx = tls_ctx.native_handle();
SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
SSL_CTX_set_cipher_list(ctx, ssl::DEFAULT_CIPHER_LIST);
SSL_CTX_set_next_proto_select_cb(ctx, client_select_next_proto_cb, nullptr);
}
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_CLIENT_TLS_CONTEXT_H
#define ASIO_CLIENT_TLS_CONTEXT_H
#include "nghttp2_config.h"
#include <nghttp2/asio_http2.h>
#endif // ASIO_CLIENT_TLS_CONTEXT_H
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "asio_common.h"
#include <memory>
#include "util.h"
namespace nghttp2 {
namespace asio_http2 {
class nghttp2_category_impl : public boost::system::error_category {
public:
const char *name() const noexcept { return "nghttp2"; }
std::string message(int ev) const { return nghttp2_strerror(ev); }
};
const boost::system::error_category &nghttp2_category() noexcept {
static nghttp2_category_impl cat;
return cat;
}
boost::system::error_code make_error_code(nghttp2_error ev) {
return boost::system::error_code(static_cast<int>(ev), nghttp2_category());
}
read_cb string_reader(std::string data) {
auto strio = std::make_shared<std::pair<std::string, size_t>>(std::move(data),
data.size());
return [strio](uint8_t *buf, size_t len) {
auto n = std::min(len, strio->second);
std::copy_n(strio->first.c_str(), n, buf);
strio->second -= n;
return std::make_pair(n, strio->second == 0);
};
}
http_header::http_header() {}
http_header::http_header(
std::initializer_list<std::pair<std::string, header_value>> ilist) {
for (auto &kv : ilist) {
auto name = kv.first;
util::inp_strlower(name);
items_.emplace(std::move(name), kv.second);
}
}
http_header &http_header::
operator=(std::initializer_list<std::pair<std::string, header_value>> ilist) {
items_.clear();
for (auto &kv : ilist) {
auto name = kv.first;
util::inp_strlower(name);
items_.emplace(std::move(name), kv.second);
}
return *this;
}
const header_map &http_header::items() const { return items_; }
void http_header::add(std::string name, std::string value, bool sensitive) {
util::inp_strlower(name);
items_.emplace(name, header_value(value, sensitive));
}
const header_value *http_header::get(const std::string &name) const {
auto it = items_.find(name);
if (it == std::end(items_)) {
return nullptr;
}
return &(*it).second;
}
std::size_t http_header::size() const { return items_.size(); }
bool http_header::empty() const { return items_.empty(); }
} // namespace asio_http2
} // namespace nghttp2
/*
* nghttp2 - HTTP/2 C Library
*
* Copyright (c) 2015 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ASIO_COMMON_H
#define ASIO_COMMON_H
#include "nghttp2_config.h"
#include <string>
#include <nghttp2/asio_http2.h>
namespace nghttp2 {
namespace asio_http2 {
read_cb string_reader(std::string data);
boost::system::error_code make_error_code(nghttp2_error ev);
} // namespace asio_http2
} // namespace nghttp2
#endif // ASIO_COMMON_H
......@@ -26,6 +26,7 @@
#include <iostream>
#include "asio_common.h"
#include "http2.h"
#include "util.h"
#include "template.h"
......@@ -206,20 +207,7 @@ void response_impl::end(std::string data) {
return;
}
auto strio = std::make_shared<std::pair<std::string, size_t>>(std::move(data),
data.size());
auto read_cb = [strio](uint8_t *buf, size_t len) {
auto nread = std::min(len, strio->second);
memcpy(buf, strio->first.c_str(), nread);
strio->second -= nread;
if (strio->second == 0) {
return std::make_pair(nread, true);
}
return std::make_pair(nread, false);
};
end(std::move(read_cb));
end(string_reader(std::move(data)));
}
void response_impl::end(read_cb cb) {
......
......@@ -92,7 +92,6 @@ void http2_impl::listen(const std::string &address, uint16_t port,
SSL_OP_CIPHER_SERVER_PREFERENCE);
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_cipher_list(ctx, ssl::DEFAULT_CIPHER_LIST);
......
......@@ -30,18 +30,79 @@
#include <string>
#include <vector>
#include <functional>
#include <map>
#include <boost/system/error_code.hpp>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <nghttp2/nghttp2.h>
namespace boost {
namespace system {
template <> struct is_error_code_enum<nghttp2_error> {
BOOST_STATIC_CONSTANT(bool, value = true);
};
} // namespace system
} // namespace boost
namespace nghttp2 {
namespace asio_http2 {
struct header {
header() : sensitive(false) {}
header(std::string name, std::string value, bool sensitive = false)
: name(std::move(name)), value(std::move(value)), sensitive(sensitive) {}
std::string name;
std::string value;
bool sensitive;
};
struct header_value {
header_value(std::string value, bool sensitive = false)
: value(std::move(value)), sensitive(sensitive) {}
std::string value;
bool sensitive;
};
using header_map = std::multimap<std::string, header_value>;
class http_header {
public:
http_header();
http_header(const http_header &other) = default;
http_header(http_header &&other) = default;
http_header(
std::initializer_list<std::pair<std::string, header_value>> ilist);
http_header &operator=(const http_header &other) = default;
http_header &operator=(http_header &&other) = default;
http_header &
operator=(std::initializer_list<std::pair<std::string, header_value>> ilist);
const header_map &items() const;
void add(std::string name, std::string value, bool sensitive);
const header_value *get(const std::string &name) const;
std::size_t size() const;
bool empty() const;
private:
header_map items_;
};
const boost::system::error_category &nghttp2_category() noexcept;
typedef std::function<void(const uint8_t *, std::size_t)> data_cb;
typedef std::function<void(void)> void_cb;
typedef std::function<void(const std::string &err)> error_cb;
typedef std::function<void(uint32_t)> close_cb;
// Callback function to generate response body. The implementation of
// this callback must fill at most |len| bytes data to |buf|. The
......@@ -103,9 +164,9 @@ public:
// string. In this case, check host().
const std::string &authority() const;
// Returns host (e.g., example.org). If host header field is not
// present, this value is copied from authority().
const std::string &host() const;
// Returns path (e.g., /index.html).
......@@ -242,6 +303,92 @@ std::string percent_decode(const std::string &s);
// Returns HTTP date representation of current posix time |t|.
std::string http_date(int64_t t);
namespace client {
class response_impl;
class response {
public:
response();
~response();
void on_data(data_cb cb);
int status_code() const;
int64_t content_length() const;
const http_header &header() const;
response_impl &impl();
private:
std::unique_ptr<response_impl> impl_;
};
class request;
using response_cb = std::function<void(response &)>;
using request_cb = std::function<void(request &)>;
class request_impl;
class request {
public:
request();
~request();
void on_response(response_cb cb);
void on_push(request_cb cb);
void on_close(close_cb cb);
void cancel();
const std::string &method() const;
const std::string &scheme() const;
const std::string &path() const;
const std::string &authority() const;
const std::string &host() const;
const http_header &header() const;
request_impl &impl();
private:
std::unique_ptr<request_impl> impl_;
};
class session_impl;
class session {
public:
session(boost::asio::io_service &io_service,
boost::asio::ip::tcp::resolver::iterator endpoint_it);
session(boost::asio::io_service &io_service,
boost::asio::ssl::context &tls_context,
boost::asio::ip::tcp::resolver::iterator endpoint_it);
~session();
void on_connect(void_cb cb);
void on_error(error_cb cb);
void shutdown();
request *submit(boost::system::error_code &ec, const std::string &method,
const std::string &uri, http_header h = {});
request *submit(boost::system::error_code &ec, const std::string &method,
const std::string &uri, std::string data, http_header h = {});
request *submit(boost::system::error_code &ec, const std::string &method,
const std::string &uri, read_cb cb, http_header h = {});
private:
std::unique_ptr<session_impl> impl_;
};
void configure_tls_context(boost::asio::ssl::context &tls_ctx);
} // namespace client
} // namespace asio_http2
} // namespace nghttp2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment