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 <media/stagefright/MediaErrors.h> 40 #include <media/stagefright/Utils.h> 41 #include <string> 42 43 namespace android { 44 45 static Mutex gNetworkThreadLock; 46 static base::Thread *gNetworkThread = NULL; 47 static scoped_refptr<SfRequestContext> 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 mUserAgent = MakeUserAgent().c_str(); 160 161 set_net_log(new SfNetLog()); 162 163 set_host_resolver( 164 net::CreateSystemHostResolver( 165 net::HostResolver::kDefaultParallelism, 166 NULL /* resolver_proc */, 167 net_log())); 168 169 set_ssl_config_service( 170 net::SSLConfigService::CreateSystemSSLConfigService()); 171 172 mProxyConfigService = new net::ProxyConfigServiceAndroid; 173 174 set_proxy_service(net::ProxyService::CreateWithoutProxyResolver( 175 mProxyConfigService, net_log())); 176 177 set_http_transaction_factory(new net::HttpCache( 178 host_resolver(), 179 new net::CertVerifier(), 180 dnsrr_resolver(), 181 dns_cert_checker(), 182 proxy_service(), 183 ssl_config_service(), 184 net::HttpAuthHandlerFactory::CreateDefault(host_resolver()), 185 network_delegate(), 186 net_log(), 187 NULL)); // backend_factory 188 189 set_cookie_store(new net::CookieMonster(NULL, NULL)); 190 } 191 192 const std::string &SfRequestContext::GetUserAgent(const GURL &url) const { 193 return mUserAgent; 194 } 195 196 status_t SfRequestContext::updateProxyConfig( 197 const char *host, int32_t port, const char *exclusionList) { 198 Mutex::Autolock autoLock(mProxyConfigLock); 199 200 if (host == NULL || *host == '\0') { 201 MY_LOGV("updateProxyConfig NULL"); 202 203 std::string proxy; 204 std::string exList; 205 mProxyConfigService->UpdateProxySettings(proxy, exList); 206 } else { 207 #if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0 208 LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, 209 "updateProxyConfig %s:%d, exclude '%s'", 210 host, port, exclusionList); 211 #endif 212 213 std::string proxy = StringPrintf("%s:%d", host, port).c_str(); 214 std::string exList = exclusionList; 215 mProxyConfigService->UpdateProxySettings(proxy, exList); 216 } 217 218 return OK; 219 } 220 221 //////////////////////////////////////////////////////////////////////////////// 222 223 SfNetworkLibrary::SfNetworkLibrary() {} 224 225 SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain( 226 const std::vector<std::string>& cert_chain, 227 const std::string& hostname, 228 const std::string& auth_type) { 229 return VERIFY_OK; 230 } 231 232 //////////////////////////////////////////////////////////////////////////////// 233 234 SfDelegate::SfDelegate() 235 : mOwner(NULL), 236 mURLRequest(NULL), 237 mReadBuffer(new net::IOBufferWithSize(8192)), 238 mNumBytesRead(0), 239 mNumBytesTotal(0), 240 mDataDestination(NULL), 241 mAtEOS(false) { 242 InitializeNetworkThreadIfNecessary(); 243 } 244 245 SfDelegate::~SfDelegate() { 246 CHECK(mURLRequest == NULL); 247 } 248 249 // static 250 status_t SfDelegate::UpdateProxyConfig( 251 const char *host, int32_t port, const char *exclusionList) { 252 InitializeNetworkThreadIfNecessary(); 253 254 return gReqContext->updateProxyConfig(host, port, exclusionList); 255 } 256 257 void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) { 258 mOwner = owner; 259 } 260 261 void SfDelegate::setUID(uid_t uid) { 262 gReqContext->setUID(uid); 263 } 264 265 bool SfDelegate::getUID(uid_t *uid) const { 266 return gReqContext->getUID(uid); 267 } 268 269 void SfDelegate::OnReceivedRedirect( 270 net::URLRequest *request, const GURL &new_url, bool *defer_redirect) { 271 MY_LOGV("OnReceivedRedirect"); 272 } 273 274 void SfDelegate::OnAuthRequired( 275 net::URLRequest *request, net::AuthChallengeInfo *auth_info) { 276 MY_LOGV("OnAuthRequired"); 277 278 inherited::OnAuthRequired(request, auth_info); 279 } 280 281 void SfDelegate::OnCertificateRequested( 282 net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) { 283 MY_LOGV("OnCertificateRequested"); 284 285 inherited::OnCertificateRequested(request, cert_request_info); 286 } 287 288 void SfDelegate::OnSSLCertificateError( 289 net::URLRequest *request, int cert_error, net::X509Certificate *cert) { 290 fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error); 291 292 inherited::OnSSLCertificateError(request, cert_error, cert); 293 } 294 295 void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) { 296 MY_LOGV("OnGetCookies"); 297 } 298 299 void SfDelegate::OnSetCookie( 300 net::URLRequest *request, 301 const std::string &cookie_line, 302 const net::CookieOptions &options, 303 bool blocked_by_policy) { 304 MY_LOGV("OnSetCookie"); 305 } 306 307 void SfDelegate::OnResponseStarted(net::URLRequest *request) { 308 if (request->status().status() != net::URLRequestStatus::SUCCESS) { 309 MY_LOGI(StringPrintf( 310 "Request failed with status %d and os_error %d", 311 request->status().status(), 312 request->status().os_error()).c_str()); 313 314 delete mURLRequest; 315 mURLRequest = NULL; 316 317 mOwner->onConnectionFailed(ERROR_IO); 318 return; 319 } else if (mRangeRequested && request->GetResponseCode() != 206) { 320 MY_LOGI(StringPrintf( 321 "We requested a content range, but server didn't " 322 "support that. (responded with %d)", 323 request->GetResponseCode()).c_str()); 324 325 delete mURLRequest; 326 mURLRequest = NULL; 327 328 mOwner->onConnectionFailed(-EPIPE); 329 return; 330 } else if ((request->GetResponseCode() / 100) != 2) { 331 MY_LOGI(StringPrintf( 332 "Server responded with http status %d", 333 request->GetResponseCode()).c_str()); 334 335 delete mURLRequest; 336 mURLRequest = NULL; 337 338 mOwner->onConnectionFailed(ERROR_IO); 339 return; 340 } 341 342 MY_LOGV("OnResponseStarted"); 343 344 std::string headers; 345 request->GetAllResponseHeaders(&headers); 346 347 MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str()); 348 349 std::string contentType; 350 request->GetResponseHeaderByName("Content-Type", &contentType); 351 352 mOwner->onConnectionEstablished( 353 request->GetExpectedContentSize(), contentType.c_str()); 354 } 355 356 void SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) { 357 if (bytes_read == -1) { 358 MY_LOGI(StringPrintf( 359 "OnReadCompleted, read failed, status %d", 360 request->status().status()).c_str()); 361 362 mOwner->onReadCompleted(ERROR_IO); 363 return; 364 } 365 366 MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str()); 367 368 if (bytes_read < 0) { 369 MY_LOGI(StringPrintf( 370 "Read failed w/ status %d\n", 371 request->status().status()).c_str()); 372 373 mOwner->onReadCompleted(ERROR_IO); 374 return; 375 } else if (bytes_read == 0) { 376 mAtEOS = true; 377 mOwner->onReadCompleted(mNumBytesRead); 378 return; 379 } 380 381 CHECK_GT(bytes_read, 0); 382 CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal); 383 384 memcpy((uint8_t *)mDataDestination + mNumBytesRead, 385 mReadBuffer->data(), 386 bytes_read); 387 388 mNumBytesRead += bytes_read; 389 390 readMore(request); 391 } 392 393 void SfDelegate::readMore(net::URLRequest *request) { 394 while (mNumBytesRead < mNumBytesTotal) { 395 size_t copy = mNumBytesTotal - mNumBytesRead; 396 if (copy > mReadBuffer->size()) { 397 copy = mReadBuffer->size(); 398 } 399 400 int n; 401 if (request->Read(mReadBuffer, copy, &n)) { 402 MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str()); 403 404 CHECK_LE((size_t)n, copy); 405 406 memcpy((uint8_t *)mDataDestination + mNumBytesRead, 407 mReadBuffer->data(), 408 n); 409 410 mNumBytesRead += n; 411 412 if (n == 0) { 413 mAtEOS = true; 414 break; 415 } 416 } else { 417 MY_LOGV("readMore pending read"); 418 419 if (request->status().status() != net::URLRequestStatus::IO_PENDING) { 420 MY_LOGI(StringPrintf( 421 "Direct read failed w/ status %d\n", 422 request->status().status()).c_str()); 423 424 mOwner->onReadCompleted(ERROR_IO); 425 return; 426 } 427 428 return; 429 } 430 } 431 432 mOwner->onReadCompleted(mNumBytesRead); 433 } 434 435 void SfDelegate::initiateConnection( 436 const char *uri, 437 const KeyedVector<String8, String8> *headers, 438 off64_t offset) { 439 GURL url(uri); 440 441 MessageLoop *loop = gNetworkThread->message_loop(); 442 loop->PostTask( 443 FROM_HERE, 444 NewRunnableFunction( 445 &SfDelegate::OnInitiateConnectionWrapper, 446 this, 447 url, 448 headers, 449 offset)); 450 451 } 452 453 // static 454 void SfDelegate::OnInitiateConnectionWrapper( 455 SfDelegate *me, GURL url, 456 const KeyedVector<String8, String8> *headers, 457 off64_t offset) { 458 me->onInitiateConnection(url, headers, offset); 459 } 460 461 void SfDelegate::onInitiateConnection( 462 const GURL &url, 463 const KeyedVector<String8, String8> *extra, 464 off64_t offset) { 465 CHECK(mURLRequest == NULL); 466 467 mURLRequest = new net::URLRequest(url, this); 468 mAtEOS = false; 469 470 mRangeRequested = false; 471 472 if (offset != 0 || extra != NULL) { 473 net::HttpRequestHeaders headers = 474 mURLRequest->extra_request_headers(); 475 476 if (offset != 0) { 477 headers.AddHeaderFromString( 478 StringPrintf("Range: bytes=%lld-", offset).c_str()); 479 480 mRangeRequested = true; 481 } 482 483 if (extra != NULL) { 484 for (size_t i = 0; i < extra->size(); ++i) { 485 AString s; 486 s.append(extra->keyAt(i).string()); 487 s.append(": "); 488 s.append(extra->valueAt(i).string()); 489 490 headers.AddHeaderFromString(s.c_str()); 491 } 492 } 493 494 mURLRequest->SetExtraRequestHeaders(headers); 495 } 496 497 mURLRequest->set_context(gReqContext); 498 499 mURLRequest->Start(); 500 } 501 502 void SfDelegate::initiateDisconnect() { 503 MessageLoop *loop = gNetworkThread->message_loop(); 504 loop->PostTask( 505 FROM_HERE, 506 NewRunnableFunction( 507 &SfDelegate::OnInitiateDisconnectWrapper, this)); 508 } 509 510 // static 511 void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) { 512 me->onInitiateDisconnect(); 513 } 514 515 void SfDelegate::onInitiateDisconnect() { 516 if (mURLRequest == NULL) { 517 return; 518 } 519 520 mURLRequest->Cancel(); 521 522 delete mURLRequest; 523 mURLRequest = NULL; 524 525 mOwner->onDisconnectComplete(); 526 } 527 528 void SfDelegate::initiateRead(void *data, size_t size) { 529 MessageLoop *loop = gNetworkThread->message_loop(); 530 loop->PostTask( 531 FROM_HERE, 532 NewRunnableFunction( 533 &SfDelegate::OnInitiateReadWrapper, this, data, size)); 534 } 535 536 // static 537 void SfDelegate::OnInitiateReadWrapper( 538 SfDelegate *me, void *data, size_t size) { 539 me->onInitiateRead(data, size); 540 } 541 542 void SfDelegate::onInitiateRead(void *data, size_t size) { 543 CHECK(mURLRequest != NULL); 544 545 mNumBytesRead = 0; 546 mNumBytesTotal = size; 547 mDataDestination = data; 548 549 if (mAtEOS) { 550 mOwner->onReadCompleted(0); 551 return; 552 } 553 554 readMore(mURLRequest); 555 } 556 557 } // namespace android 558 559