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