123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /**
- * @file llcorehttpoprequest.h
- * @brief Internal declarations for the HttpOpRequest subclass
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * 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_
- #include "openssl/x509_vfy.h"
- #include "openssl/ssl.h"
- #include "llcorehttpcommon.h"
- #include "llcorehttpheaders.h"
- #include "llcorehttpoperation.h"
- #include "llcorehttpoptions.h"
- #include "llcorehttprequest.h"
- #include "llcorerefcounted.h"
- #include "llerror.h"
- 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.
- class HttpOpRequest final : public HttpOperation
- {
- protected:
- LOG_CLASS(HttpOpRequest);
- public:
- typedef std::shared_ptr<HttpOpRequest> ptr_t;
- HttpOpRequest();
- virtual ~HttpOpRequest(); // Use release()
- HttpOpRequest(const HttpOpRequest&) = delete;
- void operator=(const HttpOpRequest&) = delete;
- enum EMethod
- {
- HOR_GET,
- HOR_POST,
- HOR_PUT,
- HOR_DELETE,
- HOR_PATCH,
- HOR_COPY,
- HOR_MOVE
- };
- 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
- //
- HttpStatus setupGet(HttpRequest::policy_t policy_id,
- const std::string& url,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
- const std::string& url,
- size_t offset, size_t len,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupPost(HttpRequest::policy_t policy_id,
- const std::string& url, BufferArray* body,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupPut(HttpRequest::policy_t policy_id,
- const std::string& url, BufferArray* body,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupDelete(HttpRequest::policy_t policy_id,
- const std::string& url,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupPatch(HttpRequest::policy_t policy_id,
- const std::string& url, BufferArray* body,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupCopy(HttpRequest::policy_t policy_id,
- const std::string& url,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- HttpStatus setupMove(HttpRequest::policy_t policy_id,
- 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);
- virtual HttpStatus cancel();
- protected:
- // Common setup for all the request methods.
- //
- // Threading: called by application thread
- //
- void setupCommon(HttpRequest::policy_t policy_id,
- const std::string& url, BufferArray* body,
- const HttpOptions::ptr_t& options,
- const HttpHeaders::ptr_t& headers);
- // libcurl operational callbacks
- //
- // Threading: called by worker thread
- //
- 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);
- static size_t headerCallback(void* data, size_t size, size_t nmemb,
- void* userdata);
- static CURLcode curlSslCtxCallback(CURL* curl, void* ssl_ctx,
- void* userdata);
- static int sslCertVerifyCallback(X509_STORE_CTX* ctx, void* userdata);
- static int debugCallback(CURL*, curl_infotype info, char* buffer,
- size_t len, void* userdata);
- 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;
- HttpRequest::policyCallback_t mCallbackSSLVerify;
- public:
- // Request data
- EMethod mReqMethod;
- std::string mReqURL;
- BufferArray* mReqBody;
- off_t mReqOffset;
- size_t mReqLength;
- HttpHeaders::ptr_t mReqHeaders;
- HttpOptions::ptr_t mReqOptions;
- // Transport data
- bool mCurlActive;
- CURL* mCurlHandle;
- HttpService* mCurlService;
- curl_slist* mCurlHeaders;
- size_t mCurlBodyPos;
- char* mCurlTemp; // Scratch buffer for header processing
- size_t mCurlTempLen;
- // Result data
- HttpStatus mStatus;
- BufferArray* mReplyBody;
- off_t mReplyOffset;
- size_t mReplyLength;
- size_t mReplyFullLength;
- HttpHeaders::ptr_t mReplyHeaders;
- std::string mReplyConType;
- int mReplyRetryAfter;
- // Policy data
- int mPolicyRetries;
- int mPolicy503Retries;
- HttpTime mPolicyRetryAt;
- int mPolicyRetryLimit;
- // *HACK: some safe place to store any "location" header entry, that would
- // otherwise get mysteriously wiped out of mReplyHeaders between the
- // headerCallback() and the visitNotifier() calls...
- std::string mLocation;
- };
- // ---------------------------------------
- // Free functions
- // ---------------------------------------
- // Internal function to append the contents of an HttpHeaders
- // instance to a curl_slist object.
- curl_slist* append_headers_to_slist(const HttpHeaders::ptr_t&,
- curl_slist* slist);
- } // End namespace LLCore
- #endif // _LLCORE_HTTP_OPREQUEST_H_
|