Reviewed by Sfalken
authorbeidson <beidson@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Sep 2006 18:22:20 +0000 (18:22 +0000)
committerbeidson <beidson@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Sep 2006 18:22:20 +0000 (18:22 +0000)
        Add redirect and other cleanup to ResourceLoaderWin.cpp

        * WebCore.xcodeproj/project.pbxproj:
        * platform/ResourceLoader.h:
        * platform/win/ResourceLoaderWin.cpp:
        (WebCore::ResourceLoaderWndProc):
        (WebCore::initializeOffScreenResourceLoaderWindow):
        (WebCore::ResourceLoader::onHandleCreated):
        (WebCore::ResourceLoader::onRequestRedirected):
        (WebCore::ResourceLoader::onRequestComplete):
        (WebCore::transferJobStatusCallback):

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

WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/platform/ResourceLoader.h
WebCore/platform/win/ResourceLoaderWin.cpp

index 7877ed63af31c352ab4c64077fa0e4e10f949e0f..70f4dc9cc3c4ce8d050693b958ac50f9a6cef05f 100644 (file)
@@ -1,3 +1,19 @@
+2006-09-22  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Sfalken
+
+        Add redirect and other cleanup to ResourceLoaderWin.cpp
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/ResourceLoader.h:
+        * platform/win/ResourceLoaderWin.cpp:
+        (WebCore::ResourceLoaderWndProc):
+        (WebCore::initializeOffScreenResourceLoaderWindow):
+        (WebCore::ResourceLoader::onHandleCreated):
+        (WebCore::ResourceLoader::onRequestRedirected):
+        (WebCore::ResourceLoader::onRequestComplete):
+        (WebCore::transferJobStatusCallback):
+
 2006-09-22  Alexey Proskuryakov  <ap@nypop.com>
 
         Reviewed by Geoff.
index d7967c365faa9aec130993e29452643a81abed59..006bfc765f47a53dac4140b325313e4166a11d56 100644 (file)
                FAE04190097596C9000540BE /* SVGImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = FAE0418E097596C9000540BE /* SVGImageLoader.h */; };
 /* End PBXBuildFile section */
 
-/* Begin PBXBuildStyle section */
-               BCECF4940AC28367009E0501 /* Development */ = {
-                       isa = PBXBuildStyle;
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                       };
-                       name = Development;
-               };
-               BCECF4950AC28367009E0501 /* Deployment */ = {
-                       isa = PBXBuildStyle;
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                       };
-                       name = Deployment;
-               };
-/* End PBXBuildStyle section */
-
 /* Begin PBXContainerItemProxy section */
                DD041FF009D9E3250010AF2A /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
