xref: /haiku/src/kits/network/libnetservices/UrlRequest.cpp (revision e7e3b6c14af93058fc5aab68ffa695bbcdd77053)
1 /*
2  * Copyright 2010 Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Christophe Huriaux, c.huriaux@gmail.com
7  */
8 
9 
10 #include <UrlRequest.h>
11 #include <Debug.h>
12 #include <stdio.h>
13 
14 
15 #ifndef LIBNETAPI_DEPRECATED
16 using namespace BPrivate::Network;
17 #endif
18 
19 static BReference<BUrlContext> gDefaultContext = new(std::nothrow) BUrlContext();
20 
21 
22 #ifdef LIBNETAPI_DEPRECATED
23 BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener,
24 	BUrlContext* context, const char* threadName, const char* protocolName)
25 	:
26 	fUrl(url),
27 	fContext(context),
28 	fListener(listener),
29 	fQuit(false),
30 	fRunning(false),
31 	fThreadStatus(B_NO_INIT),
32 	fThreadId(0),
33 	fThreadName(threadName),
34 	fProtocol(protocolName)
35 {
36 	if (fContext == NULL)
37 		fContext = gDefaultContext;
38 }
39 
40 #else
41 
42 BUrlRequest::BUrlRequest(const BUrl& url, BDataIO* output,
43 	BUrlProtocolListener* listener, BUrlContext* context,
44 	const char* threadName, const char* protocolName)
45 	:
46 	fUrl(url),
47 	fContext(context),
48 	fListener(listener),
49 	fOutput(output),
50 	fQuit(false),
51 	fRunning(false),
52 	fThreadStatus(B_NO_INIT),
53 	fThreadId(0),
54 	fThreadName(threadName),
55 	fProtocol(protocolName)
56 {
57 	if (fContext == NULL)
58 		fContext = gDefaultContext;
59 }
60 #endif // LIBNETAPI_DEPRECATED
61 
62 
63 BUrlRequest::~BUrlRequest()
64 {
65 	Stop();
66 }
67 
68 
69 // #pragma mark URL protocol thread management
70 
71 
72 thread_id
73 BUrlRequest::Run()
74 {
75 	// Thread already running
76 	if (fRunning) {
77 		PRINT(("BUrlRequest::Run() : Oops, already running ! "
78 			"[urlProtocol=%p]!\n", this));
79 		return fThreadId;
80 	}
81 
82 	fThreadId = spawn_thread(BUrlRequest::_ThreadEntry, fThreadName,
83 		B_NORMAL_PRIORITY, this);
84 
85 	if (fThreadId < B_OK)
86 		return fThreadId;
87 
88 	fRunning = true;
89 
90 	status_t launchErr = resume_thread(fThreadId);
91 	if (launchErr < B_OK) {
92 		PRINT(("BUrlRequest::Run() : Failed to resume thread %" B_PRId32 "\n",
93 			fThreadId));
94 		return launchErr;
95 	}
96 
97 	return fThreadId;
98 }
99 
100 
101 status_t
102 BUrlRequest::Pause()
103 {
104 	// TODO
105 	return B_ERROR;
106 }
107 
108 
109 status_t
110 BUrlRequest::Resume()
111 {
112 	// TODO
113 	return B_ERROR;
114 }
115 
116 
117 status_t
118 BUrlRequest::Stop()
119 {
120 	if (!fRunning)
121 		return B_ERROR;
122 
123 	fQuit = true;
124 	return B_OK;
125 }
126 
127 
128 // #pragma mark URL protocol parameters modification
129 
130 
131 status_t
132 BUrlRequest::SetUrl(const BUrl& url)
133 {
134 	// We should avoid to change URL while the thread is running ...
135 	if (IsRunning())
136 		return B_ERROR;
137 
138 	fUrl = url;
139 	return B_OK;
140 }
141 
142 
143 status_t
144 BUrlRequest::SetContext(BUrlContext* context)
145 {
146 	if (IsRunning())
147 		return B_ERROR;
148 
149 	fContext = context;
150 	return B_OK;
151 }
152 
153 
154 status_t
155 BUrlRequest::SetListener(BUrlProtocolListener* listener)
156 {
157 	if (IsRunning())
158 		return B_ERROR;
159 
160 	fListener = listener;
161 	return B_OK;
162 }
163 
164 
165 #ifndef LIBNETAPI_DEPRECATED
166 status_t
167 BUrlRequest::SetOutput(BDataIO* output)
168 {
169 	if (IsRunning())
170 		return B_ERROR;
171 
172 	fOutput = output;
173 	return B_OK;
174 }
175 #endif
176 
177 
178 // #pragma mark URL protocol parameters access
179 
180 
181 const BUrl&
182 BUrlRequest::Url() const
183 {
184 	return fUrl;
185 }
186 
187 
188 BUrlContext*
189 BUrlRequest::Context() const
190 {
191 	return fContext;
192 }
193 
194 
195 BUrlProtocolListener*
196 BUrlRequest::Listener() const
197 {
198 	return fListener;
199 }
200 
201 
202 const BString&
203 BUrlRequest::Protocol() const
204 {
205 	return fProtocol;
206 }
207 
208 
209 #ifndef LIBNETAPI_DEPRECATED
210 BDataIO*
211 BUrlRequest::Output() const
212 {
213 	return fOutput;
214 }
215 #endif
216 
217 // #pragma mark URL protocol informations
218 
219 
220 bool
221 BUrlRequest::IsRunning() const
222 {
223 	return fRunning;
224 }
225 
226 
227 status_t
228 BUrlRequest::Status() const
229 {
230 	return fThreadStatus;
231 }
232 
233 
234 // #pragma mark Thread management
235 
236 
237 /*static*/ int32
238 BUrlRequest::_ThreadEntry(void* arg)
239 {
240 	BUrlRequest* request = reinterpret_cast<BUrlRequest*>(arg);
241 	request->fThreadStatus = B_BUSY;
242 	request->_ProtocolSetup();
243 
244 	status_t protocolLoopExitStatus = request->_ProtocolLoop();
245 
246 	request->fRunning = false;
247 	request->fThreadStatus = protocolLoopExitStatus;
248 
249 	if (request->fListener != NULL) {
250 		request->fListener->RequestCompleted(request,
251 			protocolLoopExitStatus == B_OK);
252 	}
253 
254 	return B_OK;
255 }
256 
257 
258 void
259 BUrlRequest::_EmitDebug(BUrlProtocolDebugMessage type,
260 	const char* format, ...)
261 {
262 	if (fListener == NULL)
263 		return;
264 
265 	va_list arguments;
266 	va_start(arguments, format);
267 
268 	char debugMsg[1024];
269 	vsnprintf(debugMsg, sizeof(debugMsg), format, arguments);
270 	fListener->DebugMessage(this, type, debugMsg);
271 	va_end(arguments);
272 }
273