1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ChromiumHTTPDataSourceSupport" 19 #include <utils/Log.h> 20 21 #include <media/stagefright/foundation/AString.h> 22 23 #include "support.h" 24 25 #include "android/net/android_network_library_impl.h" 26 #include "base/logging.h" 27 #include "base/threading/thread.h" 28 #include "net/base/cert_verifier.h" 29 #include "net/base/cookie_monster.h" 30 #include "net/base/host_resolver.h" 31 #include "net/base/ssl_config_service.h" 32 #include "net/http/http_auth_handler_factory.h" 33 #include "net/http/http_cache.h" 34 #include "net/proxy/proxy_config_service_android.h" 35 36 #include "include/ChromiumHTTPDataSource.h" 37 38 #include <cutils/log.h> 39 #include <cutils/properties.h> 40 #include <media/stagefright/MediaErrors.h> 41 #include <string> 42 43 namespace android { 44 45 static Mutex gNetworkThreadLock; 46 static base::Thread *gNetworkThread = NULL; 47 static scoped_refptr<net::URLRequestContext> gReqContext; 48 static scoped_ptr<net::NetworkChangeNotifier> gNetworkChangeNotifier; 49 50 bool logMessageHandler( 51 int severity, 52 const char* file, 53 int line, 54 size_t message_start, 55 const std::string& str) { 56 int androidSeverity = ANDROID_LOG_VERBOSE; 57 switch(severity) { 58 case logging::LOG_FATAL: 59 androidSeverity = ANDROID_LOG_FATAL; 60 break; 61 case logging::LOG_ERROR_REPORT: 62 case logging::LOG_ERROR: 63 androidSeverity = ANDROID_LOG_ERROR; 64 break; 65 case logging::LOG_WARNING: 66 androidSeverity = ANDROID_LOG_WARN; 67 break; 68 default: 69 androidSeverity = ANDROID_LOG_VERBOSE; 70 break; 71 } 72 android_printLog(androidSeverity, "chromium-libstagefright", 73 "%s:%d: %s", file, line, str.c_str()); 74 return false; 75 } 76 77 struct AutoPrioritySaver { 78 AutoPrioritySaver() 79 : mTID(androidGetTid()), 80 mPrevPriority(androidGetThreadPriority(mTID)) { 81 androidSetThreadPriority(mTID, ANDROID_PRIORITY_NORMAL); 82 } 83 84 ~AutoPrioritySaver() { 85 androidSetThreadPriority(mTID, mPrevPriority); 86 } 87 88 private: 89 pid_t mTID; 90 int mPrevPriority; 91 92 DISALLOW_EVIL_CONSTRUCTORS(AutoPrioritySaver); 93 }; 94 95 static void InitializeNetworkThreadIfNecessary() { 96 Mutex::Autolock autoLock(gNetworkThreadLock); 97 98 if (gNetworkThread == NULL) { 99 // Make sure any threads spawned by the chromium framework are 100 // running at normal priority instead of inheriting this thread's. 101 AutoPrioritySaver saver; 102 103 gNetworkThread = new base::Thread("network"); 104 base::Thread::Options options; 105 options.message_loop_type = MessageLoop::TYPE_IO; 106 CHECK(gNetworkThread->StartWithOptions(options)); 107 108 gReqContext = new SfRequestContext; 109 110 gNetworkChangeNotifier.reset(net::NetworkChangeNotifier::Create()); 111 112 net::AndroidNetworkLibrary::RegisterSharedInstance( 113 new SfNetworkLibrary); 114 logging::SetLogMessageHandler(logMessageHandler); 115 } 116 } 117 118 static void MY_LOGI(const char *s) { 119 LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s); 120 } 121 122 static void MY_LOGV(const char *s) { 123 #if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0 124 LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s); 125 #endif 126 } 127 128 SfNetLog::SfNetLog() 129 : mNextID(1) { 130 } 131 132 void SfNetLog::AddEntry( 133 EventType type, 134 const base::TimeTicks &time, 135 const Source &source, 136 EventPhase phase, 137 EventParameters *params) { 138 #if 0 139 MY_LOGI(StringPrintf( 140 "AddEntry time=%s type=%s source=%s phase=%s\n", 141 TickCountToString(time).c_str(), 142 EventTypeToString(type), 143 SourceTypeToString(source.type), 144 EventPhaseToString(phase)).c_str()); 145 #endif 146 } 147 148 uint32 SfNetLog::NextID() { 149 return mNextID++; 150 } 151 152 net::NetLog::LogLevel SfNetLog::GetLogLevel() const { 153 return LOG_ALL; 154 } 155 156 //////////////////////////////////////////////////////////////////////////////// 157 158 SfRequestContext::SfRequestContext() { 159 AString ua; 160 ua.append("stagefright/1.2 (Linux;Android "); 161 162 #if (PROPERTY_VALUE_MAX < 8) 163 #error "PROPERTY_VALUE_MAX must be at least 8" 164 #endif 165 166 char value[PROPERTY_VALUE_MAX]; 167 property_get("ro.build.version.release", value, "Unknown"); 168 ua.append(value); 169 ua.append(")"); 170 171 mUserAgent = ua.c_str(); 172 173 set_net_log(new SfNetLog()); 174 175 set_host_resolver( 176 net::CreateSystemHostResolver( 177 net::HostResolver::kDefaultParallelism, 178 NULL /* resolver_proc */, 179 net_log())); 180 181 set_ssl_config_service( 182 net::SSLConfigService::CreateSystemSSLConfigService()); 183 184 set_proxy_service(net::ProxyService::CreateWithoutProxyResolver( 185 new net::ProxyConfigServiceAndroid, net_log())); 186 187 set_http_transaction_factory(new net::HttpCache( 188 host_resolver(), 189 new net::CertVerifier(), 190 dnsrr_resolver(), 191 dns_cert_checker(), 192 proxy_service(), 193 ssl_config_service(), 194 net::HttpAuthHandlerFactory::CreateDefault(host_resolver()), 195 network_delegate(), 196 net_log(), 197 NULL)); // backend_factory 198 199 set_cookie_store(new net::CookieMonster(NULL, NULL)); 200 } 201 202 const std::string &SfRequestContext::GetUserAgent(const GURL &url) const { 203 return mUserAgent; 204 } 205 206 //////////////////////////////////////////////////////////////////////////////// 207 208 SfNetworkLibrary::SfNetworkLibrary() {} 209 210 SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain( 211 const std::vector<std::string>& cert_chain, 212 const std::string& hostname, 213 const std::string& auth_type) { 214 return VERIFY_OK; 215 } 216 217 //////////////////////////////////////////////////////////////////////////////// 218 219 SfDelegate::SfDelegate() 220 : mOwner(NULL), 221 mURLRequest(NULL), 222 mReadBuffer(new net::IOBufferWithSize(8192)), 223 mNumBytesRead(0), 224 mNumBytesTotal(0), 225 mDataDestination(NULL), 226 mAtEOS(false) { 227 InitializeNetworkThreadIfNecessary(); 228 } 229 230 SfDelegate::~SfDelegate() { 231 CHECK(mURLRequest == NULL); 232 } 233 234 void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) { 235 mOwner = owner; 236 } 237 238 void SfDelegate::setUID(uid_t uid) { 239 gReqContext->setUID(uid); 240 } 241 242 bool SfDelegate::getUID(uid_t *uid) const { 243 return gReqContext->getUID(uid); 244 } 245 246 void SfDelegate::OnReceivedRedirect( 247 net::URLRequest *request, const GURL &new_url, bool *defer_redirect) { 248 MY_LOGV("OnReceivedRedirect"); 249 } 250 251 void SfDelegate::OnAuthRequired( 252 net::URLRequest *request, net::AuthChallengeInfo *auth_info) { 253 MY_LOGV("OnAuthRequired"); 254 255 inherited::OnAuthRequired(request, auth_info); 256 } 257 258 void SfDelegate::OnCertificateRequested( 259 net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) { 260 MY_LOGV("OnCertificateRequested"); 261 262 inherited::OnCertificateRequested(request, cert_request_info); 263 } 264 265 void SfDelegate::OnSSLCertificateError( 266 net::URLRequest *request, int cert_error, net::X509Certificate *cert) { 267 fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error); 268 269 inherited::OnSSLCertificateError(request, cert_error, cert); 270 } 271 272 void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) { 273 MY_LOGV("OnGetCookies"); 274 } 275 276 void SfDelegate::OnSetCookie( 277 net::URLRequest *request, 278 const std::string &cookie_line, 279 const net::CookieOptions &options, 280 bool blocked_by_policy) { 281 MY_LOGV("OnSetCookie"); 282 } 283 284 void SfDelegate::OnResponseStarted(net::URLRequest *request) { 285 if (request->status().status() != net::URLRequestStatus::SUCCESS) { 286 MY_LOGI(StringPrintf( 287 "Request failed with status %d and os_error %d", 288 request->status().status(), 289 request->status().os_error()).c_str()); 290 291 delete mURLRequest; 292 mURLRequest = NULL; 293 294 mOwner->onConnectionFailed(ERROR_IO); 295 return; 296 } else if (mRangeRequested && request->GetResponseCode() != 206) { 297 MY_LOGI(StringPrintf( 298 "We requested a content range, but server didn't " 299 "support that. (responded with %d)", 300 request->GetResponseCode()).c_str()); 301 302 delete mURLRequest; 303 mURLRequest = NULL; 304 305 mOwner->onConnectionFailed(-EPIPE); 306 return; 307 } else if ((request->GetResponseCode() / 100) != 2) { 308 MY_LOGI(StringPrintf( 309 "Server responded with http status %d", 310 request->GetResponseCode()).c_str()); 311 312 delete mURLRequest; 313 mURLRequest = NULL; 314 315 mOwner->onConnectionFailed(ERROR_IO); 316 return; 317 } 318 319 MY_LOGV("OnResponseStarted"); 320 321 std::string headers; 322 request->GetAllResponseHeaders(&headers); 323 324 MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str()); 325 326 std::string contentType; 327 request->GetResponseHeaderByName("Content-Type", &contentType); 328 329 mOwner->onConnectionEstablished( 330 request->GetExpectedContentSize(), contentType.c_str()); 331 } 332 333 void SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) { 334 if (bytes_read == -1) { 335 MY_LOGI(StringPrintf( 336 "OnReadCompleted, read failed, status %d", 337 request->status().status()).c_str()); 338 339 mOwner->onReadCompleted(ERROR_IO); 340 return; 341 } 342 343 MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str()); 344 345 if (bytes_read < 0) { 346 MY_LOGI(StringPrintf( 347 "Read failed w/ status %d\n", 348 request->status().status()).c_str()); 349 350 mOwner->onReadCompleted(ERROR_IO); 351 return; 352 } else if (bytes_read == 0) { 353 mAtEOS = true; 354 mOwner->onReadCompleted(mNumBytesRead); 355 return; 356 } 357 358 CHECK_GT(bytes_read, 0); 359 CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal); 360 361 memcpy((uint8_t *)mDataDestination + mNumBytesRead, 362 mReadBuffer->data(), 363 bytes_read); 364 365 mNumBytesRead += bytes_read; 366 367 readMore(request); 368 } 369 370 void SfDelegate::readMore(net::URLRequest *request) { 371 while (mNumBytesRead < mNumBytesTotal) { 372 size_t copy = mNumBytesTotal - mNumBytesRead; 373 if (copy > mReadBuffer->size()) { 374 copy = mReadBuffer->size(); 375 } 376 377 int n; 378 if (request->Read(mReadBuffer, copy, &n)) { 379 MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str()); 380 381 CHECK_LE((size_t)n, copy); 382 383 memcpy((uint8_t *)mDataDestination + mNumBytesRead, 384 mReadBuffer->data(), 385 n); 386 387 mNumBytesRead += n; 388 389 if (n == 0) { 390 mAtEOS = true; 391 break; 392 } 393 } else { 394 MY_LOGV("readMore pending read"); 395 396 if (request->status().status() != net::URLRequestStatus::IO_PENDING) { 397 MY_LOGI(StringPrintf( 398 "Direct read failed w/ status %d\n", 399 request->status().status()).c_str()); 400 401 mOwner->onReadCompleted(ERROR_IO); 402 return; 403 } 404 405 return; 406 } 407 } 408 409 mOwner->onReadCompleted(mNumBytesRead); 410 } 411 412 void SfDelegate::initiateConnection( 413 const char *uri, 414 const KeyedVector<String8, String8> *headers, 415 off64_t offset) { 416 GURL url(uri); 417 418 MessageLoop *loop = gNetworkThread->message_loop(); 419 loop->PostTask( 420 FROM_HERE, 421 NewRunnableFunction( 422 &SfDelegate::OnInitiateConnectionWrapper, 423 this, 424 url, 425 headers, 426 offset)); 427 428 } 429 430 // static 431 void SfDelegate::OnInitiateConnectionWrapper( 432 SfDelegate *me, GURL url, 433 const KeyedVector<String8, String8> *headers, 434 off64_t offset) { 435 me->onInitiateConnection(url, headers, offset); 436 } 437 438 void SfDelegate::onInitiateConnection( 439 const GURL &url, 440 const KeyedVector<String8, String8> *extra, 441 off64_t offset) { 442 CHECK(mURLRequest == NULL); 443 444 mURLRequest = new net::URLRequest(url, this); 445 mAtEOS = false; 446 447 mRangeRequested = false; 448 449 if (offset != 0 || extra != NULL) { 450 net::HttpRequestHeaders headers = 451 mURLRequest->extra_request_headers(); 452 453 if (offset != 0) { 454 headers.AddHeaderFromString( 455 StringPrintf("Range: bytes=%lld-", offset).c_str()); 456 457 mRangeRequested = true; 458 } 459 460 if (extra != NULL) { 461 for (size_t i = 0; i < extra->size(); ++i) { 462 AString s; 463 s.append(extra->keyAt(i).string()); 464 s.append(": "); 465 s.append(extra->valueAt(i).string()); 466 467 headers.AddHeaderFromString(s.c_str()); 468 } 469 } 470 471 mURLRequest->SetExtraRequestHeaders(headers); 472 } 473 474 mURLRequest->set_context(gReqContext); 475 476 mURLRequest->Start(); 477 } 478 479 void SfDelegate::initiateDisconnect() { 480 MessageLoop *loop = gNetworkThread->message_loop(); 481 loop->PostTask( 482 FROM_HERE, 483 NewRunnableFunction( 484 &SfDelegate::OnInitiateDisconnectWrapper, this)); 485 } 486 487 // static 488 void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) { 489 me->onInitiateDisconnect(); 490 } 491 492 void SfDelegate::onInitiateDisconnect() { 493 mURLRequest->Cancel(); 494 495 delete mURLRequest; 496 mURLRequest = NULL; 497 498 mOwner->onDisconnectComplete(); 499 } 500 501 void SfDelegate::initiateRead(void *data, size_t size) { 502 MessageLoop *loop = gNetworkThread->message_loop(); 503 loop->PostTask( 504 FROM_HERE, 505 NewRunnableFunction( 506 &SfDelegate::OnInitiateReadWrapper, this, data, size)); 507 } 508 509 // static 510 void SfDelegate::OnInitiateReadWrapper( 511 SfDelegate *me, void *data, size_t size) { 512 me->onInitiateRead(data, size); 513 } 514 515 void SfDelegate::onInitiateRead(void *data, size_t size) { 516 CHECK(mURLRequest != NULL); 517 518 mNumBytesRead = 0; 519 mNumBytesTotal = size; 520 mDataDestination = data; 521 522 if (mAtEOS) { 523 mOwner->onReadCompleted(0); 524 return; 525 } 526 527 readMore(mURLRequest); 528 } 529 530 } // namespace android 531 532