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 
     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