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