-                       buildSettings = {
-                       };
-                       buildStyles = (
-                               BCECF4940AC28367009E0501 /* Development */,
-                               BCECF4950AC28367009E0501 /* Deployment */,
-                       );
                        hasScannedForEncodings = 1;
                        knownRegions = (
                                English,
index f31a6aec507be655d5cbe1edd96053a14860747a..01cff97a816883336c8280a13ce7e66e9ffba6bf 100644 (file)
@@ -86,6 +86,9 @@ public:
 
 #if USE(WININET)
     void fileLoadTimer(Timer<ResourceLoader>* timer);
+    void onHandleCreated(LPARAM);
+    void onRequestRedirected(LPARAM);
+    void onRequestComplete(LPARAM);
     friend void __stdcall transferJobStatusCallback(HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD);
     friend LRESULT __stdcall ResourceLoaderWndProc(HWND, unsigned message, WPARAM, LPARAM);
 #endif
index a5790ed663c286ae01a84a5e8bb96dd18ab8a96f..48e3d562cbaca30ec6e01118f96b1f78b87e8b39 100644 (file)
@@ -42,9 +42,24 @@ static unsigned transferJobId = 0;
 static HashMap<int, ResourceLoader*>* jobIdMap = 0;
 
 static HWND transferJobWindowHandle = 0;
-static UINT loadStatusMessage = 0;
 const LPCWSTR kResourceLoaderWindowClassName = L"ResourceLoaderWindowClass";
 
+// Message types for internal use (keep in sync with kMessageHandlers)
+enum {
+  kHandleCreatedMessage = WM_USER,
+  kRequestRedirectedMessage,
+  kRequestCompleteMessage
+};
+
+typedef void (ResourceLoader:: *ResourceLoaderEventHandler)(LPARAM);
+static const ResourceLoaderEventHandler kMessageHandlers[] = {
+    &ResourceLoader::onHandleCreated,
+    &ResourceLoader::onRequestRedirected,
+    &ResourceLoader::onRequestComplete
+};
+static const int kNumMessageHandlers =
+    sizeof(kMessageHandlers) / sizeof(kMessageHandlers[0]);
+
 static int addToOutstandingJobs(ResourceLoader* job)
 {
     if (!jobIdMap)
@@ -68,150 +83,23 @@ static ResourceLoader* lookupResourceLoader(int jobId)
     return jobIdMap->get(jobId);
 }
 
-struct JobLoadStatus {
-    DWORD internetStatus;
-    DWORD_PTR dwResult;
-};
-
-LRESULT CALLBACK ResourceLoaderWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+static LRESULT CALLBACK ResourceLoaderWndProc(HWND hWnd, UINT message,
+                                              WPARAM wParam, LPARAM lParam)
 {
-    if (message == loadStatusMessage) {
-        JobLoadStatus* jobLoadStatus = (JobLoadStatus*)lParam;
-        DWORD internetStatus = jobLoadStatus->internetStatus;
-        DWORD_PTR dwResult = jobLoadStatus->dwResult;
-        delete jobLoadStatus;
-        jobLoadStatus = 0;
-
-        // If we get a message about a job we no longer know about (already deleted), ignore it.
-        unsigned jobId = (unsigned)wParam;
-        ResourceLoader* job = lookupResourceLoader(jobId);
-        if (!job)
-            return 0;
-
-        ASSERT(job->d->m_jobId == jobId);
-        ASSERT(job->d->m_threadId == GetCurrentThreadId());
-
-        if (internetStatus == INTERNET_STATUS_HANDLE_CREATED) {
-            if (!job->d->m_resourceHandle) {
-                job->d->m_resourceHandle = HINTERNET(dwResult);
-                if (job->d->status != 0) {
-                    // We were canceled before Windows actually created a handle for us, close and delete now.
-                    InternetCloseHandle(job->d->m_resourceHandle);
-                    delete job;
-                }
-
-                if (job->method() == "POST") {
-                    // FIXME: Too late to set referrer properly.
-                    DeprecatedString urlStr = job->d->URL.path();
-                    int fragmentIndex = urlStr.find('#');
-                    if (fragmentIndex != -1)
-                        urlStr = urlStr.left(fragmentIndex);
-                    static LPCSTR accept[2]={"*/*", NULL};
-                    HINTERNET urlHandle = HttpOpenRequestA(job->d->m_resourceHandle, 
-                                                           "POST", urlStr.latin1(), 0, 0, accept,
-                                                           INTERNET_FLAG_KEEP_CONNECTION | 
-                                                           INTERNET_FLAG_FORMS_SUBMIT |
-                                                           INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
-                                                           (DWORD_PTR)job->d->m_jobId);
-                    if (urlHandle == INVALID_HANDLE_VALUE) {
-                        InternetCloseHandle(job->d->m_resourceHandle);
-                        delete job;
-                    }
-                }
-            } else if (!job->d->m_secondaryHandle) {
-                assert(job->method() == "POST");
-                job->d->m_secondaryHandle = HINTERNET(dwResult);
-                
-                // Need to actually send the request now.
-                String headers = "Content-Type: application/x-www-form-urlencoded\n";
-                headers += "Referer: ";
-                headers += job->d->m_postReferrer;
-                headers += "\n";
-                String formData = job->postData().flattenToString();
-                INTERNET_BUFFERSA buffers;
-                memset(&buffers, 0, sizeof(buffers));
-                buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
-                buffers.lpcszHeader = headers.latin1();
-                buffers.dwHeadersLength = headers.length();
-                buffers.dwBufferTotal = formData.length();
-                
-                job->d->m_bytesRemainingToWrite = formData.length();
-                job->d->m_formDataString = (char*)malloc(formData.length());
-                job->d->m_formDataLength = formData.length();
-                strncpy(job->d->m_formDataString, formData.latin1(), formData.length());
-                job->d->m_writing = true;
-                HttpSendRequestExA(job->d->m_secondaryHandle, &buffers, 0, 0, (DWORD_PTR)job->d->m_jobId);
-            }
-        } else if (internetStatus == INTERNET_STATUS_REQUEST_COMPLETE) {
-            if (job->d->m_writing) {
-                DWORD bytesWritten;
-                InternetWriteFile(job->d->m_secondaryHandle,
-                                  job->d->m_formDataString + (job->d->m_formDataLength - job->d->m_bytesRemainingToWrite),
-                                  job->d->m_bytesRemainingToWrite,
-                                  &bytesWritten);
-                job->d->m_bytesRemainingToWrite -= bytesWritten;
-                if (!job->d->m_bytesRemainingToWrite) {
-                    // End the request.
-                    job->d->m_writing = false;
-                    HttpEndRequest(job->d->m_secondaryHandle, 0, 0, (DWORD_PTR)job->d->m_jobId);
-                    free(job->d->m_formDataString);
-                    job->d->m_formDataString = 0;
-                }
-                return 0;
-            }
-
-            HINTERNET handle = (job->method() == "POST") ? job->d->m_secondaryHandle : job->d->m_resourceHandle;
-            BOOL ok = FALSE;
-
-            static const int bufferSize = 32768;
-            char buffer[bufferSize];
-            INTERNET_BUFFERSA buffers;
-            buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
-            buffers.lpvBuffer = buffer;
-            buffers.dwBufferLength = bufferSize;
-
-            bool receivedAnyData = false;
-            while ((ok = InternetReadFileExA(handle, &buffers, IRF_NO_WAIT, (DWORD_PTR)job)) && buffers.dwBufferLength) {
-                if (!receivedAnyData) {
-                    receivedAnyData = true;
-                    job->client()->receivedResponse(job, 0);
-                }
-                job->client()->receivedData(job, buffer, buffers.dwBufferLength);
-                buffers.dwBufferLength = bufferSize;
-            }
-
-            PlatformDataStruct platformData;
-            platformData.errorString = 0;
-            platformData.error = 0;
-            platformData.loaded = ok;
-
-            if (!ok) {
-                int error = GetLastError();
-                if (error == ERROR_IO_PENDING)
-                    return 0;
-                else {
-                    DWORD errorStringChars = 0;
-                    if (!InternetGetLastResponseInfo(&platformData.error, 0, &errorStringChars)) {
-                        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
-                            platformData.errorString = new TCHAR[errorStringChars];
-                            InternetGetLastResponseInfo(&platformData.error, platformData.errorString, &errorStringChars);
-                        }
-                    }
-                    _RPTF1(_CRT_WARN, "Load error: %i\n", error);
-                }
+    if (message >= kHandleCreatedMessage) {
+        UINT index = message - kHandleCreatedMessage;
+        if (index < kNumMessageHandlers) {
+            unsigned jobId = (unsigned) wParam;
+            ResourceLoader* job = lookupResourceLoader(jobId);
+            if (job) {
+                ASSERT(job->d->m_jobId == jobId);
+                ASSERT(job->d->m_threadId == GetCurrentThreadId());
+                (job->*(kMessageHandlers[index]))(lParam);
             }
-            
-            if (job->d->m_secondaryHandle)
-                InternetCloseHandle(job->d->m_secondaryHandle);
-            InternetCloseHandle(job->d->m_resourceHandle);
-            
-            job->client()->receivedAllData(job, &platformData);
-            job->client()->receivedAllData(job);
-            delete job;
+            return 0;
         }
-    } else
-        return DefWindowProc(hWnd, message, wParam, lParam);
-    return 0;
+    }
+    return DefWindowProc(hWnd, message, wParam, lParam);
 }
 
 static void initializeOffScreenResourceLoaderWindow()
@@ -229,7 +117,6 @@ static void initializeOffScreenResourceLoaderWindow()
 
     transferJobWindowHandle = CreateWindow(kResourceLoaderWindowClassName, 0, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
         HWND_MESSAGE, 0, Page::instanceHandle(), 0);
-    loadStatusMessage = RegisterWindowMessage(L"com.apple.WebKit.ResourceLoaderLoadStatus");
 }
 
 ResourceLoaderInternal::~ResourceLoaderInternal()
@@ -244,16 +131,176 @@ ResourceLoader::~ResourceLoader()
         removeFromOutstandingJobs(d->m_jobId);
 }
 
