[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

andersca at apple.com andersca at apple.com
Wed Dec 22 11:20:11 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 03b171deda39a856bd0aae8b19f627621d21695a
Author: andersca at apple.com <andersca at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Jul 20 00:07:25 2010 +0000

    Implement NPN_PostURLNotify
    https://bugs.webkit.org/show_bug.cgi?id=42602
    
    Reviewed by Sam Weinig.
    
    WebCore:
    
    Export symbols needed by WebKit2.
    
    * WebCore.exp.in:
    
    WebKit2:
    
    * WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp:
    (WebKit::parsePostBuffer):
    Read the buffer from a file if necessary and parse it.
    
    (WebKit::NPN_GetURLNotify):
    Add extra arguments.
    
    (WebKit::NPN_PostURLNotify):
    Parse the post buffer, then call NetscapePlugin::loadURL.
    
    * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
    (WebKit::NetscapePlugin::loadURL):
    Pass the method, the header fields and form data along.
    
    (WebKit::NetscapePlugin::allowPopups):
    Just return false for now.
    
    (WebKit::NetscapePlugin::initialize):
    Pass extra arguments to loadURL.
    
    * WebProcess/Plugins/Netscape/NetscapePlugin.h:
    * WebProcess/Plugins/PluginController.h:
    Add method, header fields and form data.
    
    * WebProcess/Plugins/PluginView.cpp:
    (WebKit::PluginView::loadURL):
    Set the method, add the header fields and set the body.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63701 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 7692c20..9be1237 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,14 @@
+2010-07-19  Anders Carlsson  <andersca at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Implement NPN_PostURLNotify
+        https://bugs.webkit.org/show_bug.cgi?id=42602
+
+        Export symbols needed by WebKit2.
+
+        * WebCore.exp.in:
+
 2010-07-19  Tony Gentilcore  <tonyg at chromium.org>
 
         Unreviewed build fix.
diff --git a/WebCore/WebCore.exp.in b/WebCore/WebCore.exp.in
index 45ad83c..546021f 100644
--- a/WebCore/WebCore.exp.in
+++ b/WebCore/WebCore.exp.in
@@ -263,6 +263,7 @@ __ZN7WebCore12RenderWidget19showSubstituteImageEN3WTF10PassRefPtrINS_5ImageEEE
 __ZN7WebCore12SchedulePairC1EP9NSRunLoopPK10__CFString
 __ZN7WebCore12SharedBuffer10wrapNSDataEP6NSData
 __ZN7WebCore12SharedBuffer12createNSDataEv
+__ZN7WebCore12SharedBuffer24createWithContentsOfFileERKNS_6StringE
 __ZN7WebCore12SharedBufferD1Ev
 __ZN7WebCore12TextEncodingC1ERKNS_6StringE
 __ZN7WebCore12TextIterator11rangeLengthEPKNS_5RangeEb
@@ -409,7 +410,9 @@ __ZN7WebCore19AnimationController21pauseTransitionAtTimeEPNS_12RenderObjectERKNS
 __ZN7WebCore19BackForwardListImplC1EPNS_4PageE
 __ZN7WebCore19CSSStyleDeclaration11setPropertyERKNS_6StringES3_Ri
 __ZN7WebCore19InspectorController34inspectorStartsAttachedSettingNameEv
+__ZN7WebCore19ResourceRequestBase11setHTTPBodyEN3WTF10PassRefPtrINS_8FormDataEEE
 __ZN7WebCore19ResourceRequestBase13setHTTPMethodERKNS_6StringE
+__ZN7WebCore19ResourceRequestBase19addHTTPHeaderFieldsERKNS_13HTTPHeaderMapE
 __ZN7WebCore19ResourceRequestBase6setURLERKNS_4KURLE
 __ZN7WebCore19SelectionController10setFocusedEb
 __ZN7WebCore19SelectionController12setSelectionERKNS_16VisibleSelectionEbbbNS0_19CursorAlignOnScrollENS_15TextGranularityENS_20DirectionalityPolicyE
@@ -628,6 +631,7 @@ __ZN7WebCore8Document26pageSizeAndMarginsInPixelsEiRNS_7IntSizeERiS3_S3_S3_
 __ZN7WebCore8Document27removeMediaCanStartListenerEPNS_21MediaCanStartListenerE
 __ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv
 __ZN7WebCore8Document4headEv
+__ZN7WebCore8FormData6createEPKvm
 __ZN7WebCore8FormDataD1Ev
 __ZN7WebCore8IntPointC1ERK8_NSPoint
 __ZN7WebCore8PositionC1EN3WTF10PassRefPtrINS_4NodeEEEi
@@ -837,6 +841,7 @@ __ZNK7WebCore12TextIterator4nodeEv
 __ZNK7WebCore12TextIterator5rangeEv
 __ZNK7WebCore13ContainerNode14childNodeCountEv
 __ZNK7WebCore13ContainerNode9childNodeEj
+__ZNK7WebCore13HTTPHeaderMap3getEPKc
 __ZNK7WebCore13HitTestResult10isLiveLinkEv
 __ZNK7WebCore13HitTestResult10isSelectedEv
 __ZNK7WebCore13HitTestResult11targetFrameEv
diff --git a/WebKit2/ChangeLog b/WebKit2/ChangeLog
index 7d8fafb..ec0aa9b 100644
--- a/WebKit2/ChangeLog
+++ b/WebKit2/ChangeLog
@@ -1,3 +1,38 @@
+2010-07-19  Anders Carlsson  <andersca at apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Implement NPN_PostURLNotify
+        https://bugs.webkit.org/show_bug.cgi?id=42602
+
+        * WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp:
+        (WebKit::parsePostBuffer):
+        Read the buffer from a file if necessary and parse it.
+
+        (WebKit::NPN_GetURLNotify):
+        Add extra arguments.
+
+        (WebKit::NPN_PostURLNotify):
+        Parse the post buffer, then call NetscapePlugin::loadURL.
+
+        * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
+        (WebKit::NetscapePlugin::loadURL):
+        Pass the method, the header fields and form data along.
+
+        (WebKit::NetscapePlugin::allowPopups):
+        Just return false for now.
+
+        (WebKit::NetscapePlugin::initialize):
+        Pass extra arguments to loadURL.
+
+        * WebProcess/Plugins/Netscape/NetscapePlugin.h:
+        * WebProcess/Plugins/PluginController.h:
+        Add method, header fields and form data.
+
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::loadURL):
+        Set the method, add the header fields and set the body.
+
 2010-07-19  Sam Weinig  <sam at webkit.org>
 
         Reviewed by Darin Adler.
