llcorehttprequest.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. /**
  2. * @file llcorehttprequest.h
  3. * @brief Public-facing declarations for HttpRequest class
  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_REQUEST_H_
  27. #define _LLCORE_HTTP_REQUEST_H_
  28. #include "llcorehttphandler.h"
  29. #include "llcorehttpheaders.h"
  30. #include "llcorehttpoptions.h"
  31. // Convenient shortcut
  32. #define DEFAULT_HTTP_REQUEST std::make_shared<LLCore::HttpRequest>()
  33. namespace LLCore
  34. {
  35. class HttpRequestQueue;
  36. class HttpReplyQueue;
  37. class HttpService;
  38. class HttpOperation;
  39. class BufferArray;
  40. // HttpRequest supplies the entry into the HTTP transport services in the
  41. // LLCore libraries. Services provided include:
  42. //
  43. // - Some, but not all, global initialization of libcurl.
  44. // - Starting asynchronous, threaded HTTP requests.
  45. // - Definition of policy classes affect request handling.
  46. // - Utilities to control request options and headers
  47. //
  48. // Requests
  49. //
  50. // The class supports the current HTTP request operations:
  51. //
  52. // - requestGetByteRange: GET with Range header for a single range of bytes
  53. // - requestGet:
  54. // - requestPost:
  55. // - requestPut:
  56. //
  57. // Threading: An instance may only be used by one application/consumer thread.
  58. // But a thread may have as many instances of this as it likes.
  59. //
  60. // Allocation: Not refcounted, may be stack allocated though that has not been
  61. // tested. Queued requests can still run and any queued replies will keep
  62. // refcounts to the reply queue leading to memory leaks.
  63. //
  64. // Before using this class (static or instances), some global initialization is
  65. // required. See httpcommon.h for more information.
  66. class HttpRequest
  67. {
  68. public:
  69. HttpRequest();
  70. virtual ~HttpRequest();
  71. private:
  72. HttpRequest(const HttpRequest&); // Disallowed
  73. void operator=(const HttpRequest&); // Disallowed
  74. public:
  75. typedef unsigned int policy_t;
  76. typedef std::shared_ptr<HttpRequest> ptr_t;
  77. typedef std::weak_ptr<HttpRequest> wptr_t;
  78. // PolicyMethods
  79. // Represents a default, catch-all policy class that guarantees eventual
  80. // service for any HTTP request.
  81. static const policy_t DEFAULT_POLICY_ID = 0;
  82. static const policy_t INVALID_POLICY_ID = 0xFFFFFFFFU;
  83. static const policy_t GLOBAL_POLICY_ID = 0xFFFFFFFEU;
  84. // Create a new policy class into which requests can be made.
  85. //
  86. // All class creation must occur before threads are started and transport
  87. // begins. Policy classes are limited to a small value. Currently that
  88. // limit is the default class + 1.
  89. //
  90. // If positive, the policy_id used to reference the class in other methods.
  91. // If 0, requests for classes have exceeded internal limits or caller has
  92. // tried to create a class after threads have been started. Caller must
  93. // fallback and recover.
  94. static policy_t createPolicyClass();
  95. enum EPolicyOption
  96. {
  97. // Maximum number of connections the library will use to perform
  98. // operations. This is somewhat soft as the underlying transport will
  99. // cache some connections (up to 5).
  100. // A long value setting the maximum number of connections allowed over
  101. // all policy classes. Note that this will be a somewhat soft value.
  102. // There may be an additional five connections per policy class
  103. // depending upon runtime behavior.
  104. //
  105. // Both global and per-class
  106. PO_CONNECTION_LIMIT,
  107. // Limits the number of connections used for a single literal address/
  108. // port pair within the class.
  109. //
  110. // Per-class only
  111. PO_PER_HOST_CONNECTION_LIMIT,
  112. // String containing a system-appropriate directory name where SSL
  113. // certs are stored.
  114. //
  115. // Global only
  116. PO_CA_PATH,
  117. // String giving a full path to a file containing SSL certs.
  118. //
  119. // Global only
  120. PO_CA_FILE,
  121. // String of host/port to use as simple HTTP proxy. This is going to
  122. // change in the future into something more elaborate that may support
  123. // richer schemes.
  124. //
  125. // Global only
  126. PO_HTTP_PROXY,
  127. // Long value that if non-zero enables the use of the traditional
  128. // LLProxy code for http/socks5 support. If enabled, has priority over
  129. // GP_HTTP_PROXY.
  130. //
  131. // Global only
  132. PO_LLPROXY,
  133. // Long value setting the logging trace level for the library. Possible
  134. // values are:
  135. // 0 - No tracing (default)
  136. // 1 - Basic tracing of request start, stop and major events.
  137. // 2 - Connection, header and payload size information from HTTP
  138. // transactions.
  139. // 3 - Partial logging of payload itself.
  140. //
  141. // These values are also used in the trace modes for individual
  142. // requests in HttpOptions. Also be aware that tracing tends to impact
  143. // performance of the viewer.
  144. //
  145. // Global or per-class
  146. PO_TRACE,
  147. // If greater than 1, suitable requests are allowed to pipeline on
  148. // their connections when they ask for it. Value gives the maximum
  149. // number of outstanding requests on a connection.
  150. //
  151. // There is some interaction between PO_CONNECTION_LIMIT,
  152. // PO_PER_HOST_CONNECTION_LIMIT, and PO_PIPELINING_DEPTH.
  153. // When PIPELINING_DEPTH is 0 or 1 (no pipelining), this library
  154. // manages connection lifecycle and honors the PO_CONNECTION_LIMIT
  155. // setting as the maximum in-flight request limit. Libcurl itself may
  156. // be caching additional connections under its connection cache policy.
  157. //
  158. // When PIPELINING_DEPTH is 2 or more, libcurl performs connection
  159. // management and both PO_CONNECTION_LIMIT and
  160. // PO_PER_HOST_CONNECTION_LIMIT should be set and non-zero. In this
  161. // case (as of libcurl 7.37.0), libcurl will open new connections in
  162. // preference to pipelining, up to the above limits at which time
  163. // pipelining begins. And as usual, an additional cache of open but
  164. // inactive connections may still be maintained within libcurl.
  165. // For SL, a good rule-of-thumb is to set PO_PER_HOST_CONNECTION_LIMIT
  166. // to the user-visible concurrency value and PO_CONNECTION_LIMIT to
  167. // twice that for baked texture loads and region crossings where
  168. // additional connection load will be tolerated. If either limit is 0,
  169. // libcurl will prefer pipelining over connection creation, which is
  170. // still interesting, but won't be pursued at this time.
  171. //
  172. // Per-class only
  173. PO_PIPELINING_DEPTH,
  174. // Controls whether client-side throttling should be performed on this
  175. // policy class. Positive values enable throttling and specify the
  176. // request rate (requests per second) that should be targeted. A value
  177. // of zero, the default, specifies no throttling.
  178. //
  179. // Per-class only
  180. PO_THROTTLE_RATE,
  181. // Controls the callback function used to control SSL CTX certificate
  182. // verification.
  183. //
  184. // Global only
  185. PO_SSL_VERIFY_CALLBACK,
  186. PO_LAST // Always at end
  187. };
  188. // Prototype for policy based callbacks. The callback methods will be
  189. // executed on the worker thread so no modifications should be made to the
  190. // HttpHandler object.
  191. typedef boost::function<HttpStatus(const std::string&,
  192. const HttpHandler::ptr_t&,
  193. void*)> policyCallback_t;
  194. // Set a policy option for a global or class parameter at startup time
  195. // (prior to thread start).
  196. //
  197. // - opt: enum of option to be set.
  198. // - pclass: for class-based options, the policy class ID to be changed.
  199. // For globals, specify GLOBAL_POLICY_ID.
  200. // - value: desired value of option.
  201. // - ret_value: pointer to receive effective set value if successful. May
  202. // be NULL if effective value not wanted.
  203. // Returned value: standard status code.
  204. static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
  205. long value, long* ret_value);
  206. static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
  207. const std::string& value,
  208. std::string* ret_value);
  209. static HttpStatus setStaticPolicyOption(EPolicyOption opt, policy_t pclass,
  210. policyCallback_t value,
  211. policyCallback_t* ret_value);
  212. // Set a parameter on a class-based policy option. Calls made after the
  213. // start of the servicing thread are not honored and return an error
  214. // status.
  215. //
  216. // - opt: enum of option to be set.
  217. // - pclass: for class-based options, the policy class ID to be changed.
  218. // Ignored for globals but recommend using INVALID_POLICY_ID
  219. // in this case.
  220. // - value: desired value of option.
  221. // Returned value: handle of dynamic request. Use @see getStatus() if the
  222. // returned handle is invalid.
  223. HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, long value,
  224. HttpHandler::ptr_t handler);
  225. HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass,
  226. const std::string& value,
  227. HttpHandler::ptr_t handler);
  228. // @name RequestMethods
  229. // Some calls expect to succeed as the normal part of operation and so
  230. // return a useful value rather than a status. When they do fail, the
  231. // status is saved and can be fetched with this method.
  232. //
  233. // Returned value: Status of the failing method invocation. If the
  234. // preceding call succeeded or other HttpStatus returning calls immediately
  235. // preceded this method, the returned value may not be reliable.
  236. LL_INLINE HttpStatus getStatus() const { return mLastReqStatus; }
  237. // Queue a full HTTP GET request to be issued for entire entity. The
  238. // request is queued and serviced by the working thread and notification of
  239. // completion delivered to the optional HttpHandler argument during; see
  240. // update() calls.
  241. //
  242. // With a valid handle returned, it can be used to reference the request in
  243. // other requests (like cancellation) and will be an argument when any
  244. // HttpHandler object is invoked.
  245. //
  246. // Headers supplied by default:
  247. // - Connection: keep-alive
  248. // - Accept: * / *
  249. // - Accept-Encoding: deflate, gzip
  250. // - Keep-alive: 300
  251. // - Host: <stuff>
  252. //
  253. // Some headers excluded by default:
  254. // - Pragma:
  255. // - Cache-control:
  256. // - Range:
  257. // - Transfer-Encoding:
  258. // - Referer:
  259. //
  260. // @param policy_id Default or user-defined policy class under
  261. // which this request is to be serviced.
  262. // @param url URL with any encoded query parameters to
  263. // be accessed.
  264. // @param options Optional instance of an HttpOptions object
  265. // to provide additional controls over the request
  266. // function for this request only. Any such
  267. // object then becomes shared-read across threads
  268. // and no code should modify the HttpOptions
  269. // instance.
  270. // @param headers Optional instance of an HttpHeaders object
  271. // to provide additional and/or overridden
  272. // headers for the request. As with options,
  273. // the instance becomes shared-read across threads
  274. // and no code should modify the HttpHeaders
  275. // instance.
  276. // @param handler Optional pointer to an HttpHandler instance
  277. // whose onCompleted() method will be invoked
  278. // during calls to update(). This is a non-
  279. // reference-counted object which would be a
  280. // problem for shutdown and other edge cases but
  281. // the pointer is only dereferenced during
  282. // calls to update().
  283. //
  284. // @return The handle of the request if successfully
  285. // queued or LLCORE_HTTP_HANDLE_INVALID if the
  286. // request could not be queued. In the latter
  287. // case, @see getStatus() will return more info.
  288. //
  289. HttpHandle requestGet(policy_t policy_id, const std::string& url,
  290. const HttpOptions::ptr_t& options,
  291. const HttpHeaders::ptr_t& headers,
  292. HttpHandler::ptr_t handler);
  293. // Queue a full HTTP GET request to be issued with a 'Range' header. The
  294. // request is queued and serviced by the working thread and notification of
  295. // completion delivered to the optional HttpHandler argument during; see
  296. // update() calls.
  297. //
  298. // With a valid handle returned, it can be used to reference the request in
  299. // other requests (like cancellation) and will be an argument when any
  300. // HttpHandler object is invoked.
  301. //
  302. // Headers supplied by default:
  303. // - Connection: keep-alive
  304. // - Accept: * / *
  305. // - Accept-Encoding: deflate, gzip
  306. // - Keep-alive: 300
  307. // - Host: <stuff>
  308. // - Range: <stuff> (will be omitted if offset == 0 and len == 0)
  309. //
  310. // Some headers excluded by default:
  311. // - Pragma:
  312. // - Cache-control:
  313. // - Transfer-Encoding:
  314. // - Referer:
  315. //
  316. // @param policy_id @see requestGet()
  317. // @param url "
  318. // @param offset Offset of first byte into resource to be returned.
  319. // @param len Count of bytes to be returned
  320. // @param options @see requestGet()
  321. // @param headers "
  322. // @param handler "
  323. // @return "
  324. //
  325. HttpHandle requestGetByteRange(policy_t policy_id, const std::string& url,
  326. size_t offset, size_t len,
  327. const HttpOptions::ptr_t& options,
  328. const HttpHeaders::ptr_t& headers,
  329. HttpHandler::ptr_t handler);
  330. // Queue a full HTTP POST. Query arguments and body may/ be provided.
  331. // Caller is responsible for escaping and encoding and communicating the
  332. // content types.
  333. //
  334. // Headers supplied by default:
  335. // - Connection: keep-alive
  336. // - Accept: * / *
  337. // - Accept-Encoding: deflate, gzip
  338. // - Keep-Alive: 300
  339. // - Host: <stuff>
  340. // - Content-Length: <digits>
  341. // - Content-Type: application/x-www-form-urlencoded
  342. //
  343. // Some headers excluded by default:
  344. // - Pragma:
  345. // - Cache-Control:
  346. // - Transfer-Encoding: ... chunked ...
  347. // - Referer:
  348. // - Content-Encoding:
  349. // - Expect:
  350. //
  351. // @param policy_id @see requestGet()
  352. // @param url "
  353. // @param body Byte stream to be sent as the body. No further
  354. // encoding or escaping will be done to the content.
  355. // @param options @see requestGet()K(optional)
  356. // @param headers "
  357. // @param handler "
  358. // @return "
  359. //
  360. HttpHandle requestPost(policy_t policy_id, const std::string& url,
  361. BufferArray* body,
  362. const HttpOptions::ptr_t& options,
  363. const HttpHeaders::ptr_t& headers,
  364. HttpHandler::ptr_t handler);
  365. // Queue a full HTTP PUT. Query arguments and body may be provided. Caller
  366. // is responsible for escaping and encoding and communicating the content
  367. // types.
  368. //
  369. // Headers supplied by default:
  370. // - Connection: keep-alive
  371. // - Accept: * / *
  372. // - Accept-Encoding: deflate, gzip
  373. // - Keep-Alive: 300
  374. // - Host: <stuff>
  375. // - Content-Length: <digits>
  376. //
  377. // Some headers excluded by default:
  378. // - Pragma:
  379. // - Cache-Control:
  380. // - Transfer-Encoding: ... chunked ...
  381. // - Referer:
  382. // - Content-Encoding:
  383. // - Expect:
  384. // - Content-Type:
  385. //
  386. // @param policy_id @see requestGet()
  387. // @param url "
  388. // @param body Byte stream to be sent as the body. No further
  389. // encoding or escaping will be done to the content.
  390. // @param options @see requestGet()K(optional)
  391. // @param headers "
  392. // @param handler "
  393. // @return "
  394. //
  395. HttpHandle requestPut(policy_t policy_id, const std::string& url,
  396. BufferArray* body,
  397. const HttpOptions::ptr_t& options,
  398. const HttpHeaders::ptr_t& headers,
  399. HttpHandler::ptr_t handler);
  400. // Queue a full HTTP DELETE. Query arguments and body may be provided.
  401. // Caller is responsible for escaping and encoding and communicating the
  402. // content types.
  403. //
  404. // @param policy_id @see requestGet()
  405. // @param url "
  406. // @param options @see requestGet()K(optional)
  407. // @param headers "
  408. // @param handler "
  409. // @return "
  410. //
  411. HttpHandle requestDelete(policy_t policy_id, const std::string& url,
  412. const HttpOptions::ptr_t& options,
  413. const HttpHeaders::ptr_t& headers,
  414. HttpHandler::ptr_t user_handler);
  415. // Queue a full HTTP PATCH. Query arguments and body may be provided.
  416. // Caller is responsible for escaping and encoding and communicating the
  417. // content types.
  418. //
  419. // @param policy_id @see requestGet()
  420. // @param url "
  421. // @param body Byte stream to be sent as the body. No
  422. // further encoding or escaping will be done
  423. // to the content.
  424. // @param options @see requestGet()K(optional)
  425. // @param headers "
  426. // @param handler "
  427. // @return "
  428. //
  429. HttpHandle requestPatch(policy_t policy_id, const std::string& url,
  430. BufferArray* body,
  431. const HttpOptions::ptr_t& options,
  432. const HttpHeaders::ptr_t& headers,
  433. HttpHandler::ptr_t user_handler);
  434. // Queue a full HTTP COPY. Query arguments and body may be provided. Caller
  435. // is responsible for escaping and encoding and communicating the content
  436. // types.
  437. //
  438. // @param policy_id @see requestGet()
  439. // @param url "
  440. // @param options @see requestGet()K(optional)
  441. // @param headers "
  442. // @param handler "
  443. // @return "
  444. //
  445. HttpHandle requestCopy(policy_t policy_id, const std::string& url,
  446. const HttpOptions::ptr_t& options,
  447. const HttpHeaders::ptr_t& headers,
  448. HttpHandler::ptr_t user_handler);
  449. // Queue a full HTTP MOVE. Query arguments and body may be provided. Caller
  450. // is responsible for escaping and encoding and communicating the content
  451. // types.
  452. //
  453. // @param policy_id @see requestGet()
  454. // @param url "
  455. // @param options @see requestGet()K(optional)
  456. // @param headers "
  457. // @param handler "
  458. // @return "
  459. //
  460. HttpHandle requestMove(policy_t policy_id, const std::string& url,
  461. const HttpOptions::ptr_t& options,
  462. const HttpHeaders::ptr_t& headers,
  463. HttpHandler::ptr_t user_handler);
  464. // Queue a NoOp request.
  465. // The request is queued and serviced by the working thread which
  466. // immediately processes it and returns the request to the reply
  467. // queue.
  468. //
  469. // @param handler @see requestGet()
  470. // @return "
  471. //
  472. HttpHandle requestNoOp(HttpHandler::ptr_t handler);
  473. // While all the heavy work is done by the worker thread, notifications
  474. // must be performed in the context of the application thread. These are
  475. // done synchronously during calls to this method which gives the library
  476. // control so notification can be performed. Application handlers are
  477. // expected to return 'quickly' and do any significant processing outside
  478. // of the notification callback to onCompleted().
  479. //
  480. // @param usecs Maximum number of wallclock microseconds to spend in
  481. // the call. As hinted at above, this is partly a function
  482. // of application code so it is a soft limit. A '0' value
  483. // will run without time limit until everything queued has
  484. // been delivered.
  485. //
  486. // @return Standard status code.
  487. HttpStatus update(long usecs);
  488. // @name RequestMgmtMethods
  489. HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t);
  490. // @name UtilityMethods
  491. // Initialization method that needs to be called before queueing any
  492. // request. Doesn't start the worker thread and may be called before or
  493. // after policy setup.
  494. static HttpStatus createService();
  495. // Mostly clean shutdown of services prior to exit. Caller is expected
  496. // to have stopped a running worker thread before calling this.
  497. static HttpStatus destroyService();
  498. // Called once after @see createService() to start the worker thread.
  499. // Stopping the thread is achieved by requesting it via; see
  500. // requestStopThread().
  501. // May be called before or after requests are issued.
  502. static HttpStatus startThread();
  503. // Queues a request to the worker thread to have it stop processing and
  504. // exit (without exiting the program). When the operation is picked up by
  505. // the worker thread, it immediately processes it and begins detaching from
  506. // refcounted resources like request and reply queues and then returns to
  507. // the host OS. It *does* queue a reply to give the calling application
  508. // thread a notification that the operation has been performed.
  509. //
  510. // @param handler (optional)
  511. // @return The handle of the request if successfully queued or
  512. // LLCORE_HTTP_HANDLE_INVALID if the request could not be
  513. // queued. In the latter case (see getStatus()) will
  514. // return more info. As the request cannot be cancelled,
  515. // the handle is generally not useful.
  516. //
  517. HttpHandle requestStopThread(HttpHandler::ptr_t handler);
  518. LL_INLINE bool isCancelled() const { return mCancelled; }
  519. private:
  520. typedef std::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t;
  521. HttpStatus mLastReqStatus;
  522. HttpReplyQueuePtr_t mReplyQueue;
  523. HttpRequestQueue* mRequestQueue;
  524. bool mCancelled;
  525. static bool sInitialized;
  526. };
  527. } // End namespace LLCore
  528. #endif // _LLCORE_HTTP_REQUEST_H_