connection_ptr get_connection(resolver_type & resolver, basic_request<Tag> const & request_, optional<string_type> const & certificate_filename = optional<string_type>(), optional<string_type> const & verify_path = optional<string_type>()) {
     string_type index = (request_.host() + ':') + lexical_cast<string_type>(request_.port());
     connection_ptr connection_;
     typename host_connection_map::iterator it =
         host_connections.find(index);
     if (it == host_connections.end()) {
         connection_.reset(new connection_impl(
             resolver
             , follow_redirect_
             , request_.host()
             , lexical_cast<string_type>(request_.port())
             , boost::bind(
                 &pooled_connection_policy<Tag,version_major,version_minor>::resolve,
                 this,
                 _1, _2, _3
                 )
             , boost::bind(
                 &pooled_connection_policy<Tag,version_major,version_minor>::get_connection,
                 this,
                 _1, _2, _3, _4
                 )
             , boost::iequals(request_.protocol(), string_type("https"))
             , certificate_filename
             , verify_path
             )
         );
         host_connections.insert(std::make_pair(index, connection_));
         return connection_;
     }
     return it->second;
 }
            basic_response<Tag> send_request(string_type const & method, basic_request<Tag> request_, bool get_body) {
                basic_response<Tag> response_;
                do {
                    pimpl->init_socket(request_.host(), lexical_cast<string_type>(request_.port()));
                    pimpl->send_request_impl(method, request_);

                    response_ = basic_response<Tag>();
                    response_ << network::source(request_.host());

                    boost::asio::streambuf response_buffer;
                    pimpl->read_status(response_, response_buffer);
                    pimpl->read_headers(response_, response_buffer);
                    if (get_body) pimpl->read_body(response_, response_buffer);

                    if (follow_redirect_) {
                        boost::uint16_t status = response_.status();
                        if (status >= 300 && status <= 307) {
                            typename headers_range<http::basic_response<Tag> >::type location_range = headers(response_)["Location"];
                            typename range_iterator<typename headers_range<http::basic_request<Tag> >::type>::type location_header = boost::begin(location_range);
                            if (location_header != boost::end(location_range)) {
                                request_.uri(location_header->second);
                            } else throw std::runtime_error("Location header not defined in redirect response.");
                        } else break;
                    } else break;
                } while(true);
                return response_;
            }
 connection_ptr get_connection(resolver_type & resolver, basic_request<Tag> const & request_) {
     connection_ptr connection_(
         new connection_impl(
             resolver
             , follow_redirect_
             , request_.host()
             , lexical_cast<string_type>(request_.port())
             , boost::bind(
                 &simple_connection_policy<Tag,version_major,version_minor>::resolve,
                 this,
                 _1, _2, _3
                 )
             , boost::iequals(request_.protocol(), string_type("https"))
             )
         );
     return connection_;
 }
    basic_response<Tag> send_request(string_type /*unused*/ const& method,
                                     basic_request<Tag> request_, bool get_body,
                                     body_callback_function_type callback,
                                     body_generator_function_type generator) {
      // TODO(dberris): review parameter necessity.
      (void)callback;

      basic_response<Tag> response_;
      do {
        pimpl->init_socket(request_.host(), std::to_string(request_.port()));
        pimpl->send_request_impl(method, request_, generator);

        response_ = basic_response<Tag>();
        response_ << network::source(request_.host());

        ::asio::streambuf response_buffer;
        pimpl->read_status(response_, response_buffer);
        pimpl->read_headers(response_, response_buffer);
        if (get_body) pimpl->read_body(response_, response_buffer);

        if (follow_redirect_) {
          std::uint16_t status = response_.status();
          if (status >= 300 && status <= 307) {
            typename headers_range<http::basic_response<Tag> >::type
                location_range = headers(response_)["Location"];
            typename range_iterator<
                typename headers_range<http::basic_response<Tag> >::type>::type
                location_header = std::begin(location_range);
            if (location_header != std::end(location_range)) {
              request_.uri(location_header->second);
            } else
              throw std::runtime_error(
                  "Location header not defined in redirect response.");
          } else {
            break;
          }
        } else {
          break;
        }
      } while (true);
      return response_;
    }
 connection_ptr get_connection(
     resolver_type& resolver, basic_request<Tag> const& request_,
     bool always_verify_peer,
     optional<string_type> /*unused*/ const& certificate_filename =
         optional<string_type>(),
     optional<string_type> const& verify_path = optional<string_type>(),
     optional<string_type> const& certificate_file = optional<string_type>(),
     optional<string_type> const& private_key_file = optional<string_type>(),
     optional<string_type> const& ciphers = optional<string_type>(),
     long ssl_options = 0) {
   namespace ph = std::placeholders;
   connection_ptr connection_(new connection_impl(
       resolver, follow_redirect_, always_verify_peer, request_.host(),
       std::to_string(request_.port()),
       [this](resolver_type& resolver, string_type const& host,
              std::uint16_t port, resolver_completion_function once_resolved) {
         this->resolve(resolver, host, port, once_resolved);
       },
       boost::iequals(request_.protocol(), string_type("https")), timeout_,
       certificate_filename, verify_path, certificate_file, private_key_file,
       ciphers, ssl_options));
   return connection_;
 }
