llcorehttputil.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /**
  2. * @file llcorehttputil.h
  3. * @date 2014-08-25
  4. * @brief Adapter and utility classes expanding the llcorehttp interfaces.
  5. *
  6. * $LicenseInfo:firstyear=2014&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2014, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #ifndef LL_LLCOREHTTPUTIL_H
  28. #define LL_LLCOREHTTPUTIL_H
  29. #include <memory>
  30. #include "llassettype.h"
  31. #include "llcorebufferarray.h"
  32. #include "llcorebufferstream.h"
  33. #include "llcorehttphandler.h"
  34. #include "llcorehttpheaders.h"
  35. #include "llcorehttpoptions.h"
  36. #include "llcorehttprequest.h"
  37. #include "llcorehttpresponse.h"
  38. #include "llcoros.h"
  39. #include "llerror.h"
  40. #include "lleventcoro.h"
  41. #include "llhttpconstants.h"
  42. #include "llstring.h"
  43. #include "lluuid.h"
  44. // The base llcorehttp library implements many HTTP idioms used in the viewer
  45. // but not all. That library intentionally avoids the use of LLSD and its
  46. // conventions which aren't universally applicable. This module, using
  47. // namespace LLCoreHttpUtil, provides the additional helper functions that
  48. // support idiomatic LLSD transport via the newer llcorehttp library.
  49. namespace LLCoreHttpUtil
  50. {
  51. constexpr F32 HTTP_REQUEST_EXPIRY_SECS = 60.f;
  52. // Attempts to convert a response object's contents to LLSD. It is expected
  53. // that the response body will be of non-zero length on input but basic checks
  54. // will be performed and error (false status) returned if there is no data.
  55. // If there is data but it cannot be successfully parsed, an error is also
  56. // returned. If successfully parsed, the output LLSD object, out_llsd, is
  57. // written with the result and true is returned.
  58. //
  59. // @arg response Response object as returned in an HttpHandler onCompleted()
  60. // callback.
  61. // @arg log If true, LLSD parser will emit errors as llinfos-level
  62. // messages as it parses. Otherwise, it *should* be a quiet
  63. // parse.
  64. // @arg out_llsd Output LLSD object written only upon successful parse of
  65. // the response object.
  66. //
  67. // @return Returns true (and writes to out_llsd) if parse was
  68. // successful. False otherwise.
  69. bool responseToLLSD(LLCore::HttpResponse* response, bool log, LLSD& out_llsd);
  70. // Creates a std::string representation of a response object suitable for
  71. // logging. Mainly intended for logging of failures and debug information. This
  72. // won't be fast, just adequate.
  73. std::string responseToString(LLCore::HttpResponse* response);
  74. // Issues a standard HttpRequest::requestPost() call but using an LLSD object
  75. // as the request body. Conventions are the same as with that method. Caller is
  76. // expected to provide an HttpHeaders object with a correct 'Content-Type:'
  77. // header. One will not be provided by this call. You might look after the
  78. // 'Accept:' header as well.
  79. //
  80. // @return If request is successfully issued, the HttpHandle representing the
  81. // request. On error, LLCORE_HTTP_HANDLE_INVALID is returned and the
  82. // caller can fetch detailed status with the getStatus() method on the
  83. // request object. In case of error, no request is queued and the
  84. // caller may need to perform additional cleanup such as freeing a
  85. // now-useless HttpHandler object.
  86. LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest* request,
  87. LLCore::HttpRequest::policy_t policy_id,
  88. const std::string& url,
  89. const LLSD& body,
  90. const LLCore::HttpOptions::ptr_t& options,
  91. const LLCore::HttpHeaders::ptr_t& headers,
  92. const LLCore::HttpHandler::ptr_t& handler);
  93. LL_INLINE LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t& request,
  94. LLCore::HttpRequest::policy_t policy_id,
  95. const std::string& url,
  96. const LLSD& body,
  97. const LLCore::HttpOptions::ptr_t& options,
  98. const LLCore::HttpHeaders::ptr_t& headers,
  99. const LLCore::HttpHandler::ptr_t& handler)
  100. {
  101. return requestPostWithLLSD(request.get(), policy_id, url, body, options,
  102. headers, handler);
  103. }
  104. LL_INLINE LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t& request,
  105. LLCore::HttpRequest::policy_t policy_id,
  106. const std::string& url,
  107. const LLSD& body,
  108. const LLCore::HttpHandler::ptr_t& handler)
  109. {
  110. LLCore::HttpOptions::ptr_t options;
  111. LLCore::HttpHeaders::ptr_t headers;
  112. return requestPostWithLLSD(request.get(), policy_id, url, body,
  113. options, headers, handler);
  114. }
  115. // Issues a standard HttpRequest::requestPut() call but using an LLSD object as
  116. // the request body. Conventions are the same as with that method. Caller is
  117. // expected to provide an HttpHeaders object with a correct 'Content-Type:'
  118. // header. One will not be provided by this call.
  119. //
  120. // @return If request is successfully issued, the HttpHandle representing the
  121. // request. On error, LLCORE_HTTP_HANDLE_INVALID is returned and
  122. // caller can fetch detailed status with the getStatus() method on the
  123. // request object. In case of error, no request is queued and caller
  124. // may need to perform additional cleanup such as freeing a now
  125. // useless HttpHandler object.
  126. LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest* request,
  127. LLCore::HttpRequest::policy_t policy_id,
  128. const std::string& url, const LLSD& body,
  129. const LLCore::HttpOptions::ptr_t& options,
  130. const LLCore::HttpHeaders::ptr_t& headers,
  131. const LLCore::HttpHandler::ptr_t& handler);
  132. LL_INLINE LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t& request,
  133. LLCore::HttpRequest::policy_t policy_id,
  134. const std::string& url,
  135. const LLSD& body,
  136. const LLCore::HttpOptions::ptr_t& options,
  137. const LLCore::HttpHeaders::ptr_t& headers,
  138. LLCore::HttpHandler::ptr_t handler)
  139. {
  140. return requestPutWithLLSD(request.get(), policy_id, url, body, options,
  141. headers, handler);
  142. }
  143. LL_INLINE LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t& request,
  144. LLCore::HttpRequest::policy_t policy_id,
  145. const std::string& url,
  146. const LLSD& body,
  147. LLCore::HttpHandler::ptr_t handler)
  148. {
  149. LLCore::HttpOptions::ptr_t options;
  150. LLCore::HttpHeaders::ptr_t headers;
  151. return requestPutWithLLSD(request.get(), policy_id, url, body, options,
  152. headers, handler);
  153. }
  154. // Issues a standard HttpRequest::requestPatch() call but using an LLSD object
  155. // as the request body. Conventions are the same as with that method. Caller is
  156. // expected to provide an HttpHeaders object with a correct 'Content-Type:'
  157. // header. One will not be provided by this call.
  158. //
  159. // @return If request is successfully issued, the HttpHandle representing the
  160. // request. On error, LLCORE_HTTP_HANDLE_INVALID is returned and
  161. // caller can fetch detailed status with the getStatus() method on the
  162. // request object. In case of error, no request is queued and caller
  163. // may need to perform additional cleanup such as freeing a now
  164. // useless HttpHandler object.
  165. LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest* request,
  166. LLCore::HttpRequest::policy_t policy_id,
  167. const std::string& url,
  168. const LLSD& body,
  169. const LLCore::HttpOptions::ptr_t& options,
  170. const LLCore::HttpHeaders::ptr_t& headers,
  171. const LLCore::HttpHandler::ptr_t& handler);
  172. LL_INLINE LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t& request,
  173. LLCore::HttpRequest::policy_t policy_id,
  174. const std::string& url,
  175. const LLSD& body,
  176. const LLCore::HttpOptions::ptr_t& options,
  177. const LLCore::HttpHeaders::ptr_t& headers,
  178. const LLCore::HttpHandler::ptr_t& handler)
  179. {
  180. return requestPatchWithLLSD(request.get(), policy_id, url, body, options,
  181. headers, handler);
  182. }
  183. LL_INLINE LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t& request,
  184. LLCore::HttpRequest::policy_t policy_id,
  185. const std::string& url,
  186. const LLSD& body,
  187. const LLCore::HttpHandler::ptr_t& handler)
  188. {
  189. LLCore::HttpOptions::ptr_t options;
  190. LLCore::HttpHeaders::ptr_t headers;
  191. return requestPatchWithLLSD(request.get(), policy_id, url, body, options,
  192. headers, handler);
  193. }
  194. // The HttpCoroHandler is a specialization of the LLCore::HttpHandler for
  195. // interacting with coroutines. When the request is completed the response will
  196. // be posted onto the supplied Event Pump.
  197. //
  198. // The LLSD posted back to the coroutine will have the following additions:
  199. // llsd["http_result"] -+- ["message"] An error message returned from the HTTP
  200. // status.
  201. // +- ["status"] The status code associated with the
  202. // HTTP call.
  203. // +- ["success"] Success of failure of the HTTP call and
  204. // LLSD parsing.
  205. // +- ["type"] The LLCore::HttpStatus type associted
  206. // with the HTTP call.
  207. // +- ["url"] The URL used to make the call.
  208. // +- ["headers"] A map of name name value pairs with the
  209. // HTTP headers.
  210. class HttpCoroHandler : public LLCore::HttpHandler
  211. {
  212. protected:
  213. LOG_CLASS(HttpCoroHandler);
  214. public:
  215. typedef std::shared_ptr<HttpCoroHandler> ptr_t;
  216. typedef std::weak_ptr<HttpCoroHandler> wptr_t;
  217. HttpCoroHandler(LLEventStream& reply);
  218. static void writeStatusCodes(LLCore::HttpStatus status,
  219. const std::string& url, LLSD& result);
  220. virtual void onCompleted(LLCore::HttpHandle handle,
  221. LLCore::HttpResponse* response);
  222. LL_INLINE LLEventStream& getReplyPump() { return mReplyPump; }
  223. protected:
  224. // this method may modify the status value
  225. virtual LLSD handleSuccess(LLCore::HttpResponse* response,
  226. LLCore::HttpStatus& status) = 0;
  227. virtual LLSD parseBody(LLCore::HttpResponse* response, bool& success) = 0;
  228. private:
  229. void buildStatusEntry(LLCore::HttpResponse* response,
  230. LLCore::HttpStatus status, LLSD& result);
  231. private:
  232. LLEventStream& mReplyPump;
  233. };
  234. // HttpCoroutineAdapter is an adapter to handle some of the boilerplate code
  235. // surrounding HTTP and coroutine interaction.
  236. //
  237. // Construct an HttpCoroutineAdapter giving it a name and policy Id. After any
  238. // application specific setup call the post, put or get method. The request
  239. // will be automatically pumped and the method will return with an LLSD
  240. // describing the result of the operation. See HttpCoroHandler for a
  241. // description of the decoration done to the returned LLSD.
  242. //
  243. // Posting through the adapter will automatically add the following headers to
  244. // the request if they have not been previously specified in a supplied
  245. // HttpHeaders object:
  246. // "Accept=application/llsd+xml"
  247. // "X-SecondLife-UDP-Listen-Port=###"
  248. class HttpCoroutineAdapter
  249. {
  250. protected:
  251. LOG_CLASS(HttpCoroutineAdapter);
  252. public:
  253. static const std::string HTTP_RESULTS;
  254. static const std::string HTTP_RESULTS_SUCCESS;
  255. static const std::string HTTP_RESULTS_TYPE;
  256. static const std::string HTTP_RESULTS_STATUS;
  257. static const std::string HTTP_RESULTS_MESSAGE;
  258. static const std::string HTTP_RESULTS_URL;
  259. static const std::string HTTP_RESULTS_HEADERS;
  260. static const std::string HTTP_RESULTS_CONTENT;
  261. static const std::string HTTP_RESULTS_RAW;
  262. typedef std::shared_ptr<HttpCoroutineAdapter> ptr_t;
  263. typedef std::weak_ptr<HttpCoroutineAdapter> wptr_t;
  264. // Use this constructor if you really need to use your own (persistent)
  265. // HttpRequest.
  266. HttpCoroutineAdapter(const std::string& name,
  267. LLCore::HttpRequest::ptr_t& request,
  268. // using DEFAULT_POLICY_ID by default
  269. LLCore::HttpRequest::policy_t policy_id = 0U);
  270. // Use this constructor for all other cases: it will create its own
  271. // HttpRequest on the fly.
  272. HttpCoroutineAdapter(const std::string& name,
  273. // using DEFAULT_POLICY_ID by default
  274. LLCore::HttpRequest::policy_t policy_id = 0U);
  275. ~HttpCoroutineAdapter();
  276. // Executes a Post transaction on the supplied URL and yield execution of
  277. // the coroutine until a result is available.
  278. LLSD postAndSuspend(const std::string& url, const LLSD& body,
  279. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  280. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  281. LLSD postAndSuspend(const std::string& url, LLCore::BufferArray::ptr_t rawbody,
  282. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  283. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  284. LL_INLINE LLSD postAndSuspend(const std::string& url, const LLSD& body,
  285. LLCore::HttpHeaders::ptr_t& headers)
  286. {
  287. return postAndSuspend(url, body, DEFAULT_HTTP_OPTIONS, headers);
  288. }
  289. LL_INLINE LLSD postAndSuspend(const std::string& url,
  290. LLCore::BufferArray::ptr_t& rawbody,
  291. LLCore::HttpHeaders::ptr_t& headers)
  292. {
  293. return postAndSuspend(url, rawbody, DEFAULT_HTTP_OPTIONS, headers);
  294. }
  295. LLSD postRawAndSuspend(const std::string& url,
  296. LLCore::BufferArray::ptr_t rawbody,
  297. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  298. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  299. LL_INLINE LLSD postRawAndSuspend(const std::string& url,
  300. LLCore::BufferArray::ptr_t& rawbody,
  301. LLCore::HttpHeaders::ptr_t& headers)
  302. {
  303. return postRawAndSuspend(url, rawbody, DEFAULT_HTTP_OPTIONS, headers);
  304. }
  305. LLSD postFileAndSuspend(const std::string& url, std::string filename,
  306. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  307. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  308. LL_INLINE LLSD postFileAndSuspend(const std::string& url,
  309. std::string filename,
  310. LLCore::HttpHeaders::ptr_t& headers)
  311. {
  312. return postFileAndSuspend(url, filename, DEFAULT_HTTP_OPTIONS,
  313. headers);
  314. }
  315. LLSD postFileAndSuspend(const std::string& url, const LLUUID& assetid,
  316. LLAssetType::EType assettype,
  317. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  318. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  319. LL_INLINE LLSD postFileAndSuspend(const std::string& url,
  320. const LLUUID& assetid,
  321. LLAssetType::EType assettype,
  322. LLCore::HttpHeaders::ptr_t& headers)
  323. {
  324. return postFileAndSuspend(url, assetid, assettype,
  325. DEFAULT_HTTP_OPTIONS, headers);
  326. }
  327. LLSD postJsonAndSuspend(const std::string& url, const LLSD& body,
  328. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  329. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  330. LL_INLINE LLSD postJsonAndSuspend(const std::string& url, const LLSD& body,
  331. LLCore::HttpHeaders::ptr_t& headers)
  332. {
  333. return postJsonAndSuspend(url, body, DEFAULT_HTTP_OPTIONS, headers);
  334. }
  335. // Executes a Put transaction on the supplied URL and yield execution of
  336. // the coroutine until a result is available.
  337. LLSD putAndSuspend(const std::string& url, const LLSD& body,
  338. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  339. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  340. LL_INLINE LLSD putAndSuspend(const std::string& url, const LLSD& body,
  341. LLCore::HttpHeaders::ptr_t headers)
  342. {
  343. return putAndSuspend(url, body, DEFAULT_HTTP_OPTIONS, headers);
  344. }
  345. LLSD putJsonAndSuspend(const std::string& url, const LLSD& body,
  346. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  347. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  348. LL_INLINE LLSD putJsonAndSuspend(const std::string& url, const LLSD& body,
  349. LLCore::HttpHeaders::ptr_t& headers)
  350. {
  351. return putJsonAndSuspend(url, body, DEFAULT_HTTP_OPTIONS, headers);
  352. }
  353. // Executes a Get transaction on the supplied URL and yield execution of
  354. // the coroutine until a result is available.
  355. LLSD getAndSuspend(const std::string& url,
  356. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  357. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  358. LL_INLINE LLSD getAndSuspend(const std::string& url,
  359. LLCore::HttpHeaders::ptr_t& headers)
  360. {
  361. return getAndSuspend(url, DEFAULT_HTTP_OPTIONS, headers);
  362. }
  363. LLSD getRawAndSuspend(const std::string& url,
  364. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  365. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  366. LL_INLINE LLSD getRawAndSuspend(const std::string& url,
  367. LLCore::HttpHeaders::ptr_t& headers)
  368. {
  369. return getRawAndSuspend(url, DEFAULT_HTTP_OPTIONS, headers);
  370. }
  371. // These methods have the same behavior as @getAndSuspend() however they
  372. // are expecting the server to return the results formatted in a JSON
  373. // string. On a successful GET call the JSON results will be converted into
  374. // LLSD before being returned to the caller.
  375. LLSD getJsonAndSuspend(const std::string& url,
  376. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  377. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  378. LL_INLINE LLSD getJsonAndSuspend(const std::string& url,
  379. LLCore::HttpHeaders::ptr_t& headers)
  380. {
  381. return getJsonAndSuspend(url, DEFAULT_HTTP_OPTIONS, headers);
  382. }
  383. // Executes a DELETE transaction on the supplied URL and yield execution of
  384. // the coroutine until a result is available.
  385. LLSD deleteAndSuspend(const std::string& url,
  386. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  387. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  388. LL_INLINE LLSD deleteAndSuspend(const std::string& url,
  389. LLCore::HttpHeaders::ptr_t headers)
  390. {
  391. return deleteAndSuspend(url, DEFAULT_HTTP_OPTIONS, headers);
  392. }
  393. // These methods have the same behavior as @deleteAndSuspend() however they
  394. // are expecting the server to return any results formatted in a JSON
  395. // string. On a successful DELETE call the JSON results will be converted
  396. // into LLSD before being returned to the caller.
  397. LLSD deleteJsonAndSuspend(const std::string& url,
  398. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  399. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  400. LL_INLINE LLSD deleteJsonAndSuspend(const std::string& url,
  401. LLCore::HttpHeaders::ptr_t headers)
  402. {
  403. return deleteJsonAndSuspend(url, DEFAULT_HTTP_OPTIONS, headers);
  404. }
  405. // Executes a PATCH transaction on the supplied URL and yield execution of
  406. // the coroutine until a result is available.
  407. LLSD patchAndSuspend(const std::string& url, const LLSD& body,
  408. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  409. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  410. LL_INLINE LLSD patchAndSuspend(const std::string& url, const LLSD& body,
  411. LLCore::HttpHeaders::ptr_t& headers)
  412. {
  413. return patchAndSuspend(url, body, DEFAULT_HTTP_OPTIONS, headers);
  414. }
  415. // Executes a COPY transaction on the supplied URL and yield execution of
  416. // the coroutine until a result is available.
  417. //
  418. // Note: the destination is passed through the HTTP pipe as a header. The
  419. // header used is defined as: HTTP_OUT_HEADER_DESTINATION("Destination");
  420. LLSD copyAndSuspend(const std::string& url, const std::string dest,
  421. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  422. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  423. LL_INLINE LLSD copyAndSuspend(const std::string& url,
  424. const std::string& dest,
  425. LLCore::HttpHeaders::ptr_t& headers)
  426. {
  427. return copyAndSuspend(url, dest, DEFAULT_HTTP_OPTIONS, headers);
  428. }
  429. // Executes a MOVE transaction on the supplied URL and yield execution of
  430. // the coroutine until a result is available.
  431. //
  432. // Note: the destination is passed through the HTTP pipe in the headers.
  433. // The header used is defined as:
  434. // HTTP_OUT_HEADER_DESTINATION("Destination");
  435. LLSD moveAndSuspend(const std::string& url, const std::string dest,
  436. LLCore::HttpOptions::ptr_t options = DEFAULT_HTTP_OPTIONS,
  437. LLCore::HttpHeaders::ptr_t headers = DEFAULT_HTTP_HEADERS);
  438. LL_INLINE LLSD moveAndSuspend(const std::string& url,
  439. const std::string& dest,
  440. LLCore::HttpHeaders::ptr_t& headers)
  441. {
  442. return moveAndSuspend(url, dest, DEFAULT_HTTP_OPTIONS, headers);
  443. }
  444. void cancelSuspendedOperation();
  445. static LLCore::HttpStatus getStatusFromLLSD(const LLSD& results);
  446. // The convenience routines below can be provided with callback functors.
  447. // which will be invoked in the case of success or failure. These callbacks
  448. // should match this form.
  449. // @sa callbackHttpGet
  450. // @sa callbackHttpPost
  451. typedef boost::function<void(const LLSD&)> completionCallback_t;
  452. static void callbackHttpGet(const std::string& url,
  453. LLCore::HttpRequest::policy_t policy_id,
  454. completionCallback_t success = NULL,
  455. completionCallback_t failure = NULL);
  456. LL_INLINE static void callbackHttpGet(const std::string& url,
  457. completionCallback_t success = NULL,
  458. completionCallback_t failure = NULL)
  459. {
  460. callbackHttpGet(url, LLCore::HttpRequest::DEFAULT_POLICY_ID, success,
  461. failure);
  462. }
  463. static void callbackHttpPost(const std::string& url,
  464. LLCore::HttpRequest::policy_t policy_id,
  465. const LLSD& postdata,
  466. completionCallback_t success = NULL,
  467. completionCallback_t failure = NULL);
  468. LL_INLINE static void callbackHttpPost(const std::string& url,
  469. const LLSD& postdata,
  470. completionCallback_t success = NULL,
  471. completionCallback_t failure = NULL)
  472. {
  473. callbackHttpPost(url, LLCore::HttpRequest::DEFAULT_POLICY_ID, postdata,
  474. success, failure);
  475. }
  476. // Generic Get and post routines for HTTP via coroutines. These static
  477. // methods do all required setup for the GET or POST operation. When the
  478. // operation completes successfully they will put the success message in
  479. // the log at INFO level, If the operation fails the failure message is
  480. // written to the log at WARN level.
  481. static void messageHttpGet(const std::string& url,
  482. const std::string& success = LLStringUtil::null,
  483. const std::string& failed = LLStringUtil::null);
  484. static void messageHttpPost(const std::string& url, const LLSD& postdata,
  485. const std::string& success,
  486. const std::string& failed);
  487. // Cancels all suspended operations.
  488. static void cleanup();
  489. private:
  490. LLSD buildImmediateErrorResult(const std::string& url);
  491. void saveState(const std::string& url,
  492. LLCore::HttpHandle yielding_handle,
  493. HttpCoroHandler::ptr_t& handler);
  494. void cleanState();
  495. LLSD postAndSuspend_(const std::string& url, const LLSD& body,
  496. LLCore::HttpOptions::ptr_t& options,
  497. LLCore::HttpHeaders::ptr_t& headers,
  498. HttpCoroHandler::ptr_t& handler);
  499. LLSD postAndSuspend_(const std::string& url,
  500. LLCore::BufferArray::ptr_t& rawbody,
  501. LLCore::HttpOptions::ptr_t& options,
  502. LLCore::HttpHeaders::ptr_t& headers,
  503. HttpCoroHandler::ptr_t& handler);
  504. LLSD putAndSuspend_(const std::string& url, const LLSD& body,
  505. LLCore::HttpOptions::ptr_t& options,
  506. LLCore::HttpHeaders::ptr_t& headers,
  507. HttpCoroHandler::ptr_t& handler);
  508. LLSD putAndSuspend_(const std::string& url,
  509. const LLCore::BufferArray::ptr_t& rawbody,
  510. LLCore::HttpOptions::ptr_t& options,
  511. LLCore::HttpHeaders::ptr_t& headers,
  512. HttpCoroHandler::ptr_t& handler);
  513. LLSD getAndSuspend_(const std::string& url,
  514. LLCore::HttpOptions::ptr_t& options,
  515. LLCore::HttpHeaders::ptr_t& headers,
  516. HttpCoroHandler::ptr_t& handler);
  517. LLSD deleteAndSuspend_(const std::string& url,
  518. LLCore::HttpOptions::ptr_t& options,
  519. LLCore::HttpHeaders::ptr_t& headers,
  520. HttpCoroHandler::ptr_t& handler);
  521. LLSD patchAndSuspend_(const std::string& url, const LLSD& body,
  522. LLCore::HttpOptions::ptr_t& options,
  523. LLCore::HttpHeaders::ptr_t& headers,
  524. HttpCoroHandler::ptr_t& handler);
  525. LLSD copyAndSuspend_(const std::string& url,
  526. LLCore::HttpOptions::ptr_t& options,
  527. LLCore::HttpHeaders::ptr_t& headers,
  528. HttpCoroHandler::ptr_t& handler);
  529. LLSD moveAndSuspend_(const std::string& url,
  530. LLCore::HttpOptions::ptr_t& options,
  531. LLCore::HttpHeaders::ptr_t& headers,
  532. HttpCoroHandler::ptr_t& handler);
  533. static void trivialGetCoro(std::string url,
  534. LLCore::HttpRequest::policy_t policy_id,
  535. completionCallback_t success,
  536. completionCallback_t failure);
  537. static void trivialPostCoro(std::string url,
  538. LLCore::HttpRequest::policy_t policy_id,
  539. LLSD postdata, completionCallback_t success,
  540. completionCallback_t failure);
  541. void checkDefaultHeaders(LLCore::HttpHeaders::ptr_t& headers);
  542. private:
  543. std::string mAdapterName;
  544. std::string mURL;
  545. LLCore::HttpRequest::policy_t mPolicyId;
  546. LLCore::HttpRequest::ptr_t mRequest;
  547. LLCore::HttpHandle mYieldingHandle;
  548. LLCore::HttpRequest::wptr_t mWeakRequest;
  549. HttpCoroHandler::wptr_t mWeakHandler;
  550. typedef fast_hset<HttpCoroutineAdapter*> instances_list_t;
  551. static instances_list_t sInstances;
  552. };
  553. } // End namespace LLCoreHttpUtil
  554. #endif // LL_LLCOREHTTPUTIL_H