diff -Naur Source.org/WebCore/inspector/CodeGeneratorInspectorStrings.pyc Source/WebCore/inspector/CodeGeneratorInspectorStrings.pyc --- Source.org/WebCore/inspector/CodeGeneratorInspectorStrings.pyc 2014-10-27 23:02:09 +0000 +++ Source/WebCore/inspector/CodeGeneratorInspectorStrings.pyc 2014-11-13 19:32:17 +0000 @@ -1,5 +1,5 @@ ó -€ŸJTc@sddZdZdZdZdZdZdZdZdZd Z d +ÇdTc@sddZdZdZdZdZdZdZdZdZd Z d Z d Z d Z d Z dZdZdS(sp class $domainClassName { public: diff -Naur Source.org/WebCore/platform/network/qt/QNetworkReplyHandler.cpp Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp --- Source.org/WebCore/platform/network/qt/QNetworkReplyHandler.cpp 2014-10-24 18:56:02 +0000 +++ Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp 2014-11-13 22:49:20 +0000 @@ -441,6 +441,7 @@ , m_resourceHandle(handle) , m_loadType(loadType) , m_redirectionTries(gMaxRedirections) + , m_boundariesRead(0) , m_queue(this, deferred) { const ResourceRequest &r = m_resourceHandle->firstRequest(); @@ -581,6 +582,10 @@ m_replyWrapper->reply()->header(QNetworkRequest::ContentLengthHeader).toLongLong(), m_replyWrapper->encoding(), String()); + if (/*m_responseSent && */ response.isMultipart()) + client->didReceiveResponse(m_resourceHandle, response); + /* Missing return? */ + if (url.isLocalFile()) { client->didReceiveResponse(m_resourceHandle, response); return; @@ -627,6 +632,82 @@ client->didReceiveResponse(m_resourceHandle, response); } +bool QNetworkReplyHandler::isMultipartResponse() const +{ + QString contentType = m_replyWrapper->reply()->header(QNetworkRequest::ContentTypeHeader).toString(); + if (contentType.contains("multipart/x-mixed-replace")) + return true; + return false; +} + +void QNetworkReplyHandler::processMultipartResponse(QByteArray* data, ResourceHandleClient* client) +{ + QString contentType = m_replyWrapper->reply()->header(QNetworkRequest::ContentTypeHeader).toString(); + int s = contentType.lastIndexOf("boundary=") + 9; + // The boundary could be given in any number of ways: RFC 2046 section 5.1.1 + // We should use a QRegExp when QByteArray supports it + QString boundary = contentType.mid(s, contentType.length()); + QStringList possibleBoundaries; + possibleBoundaries << "\r\n--" + boundary + "\r\n" + << "--" + boundary + "\r\n" + << "\r\n--\"" + boundary + "\"\r\n" + << "--\"" + boundary + "\"\r\n" + << "\r\n\"" + boundary + "\"\r\n" + << "\"" + boundary + "\"\r\n" + << "\r\n" + boundary + "\r\n" + << boundary + "\r\n"; + + for (int i = 0; i < possibleBoundaries.size(); ++i) { + boundary = possibleBoundaries.at(i); + if (data->indexOf(boundary, 0) != -1) + break; + } + // WebCore needs one complete section of the multipart response at a time. + // It also needs to have one complete section waiting to be rendered when + // the load finishes because it clears the resource's data when it + // processes a section. This means we have to take in each section and + // only send it for processing when we have received the entire next section. + // It also means we will never display the last section. This can be fixed if + // we prevent Loader::Host::didFinishLoading() from trying to load the + // resource's data in the case of a multipart response - which would always + // be empty if we sent multipart sections to the loader as we receive them. + // See https://bugs.webkit.org/show_bug.cgi?id=13759#c4 + int boundaryIndex = 0, prevBoundaryIndex = 0; + while (!boundary.isEmpty() + && (boundaryIndex = data->indexOf(boundary, prevBoundaryIndex)) != -1) { + m_multiPartSection.append(data->mid(prevBoundaryIndex, boundaryIndex - prevBoundaryIndex)); + boundaryIndex += boundary.length(); + prevBoundaryIndex = boundaryIndex; + if (++m_boundariesRead < 2) + continue; + // 2nd boundary marker means we have a previous section ready to render + if (!m_prevMultiPartSection.isEmpty()) { + sendResponseIfNeeded(); + client->didReceiveData(m_resourceHandle, m_prevMultiPartSection.constData(), + m_prevMultiPartSection.length(), m_prevMultiPartSection.length() /*FixMe*/); + } + m_prevMultiPartSection = m_multiPartSection; + m_multiPartSection.clear(); + } + m_multiPartSection.append(data->mid(prevBoundaryIndex, data->length() - prevBoundaryIndex)); +} + +void QNetworkReplyHandler::removeMultipartHeaders(QByteArray* data) +{ + QStringList headers; + headers << "Content-Type" << "Content-Length" + << "Content-Range" << "Content-Disposition" + << "Range" << "Set-Cookie"; + for (int i = 0; i < headers.size(); ++i) { + QString header = headers.at(i); + while (data->indexOf(header) != -1) { + int hs = data->indexOf(header); + int he = data->indexOf("\r\n\r\n", hs) + 4; + data->remove(hs, he - hs); + } + } +} + void QNetworkReplyHandler::redirect(ResourceResponse& response, const QUrl& redirection) { QUrl newUrl = m_replyWrapper->reply()->url().resolved(redirection); @@ -672,6 +753,9 @@ { ASSERT(m_replyWrapper && m_replyWrapper->reply() && !wasAborted() && !m_replyWrapper->wasRedirected()); + if (!isMultipartResponse()) + sendResponseIfNeeded(); + ResourceHandleClient* client = m_resourceHandle->client(); if (!client) return; @@ -679,14 +763,30 @@ qint64 bytesAvailable = m_replyWrapper->reply()->bytesAvailable(); char* buffer = new char[8128]; // smaller than 8192 to fit within 8k including overhead. while (bytesAvailable > 0 && !m_queue.deferSignals()) { - qint64 readSize = m_replyWrapper->reply()->read(buffer, 8128); + QByteArray data = m_replyWrapper->reply()->read(8128); + if (data.isEmpty()) + return; + + qint64 readSize = data.length(); if (readSize <= 0) break; bytesAvailable -= readSize; + + // For now we just support multipart-responses on the assumption + // that they are bound to an image object, so we remove headers + // and boundary markers and send the raw image data only. + // FIXME: We need to handle multipart responses bound to iframes. + if (isMultipartResponse()) { + removeMultipartHeaders(&data); + processMultipartResponse(&data, client); + return; + } + // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793 // -1 means we do not provide any data about transfer size to inspector so it would use // Content-Length headers or content size to show transfer size. - client->didReceiveData(m_resourceHandle, buffer, readSize, -1); + client->didReceiveData(m_resourceHandle, data.constData(), readSize, -1); + // Check if the request has been aborted or this reply-handler was otherwise released. if (wasAborted() || !m_replyWrapper) break; diff -Naur Source.org/WebCore/platform/network/qt/QNetworkReplyHandler.h Source/WebCore/platform/network/qt/QNetworkReplyHandler.h --- Source.org/WebCore/platform/network/qt/QNetworkReplyHandler.h 2014-10-24 18:50:47 +0000 +++ Source/WebCore/platform/network/qt/QNetworkReplyHandler.h 2014-11-13 23:00:15 +0000 @@ -39,6 +39,7 @@ class FormDataIODevice; class ResourceError; class ResourceHandle; +class ResourceHandleClient; class ResourceRequest; class ResourceResponse; class QNetworkReplyHandler; @@ -144,6 +145,9 @@ private: void start(); + void removeMultipartHeaders(QByteArray*); + void processMultipartResponse(QByteArray*, ResourceHandleClient*); + bool isMultipartResponse() const; String httpMethod() const; void redirect(ResourceResponse&, const QUrl&); bool wasAborted() const { return !m_resourceHandle; } @@ -163,6 +167,9 @@ // defer state holding int m_redirectionTries; + int m_boundariesRead; + QByteArray m_multiPartSection; + QByteArray m_prevMultiPartSection; QNetworkReplyHandlerCallQueue m_queue; }; diff -Naur Source.org/WebKit2/Scripts/webkit2/__init__.pyc Source/WebKit2/Scripts/webkit2/__init__.pyc --- Source.org/WebKit2/Scripts/webkit2/__init__.pyc 2014-10-29 13:14:08 +0000 +++ Source/WebKit2/Scripts/webkit2/__init__.pyc 2014-11-14 22:44:17 +0000 @@ -1,2 +1,2 @@ ó -’ŸJTc@sdS(N((((sBC:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\__init__.pyts \ No newline at end of file +qÇdTc@sdS(N((((sBC:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\__init__.pyts \ No newline at end of file diff -Naur Source.org/WebKit2/Scripts/webkit2/messages.pyc Source/WebKit2/Scripts/webkit2/messages.pyc --- Source.org/WebKit2/Scripts/webkit2/messages.pyc 2014-10-29 13:14:08 +0000 +++ Source/WebKit2/Scripts/webkit2/messages.pyc 2014-11-14 22:44:17 +0000 @@ -1,5 +1,5 @@ ó -’ŸJTc@sddlZddlZddlmZdZdZdZdZdZd„Z d „Z +pÇdTc@sddlZddlZddlmZdZdZdZdZdZd„Z d „Z d „Z d „Z d „Z d „Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„ZdS(iÿÿÿÿN(tparsertWantsConnectiontLegacyReceivertDelayedtVariadicsN/* * Copyright (C) 2010 Apple Inc. All rights reserved. diff -Naur Source.org/WebKit2/Scripts/webkit2/model.pyc Source/WebKit2/Scripts/webkit2/model.pyc --- Source.org/WebKit2/Scripts/webkit2/model.pyc 2014-10-29 13:14:08 +0000 +++ Source/WebKit2/Scripts/webkit2/model.pyc 2014-11-14 22:44:17 +0000 @@ -1,5 +1,5 @@ ó -’ŸJTc@sRddlZdefd„ƒYZdefd„ƒYZdefd„ƒYZdS(iÿÿÿÿNtMessageReceivercBs#eZd„Zd„Zd„ZRS(cCs4||_t|pgƒ|_||_||_dS(N(tnamet frozensett +pÇdTc@sRddlZdefd„ƒYZdefd„ƒYZdefd„ƒYZdS(iÿÿÿÿNtMessageReceivercBs#eZd„Zd„Zd„ZRS(cCs4||_t|pgƒ|_||_||_dS(N(tnamet frozensett attributestmessagest condition(tselfRRRR((s?C:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\model.pyt__init__s  cCs*tjd„|jDƒd„|jDƒƒS(Ncss%|]}|jD] }|VqqdS(N(t parameters(t.0tmessaget parameter((s?C:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\model.pys "scss.|]$}|jr|jD] }|VqqdS(N(treply_parameters(R R treply_parameter((s?C:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\model.pys #s(t itertoolstchainR(R((s?C:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\model.pytiterparameters!scCs ||jkS(N(R(Rt attribute((s?C:\project\qt5\qtwebkit\Source\WebKit2\Scripts\webkit2\model.pyt has_attribute%s(t__name__t diff -Naur Source.org/WebKit2/Scripts/webkit2/parser.pyc Source/WebKit2/Scripts/webkit2/parser.pyc --- Source.org/WebKit2/Scripts/webkit2/parser.pyc 2014-10-29 13:14:08 +0000 +++ Source/WebKit2/Scripts/webkit2/parser.pyc 2014-11-14 22:44:17 +0000 @@ -1,5 +1,5 @@ ó -’ŸJTc@sDddlZddlmZd„Zd„Zd„Zd„ZdS(iÿÿÿÿN(tmodelcCsËd}d}g}d}d}x”|D]Œ}tjd|ƒ}|r‚t|jdƒƒ}|rm|}d}n|jdƒ}q%n|jdƒrÑ|jdƒr³|jƒd}q%|jdƒr%d}q%q%ntjd|ƒ}|r%|jƒ\}} } +pÇdTc@sDddlZddlmZd„Zd„Zd„Zd„ZdS(iÿÿÿÿN(tmodelcCsËd}d}g}d}d}x”|D]Œ}tjd|ƒ}|r‚t|jdƒƒ}|rm|}d}n|jdƒ}q%n|jdƒrÑ|jdƒr³|jƒd}q%|jdƒr%d}q%q%ntjd|ƒ}|r%|jƒ\}} } } | r0t| ƒ} x | D]} || _ qWng} t| ƒ}| rqt| ƒ}x5|D]}||_ q[Wn|