Example #6
0
 response_type const request_skeleton(
     basic_request<Tag> const & request,
     string_type const & method,
     bool get_body,
     body_callback_function_type callback,
     body_generator_function_type generator
 ) {
     auto && app = webmock::api::app();
     
     webmock::core::request webmock_request;
     webmock_request.method = method;
     webmock_request.url.set_encoded(request.uri().string());
     for (auto && header: http::headers(request)) {
         webmock_request.headers.insert(header);
     }
     webmock_request.body = http::body(request);
     
     if (auto && webmock_response = app.registry.access(webmock_request)) {
         basic_response<Tag> response;
         response
             << http::status(webmock_response->status)
             << network::body(webmock_response->body);
         
         for (auto && header: webmock_response->headers) {
             response << network::header(header.first, header.second);
         }
         return response;
     }
     
     if (app.config.stub_not_found.is_connecting_to_net) {
         return this->connect_net(
             request,
             method,
             get_body,
             callback,
             generator
         );
     }
     
     if (app.config.stub_not_found.callback) {
         app.config.stub_not_found.callback(webmock_request);
     }
     
     throw (std::ostringstream()
         << "A stub satisfying the request not found!\n"
         << webmock_request
     ).str();
 }
            basic_response<Tag> send_request_impl(string_type const & method, basic_request<Tag> request_, bool get_body) {
                boost::uint8_t count = 0;
                bool retry = false;
                do {
                    if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT)
                        boost::throw_exception(std::runtime_error("Redirection exceeds maximum redirect count."));

                    basic_response<Tag> response_;
                    // check if the socket is open first
                    if (!pimpl->is_open()) {
                        pimpl->init_socket(request_.host(), lexical_cast<string_type>(request_.port()));
                    }
                    response_ = basic_response<Tag>();
                    response_ << ::boost::network::source(request_.host());

                    pimpl->send_request_impl(method, request_);
                    boost::asio::streambuf response_buffer;

                    try {
                        pimpl->read_status(response_, response_buffer);
                    } catch (boost::system::system_error & e) {
                        if (!retry && e.code() == boost::asio::error::eof) {
                            retry = true;
                            pimpl->init_socket(request_.host(), lexical_cast<string_type>(request_.port()));
                            continue;
                        }
                        throw; // it's a retry, and there's something wrong.
                    }

                    pimpl->read_headers(response_, response_buffer);

                    if (
                        get_body && response_.status() != 304
                        && (response_.status() != 204)
                        && !(response_.status() >= 100 && response_.status() <= 199)
                       ) {
                        pimpl->read_body(response_, response_buffer);
                    }

                    typename headers_range<basic_response<Tag> >::type connection_range = headers(response_)["Connection"];
                    if (version_major == 1 && version_minor == 1 && !empty(connection_range) && boost::begin(connection_range)->second == string_type("close")) {
                        pimpl->close_socket();
                    } else if (version_major == 1 && version_minor == 0) {
                        pimpl->close_socket();
                    }

                    if (connection_follow_redirect_) {
                        boost::uint16_t status = response_.status();
                        if (status >= 300 && status <= 307) {
                            typename headers_range<basic_response<Tag> >::type location_range = headers(response_)["Location"];
                            typename range_iterator<typename headers_range<basic_request<Tag> >::type>::type location_header = boost::begin(location_range);
                            if (location_header != boost::end(location_range)) {
                                request_.uri(location_header->second);
                                connection_ptr connection_;
                                connection_ = get_connection_(resolver_, request_, certificate_filename_, verify_path_);
                                ++count;
                                continue;
                            } else boost::throw_exception(std::runtime_error("Location header not defined in redirect response."));
                        }
                    }
                    return response_;
                } while(true);
            }
Example #8
0
 inline void swap(basic_request<Tag> & lhs, basic_request<Tag> & rhs) {
     lhs.swap(rhs);
 }
Example #9
0
 response_type const connect_net(
     basic_request<Tag> const & request,
     string_type const & method,
     bool get_body,
     body_callback_function_type callback,
     body_generator_function_type generator
 ) {
     using original_tag = typename webmock::adapter::cpp_netlib::tags::rmap<Tag>::type;
     using original_string_type = typename string<original_tag>::type;
     using original_client_type = basic_client<
         original_tag,
         version_major,
         version_minor
     >;
     
     typename original_client_type::request original_request(request.uri());
     for (auto && header: http::headers(request)) {
         original_request << network::header(header.first, header.second);
     }
     std::string body = http::body(request);
     original_request << network::body(body);
     
     client_options<original_tag> original_option;
     original_option
         .cache_resolved(this->cache_resolved)
         .follow_redirects(this->follow_redirect)
         .io_service(this->service)
         .timeout(this->timeout)
     ;
     if (this->certificate_filename) {
         original_option.openssl_certificate(
             lexical_cast<original_string_type>(*this->certificate_filename)
         );
     }
     if (this->verify_path) {
         original_option.openssl_verify_path(
             lexical_cast<original_string_type>(*this->verify_path)
         );
     }
     if (this->certificate_file) {
         original_option.openssl_certificate_file(
             lexical_cast<original_string_type>(*this->certificate_file)
         );
     }
     if (this->private_key_file) {
         original_option.openssl_private_key_file(
             lexical_cast<original_string_type>(*this->private_key_file)
         );
     }
     
     original_client_type  original_client(original_option);
     typename original_client_type::response original_response;
     
     if (method == "HEAD") {
         original_response = original_client.head(
             original_request
         );
     }
     else if (method == "GET") {
         original_response = original_client.get(
             original_request,
             callback
         );
     }
     else if (method == "POST") {
         original_response = original_client.post(
             original_request,
             body,
             callback,
             generator
         );
     }
     else if (method == "PUT") {
         original_response = original_client.put(
             original_request,
             body,
             callback,
             generator
         );
     }
     else if (method == "DELETE") {
         original_response = original_client.delete_(
             original_request,
             callback
         );
     }
     
     basic_response<Tag> response;
     response
         << http::status(static_cast<int>(http::status(original_response)))
         << network::body(static_cast<std::string>(http::body(original_response)));
     
     for (auto && header: http::headers(original_response)) {
         response << network::header(header.first, header.second);
     }
     return response;
 }