#ifndef Resource_h
#define Resource_h
-#include "core/fetch/CachePolicy.h"
#include "core/fetch/ResourceLoaderOptions.h"
#include "platform/Timer.h"
#include "platform/network/ResourceError.h"
namespace WebCore {
+struct FetchInitiatorInfo;
class MemoryCache;
class CachedMetadata;
class ResourceClient;
virtual void appendData(const char*, int);
virtual void error(Resource::Status);
+ void setNeedsSynchronousCacheHit(bool needsSynchronousCacheHit) { m_needsSynchronousCacheHit = needsSynchronousCacheHit; }
+
void setResourceError(const ResourceError& error) { m_error = error; }
const ResourceError& resourceError() const { return m_error; }
Status status() const { return static_cast<Status>(m_status); }
void setStatus(Status status) { m_status = status; }
- unsigned size() const { return encodedSize() + decodedSize() + overheadSize(); }
- unsigned encodedSize() const { return m_encodedSize; }
- unsigned decodedSize() const { return m_decodedSize; }
- unsigned overheadSize() const;
+ size_t size() const { return encodedSize() + decodedSize() + overheadSize(); }
+ size_t encodedSize() const { return m_encodedSize; }
+ size_t decodedSize() const { return m_decodedSize; }
+ size_t overheadSize() const;
bool isLoaded() const { return !m_loading; } // FIXME. Method name is inaccurate. Loading might not have started yet.
SharedBuffer* resourceBuffer() const { ASSERT(!m_purgeableData); return m_data.get(); }
void setResourceBuffer(PassRefPtr<SharedBuffer>);
- virtual void willSendRequest(ResourceRequest&, const ResourceResponse&) { m_requestedFromNetworkingLayer = true; }
+ virtual void willSendRequest(ResourceRequest&, const ResourceResponse&);
+
+ virtual void updateRequest(const ResourceRequest&) { }
virtual void responseReceived(const ResourceResponse&);
void setResponse(const ResourceResponse& response) { m_response = response; }
const ResourceResponse& response() const { return m_response; }
// Returns cached metadata of the given type associated with this resource.
CachedMetadata* cachedMetadata(unsigned dataTypeID) const;
- bool canDelete() const { return !hasClients() && !m_loader && !m_preloadCount && !m_handleCount && !m_resourceToRevalidate && !m_proxyResource; }
+ bool canDelete() const { return !hasClients() && !m_loader && !m_preloadCount && !m_handleCount && !m_protectorCount && !m_resourceToRevalidate && !m_proxyResource; }
bool hasOneHandle() const { return m_handleCount == 1; }
- bool isExpired() const;
-
// List of acceptable MIME types separated by ",".
// A MIME type may contain a wildcard, e.g. "text/*".
AtomicString accept() const { return m_accept; }
bool errorOccurred() const { return m_status == LoadError || m_status == DecodeError; }
bool loadFailedOrCanceled() { return !m_error.isNull(); }
- bool shouldSendResourceLoadCallbacks() const { return m_options.sendLoadCallbacks == SendCallbacks; }
DataBufferingPolicy dataBufferingPolicy() const { return m_options.dataBufferingPolicy; }
-
- virtual void destroyDecodedData() { }
+ void setDataBufferingPolicy(DataBufferingPolicy);
bool isPreloaded() const { return m_preloadCount; }
void increasePreloadCount() { ++m_preloadCount; }
void registerHandle(ResourcePtrBase* h);
void unregisterHandle(ResourcePtrBase* h);
+ bool canReuseRedirectChain() const;
+ bool mustRevalidateDueToCacheHeaders() const;
bool canUseCacheValidator() const;
- bool mustRevalidateDueToCacheHeaders(CachePolicy) const;
bool isCacheValidator() const { return m_resourceToRevalidate; }
Resource* resourceToRevalidate() const { return m_resourceToRevalidate; }
void setResourceToRevalidate(Resource*);
bool isPurgeable() const;
bool wasPurged() const;
-
- // This is used by the archive machinery to get at a purged resource without
- // triggering a load. We should make it protected again if we can find a
- // better way to handle the archive case.
- bool makePurgeable(bool purgeable);
+ bool lock();
virtual void didSendData(unsigned long long /* bytesSent */, unsigned long long /* totalBytesToBeSent */) { }
virtual void didDownloadData(int) { }
virtual bool canReuse(const ResourceRequest&) const { return true; }
+ void prune();
+
+ static const char* resourceTypeToString(Type, const FetchInitiatorInfo&);
+
protected:
virtual void checkNotify();
virtual void finishOnePart();
- void setEncodedSize(unsigned);
- void setDecodedSize(unsigned);
- void didAccessDecodedData(double timeStamp);
+ // Normal resource pointers will silently switch what Resource* they reference when we
+ // successfully revalidated the resource. We need a way to guarantee that the Resource
+ // that received the 304 response survives long enough to switch everything over to the
+ // revalidatedresource. The normal mechanisms for keeping a Resource alive externally
+ // (ResourcePtrs and ResourceClients registering themselves) don't work in this case, so
+ // have a separate internal protector).
+ class InternalResourcePtr {
+ public:
+ explicit InternalResourcePtr(Resource* resource)
+ : m_resource(resource)
+ {
+ m_resource->incrementProtectorCount();
+ }
+
+ ~InternalResourcePtr()
+ {
+ m_resource->decrementProtectorCount();
+ m_resource->deleteIfPossible();
+ }
+ private:
+ Resource* m_resource;
+ };
- bool isSafeToMakePurgeable() const;
+ void incrementProtectorCount() { m_protectorCount++; }
+ void decrementProtectorCount() { m_protectorCount--; }
+
+ void setEncodedSize(size_t);
+ void setDecodedSize(size_t);
+ void didAccessDecodedData(double timeStamp);
virtual void switchClientsToRevalidatedResource();
void clearResourceToRevalidate();
bool hasClient(ResourceClient* client) { return m_clients.contains(client) || m_clientsAwaitingCallback.contains(client); }
+ struct RedirectPair {
+ public:
+ explicit RedirectPair(const ResourceRequest& request, const ResourceResponse& redirectResponse)
+ : m_request(request)
+ , m_redirectResponse(redirectResponse)
+ {
+ }
+
+ const ResourceRequest m_request;
+ const ResourceResponse m_redirectResponse;
+ };
+ const Vector<RedirectPair>& redirectChain() const { return m_redirectChain; }
+
+ virtual bool isSafeToUnlock() const { return false; }
+ virtual void destroyDecodedDataIfPossible() { }
+
ResourceRequest m_resourceRequest;
AtomicString m_accept;
RefPtr<ResourceLoader> m_loader;
void revalidationSucceeded(const ResourceResponse&);
void revalidationFailed();
- double currentAge() const;
- double freshnessLifetime() const;
+ bool unlock();
void failBeforeStarting();
unsigned long m_identifier;
- unsigned m_encodedSize;
- unsigned m_decodedSize;
+ size_t m_encodedSize;
+ size_t m_decodedSize;
unsigned m_accessCount;
unsigned m_handleCount;
unsigned m_preloadCount;
+ unsigned m_protectorCount;
unsigned m_preloadResult : 2; // PreloadResult
unsigned m_cacheLiveResourcePriority : 2; // CacheLiveResourcePriority
unsigned m_type : 4; // Type
unsigned m_status : 3; // Status
+ unsigned m_wasPurged : 1;
+
+ unsigned m_needsSynchronousCacheHit : 1;
+
#ifndef NDEBUG
bool m_deleted;
unsigned m_lruIndex;
// These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response.
HashSet<ResourcePtrBase*> m_handlesToRevalidate;
+
+ // Ordered list of all redirects followed while fetching this resource.
+ Vector<RedirectPair> m_redirectChain;
};
#if !LOG_DISABLED
const char* ResourceTypeName(Resource::Type);
#endif
+#define DEFINE_RESOURCE_TYPE_CASTS(typeName) \
+ DEFINE_TYPE_CASTS(typeName##Resource, Resource, resource, resource->type() == Resource::typeName, resource.type() == Resource::typeName); \
+ inline typeName##Resource* to##typeName##Resource(const ResourcePtr<Resource>& ptr) { return to##typeName##Resource(ptr.get()); }
+
}
#endif