llcorehttpoprequest.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /**
  2. * @file llcorehttpoprequest.h
  3. * @brief Internal declarations for the HttpOpRequest subclass
  4. *
  5. * $LicenseInfo:firstyear=2012&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2012, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef _LLCORE_HTTP_OPREQUEST_H_
  27. #define _LLCORE_HTTP_OPREQUEST_H_
  28. #include "openssl/x509_vfy.h"
  29. #include "openssl/ssl.h"
  30. #include "llcorehttpcommon.h"
  31. #include "llcorehttpheaders.h"
  32. #include "llcorehttpoperation.h"
  33. #include "llcorehttpoptions.h"
  34. #include "llcorehttprequest.h"
  35. #include "llcorerefcounted.h"
  36. #include "llerror.h"
  37. namespace LLCore
  38. {
  39. class BufferArray;
  40. // HttpOpRequest requests a supported HTTP method invocation with option and
  41. // header overrides.
  42. //
  43. // Essentially an RPC to get an HTTP GET, POST or PUT executed asynchronously
  44. // with options to override behaviors and HTTP headers.
  45. //
  46. // Constructor creates a raw object incapable of useful work. A subsequent call
  47. // to one of the setupXXX() methods provides the information needed to make a
  48. // working request which can then be enqueued to a request queue.
  49. class HttpOpRequest final : public HttpOperation
  50. {
  51. protected:
  52. LOG_CLASS(HttpOpRequest);
  53. public:
  54. typedef std::shared_ptr<HttpOpRequest> ptr_t;
  55. HttpOpRequest();
  56. virtual ~HttpOpRequest(); // Use release()
  57. HttpOpRequest(const HttpOpRequest&) = delete;
  58. void operator=(const HttpOpRequest&) = delete;
  59. enum EMethod
  60. {
  61. HOR_GET,
  62. HOR_POST,
  63. HOR_PUT,
  64. HOR_DELETE,
  65. HOR_PATCH,
  66. HOR_COPY,
  67. HOR_MOVE
  68. };
  69. virtual void stageFromRequest(HttpService*);
  70. virtual void stageFromReady(HttpService*);
  71. virtual void stageFromActive(HttpService*);
  72. virtual void visitNotifier(HttpRequest* request);
  73. public:
  74. // Setup Methods
  75. //
  76. // Basically an RPC setup for each type of HTTP method invocation with one
  77. // per method type. These are generally invoked right after construction.
  78. //
  79. // Threading: called by application thread
  80. //
  81. HttpStatus setupGet(HttpRequest::policy_t policy_id,
  82. const std::string& url,
  83. const HttpOptions::ptr_t& options,
  84. const HttpHeaders::ptr_t& headers);
  85. HttpStatus setupGetByteRange(HttpRequest::policy_t policy_id,
  86. const std::string& url,
  87. size_t offset, size_t len,
  88. const HttpOptions::ptr_t& options,
  89. const HttpHeaders::ptr_t& headers);
  90. HttpStatus setupPost(HttpRequest::policy_t policy_id,
  91. const std::string& url, BufferArray* body,
  92. const HttpOptions::ptr_t& options,
  93. const HttpHeaders::ptr_t& headers);
  94. HttpStatus setupPut(HttpRequest::policy_t policy_id,
  95. const std::string& url, BufferArray* body,
  96. const HttpOptions::ptr_t& options,
  97. const HttpHeaders::ptr_t& headers);
  98. HttpStatus setupDelete(HttpRequest::policy_t policy_id,
  99. const std::string& url,
  100. const HttpOptions::ptr_t& options,
  101. const HttpHeaders::ptr_t& headers);
  102. HttpStatus setupPatch(HttpRequest::policy_t policy_id,
  103. const std::string& url, BufferArray* body,
  104. const HttpOptions::ptr_t& options,
  105. const HttpHeaders::ptr_t& headers);
  106. HttpStatus setupCopy(HttpRequest::policy_t policy_id,
  107. const std::string& url,
  108. const HttpOptions::ptr_t& options,
  109. const HttpHeaders::ptr_t& headers);
  110. HttpStatus setupMove(HttpRequest::policy_t policy_id,
  111. const std::string& url,
  112. const HttpOptions::ptr_t& options,
  113. const HttpHeaders::ptr_t& headers);
  114. // Internal method used to setup the libcurl options for a request.
  115. // Does all the libcurl handle setup in one place.
  116. //
  117. // Threading: called by worker thread
  118. //
  119. HttpStatus prepareRequest(HttpService* service);
  120. virtual HttpStatus cancel();
  121. protected:
  122. // Common setup for all the request methods.
  123. //
  124. // Threading: called by application thread
  125. //
  126. void setupCommon(HttpRequest::policy_t policy_id,
  127. const std::string& url, BufferArray* body,
  128. const HttpOptions::ptr_t& options,
  129. const HttpHeaders::ptr_t& headers);
  130. // libcurl operational callbacks
  131. //
  132. // Threading: called by worker thread
  133. //
  134. static size_t writeCallback(void* data, size_t size, size_t nmemb,
  135. void* userdata);
  136. static size_t readCallback(void* data, size_t size, size_t nmemb,
  137. void* userdata);
  138. static int seekCallback(void* data, curl_off_t offset, int origin);
  139. static size_t headerCallback(void* data, size_t size, size_t nmemb,
  140. void* userdata);
  141. static CURLcode curlSslCtxCallback(CURL* curl, void* ssl_ctx,
  142. void* userdata);
  143. static int sslCertVerifyCallback(X509_STORE_CTX* ctx, void* userdata);
  144. static int debugCallback(CURL*, curl_infotype info, char* buffer,
  145. size_t len, void* userdata);
  146. protected:
  147. unsigned int mProcFlags;
  148. static const unsigned int PF_SCAN_RANGE_HEADER = 0x00000001U;
  149. static const unsigned int PF_SAVE_HEADERS = 0x00000002U;
  150. static const unsigned int PF_USE_RETRY_AFTER = 0x00000004U;
  151. HttpRequest::policyCallback_t mCallbackSSLVerify;
  152. public:
  153. // Request data
  154. EMethod mReqMethod;
  155. std::string mReqURL;
  156. BufferArray* mReqBody;
  157. off_t mReqOffset;
  158. size_t mReqLength;
  159. HttpHeaders::ptr_t mReqHeaders;
  160. HttpOptions::ptr_t mReqOptions;
  161. // Transport data
  162. bool mCurlActive;
  163. CURL* mCurlHandle;
  164. HttpService* mCurlService;
  165. curl_slist* mCurlHeaders;
  166. size_t mCurlBodyPos;
  167. char* mCurlTemp; // Scratch buffer for header processing
  168. size_t mCurlTempLen;
  169. // Result data
  170. HttpStatus mStatus;
  171. BufferArray* mReplyBody;
  172. off_t mReplyOffset;
  173. size_t mReplyLength;
  174. size_t mReplyFullLength;
  175. HttpHeaders::ptr_t mReplyHeaders;
  176. std::string mReplyConType;
  177. int mReplyRetryAfter;
  178. // Policy data
  179. int mPolicyRetries;
  180. int mPolicy503Retries;
  181. HttpTime mPolicyRetryAt;
  182. int mPolicyRetryLimit;
  183. // *HACK: some safe place to store any "location" header entry, that would
  184. // otherwise get mysteriously wiped out of mReplyHeaders between the
  185. // headerCallback() and the visitNotifier() calls...
  186. std::string mLocation;
  187. };
  188. // ---------------------------------------
  189. // Free functions
  190. // ---------------------------------------
  191. // Internal function to append the contents of an HttpHeaders
  192. // instance to a curl_slist object.
  193. curl_slist* append_headers_to_slist(const HttpHeaders::ptr_t&,
  194. curl_slist* slist);
  195. } // End namespace LLCore
  196. #endif // _LLCORE_HTTP_OPREQUEST_H_