blob: 48b7d6c379b85b4e758dd9151fa383460508664b [file] [log] [blame]
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef HTTP_MOCK_SERVER_HPP
#define HTTP_MOCK_SERVER_HPP
#define HTTP_MOCK_HOSTNAME "cpp-driver.hostname."
#define HTTP_MOCK_SERVER_IP "127.254.254.254"
#define HTTP_MOCK_SERVER_PORT 30443
#include "http_parser.h"
#include "mockssandra.hpp"
#include "string.hpp"
namespace mockssandra { namespace http {
/**
* Mockssandra HTTP server.
*
* If no response body is set then the default response will the be original request; e.g. echo HTTP
* server.
*/
class Server {
public:
Server()
: path_("/")
, content_type_("text/plain")
, response_status_code_(200)
, enable_valid_response_(true)
, close_connnection_after_request_(true)
, event_loop_group_(1, "HTTP Server")
, factory_(this)
, server_connection_(new internal::ServerConnection(
Address(HTTP_MOCK_SERVER_IP, HTTP_MOCK_SERVER_PORT), factory_)) {}
const String& path() const { return path_; }
const String& content_type() const { return content_type_; }
const String& response_body() const { return response_body_; }
int response_status_code() const { return response_status_code_; }
bool enable_valid_response() { return enable_valid_response_; }
bool close_connnection_after_request() { return close_connnection_after_request_; }
void set_path(const String& path) { path_ = path; }
void set_content_type(const String& content_type) { content_type_ = content_type; }
void set_response_body(const String& response_body) { response_body_ = response_body; }
void set_response_status_code(int status_code) { response_status_code_ = status_code; }
void enable_valid_response(bool enable) { enable_valid_response_ = enable; }
void set_close_connnection_after_request(bool enable) {
close_connnection_after_request_ = enable;
}
bool use_ssl(const String& key, const String& cert, const String& ca_cert = "",
bool require_client_cert = false);
void listen();
void close();
private:
class ClientConnection : public internal::ClientConnection {
public:
ClientConnection(internal::ServerConnection* server_connection, Server* server);
virtual void on_read(const char* data, size_t len);
private:
static int on_url(http_parser* parser, const char* buf, size_t len);
void handle_url(const char* buf, size_t len);
private:
String path_;
String content_type_;
String response_body_;
int response_status_code_;
bool enable_valid_response_;
bool close_connnection_after_request_;
String request_;
http_parser parser_;
http_parser_settings parser_settings_;
};
class ClientConnectionFactory : public internal::ClientConnectionFactory {
public:
ClientConnectionFactory(Server* server)
: server_(server) {}
virtual internal::ClientConnection*
create(internal::ServerConnection* server_connection) const {
return new ClientConnection(server_connection, server_);
}
private:
Server* const server_;
};
private:
String path_;
String content_type_;
String response_body_;
int response_status_code_;
bool enable_valid_response_;
bool close_connnection_after_request_;
SimpleEventLoopGroup event_loop_group_;
ClientConnectionFactory factory_;
internal::ServerConnection::Ptr server_connection_;
};
}} // namespace mockssandra::http
#endif