xref: /haiku/src/kits/network/libnetservices/UrlRequest.cpp (revision 895e0c8a3260907dd12f7bd6e44d7c8846ae7951)
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::Stop()
103 {
104 	if (!fRunning)
105 		return B_ERROR;
106 
107 	fQuit = true;
108 	return B_OK;
109 }
110 
111 
112 #ifdef LIBNETAPI_DEPRECATED
113 status_t
114 BUrlRequest::Pause()
115 {
116 	return B_ERROR;
117 }
118 
119 
120 status_t
121 BUrlRequest::Resume()
122 {
123 	return B_ERROR;
124 }
125 #endif
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 	if (context == NULL)
150 		fContext = gDefaultContext;
151 	else
152 		fContext = context;
153 
154 	return B_OK;
155 }
156 
157 
158 status_t
159 BUrlRequest::SetListener(BUrlProtocolListener* listener)
160 {
161 	if (IsRunning())
162 		return B_ERROR;
163 
164 	fListener = listener;
165 	return B_OK;
166 }
167 
168 
169 #ifndef LIBNETAPI_DEPRECATED
170 status_t
171 BUrlRequest::SetOutput(BDataIO* output)
172 {
173 	if (IsRunning())
174 		return B_ERROR;
175 
176 	fOutput = output;
177 	return B_OK;
178 }
179 #endif
180 
181 
182 // #pragma mark URL protocol parameters access
183 
184 
185 const BUrl&
186 BUrlRequest::Url() const
187 {
188 	return fUrl;
189 }
190 
191 
192 BUrlContext*
193 BUrlRequest::Context() const
194 {
195 	return fContext;
196 }
197 
198 
199 BUrlProtocolListener*
200 BUrlRequest::Listener() const
201 {
202 	return fListener;
203 }
204 
205 
206 const BString&
207 BUrlRequest::Protocol() const
208 {
209 	return fProtocol;
210 }
211 
212 
213 #ifndef LIBNETAPI_DEPRECATED
214 BDataIO*
215 BUrlRequest::Output() const
216 {
217 	return fOutput;
218 }
219 #endif
220 
221 // #pragma mark URL protocol informations
222 
223 
224 bool
225 BUrlRequest::IsRunning() const
226 {
227 	return fRunning;
228 }
229 
230 
231 status_t
232 BUrlRequest::Status() const
233 {
234 	return fThreadStatus;
235 }
236 
237 
238 // #pragma mark Thread management
239 
240 
241 /*static*/ int32
242 BUrlRequest::_ThreadEntry(void* arg)
243 {
244 	BUrlRequest* request = reinterpret_cast<BUrlRequest*>(arg);
245 	request->fThreadStatus = B_BUSY;
246 	request->_ProtocolSetup();
247 
248 	status_t protocolLoopExitStatus = request->_ProtocolLoop();
249 
250 	request->fRunning = false;
251 	request->fThreadStatus = protocolLoopExitStatus;
252 
253 	if (request->fListener != NULL) {
254 		request->fListener->RequestCompleted(request,
255 			protocolLoopExitStatus == B_OK);
256 	}
257 
258 	return B_OK;
259 }
260 
261 
262 void
263 BUrlRequest::_EmitDebug(BUrlProtocolDebugMessage type,
264 	const char* format, ...)
265 {
266 	if (fListener == NULL)
267 		return;
268 
269 	va_list arguments;
270 	va_start(arguments, format);
271 
272 	char debugMsg[1024];
273 	vsnprintf(debugMsg, sizeof(debugMsg), format, arguments);
274 	fListener->DebugMessage(this, type, debugMsg);
275 	va_end(arguments);
276 }
277