diff --git a/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp b/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp
index 0af9b57..1a6f707 100644
--- a/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp
+++ b/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp
@@ -28,12 +28,225 @@
 #include "NPRuntimeUtilities.h"
 #include "NetscapePlugin.h"
 #include "NotImplemented.h"
+#include <WebCore/HTTPHeaderMap.h>
 #include <WebCore/IdentifierRep.h>
+#include <WebCore/SharedBuffer.h>
+#include <utility>
 
 using namespace WebCore;
+using namespace std;
 
 namespace WebKit {
+
+static bool startsWithBlankLine(const char* bytes, unsigned length)
+{
+    return length > 0 && bytes[0] == '\n';
+}
+
+static int locationAfterFirstBlankLine(const char* bytes, unsigned length)
+{
+    for (unsigned i = 0; i < length - 4; i++) {
+        // Support for Acrobat. It sends "\n\n".
+        if (bytes[i] == '\n' && bytes[i + 1] == '\n')
+            return i + 2;
+        
+        // Returns the position after 2 CRLF's or 1 CRLF if it is the first line.
+        if (bytes[i] == '\r' && bytes[i + 1] == '\n') {
+            i += 2;
+            if (i == 2)
+                return i;
+
+            if (bytes[i] == '\n') {
+                // Support for Director. It sends "\r\n\n" (3880387).
+                return i + 1;
+            }
+
+            if (bytes[i] == '\r' && bytes[i + 1] == '\n') {
+                // Support for Flash. It sends "\r\n\r\n" (3758113).
+                return i + 2;
+            }
+        }
+    }
+
+    return -1;
+}
+
+static const char* findEndOfLine(const char* bytes, unsigned length)
+{
+    // According to the HTTP specification EOL is defined as
+    // a CRLF pair. Unfortunately, some servers will use LF
+    // instead. Worse yet, some servers will use a combination
+    // of both (e.g. <header>CRLFLF<body>), so findEOL needs
+    // to be more forgiving. It will now accept CRLF, LF or
+    // CR.
+    //
+    // It returns 0 if EOLF is not found or it will return
+    // a pointer to the first terminating character.
+    for (unsigned i = 0; i < length; i++) {
+        if (bytes[i] == '\n')
+            return bytes + i;
+        if (bytes[i] == '\r') {
+            // Check to see if spanning buffer bounds
+            // (CRLF is across reads). If so, wait for
+            // next read.
+            if (i + 1 == length)
+                break;
+
+            return bytes + i;
+        }
+    }
+
+    return 0;
+}
+
+static String capitalizeRFC822HeaderFieldName(const String& name)
+{
+    bool capitalizeCharacter = true;
+    String result;
+
+    for (unsigned i = 0; i < name.length(); i++) {
+        UChar c;
+
+        if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z')
+            c = toASCIIUpper(name[i]);
+        else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z')
+            c = toASCIILower(name[i]);
+        else
+            c = name[i];
+
+        if (name[i] == '-')
+            capitalizeCharacter = true;
+        else
+            capitalizeCharacter = false;
+
+        result.append(c);
+    }
+
+    return result;
+}
+
+static HTTPHeaderMap parseRFC822HeaderFields(const char* bytes, unsigned length)
+{
+    String lastHeaderKey;
+    HTTPHeaderMap headerFields;
+
+    // Loop over lines until we're past the header, or we can't find any more end-of-lines
+    while (const char* endOfLine = findEndOfLine(bytes, length)) {
+        const char* line = bytes;
+        int lineLength = endOfLine - bytes;
+
+        // Move bytes to the character after the terminator as returned by findEndOfLine.
+        bytes = endOfLine + 1;
+        if ((*endOfLine == '\r') && (*bytes == '\n'))
+            bytes++; // Safe since findEndOfLine won't return a spanning CRLF.
+
+        length -= (bytes - line);
+        if (!lineLength) {
+            // Blank line; we're at the end of the header
+            break;
+        }
+
+        if (*line == ' ' || *line == '\t') {
+            // Continuation of the previous header
+            if (lastHeaderKey.isNull()) {
+                // malformed header; ignore it and continue
+                continue;
+            } 
+            
+            // Merge the continuation of the previous header
+            String currentValue = headerFields.get(lastHeaderKey);
+            String newValue(line, lineLength);
+            
+            headerFields.set(lastHeaderKey, currentValue + newValue);
+        } else {
+            // Brand new header
+            const char* colon = line;
+            while (*colon != ':' && colon != endOfLine)
+                colon++;
+
+            if (colon == endOfLine) {
+                // malformed header; ignore it and continue
+                continue;
+            }
+
+            lastHeaderKey = capitalizeRFC822HeaderFieldName(String(line, colon - line));
+            String value;
+            
+            for (colon++; colon != endOfLine; colon++) {
+                if (*colon != ' ' && *colon != '\t')
+                    break;
+            }
+            if (colon == endOfLine)
+                value = "";
+            else
+                value = String(colon, endOfLine - colon);
+            
+            String oldValue = headerFields.get(lastHeaderKey);
+            if (!oldValue.isNull()) {
+                String tmp = oldValue;
+                tmp += ", ";
+                tmp += value;
+                value = tmp;
+            }
+            
+            headerFields.set(lastHeaderKey, value);
+        }
+    }
+
+    return headerFields;
+}
     
+static NPError parsePostBuffer(bool isFile, const char *buffer, uint32_t length, bool parseHeaders, HTTPHeaderMap& headerFields, Vector<char>& bodyData)
+{
+    RefPtr<SharedBuffer> fileContents;
+    const char* postBuffer = 0;
+    uint32_t postBufferSize = 0;
+
+    if (isFile) {
+        fileContents = SharedBuffer::createWithContentsOfFile(String::fromUTF8(buffer));
+        if (!fileContents)
+            return NPERR_FILE_NOT_FOUND;
+
+        postBuffer = fileContents->data();
+        postBufferSize = fileContents->size();
+    } else {
+        postBuffer = buffer;
+        postBufferSize = length;
+    }
+
+    if (parseHeaders) {
+        if (startsWithBlankLine(postBuffer, postBufferSize)) {
+            postBuffer++;
+            postBufferSize--;
+        } else {
+            int location = locationAfterFirstBlankLine(postBuffer, postBufferSize);
+            if (location != -1) {
+                // If the blank line is somewhere in the middle of the buffer, everything before is the header
+                headerFields = parseRFC822HeaderFields(postBuffer, location);
+                unsigned dataLength = postBufferSize - location;
+                
+                // Sometimes plugins like to set Content-Length themselves when they post,
+                // but WebFoundation does not like that. So we will remove the header
+                // and instead truncate the data to the requested length.
+                String contentLength = headerFields.get("Content-Length");
+                
+                if (!contentLength.isNull())
+                    dataLength = min(contentLength.toInt(), (int)dataLength);
+                headerFields.remove("Content-Length");
+                
+                postBuffer += location;
+                postBufferSize = dataLength;
+                
+            }
+        }
+    }
+
+    ASSERT(bodyData.isEmpty());
+    bodyData.append(postBuffer, postBufferSize);
+
+    return NPERR_NO_ERROR;
+}
+
 static NPError NPN_GetURL(NPP instance, const char* url, const char* target)
 {
     notImplemented();
@@ -138,13 +351,23 @@ static NPError NPN_GetURLNotify(NPP npp, const char* url, const char* target, vo
         return NPERR_GENERIC_ERROR;
 
     RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
-    plugin->loadURL(makeURLString(url), target, true, notifyData);
+    plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<char>(), true, notifyData);
     
     return NPERR_NO_ERROR;
 }
 
-static NPError NPN_PostURLNotify(NPP instance, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData)
+static NPError NPN_PostURLNotify(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData)
 {
+    HTTPHeaderMap headerFields;
+    Vector<char> postData;
+    NPError error = parsePostBuffer(file, buf, len, true, headerFields, postData);
+    if (error != NPERR_NO_ERROR)
+        return error;
+
+    RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp);
+    plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, true, notifyData);
+    return NPERR_NO_ERROR;
+    
     notImplemented();
     return NPERR_GENERIC_ERROR;
 }
