summaryrefslogtreecommitdiffstats
path: root/webkit/appcache
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-21 03:59:04 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-21 03:59:04 +0000
commit80f584d94f57afdfddeba1fa7384ed409cd91273 (patch)
treed6e51ebde489e245e98e56ca061c0dce78895d63 /webkit/appcache
parent204e936d3b0455b0c55f2dc5713f8a84b55e0cbf (diff)
downloadchromium_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.cc6
-rw-r--r--webkit/appcache/appcache_response.h4
-rw-r--r--webkit/appcache/appcache_url_request_job.cc65
-rw-r--r--webkit/appcache/appcache_url_request_job.h13
-rw-r--r--webkit/appcache/web_application_cache_host_impl.cc18
-rw-r--r--webkit/appcache/web_application_cache_host_impl.h7
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();