2007-07-17 Holger Hans Peter Freyther <zecke@selfish.org>
authorzecke <zecke@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jul 2007 20:51:53 +0000 (20:51 +0000)
committerzecke <zecke@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 17 Jul 2007 20:51:53 +0000 (20:51 +0000)
        Reviewed by Maciej.

        Implement the callback responsible for handling HTTP headers. This
        callback gets called for every header.
        We will add these headers to our ResourceResponse and on the 'end-of-header'
        indicator we will update the ResourceResponse and dispatch it.

        This patch adds various set methods to ResourceResponse. This improves
        the readability of the headerCallback and avoids storing a CURL handle inside
        the ResourceResponse which would be needed to implement ResourceResponse::doUpdateResourceResponse

        Add a destructor for ResourceHandleManager which would free the resources and remove
        a unused variable.

        * platform/network/ResourceHandleInternal.h:
        (WebCore::ResourceHandleInternal::ResourceHandleInternal):
        * platform/network/ResourceResponse.cpp:
        (WebCore::ResourceResponse::setUrl):
        (WebCore::ResourceResponse::setMimeType):
        (WebCore::ResourceResponse::setExpectedContentLength):
        (WebCore::ResourceResponse::setTextEncodingName):
        (WebCore::ResourceResponse::setSuggestedFilename):
        * platform/network/ResourceResponse.h:
        * platform/network/curl/ResourceHandleCurl.cpp:
        (WebCore::ResourceHandleInternal::~ResourceHandleInternal):
        * platform/network/curl/ResourceHandleManager.cpp:
        (WebCore::ResourceHandleManager::~ResourceHandleManager):
        (WebCore::ResourceHandleManager::sharedInstance):
        (WebCore::headerCallback):
        * platform/network/curl/ResourceHandleManager.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@24372 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/network/ResourceHandleInternal.h
WebCore/platform/network/ResourceResponse.cpp
WebCore/platform/network/ResourceResponse.h
WebCore/platform/network/curl/ResourceHandleCurl.cpp
WebCore/platform/network/curl/ResourceHandleManager.cpp
WebCore/platform/network/curl/ResourceHandleManager.h

index a29d45e56e4081f10cbb04161eb93b7456356ee7..bc2d8cc594e56519be9fc8aef9920871601ced4d 100644 (file)
@@ -1,3 +1,36 @@
+2007-07-17  Holger Hans Peter Freyther  <zecke@selfish.org>
+
+        Reviewed by Maciej.
+
+        Implement the callback responsible for handling HTTP headers. This
+        callback gets called for every header.
+        We will add these headers to our ResourceResponse and on the 'end-of-header'
+        indicator we will update the ResourceResponse and dispatch it.
+
+        This patch adds various set methods to ResourceResponse. This improves
+        the readability of the headerCallback and avoids storing a CURL handle inside
+        the ResourceResponse which would be needed to implement ResourceResponse::doUpdateResourceResponse
+
+        Add a destructor for ResourceHandleManager which would free the resources and remove
+        a unused variable.
+
+        * platform/network/ResourceHandleInternal.h:
+        (WebCore::ResourceHandleInternal::ResourceHandleInternal):
+        * platform/network/ResourceResponse.cpp:
+        (WebCore::ResourceResponse::setUrl):
+        (WebCore::ResourceResponse::setMimeType):
+        (WebCore::ResourceResponse::setExpectedContentLength):
+        (WebCore::ResourceResponse::setTextEncodingName):
+        (WebCore::ResourceResponse::setSuggestedFilename):
+        * platform/network/ResourceResponse.h:
+        * platform/network/curl/ResourceHandleCurl.cpp:
+        (WebCore::ResourceHandleInternal::~ResourceHandleInternal):
+        * platform/network/curl/ResourceHandleManager.cpp:
+        (WebCore::ResourceHandleManager::~ResourceHandleManager):
+        (WebCore::ResourceHandleManager::sharedInstance):
+        (WebCore::headerCallback):
+        * platform/network/curl/ResourceHandleManager.h:
+
 2007-07-17  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Adam Roben.
