support.cpp revision a533975a8e3bb741948750a68a2c962a48777fe0
11156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber/*
21156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * Copyright (C) 2011 The Android Open Source Project
31156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber *
41156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * you may not use this file except in compliance with the License.
61156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * You may obtain a copy of the License at
71156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber *
81156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber *
101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * Unless required by applicable law or agreed to in writing, software
111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * See the License for the specific language governing permissions and
141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber * limitations under the License.
151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber */
161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber//#define LOG_NDEBUG 0
181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#define LOG_TAG "ChromiumHTTPDataSourceSupport"
191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <utils/Log.h>
201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <media/stagefright/foundation/AString.h>
221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "support.h"
241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "android/net/android_network_library_impl.h"
26a533975a8e3bb741948750a68a2c962a48777fe0Kristian Monsen#include "base/threading/thread.h"
27cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen#include "net/base/cert_verifier.h"
281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "net/base/host_resolver.h"
291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "net/base/ssl_config_service.h"
3070fcf534d3fb6faa3aaa8061fc87f720c396e7aeAndreas Huber#include "net/http/http_auth_handler_factory.h"
311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "net/http/http_cache.h"
3272fee698602ede6f6b64b77c0f1f28d96ff673d3Andreas Huber#include "net/proxy/proxy_config_service_android.h"
331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "include/ChromiumHTTPDataSource.h"
351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <cutils/properties.h>
371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <media/stagefright/MediaErrors.h>
381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubernamespace android {
401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic Mutex gNetworkThreadLock;
421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic base::Thread *gNetworkThread = NULL;
431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic scoped_refptr<URLRequestContext> gReqContext;
441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic void InitializeNetworkThreadIfNecessary() {
461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    Mutex::Autolock autoLock(gNetworkThreadLock);
471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (gNetworkThread == NULL) {
481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        gNetworkThread = new base::Thread("network");
491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        base::Thread::Options options;
501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        options.message_loop_type = MessageLoop::TYPE_IO;
511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        CHECK(gNetworkThread->StartWithOptions(options));
521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        gReqContext = new SfRequestContext;
541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::AndroidNetworkLibrary::RegisterSharedInstance(
561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                new SfNetworkLibrary);
571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic void MY_LOGI(const char *s) {
611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s);
621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic void MY_LOGV(const char *s) {
651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s);
671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#endif
681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
701156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfNetLog::SfNetLog()
711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    : mNextID(1) {
721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfNetLog::AddEntry(
751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        EventType type,
761156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const base::TimeTicks &time,
771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const Source &source,
781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        EventPhase phase,
791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        EventParameters *params) {
801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#if 0
811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI(StringPrintf(
821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                "AddEntry time=%s type=%s source=%s phase=%s\n",
831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                TickCountToString(time).c_str(),
841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                EventTypeToString(type),
851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                SourceTypeToString(source.type),
861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                EventPhaseToString(phase)).c_str());
871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#endif
881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberuint32 SfNetLog::NextID() {
911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return mNextID++;
921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubernet::NetLog::LogLevel SfNetLog::GetLogLevel() const {
951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return LOG_ALL;
961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber////////////////////////////////////////////////////////////////////////////////
991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1001156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfRequestContext::SfRequestContext() {
1011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    AString ua;
1021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
1031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1041156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#if (PROPERTY_VALUE_MAX < 8)
1051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
1061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#endif
1071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    char value[PROPERTY_VALUE_MAX];
1091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    property_get("ro.build.version.release", value, "Unknown");
1101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ua.append(value);
1111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ua.append(")");
1121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mUserAgent = ua.c_str();
1141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    net_log_ = new SfNetLog;
1161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    host_resolver_ =
1181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::CreateSystemHostResolver(
1191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                net::HostResolver::kDefaultParallelism,
1201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                NULL /* resolver_proc */,
1211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                net_log_);
1221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ssl_config_service_ =
1241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::SSLConfigService::CreateSystemSSLConfigService();
1251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
12672fee698602ede6f6b64b77c0f1f28d96ff673d3Andreas Huber    proxy_service_ = net::ProxyService::CreateWithoutProxyResolver(
12772fee698602ede6f6b64b77c0f1f28d96ff673d3Andreas Huber            new net::ProxyConfigServiceAndroid, net_log_);
1281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    http_transaction_factory_ = new net::HttpCache(
1301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            host_resolver_,
131cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            new net::CertVerifier(),
1321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            dnsrr_resolver_,
1331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            dns_cert_checker_.get(),
1341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            proxy_service_.get(),
1351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            ssl_config_service_.get(),
13670fcf534d3fb6faa3aaa8061fc87f720c396e7aeAndreas Huber            net::HttpAuthHandlerFactory::CreateDefault(host_resolver_),
1371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            network_delegate_,
1381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            net_log_,
1391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NULL);  // backend_factory
1401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberconst std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
1431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return mUserAgent;
1441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber////////////////////////////////////////////////////////////////////////////////
1471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1481156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfNetworkLibrary::SfNetworkLibrary() {}
1491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1501156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
1511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::vector<std::string>& cert_chain,
1521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::string& hostname,
1531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::string& auth_type) {
1541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return VERIFY_OK;
1551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber////////////////////////////////////////////////////////////////////////////////
1581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1591156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfDelegate::SfDelegate()
1601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    : mOwner(NULL),
1611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mURLRequest(NULL),
1621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mReadBuffer(new net::IOBufferWithSize(8192)),
1631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mNumBytesRead(0),
1641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mNumBytesTotal(0),
1651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mDataDestination(NULL),
1661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mAtEOS(false) {
1671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    InitializeNetworkThreadIfNecessary();
1681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1701156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfDelegate::~SfDelegate() {
1711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK(mURLRequest == NULL);
1721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::setOwner(ChromiumHTTPDataSource *owner) {
1751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mOwner = owner;
1761156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnReceivedRedirect(
179cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
1801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnReceivedRedirect");
1811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnAuthRequired(
184cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, net::AuthChallengeInfo *auth_info) {
1851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnAuthRequired");
1861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    inherited::OnAuthRequired(request, auth_info);
1881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnCertificateRequested(
191cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
1921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnCertificateRequested");
1931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    inherited::OnCertificateRequested(request, cert_request_info);
1951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnSSLCertificateError(
198cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, int cert_error, net::X509Certificate *cert) {
1991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
2001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    inherited::OnSSLCertificateError(request, cert_error, cert);
2021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
204cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) {
2051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnGetCookies");
2061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnSetCookie(
209cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen        net::URLRequest *request,
2101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::string &cookie_line,
2111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const net::CookieOptions &options,
2121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        bool blocked_by_policy) {
2131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnSetCookie");
2141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
216cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::OnResponseStarted(net::URLRequest *request) {
2171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (request->status().status() != URLRequestStatus::SUCCESS) {
2181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "Request failed with status %d and os_error %d",
2201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().status(),
2211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().os_error()).c_str());
2221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        delete mURLRequest;
2241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest = NULL;
2251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onConnectionFailed(ERROR_IO);
2271156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    } else if (mRangeRequested && request->GetResponseCode() != 206) {
2291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "We requested a content range, but server didn't "
2311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "support that. (responded with %d)",
2321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->GetResponseCode()).c_str());
2331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        delete mURLRequest;
2351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest = NULL;
2361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onConnectionFailed(-EPIPE);
2381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    } else if ((request->GetResponseCode() / 100) != 2) {
2401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "Server responded with http status %d",
2421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->GetResponseCode()).c_str());
2431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        delete mURLRequest;
2451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest = NULL;
2461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onConnectionFailed(ERROR_IO);
2481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
2501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGV("OnResponseStarted");
2521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    std::string headers;
2541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    request->GetAllResponseHeaders(&headers);
2551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str());
2571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2586511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    std::string contentType;
2596511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    request->GetResponseHeaderByName("Content-Type", &contentType);
2606511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
2616511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    mOwner->onConnectionEstablished(
2626511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            request->GetExpectedContentSize(), contentType.c_str());
2631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
265cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) {
2661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (bytes_read == -1) {
2671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "OnReadCompleted, read failed, status %d",
2691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().status()).c_str());
2701156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(ERROR_IO);
2721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
2741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str());
2761156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (bytes_read < 0) {
2781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "Read failed w/ status %d\n",
2801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().status()).c_str());
2811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(ERROR_IO);
2831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    } else if (bytes_read == 0) {
2851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mAtEOS = true;
2861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(mNumBytesRead);
2871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
2891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK_GT(bytes_read, 0);
2911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal);
2921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    memcpy((uint8_t *)mDataDestination + mNumBytesRead,
2941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber           mReadBuffer->data(),
2951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber           bytes_read);
2961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mNumBytesRead += bytes_read;
2981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    readMore(request);
3001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
302cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::readMore(net::URLRequest *request) {
3031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    while (mNumBytesRead < mNumBytesTotal) {
3041156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        size_t copy = mNumBytesTotal - mNumBytesRead;
3051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (copy > mReadBuffer->size()) {
3061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            copy = mReadBuffer->size();
3071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
3081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        int n;
3101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (request->Read(mReadBuffer, copy, &n)) {
3111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str());
3121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            CHECK_LE((size_t)n, copy);
3141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            memcpy((uint8_t *)mDataDestination + mNumBytesRead,
3161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                   mReadBuffer->data(),
3171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                   n);
3181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            mNumBytesRead += n;
3201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            if (n == 0) {
3221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                mAtEOS = true;
3231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                break;
3241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            }
3251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        } else {
3261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            MY_LOGV("readMore pending read");
3271156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            if (request->status().status() != URLRequestStatus::IO_PENDING) {
3291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                MY_LOGI(StringPrintf(
3301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                            "Direct read failed w/ status %d\n",
3311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                            request->status().status()).c_str());
3321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                mOwner->onReadCompleted(ERROR_IO);
3341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                return;
3351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            }
3361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            return;
3381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
3391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
3401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mOwner->onReadCompleted(mNumBytesRead);
3421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::initiateConnection(
3451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const char *uri,
3461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const KeyedVector<String8, String8> *headers,
3471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        off64_t offset) {
3481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    GURL url(uri);
3491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MessageLoop *loop = gNetworkThread->message_loop();
3511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    loop->PostTask(
3521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            FROM_HERE,
3531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NewRunnableFunction(
3541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                &SfDelegate::OnInitiateConnectionWrapper,
3551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                this,
3561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                url,
3571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                headers,
3581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                offset));
3591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber// static
3631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnInitiateConnectionWrapper(
3641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        SfDelegate *me, GURL url,
3651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const KeyedVector<String8, String8> *headers,
3661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        off64_t offset) {
3671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    me->onInitiateConnection(url, headers, offset);
3681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3701156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::onInitiateConnection(
3711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const GURL &url,
3721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const KeyedVector<String8, String8> *extra,
3731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        off64_t offset) {
3741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK(mURLRequest == NULL);
3751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
376cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen    mURLRequest = new net::URLRequest(url, this);
3771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mAtEOS = false;
3781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mRangeRequested = false;
3801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (offset != 0 || extra != NULL) {
3821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::HttpRequestHeaders headers =
3831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            mURLRequest->extra_request_headers();
3841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (offset != 0) {
3861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            headers.AddHeaderFromString(
3871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    StringPrintf("Range: bytes=%lld-", offset).c_str());
3881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            mRangeRequested = true;
3901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
3911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (extra != NULL) {
3931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            for (size_t i = 0; i < extra->size(); ++i) {
3941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                AString s;
3951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                s.append(extra->keyAt(i).string());
3961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                s.append(": ");
3971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                s.append(extra->valueAt(i).string());
3981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                headers.AddHeaderFromString(s.c_str());
4001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            }
4011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
4021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest->SetExtraRequestHeaders(headers);
4041156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
4051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest->set_context(gReqContext);
4071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest->Start();
4091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::initiateDisconnect() {
4121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MessageLoop *loop = gNetworkThread->message_loop();
4131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    loop->PostTask(
4141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            FROM_HERE,
4151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NewRunnableFunction(
4161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                &SfDelegate::OnInitiateDisconnectWrapper, this));
4171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber// static
4201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) {
4211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    me->onInitiateDisconnect();
4221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::onInitiateDisconnect() {
4251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest->Cancel();
4261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4271156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    delete mURLRequest;
4281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest = NULL;
4291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mOwner->onDisconnectComplete();
4311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::initiateRead(void *data, size_t size) {
4341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MessageLoop *loop = gNetworkThread->message_loop();
4351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    loop->PostTask(
4361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            FROM_HERE,
4371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NewRunnableFunction(
4381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                &SfDelegate::OnInitiateReadWrapper, this, data, size));
4391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber// static
4421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnInitiateReadWrapper(
4431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        SfDelegate *me, void *data, size_t size) {
4441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    me->onInitiateRead(data, size);
4451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::onInitiateRead(void *data, size_t size) {
4481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK(mURLRequest != NULL);
4491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mNumBytesRead = 0;
4511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mNumBytesTotal = size;
4521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mDataDestination = data;
4531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (mAtEOS) {
4551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(0);
4561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
4571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
4581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    readMore(mURLRequest);
4601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}  // namespace android
4631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
464