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 #include <arpa/inet.h> 38 #include <binder/Parcel.h> 39 #include <cutils/log.h> 40 #include <media/stagefright/MediaErrors.h> 41 #include <media/stagefright/Utils.h> 42 #include <string> 43 44 #include <utils/Errors.h> 45 #include <binder/IInterface.h> 46 #include <binder/IServiceManager.h> 47 48 namespace android { 49 50 // must be kept in sync with interface defined in IAudioService.aidl 51 class IAudioService : public IInterface 52 { 53 public: 54 DECLARE_META_INTERFACE(AudioService); 55 56 virtual int verifyX509CertChain( 57 const std::vector<std::string>& cert_chain, 58 const std::string& hostname, 59 const std::string& auth_type) = 0; 60 }; 61 62 class BpAudioService : public BpInterface<IAudioService> 63 { 64 public: 65 BpAudioService(const sp<IBinder>& impl) 66 : BpInterface<IAudioService>(impl) 67 { 68 } 69 70 virtual int verifyX509CertChain( 71 const std::vector<std::string>& cert_chain, 72 const std::string& hostname, 73 const std::string& auth_type) 74 { 75 Parcel data, reply; 76 data.writeInterfaceToken(IAudioService::getInterfaceDescriptor()); 77 78 // The vector of std::string we get isn't really a vector of strings, 79 // but rather a vector of binary certificate data. If we try to pass 80 // it to Java language code as a string, it ends up mangled on the other 81 // side, so send them as bytes instead. 82 // Since we can't send an array of byte arrays, send a single array, 83 // which will be split out by the recipient. 84 85 int numcerts = cert_chain.size(); 86 data.writeInt32(numcerts); 87 size_t total = 0; 88 for (int i = 0; i < numcerts; i++) { 89 total += cert_chain[i].size(); 90 } 91 size_t bytesize = total + numcerts * 4; 92 uint8_t *bytes = (uint8_t*) malloc(bytesize); 93 if (!bytes) { 94 return 5; // SSL_INVALID 95 } 96 ALOGV("%d certs: %d -> %d", numcerts, total, bytesize); 97 98 int offset = 0; 99 for (int i = 0; i < numcerts; i++) { 100 int32_t certsize = cert_chain[i].size(); 101 // store this in a known order, which just happens to match the default 102 // byte order of a java ByteBuffer 103 int32_t bigsize = htonl(certsize); 104 ALOGV("cert %d, size %d", i, certsize); 105 memcpy(bytes + offset, &bigsize, sizeof(bigsize)); 106 offset += sizeof(bigsize); 107 memcpy(bytes + offset, cert_chain[i].data(), certsize); 108 offset += certsize; 109 } 110 data.writeByteArray(bytesize, bytes); 111 free(bytes); 112 data.writeString16(String16(hostname.c_str())); 113 data.writeString16(String16(auth_type.c_str())); 114 115 int32_t result; 116 if (remote()->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply) != NO_ERROR 117 || reply.readExceptionCode() < 0 || reply.readInt32(&result) != NO_ERROR) { 118 return 5; // SSL_INVALID; 119 } 120 return result; 121 } 122 123 }; 124 125 IMPLEMENT_META_INTERFACE(AudioService, "android.media.IAudioService"); 126 127 128 static Mutex gNetworkThreadLock; 129 static base::Thread *gNetworkThread = NULL; 130 static scoped_refptr<SfRequestContext> gReqContext; 131 static scoped_ptr<net::NetworkChangeNotifier> gNetworkChangeNotifier; 132 133 bool logMessageHandler( 134 int severity, 135 const char* file, 136 int line, 137 size_t message_start, 138 const std::string& str) { 139 int androidSeverity = ANDROID_LOG_VERBOSE; 140 switch(severity) { 141 case logging::LOG_FATAL: 142 androidSeverity = ANDROID_LOG_FATAL; 143 break; 144 case logging::LOG_ERROR_REPORT: 145 case logging::LOG_ERROR: 146 androidSeverity = ANDROID_LOG_ERROR; 147 break; 148 case logging::LOG_WARNING: 149 androidSeverity = ANDROID_LOG_WARN; 150 break; 151 default: 152 androidSeverity = ANDROID_LOG_VERBOSE; 153 break; 154 } 155 android_printLog(androidSeverity, "chromium-libstagefright", 156 "%s:%d: %s", file, line, str.c_str()); 157 return false; 158 } 159 160 struct AutoPrioritySaver { 161 AutoPrioritySaver() 162 : mTID(androidGetTid()), 163 mPrevPriority(androidGetThreadPriority(mTID)) { 164 androidSetThreadPriority(mTID, ANDROID_PRIORITY_NORMAL); 165 } 166 167 ~AutoPrioritySaver() { 168 androidSetThreadPriority(mTID, mPrevPriority); 169 } 170 171 private: 172 pid_t mTID; 173 int mPrevPriority; 174 175 DISALLOW_EVIL_CONSTRUCTORS(AutoPrioritySaver); 176 }; 177 178 static void InitializeNetworkThreadIfNecessary() { 179 Mutex::Autolock autoLock(gNetworkThreadLock); 180 181 if (gNetworkThread == NULL) { 182 // Make sure any threads spawned by the chromium framework are 183 // running at normal priority instead of inheriting this thread's. 184 AutoPrioritySaver saver; 185 186 gNetworkThread = new base::Thread("network"); 187 base::Thread::Options options; 188 options.message_loop_type = MessageLoop::TYPE_IO; 189 CHECK(gNetworkThread->StartWithOptions(options)); 190 191 gReqContext = new SfRequestContext; 192 193 gNetworkChangeNotifier.reset(net::NetworkChangeNotifier::Create()); 194 195 net::AndroidNetworkLibrary::RegisterSharedInstance( 196 new SfNetworkLibrary); 197 logging::SetLogMessageHandler(logMessageHandler); 198 } 199 } 200 201 static void MY_LOGI(const char *s) { 202 LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s); 203 } 204 205 static void MY_LOGV(const char *s) { 206 #if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0 207 LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s); 208 #endif 209 } 210 211 SfNetLog::SfNetLog() 212 : mNextID(1) { 213 } 214 215 void SfNetLog::AddEntry( 216 EventType type, 217 const base::TimeTicks &time, 218 const Source &source, 219 EventPhase phase, 220 EventParameters *params) { 221 #if 0 222 MY_LOGI(StringPrintf( 223 "AddEntry time=%s type=%s source=%s phase=%s\n", 224 TickCountToString(time).c_str(), 225 EventTypeToString(type), 226 SourceTypeToString(source.type), 227 EventPhaseToString(phase)).c_str()); 228 #endif 229 } 230 231 uint32 SfNetLog::NextID() { 232 return mNextID++; 233 } 234 235 net::NetLog::LogLevel SfNetLog::GetLogLevel() const { 236 return LOG_BASIC; 237 } 238 239 //////////////////////////////////////////////////////////////////////////////// 240 241 SfRequestContext::SfRequestContext() { 242 mUserAgent = MakeUserAgent().c_str(); 243 244 set_net_log(new SfNetLog()); 245 246 set_host_resolver( 247 net::CreateSystemHostResolver( 248 net::HostResolver::kDefaultParallelism, 249 NULL /* resolver_proc */, 250 net_log())); 251 252 set_ssl_config_service( 253 net::SSLConfigService::CreateSystemSSLConfigService()); 254 255 mProxyConfigService = new net::ProxyConfigServiceAndroid; 256 257 set_proxy_service(net::ProxyService::CreateWithoutProxyResolver( 258 mProxyConfigService, net_log())); 259 260 set_http_transaction_factory(new net::HttpCache( 261 host_resolver(), 262 new net::CertVerifier(), 263 dnsrr_resolver(), 264 dns_cert_checker(), 265 proxy_service(), 266 ssl_config_service(), 267 net::HttpAuthHandlerFactory::CreateDefault(host_resolver()), 268 network_delegate(), 269 net_log(), 270 NULL)); // backend_factory 271 272 set_cookie_store(new net::CookieMonster(NULL, NULL)); 273 } 274 275 const std::string &SfRequestContext::GetUserAgent(const GURL &url) const { 276 return mUserAgent; 277 } 278 279 status_t SfRequestContext::updateProxyConfig( 280 const char *host, int32_t port, const char *exclusionList) { 281 Mutex::Autolock autoLock(mProxyConfigLock); 282 283 if (host == NULL || *host == '\0') { 284 MY_LOGV("updateProxyConfig NULL"); 285 286 std::string proxy; 287 std::string exList; 288 mProxyConfigService->UpdateProxySettings(proxy, exList); 289 } else { 290 #if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0 291 LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, 292 "updateProxyConfig %s:%d, exclude '%s'", 293 host, port, exclusionList); 294 #endif 295 296 std::string proxy = StringPrintf("%s:%d", host, port).c_str(); 297 std::string exList = exclusionList; 298 mProxyConfigService->UpdateProxySettings(proxy, exList); 299 } 300 301 return OK; 302 } 303 304 //////////////////////////////////////////////////////////////////////////////// 305 306 SfNetworkLibrary::SfNetworkLibrary() {} 307 308 SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain( 309 const std::vector<std::string>& cert_chain, 310 const std::string& hostname, 311 const std::string& auth_type) { 312 313 sp<IBinder> binder = 314 defaultServiceManager()->checkService(String16("audio")); 315 if (binder == 0) { 316 ALOGW("Thread cannot connect to the audio service"); 317 } else { 318 sp<IAudioService> service = interface_cast<IAudioService>(binder); 319 int code = service->verifyX509CertChain(cert_chain, hostname, auth_type); 320 ALOGV("verified: %d", code); 321 if (code == -1) { 322 return VERIFY_OK; 323 } else if (code == 2) { // SSL_IDMISMATCH 324 return VERIFY_BAD_HOSTNAME; 325 } else if (code == 3) { // SSL_UNTRUSTED 326 return VERIFY_NO_TRUSTED_ROOT; 327 } 328 } 329 return VERIFY_INVOCATION_ERROR; 330 } 331 332 //////////////////////////////////////////////////////////////////////////////// 333 334 SfDelegate::SfDelegate() 335 : mOwner(NULL), 336 mURLRequest(NULL), 337 mReadBuffer(new net::IOBufferWithSize(8192)), 338 mNumBytesRead(0), 339 mNumBytesTotal(0), 340 mDataDestination(NULL), 341 mAtEOS(false) { 342 InitializeNetworkThreadIfNecessary(); 343 } 344 345 SfDelegate::~SfDelegate() { 346 CHECK(mURLRequest == NULL); 347 } 348 349 // static 350 status_t SfDelegate::UpdateProxyConfig( 351 const char *host, int32_t port, const char *exclusionList) { 352 InitializeNetworkThreadIfNecessary(); 353 354 return gReqContext->updateProxyConfig(host, port, exclusionList); 355 } 356 357 void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) { 358 mOwner = owner; 359 } 360 361 void SfDelegate::setUID(uid_t uid) { 362 gReqContext->setUID(uid); 363 } 364 365 bool SfDelegate::getUID(uid_t *uid) const { 366 return gReqContext->getUID(uid); 367 } 368 369 void SfDelegate::OnReceivedRedirect( 370 net::URLRequest *request, const GURL &new_url, bool *defer_redirect) { 371 MY_LOGV("OnReceivedRedirect"); 372 mOwner->onRedirect(new_url.spec().c_str()); 373 } 374 375 void SfDelegate::OnAuthRequired( 376 net::URLRequest *request, net::AuthChallengeInfo *auth_info) { 377 MY_LOGV("OnAuthRequired"); 378 379 inherited::OnAuthRequired(request, auth_info); 380 } 381 382 void SfDelegate::OnCertificateRequested( 383 net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) { 384 MY_LOGV("OnCertificateRequested"); 385 386 inherited::OnCertificateRequested(request, cert_request_info); 387 } 388 389 void SfDelegate::OnSSLCertificateError( 390 net::URLRequest *request, int cert_error, net::X509Certificate *cert) { 391 fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error); 392 393 inherited::OnSSLCertificateError(request, cert_error, cert); 394 } 395 396 void SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) { 397 MY_LOGV("OnGetCookies"); 398 } 399 400 void SfDelegate::OnSetCookie( 401 net::URLRequest *request, 402 const std::string &cookie_line, 403 const net::CookieOptions &options, 404 bool blocked_by_policy) { 405 MY_LOGV("OnSetCookie"); 406 } 407 408 void SfDelegate::OnResponseStarted(net::URLRequest *request) { 409 if (request->status().status() != net::URLRequestStatus::SUCCESS) { 410 MY_LOGI(StringPrintf( 411 "Request failed with status %d and os_error %d", 412 request->status().status(), 413 request->status().os_error()).c_str()); 414 415 delete mURLRequest; 416 mURLRequest = NULL; 417 418 mOwner->onConnectionFailed(ERROR_IO); 419 return; 420 } else if (mRangeRequested && request->GetResponseCode() != 206) { 421 MY_LOGI(StringPrintf( 422 "We requested a content range, but server didn't " 423 "support that. (responded with %d)", 424 request->GetResponseCode()).c_str()); 425 426 delete mURLRequest; 427 mURLRequest = NULL; 428 429 mOwner->onConnectionFailed(-EPIPE); 430 return; 431 } else if ((request->GetResponseCode() / 100) != 2) { 432 MY_LOGI(StringPrintf( 433 "Server responded with http status %d", 434 request->GetResponseCode()).c_str()); 435 436 delete mURLRequest; 437 mURLRequest = NULL; 438 439 mOwner->onConnectionFailed(ERROR_IO); 440 return; 441 } 442 443 MY_LOGV("OnResponseStarted"); 444 445 std::string headers; 446 request->GetAllResponseHeaders(&headers); 447 448 MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str()); 449 450 std::string contentType; 451 request->GetResponseHeaderByName("Content-Type", &contentType); 452 453 mOwner->onConnectionEstablished( 454 request->GetExpectedContentSize(), contentType.c_str()); 455 } 456 457 void SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) { 458 if (bytes_read == -1) { 459 MY_LOGI(StringPrintf( 460 "OnReadCompleted, read failed, status %d", 461 request->status().status()).c_str()); 462 463 mOwner->onReadCompleted(ERROR_IO); 464 return; 465 } 466 467 MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str()); 468 469 if (bytes_read < 0) { 470 MY_LOGI(StringPrintf( 471 "Read failed w/ status %d\n", 472 request->status().status()).c_str()); 473 474 mOwner->onReadCompleted(ERROR_IO); 475 return; 476 } else if (bytes_read == 0) { 477 mAtEOS = true; 478 mOwner->onReadCompleted(mNumBytesRead); 479 return; 480 } 481 482 CHECK_GT(bytes_read, 0); 483 CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal); 484 485 memcpy((uint8_t *)mDataDestination + mNumBytesRead, 486 mReadBuffer->data(), 487 bytes_read); 488 489 mNumBytesRead += bytes_read; 490 491 readMore(request); 492 } 493 494 void SfDelegate::readMore(net::URLRequest *request) { 495 while (mNumBytesRead < mNumBytesTotal) { 496 size_t copy = mNumBytesTotal - mNumBytesRead; 497 if (copy > mReadBuffer->size()) { 498 copy = mReadBuffer->size(); 499 } 500 501 int n; 502 if (request->Read(mReadBuffer, copy, &n)) { 503 MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str()); 504 505 CHECK_LE((size_t)n, copy); 506 507 memcpy((uint8_t *)mDataDestination + mNumBytesRead, 508 mReadBuffer->data(), 509 n); 510 511 mNumBytesRead += n; 512 513 if (n == 0) { 514 mAtEOS = true; 515 break; 516 } 517 } else { 518 MY_LOGV("readMore pending read"); 519 520 if (request->status().status() != net::URLRequestStatus::IO_PENDING) { 521 MY_LOGI(StringPrintf( 522 "Direct read failed w/ status %d\n", 523 request->status().status()).c_str()); 524 525 mOwner->onReadCompleted(ERROR_IO); 526 return; 527 } 528 529 return; 530 } 531 } 532 533 mOwner->onReadCompleted(mNumBytesRead); 534 } 535 536 void SfDelegate::initiateConnection( 537 const char *uri, 538 const KeyedVector<String8, String8> *headers, 539 off64_t offset) { 540 GURL url(uri); 541 542 MessageLoop *loop = gNetworkThread->message_loop(); 543 loop->PostTask( 544 FROM_HERE, 545 NewRunnableFunction( 546 &SfDelegate::OnInitiateConnectionWrapper, 547 this, 548 url, 549 headers, 550 offset)); 551 552 } 553 554 // static 555 void SfDelegate::OnInitiateConnectionWrapper( 556 SfDelegate *me, GURL url, 557 const KeyedVector<String8, String8> *headers, 558 off64_t offset) { 559 me->onInitiateConnection(url, headers, offset); 560 } 561 562 void SfDelegate::onInitiateConnection( 563 const GURL &url, 564 const KeyedVector<String8, String8> *extra, 565 off64_t offset) { 566 CHECK(mURLRequest == NULL); 567 568 mURLRequest = new net::URLRequest(url, this); 569 mAtEOS = false; 570 571 mRangeRequested = false; 572 573 if (offset != 0 || extra != NULL) { 574 net::HttpRequestHeaders headers = 575 mURLRequest->extra_request_headers(); 576 577 if (offset != 0) { 578 headers.AddHeaderFromString( 579 StringPrintf("Range: bytes=%lld-", offset).c_str()); 580 581 mRangeRequested = true; 582 } 583 584 if (extra != NULL) { 585 for (size_t i = 0; i < extra->size(); ++i) { 586 AString s; 587 s.append(extra->keyAt(i).string()); 588 s.append(": "); 589 s.append(extra->valueAt(i).string()); 590 591 headers.AddHeaderFromString(s.c_str()); 592 } 593 } 594 595 mURLRequest->SetExtraRequestHeaders(headers); 596 } 597 598 mURLRequest->set_context(gReqContext); 599 600 mURLRequest->Start(); 601 } 602 603 void SfDelegate::initiateDisconnect() { 604 MessageLoop *loop = gNetworkThread->message_loop(); 605 loop->PostTask( 606 FROM_HERE, 607 NewRunnableFunction( 608 &SfDelegate::OnInitiateDisconnectWrapper, this)); 609 } 610 611 // static 612 void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) { 613 me->onInitiateDisconnect(); 614 } 615 616 void SfDelegate::onInitiateDisconnect() { 617 if (mURLRequest == NULL) { 618 return; 619 } 620 621 mURLRequest->Cancel(); 622 623 delete mURLRequest; 624 mURLRequest = NULL; 625 626 mOwner->onDisconnectComplete(); 627 } 628 629 void SfDelegate::initiateRead(void *data, size_t size) { 630 MessageLoop *loop = gNetworkThread->message_loop(); 631 loop->PostTask( 632 FROM_HERE, 633 NewRunnableFunction( 634 &SfDelegate::OnInitiateReadWrapper, this, data, size)); 635 } 636 637 // static 638 void SfDelegate::OnInitiateReadWrapper( 639 SfDelegate *me, void *data, size_t size) { 640 me->onInitiateRead(data, size); 641 } 642 643 void SfDelegate::onInitiateRead(void *data, size_t size) { 644 CHECK(mURLRequest != NULL); 645 646 mNumBytesRead = 0; 647 mNumBytesTotal = size; 648 mDataDestination = data; 649 650 if (mAtEOS) { 651 mOwner->onReadCompleted(0); 652 return; 653 } 654 655 readMore(mURLRequest); 656 } 657 658 } // namespace android 659 660