Newer
Older
Monty Brandenberg
committed
/**
* @file _httpoprequest.h
* @brief Internal declarations for the HttpOpRequest subclass
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2012-2013, Linden Research, Inc.
Monty Brandenberg
committed
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef _LLCORE_HTTP_OPREQUEST_H_
#define _LLCORE_HTTP_OPREQUEST_H_
Monty Brandenberg
committed
#include "linden_common.h" // Modifies curl/curl.h interfaces
#include <string>
Monty Brandenberg
committed
#include <curl/curl.h>
#include <openssl/x509_vfy.h>
#include <openssl/ssl.h>
#include "httpcommon.h"
#include "httprequest.h"
Monty Brandenberg
committed
#include "_httpoperation.h"
#include "_refcounted.h"
Rider Linden
committed
#include "httpheaders.h"
#include "httpoptions.h"
Monty Brandenberg
committed
namespace LLCore
{
class BufferArray;
/// HttpOpRequest requests a supported HTTP method invocation with
/// option and header overrides.
///
/// Essentially an RPC to get an HTTP GET, POST or PUT executed
/// asynchronously with options to override behaviors and HTTP
/// headers.
///
/// Constructor creates a raw object incapable of useful work.
/// A subsequent call to one of the setupXXX() methods provides
/// the information needed to make a working request which can
/// then be enqueued to a request queue.
///
Monty Brandenberg
committed
class HttpOpRequest : public HttpOperation
{
public:
typedef boost::shared_ptr<HttpOpRequest> ptr_t;
virtual ~HttpOpRequest(); // Use release()
Monty Brandenberg
committed
private:
HttpOpRequest(const HttpOpRequest &); // Not defined
void operator=(const HttpOpRequest &); // Not defined
public:
enum EMethod
{
HOR_GET,
HOR_POST,
HOR_PUT,
HOR_DELETE,
HOR_PATCH,
Rider Linden
committed
HOR_COPY,
HOR_MOVE
Monty Brandenberg
committed
};
Rider Linden
committed
static std::string methodToString(const EMethod &);
Monty Brandenberg
committed
virtual void stageFromRequest(HttpService *);
virtual void stageFromReady(HttpService *);
virtual void stageFromActive(HttpService *);
virtual void visitNotifier(HttpRequest * request);
public:
/// Setup Methods
///
/// Basically an RPC setup for each type of HTTP method
/// invocation with one per method type. These are
/// generally invoked right after construction.
///
/// Threading: called by application thread
///
Monty Brandenberg
committed
HttpStatus setupGet(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
Monty Brandenberg
committed
HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
Monty Brandenberg
committed
const std::string & url,
size_t offset,
size_t len,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
Monty Brandenberg
committed
HttpStatus setupPost(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
BufferArray * body,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
HttpStatus setupPut(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
BufferArray * body,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
HttpStatus setupDelete(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
HttpStatus setupPatch(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
BufferArray * body,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
HttpStatus setupCopy(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
Rider Linden
committed
HttpStatus setupMove(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
// Internal method used to setup the libcurl options for a request.
// Does all the libcurl handle setup in one place.
//
// Threading: called by worker thread
//
HttpStatus prepareRequest(HttpService * service);
Monty Brandenberg
committed
virtual HttpStatus cancel();
protected:
// Common setup for all the request methods.
//
// Threading: called by application thread
//
Monty Brandenberg
committed
void setupCommon(HttpRequest::policy_t policy_id,
HttpRequest::priority_t priority,
const std::string & url,
BufferArray * body,
const HttpOptions::ptr_t & options,
const HttpHeaders::ptr_t & headers);
// libcurl operational callbacks
//
// Threading: called by worker thread
//
Monty Brandenberg
committed
static size_t writeCallback(void * data, size_t size, size_t nmemb, void * userdata);
static size_t readCallback(void * data, size_t size, size_t nmemb, void * userdata);
static int seekCallback(void *data, curl_off_t offset, int origin);
Monty Brandenberg
committed
static size_t headerCallback(void * data, size_t size, size_t nmemb, void * userdata);
static CURLcode curlSslCtxCallback(CURL *curl, void *ssl_ctx, void *userptr);
static int sslCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
Monty Brandenberg
committed
static int debugCallback(CURL *, curl_infotype info, char * buffer, size_t len, void * userdata);
Monty Brandenberg
committed
protected:
unsigned int mProcFlags;
static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U;
static const unsigned int PF_SAVE_HEADERS = 0x00000002U;
static const unsigned int PF_USE_RETRY_AFTER = 0x00000004U;
Monty Brandenberg
committed
HttpRequest::policyCallback_t mCallbackSSLVerify;
Monty Brandenberg
committed
public:
// Request data
EMethod mReqMethod;
std::string mReqURL;
BufferArray * mReqBody;
off_t mReqOffset;
size_t mReqLength;
Rider Linden
committed
HttpHeaders::ptr_t mReqHeaders;
HttpOptions::ptr_t mReqOptions;
Monty Brandenberg
committed
// Transport data
bool mCurlActive;
CURL * mCurlHandle;
HttpService * mCurlService;
curl_slist * mCurlHeaders;
size_t mCurlBodyPos;
char * mCurlTemp; // Scratch buffer for header processing
size_t mCurlTempLen;
Monty Brandenberg
committed
// Result data
HttpStatus mStatus;
BufferArray * mReplyBody;
off_t mReplyOffset;
size_t mReplyLength;
Monty Brandenberg
committed
size_t mReplyFullLength;
Rider Linden
committed
HttpHeaders::ptr_t mReplyHeaders;
std::string mReplyConType;
int mReplyRetryAfter;
// Policy data
int mPolicyRetries;
int mPolicy503Retries;
HttpTime mPolicyRetryAt;
int mPolicyRetryLimit;
HttpTime mPolicyMinRetryBackoff; // initial delay between retries (mcs)
HttpTime mPolicyMaxRetryBackoff;
Monty Brandenberg
committed
}; // end class HttpOpRequest
Rider Linden
committed
Monty Brandenberg
committed
/// HttpOpRequestCompare isn't an operation but a uniform comparison
/// functor for STL containers that order by priority. Mainly
/// used for the ready queue container but defined here.
class HttpOpRequestCompare
{
public:
bool operator()(const HttpOpRequest * lhs, const HttpOpRequest * rhs)
{
return lhs->mReqPriority > rhs->mReqPriority;
}
}; // end class HttpOpRequestCompare
// ---------------------------------------
// Free functions
// ---------------------------------------
// Internal function to append the contents of an HttpHeaders
// instance to a curl_slist object.
Rider Linden
committed
curl_slist * append_headers_to_slist(const HttpHeaders::ptr_t &, curl_slist * slist);
Monty Brandenberg
committed
} // end namespace LLCore
#endif // _LLCORE_HTTP_OPREQUEST_H_