diff options
author | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-21 03:59:04 +0000 |
---|---|---|
committer | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-21 03:59:04 +0000 |
commit | 80f584d94f57afdfddeba1fa7384ed409cd91273 (patch) | |
tree | d6e51ebde489e245e98e56ca061c0dce78895d63 /webkit/appcache | |
parent | 204e936d3b0455b0c55f2dc5713f8a84b55e0cbf (diff) | |
download | chromium_src-80f584d94f57afdfddeba1fa7384ed409cd91273.zip chromium_src-80f584d94f57afdfddeba1fa7384ed409cd91273.tar.gz chromium_src-80f584d94f57afdfddeba1fa7384ed409cd91273.tar.bz2 |
Support for playing back media from the appcache.
* add the appcache_host_id to resource requests
* support for byte-range requests
TEST=manual
BUG=none
Review URL: http://codereview.chromium.org/550040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36727 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/appcache')
-rw-r--r-- | webkit/appcache/appcache_response.cc | 6 | ||||
-rw-r--r-- | webkit/appcache/appcache_response.h | 4 | ||||
-rw-r--r-- | webkit/appcache/appcache_url_request_job.cc | 65 | ||||
-rw-r--r-- | webkit/appcache/appcache_url_request_job.h | 13 | ||||
-rw-r--r-- | webkit/appcache/web_application_cache_host_impl.cc | 18 | ||||
-rw-r--r-- | webkit/appcache/web_application_cache_host_impl.h | 7 |
6 files changed, 108 insertions, 5 deletions
diff --git a/webkit/appcache/appcache_response.cc b/webkit/appcache/appcache_response.cc index f9af38e..68b7f09 100644 --- a/webkit/appcache/appcache_response.cc +++ b/webkit/appcache/appcache_response.cc @@ -179,6 +179,12 @@ void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len, buf, buf_len); } +int AppCacheResponseReader::GetResourceSize() { + if (!OpenEntryIfNeeded()) + return -1; + return entry_->GetDataSize(kResponseContentIndex); +} + void AppCacheResponseReader::SetReadRange(int offset, int length) { DCHECK(!IsReadPending() && !read_position_); range_offset_ = offset; diff --git a/webkit/appcache/appcache_response.h b/webkit/appcache/appcache_response.h index f8ffcc6..68538e7 100644 --- a/webkit/appcache/appcache_response.h +++ b/webkit/appcache/appcache_response.h @@ -131,6 +131,10 @@ class AppCacheResponseReader : public AppCacheResponseIO { // Returns true if there is a read operation, for data or info, pending. bool IsReadPending() { return IsIOPending(); } + // Returns the size of the resource in the disk cache or a negative value + // if there is no disk cache entry. + int GetResourceSize(); + // Used to support range requests. If not called, the reader will // read the entire response body. If called, this must be called prior // to the first call to the ReadData method. diff --git a/webkit/appcache/appcache_url_request_job.cc b/webkit/appcache/appcache_url_request_job.cc index 4a6e4ae..a616394 100644 --- a/webkit/appcache/appcache_url_request_job.cc +++ b/webkit/appcache/appcache_url_request_job.cc @@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "webkit/appcache/appcache_url_request_job.h" #include "base/message_loop.h" +#include "base/string_util.h" +#include "net/http/http_util.h" #include "net/url_request/url_request_status.h" namespace appcache { @@ -97,6 +101,10 @@ void AppCacheURLRequestJob::OnResponseInfoLoaded( info_ = response_info; reader_.reset( storage_->CreateResponseReader(manifest_url_, entry_.response_id())); + + if (is_range_request()) + SetupRangeResponse(); + NotifyHeadersComplete(); } else { NotifyStartError( @@ -105,6 +113,53 @@ void AppCacheURLRequestJob::OnResponseInfoLoaded( storage_ = NULL; // no longer needed } +const net::HttpResponseInfo* AppCacheURLRequestJob::http_info() const { + if (!info_.get()) + return NULL; + if (range_response_info_.get()) + return range_response_info_.get(); + return info_->http_response_info(); +} + +void AppCacheURLRequestJob::SetupRangeResponse() { + DCHECK(is_range_request() && reader_.get() && + is_delivering_appcache_response()); + int resource_size = reader_->GetResourceSize(); + if (resource_size < 0 || !range_requested_.ComputeBounds(resource_size)) { + range_requested_ = net::HttpByteRange(); + return; + } + + DCHECK(range_requested_.HasFirstBytePosition() && + range_requested_.HasLastBytePosition()); + int offset = static_cast<int>(range_requested_.first_byte_position()); + int length = static_cast<int>(range_requested_.last_byte_position() - + range_requested_.first_byte_position() + 1); + + // Tell the reader about the range to read. + reader_->SetReadRange(offset, length); + + // Make a copy of the full response headers and fix them up + // for the range we'll be returning. + const char kLengthHeader[] = "Content-Length"; + const char kRangeHeader[] = "Content-Range"; + const char kPartialStatusLine[] = "HTTP/1.1 206 Partial Content"; + range_response_info_.reset( + new net::HttpResponseInfo(*info_->http_response_info())); + net::HttpResponseHeaders* headers = range_response_info_->headers; + headers->RemoveHeader(kLengthHeader); + headers->RemoveHeader(kRangeHeader); + headers->ReplaceStatusLine(kPartialStatusLine); + headers->AddHeader( + StringPrintf("%s: %d", kLengthHeader, length)); + headers->AddHeader( + StringPrintf("%s: bytes %d-%d/%d", + kRangeHeader, + offset, + offset + length - 1, + resource_size)); +} + void AppCacheURLRequestJob::OnReadComplete(int result) { DCHECK(is_delivering_appcache_response()); if (result == 0) @@ -186,5 +241,15 @@ bool AppCacheURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size, return false; } +void AppCacheURLRequestJob::SetExtraRequestHeaders( + const std::string& headers) { + // If multiple ranges are requested, we play dumb and + // return the entire response with 200 OK. + std::vector<net::HttpByteRange> ranges; + if (!net::HttpUtil::ParseRanges(headers, &ranges) || (ranges.size() > 1U)) + return; + range_requested_ = ranges[0]; +} + } // namespace appcache diff --git a/webkit/appcache/appcache_url_request_job.h b/webkit/appcache/appcache_url_request_job.h index fe87361..dab6f22 100644 --- a/webkit/appcache/appcache_url_request_job.h +++ b/webkit/appcache/appcache_url_request_job.h @@ -7,6 +7,7 @@ #include <string> +#include "net/http/http_byte_range.h" #include "net/url_request/url_request_job.h" #include "webkit/appcache/appcache_entry.h" #include "webkit/appcache/appcache_response.h" @@ -91,9 +92,9 @@ class AppCacheURLRequestJob : public URLRequestJob, virtual void OnResponseInfoLoaded( AppCacheResponseInfo* response_info, int64 response_id); - const net::HttpResponseInfo* http_info() const { - return info_.get() ? info_->http_response_info() : NULL; - } + const net::HttpResponseInfo* http_info() const; + bool is_range_request() const { return range_requested_.IsValid(); } + void SetupRangeResponse(); // AppCacheResponseReader completion callback void OnReadComplete(int result); @@ -106,8 +107,8 @@ class AppCacheURLRequestJob : public URLRequestJob, virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); // Sets extra request headers for Job types that support request headers. - // TODO(michaeln): support for range-requests - virtual void SetExtraRequestHeaders(const std::string& headers) {} + // This is how we get informed of range-requests. + virtual void SetExtraRequestHeaders(const std::string& headers); // TODO(michaeln): does this apply to our cached responses? // The payload we store should have been fully decoded prior to @@ -131,6 +132,8 @@ class AppCacheURLRequestJob : public URLRequestJob, int64 cache_id_; AppCacheEntry entry_; scoped_refptr<AppCacheResponseInfo> info_; + net::HttpByteRange range_requested_; + scoped_ptr<net::HttpResponseInfo> range_response_info_; scoped_ptr<AppCacheResponseReader> reader_; net::CompletionCallbackImpl<AppCacheURLRequestJob> read_callback_; }; diff --git a/webkit/appcache/web_application_cache_host_impl.cc b/webkit/appcache/web_application_cache_host_impl.cc index b6586de..8db6aa9 100644 --- a/webkit/appcache/web_application_cache_host_impl.cc +++ b/webkit/appcache/web_application_cache_host_impl.cc @@ -7,12 +7,16 @@ #include "base/compiler_specific.h" #include "base/id_map.h" #include "base/string_util.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDataSource.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" using WebKit::WebApplicationCacheHost; using WebKit::WebApplicationCacheHostClient; +using WebKit::WebDataSource; +using WebKit::WebFrame; using WebKit::WebURLRequest; using WebKit::WebURL; using WebKit::WebURLResponse; @@ -25,6 +29,20 @@ WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromId(int id) { return all_hosts.Lookup(id); } +WebApplicationCacheHostImpl* WebApplicationCacheHostImpl::FromFrame( + WebFrame* frame) { + if (!frame) + return NULL; + WebDataSource* data_source = frame->dataSource(); + if (!data_source) + return NULL; + return NULL; + // TODO(michaeln): Uncomment after the new webkit api is available, + // (see https://bugs.webkit.org/show_bug.cgi?id=33880) + // return static_cast<WebApplicationCacheHostImpl*> + // (data_source->applicationCacheHost()); +} + WebApplicationCacheHostImpl::WebApplicationCacheHostImpl( WebApplicationCacheHostClient* client, AppCacheBackend* backend) diff --git a/webkit/appcache/web_application_cache_host_impl.h b/webkit/appcache/web_application_cache_host_impl.h index e5e529e..bb73e9a 100644 --- a/webkit/appcache/web_application_cache_host_impl.h +++ b/webkit/appcache/web_application_cache_host_impl.h @@ -10,6 +10,10 @@ #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "webkit/appcache/appcache_interfaces.h" +namespace WebKit { +class WebFrame; +} + namespace appcache { class WebApplicationCacheHostImpl : public WebKit::WebApplicationCacheHost { @@ -17,6 +21,9 @@ class WebApplicationCacheHostImpl : public WebKit::WebApplicationCacheHost { // Returns the host having given id or NULL if there is no such host. static WebApplicationCacheHostImpl* FromId(int id); + // Returns the host associated with the current document in frame. + static WebApplicationCacheHostImpl* FromFrame(WebKit::WebFrame* frame); + WebApplicationCacheHostImpl(WebKit::WebApplicationCacheHostClient* client, AppCacheBackend* backend); virtual ~WebApplicationCacheHostImpl(); |