-static void __stdcall transferJobStatusCallback(HINTERNET internetHandle, DWORD_PTR timerId, DWORD internetStatus, LPVOID statusInformation, DWORD statusInformationLength)
+void ResourceLoader::onHandleCreated(LPARAM lParam)
+{
+    if (!d->m_resourceHandle) {
+        d->m_resourceHandle = HINTERNET(lParam);
+        if (d->status != 0) {
+            // We were canceled before Windows actually created a handle for us, close and delete now.
+            InternetCloseHandle(d->m_resourceHandle);
+            delete this;
+            return;
+        }
+
+        if (method() == "POST") {
+            // FIXME: Too late to set referrer properly.
+            DeprecatedString urlStr = d->URL.path();
+            int fragmentIndex = urlStr.find('#');
+            if (fragmentIndex != -1)
+                urlStr = urlStr.left(fragmentIndex);
+            static LPCSTR accept[2]={"*/*", NULL};
+            HINTERNET urlHandle = HttpOpenRequestA(d->m_resourceHandle, 
+                                                   "POST", urlStr.latin1(), 0, 0, accept,
+                                                   INTERNET_FLAG_KEEP_CONNECTION | 
+                                                   INTERNET_FLAG_FORMS_SUBMIT |
+                                                   INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
+                                                   (DWORD_PTR)d->m_jobId);
+            if (urlHandle == INVALID_HANDLE_VALUE) {
+                InternetCloseHandle(d->m_resourceHandle);
+                delete this;
+            }
+        }
+    } else if (!d->m_secondaryHandle) {
+        assert(method() == "POST");
+        d->m_secondaryHandle = HINTERNET(lParam);
+        
+        // Need to actually send the request now.
+        String headers = "Content-Type: application/x-www-form-urlencoded\n";
+        headers += "Referer: ";
+        headers += d->m_postReferrer;
+        headers += "\n";
+        String formData = postData().flattenToString();
+        INTERNET_BUFFERSA buffers;
+        memset(&buffers, 0, sizeof(buffers));
+        buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
+        buffers.lpcszHeader = headers.latin1();
+        buffers.dwHeadersLength = headers.length();
+        buffers.dwBufferTotal = formData.length();
+        
+        d->m_bytesRemainingToWrite = formData.length();
+        d->m_formDataString = (char*)malloc(formData.length());
+        d->m_formDataLength = formData.length();
+        strncpy(d->m_formDataString, formData.latin1(), formData.length());
+        d->m_writing = true;
+        HttpSendRequestExA(d->m_secondaryHandle, &buffers, 0, 0, (DWORD_PTR)d->m_jobId);
+    }
+}
+
+void ResourceLoader::onRequestRedirected(LPARAM lParam)
+{
+    // If already canceled, then ignore this event.
+    if (d->status != 0)
+        return;
+
+    KURL url(String((StringImpl*) lParam).deprecatedString());
+    client()->receivedRedirect(this, url);
+}
+
+void ResourceLoader::onRequestComplete(LPARAM lParam)
+{
+    if (d->m_writing) {
+        DWORD bytesWritten;
+        InternetWriteFile(d->m_secondaryHandle,
+                          d->m_formDataString + (d->m_formDataLength - d->m_bytesRemainingToWrite),
+                          d->m_bytesRemainingToWrite,
+                          &bytesWritten);
+        d->m_bytesRemainingToWrite -= bytesWritten;
+        if (!d->m_bytesRemainingToWrite) {
+            // End the request.
+            d->m_writing = false;
+            HttpEndRequest(d->m_secondaryHandle, 0, 0, (DWORD_PTR)d->m_jobId);
+            free(d->m_formDataString);
+            d->m_formDataString = 0;
+        }
+        return;
+    }
+
+    HINTERNET handle = (method() == "POST") ? d->m_secondaryHandle : d->m_resourceHandle;
+    BOOL ok = FALSE;
+
+    static const int bufferSize = 32768;
+    char buffer[bufferSize];
+    INTERNET_BUFFERSA buffers;
+    buffers.dwStructSize = sizeof(INTERNET_BUFFERSA);
+    buffers.lpvBuffer = buffer;
+    buffers.dwBufferLength = bufferSize;
+
+    bool receivedAnyData = false;
+    while ((ok = InternetReadFileExA(handle, &buffers, IRF_NO_WAIT, (DWORD_PTR)this)) && buffers.dwBufferLength) {
+        if (!receivedAnyData) {
+            receivedAnyData = true;
+            client()->receivedResponse(this, 0);
+        }
+        client()->receivedData(this, buffer, buffers.dwBufferLength);
+        buffers.dwBufferLength = bufferSize;
+    }
+
+    PlatformDataStruct platformData;
+    platformData.errorString = 0;
+    platformData.error = 0;
+    platformData.loaded = ok;
+
+    if (!ok) {
+        int error = GetLastError();
+        if (error == ERROR_IO_PENDING)
+            return;
+        DWORD errorStringChars = 0;
+        if (!InternetGetLastResponseInfo(&platformData.error, 0, &errorStringChars)) {
+            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+                platformData.errorString = new TCHAR[errorStringChars];
+                InternetGetLastResponseInfo(&platformData.error, platformData.errorString, &errorStringChars);
+            }
+        }
+        _RPTF1(_CRT_WARN, "Load error: %i\n", error);
+    }
+    
+    if (d->m_secondaryHandle)
+        InternetCloseHandle(d->m_secondaryHandle);
+    InternetCloseHandle(d->m_resourceHandle);
+    
+    client()->receivedAllData(this, &platformData);
+    client()->receivedAllData(this);
+    delete this;
+}
+
+static void __stdcall transferJobStatusCallback(HINTERNET internetHandle,
+                                                DWORD_PTR jobId,
+                                                DWORD internetStatus,
+                                                LPVOID statusInformation,
+                                                DWORD statusInformationLength)
 {
+    UINT msg;
+    LPARAM lParam;
+
     switch (internetStatus) {
     case INTERNET_STATUS_HANDLE_CREATED:
+        // tell the main thread about the newly created handle
+        msg = kHandleCreatedMessage;
+        lParam = (LPARAM) LPINTERNET_ASYNC_RESULT(statusInformation)->dwResult;
+        break;
     case INTERNET_STATUS_REQUEST_COMPLETE:
-        JobLoadStatus* jobLoadStatus = new JobLoadStatus;
-        jobLoadStatus->internetStatus = internetStatus;
-        jobLoadStatus->dwResult = LPINTERNET_ASYNC_RESULT(statusInformation)->dwResult;
-        PostMessage(transferJobWindowHandle, loadStatusMessage, (WPARAM)timerId, (LPARAM)jobLoadStatus);
+        // tell the main thread that the request is done
+        msg = kRequestCompleteMessage;
+        lParam = 0;
+        break;
+    case INTERNET_STATUS_REDIRECT:
+        // tell the main thread to observe this redirect (FIXME: we probably
+        // need to block the redirect at this point so the application can
+        // decide whether or not to follow the redirect)
+        msg = kRequestRedirectedMessage;
+        lParam = (LPARAM) new StringImpl((const UChar*) statusInformation,
+                                         statusInformationLength);
+        break;
+    case INTERNET_STATUS_USER_INPUT_REQUIRED:
+        // FIXME: prompt the user if necessary
+        ResumeSuspendedDownload(internetHandle, 0);
+    case INTERNET_STATUS_STATE_CHANGE:
+        // may need to call ResumeSuspendedDownload here as well
+    default:
+        return;
     }
+
+    PostMessage(transferJobWindowHandle, msg, (WPARAM) jobId, lParam);
 }
 
 bool ResourceLoader::start(DocLoader* docLoader)