18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "loader.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Cache.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedImage.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedResource.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CString.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocLoader.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDocument.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Request.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceHandle.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceRequest.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ResourceResponse.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SecurityOrigin.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SubresourceLoader.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h>
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
449b6dda97f056112bed1755d9d49c34d709db299cPatrick Scott#define REQUEST_MANAGEMENT_ENABLED 1
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define REQUEST_DEBUG 0
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if REQUEST_MANAGEMENT_ENABLED
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Match the parallel connection count used by the networking layer
515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic unsigned maxRequestsInFlightPerHost;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Having a limit might still help getting more important resources first
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const unsigned maxRequestsInFlightForNonHTTPProtocols = 20;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const unsigned maxRequestsInFlightPerHost = 10000;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const unsigned maxRequestsInFlightForNonHTTPProtocols = 10000;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLoader::Loader()
605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    : m_requestTimer(this, &Loader::requestTimerFired)
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_isSuspendingPendingRequests(false)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_nonHTTPProtocolHost = Host::create(AtomicString(), maxRequestsInFlightForNonHTTPProtocols);
645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if REQUEST_MANAGEMENT_ENABLED
655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    maxRequestsInFlightPerHost = initializeMaximumHTTPConnectionCountPerHost();
665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLoader::~Loader()
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource::Type type)
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (type) {
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case CachedResource::CSSStyleSheet:
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#if ENABLE(XSLT)
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case CachedResource::XSLStyleSheet:
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#if ENABLE(XBL)
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case CachedResource::XBL:
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return ResourceRequest::TargetIsStyleSheet;
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case CachedResource::Script:
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return ResourceRequest::TargetIsScript;
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case CachedResource::FontResource:
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return ResourceRequest::TargetIsFontResource;
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case CachedResource::ImageResource:
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return ResourceRequest::TargetIsImage;
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return ResourceRequest::TargetIsSubresource;
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLoader::Priority Loader::determinePriority(const CachedResource* resource) const
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if REQUEST_MANAGEMENT_ENABLED
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (resource->type()) {
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CachedResource::CSSStyleSheet:
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(XSLT)
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CachedResource::XSLStyleSheet:
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(XBL)
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CachedResource::XBL:
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return High;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CachedResource::Script:
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CachedResource::FontResource:
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return Medium;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case CachedResource::ImageResource:
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return Low;
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT_NOT_REACHED();
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Low;
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return High;
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
120d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid Loader::load(DocLoader* docLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(docLoader);
123d0825bca7fe65beaee391d30da42e937db621564Steve Block    Request* request = new Request(docLoader, resource, incremental, securityCheck, sendResourceLoadCallbacks);
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Host> host;
126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    KURL url(ParsedURLString, resource->url());
1275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (url.protocolInHTTPFamily()) {
128d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_hosts.checkConsistency();
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        AtomicString hostName = url.host();
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        host = m_hosts.get(hostName.impl());
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!host) {
1325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            host = Host::create(hostName, maxRequestsInFlightPerHost);
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_hosts.add(hostName.impl(), host);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        host = m_nonHTTPProtocolHost;
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hadRequests = host->hasRequests();
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Priority priority = determinePriority(resource);
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    host->addRequest(request, priority);
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    docLoader->incrementRequestCount();
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (priority > Low || !url.protocolInHTTPFamily() || !hadRequests) {
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Try to request important resources immediately
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        host->servePendingRequests(priority);
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Handle asynchronously so early low priority requests don't get scheduled before later high priority ones
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        scheduleServePendingRequests();
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::scheduleServePendingRequests()
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_requestTimer.isActive())
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_requestTimer.startOneShot(0);
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::requestTimerFired(Timer<Loader>*)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    servePendingRequests();
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::servePendingRequests(Priority minimumPriority)
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_isSuspendingPendingRequests)
1665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
1675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_requestTimer.stop();
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_nonHTTPProtocolHost->servePendingRequests(minimumPriority);
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<Host*> hostsToServe;
173d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_hosts.checkConsistency();
1745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HostMap::iterator i = m_hosts.begin();
1755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HostMap::iterator end = m_hosts.end();
1765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (;i != end; ++i)
1775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        hostsToServe.append(i->second.get());
1785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < hostsToServe.size(); ++n) {
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Host* host = hostsToServe[n];
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (host->hasRequests())
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            host->servePendingRequests(minimumPriority);
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (!host->processingResource()){
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            AtomicString name = host->name();
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_hosts.remove(name.impl());
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Loader::suspendPendingRequests()
1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(!m_isSuspendingPendingRequests);
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_isSuspendingPendingRequests = true;
1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Loader::resumePendingRequests()
1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(m_isSuspendingPendingRequests);
1995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_isSuspendingPendingRequests = false;
2005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!m_hosts.isEmpty() || m_nonHTTPProtocolHost->hasRequests())
2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        scheduleServePendingRequests();
2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid Loader::nonCacheRequestInFlight(const KURL& url)
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!url.protocolInHTTPFamily())
2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    AtomicString hostName = url.host();
210d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_hosts.checkConsistency();
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RefPtr<Host> host = m_hosts.get(hostName.impl());
2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!host) {
2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        host = Host::create(hostName, maxRequestsInFlightPerHost);
2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_hosts.add(hostName.impl(), host);
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    host->nonCacheRequestInFlight();
2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid Loader::nonCacheRequestComplete(const KURL& url)
2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!url.protocolInHTTPFamily())
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    AtomicString hostName = url.host();
226d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_hosts.checkConsistency();
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    RefPtr<Host> host = m_hosts.get(hostName.impl());
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(host);
2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!host)
2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    host->nonCacheRequestComplete();
2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::cancelRequests(DocLoader* docLoader)
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    docLoader->clearPendingPreloads();
2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_nonHTTPProtocolHost->hasRequests())
2405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_nonHTTPProtocolHost->cancelRequests(docLoader);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<Host*> hostsToCancel;
243d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_hosts.checkConsistency();
2445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HostMap::iterator i = m_hosts.begin();
2455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HostMap::iterator end = m_hosts.end();
2465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    for (;i != end; ++i)
2475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        hostsToCancel.append(i->second.get());
2485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < hostsToCancel.size(); ++n) {
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Host* host = hostsToCancel[n];
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (host->hasRequests())
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            host->cancelRequests(docLoader);
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    scheduleServePendingRequests();
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(docLoader->requestCount() == (docLoader->loadInProgress() ? 1 : 0));
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLoader::Host::Host(const AtomicString& name, unsigned maxRequestsInFlight)
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_name(name)
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_maxRequestsInFlight(maxRequestsInFlight)
263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_numResourcesProcessing(0)
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_nonCachedRequestsInFlight(0)
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectLoader::Host::~Host()
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_requestsLoading.isEmpty());
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned p = 0; p <= High; p++)
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_requestsPending[p].isEmpty());
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::addRequest(Request* request, Priority priority)
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_requestsPending[priority].append(request);
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid Loader::Host::nonCacheRequestInFlight()
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ++m_nonCachedRequestsInFlight;
2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid Loader::Host::nonCacheRequestComplete()
2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    --m_nonCachedRequestsInFlight;
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(m_nonCachedRequestsInFlight >= 0);
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Loader::Host::hasRequests() const
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_requestsLoading.isEmpty())
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned p = 0; p <= High; p++) {
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_requestsPending[p].isEmpty())
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::servePendingRequests(Loader::Priority minimumPriority)
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (cache()->loader()->isSuspendingPendingRequests())
3055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
3065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool serveMore = true;
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int priority = High; priority >= minimumPriority && serveMore; --priority)
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        servePendingRequests(m_requestsPending[priority], serveMore);
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority)
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (!requestsPending.isEmpty()) {
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Request* request = requestsPending.first();
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        DocLoader* docLoader = request->docLoader();
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing
3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // and we don't know all stylesheets yet.
3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        bool shouldLimitRequests = !m_name.isNull() || docLoader->doc()->parsing() || !docLoader->doc()->haveStylesheetsLoaded();
3230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) {
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            serveLowerPriority = false;
3258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block            cache()->loader()->scheduleServePendingRequests();
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        requestsPending.removeFirst();
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ResourceRequest resourceRequest(request->cachedResource()->url());
331643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type()));
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!request->cachedResource()->accept().isEmpty())
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            resourceRequest.setHTTPAccept(request->cachedResource()->accept());
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian         // Do not set the referrer or HTTP origin here. That's handled by SubresourceLoader::create.
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (resourceIsCacheValidator) {
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(resourceToRevalidate->canUseCacheValidator());
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(resourceToRevalidate->isLoaded());
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!lastModified.isEmpty() || !eTag.isEmpty()) {
345635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                ASSERT(docLoader->cachePolicy() != CachePolicyReload);
346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (docLoader->cachePolicy() == CachePolicyRevalidate)
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!lastModified.isEmpty())
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!eTag.isEmpty())
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
356d0825bca7fe65beaee391d30da42e937db621564Steve Block            this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (loader) {
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_requestsLoading.add(loader.release(), request);
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            request->cachedResource()->setRequestedFromNetworkingLayer();
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if REQUEST_DEBUG
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            docLoader->decrementRequestCount();
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            docLoader->setLoadInProgress(true);
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            request->cachedResource()->error();
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            docLoader->setLoadInProgress(false);
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete request;
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::didFinishLoading(SubresourceLoader* loader)
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Host> myProtector(this);
3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RequestMap::iterator i = m_requestsLoading.find(loader);
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (i == m_requestsLoading.end())
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Request* request = i->second;
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_requestsLoading.remove(i);
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DocLoader* docLoader = request->docLoader();
3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Prevent the document from being destroyed before we are done with
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // the docLoader that it will delete when the document gets deleted.
386231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<Document> protector(docLoader->doc());
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!request->isMultipart())
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        docLoader->decrementRequestCount();
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedResource* resource = request->cachedResource();
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!resource->resourceToRevalidate());
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we got a 4xx response, we're pretending to have received a network
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // error, so we can't send the successful data() and finish() callbacks.
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!resource->errorOccurred()) {
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        docLoader->setLoadInProgress(true);
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resource->data(loader->resourceData(), true);
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resource->finish();
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete request;
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    docLoader->setLoadInProgress(false);
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    docLoader->checkForPendingPreloads();
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if REQUEST_DEBUG
408643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    KURL u(ParsedURLString, resource->url());
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    printf("HOST %s COUNT %d RECEIVED %s\n", u.host().latin1().data(), m_requestsLoading.size(), resource->url().latin1().data());
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    servePendingRequests();
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::didFail(SubresourceLoader* loader, const ResourceError&)
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    didFail(loader);
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Host> myProtector(this);
4225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    loader->clearClient();
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RequestMap::iterator i = m_requestsLoading.find(loader);
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (i == m_requestsLoading.end())
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Request* request = i->second;
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_requestsLoading.remove(i);
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DocLoader* docLoader = request->docLoader();
4328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Prevent the document from being destroyed before we are done with
4338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // the docLoader that it will delete when the document gets deleted.
434231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    RefPtr<Document> protector(docLoader->doc());
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!request->isMultipart())
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        docLoader->decrementRequestCount();
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedResource* resource = request->cachedResource();
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (resource->resourceToRevalidate())
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cache()->revalidationFailed(resource);
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!cancelled) {
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        docLoader->setLoadInProgress(true);
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resource->error();
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    docLoader->setLoadInProgress(false);
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (cancelled || !resource->isPreloaded())
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cache()->remove(resource);
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete request;
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    docLoader->checkForPendingPreloads();
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    servePendingRequests();
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::didReceiveResponse(SubresourceLoader* loader, const ResourceResponse& response)
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Host> protector(this);
4625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Request* request = m_requestsLoading.get(loader);
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: This is a workaround for <rdar://problem/5236843>
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If a load starts while the frame is still in the provisional state
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (this can be the case when loading the user style sheet), committing the load then causes all
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // requests to be removed from the m_requestsLoading map. This means that request might be null here.
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In that case we just return early.
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // ASSERT(request);
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!request)
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedResource* resource = request->cachedResource();
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (resource->isCacheValidator()) {
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (response.httpStatusCode() == 304) {
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // 304 Not modified / Use local copy
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_requestsLoading.remove(loader);
480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            loader->clearClient();
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            request->docLoader()->decrementRequestCount();
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Existing resource is ok, just use it updating the expiration time.
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cache()->revalidationSucceeded(resource, response);
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (request->docLoader()->frame())
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                request->docLoader()->frame()->loader()->checkCompleted();
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete request;
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            servePendingRequests();
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Did not get 304 response, continue as a regular resource load.
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cache()->revalidationFailed(resource);
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
497635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resource->setResponse(response);
499635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String encoding = response.textEncodingName();
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!encoding.isNull())
502635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        resource->setEncoding(encoding);
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (request->isMultipart()) {
505635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(resource->isImage());
506635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        static_cast<CachedImage*>(resource)->clear();
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (request->docLoader()->frame())
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            request->docLoader()->frame()->loader()->checkCompleted();
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (response.isMultipart()) {
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        request->setIsMultipart(true);
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We don't count multiParts in a DocLoader's request count
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        request->docLoader()->decrementRequestCount();
514635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If we get a multipart response, we must have a handle
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(loader->handle());
517635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (!resource->isImage())
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            loader->handle()->cancel();
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::didReceiveData(SubresourceLoader* loader, const char* data, int size)
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Host> protector(this);
5255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Request* request = m_requestsLoading.get(loader);
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!request)
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CachedResource* resource = request->cachedResource();
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!resource->isCacheValidator());
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (resource->errorOccurred())
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (resource->response().httpStatusCode() / 100 == 4) {
5375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Treat a 4xx response like a network error for all resources but images (which will ignore the error and continue to load for
5385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // legacy compatibility).
5395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        resource->httpStatusCodeError();
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Set the data.
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (request->isMultipart()) {
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The loader delivers the data in a multipart section all at once, send eof.
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The resource data will change as the next part is loaded, so we need to make a copy.
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<SharedBuffer> copiedData = SharedBuffer::create(data, size);
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resource->data(copiedData.release(), true);
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (request->isIncremental())
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resource->data(loader->resourceData(), false);
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::cancelPendingRequests(RequestQueue& requestsPending, DocLoader* docLoader)
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RequestQueue remaining;
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RequestQueue::iterator end = requestsPending.end();
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RequestQueue::iterator it = requestsPending.begin(); it != end; ++it) {
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Request* request = *it;
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (request->docLoader() == docLoader) {
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            cache()->remove(request->cachedResource());
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete request;
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            docLoader->decrementRequestCount();
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            remaining.append(request);
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    requestsPending.swap(remaining);
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Loader::Host::cancelRequests(DocLoader* docLoader)
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned p = 0; p <= High; p++)
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cancelPendingRequests(m_requestsPending[p], docLoader);
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<SubresourceLoader*, 256> loadersToCancel;
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RequestMap::iterator end = m_requestsLoading.end();
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (RequestMap::iterator i = m_requestsLoading.begin(); i != end; ++i) {
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Request* r = i->second;
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (r->docLoader() == docLoader)
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            loadersToCancel.append(i->first.get());
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < loadersToCancel.size(); ++i) {
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SubresourceLoader* loader = loadersToCancel[i];
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        didFail(loader, true);
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} //namespace WebCore
590