summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorSzabolcs David <davidsz@inf.u-szeged.hu>2020-01-07 17:12:18 +0100
committerSzabolcs David <davidsz@inf.u-szeged.hu>2020-01-20 13:01:08 +0100
commit47f63517d4bb10c0771a8009397df7d5e20ec5cc (patch)
tree01f9594dba369b61fc24c35114119d5385db12c6 /src/core
parent075050991bbdc8c165b5ccf809516e3eaa5ee859 (diff)
Support Range headers in custom URLRequestJobs
This is essential when Chromium tries to load media files in multiple jobs over custom protocols, like qrc. Allow subsequent jobs to continue reading media files from specified positions to avoid media glitches and errors. Task-number: QTBUG-80234 Change-Id: I9a7e98c0cb08b2399b7928ecf026c0deb90a1bcb Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/net/url_request_custom_job.cpp14
-rw-r--r--src/core/net/url_request_custom_job.h2
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp11
3 files changed, 24 insertions, 3 deletions
diff --git a/src/core/net/url_request_custom_job.cpp b/src/core/net/url_request_custom_job.cpp
index 607e8d232..0d4ac620f 100644
--- a/src/core/net/url_request_custom_job.cpp
+++ b/src/core/net/url_request_custom_job.cpp
@@ -62,6 +62,7 @@ URLRequestCustomJob::URLRequestCustomJob(URLRequest *request,
: URLRequestJob(request, networkDelegate)
, m_proxy(new URLRequestCustomJobProxy(this, scheme, profileAdapter))
, m_device(nullptr)
+ , m_firstBytePosition(0)
, m_error(0)
, m_pendingReadSize(0)
, m_pendingReadPos(0)
@@ -184,6 +185,19 @@ bool URLRequestCustomJob::IsRedirectResponse(GURL *location, int *http_status_co
return false;
}
+void URLRequestCustomJob::SetExtraRequestHeaders(const HttpRequestHeaders &headers)
+{
+ std::string rangeHeader;
+ if (headers.GetHeader(HttpRequestHeaders::kRange, &rangeHeader)) {
+ std::vector<HttpByteRange> ranges;
+ if (HttpUtil::ParseRangeHeader(rangeHeader, &ranges)) {
+ // Chromium doesn't support multiple range requests in one single URL request.
+ if (ranges.size() == 1)
+ m_firstBytePosition = ranges[0].first_byte_position();
+ }
+ }
+}
+
int URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/src/core/net/url_request_custom_job.h b/src/core/net/url_request_custom_job.h
index af5a6f8e0..db40b52bb 100644
--- a/src/core/net/url_request_custom_job.h
+++ b/src/core/net/url_request_custom_job.h
@@ -67,6 +67,7 @@ public:
bool GetCharset(std::string *charset) override;
void GetResponseInfo(net::HttpResponseInfo *info) override;
bool IsRedirectResponse(GURL *location, int *http_status_code, bool *insecure_scheme_was_upgraded) override;
+ void SetExtraRequestHeaders(const net::HttpRequestHeaders &headers);
protected:
virtual ~URLRequestCustomJob();
@@ -78,6 +79,7 @@ private:
std::string m_charset;
GURL m_redirect;
QIODevice *m_device;
+ int64_t m_firstBytePosition;
int m_error;
int m_pendingReadSize;
int m_pendingReadPos;
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 72d14450e..27fed7bf2 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -95,9 +95,14 @@ void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device)
if (m_job->m_device && !m_job->m_device->isReadable())
m_job->m_device->open(QIODevice::ReadOnly);
- qint64 size = m_job->m_device ? m_job->m_device->size() : -1;
- if (size > 0)
- m_job->set_expected_content_size(size);
+ if (m_job->m_firstBytePosition > 0)
+ m_job->m_device->seek(m_job->m_firstBytePosition);
+
+ qint64 deviceSize = m_job->m_device ? m_job->m_device->size() : -1;
+ qint64 remainingBytes = deviceSize - m_job->m_firstBytePosition;
+ if (remainingBytes > 0)
+ m_job->set_expected_content_size(remainingBytes);
+
if (m_job->m_device && m_job->m_device->isReadable()) {
m_started = true;
m_job->NotifyHeadersComplete();