summaryrefslogtreecommitdiff
path: root/indra/llmessage/llcurl.h
blob: 5335906b47d573941f6df47c799c9c92a1fe39a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
 * @file llcurl.h
 * @author Zero / Donovan
 * @date 2006-10-15
 * @brief Curl wrapper
 *
 * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
 * $License$
 */
 
#ifndef LL_LLCURL_H
#define LL_LLCURL_H

#include "linden_common.h"

#include <sstream>
#include <string>
#include <vector>

#include <boost/intrusive_ptr.hpp>
#include <curl/curl.h>

// #include "llhttpclient.h"

class LLCurl
{
public:
	class Multi;

	class Responder
	{
	public:
		Responder();
		virtual ~Responder();

		virtual void error(U32 status, const std::stringstream& content);	// called with bad status codes
		
		virtual void result(const std::stringstream& content);
		
		virtual void completed(U32 status, const std::stringstream& content);
			/**< The default implemetnation calls
				either:
				* result(), or
				* error() 
			*/
			
	public: /* but not really -- don't touch this */
		U32 mReferenceCount;
	};
	typedef boost::intrusive_ptr<Responder>	ResponderPtr;
	
	class Easy
	{
	public:
		Easy();
		~Easy();
		
		void get(const std::string& url, ResponderPtr);
		void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr);

		void perform();

	private:
		void prep(const std::string& url, ResponderPtr);
		void report(CURLcode);
		
		CURL*				mHandle;
		struct curl_slist*	mHeaders;
		
		std::string			mURL;
		std::string			mRange;
		std::stringstream	mRequest;

		std::stringstream	mOutput;
		char				mErrorBuffer[CURL_ERROR_SIZE];

		std::stringstream	mHeaderOutput; // Debug
		
		ResponderPtr		mResponder;

		friend class Multi;
	};


	class Multi
	{
	public:
		Multi();
		~Multi();

		void get(const std::string& url, ResponderPtr);
		void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr);

		void process();
		
	private:
		Easy* easyAlloc();
		void easyFree(Easy*);
		
		CURLM* mHandle;
		
		typedef std::vector<Easy*>	EasyList;
		EasyList mFreeEasy;
	};


	static void get(const std::string& url, ResponderPtr);
	static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder);
	
	static void process();
	static void cleanup();
};

namespace boost
{
	void intrusive_ptr_add_ref(LLCurl::Responder* p);
	void intrusive_ptr_release(LLCurl::Responder* p);
};

#endif // LL_LLCURL_H