blob: 19f27cde6a03838f5556dc6e52c44c125ffbe73c [file] [log] [blame]
/*
* Copyright 2015 Twitter, Inc.
*
* Licensed 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.
*/
///////////////////////////////////////////////////////////////////////////////
//
// This file defines the HTTPClient class.
// HTTPClient is actually a misnomer, this is actually an httpclientpool
// managing multiple simultaneous requests to multiple hosts. Takes care of
// very rudimentary hostload stuff by establishing just one connection
// to a particular host at a time.
// Users just use the client as follows
// HTTPClient* client = new HTTPClient(...);
// OutgoingHTTPRequest* request = new OutgoingHTTPRequest(...);
// .....
// Fill in the request
// ...
// CallBack1<IncomingHTTPResponse*>* cb = CreateCallback(...)
// client->SendRequest(request, cb)
//
// The Callback cb is called once the request completes.
// void cb(IncomingHTTPResponse* response)
// {
// if (response->GetResponseCode() == 200) {
// sp_string body = response->GetResponseBody();
// }
// Error processing
// }
//
// HTTPClient supports Asynchronous dns resolution as well.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef HTTPCLIENT_H_
#define HTTPCLIENT_H_
#include <functional>
#include <unordered_map>
#include <utility>
#include "network/asyncdns.h"
#include "network/httputils.h"
#include "network/event_loop.h"
#include "basics/basics.h"
// Forward Declarations
struct evhttp_connection;
class IncomingHTTPResponse;
class IncomingHTTPResponse;
class HTTPClient {
public:
// Constructor
HTTPClient(EventLoop* eventLoop, AsyncDNS* _dns);
// Destructor.
virtual ~HTTPClient();
//! The main interface of the client
//! _request now belongs to the HTTPClient. Callers
// should not touch it after this call.
// After the request completes, the callback cb is
// called with the response structure. The IncomingHTTPResponse
// strucuture now belongs to the callee and should be deleted
// A return value of LX_OK means the request was queued for sending.
// It doesnt mean that the request was sent. When the request completes
// and the response arrives, the callback _cb will be called.
sp_int32 SendRequest(OutgoingHTTPRequest* _request, VCallback<IncomingHTTPResponse*> _cb);
// get the underlying select server
EventLoop* getEventLoop() { return eventLoop_; }
private:
//! A structure used for internal purposes
struct Combo {
Combo(OutgoingHTTPRequest* _request, HTTPClient* _client) {
request_ = _request;
client_ = _client;
}
~Combo() {}
OutgoingHTTPRequest* request_;
HTTPClient* client_;
};
//! A Callback called when the http request gets done
void HandleRequestDone(OutgoingHTTPRequest* _req, IncomingHTTPResponse* _response);
//! A Callback called when a http connection closes
void HandleConnectionClose(struct evhttp_connection* _connection);
//! Utility function to create the connection
struct evhttp_connection* CreateConnection(const sp_string& _host, sp_int32 _port);
//! Utility function to fill the request
struct evhttp_request* CreateUnderlyingRequest(OutgoingHTTPRequest* _req, Combo* _combo);
// Map from the host/port pair to the connections
std::unordered_map<std::pair<sp_string, sp_int32>, struct evhttp_connection*> connections_;
// Map from the connections to host/port pair
std::unordered_map<void*, std::pair<sp_string, sp_int32>> rconnections_;
// Map from the OutgoingHTTPRequest to the callback
std::unordered_map<void*, VCallback<IncomingHTTPResponse*>> inflight_urls_;
//! the EventLoop and the aysnc dns pointers
EventLoop* eventLoop_;
AsyncDNS* dns_;
//! friend functions
friend void httpdonecb(struct evhttp_request*, void*);
friend void httpconnectionclose(struct evhttp_connection*, void*);
};
#endif // HTTPCLIENT_H_