xref: /haiku/src/kits/network/libnetservices/UrlRequest.cpp (revision acdafb571df692fab7ad89836e39590dd8d415e2)
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 BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener,
23 	BUrlContext* context, const char* threadName, const char* protocolName)
24 	:
25 	fUrl(url),
26 	fContext(context),
27 	fListener(listener),
28 	fQuit(false),
29 	fRunning(false),
30 	fThreadStatus(B_NO_INIT),
31 	fThreadId(0),
32 	fThreadName(threadName),
33 	fProtocol(protocolName)
34 {
35 	if (fContext == NULL)
36 		fContext = gDefaultContext;
37 }
38 
39 
40 BUrlRequest::~BUrlRequest()
41 {
42 	Stop();
43 }
44 
45 
46 // #pragma mark URL protocol thread management
47 
48 
49 thread_id
50 BUrlRequest::Run()
51 {
52 	// Thread already running
53 	if (fRunning) {
54 		PRINT(("BUrlRequest::Run() : Oops, already running ! "
55 			"[urlProtocol=%p]!\n", this));
56 		return fThreadId;
57 	}
58 
59 	fThreadId = spawn_thread(BUrlRequest::_ThreadEntry, fThreadName,
60 		B_NORMAL_PRIORITY, this);
61 
62 	if (fThreadId < B_OK)
63 		return fThreadId;
64 
65 	fRunning = true;
66 
67 	status_t launchErr = resume_thread(fThreadId);
68 	if (launchErr < B_OK) {
69 		PRINT(("BUrlRequest::Run() : Failed to resume thread %" B_PRId32 "\n",
70 			fThreadId));
71 		return launchErr;
72 	}
73 
74 	return fThreadId;
75 }
76 
77 
78 status_t
79 BUrlRequest::Pause()
80 {
81 	// TODO
82 	return B_ERROR;
83 }
84 
85 
86 status_t
87 BUrlRequest::Resume()
88 {
89 	// TODO
90 	return B_ERROR;
91 }
92 
93 
94 status_t
95 BUrlRequest::Stop()
96 {
97 	if (!fRunning)
98 		return B_ERROR;
99 
100 	fQuit = true;
101 	return B_OK;
102 }
103 
104 
105 // #pragma mark URL protocol parameters modification
106 
107 
108 status_t
109 BUrlRequest::SetUrl(const BUrl& url)
110 {
111 	// We should avoid to change URL while the thread is running ...
112 	if (IsRunning())
113 		return B_ERROR;
114 
115 	fUrl = url;
116 	return B_OK;
117 }
118 
119 
120 status_t
121 BUrlRequest::SetContext(BUrlContext* context)
122 {
123 	if (IsRunning())
124 		return B_ERROR;
125 
126 	fContext = context;
127 	return B_OK;
128 }
129 
130 
131 status_t
132 BUrlRequest::SetListener(BUrlProtocolListener* listener)
133 {
134 	if (IsRunning())
135 		return B_ERROR;
136 
137 	fListener = listener;
138 	return B_OK;
139 }
140 
141 
142 // #pragma mark URL protocol parameters access
143 
144 
145 const BUrl&
146 BUrlRequest::Url() const
147 {
148 	return fUrl;
149 }
150 
151 
152 BUrlContext*
153 BUrlRequest::Context() const
154 {
155 	return fContext;
156 }
157 
158 
159 BUrlProtocolListener*
160 BUrlRequest::Listener() const
161 {
162 	return fListener;
163 }
164 
165 
166 const BString&
167 BUrlRequest::Protocol() const
168 {
169 	return fProtocol;
170 }
171 
172 
173 // #pragma mark URL protocol informations
174 
175 
176 bool
177 BUrlRequest::IsRunning() const
178 {
179 	return fRunning;
180 }
181 
182 
183 status_t
184 BUrlRequest::Status() const
185 {
186 	return fThreadStatus;
187 }
188 
189 
190 // #pragma mark Thread management
191 
192 
193 /*static*/ int32
194 BUrlRequest::_ThreadEntry(void* arg)
195 {
196 	BUrlRequest* request = reinterpret_cast<BUrlRequest*>(arg);
197 	request->fThreadStatus = B_BUSY;
198 	request->_ProtocolSetup();
199 
200 	status_t protocolLoopExitStatus = request->_ProtocolLoop();
201 
202 	request->fRunning = false;
203 	request->fThreadStatus = protocolLoopExitStatus;
204 
205 	if (request->fListener != NULL) {
206 		request->fListener->RequestCompleted(request,
207 			protocolLoopExitStatus == B_OK);
208 	}
209 
210 	return B_OK;
211 }
212 
213 
214 void
215 BUrlRequest::_EmitDebug(BUrlProtocolDebugMessage type,
216 	const char* format, ...)
217 {
218 	if (fListener == NULL)
219 		return;
220 
221 	va_list arguments;
222 	va_start(arguments, format);
223 
224 	char debugMsg[1024];
225 	vsnprintf(debugMsg, sizeof(debugMsg), format, arguments);
226 	fListener->DebugMessage(this, type, debugMsg);
227 	va_end(arguments);
228 }
229