PageRenderTime 80ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmessage/llurlrequest.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 382 lines | 124 code | 52 blank | 206 comment | 0 complexity | c2126a99c6df045d95843faa8c3e4a11 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llurlrequest.h
  3. * @author Phoenix
  4. * @date 2005-04-21
  5. * @brief Declaration of url based requests on pipes.
  6. *
  7. * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #ifndef LL_LLURLREQUEST_H
  29. #define LL_LLURLREQUEST_H
  30. /**
  31. * This file holds the declaration of useful classes for dealing with
  32. * url based client requests.
  33. */
  34. #include <string>
  35. #include "lliopipe.h"
  36. #include "llchainio.h"
  37. #include "llerror.h"
  38. #include <openssl/x509_vfy.h>
  39. #include "llcurl.h"
  40. extern const std::string CONTEXT_REQUEST;
  41. extern const std::string CONTEXT_DEST_URI_SD_LABEL;
  42. extern const std::string CONTEXT_RESPONSE;
  43. extern const std::string CONTEXT_TRANSFERED_BYTES;
  44. class LLURLRequestDetail;
  45. class LLURLRequestComplete;
  46. /**
  47. * @class LLURLRequest
  48. * @brief Class to handle url based requests.
  49. * @see LLIOPipe
  50. *
  51. * Currently, this class is implemented on top of curl. From the
  52. * vantage of a programmer using this class, you do not care so much,
  53. * but it's useful to know since in order to accomplish 'non-blocking'
  54. * behavior, we have to use a more expensive curl interface which can
  55. * still block if the server enters a half-accepted state. It would be
  56. * worth the time and effort to eventually port this to a raw client
  57. * socket.
  58. */
  59. class LLURLRequest : public LLIOPipe
  60. {
  61. LOG_CLASS(LLURLRequest);
  62. public:
  63. typedef int (* SSLCertVerifyCallback)(X509_STORE_CTX *ctx, void *param);
  64. /**
  65. * @brief This enumeration is for specifying the type of request.
  66. */
  67. enum ERequestAction
  68. {
  69. INVALID,
  70. HTTP_HEAD,
  71. HTTP_GET,
  72. HTTP_PUT,
  73. HTTP_POST,
  74. HTTP_DELETE,
  75. HTTP_MOVE, // Caller will need to set 'Destination' header
  76. REQUEST_ACTION_COUNT
  77. };
  78. /**
  79. * @brief Turn the requst action into an http verb.
  80. */
  81. static std::string actionAsVerb(ERequestAction action);
  82. /**
  83. * @brief Constructor.
  84. *
  85. * @param action One of the ERequestAction enumerations.
  86. */
  87. LLURLRequest(ERequestAction action);
  88. /**
  89. * @brief Constructor.
  90. *
  91. * @param action One of the ERequestAction enumerations.
  92. * @param url The url of the request. It should already be encoded.
  93. */
  94. LLURLRequest(ERequestAction action, const std::string& url);
  95. /**
  96. * @brief Destructor.
  97. */
  98. virtual ~LLURLRequest();
  99. /* @name Instance methods
  100. */
  101. //@{
  102. /**
  103. * @brief Set the url for the request
  104. *
  105. * This method assumes the url is encoded appropriately for the
  106. * request.
  107. * The url must be set somehow before the first call to process(),
  108. * or the url will not be set correctly.
  109. *
  110. */
  111. void setURL(const std::string& url);
  112. std::string getURL() const;
  113. /**
  114. * @brief Add a header to the http post.
  115. *
  116. * The header must be correctly formatted for HTTP requests. This
  117. * provides a raw interface if you know what kind of request you
  118. * will be making during construction of this instance. All
  119. * required headers will be automatically constructed, so this is
  120. * usually useful for encoding parameters.
  121. */
  122. void addHeader(const char* header);
  123. /**
  124. * @brief Check remote server certificate signed by a known root CA.
  125. *
  126. * Set whether request will check that remote server
  127. * certificates are signed by a known root CA when using HTTPS.
  128. */
  129. void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param);
  130. /**
  131. * @brief Return at most size bytes of body.
  132. *
  133. * If the body had more bytes than this limit, they will not be
  134. * returned and the connection closed. In this case, STATUS_STOP
  135. * will be passed to responseStatus();
  136. */
  137. void setBodyLimit(U32 size);
  138. /**
  139. * @brief Set a completion callback for this URLRequest.
  140. *
  141. * The callback is added to this URLRequet's pump when either the
  142. * entire buffer is known or an error like timeout or connection
  143. * refused has happened. In the case of a complete transfer, this
  144. * object builds a response chain such that the callback and the
  145. * next process consumer get to read the output.
  146. *
  147. * This setup is a little fragile since the url request consumer
  148. * might not just read the data - it may do a channel change,
  149. * which invalidates the input to the callback, but it works well
  150. * in practice.
  151. */
  152. void setCallback(LLURLRequestComplete* callback);
  153. //@}
  154. /* @name LLIOPipe virtual implementations
  155. */
  156. /**
  157. * @ brief Turn off (or on) the CURLOPT_PROXY header.
  158. */
  159. void useProxy(bool use_proxy);
  160. /**
  161. * @ brief Set the CURLOPT_PROXY header to the given value.
  162. */
  163. void useProxy(const std::string& proxy);
  164. /**
  165. * @brief Turn on cookie handling for this request with CURLOPT_COOKIEFILE.
  166. */
  167. void allowCookies();
  168. /*virtual*/ bool isValid() ;
  169. public:
  170. /**
  171. * @brief Give this pipe a chance to handle a generated error
  172. */
  173. virtual EStatus handleError(EStatus status, LLPumpIO* pump);
  174. protected:
  175. /**
  176. * @brief Process the data in buffer
  177. */
  178. virtual EStatus process_impl(
  179. const LLChannelDescriptors& channels,
  180. buffer_ptr_t& buffer,
  181. bool& eos,
  182. LLSD& context,
  183. LLPumpIO* pump);
  184. //@}
  185. protected:
  186. enum EState
  187. {
  188. STATE_INITIALIZED,
  189. STATE_WAITING_FOR_RESPONSE,
  190. STATE_PROCESSING_RESPONSE,
  191. STATE_HAVE_RESPONSE,
  192. };
  193. EState mState;
  194. ERequestAction mAction;
  195. LLURLRequestDetail* mDetail;
  196. LLIOPipe::ptr_t mCompletionCallback;
  197. S32 mRequestTransferedBytes;
  198. S32 mResponseTransferedBytes;
  199. static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
  200. private:
  201. /**
  202. * @brief Initialize the object. Called during construction.
  203. */
  204. void initialize();
  205. /**
  206. * @brief Handle action specific url request configuration.
  207. *
  208. * @return Returns true if this is configured.
  209. */
  210. bool configure();
  211. /**
  212. * @brief Download callback method.
  213. */
  214. static size_t downCallback(
  215. char* data,
  216. size_t size,
  217. size_t nmemb,
  218. void* user);
  219. /**
  220. * @brief Upload callback method.
  221. */
  222. static size_t upCallback(
  223. char* data,
  224. size_t size,
  225. size_t nmemb,
  226. void* user);
  227. /**
  228. * @brief Declaration of unimplemented method to prevent copy
  229. * construction.
  230. */
  231. LLURLRequest(const LLURLRequest&);
  232. };
  233. /**
  234. * @class LLContextURLExtractor
  235. * @brief This class unpacks the url out of a agent usher service so
  236. * it can be packed into a LLURLRequest object.
  237. * @see LLIOPipe
  238. *
  239. * This class assumes that the context is a map that contains an entry
  240. * named CONTEXT_DEST_URI_SD_LABEL.
  241. */
  242. class LLContextURLExtractor : public LLIOPipe
  243. {
  244. public:
  245. LLContextURLExtractor(LLURLRequest* req) : mRequest(req) {}
  246. ~LLContextURLExtractor() {}
  247. protected:
  248. /* @name LLIOPipe virtual implementations
  249. */
  250. //@{
  251. /**
  252. * @brief Process the data in buffer
  253. */
  254. virtual EStatus process_impl(
  255. const LLChannelDescriptors& channels,
  256. buffer_ptr_t& buffer,
  257. bool& eos,
  258. LLSD& context,
  259. LLPumpIO* pump);
  260. //@}
  261. protected:
  262. LLURLRequest* mRequest;
  263. };
  264. /**
  265. * @class LLURLRequestComplete
  266. * @brief Class which can optionally be used with an LLURLRequest to
  267. * get notification when the url request is complete.
  268. */
  269. class LLURLRequestComplete : public LLIOPipe
  270. {
  271. public:
  272. // Called once for each header received, except status lines
  273. virtual void header(const std::string& header, const std::string& value);
  274. // May be called more than once, particularly for redirects and proxy madness.
  275. // Ex. a 200 for a connection to https through a proxy, followed by the "real" status
  276. // a 3xx for a redirect followed by a "real" status, or more redirects.
  277. virtual void httpStatus(U32 status, const std::string& reason) { }
  278. virtual void complete(
  279. const LLChannelDescriptors& channels,
  280. const buffer_ptr_t& buffer);
  281. /**
  282. * @brief This method is called when we got a valid response.
  283. *
  284. * It is up to class implementers to do something useful here.
  285. */
  286. virtual void response(
  287. const LLChannelDescriptors& channels,
  288. const buffer_ptr_t& buffer);
  289. /**
  290. * @brief This method is called if there was no response.
  291. *
  292. * It is up to class implementers to do something useful here.
  293. */
  294. virtual void noResponse();
  295. /**
  296. * @brief This method will be called by the LLURLRequest object.
  297. *
  298. * If this is set to STATUS_OK or STATUS_STOP, then the transfer
  299. * is asssumed to have worked. This will lead to calling response()
  300. * on the next call to process(). Otherwise, this object will call
  301. * noResponse() on the next call to process.
  302. * @param status The status of the URLRequest.
  303. */
  304. void responseStatus(EStatus status);
  305. // constructor & destructor.
  306. LLURLRequestComplete();
  307. virtual ~LLURLRequestComplete();
  308. protected:
  309. /* @name LLIOPipe virtual implementations
  310. */
  311. //@{
  312. /**
  313. * @brief Process the data in buffer
  314. */
  315. virtual EStatus process_impl(
  316. const LLChannelDescriptors& channels,
  317. buffer_ptr_t& buffer,
  318. bool& eos,
  319. LLSD& context,
  320. LLPumpIO* pump);
  321. //@}
  322. // value to note if we actually got the response. This value
  323. // depends on correct useage from the LLURLRequest instance.
  324. EStatus mRequestStatus;
  325. };
  326. /**
  327. * External constants
  328. */
  329. extern const std::string CONTEXT_DEST_URI_SD_LABEL;
  330. #endif // LL_LLURLREQUEST_H