diff --git a/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
index 6d67f8c..0976aff 100644
--- a/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
+++ b/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
@@ -28,6 +28,7 @@
 #include "NetscapePluginStream.h"
 #include "PluginController.h"
 #include <WebCore/GraphicsContext.h>
+#include <WebCore/HTTPHeaderMap.h>
 #include <WebCore/IntRect.h>
 #include <WebCore/KURL.h>
 #include <utility>
@@ -101,14 +102,13 @@ const char* NetscapePlugin::userAgent()
     return m_userAgent.data();
 }
 
-void NetscapePlugin::loadURL(const String& urlString, const String& target, bool sendNotification, void* notificationData)
+void NetscapePlugin::loadURL(const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<char>& httpBody,
+                             bool sendNotification, void* notificationData)
 {
     uint64_t requestID = ++m_nextRequestID;
-
-    // FIXME: Handle popups.
-    bool allowPopups = false;
-    m_pluginController->loadURL(requestID, urlString, target, allowPopups);
     
+    m_pluginController->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups());
+
     if (target.isNull()) {
         // The browser is going to send the data in a stream, create a plug-in stream.
         RefPtr<NetscapePluginStream> pluginStream = NetscapePluginStream::create(this, requestID, sendNotification, notificationData);
@@ -249,6 +249,12 @@ void NetscapePlugin::stopAllStreams()
         streams[i]->stop(NPRES_USER_BREAK);
 }
 
