Home | History | Annotate | Download | only in chromium_http
      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