support.cpp revision deaba1c70b8ebdd1fffb40665a40e0593bd9cf3e
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"
28deaba1c70b8ebdd1fffb40665a40e0593bd9cf3eKristian Monsen#include "net/base/cookie_monster.h"
291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "net/base/host_resolver.h"
301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "net/base/ssl_config_service.h"
3170fcf534d3fb6faa3aaa8061fc87f720c396e7aeAndreas Huber#include "net/http/http_auth_handler_factory.h"
321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "net/http/http_cache.h"
3372fee698602ede6f6b64b77c0f1f28d96ff673d3Andreas Huber#include "net/proxy/proxy_config_service_android.h"
341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include "include/ChromiumHTTPDataSource.h"
361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <cutils/properties.h>
381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#include <media/stagefright/MediaErrors.h>
391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubernamespace android {
411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic Mutex gNetworkThreadLock;
431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic base::Thread *gNetworkThread = NULL;
4464125da2f3b76f2d88bb757cb6bf5bd5e29a0639Kristian Monsenstatic scoped_refptr<net::URLRequestContext> gReqContext;
45553f66e21be6e11120460830fc78793a4d11b465Andreas Huberstatic scoped_ptr<net::NetworkChangeNotifier> gNetworkChangeNotifier;
461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic void InitializeNetworkThreadIfNecessary() {
481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    Mutex::Autolock autoLock(gNetworkThreadLock);
491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (gNetworkThread == NULL) {
501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        gNetworkThread = new base::Thread("network");
511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        base::Thread::Options options;
521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        options.message_loop_type = MessageLoop::TYPE_IO;
531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        CHECK(gNetworkThread->StartWithOptions(options));
541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        gReqContext = new SfRequestContext;
561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
57553f66e21be6e11120460830fc78793a4d11b465Andreas Huber        gNetworkChangeNotifier.reset(net::NetworkChangeNotifier::Create());
58553f66e21be6e11120460830fc78793a4d11b465Andreas Huber
591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::AndroidNetworkLibrary::RegisterSharedInstance(
601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                new SfNetworkLibrary);
611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic void MY_LOGI(const char *s) {
651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s);
661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberstatic void MY_LOGV(const char *s) {
691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
701156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s);
711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#endif
721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
741156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfNetLog::SfNetLog()
751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    : mNextID(1) {
761156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfNetLog::AddEntry(
791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        EventType type,
801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const base::TimeTicks &time,
811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const Source &source,
821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        EventPhase phase,
831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        EventParameters *params) {
841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#if 0
851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI(StringPrintf(
861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                "AddEntry time=%s type=%s source=%s phase=%s\n",
871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                TickCountToString(time).c_str(),
881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                EventTypeToString(type),
891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                SourceTypeToString(source.type),
901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                EventPhaseToString(phase)).c_str());
911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#endif
921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberuint32 SfNetLog::NextID() {
951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return mNextID++;
961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubernet::NetLog::LogLevel SfNetLog::GetLogLevel() const {
991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return LOG_ALL;
1001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber////////////////////////////////////////////////////////////////////////////////
1031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1041156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfRequestContext::SfRequestContext() {
1051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    AString ua;
1061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ua.append("stagefright/1.2 (Linux;Android ");
1071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#if (PROPERTY_VALUE_MAX < 8)
1091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#error "PROPERTY_VALUE_MAX must be at least 8"
1101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber#endif
1111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    char value[PROPERTY_VALUE_MAX];
1131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    property_get("ro.build.version.release", value, "Unknown");
1141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ua.append(value);
1151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    ua.append(")");
1161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mUserAgent = ua.c_str();
1181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
11963d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen    set_net_log(new SfNetLog());
1201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
12163d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen    set_host_resolver(
1221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::CreateSystemHostResolver(
1231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                net::HostResolver::kDefaultParallelism,
1241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                NULL /* resolver_proc */,
12563d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen                net_log()));
1261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
12763d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen    set_ssl_config_service(
12863d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen        net::SSLConfigService::CreateSystemSSLConfigService());
1291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
13063d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen    set_proxy_service(net::ProxyService::CreateWithoutProxyResolver(
13163d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen        new net::ProxyConfigServiceAndroid, net_log()));
1321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
13363d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen    set_http_transaction_factory(new net::HttpCache(
13463d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            host_resolver(),
135cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            new net::CertVerifier(),
13663d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            dnsrr_resolver(),
13763d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            dns_cert_checker(),
13863d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            proxy_service(),
13963d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            ssl_config_service(),
14063d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            net::HttpAuthHandlerFactory::CreateDefault(host_resolver()),
14163d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            network_delegate(),
14263d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            net_log(),
14363d794763a680c29edccce3a6fac3d6d9c13c8e3Kristian Monsen            NULL));  // backend_factory
144deaba1c70b8ebdd1fffb40665a40e0593bd9cf3eKristian Monsen
145deaba1c70b8ebdd1fffb40665a40e0593bd9cf3eKristian Monsen    set_cookie_store(new net::CookieMonster(NULL, NULL));
1461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huberconst std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
1491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return mUserAgent;
1501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber////////////////////////////////////////////////////////////////////////////////
1531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1541156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfNetworkLibrary::SfNetworkLibrary() {}
1551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1561156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
1571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::vector<std::string>& cert_chain,
1581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::string& hostname,
1591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::string& auth_type) {
1601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    return VERIFY_OK;
1611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber////////////////////////////////////////////////////////////////////////////////
1641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1651156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfDelegate::SfDelegate()
1661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    : mOwner(NULL),
1671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mURLRequest(NULL),
1681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mReadBuffer(new net::IOBufferWithSize(8192)),
1691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mNumBytesRead(0),
1701156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mNumBytesTotal(0),
1711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mDataDestination(NULL),
1721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber      mAtEOS(false) {
1731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    InitializeNetworkThreadIfNecessary();
1741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1761156dc913a5ba7b2bc86489468d4914430f03d14Andreas HuberSfDelegate::~SfDelegate() {
1771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK(mURLRequest == NULL);
1781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::setOwner(ChromiumHTTPDataSource *owner) {
1811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mOwner = owner;
1821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnReceivedRedirect(
185cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
1861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnReceivedRedirect");
1871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnAuthRequired(
190cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, net::AuthChallengeInfo *auth_info) {
1911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnAuthRequired");
1921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    inherited::OnAuthRequired(request, auth_info);
1941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
1951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
1961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnCertificateRequested(
197cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
1981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnCertificateRequested");
1991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    inherited::OnCertificateRequested(request, cert_request_info);
2011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnSSLCertificateError(
204cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen            net::URLRequest *request, int cert_error, net::X509Certificate *cert) {
2051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
2061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    inherited::OnSSLCertificateError(request, cert_error, cert);
2081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
210cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::OnGetCookies(net::URLRequest *request, bool blocked_by_policy) {
2111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnGetCookies");
2121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnSetCookie(
215cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen        net::URLRequest *request,
2161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const std::string &cookie_line,
2171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const net::CookieOptions &options,
2181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        bool blocked_by_policy) {
2191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGI("OnSetCookie");
2201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
222cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::OnResponseStarted(net::URLRequest *request) {
22364125da2f3b76f2d88bb757cb6bf5bd5e29a0639Kristian Monsen    if (request->status().status() != net::URLRequestStatus::SUCCESS) {
2241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "Request failed with status %d and os_error %d",
2261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().status(),
2271156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().os_error()).c_str());
2281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        delete mURLRequest;
2301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest = NULL;
2311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onConnectionFailed(ERROR_IO);
2331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    } else if (mRangeRequested && request->GetResponseCode() != 206) {
2351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "We requested a content range, but server didn't "
2371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "support that. (responded with %d)",
2381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->GetResponseCode()).c_str());
2391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        delete mURLRequest;
2411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest = NULL;
2421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onConnectionFailed(-EPIPE);
2441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    } else if ((request->GetResponseCode() / 100) != 2) {
2461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "Server responded with http status %d",
2481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->GetResponseCode()).c_str());
2491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        delete mURLRequest;
2511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest = NULL;
2521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onConnectionFailed(ERROR_IO);
2541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
2561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGV("OnResponseStarted");
2581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    std::string headers;
2601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    request->GetAllResponseHeaders(&headers);
2611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str());
2631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2646511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    std::string contentType;
2656511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    request->GetResponseHeaderByName("Content-Type", &contentType);
2666511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber
2676511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber    mOwner->onConnectionEstablished(
2686511c9755c3a3360ba869772600c7aae048a7ffcAndreas Huber            request->GetExpectedContentSize(), contentType.c_str());
2691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
2701156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
271cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::OnReadCompleted(net::URLRequest *request, int bytes_read) {
2721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (bytes_read == -1) {
2731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "OnReadCompleted, read failed, status %d",
2751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().status()).c_str());
2761156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(ERROR_IO);
2781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
2801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str());
2821156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (bytes_read < 0) {
2841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        MY_LOGI(StringPrintf(
2851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    "Read failed w/ status %d\n",
2861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    request->status().status()).c_str());
2871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(ERROR_IO);
2891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    } else if (bytes_read == 0) {
2911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mAtEOS = true;
2921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(mNumBytesRead);
2931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
2941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
2951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK_GT(bytes_read, 0);
2971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal);
2981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
2991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    memcpy((uint8_t *)mDataDestination + mNumBytesRead,
3001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber           mReadBuffer->data(),
3011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber           bytes_read);
3021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mNumBytesRead += bytes_read;
3041156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    readMore(request);
3061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
308cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsenvoid SfDelegate::readMore(net::URLRequest *request) {
3091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    while (mNumBytesRead < mNumBytesTotal) {
3101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        size_t copy = mNumBytesTotal - mNumBytesRead;
3111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (copy > mReadBuffer->size()) {
3121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            copy = mReadBuffer->size();
3131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
3141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        int n;
3161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (request->Read(mReadBuffer, copy, &n)) {
3171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str());
3181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            CHECK_LE((size_t)n, copy);
3201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            memcpy((uint8_t *)mDataDestination + mNumBytesRead,
3221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                   mReadBuffer->data(),
3231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                   n);
3241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            mNumBytesRead += n;
3261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3271156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            if (n == 0) {
3281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                mAtEOS = true;
3291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                break;
3301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            }
3311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        } else {
3321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            MY_LOGV("readMore pending read");
3331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
33464125da2f3b76f2d88bb757cb6bf5bd5e29a0639Kristian Monsen            if (request->status().status() != net::URLRequestStatus::IO_PENDING) {
3351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                MY_LOGI(StringPrintf(
3361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                            "Direct read failed w/ status %d\n",
3371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                            request->status().status()).c_str());
3381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                mOwner->onReadCompleted(ERROR_IO);
3401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                return;
3411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            }
3421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            return;
3441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
3451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
3461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mOwner->onReadCompleted(mNumBytesRead);
3481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::initiateConnection(
3511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const char *uri,
3521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const KeyedVector<String8, String8> *headers,
3531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        off64_t offset) {
3541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    GURL url(uri);
3551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MessageLoop *loop = gNetworkThread->message_loop();
3571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    loop->PostTask(
3581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            FROM_HERE,
3591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NewRunnableFunction(
3601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                &SfDelegate::OnInitiateConnectionWrapper,
3611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                this,
3621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                url,
3631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                headers,
3641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                offset));
3651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber// static
3691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnInitiateConnectionWrapper(
3701156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        SfDelegate *me, GURL url,
3711156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const KeyedVector<String8, String8> *headers,
3721156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        off64_t offset) {
3731156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    me->onInitiateConnection(url, headers, offset);
3741156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
3751156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3761156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::onInitiateConnection(
3771156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const GURL &url,
3781156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        const KeyedVector<String8, String8> *extra,
3791156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        off64_t offset) {
3801156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK(mURLRequest == NULL);
3811156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
382cd45ccddb00662f2af8409b895fbcdd0434da8b1Kristian Monsen    mURLRequest = new net::URLRequest(url, this);
3831156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mAtEOS = false;
3841156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3851156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mRangeRequested = false;
3861156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3871156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (offset != 0 || extra != NULL) {
3881156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        net::HttpRequestHeaders headers =
3891156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            mURLRequest->extra_request_headers();
3901156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3911156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (offset != 0) {
3921156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            headers.AddHeaderFromString(
3931156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                    StringPrintf("Range: bytes=%lld-", offset).c_str());
3941156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3951156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            mRangeRequested = true;
3961156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
3971156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
3981156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        if (extra != NULL) {
3991156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            for (size_t i = 0; i < extra->size(); ++i) {
4001156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                AString s;
4011156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                s.append(extra->keyAt(i).string());
4021156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                s.append(": ");
4031156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                s.append(extra->valueAt(i).string());
4041156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4051156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                headers.AddHeaderFromString(s.c_str());
4061156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            }
4071156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        }
4081156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4091156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mURLRequest->SetExtraRequestHeaders(headers);
4101156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
4111156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4121156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest->set_context(gReqContext);
4131156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4141156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest->Start();
4151156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4161156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4171156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::initiateDisconnect() {
4181156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MessageLoop *loop = gNetworkThread->message_loop();
4191156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    loop->PostTask(
4201156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            FROM_HERE,
4211156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NewRunnableFunction(
4221156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                &SfDelegate::OnInitiateDisconnectWrapper, this));
4231156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4241156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4251156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber// static
4261156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) {
4271156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    me->onInitiateDisconnect();
4281156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4291156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4301156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::onInitiateDisconnect() {
4311156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest->Cancel();
4321156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4331156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    delete mURLRequest;
4341156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mURLRequest = NULL;
4351156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4361156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mOwner->onDisconnectComplete();
4371156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4381156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4391156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::initiateRead(void *data, size_t size) {
4401156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    MessageLoop *loop = gNetworkThread->message_loop();
4411156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    loop->PostTask(
4421156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            FROM_HERE,
4431156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber            NewRunnableFunction(
4441156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber                &SfDelegate::OnInitiateReadWrapper, this, data, size));
4451156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4461156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4471156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber// static
4481156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::OnInitiateReadWrapper(
4491156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        SfDelegate *me, void *data, size_t size) {
4501156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    me->onInitiateRead(data, size);
4511156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4521156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4531156dc913a5ba7b2bc86489468d4914430f03d14Andreas Hubervoid SfDelegate::onInitiateRead(void *data, size_t size) {
4541156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    CHECK(mURLRequest != NULL);
4551156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4561156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mNumBytesRead = 0;
4571156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mNumBytesTotal = size;
4581156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    mDataDestination = data;
4591156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4601156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    if (mAtEOS) {
4611156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        mOwner->onReadCompleted(0);
4621156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber        return;
4631156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    }
4641156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4651156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber    readMore(mURLRequest);
4661156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}
4671156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
4681156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber}  // namespace android
4691156dc913a5ba7b2bc86489468d4914430f03d14Andreas Huber
470