+bool NetscapePlugin::allowPopups() const
+{
+    // FIXME: Handle popups.
+    return false;
+}
+
 bool NetscapePlugin::initialize(PluginController* pluginController, const Parameters& parameters)
 {
     ASSERT(!m_pluginController);
@@ -298,7 +304,7 @@ bool NetscapePlugin::initialize(PluginController* pluginController, const Parame
 
     // Load the src URL if needed.
     if (!parameters.url.isEmpty() && shouldLoadSrcURL())
-        loadURL(parameters.url.string(), String(), false, 0);
+        loadURL("GET", parameters.url.string(), String(), HTTPHeaderMap(), Vector<char>(), false, 0);
     
     return true;
 }
diff --git a/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h
index 88b47bd..e6eee84 100644
--- a/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h
+++ b/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h
@@ -31,6 +31,10 @@
 #include <WebCore/IntRect.h>
 #include <WebCore/StringHash.h>
 
+namespace WebCore {
+    class HTTPHeaderMap;
+}
+
 namespace WebKit {
 
 class NetscapePluginStream;
@@ -52,7 +56,8 @@ public:
 
     void invalidate(const NPRect*);
     const char* userAgent();
-    void loadURL(const WebCore::String& urlString, const WebCore::String& target, bool sendNotification, void* notificationData);
+    void loadURL(const WebCore::String& method, const WebCore::String& urlString, const WebCore::String& target, const WebCore::HTTPHeaderMap& headerFields,
+                 const Vector<char>& httpBody, bool sendNotification, void* notificationData);
     NPError destroyStream(NPStream*, NPReason);
 
     // These return retained objects.
@@ -79,12 +84,12 @@ private:
     void callSetWindow();
     bool shouldLoadSrcURL();
     NetscapePluginStream* streamFromID(uint64_t streamID);
+    void stopAllStreams();
+    bool allowPopups() const;
 
     bool platformPostInitialize();
     void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect);
 
-    void stopAllStreams();
-
     // Plugin
     virtual bool initialize(PluginController*, const Parameters&);
     virtual void destroy();
diff --git a/WebKit2/WebProcess/Plugins/PluginController.h b/WebKit2/WebProcess/Plugins/PluginController.h
index bba6dc9..2dd6b8b 100644
--- a/WebKit2/WebProcess/Plugins/PluginController.h
+++ b/WebKit2/WebProcess/Plugins/PluginController.h
@@ -29,6 +29,7 @@
 struct NPObject;
 
 namespace WebCore {
+    class HTTPHeaderMap;
     class IntRect;
     class KURL;
     class String;
@@ -51,7 +52,8 @@ public:
     // fails to load, Plugin::frameDidFailToLoad will be called.
     //
     // If the URL is a JavaScript URL, the JavaScript code will be evaluated and the result sent back using Plugin::didEvaluateJavaScript.
-    virtual void loadURL(uint64_t requestID, const WebCore::String& urlString, const WebCore::String& target, bool allowPopups) = 0;
+    virtual void loadURL(uint64_t requestID, const WebCore::String& method, const WebCore::String& urlString, const WebCore::String& target, 
+                         const WebCore::HTTPHeaderMap& headerFields, const Vector<char>& httpBody, bool allowPopups) = 0;
 
     /// Cancels the load of a stream that was requested by loadURL.
     virtual void cancelStreamLoad(uint64_t streamID) = 0;
diff --git a/WebKit2/WebProcess/Plugins/PluginView.cpp b/WebKit2/WebProcess/Plugins/PluginView.cpp
index 612b46f..9c2466d 100644
--- a/WebKit2/WebProcess/Plugins/PluginView.cpp
+++ b/WebKit2/WebProcess/Plugins/PluginView.cpp
@@ -520,13 +520,16 @@ String PluginView::userAgent(const KURL& url)
     return frame->loader()->client()->userAgent(url);
 }
 
-void PluginView::loadURL(uint64_t requestID, const String& urlString, const String& target, bool allowPopups)
+void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, 
+                         const HTTPHeaderMap& headerFields, const Vector<char>& httpBody, bool allowPopups)
 {
     FrameLoadRequest frameLoadRequest;
     frameLoadRequest.setFrameName(target);
-    frameLoadRequest.resourceRequest().setHTTPMethod("GET");
+    frameLoadRequest.resourceRequest().setHTTPMethod(method);
     frameLoadRequest.resourceRequest().setURL(m_pluginElement->document()->completeURL(urlString));
-    
+    frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields);
+    frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(httpBody.data(), httpBody.size()));
+
     m_pendingURLRequests.append(URLRequest::create(requestID, frameLoadRequest, allowPopups));
     m_pendingURLRequestsTimer.startOneShot(0);
 }
diff --git a/WebKit2/WebProcess/Plugins/PluginView.h b/WebKit2/WebProcess/Plugins/PluginView.h
index 0d82c9c..1036009 100644
--- a/WebKit2/WebProcess/Plugins/PluginView.h
+++ b/WebKit2/WebProcess/Plugins/PluginView.h
@@ -92,7 +92,8 @@ private:
     // PluginController
     virtual void invalidate(const WebCore::IntRect&);
     virtual WebCore::String userAgent(const WebCore::KURL&);
-    virtual void loadURL(uint64_t requestID, const WebCore::String& urlString, const WebCore::String& target, bool allowPopups);
+    virtual void loadURL(uint64_t requestID, const WebCore::String& method, const WebCore::String& urlString, const WebCore::String& target, 
+                         const WebCore::HTTPHeaderMap& headerFields, const Vector<char>& httpBody, bool allowPopups);
     virtual void cancelStreamLoad(uint64_t streamID);
     virtual NPObject* windowScriptNPObject();
     virtual NPObject* pluginElementNPObject();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list