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 <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     if (mURLRequest == NULL) {
    494         return;
    495     }
    496 
    497     mURLRequest->Cancel();
    498 
    499     delete mURLRequest;
    500     mURLRequest = NULL;
    501 
    502     mOwner->onDisconnectComplete();
    503 }
    504 
    505 void SfDelegate::initiateRead(void *data, size_t size) {
    506     MessageLoop *loop = gNetworkThread->message_loop();
    507     loop->PostTask(
    508             FROM_HERE,
    509             NewRunnableFunction(
    510                 &SfDelegate::OnInitiateReadWrapper, this, data, size));
    511 }
    512 
    513 // static
    514 void SfDelegate::OnInitiateReadWrapper(
    515         SfDelegate *me, void *data, size_t size) {
    516     me->onInitiateRead(data, size);
    517 }
    518 
    519 void SfDelegate::onInitiateRead(void *data, size_t size) {
    520     CHECK(mURLRequest != NULL);
    521 
    522     mNumBytesRead = 0;
    523     mNumBytesTotal = size;
    524     mDataDestination = data;
    525 
    526     if (mAtEOS) {
    527         mOwner->onReadCompleted(0);
    528         return;
    529     }
    530 
    531     readMore(mURLRequest);
    532 }
    533 
    534 }  // namespace android
    535 
    536