Skip to content

Commit

Permalink
Merge "Always set curl_forbid_reuse flag." into R2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed May 28, 2015
2 parents e82b366 + 8c6003a commit af90fc0
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 71 deletions.
45 changes: 25 additions & 20 deletions src/http/client/http_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,7 @@ HttpConnection::HttpConnection(boost::asio::ip::tcp::endpoint ep, size_t id,
}

HttpConnection::~HttpConnection() {
if (session_) {
{
tbb::mutex::scoped_lock lock(session_->mutex());
session_->SetConnection(NULL);
}
client_->DeleteSession(session_);
set_session(NULL);
}
delete_session();
}

std::string HttpConnection::make_url(std::string &path) {
Expand All @@ -98,6 +91,18 @@ HttpClientSession *HttpConnection::CreateSession() {
return session;
}

void HttpConnection::delete_session() {
HttpClientSession *session = session_;
if (session_) {
{
tbb::mutex::scoped_lock lock(session_->mutex());
session_->SetConnection(NULL);
session_ = NULL;
}
client_->DeleteSession(session);
}
}

void HttpConnection::set_session(HttpClientSession *session) {
session_ = session;
if (session && event_cb_ && !event_cb_.empty())
Expand All @@ -109,22 +114,22 @@ int HttpConnection::HttpGet(const std::string &path, HttpCb cb) {
return HttpGet(path, false, true, false, hdr_options, cb);
}

int HttpConnection::HttpGet(const std::string &path, bool header, bool timeout,
int HttpConnection::HttpGet(const std::string &path, bool header, bool short_timeout,
bool reuse, std::vector<std::string> &hdr_options,
HttpCb cb) {
const std::string body;
client()->ProcessEvent(boost::bind(&HttpConnection::HttpProcessInternal,
this, body, path, header, timeout, reuse,
this, body, path, header, short_timeout, reuse,
hdr_options, cb, HTTP_GET));
return 0;
}

int HttpConnection::HttpHead(const std::string &path, bool header, bool timeout,
int HttpConnection::HttpHead(const std::string &path, bool header, bool short_timeout,
bool reuse, std::vector<std::string> &hdr_options,
HttpCb cb) {
const std::string body;
client()->ProcessEvent(boost::bind(&HttpConnection::HttpProcessInternal,
this, body, path, header, timeout, reuse,
this, body, path, header, short_timeout, reuse,
hdr_options, cb, HTTP_HEAD));
return 0;
}
Expand All @@ -136,11 +141,11 @@ int HttpConnection::HttpPut(const std::string &put_string,
}

int HttpConnection::HttpPut(const std::string &put_string,
const std::string &path, bool header, bool timeout,
const std::string &path, bool header, bool short_timeout,
bool reuse, std::vector<std::string> &hdr_options,
HttpCb cb) {
client()->ProcessEvent(boost::bind(&HttpConnection::HttpProcessInternal,
this, put_string, path, header, timeout,
this, put_string, path, header, short_timeout,
reuse, hdr_options, cb, HTTP_PUT));
return 0;
}
Expand All @@ -152,11 +157,11 @@ int HttpConnection::HttpPost(const std::string &post_string,
}

int HttpConnection::HttpPost(const std::string &post_string,
const std::string &path, bool header, bool timeout,
const std::string &path, bool header, bool short_timeout,
bool reuse, std::vector<std::string> &hdr_options,
HttpCb cb) {
client()->ProcessEvent(boost::bind(&HttpConnection::HttpProcessInternal,
this, post_string, path, header, timeout, reuse,
this, post_string, path, header, short_timeout, reuse,
hdr_options, cb, HTTP_POST));
return 0;
}
Expand All @@ -166,12 +171,12 @@ int HttpConnection::HttpDelete(const std::string &path, HttpCb cb) {
return HttpDelete(path, false, true, false, hdr_options, cb);
}

int HttpConnection::HttpDelete(const std::string &path, bool header, bool timeout,
int HttpConnection::HttpDelete(const std::string &path, bool header, bool short_timeout,
bool reuse, std::vector<std::string> &hdr_options,
HttpCb cb) {
const std::string body;
client()->ProcessEvent(boost::bind(&HttpConnection::HttpProcessInternal,
this, body, path, header, timeout, reuse,
this, body, path, header, short_timeout, reuse,
hdr_options, cb, HTTP_DELETE));
return 0;
}
Expand All @@ -181,7 +186,7 @@ void HttpConnection::ClearCallback() {
}

void HttpConnection::HttpProcessInternal(const std::string body, std::string path,
bool header, bool timeout, bool reuse,
bool header, bool short_timeout, bool reuse,
std::vector<std::string> hdr_options,
HttpCb cb, http_method method) {
if (client()->AddConnection(this) == false) {
Expand All @@ -191,7 +196,7 @@ void HttpConnection::HttpProcessInternal(const std::string body, std::string pat
}

struct _GlobalInfo *gi = client()->GlobalInfo();
struct _ConnInfo *curl_handle = new_conn(this, gi, header, timeout, reuse);
struct _ConnInfo *curl_handle = new_conn(this, gi, header, short_timeout, reuse);
if (!curl_handle) {
LOG(DEBUG, "Http : unable to create new connection");
return;
Expand Down
13 changes: 7 additions & 6 deletions src/http/client/http_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,19 @@ class HttpConnection {

int HttpPut(const std::string &put_string, const std::string &path, HttpCb);
int HttpPut(const std::string &put_string, const std::string &path,
bool header, bool timeout, bool reuse,
bool header, bool short_timeout, bool reuse,
std::vector<std::string> &hdr_options, HttpCb cb);
int HttpPost(const std::string &post_string, const std::string &path, HttpCb);
int HttpPost(const std::string &post_string, const std::string &path,
bool header, bool timeout, bool reuse,
bool header, bool short_timeout, bool reuse,
std::vector<std::string> &hdr_options, HttpCb cb);
int HttpGet(const std::string &path, HttpCb);
int HttpGet(const std::string &path, bool header, bool timeout, bool reuse,
int HttpGet(const std::string &path, bool header, bool short_timeout, bool reuse,
std::vector<std::string> &hdr_options, HttpCb cb);
int HttpHead(const std::string &path, bool header, bool timeout, bool reuse,
int HttpHead(const std::string &path, bool header, bool short_timeout, bool reuse,
std::vector<std::string> &hdr_options, HttpCb cb);
int HttpDelete(const std::string &path, HttpCb);
int HttpDelete(const std::string &path, bool header, bool timeout,
int HttpDelete(const std::string &path, bool header, bool short_timeout,
bool reuse, std::vector<std::string> &hdr_options,
HttpCb cb);
void ClearCallback();
Expand All @@ -97,6 +97,7 @@ class HttpConnection {
void set_curl_handle(struct _ConnInfo *handle) { curl_handle_ = handle; }
HttpClientSession *CreateSession();
void set_session(HttpClientSession *session);
void delete_session();
void AssignData(const char *ptr, size_t size);
void UpdateOffset(size_t bytes);
size_t GetOffset();
Expand All @@ -107,7 +108,7 @@ class HttpConnection {
std::string make_url(std::string &path);

void HttpProcessInternal(const std::string body, std::string path,
bool header, bool timeout, bool reuse,
bool header, bool short_timeout, bool reuse,
std::vector<std::string> hdr_options,
HttpCb, http_method);

Expand Down
84 changes: 40 additions & 44 deletions src/http/client/http_curl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ using tbb::mutex;

const CurlErrorCategory curl_error_category;

/* boost::asio related objects
* using global variables for simplicity
*/
std::map<curl_socket_t, HttpClientSession *> socket_map;


/* Update the event timer after curl_multi library calls */
static int multi_timer_cb(CURLM *multi, long timeout_ms, HttpClient *client)
{
Expand Down Expand Up @@ -98,12 +92,12 @@ static void check_multi_info(GlobalInfo *g)
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);

boost::system::error_code error(res, curl_error_category);
std::string empty_str("");
if (conn->connection->HttpClientCb() != NULL)
conn->connection->HttpClientCb()(empty_str, error);

if (conn) {
boost::system::error_code error(res, curl_error_category);
std::string empty_str("");
if (conn->connection->HttpClientCb() != NULL)
conn->connection->HttpClientCb()(empty_str, error);

conn->connection->set_curl_handle(NULL);
del_curl_handle(conn, g);
}
Expand Down Expand Up @@ -165,29 +159,28 @@ bool timer_cb(GlobalInfo *g)
}

/* Clean up any data */
static void remsock(int *f, GlobalInfo *g)
static void remsock(SockInfo *sock_info, GlobalInfo *g)
{
if ( f )
if ( sock_info )
{
free(f);
free(sock_info);
}
}

static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo *g)
static bool setsock(SockInfo *sock_info, curl_socket_t s, CURL*e, int act, GlobalInfo *g)
{
std::map<curl_socket_t, HttpClientSession *>::iterator it = socket_map.find(s);

if ( it == socket_map.end() )
if (!sock_info || !sock_info->conn_info || !sock_info->conn_info->connection)
{
return;
return false;
}

HttpClientSession *session = it->second;
if (session->IsClosed()) return;
HttpClientSession *session = sock_info->conn_info->connection->session();
if (!session || session->IsClosed())
return false;

boost::asio::ip::tcp::socket * tcp_socket = session->socket();

*fdp = act;
sock_info->action = act;

if ( act == CURL_POLL_IN )
{
Expand All @@ -210,36 +203,43 @@ static void setsock(int *fdp, curl_socket_t s, CURL*e, int act, GlobalInfo *g)
boost::bind(&event_cb, g, TcpSessionPtr(session),
act, _1, _2));
}
return true;
}


static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
{
int *fdp = (int *)calloc(sizeof(int), 1); /* fdp is used to store current action */
// store socket details in SockInfo
SockInfo *sock_info = (SockInfo *)calloc(sizeof(SockInfo), 1);
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &sock_info->conn_info);

setsock(fdp, s, easy, action, g);
curl_multi_assign(g->multi, s, fdp);
if (!setsock(sock_info, s, easy, action, g)) {
free(sock_info);
return;
}

curl_multi_assign(g->multi, s, sock_info);
}

/* CURLMOPT_SOCKETFUNCTION */
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
{
GlobalInfo *g = (GlobalInfo*) cbp;
int *actionp = (int*) sockp;
SockInfo *sock_info = (SockInfo *)sockp;

if ( what == CURL_POLL_REMOVE )
{
remsock(actionp, g);
remsock(sock_info, g);
}
else
{
if ( !actionp )
if ( !sockp )
{
addsock(s, e, what, g);
}
else
{
setsock(actionp, s, e, what, g);
setsock(sock_info, s, e, what, g);
}
}
return 0;
Expand Down Expand Up @@ -307,24 +307,18 @@ static curl_socket_t opensocket(void *data,
HttpClientSession *session = conn->CreateSession();
if (session) {
sockfd = session->socket()->native_handle();
socket_map.insert(std::pair<curl_socket_t, HttpClientSession *>(
sockfd, static_cast<HttpClientSession *>(session)));
conn->set_session(session);
}
}


return sockfd;
}

/* CURLOPT_CLOSESOCKETFUNCTION */
static int closesocket(void *clientp, curl_socket_t item)
{
std::map<curl_socket_t, HttpClientSession *>::iterator it = socket_map.find(item);
if ( it != socket_map.end() ) {
socket_map.erase(it);
}

HttpConnection *conn = static_cast<HttpConnection *>(clientp);
conn->delete_session();
return 0;
}

Expand Down Expand Up @@ -355,7 +349,6 @@ void del_conn(HttpConnection *connection, GlobalInfo *g) {

if (connection->session()) {
tbb::mutex::scoped_lock lock(connection->session()->mutex());
closesocket(NULL, connection->session()->socket()->native_handle());
connection->session()->SetConnection(NULL);
}

Expand All @@ -368,6 +361,7 @@ void del_conn(HttpConnection *connection, GlobalInfo *g) {

void del_curl_handle(ConnInfo *curl_handle, GlobalInfo *g) {
if (curl_handle) {
curl_easy_setopt(curl_handle->easy, CURLOPT_PRIVATE, NULL);
curl_multi_remove_handle(g->multi, curl_handle->easy);
curl_slist_free_all(curl_handle->headers);
free(curl_handle->post);
Expand All @@ -379,7 +373,7 @@ void del_curl_handle(ConnInfo *curl_handle, GlobalInfo *g) {

/* Create a new easy handle, and add it to the global curl_multi */
ConnInfo *new_conn(HttpConnection *connection, GlobalInfo *g,
bool header, bool timeout, bool reuse)
bool header, bool short_timeout, bool reuse)
{
ConnInfo *conn = (ConnInfo *)calloc(1, sizeof(ConnInfo));
memset(conn, 0, sizeof(ConnInfo));
Expand All @@ -402,14 +396,16 @@ ConnInfo *new_conn(HttpConnection *connection, GlobalInfo *g,
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 4L); // in secs
if (timeout) {
if (short_timeout) {
/* set the timeout limits to abort the connection */
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
} else {
/* set longer timeout limits */
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L);
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
}
if (!reuse) {
curl_easy_setopt(conn->easy, CURLOPT_FORBID_REUSE, 1L);
}
curl_easy_setopt(conn->easy, CURLOPT_FORBID_REUSE, 1L);

/* to include the header in the body */
if (header)
Expand All @@ -421,6 +417,7 @@ ConnInfo *new_conn(HttpConnection *connection, GlobalInfo *g,

/* call this function to close a socket */
curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETFUNCTION, closesocket);
curl_easy_setopt(conn->easy, CURLOPT_CLOSESOCKETDATA, connection);

return conn;
}
Expand Down Expand Up @@ -480,7 +477,6 @@ int http_delete(ConnInfo *conn, GlobalInfo *g) {

int curl_init(HttpClient *client)
{

struct _GlobalInfo *g = client->GlobalInfo();

memset(g, 0, sizeof(GlobalInfo));
Expand Down
8 changes: 7 additions & 1 deletion src/http/client/http_curl.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ typedef struct _ConnInfo
HttpConnection *connection;
} ConnInfo;

typedef struct _SockInfo
{
int action;
ConnInfo *conn_info;
} SockInfo;

class CurlErrorCategory : public boost::system::error_category
{
public:
Expand All @@ -42,7 +48,7 @@ int http_get(ConnInfo *conn, GlobalInfo *g);
void set_url(ConnInfo *conn, const char *url);
int curl_init(HttpClient *);
ConnInfo *new_conn(HttpConnection *connection, GlobalInfo *g,
bool header, bool timeout, bool reuse);
bool header, bool short_timeout, bool reuse);
void del_conn(HttpConnection *connection, GlobalInfo *g);
void del_curl_handle(ConnInfo *curl_handle, GlobalInfo *g);
void set_header_options(ConnInfo *conn, const char *options);
Expand Down

0 comments on commit af90fc0

Please sign in to comment.