index 37d3ce1345cd793b25311269df04ea9547c7cc34..498729e319e2cff84cb246f542130e856fcceea3 100644 (file)
@@ -94,7 +94,6 @@ namespace WebCore {
             , m_url(0)
             , m_fileName(0)
             , m_customHeaders(0)
-            , m_customPostHeader(0)
 #endif
 #if PLATFORM(QT)
             , m_job(0)
@@ -146,8 +145,8 @@ namespace WebCore {
         char* m_url;
         char* m_fileName;
         struct curl_slist* m_customHeaders;        
-        struct curl_slist* m_customPostHeader;
         Vector<char> m_postBytes;
+        ResourceResponse m_response;
 #endif
 #if PLATFORM(QT)
         QWebNetworkJob *m_job;
index 53d9d403bb3c02058660c652ed0a4cb9699e8144..8a7eb373dabaa43e65ebdb4f0b5f88945c6f2a34 100644 (file)
@@ -45,6 +45,14 @@ const KURL& ResourceResponse::url() const
     return m_url; 
 }
 
+void ResourceResponse::setUrl(const KURL& url)
+{
+    updateResourceResponse();
+    m_isNull = false;
+    
+    m_url = url; 
+}
+
 const String& ResourceResponse::mimeType() const
 {
     updateResourceResponse();
@@ -52,6 +60,14 @@ const String& ResourceResponse::mimeType() const
     return m_mimeType; 
 }
 
+void ResourceResponse::setMimeType(const String& mimeType)
+{
+    updateResourceResponse();
+    m_isNull = false;
+    
+    m_mimeType = mimeType; 
+}
+
 long long ResourceResponse::expectedContentLength() const 
 {
     updateResourceResponse();
@@ -59,6 +75,14 @@ long long ResourceResponse::expectedContentLength() const
     return m_expectedContentLength;
 }
 
+void ResourceResponse::setExpectedContentLength(long long expectedContentLength)
+{
+    updateResourceResponse();
+    m_isNull = false;
+    
+    m_expectedContentLength = expectedContentLength; 
+}
+
 const String& ResourceResponse::textEncodingName() const
 {
     updateResourceResponse();
@@ -66,6 +90,14 @@ const String& ResourceResponse::textEncodingName() const
     return m_textEncodingName;
 }
 
+void ResourceResponse::setTextEncodingName(const String& encodingName)
+{
+    updateResourceResponse();
+    m_isNull = false;
+    
+    m_textEncodingName = encodingName; 
+}
+
 // FIXME should compute this on the fly
 const String& ResourceResponse::suggestedFilename() const
 {
@@ -74,6 +106,14 @@ const String& ResourceResponse::suggestedFilename() const
     return m_suggestedFilename;
 }
 
+void ResourceResponse::setSuggestedFilename(const String& suggestedName)
+{
+    updateResourceResponse();
+    m_isNull = false;
+    
+    m_suggestedFilename = suggestedName; 
+}
+
 int ResourceResponse::httpStatusCode() const
 {
     updateResourceResponse();
index fbdd9507c90cfb7e2b62b5f4184e128c25bc9d92..e0d1328678937e4a57224e0d44596da0aab33866 100644 (file)
@@ -73,12 +73,20 @@ public:
     bool isHTTP() const;
     
     const KURL& url() const;
+    void setUrl(const KURL& url);
+
     const String& mimeType() const;
+    void setMimeType(const String& mimeType);
+
     long long expectedContentLength() const;
+    void setExpectedContentLength(long long expectedContentLength);
+
     const String& textEncodingName() const;
+    void setTextEncodingName(const String& name);
 
     // FIXME should compute this on the fly
     const String& suggestedFilename() const;
+    void setSuggestedFilename(const String&);
 
     int httpStatusCode() const;
     void setHTTPStatusCode(int);
index 8c53b81df042b57f5fb242efc12e244970e20d0e..39bc2254c1c1f9c576c39126bbc0899097d7084f 100644 (file)
@@ -41,8 +41,6 @@ ResourceHandleInternal::~ResourceHandleInternal()
     free(m_fileName);
     if (m_customHeaders)
         curl_slist_free_all(m_customHeaders);
-    if (m_customPostHeader)
-        curl_slist_free_all(m_customPostHeader);
 }
 
 ResourceHandle::~ResourceHandle()
index 823b53c1fdcac692a9fb6c25394658974027f7b3..8db4fa8e09c5bfeb197f71c4588190ac430f2008 100644 (file)
@@ -1,6 +1,8 @@
 /*
  * Copyright (C) 2004, 2006 Apple Computer, Inc.  All rights reserved.
  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
+ * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk>
+ * Copyright (C) 2007 Holger Hans Peter Freyther
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,6 +34,8 @@
 #include "NotImplemented.h"
 #include "ResourceHandle.h"
 #include "ResourceHandleInternal.h"
+#include "HTTPParsers.h"
+
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -51,6 +55,14 @@ ResourceHandleManager::ResourceHandleManager()
     curl_share_setopt(m_curlShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
 }
 
+ResourceHandleManager::~ResourceHandleManager()
+{
+    curl_multi_cleanup(m_curlMultiHandle);
+    curl_share_cleanup(m_curlShareHandle);
+    if (m_cookieJarFileName)
+        free(m_cookieJarFileName);
+}
+
 void ResourceHandleManager::setCookieJarFileName(const char* cookieJarFileName)
 { 
     m_cookieJarFileName = strdup(cookieJarFileName);
@@ -58,7 +70,7 @@ void ResourceHandleManager::setCookieJarFileName(const char* cookieJarFileName)
 
 ResourceHandleManager* ResourceHandleManager::sharedInstance()
 {
-    static ResourceHandleManager* sharedInstance;
+    static ResourceHandleManager* sharedInstance = 0;
     if (!sharedInstance)
         sharedInstance = new ResourceHandleManager();
     return sharedInstance;
@@ -85,11 +97,60 @@ static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data)
     return totalSize;
 }
 
-// This is being called for each HTTP header in the response so it'll be called
-// multiple times for a given response.
+/*
+ * This is being called for each HTTP header in the response. This includes '\r\n'
+ * for the last line of the header.
+ *
+ * We will add each HTTP Header to the ResourceResponse and on the termination
+ * of the header (\r\n) we will parse Content-Type and Content-Disposition and
+ * update the ResourceResponse and then send it away.
+ *
+ */
 static size_t headerCallback(char* ptr, size_t size, size_t nmemb, void* data)
 {
-    int totalSize = size * nmemb;
+    ResourceHandle* job = static_cast<ResourceHandle*>(data);
+    ResourceHandleInternal* d = job->getInternal();
+
+    unsigned int totalSize = size * nmemb;
+    ResourceHandleClient* client = d->client();
+    if (!client) {
+        return totalSize;
+    }
+
+    
+    String header(static_cast<const char*>(ptr), totalSize);
+
+    /*
+     * a) We can finish and send the ResourceResponse
+     * b) We will add the current header to the HTTPHeaderMap of the ResourceResponse 
+     */
+    if (header == String("\r\n")) {
+        CURL* h = d->m_handle;
+        CURLcode err;
+
+        double contentLength = 0;
+        err = curl_easy_getinfo(h, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength);
+        d->m_response.setExpectedContentLength(static_cast<long long int>(contentLength)); 
+
+        const char* hdr;
+        err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
+        d->m_response.setUrl(KURL(hdr));
+
+        long httpCode = 0;
+        err = curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &httpCode);
+        d->m_response.setHTTPStatusCode(httpCode);
+    
+        d->m_response.setMimeType(extractMIMETypeFromMediaType(d->m_response.httpHeaderField("Content-Type")));
+        d->m_response.setTextEncodingName(extractCharsetFromMediaType(d->m_response.httpHeaderField("Content-Type")));
+        d->m_response.setSuggestedFilename(filenameFromHTTPContentDisposition(d->m_response.httpHeaderField("Content-Disposition")));
+
+        client->didReceiveResponse(job, d->m_response);
+    } else {
+        int splitPos = header.find(":");
+        if (splitPos != -1)
+            d->m_response.setHTTPHeaderField(header.left(splitPos), header.substring(splitPos+1).stripWhiteSpace());
+    }
+
     return totalSize;
 }
 
index 19370ee81e71f555e4589b7ec24d6ec592fa0a76..8cb07676c4ae7a7592d96b215fb684787bdad849 100644 (file)
@@ -65,6 +65,7 @@ public:
 
 private:
     ResourceHandleManager();
+    ~ResourceHandleManager();
     void downloadTimerCallback(Timer<ResourceHandleManager>*);
     void removeFromCurl(ResourceHandle*);
     bool removeScheduledJob(ResourceHandle*);
@@ -72,9 +73,9 @@ private:
     bool startScheduledJobs();
 
     Timer<ResourceHandleManager> m_downloadTimer;
-    CURLM* m_curlMultiHandle; // FIXME: never freed
-    CURLSH* m_curlShareHandle; // FIXME: never freed
-    char* m_cookieJarFileName; // FIXME: never freed
+    CURLM* m_curlMultiHandle;
+    CURLSH* m_curlShareHandle;
+    char* m_cookieJarFileName;
     char m_curlErrorBuffer[CURL_ERROR_SIZE];
     ResourceHandleList* m_resourceHandleListHead;
 };