[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677
cblu
cblu at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:27:57 UTC 2009
The following commit has been merged in the debian/unstable branch:
commit cd88c3cb1964e3a7320acf061aa3624cf50cec73
Author: cblu <cblu at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Mar 7 02:37:25 2003 +0000
WebFoundation:
Reviewed by trey.
Added _web_changeFileAttributes:atPath and factored _web_changeFinderAttributes out to its own method.
* Misc.subproj/WebNSFileManagerExtras.h:
* Misc.subproj/WebNSFileManagerExtras.m:
(-[NSFileManager _web_changeFinderAttributes:forFileAtPath:]): was _web_createFileAtPath
(-[NSFileManager _web_changeFileAttributes:atPath:]): call createFileAtPath, then _web_changeFinderAttributes
(-[NSFileManager _web_createFileAtPath:contents:attributes:]): call changeFileAttributes, then _web_changeFinderAttributes
WebKit:
Implemented WebDownload API.
Fixed: 3118355 - Download mechanism that doesn't involve WebDataSource, WebFrame, WebController etc
Fixed: 3110173 - add per-request disabling of download decoding, use to turn off when "Open Safe Files" is off
Reviewed by trey, rjw, mjs.
* Downloads.subproj/WebDownload.h: Tweaked comments, added new methods.
* Downloads.subproj/WebDownload.m:
(-[WebDownloadPrivate dealloc]): release new objects
(-[WebDownload initWithRequest:]): was initWithRequest:delegate:, but found that starting the load from the init method made it tricky to do other set up work before the load started.
(-[WebDownload _initWithLoadingResource:dataSource:]): private init method, "catches up" to load by sending delegate method immediately, doesn't retain the dataSource, uses it for info
(-[WebDownload loadWithDelegate:]): new, starts load
(-[WebDownload cancel]): cancel load with no error
(-[WebDownload path]): simple getter
(-[WebDownload setPath:]): implement this because WebDownload is the WebDownloadDecisionListener, call _setPath
(-[WebDownload resource:willSendRequest:]): resource delegate method
(-[WebDownload resource:didReceiveResponse:]): resource delegate method
(-[WebDownload resource:didReceiveData:]): resource delegate method, decode and write data, cancel load if error
(-[WebDownload resourceDidFinishLoading:]): resource delegate method, decode and write data if necessary, end in error if error
(-[WebDownload resource:didFailLoadingWithError:]): resource delegate method, end in error
(-[WebDownload _pathWithUniqueFilenameForPath:]): this work was done in _createFileIfNecessary, does what it says
(-[WebDownload _createFSRefForPath:]): this work was done in _createFileIfNecessary as well, makes fileRefPtr point to a file
(-[WebDownload _createFileIfNecessary]): creates file, creates temp file if path hasn't been set yet
(-[WebDownload _decodeHeaderData:dataForkData:resourceForkData:]): call private method
(-[WebDownload _decodeData:dataForkData:resourceForkData:]): made private, if the download is encoded, ask client if OK to decode
(-[WebDownload _decodeData:]): hardly changed, don't cancel, just return error
(-[WebDownload _dataIfDoneBufferingData:]): moved, not changed
(-[WebDownload _finishDecoding]): hardly changed, don't cancel, just return error
(-[WebDownload _writeForkData:isDataFork:]): moved, not changed
(-[WebDownload _writeDataForkData:resourceForkData:]): moved, not changed
(-[WebDownload _isFileClosed]): new
(-[WebDownload _fileDidClose:]): new, called by the callback thread, delete file if deleteFile flag is set, report error or end successfully
(-[WebDownload _closeForkAsync:]): new
(-[WebDownload _closeForkSync:]): new
(-[WebDownload _closeFileAsync]): new
(-[WebDownload _closeFileSync]): new
(-[WebDownload _deleteFileAsnyc]): new
(-[WebDownload _closeAndDeleteFileAsync]): new
(-[WebDownload _cancelWithError:]): kill load if there is one, report error if there is one, close and delete file is not already closed or deleted
(-[WebDownload _cancelWithErrorCode:]): internal convenienve, calls _cancelWithError
(-[WebDownload _setPath:]): set path, if we are already saving data to a temp path, move the file and continue downloading
(-[WebDownload _currentPath]): new
(-[WebDownload _errorWithCode:]): new
(-[WebDownload _dataForkReferenceNumber]): added underscore
(-[WebDownload _setDataForkReferenceNumber:]): added underscore
(-[WebDownload _resourceForkReferenceNumber]): added underscore
(-[WebDownload _setResourceForkReferenceNumber:]): added underscore
(-[WebDownload _areWritesCancelled]): added underscore
(-[WebDownload _setWritesCancelled:]): added underscore
(-[WebDownload _encounteredCloseError]): new
(-[WebDownload _setEncounteredCloseError:]): new
(WriteCompletionCallback): call underscored methods
(CloseCompletionCallback): call underscored methods, handle close error, don't delete file
(DeleteCompletionCallback): call _currentPath
* Downloads.subproj/WebDownloadPrivate.h:
* WebView.subproj/WebBaseResourceHandleDelegate.h: renamed handle to resource
* WebView.subproj/WebBaseResourceHandleDelegate.m: renamed handle to resource
(-[WebBaseResourceHandleDelegate _releaseResources]): renamed handle to resource
(-[WebBaseResourceHandleDelegate startLoading:]): renamed handle to resource
(-[WebBaseResourceHandleDelegate loadWithRequest:]): renamed handle to resource
(-[WebBaseResourceHandleDelegate setDefersCallbacks:]): renamed handle to resource
(-[WebBaseResourceHandleDelegate resource:willSendRequest:]): renamed handle to resource
(-[WebBaseResourceHandleDelegate resource:didReceiveResponse:]): renamed handle to resource, don't handle downloads
(-[WebBaseResourceHandleDelegate resource:didReceiveData:]): renamed handle to resource, don't handle downloads
(-[WebBaseResourceHandleDelegate resourceDidFinishLoading:]): renamed handle to resource, don't handle downloads
(-[WebBaseResourceHandleDelegate resource:didFailLoadingWithError:]): renamed handle to resource, don't handle downloads
(-[WebBaseResourceHandleDelegate cancelWithError:]): renamed handle to resource, don't handle downloads
* WebView.subproj/WebController.h: updated comments
* WebView.subproj/WebController.m:
(-[WebController setDownloadDelegate:]): call the ivar downloadDelegate, not downloadProgressDelegate
(-[WebController downloadDelegate]): call the ivar downloadDelegate, not downloadProgressDelegate
* WebView.subproj/WebControllerPolicyDelegate.h: removed saveFilenameForResponse:andRequest:, handle by WebDownload
* WebView.subproj/WebControllerPrivate.h: call the ivar downloadDelegate, not downloadProgressDelegate
* WebView.subproj/WebDefaultPolicyDelegate.m: removed saveFilenameForResponse:andRequest:, handle by WebDownload
* WebView.subproj/WebMainResourceClient.h: added WebResourceDelegateProxy icar
* WebView.subproj/WebMainResourceClient.m: remove most download related stuff
(-[WebMainResourceClient initWithDataSource:]): create a WebResourceDelegateProxy which allows us to change the resource delegate
(-[WebMainResourceClient dealloc]): release the proxy
(-[WebMainResourceClient receivedError:complete:]): don't handle downloads
(-[WebMainResourceClient continueAfterContentPolicy:response:]): pass the load off to the download
(-[WebMainResourceClient resource:didReceiveResponse:]): don't handle downloads
(-[WebMainResourceClient resource:didReceiveData:]): don't handle downloads
(-[WebMainResourceClient resourceDidFinishLoading:]): don't handle downloads
(-[WebMainResourceClient resource:didFailLoadingWithError:]): don't handle downloads
(-[WebMainResourceClient startLoading:]): make the proxy the delegate
(-[WebResourceDelegateProxy setDelegate:]): switches the resource delegate
(-[WebResourceDelegateProxy resource:willSendRequest:]): forwards message
(-[WebResourceDelegateProxy resource:didReceiveResponse:]): forwards message
(-[WebResourceDelegateProxy resource:didReceiveData:]): forwards message
(-[WebResourceDelegateProxy resourceDidFinishLoading:]): forwards message
(-[WebResourceDelegateProxy resource:didFailLoadingWithError:]): forwards message
WebBrowser:
Made WebBrowser use the WebDownload API. Most of the changes involved switching from a WebDataSource to a WebDownload to represent a download.
Fixed: 3118355 - Download mechanism that doesn't involve WebDataSource, WebFrame, WebController etc
Fixed: 3110173 - add per-request disabling of download decoding, use to turn off when "Open Safe Files" is off
Reviewed by trey.
* BrowserWebController.m: Removed savePathForResponse:: because it is handled by the WebDownload API
* BrowserWebErrorExtras.m: Define WebErrorDomainBrowser in here not in DownloadMonitor.
* DownloadMonitor.h:
* DownloadMonitor.m:
(-[DownloadMonitor _loadDownloadHistory]): call DownloadProgressEntry init method, not class constructor
(-[DownloadMonitor init]):
(-[DownloadMonitor download:didStartFromDataSource:]): new WebDownload API, reuse a DownloadProgressEntry if reloading, else create a new one
(-[DownloadMonitor download:willSendRequest:]): new WebDownload API
(-[DownloadMonitor download:didReceiveResponse:]): new WebDownload API
(-[DownloadMonitor download:decidePathWithListener:suggestedFilename:]): new WebDownload API, set path immediately
(-[DownloadMonitor download:didReceiveDataOfLength:]): new WebDownload API
(-[DownloadMonitor downloadShouldDecodeEncodedFile:]): new WebDownload API, return YES if "Open Safe Downloads" is enabled
(-[DownloadMonitor download:didCreateFileAtPath:]): new WebDownload API
(-[DownloadMonitor downloadDidFinishDownloading:]): new WebDownload API
(-[DownloadMonitor download:didFailDownloadingWithError:]): new WebDownload API
(-[DownloadMonitor downloadMayBeOpenedForDataSource:]): use renamed dictionary
(-[DownloadMonitor setEntry:forReloadingDownload:]):
* DownloadProgressEntry.h:
* DownloadProgressEntry.m:
(-[DownloadProgressEntry _setDownload:]): new, replaces setDataSource
(-[DownloadProgressEntry dealloc]): release the response
(-[DownloadProgressEntry setResponse:]): new
(-[DownloadProgressEntry response]): new
(-[DownloadProgressEntry filename]): handle the nil path case (a DownloadProgressEntry now will be created before the file exists)
(-[DownloadProgressEntry setPath:]): added comments
(-[DownloadProgressEntry fileExists]): handle the nil path
(-[DownloadProgressEntry open]): assert for nil path
(-[DownloadProgressEntry stop]): cancel the download
(-[DownloadProgressEntry reload]): No need to involve all the WebKit machinery to do a download. Phew!
(-[DownloadProgressEntry reveal]): handle the nil path
(-[DownloadProgressEntry setDownloadStage:]): don't do anything if the set stage is the same as the current
(-[DownloadProgressEntry _openDiskCopyFile]): assert for nil path
(-[DownloadProgressEntry _openInstallerPackage]): assert for nil path
(-[DownloadProgressEntry autoOpen]): assert for nil path
(-[DownloadProgressEntry setDone:]): release and set download to nil
(-[NSFileManager _pathForSingleItemAtPath:]): assert for nil path
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3772 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 2bcee76..24f6e8c 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,98 @@
+2003-03-06 Chris Blumenberg <cblu at apple.com>
+
+ Implemented WebDownload API.
+
+ Fixed: 3118355 - Download mechanism that doesn't involve WebDataSource, WebFrame, WebController etc
+ Fixed: 3110173 - add per-request disabling of download decoding, use to turn off when "Open Safe Files" is off
+
+ Reviewed by trey, rjw, mjs.
+
+ * Downloads.subproj/WebDownload.h: Tweaked comments, added new methods.
+ * Downloads.subproj/WebDownload.m:
+ (-[WebDownloadPrivate dealloc]): release new objects
+ (-[WebDownload initWithRequest:]): was initWithRequest:delegate:, but found that starting the load from the init method made it tricky to do other set up work before the load started.
+ (-[WebDownload _initWithLoadingResource:dataSource:]): private init method, "catches up" to load by sending delegate method immediately, doesn't retain the dataSource, uses it for info
+ (-[WebDownload loadWithDelegate:]): new, starts load
+ (-[WebDownload cancel]): cancel load with no error
+ (-[WebDownload path]): simple getter
+ (-[WebDownload setPath:]): implement this because WebDownload is the WebDownloadDecisionListener, call _setPath
+ (-[WebDownload resource:willSendRequest:]): resource delegate method
+ (-[WebDownload resource:didReceiveResponse:]): resource delegate method
+ (-[WebDownload resource:didReceiveData:]): resource delegate method, decode and write data, cancel load if error
+ (-[WebDownload resourceDidFinishLoading:]): resource delegate method, decode and write data if necessary, end in error if error
+ (-[WebDownload resource:didFailLoadingWithError:]): resource delegate method, end in error
+ (-[WebDownload _pathWithUniqueFilenameForPath:]): this work was done in _createFileIfNecessary, does what it says
+ (-[WebDownload _createFSRefForPath:]): this work was done in _createFileIfNecessary as well, makes fileRefPtr point to a file
+ (-[WebDownload _createFileIfNecessary]): creates file, creates temp file if path hasn't been set yet
+ (-[WebDownload _decodeHeaderData:dataForkData:resourceForkData:]): call private method
+ (-[WebDownload _decodeData:dataForkData:resourceForkData:]): made private, if the download is encoded, ask client if OK to decode
+ (-[WebDownload _decodeData:]): hardly changed, don't cancel, just return error
+ (-[WebDownload _dataIfDoneBufferingData:]): moved, not changed
+ (-[WebDownload _finishDecoding]): hardly changed, don't cancel, just return error
+ (-[WebDownload _writeForkData:isDataFork:]): moved, not changed
+ (-[WebDownload _writeDataForkData:resourceForkData:]): moved, not changed
+ (-[WebDownload _isFileClosed]): new
+ (-[WebDownload _fileDidClose:]): new, called by the callback thread, delete file if deleteFile flag is set, report error or end successfully
+ (-[WebDownload _closeForkAsync:]): new
+ (-[WebDownload _closeForkSync:]): new
+ (-[WebDownload _closeFileAsync]): new
+ (-[WebDownload _closeFileSync]): new
+ (-[WebDownload _deleteFileAsnyc]): new
+ (-[WebDownload _closeAndDeleteFileAsync]): new
+ (-[WebDownload _cancelWithError:]): kill load if there is one, report error if there is one, close and delete file is not already closed or deleted
+ (-[WebDownload _cancelWithErrorCode:]): internal convenienve, calls _cancelWithError
+ (-[WebDownload _setPath:]): set path, if we are already saving data to a temp path, move the file and continue downloading
+ (-[WebDownload _currentPath]): new
+ (-[WebDownload _errorWithCode:]): new
+ (-[WebDownload _dataForkReferenceNumber]): added underscore
+ (-[WebDownload _setDataForkReferenceNumber:]): added underscore
+ (-[WebDownload _resourceForkReferenceNumber]): added underscore
+ (-[WebDownload _setResourceForkReferenceNumber:]): added underscore
+ (-[WebDownload _areWritesCancelled]): added underscore
+ (-[WebDownload _setWritesCancelled:]): added underscore
+ (-[WebDownload _encounteredCloseError]): new
+ (-[WebDownload _setEncounteredCloseError:]): new
+ (WriteCompletionCallback): call underscored methods
+ (CloseCompletionCallback): call underscored methods, handle close error, don't delete file
+ (DeleteCompletionCallback): call _currentPath
+ * Downloads.subproj/WebDownloadPrivate.h:
+ * WebView.subproj/WebBaseResourceHandleDelegate.h: renamed handle to resource
+ * WebView.subproj/WebBaseResourceHandleDelegate.m: renamed handle to resource
+ (-[WebBaseResourceHandleDelegate _releaseResources]): renamed handle to resource
+ (-[WebBaseResourceHandleDelegate startLoading:]): renamed handle to resource
+ (-[WebBaseResourceHandleDelegate loadWithRequest:]): renamed handle to resource
+ (-[WebBaseResourceHandleDelegate setDefersCallbacks:]): renamed handle to resource
+ (-[WebBaseResourceHandleDelegate resource:willSendRequest:]): renamed handle to resource
+ (-[WebBaseResourceHandleDelegate resource:didReceiveResponse:]): renamed handle to resource, don't handle downloads
+ (-[WebBaseResourceHandleDelegate resource:didReceiveData:]): renamed handle to resource, don't handle downloads
+ (-[WebBaseResourceHandleDelegate resourceDidFinishLoading:]): renamed handle to resource, don't handle downloads
+ (-[WebBaseResourceHandleDelegate resource:didFailLoadingWithError:]): renamed handle to resource, don't handle downloads
+ (-[WebBaseResourceHandleDelegate cancelWithError:]): renamed handle to resource, don't handle downloads
+ * WebView.subproj/WebController.h: updated comments
+ * WebView.subproj/WebController.m:
+ (-[WebController setDownloadDelegate:]): call the ivar downloadDelegate, not downloadProgressDelegate
+ (-[WebController downloadDelegate]): call the ivar downloadDelegate, not downloadProgressDelegate
+ * WebView.subproj/WebControllerPolicyDelegate.h: removed saveFilenameForResponse:andRequest:, handle by WebDownload
+ * WebView.subproj/WebControllerPrivate.h: call the ivar downloadDelegate, not downloadProgressDelegate
+ * WebView.subproj/WebDefaultPolicyDelegate.m: removed saveFilenameForResponse:andRequest:, handle by WebDownload
+ * WebView.subproj/WebMainResourceClient.h: added WebResourceDelegateProxy icar
+ * WebView.subproj/WebMainResourceClient.m: remove most download related stuff
+ (-[WebMainResourceClient initWithDataSource:]): create a WebResourceDelegateProxy which allows us to change the resource delegate
+ (-[WebMainResourceClient dealloc]): release the proxy
+ (-[WebMainResourceClient receivedError:complete:]): don't handle downloads
+ (-[WebMainResourceClient continueAfterContentPolicy:response:]): pass the load off to the download
+ (-[WebMainResourceClient resource:didReceiveResponse:]): don't handle downloads
+ (-[WebMainResourceClient resource:didReceiveData:]): don't handle downloads
+ (-[WebMainResourceClient resourceDidFinishLoading:]): don't handle downloads
+ (-[WebMainResourceClient resource:didFailLoadingWithError:]): don't handle downloads
+ (-[WebMainResourceClient startLoading:]): make the proxy the delegate
+ (-[WebResourceDelegateProxy setDelegate:]): switches the resource delegate
+ (-[WebResourceDelegateProxy resource:willSendRequest:]): forwards message
+ (-[WebResourceDelegateProxy resource:didReceiveResponse:]): forwards message
+ (-[WebResourceDelegateProxy resource:didReceiveData:]): forwards message
+ (-[WebResourceDelegateProxy resourceDidFinishLoading:]): forwards message
+ (-[WebResourceDelegateProxy resource:didFailLoadingWithError:]): forwards message
+
2003-03-06 Richard Williamson <rjw at apple.com>
Move tweaks to WebKit API.
diff --git a/WebKit/Downloads.subproj/WebDownload.h b/WebKit/Downloads.subproj/WebDownload.h
index 8188acc..a14544e 100644
--- a/WebKit/Downloads.subproj/WebDownload.h
+++ b/WebKit/Downloads.subproj/WebDownload.h
@@ -7,6 +7,7 @@
#import <Foundation/Foundation.h>
+ at class WebDataSource;
@class WebDownload;
@class WebDownloadPrivate;
@class WebError;
@@ -24,30 +25,37 @@
@method setPath:
@abstract This method should be called when the path of the downloaded file has been decided.
@param path The path of the downloaded file.
+ @discussion If necessary, to avoid overwriting files, "-n" will be appended to the filename before the
+ extension where "n" is a number. Because of this, use the path passed with download:didCreateFileAtPath:
+ on WebDownload when referring to the path of the downloaded file, not the path set with this method.
*/
-(void)setPath:(NSString *)path;
+
@end
/*!
@protocol WebDownloadDelegate
- @discussion The delegate of a WebDownload must conform to the WebDownloadDelegate protocol.
+ @discussion The delegate of a WebDownload can conform to the WebDownloadDelegate protocol.
The delegate is primarily used to report the progress of the download. Note: The word "download" is used to
refer to the process of loading data off a network, decoding the data if necessary and saving the data to a file.
- The delegate recieves these calls in this order:
-
- - download:willSendRequest: (called once or more)<BR>
- - download:didReceiveResponse:<BR>
- - download:decidePathWithListener:suggestedFilename: (possibly not called)<BR>
- - download:didReceiveDataOfLength: (called once or more)<BR>
- - downloadDidFinishLoading: or - download:didFailLoadingWithError:
*/
- at protocol WebDownloadDelegate <NSObject>
+ at interface NSObject (WebDownloadDelegate)
+
+/*!
+ @method download:startedFromDataSource:
+ @abstract This method is called immediately after the download has started.
+ @discussion A download is started from a data source if the WebPolicySave WebPolicyAction was chosen for a request.
+ @param download The download that just started downloading.
+ @param response The data source that the download started from. Nil if the download was not started from a data source.
+ */
+- (void)download:(WebDownload *)download didStartFromDataSource:(WebDataSource *)dataSource;
+
/*!
@method download:willSendRequest:
@abstract This method is called whenever the download is about to load a request or if the download
must load another request because the previous request was redirected.
- @discussion This method is always initially called with a copy of the request that was passed with
- initWithRequest:delegate:. This method gives the delegate an opportunity to inspect the request
+ @discussion This method is called with a copy of the request that was passed with
+ initWithRequest:. This method gives the delegate an opportunity to inspect the request
that will be used to continue loading the request, and modify it if necessary.
@param download The download that will send the request.
@param request The request that will be used to continue loading.
@@ -57,8 +65,8 @@
/*!
@method download:didReceiveResponse:
- @abstract This method is called when the download has received enough information to contruct a WebResourceResponse.
- @param download The download that now has a WebResourceResponse available for inspection.
+ @abstract This method is called when the download has received enough information to contruct a WebResponse.
+ @param download The download that now has a WebResponse available for inspection.
@param response The WebResourceResponse object for the given download.
*/
- (void)download:(WebDownload *)download didReceiveResponse:(WebResponse *)response;
@@ -86,23 +94,44 @@
- (void)download:(WebDownload *)download didReceiveDataOfLength:(unsigned)length;
/*!
- @method downloadDidFinishLoading:
+ @method downloadShouldDecodeEncodedFile:
+ @abstract This method is called if the download detects that the downloading file is encoded.
+ @discussion An encoded file is encoded in MacBinary, BinHex or gzip format.
+ This method is not called if the download is not encoded.
+ @param download The download that has detected that the downloading file is encoded.
+ @result Return YES to decode the file, NO to not decode the file.
+*/
+- (BOOL)downloadShouldDecodeEncodedFile:(WebDownload *)download;
+
+/*!
+ @method download:didCreatedFileAtPath:
+ @abstract This method is called after the download creates the download file.
+ @discussion The filename of path may be different than the path set with setPath:
+ so the download does not overwrite an existing file.
+ @param download The download that created the downloading file.
+ @param path The path of the downloading file.
+*/
+- (void)download:(WebDownload *)download didCreateFileAtPath:(NSString *)path;
+
+/*!
+ @method downloadDidFinishDownloading:
@abstract This method is called when the download has finished downloading.
@discussion This method is called after all the data has been received and written to disk.
- This method or download:didFailLoadingWithError: will only be called once.
+ This method or download:didFailDownloadingWithError: will only be called once.
@param download The download that has finished downloading.
*/
-- (void)downloadDidFinishLoading:(WebDownload *)download;
+- (void)downloadDidFinishDownloading:(WebDownload *)download;
/*!
- @method download:didFailLoadingWithError:
+ @method download:didFailDownloadingWithError:
@abstract This method is called when the download has failed.
@discussion This method is called when the download encounters a network or file I/O related error.
- This method or downloadDidFinishLoading: will only be called once.
+ This method or downloadDidFinishDownloading: will only be called once.
@param download The download that ended in error.
@param error The error caused the download to fail.
*/
-- (void)download:(WebDownload *)download didFailLoadingWithError:(WebError *)error;
+- (void)download:(WebDownload *)download didFailDownloadingWithError:(WebError *)error;
+
@end
/*!
@@ -118,18 +147,22 @@
}
/*!
- @method initWithRequest:delegate:
+ @method initWithRequest:
@abstract Initializes a WebDownload object.
- @discussion This method also begins the download.
@param request The request to download. Must not be nil.
+*/
+- initWithRequest:(WebRequest *)request;
+
+/*!
+ @method loadWithDelegate:
+ @abstract Starts the download.
@param delegate The delegate of the download. Must not be nil.
*/
-- initWithRequest:(WebRequest *)request delegate:(id <WebDownloadDelegate>)delegate;
+- (void)loadWithDelegate:(id)delegate;
/*!
@method cancel
@abstract Cancels the download and deletes the downloaded file.
- @discussion Has no effect after the download has completed.
*/
- (void)cancel;
diff --git a/WebKit/Downloads.subproj/WebDownload.m b/WebKit/Downloads.subproj/WebDownload.m
index efee4db..d8d081e 100644
--- a/WebKit/Downloads.subproj/WebDownload.m
+++ b/WebKit/Downloads.subproj/WebDownload.m
@@ -3,12 +3,13 @@
// WebKit
//
// Created by Chris Blumenberg on Thu Apr 11 2002.
-// Copyright (c) 2002 Apple Computer, Inc.
+// Copyright (c) 2003 Apple Computer, Inc.
//
#import <WebKit/WebDownloadPrivate.h>
#import <WebKit/WebBinHexDecoder.h>
+#import <WebKit/WebController.h>
#import <WebKit/WebDataSourcePrivate.h>
#import <WebKit/WebDownloadDecoder.h>
#import <WebKit/WebGZipDecoder.h>
@@ -16,18 +17,19 @@
#import <WebKit/WebKitLogging.h>
#import <WebKit/WebMacBinaryDecoder.h>
#import <WebKit/WebNSWorkspaceExtras.h>
+#import <WebKit/WebResourceResponseExtras.h>
#import <WebFoundation/WebError.h>
#import <WebFoundation/WebNSFileManagerExtras.h>
#import <WebFoundation/WebNSStringExtras.h>
#import <WebFoundation/WebRequest.h>
+#import <WebFoundation/WebResource.h>
#import <WebFoundation/WebResponse.h>
typedef struct WebFSForkIOParam
{
FSForkIOParam paramBlock;
WebDownload *download;
- BOOL deleteFile;
NSData *data;
} WebFSForkIOParam;
@@ -40,52 +42,107 @@ typedef struct WebFSRefParam
@interface WebDownloadPrivate : NSObject
{
@public
- WebDataSource *dataSource;
-
- NSArray *decoderClasses;
NSMutableArray *decoderSequence;
NSMutableData *bufferedData;
- FSRef fileRef;
FSRefPtr fileRefPtr;
SInt16 dataForkRefNum;
SInt16 resourceForkRefNum;
- // isCancelled is used to make sure we don't write after cancelling the load.
- BOOL isCancelled;
-
- // areWritesCancelled is only used by WriteCompletionCallback to make
- // sure that only 1 write failure cancels the load.
+ BOOL deleteFile;
+ BOOL isLoading;
BOOL areWritesCancelled;
+ BOOL encounteredCloseError;
+
+ WebResource *resource;
+ WebRequest *request;
+ WebResponse *response;
+
+ id delegate;
+
+ NSString *path;
+ NSString *tempPath;
}
@end
+static NSArray *decoderClasses = nil;
+
static void WriteCompletionCallback(ParmBlkPtr paramBlock);
static void CloseCompletionCallback(ParmBlkPtr paramBlock);
static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
+ at interface WebDownload (ForwardDeclarations)
+#pragma mark CREATING
+- (NSString *)_pathWithUniqueFilenameForPath:(NSString *)path;
+- (BOOL)_createFSRefForPath:(NSString *)path;
+- (BOOL)_createFileIfNecessary;
+#pragma mark DECODING
+- (void)_decodeHeaderData:(NSData *)headerData dataForkData:(NSData **)dataForkData resourceForkData:(NSData **)resourceForkData;
+- (BOOL)_decodeData:(NSData *)data dataForkData:(NSData **)dataForkData resourceForkData:(NSData **)resourceForkData;
+- (WebError *)_decodeData:(NSData *)data;
+- (NSData *)_dataIfDoneBufferingData:(NSData *)data;
+- (BOOL)_finishDecoding;
+#pragma mark WRITING
+- (BOOL)_writeForkData:(NSData *)data isDataFork:(BOOL)isDataFork;
+- (WebError *)_writeDataForkData:(NSData *)dataForkData resourceForkData:(NSData *)resourceForkData;
+#pragma mark CLOSING;
+- (BOOL)_isFileClosed;
+- (void)_didCloseFile:(WebError *)error;
+- (void)_closeForkAsync:(SInt16)forkRefNum;
+- (BOOL)_closeForkSync:(SInt16)forkRefNum;
+- (void)_closeFileAsync;
+- (BOOL)_closeFileSync;
+#pragma mark DELETING
+- (void)_didDeleteFile;
+- (void)_deleteFileAsnyc;
+- (void)_closeAndDeleteFileAsync;
+- (void)_cancelWithError:(WebError *)error;
+- (void)_cancelWithErrorCode:(int)code;
+#pragma mark MISC
+- (NSString *)_currentPath;
+- (WebError *)_errorWithCode:(int)code;
+- (SInt16)_dataForkReferenceNumber;
+- (void)_setDataForkReferenceNumber:(SInt16)forkRefNum;
+- (SInt16)_resourceForkReferenceNumber;
+- (void)_setResourceForkReferenceNumber:(SInt16)forkRefNum;
+- (BOOL)_areWritesCancelled;
+- (void)_setWritesCancelled:(BOOL)cancelled;
+- (BOOL)_encounteredCloseError;
+- (void)_setEncounteredCloseError:(BOOL)encounteredCloseError;
+ at end
+
@implementation WebDownloadPrivate
- init
{
[super init];
-
- decoderClasses = [[NSArray arrayWithObjects:
- [WebBinHexDecoder class],
- [WebMacBinaryDecoder class],
- [WebGZipDecoder class],
- nil] retain];
+ if (!decoderClasses) {
+ decoderClasses = [[NSArray arrayWithObjects:
+ [WebBinHexDecoder class],
+ [WebMacBinaryDecoder class],
+ [WebGZipDecoder class],
+ nil] retain];
+ }
+
return self;
}
- (void)dealloc
{
+ ASSERT(!resource);
+ ASSERT(!delegate);
+
+ free(fileRefPtr);
+
[bufferedData release];
- [dataSource release];
- [decoderClasses release];
[decoderSequence release];
+ [request release];
+ [resource release];
+ [response release];
+ [path release];
+ [tempPath release];
[super dealloc];
}
@@ -93,10 +150,57 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
@implementation WebDownload
-- initWithRequest:(WebRequest *)request delegate:(id <WebDownloadDelegate>)delegate
+- initWithRequest:(WebRequest *)request
+{
+ ASSERT(request);
+
+ [super init];
+
+ _private = [[WebDownloadPrivate alloc] init];
+ _private->request = [request retain];
+
+ _private->resource = [[WebResource alloc] initWithRequest:request];
+ if (!_private->resource) {
+ [self release];
+ return nil;
+ }
+
+ return self;
+}
+
+- _initWithLoadingResource:(WebResource *)resource dataSource:(WebDataSource *)dataSource
{
[super init];
- // FIXME: Implement.
+
+ _private = [[WebDownloadPrivate alloc] init];
+ _private->resource = [resource retain];
+ _private->request = [[dataSource request] retain];
+ _private->response = [[dataSource response] retain];
+ _private->delegate = [[dataSource _controller] downloadDelegate];
+ _private->isLoading = YES;
+
+ // Replay the delegate methods that would be called in the standalone download case.
+ if ([_private->delegate respondsToSelector:@selector(download:didStartFromDataSource:)]) {
+ [_private->delegate download:self didStartFromDataSource:dataSource];
+ }
+
+ // If the request is altered, cancel the previous resource and start a new one.
+ if ([_private->delegate respondsToSelector:@selector(download:willSendRequest:)]) {
+ WebRequest *request = [_private->delegate download:self willSendRequest:_private->request];
+ if (request != _private->request) {
+ [self cancel];
+ if (request) {
+ _private->resource = [[WebResource alloc] initWithRequest:request];
+ [_private->resource loadWithDelegate:(id <WebResourceDelegate>)self];
+ }
+ return self;
+ }
+ }
+
+ if ([_private->delegate respondsToSelector:@selector(download:didReceiveResponse:)]) {
+ [_private->delegate download:self didReceiveResponse:_private->response];
+ }
+
return self;
}
@@ -106,71 +210,243 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
[super dealloc];
}
-- (void)cancel
+- (void)loadWithDelegate:(id)delegate
{
- _private->isCancelled = YES;
- [self cleanUpAfterFailure];
+ if (!_private->isLoading) {
+ _private->delegate = delegate;
+ [_private->resource loadWithDelegate:(id <WebResourceDelegate>)self];
+ _private->isLoading = YES;
+
+ if ([_private->delegate respondsToSelector:@selector(download:didStartFromDataSource:)]) {
+ [_private->delegate download:self didStartFromDataSource:nil];
+ }
+ }
}
- at end
+- (void)cancel
+{
+ [self _cancelWithError:nil];
+}
- at implementation WebDownload (WebPrivate)
+- (NSString *)path
+{
+ return _private->path;
+}
-- _initWithLoadingHandle:(WebResource *)handle
- request:(WebRequest *)request
- response:(WebRequest *)response
- delegate:(id <WebDownloadDelegate>)delegate
+// setPath: is not public. This is the WebDownloadDecisionListener method.
+- (void)setPath:(NSString *)path
{
- [super init];
- // FIXME: Implement.
- return self;
+ [self _setPath:path];
}
-// FIXME: Remove many of the following methods.
+#pragma mark LOADING
-- initWithDataSource:(WebDataSource *)dSource
+- (void)_loadFinished
{
- [super init];
+ _private->isLoading = NO;
+
+ [_private->resource release];
+ _private->resource = nil;
+}
- _private = [[WebDownloadPrivate alloc] init];
- _private->dataSource = [dSource retain];
+-(WebRequest *)resource:(WebResource *)resource willSendRequest:(WebRequest *)theRequest
+{
+ WebRequest *request = nil;
+
+ if ([_private->delegate respondsToSelector:@selector(download:willSendRequest:)]) {
+ request = [_private->delegate download:self willSendRequest:theRequest];
+ } else {
+ request = theRequest;
+ }
+
+ if (!request) {
+ [self _loadFinished];
+ }
- LOG(Download, "Download started for: %@", [[dSource request] URL]);
- return self;
+ if (_private->request != request) {
+ [_private->request release];
+ _private->request = [request retain];
+ }
+
+ return request;
}
-- (WebError *)receivedData:(NSData *)data
+-(void)resource:(WebResource *)resource didReceiveResponse:(WebResponse *)response
{
- ASSERT(data);
+ ASSERT(!_private->response);
+
+ _private->response = [response retain];
+ if ([_private->delegate respondsToSelector:@selector(download:didReceiveResponse:)]) {
+ [_private->delegate download:self didReceiveResponse:response];
+ }
+}
- return [self decodeData:[self dataIfDoneBufferingData:data]];
+-(void)resource:(WebResource *)resource didReceiveData:(NSData *)data
+{
+ if ([_private->delegate respondsToSelector:@selector(download:didReceiveDataOfLength:)]) {
+ [_private->delegate download:self didReceiveDataOfLength:[data length]];
+ }
+
+ WebError *error = [self _decodeData:[self _dataIfDoneBufferingData:data]];
+ if (error) {
+ [self _cancelWithError:error];
+ }
}
-- (WebError *)finishedLoading
+-(void)resourceDidFinishLoading:(WebResource *)resource
{
- WebError *error = [self decodeData:_private->bufferedData];
+ [self _loadFinished];
+
+ WebError *error = [self _decodeData:_private->bufferedData];
[_private->bufferedData release];
_private->bufferedData = nil;
if (error) {
- return error;
+ [self _cancelWithError:error];
+ return;
}
- if (![self finishDecoding]) {
+ if (![self _finishDecoding]) {
ERROR("Download decoding failed.");
- [self cleanUpAfterFailure];
- return [self errorWithCode:WebKitErrorDownloadDecodingFailedToComplete];
+ [self _cancelWithErrorCode:WebKitErrorDownloadDecodingFailedToComplete];
+ return;
}
- [self closeFile];
+ [self _closeFileAsync];
+}
- LOG(Download, "Download complete. Saved to: %@", [_private->dataSource downloadPath]);
+-(void)resource:(WebResource *)resource didFailLoadingWithError:(WebError *)error
+{
+ [self _loadFinished];
+
+ [self _cancelWithError:error];
+}
- return nil;
+#pragma mark CREATING
+
+- (NSString *)_pathWithUniqueFilenameForPath:(NSString *)path
+{
+ // "Fix" the filename of the path.
+ NSString *filename = [[path lastPathComponent] _web_filenameByFixingIllegalCharacters];
+ path = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:filename];
+
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ if ([fileManager fileExistsAtPath:path]) {
+ // Don't overwrite existing files by appending "-n" or "-n.ext" to the filename.
+ NSString *pathWithoutExtension = [path stringByDeletingPathExtension];
+ NSString *extension = [path pathExtension];
+ NSString *pathWithAppendedNumber;
+ unsigned i;
+
+ for (i = 1; 1; i++) {
+ pathWithAppendedNumber = [NSString stringWithFormat:@"%@-%d", pathWithoutExtension, i];
+ if (extension && [extension length]) {
+ path = [pathWithAppendedNumber stringByAppendingPathExtension:extension];
+ } else {
+ path = pathWithAppendedNumber;
+ }
+ if (![fileManager fileExistsAtPath:path]) {
+ break;
+ }
+ }
+ }
+
+ return path;
+}
+
+- (BOOL)_createFSRefForPath:(NSString *)path
+{
+ free(_private->fileRefPtr);
+ _private->fileRefPtr = malloc(sizeof(FSRef));
+
+ OSErr result = FSPathMakeRef((const UInt8 *)[path fileSystemRepresentation], _private->fileRefPtr, NULL);
+ if (result != noErr) {
+ ERROR("FSPathMakeRef failed.");
+ free(_private->fileRefPtr);
+ _private->fileRefPtr = NULL;
+ return NO;
+ }
+
+ return YES;
+}
+
+- (BOOL)_createFileIfNecessary
+{
+ if (_private->fileRefPtr) {
+ // File is already created.
+ return YES;
+ }
+
+ NSObject <WebDownloadDecoder> *lastDecoder = [_private->decoderSequence lastObject];
+ NSMutableDictionary *attributes = [[lastDecoder fileAttributes] mutableCopy];
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+
+ if (!attributes) {
+ attributes = [[NSMutableDictionary alloc] init];
+ }
+ if (![attributes objectForKey:NSFileCreationDate]) {
+ [attributes setObject:[_private->response createdDate] forKey:NSFileCreationDate];
+ }
+ if (![attributes objectForKey:NSFileModificationDate]) {
+ [attributes setObject:[_private->response createdDate] forKey:NSFileModificationDate];
+ }
+
+ // Check if the path is predetermined. If not, ask for one.
+ if (!_private->path) {
+ NSString *filename = [[lastDecoder filename] _web_filenameByFixingIllegalCharacters];
+ if ([filename length] == 0) {
+ filename = [_private->response suggestedFilenameForSaving];
+ }
+
+ if ([_private->delegate respondsToSelector:@selector(download:decidePathWithListener:suggestedFilename:)]) {
+ [_private->delegate download:self
+ decidePathWithListener:(id <WebDownloadDecisionListener>)self
+ suggestedFilename:filename];
+ }
+ }
+
+ NSString *path = nil;
+ if (_private->path) {
+ // Path was immeditately set.
+ path = _private->path;
+ } else {
+ // Path wasn't immeditately set. Create the file in /tmp.
+ // FIXME: Consider downloading the file to the default download directory or some other location.
+ char *pathC = strdup("/tmp/WebKitDownload.XXXXXX");
+ if (mktemp(pathC)) {
+ _private->tempPath = [[NSString alloc] initWithCString:pathC];
+ path = _private->tempPath;
+ }
+ free(pathC);
+ if (!path) {
+ ERROR("mktemp failed to create a unique filename in /tmp.");
+ return NO;
+ }
+ }
+
+ if (![fileManager _web_createFileAtPath:path contents:nil attributes:attributes]) {
+ ERROR("-[NSFileManager _web_createFileAtPath:contents:attributes:] failed.");
+ return NO;
+ }
+
+ if (![self _createFSRefForPath:path]) {
+ return NO;
+ }
+
+ [[NSWorkspace sharedWorkspace] _web_noteFileChangedAtPath:path];
+
+ if (_private->path && [_private->delegate respondsToSelector:@selector(download:didCreateFileAtPath:)]) {
+ [_private->delegate download:self didCreateFileAtPath:_private->path];
+ }
+
+ return YES;
}
-- (void)decodeHeaderData:(NSData *)headerData
- dataForkData:(NSData **)dataForkData
- resourceForkData:(NSData **)resourceForkData
+
+#pragma mark DECODING
+
+- (void)_decodeHeaderData:(NSData *)headerData
+ dataForkData:(NSData **)dataForkData
+ resourceForkData:(NSData **)resourceForkData
{
ASSERT(headerData);
ASSERT([headerData length]);
@@ -178,9 +454,9 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
ASSERT(resourceForkData);
unsigned i;
- for (i = 0; i < [_private->decoderClasses count]; i++) {
- Class decoderClass = [_private->decoderClasses objectAtIndex:i];
-
+ for (i = 0; i < [decoderClasses count]; i++) {
+ Class decoderClass = [decoderClasses objectAtIndex:i];
+
if ([decoderClass canDecodeHeaderData:headerData]) {
NSObject <WebDownloadDecoder> *decoder = [[[decoderClass alloc] init] autorelease];
BOOL didDecode = [decoder decodeData:headerData dataForkData:dataForkData resourceForkData:resourceForkData];
@@ -193,13 +469,13 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
[_private->decoderSequence addObject:decoder];
- [self decodeHeaderData:*dataForkData dataForkData:dataForkData resourceForkData:resourceForkData];
+ [self _decodeHeaderData:*dataForkData dataForkData:dataForkData resourceForkData:resourceForkData];
break;
}
}
}
-- (BOOL)decodeData:(NSData *)data
+- (BOOL)_decodeData:(NSData *)data
dataForkData:(NSData **)dataForkData
resourceForkData:(NSData **)resourceForkData
{
@@ -210,7 +486,13 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
if (!_private->decoderSequence) {
_private->decoderSequence = [[NSMutableArray array] retain];
- [self decodeHeaderData:data dataForkData:dataForkData resourceForkData:resourceForkData];
+ [self _decodeHeaderData:data dataForkData:dataForkData resourceForkData:resourceForkData];
+
+ if ([_private->decoderSequence count] > 0 &&
+ [_private->delegate respondsToSelector:@selector(downloadShouldDecodeEncodedFile:)] &&
+ ![_private->delegate downloadShouldDecodeEncodedFile:self]) {
+ [_private->decoderSequence removeAllObjects];
+ }
} else {
unsigned i;
for (i = 0; i< [_private->decoderSequence count]; i++) {
@@ -233,128 +515,32 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
return YES;
}
-- (void)closeFork:(SInt16)forkRefNum deleteFile:(BOOL)deleteFile
+- (WebError *)_decodeData:(NSData *)data
{
- if (forkRefNum) {
- WebFSForkIOParam *block = malloc(sizeof(WebFSForkIOParam));
- block->paramBlock.ioCompletion = CloseCompletionCallback;
- block->paramBlock.forkRefNum = forkRefNum;
- block->paramBlock.ref = _private->fileRefPtr;
- block->download = [self retain];
- block->deleteFile = deleteFile;
- PBCloseForkAsync(&block->paramBlock);
- }
-}
-
-- (void)closeFileAndDelete:(BOOL)deleteFile
-{
- [self closeFork:_private->dataForkRefNum deleteFile:deleteFile];
- [self closeFork:_private->resourceForkRefNum deleteFile:deleteFile];
-}
-
-- (void)closeFile
-{
- [self closeFileAndDelete:NO];
-}
-
-- (void)cleanUpAfterFailure
-{
- [self closeFileAndDelete:YES];
-}
-
-- (WebError *)createFileIfNecessary
-{
- if (_private->fileRefPtr) {
+ if ([data length] == 0) {
return nil;
}
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSString *path = [_private->dataSource downloadPath];
- NSObject <WebDownloadDecoder> *lastDecoder = [_private->decoderSequence lastObject];
-
- NSString *filename = [[lastDecoder filename] _web_filenameByFixingIllegalCharacters];
-
- if ([filename length] != 0) {
- path = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:filename];
- }
-
- if ([fileManager fileExistsAtPath:path]) {
- NSString *pathWithoutExtension = [path stringByDeletingPathExtension];
- NSString *extension = [path pathExtension];
- NSString *pathWithAppendedNumber;
- unsigned i;
-
- for (i = 1; 1; i++) {
- pathWithAppendedNumber = [NSString stringWithFormat:@"%@-%d", pathWithoutExtension, i];
- if (extension && [extension length]) {
- path = [pathWithAppendedNumber stringByAppendingPathExtension:extension];
- } else {
- path = pathWithAppendedNumber;
- }
- if (![fileManager fileExistsAtPath:path]) {
- break;
- }
- }
- }
-
- [_private->dataSource _setDownloadPath:path];
-
- NSDictionary *fileAttributes = [lastDecoder fileAttributes];
- // FIXME: This assumes that if we get any file attributes, they will include the creation
- // and modification date, which is not necessarily true.
- if (!fileAttributes) {
- WebResponse *response = [_private->dataSource response];
- fileAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
- [response createdDate], NSFileCreationDate,
- [response lastModifiedDate], NSFileModificationDate, nil];
- }
-
- if (![fileManager _web_createFileAtPath:path contents:nil attributes:fileAttributes]) {
- ERROR("-[NSFileManager _web_createFileAtPath:contents:attributes:] failed.");
- return [self errorWithCode:WebKitErrorCannotCreateFile];
- }
-
- [[NSWorkspace sharedWorkspace] _web_noteFileChangedAtPath:path];
+ NSData *dataForkData = nil;
+ NSData *resourceForkData = nil;
- OSErr result = FSPathMakeRef((const UInt8 *)[path fileSystemRepresentation], &_private->fileRef, NULL);
- if (result == noErr) {
- _private->fileRefPtr = &_private->fileRef;
- } else {
- ERROR("FSPathMakeRef failed.");
- [self cleanUpAfterFailure];
- return [self errorWithCode:WebKitErrorCannotCreateFile];
+ if (![self _decodeData:data dataForkData:&dataForkData resourceForkData:&resourceForkData]) {
+ ERROR("Download decoding failed.");
+ return [self _errorWithCode:WebKitErrorDownloadDecodingFailedMidStream];
}
- return nil;
-}
-
-- (WebError *)writeDataForkData:(NSData *)dataForkData resourceForkData:(NSData *)resourceForkData
-{
- WebError *error = [self createFileIfNecessary];
+ WebError *error = [self _writeDataForkData:dataForkData resourceForkData:resourceForkData];
if (error) {
return error;
}
- BOOL didWrite = YES;
-
- if ([dataForkData length]) {
- didWrite = [self writeForkData:dataForkData isDataFork:YES];
- }
-
- if (didWrite && [resourceForkData length]) {
- didWrite = [self writeForkData:resourceForkData isDataFork:NO];
- }
-
- if (!didWrite) {
- [self cleanUpAfterFailure];
- return [self errorWithCode:WebKitErrorCannotWriteToFile];
- }
-
return nil;
}
-- (NSData *)dataIfDoneBufferingData:(NSData *)data
+- (NSData *)_dataIfDoneBufferingData:(NSData *)data
{
+ ASSERT([data length] > 0);
+
if (!_private->bufferedData) {
_private->bufferedData = [data mutableCopy];
} else if ([_private->bufferedData length] == 0) {
@@ -369,7 +555,8 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
// We've have enough now. Make a copy so we can set bufferedData's length to 0,
// so we're know we're done buffering.
data = [[_private->bufferedData copy] autorelease];
- [_private->bufferedData setLength:0];
+ [_private->bufferedData release];
+ _private->bufferedData = [[NSMutableData alloc] init];
return data;
} else {
// Keep buffering. The header is not big enough to determine the encoding sequence.
@@ -377,30 +564,7 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
}
}
-- (WebError *)decodeData:(NSData *)data
-{
- if ([data length] == 0) {
- return nil;
- }
-
- NSData *dataForkData = nil;
- NSData *resourceForkData = nil;
-
- if (![self decodeData:data dataForkData:&dataForkData resourceForkData:&resourceForkData]) {
- ERROR("Download decoding failed.");
- [self cleanUpAfterFailure];
- return [self errorWithCode:WebKitErrorDownloadDecodingFailedMidStream];
- }
-
- WebError *error = [self writeDataForkData:dataForkData resourceForkData:resourceForkData];
- if (error) {
- return error;
- }
-
- return nil;
-}
-
-- (BOOL)finishDecoding
+- (BOOL)_finishDecoding
{
NSObject <WebDownloadDecoder> *decoder;
unsigned i;
@@ -415,26 +579,15 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
return YES;
}
-- (NSString *)path
-{
- return [_private->dataSource downloadPath];
-}
+#pragma mark WRITING
-- (BOOL)writeForkData:(NSData *)data isDataFork:(BOOL)isDataFork
+- (BOOL)_writeForkData:(NSData *)data isDataFork:(BOOL)isDataFork
{
- ASSERT(!_private->isCancelled);
-
- OSErr result;
SInt16 *forkRefNum = isDataFork ? &_private->dataForkRefNum : &_private->resourceForkRefNum;
-
+
if (*forkRefNum == 0) {
HFSUniStr255 forkName;
- if (isDataFork) {
- result = FSGetDataForkName(&forkName);
- } else {
- result = FSGetResourceForkName(&forkName);
- }
-
+ OSErr result = isDataFork ? FSGetDataForkName(&forkName) : FSGetResourceForkName(&forkName);
if (result != noErr) {
ERROR("Couldn't get fork name of download file.");
return NO;
@@ -462,48 +615,249 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock);
return YES;
}
-- (WebError *)errorWithCode:(int)code
+- (WebError *)_writeDataForkData:(NSData *)dataForkData resourceForkData:(NSData *)resourceForkData
{
- return [WebError errorWithCode:code
- inDomain:WebErrorDomainWebKit
- failingURL:[[_private->dataSource _URL] absoluteString]];
+ if (![self _createFileIfNecessary]) {
+ return [self _errorWithCode:WebKitErrorCannotCreateFile];
+ }
+
+ BOOL didWrite = YES;
+
+ if ([dataForkData length]) {
+ didWrite = [self _writeForkData:dataForkData isDataFork:YES];
+ }
+
+ if (didWrite && [resourceForkData length]) {
+ didWrite = [self _writeForkData:resourceForkData isDataFork:NO];
+ }
+
+ if (!didWrite) {
+ [self _closeAndDeleteFileAsync];
+ return [self _errorWithCode:WebKitErrorCannotWriteToFile];
+ }
+
+ return nil;
+}
+
+#pragma mark CLOSING
+
+- (BOOL)_isFileClosed
+{
+ return (_private->dataForkRefNum == 0 && _private->resourceForkRefNum == 0);
+}
+
+- (void)_didCloseFile:(WebError *)error
+{
+ if (_private->deleteFile) {
+ [self _deleteFileAsnyc];
+ } else if (error) {
+ [self _cancelWithError:error];
+ } else {
+ [[NSWorkspace sharedWorkspace] _web_noteFileChangedAtPath:[self _currentPath]];
+ if ([_private->delegate respondsToSelector:@selector(downloadDidFinishDownloading:)]) {
+ [_private->delegate downloadDidFinishDownloading:self];
+ }
+ _private->delegate = nil;
+ }
+}
+
+- (void)_closeForkAsync:(SInt16)forkRefNum
+{
+ if (forkRefNum) {
+ WebFSForkIOParam *block = malloc(sizeof(WebFSForkIOParam));
+ block->paramBlock.ioCompletion = CloseCompletionCallback;
+ block->paramBlock.forkRefNum = forkRefNum;
+ block->download = [self retain];
+ PBCloseForkAsync(&block->paramBlock);
+ }
+}
+
+- (BOOL)_closeForkSync:(SInt16)forkRefNum
+{
+ if (forkRefNum) {
+ OSErr error = FSCloseFork(forkRefNum);
+ if (error != noErr) {
+ ERROR("FSCloseFork failed to close fork of download file with error %d", error);
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+- (void)_closeFileAsync
+{
+ [self _closeForkAsync:_private->dataForkRefNum];
+ [self _closeForkAsync:_private->resourceForkRefNum];
+}
+
+- (BOOL)_closeFileSync
+{
+ BOOL result = YES;
+
+ if (![self _closeForkSync:_private->dataForkRefNum]) {
+ result = NO;
+ }
+
+ if (![self _closeForkSync:_private->resourceForkRefNum]) {
+ result = NO;
+ }
+
+ _private->dataForkRefNum = 0;
+ _private->resourceForkRefNum = 0;
+
+ return result;
+}
+
+#pragma mark DELETING
+
+- (void)_didDeleteFile
+{
+ [[NSWorkspace sharedWorkspace] _web_noteFileChangedAtPath:[self _currentPath]];
+}
+
+- (void)_deleteFileAsnyc
+{
+ if (_private->fileRefPtr) {
+ WebFSRefParam *deleteBlock = malloc(sizeof(WebFSRefParam));
+ deleteBlock->paramBlock.ioCompletion = DeleteCompletionCallback;
+ deleteBlock->paramBlock.ref = _private->fileRefPtr;
+ deleteBlock->download = [self retain];
+ PBDeleteObjectAsync(&deleteBlock->paramBlock);
+ free(_private->fileRefPtr);
+ _private->fileRefPtr = NULL;
+ }
+}
+
+- (void)_closeAndDeleteFileAsync
+{
+ if ([self _isFileClosed]) {
+ [self _deleteFileAsnyc];
+ } else {
+ [self _closeFileAsync];
+ _private->deleteFile = YES;
+ }
+}
+
+- (void)_cancelWithError:(WebError *)error
+{
+ [_private->resource cancel];
+ [self _loadFinished];
+
+ if (error) {
+ if ([_private->delegate respondsToSelector:@selector(download:didFailDownloadingWithError:)]) {
+ [_private->delegate download:self didFailDownloadingWithError:error];
+ }
+ }
+
+ _private->delegate = nil;
+
+ [self _closeAndDeleteFileAsync];
}
-- (void)cancelWithError:(WebError *)error
+- (void)_cancelWithErrorCode:(int)code
{
- [_private->dataSource _stopLoadingWithError:error];
+ [self _cancelWithError:[self _errorWithCode:code]];
}
-- (SInt16)dataForkReferenceNumber
+#pragma mark MISCELLANEOUS
+
+- (void)_setPath:(NSString *)path
+{
+ ASSERT(path);
+ ASSERT(!_private->path);
+ ASSERT([path isAbsolutePath]);
+
+ // Path has already been set.
+ if (_private->path) {
+ return;
+ }
+
+ if (!path || ![path isAbsolutePath]) {
+ ERROR("setPath: cannot be called with a nil or non-absolute path.");
+ [self cancel];
+ return;
+ }
+
+ // Make sure we don't overwrite an existing file.
+ _private->path = [[self _pathWithUniqueFilenameForPath:path] retain];
+
+ // FIXME: Moving the downloading file synchronously may block the main thread for a long time
+ // if the move is across volumes.
+ if (_private->tempPath && ![_private->tempPath isEqualToString:_private->path]) {
+ if (![self _closeFileSync]) {
+ [self _cancelWithErrorCode:WebKitErrorCannotCloseFile];
+ return;
+ }
+ if (![[NSFileManager defaultManager] movePath:_private->tempPath toPath:_private->path handler:nil]) {
+ [self _cancelWithErrorCode:WebKitErrorCannotMoveFile];
+ return;
+ }
+ if (![self _createFSRefForPath:_private->path]) {
+ [self _cancelWithErrorCode:WebKitErrorCannotCreateFile];
+ return;
+ }
+
+ [[NSWorkspace sharedWorkspace] _web_noteFileChangedAtPath:_private->path];
+
+ if ([_private->delegate respondsToSelector:@selector(download:didCreateFileAtPath:)]) {
+ [_private->delegate download:self didCreateFileAtPath:_private->path];
+ }
+ }
+}
+
+- (NSString *)_currentPath
+{
+ return _private->path ? _private->path : _private->tempPath;
+}
+
+- (WebError *)_errorWithCode:(int)code
+{
+ return [WebError errorWithCode:code
+ inDomain:WebErrorDomainWebKit
+ failingURL:[[_private->request URL] absoluteString]];
+}
+
+- (SInt16)_dataForkReferenceNumber
{
return _private->dataForkRefNum;
}
-- (void)setDataForkReferenceNumber:(SInt16)forkRefNum
+- (void)_setDataForkReferenceNumber:(SInt16)forkRefNum
{
_private->dataForkRefNum = forkRefNum;
}
-- (SInt16)resourceForkReferenceNumber
+- (SInt16)_resourceForkReferenceNumber
{
return _private->resourceForkRefNum;
}
-- (void)setResourceForkReferenceNumber:(SInt16)forkRefNum
+- (void)_setResourceForkReferenceNumber:(SInt16)forkRefNum
{
_private->resourceForkRefNum = forkRefNum;
}
-- (BOOL)areWritesCancelled
+- (BOOL)_areWritesCancelled
{
return _private->areWritesCancelled;
}
-- (void)setWritesCancelled:(BOOL)cancelled
+- (void)_setWritesCancelled:(BOOL)cancelled
{
_private->areWritesCancelled = cancelled;
}
+- (BOOL)_encounteredCloseError
+{
+ return _private->encounteredCloseError;
+}
+
+- (void)_setEncounteredCloseError:(BOOL)encounteredCloseError
+{
+ _private->encounteredCloseError = encounteredCloseError;
+}
+
@end
static void WriteCompletionCallback(ParmBlkPtr paramBlock)
@@ -512,12 +866,13 @@ static void WriteCompletionCallback(ParmBlkPtr paramBlock)
WebFSForkIOParam *block = (WebFSForkIOParam *)paramBlock;
WebDownload *download = block->download;
- if (block->paramBlock.ioResult != noErr && ![download areWritesCancelled]) {
+ if (block->paramBlock.ioResult != noErr && ![download _areWritesCancelled]) {
ERROR("Writing to fork of download file failed with error: %d", block->paramBlock.ioResult);
- [download setWritesCancelled:YES];
- [download performSelectorOnMainThread:@selector(cancelWithError:)
- withObject:[download errorWithCode:WebKitErrorCannotWriteToFile]
- waitUntilDone:NO];
+ // Prevent multiple errors from being reported by setting the areWritesCancelled boolean.
+ [download _setWritesCancelled:YES];
+ [download performSelectorOnMainThread:@selector(_cancelWithError:)
+ withObject:[download _errorWithCode:WebKitErrorCannotWriteToFile]
+ waitUntilDone:NO];
}
[download release];
@@ -534,28 +889,19 @@ static void CloseCompletionCallback(ParmBlkPtr paramBlock)
if (block->paramBlock.ioResult != noErr) {
ERROR("Closing fork of download file failed with error: %d", block->paramBlock.ioResult);
- // FIXME: Need to report close errors.
+ [download _setEncounteredCloseError:YES];
}
- if (block->paramBlock.forkRefNum == [download dataForkReferenceNumber]) {
- [download setDataForkReferenceNumber:0];
+ if (block->paramBlock.forkRefNum == [download _dataForkReferenceNumber]) {
+ [download _setDataForkReferenceNumber:0];
} else {
- [download setResourceForkReferenceNumber:0];
- }
-
- // Check if both the data fork and resource fork are now closed.
- if ([download dataForkReferenceNumber] == 0 && [download resourceForkReferenceNumber] == 0) {
- if (block->deleteFile && block->paramBlock.ref) {
- WebFSRefParam *deleteBlock = malloc(sizeof(WebFSRefParam));
- deleteBlock->paramBlock.ioCompletion = DeleteCompletionCallback;
- deleteBlock->paramBlock.ref = block->paramBlock.ref;
- deleteBlock->download = [download retain];
- PBDeleteObjectAsync(&deleteBlock->paramBlock);
- } else {
- [[NSWorkspace sharedWorkspace] performSelectorOnMainThread:@selector(_web_noteFileChangedAtPath:)
- withObject:[download path]
- waitUntilDone:NO];
- }
+ [download _setResourceForkReferenceNumber:0];
+ }
+
+ if ([download _isFileClosed]) {
+ WebError *error = [download _encounteredCloseError] ?
+ [download _errorWithCode:WebKitErrorCannotCloseFile] : nil;
+ [download performSelectorOnMainThread:@selector(_didCloseFile:) withObject:error waitUntilDone:NO];
}
[download release];
@@ -572,9 +918,7 @@ static void DeleteCompletionCallback(ParmBlkPtr paramBlock)
if (block->paramBlock.ioResult != noErr) {
ERROR("Removal of download file failed with error: %d", block->paramBlock.ioResult);
} else {
- [[NSWorkspace sharedWorkspace] performSelectorOnMainThread:@selector(_web_noteFileChangedAtPath:)
- withObject:[download path]
- waitUntilDone:NO];
+ [download performSelectorOnMainThread:@selector(_didDeleteFile) withObject:nil waitUntilDone:NO];
}
[download release];
diff --git a/WebKit/Downloads.subproj/WebDownloadPrivate.h b/WebKit/Downloads.subproj/WebDownloadPrivate.h
index d8099d8..b385894 100644
--- a/WebKit/Downloads.subproj/WebDownloadPrivate.h
+++ b/WebKit/Downloads.subproj/WebDownloadPrivate.h
@@ -11,37 +11,6 @@
@class WebResource;
@interface WebDownload (WebPrivate)
-- _initWithLoadingHandle:(WebResource *)handle
- request:(WebRequest *)request
- response:(WebRequest *)response
- delegate:(id <WebDownloadDelegate>)delegate;
-// FIXME: Remove many of the following methods.
-- initWithDataSource:(WebDataSource *)dSource;
-- (WebError *)receivedData:(NSData *)data;
-- (WebError *)finishedLoading;
-- (void)decodeHeaderData:(NSData *)headerData
- dataForkData:(NSData **)dataForkData
- resourceForkData:(NSData **)resourceForkData;
-- (BOOL)decodeData:(NSData *)data
- dataForkData:(NSData **)dataForkData
- resourceForkData:(NSData **)resourceForkData;
-- (void)closeFork:(SInt16)forkRefNum deleteFile:(BOOL)deleteFile;
-- (void)closeFileAndDelete:(BOOL)deleteFile;
-- (void)closeFile;
-- (void)cleanUpAfterFailure;
-- (WebError *)createFileIfNecessary;
-- (WebError *)writeDataForkData:(NSData *)dataForkData resourceForkData:(NSData *)resourceForkData;
-- (NSData *)dataIfDoneBufferingData:(NSData *)data;
-- (WebError *)decodeData:(NSData *)data;
-- (BOOL)finishDecoding;
-- (NSString *)path;
-- (WebError *)errorWithCode:(int)code;
-- (void)cancelWithError:(WebError *)error;
-- (SInt16)dataForkReferenceNumber;
-- (void)setDataForkReferenceNumber:(SInt16)forkRefNum;
-- (SInt16)resourceForkReferenceNumber;
-- (void)setResourceForkReferenceNumber:(SInt16)forkRefNum;
-- (BOOL)writeForkData:(NSData *)data isDataFork:(BOOL)isDataFork;
-- (BOOL)areWritesCancelled;
-- (void)setWritesCancelled:(BOOL)cancelled;
+- _initWithLoadingResource:(WebResource *)resource dataSource:(WebDataSource *)dataSource;
+- (void)_setPath:(NSString *)path;
@end
diff --git a/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.h b/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.h
index ca50a89..f7f62f4 100644
--- a/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.h
+++ b/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.h
@@ -18,7 +18,7 @@
{
@protected
WebDataSource *dataSource;
- WebResource *handle;
+ WebResource *resource;
WebRequest *request;
@private
WebController *controller;
@@ -41,7 +41,6 @@
- resourceLoadDelegate;
- downloadDelegate;
-- (BOOL)isDownload;
- (void)cancel;
- (void)cancelQuietly;
diff --git a/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.m b/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.m
index aee3fa1..b8b50e1 100644
--- a/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.m
+++ b/WebKit/WebView.subproj/WebBaseResourceHandleDelegate.m
@@ -33,8 +33,8 @@
[identifier release];
identifier = nil;
- [handle release];
- handle = nil;
+ [resource release];
+ resource = nil;
[controller release];
controller = nil;
@@ -64,19 +64,19 @@
- (void)startLoading:(WebRequest *)r
{
- [handle loadWithDelegate:self];
+ [resource loadWithDelegate:self];
}
- (BOOL)loadWithRequest:(WebRequest *)r
{
- ASSERT(handle == nil);
+ ASSERT(resource == nil);
- handle = [[WebResource alloc] initWithRequest:r];
- if (!handle) {
+ resource = [[WebResource alloc] initWithRequest:r];
+ if (!resource) {
return NO;
}
if (defersCallbacks) {
- [handle setDefersCallbacks:YES];
+ [resource setDefersCallbacks:YES];
}
[self startLoading:r];
@@ -87,7 +87,7 @@
- (void)setDefersCallbacks:(BOOL)defers
{
defersCallbacks = defers;
- [handle setDefersCallbacks:defers];
+ [resource setDefersCallbacks:defers];
}
- (BOOL)defersCallbacks
@@ -129,14 +129,9 @@
return downloadDelegate;
}
-- (BOOL)isDownload
-{
- return NO;
-}
-
-(WebRequest *)resource:(WebResource *)h willSendRequest:(WebRequest *)newRequest
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
[newRequest setUserAgent:[controller userAgentForURL:[newRequest URL]]];
@@ -182,41 +177,31 @@
-(void)resource:(WebResource *)h didReceiveResponse:(WebResponse *)r
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
[r retain];
[response release];
response = r;
- if ([self isDownload])
- [downloadDelegate resource:identifier didReceiveResponse:r fromDataSource:dataSource];
- else {
- [dataSource _addResponse: r];
- [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveResponse:r fromDataSource:dataSource];
- }
+ [dataSource _addResponse: r];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveResponse:r fromDataSource:dataSource];
}
- (void)resource:(WebResource *)h didReceiveData:(NSData *)data
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
- if ([self isDownload])
- [downloadDelegate resource:identifier didReceiveContentLength:[data length] fromDataSource:dataSource];
- else
- [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveContentLength:[data length] fromDataSource:dataSource];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveContentLength:[data length] fromDataSource:dataSource];
}
- (void)resourceDidFinishLoading:(WebResource *)h
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
- if ([self isDownload])
- [downloadDelegate resource:identifier didFinishLoadingFromDataSource:dataSource];
- else
- [[controller _resourceLoadDelegateForwarder] resource:identifier didFinishLoadingFromDataSource:dataSource];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didFinishLoadingFromDataSource:dataSource];
ASSERT(currentURL);
[[WebStandardPanels sharedStandardPanels] _didStopLoadingURL:currentURL inController:controller];
@@ -226,13 +211,10 @@
- (void)resource:(WebResource *)h didFailLoadingWithError:(WebError *)result
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
- if ([self isDownload])
- [downloadDelegate resource:identifier didFailLoadingWithError:result fromDataSource:dataSource];
- else
- [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:result fromDataSource:dataSource];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:result fromDataSource:dataSource];
// currentURL may be nil if the request was aborted
if (currentURL)
@@ -245,18 +227,14 @@
{
ASSERT(!reachedTerminalState);
- [handle cancel];
+ [resource cancel];
// currentURL may be nil if the request was aborted
if (currentURL)
[[WebStandardPanels sharedStandardPanels] _didStopLoadingURL:currentURL inController:controller];
if (error) {
- if ([self isDownload]) {
- [downloadDelegate resource:identifier didFailLoadingWithError:error fromDataSource:dataSource];
- } else {
- [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:error fromDataSource:dataSource];
- }
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:error fromDataSource:dataSource];
}
[self _releaseResources];
diff --git a/WebKit/WebView.subproj/WebController.h b/WebKit/WebView.subproj/WebController.h
index 0ce09ae..f325c6f 100644
--- a/WebKit/WebView.subproj/WebController.h
+++ b/WebKit/WebView.subproj/WebController.h
@@ -146,15 +146,15 @@ extern NSString *WebElementLinkLabelKey; // NSString of the text within the anch
/*!
@method setDownloadDelegate:
- @abstract Set the controller's WebResourceLoadDelegate download delegate.
- @param delegate The WebResourceLoadDelegate to set as the download delegate.
+ @abstract Set the controller's WebDownloadDelegate.
+ @param delegate The WebDownloadDelegate to set as the download delegate.
*/
- (void)setDownloadDelegate: (id)delegate;
/*!
@method downloadDelegate
- @abstract Return the controller's WebResourceLoadDelegate download delegate.
- @result The controller's WebResourceLoadDelegate download delegate.
+ @abstract Return the controller's WebDownloadDelegate.
+ @result The controller's WebDownloadDelegate.
*/
- (id)downloadDelegate;
diff --git a/WebKit/WebView.subproj/WebController.m b/WebKit/WebView.subproj/WebController.m
index 827b5dc..362bfaf 100644
--- a/WebKit/WebView.subproj/WebController.m
+++ b/WebKit/WebView.subproj/WebController.m
@@ -167,13 +167,13 @@ NSString *WebElementLinkTitleKey = @"WebElementLinkTitle";
- (void)setDownloadDelegate: delegate
{
- _private->downloadProgressDelegate = delegate;
+ _private->downloadDelegate = delegate;
}
- downloadDelegate
{
- return _private->downloadProgressDelegate;
+ return _private->downloadDelegate;
}
- (void)setContextMenuDelegate: delegate
diff --git a/WebKit/WebView.subproj/WebControllerPolicyDelegate.h b/WebKit/WebView.subproj/WebControllerPolicyDelegate.h
index 46fdad5..de07d81 100644
--- a/WebKit/WebView.subproj/WebControllerPolicyDelegate.h
+++ b/WebKit/WebView.subproj/WebControllerPolicyDelegate.h
@@ -117,18 +117,6 @@ typedef enum {
andRequest:(WebRequest *)request
inFrame:(WebFrame *)frame;
-
-/*!
- @method saveFilenameForResponse:andRequest:
- @discussion Returns the filename to use for a load that's being saved.
- @param response The response for the partially loaded content.
- @param request A WebResourceRequest for the partially loaded content.
- @result The filename to use to save a loaded resource.
-*/
-- (NSString *)savePathForResponse:(WebResponse *)response
- andRequest:(WebRequest *)request;
-
-
/*!
@method unableToImplementPolicy:error:forURL:inFrame:
@discussion Called when a WebPolicy could not be implemented. It is up to the client to display appropriate feedback.
diff --git a/WebKit/WebView.subproj/WebControllerPrivate.h b/WebKit/WebView.subproj/WebControllerPrivate.h
index 19bd75f..c2d3cf5 100644
--- a/WebKit/WebView.subproj/WebControllerPrivate.h
+++ b/WebKit/WebView.subproj/WebControllerPrivate.h
@@ -24,7 +24,7 @@ enum { NumUserAgentStringTypes = WinIE + 1 };
id windowContext;
id resourceProgressDelegate;
- id downloadProgressDelegate;
+ id downloadDelegate;
id contextMenuDelegate;
id policyDelegate;
id locationChangeDelegate;
diff --git a/WebKit/WebView.subproj/WebDefaultPolicyDelegate.m b/WebKit/WebView.subproj/WebDefaultPolicyDelegate.m
index c4560a6..4b40ee2 100644
--- a/WebKit/WebView.subproj/WebDefaultPolicyDelegate.m
+++ b/WebKit/WebView.subproj/WebDefaultPolicyDelegate.m
@@ -54,12 +54,6 @@ static WebDefaultPolicyDelegate *sharedDelegate = nil;
}
}
-- (NSString *)savePathForResponse:(WebResponse *)response
- andRequest:(WebRequest *)request
-{
- return nil;
-}
-
- (void)decideNavigationPolicyForAction:(NSDictionary *)actionInformation
andRequest:(WebRequest *)request
inFrame:(WebFrame *)frame
diff --git a/WebKit/WebView.subproj/WebLoader.h b/WebKit/WebView.subproj/WebLoader.h
index ca50a89..f7f62f4 100644
--- a/WebKit/WebView.subproj/WebLoader.h
+++ b/WebKit/WebView.subproj/WebLoader.h
@@ -18,7 +18,7 @@
{
@protected
WebDataSource *dataSource;
- WebResource *handle;
+ WebResource *resource;
WebRequest *request;
@private
WebController *controller;
@@ -41,7 +41,6 @@
- resourceLoadDelegate;
- downloadDelegate;
-- (BOOL)isDownload;
- (void)cancel;
- (void)cancelQuietly;
diff --git a/WebKit/WebView.subproj/WebLoader.m b/WebKit/WebView.subproj/WebLoader.m
index aee3fa1..b8b50e1 100644
--- a/WebKit/WebView.subproj/WebLoader.m
+++ b/WebKit/WebView.subproj/WebLoader.m
@@ -33,8 +33,8 @@
[identifier release];
identifier = nil;
- [handle release];
- handle = nil;
+ [resource release];
+ resource = nil;
[controller release];
controller = nil;
@@ -64,19 +64,19 @@
- (void)startLoading:(WebRequest *)r
{
- [handle loadWithDelegate:self];
+ [resource loadWithDelegate:self];
}
- (BOOL)loadWithRequest:(WebRequest *)r
{
- ASSERT(handle == nil);
+ ASSERT(resource == nil);
- handle = [[WebResource alloc] initWithRequest:r];
- if (!handle) {
+ resource = [[WebResource alloc] initWithRequest:r];
+ if (!resource) {
return NO;
}
if (defersCallbacks) {
- [handle setDefersCallbacks:YES];
+ [resource setDefersCallbacks:YES];
}
[self startLoading:r];
@@ -87,7 +87,7 @@
- (void)setDefersCallbacks:(BOOL)defers
{
defersCallbacks = defers;
- [handle setDefersCallbacks:defers];
+ [resource setDefersCallbacks:defers];
}
- (BOOL)defersCallbacks
@@ -129,14 +129,9 @@
return downloadDelegate;
}
-- (BOOL)isDownload
-{
- return NO;
-}
-
-(WebRequest *)resource:(WebResource *)h willSendRequest:(WebRequest *)newRequest
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
[newRequest setUserAgent:[controller userAgentForURL:[newRequest URL]]];
@@ -182,41 +177,31 @@
-(void)resource:(WebResource *)h didReceiveResponse:(WebResponse *)r
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
[r retain];
[response release];
response = r;
- if ([self isDownload])
- [downloadDelegate resource:identifier didReceiveResponse:r fromDataSource:dataSource];
- else {
- [dataSource _addResponse: r];
- [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveResponse:r fromDataSource:dataSource];
- }
+ [dataSource _addResponse: r];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveResponse:r fromDataSource:dataSource];
}
- (void)resource:(WebResource *)h didReceiveData:(NSData *)data
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
- if ([self isDownload])
- [downloadDelegate resource:identifier didReceiveContentLength:[data length] fromDataSource:dataSource];
- else
- [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveContentLength:[data length] fromDataSource:dataSource];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didReceiveContentLength:[data length] fromDataSource:dataSource];
}
- (void)resourceDidFinishLoading:(WebResource *)h
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
- if ([self isDownload])
- [downloadDelegate resource:identifier didFinishLoadingFromDataSource:dataSource];
- else
- [[controller _resourceLoadDelegateForwarder] resource:identifier didFinishLoadingFromDataSource:dataSource];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didFinishLoadingFromDataSource:dataSource];
ASSERT(currentURL);
[[WebStandardPanels sharedStandardPanels] _didStopLoadingURL:currentURL inController:controller];
@@ -226,13 +211,10 @@
- (void)resource:(WebResource *)h didFailLoadingWithError:(WebError *)result
{
- ASSERT(handle == h);
+ ASSERT(resource == h);
ASSERT(!reachedTerminalState);
- if ([self isDownload])
- [downloadDelegate resource:identifier didFailLoadingWithError:result fromDataSource:dataSource];
- else
- [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:result fromDataSource:dataSource];
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:result fromDataSource:dataSource];
// currentURL may be nil if the request was aborted
if (currentURL)
@@ -245,18 +227,14 @@
{
ASSERT(!reachedTerminalState);
- [handle cancel];
+ [resource cancel];
// currentURL may be nil if the request was aborted
if (currentURL)
[[WebStandardPanels sharedStandardPanels] _didStopLoadingURL:currentURL inController:controller];
if (error) {
- if ([self isDownload]) {
- [downloadDelegate resource:identifier didFailLoadingWithError:error fromDataSource:dataSource];
- } else {
- [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:error fromDataSource:dataSource];
- }
+ [[controller _resourceLoadDelegateForwarder] resource:identifier didFailLoadingWithError:error fromDataSource:dataSource];
}
[self _releaseResources];
diff --git a/WebKit/WebView.subproj/WebMainResourceClient.h b/WebKit/WebView.subproj/WebMainResourceClient.h
index 4e018f8..d5a17f4 100644
--- a/WebKit/WebView.subproj/WebMainResourceClient.h
+++ b/WebKit/WebView.subproj/WebMainResourceClient.h
@@ -14,19 +14,19 @@
@class WebDownload;
@class WebDataSource;
@class WebResource;
+ at class WebResourceDelegateProxy;
@class WebRequest;
@class WebResponse;
@interface WebMainResourceClient : WebBaseResourceHandleDelegate
{
- WebDownload *download;
NSMutableData *resourceData;
int _contentLength; // for logging only
int _bytesReceived; // for logging only
+ WebResourceDelegateProxy *proxy;
}
- initWithDataSource:(WebDataSource *)dataSource;
-- (WebDownload *)download;
- (NSData *)resourceData;
@end
diff --git a/WebKit/WebView.subproj/WebMainResourceClient.m b/WebKit/WebView.subproj/WebMainResourceClient.m
index 2fea522..9ee3901 100644
--- a/WebKit/WebView.subproj/WebMainResourceClient.m
+++ b/WebKit/WebView.subproj/WebMainResourceClient.m
@@ -34,6 +34,13 @@
// FIXME: More that is in common with WebSubresourceClient should move up into WebBaseResourceHandleDelegate.
+ at interface WebResourceDelegateProxy : NSObject <WebResourceDelegate>
+{
+ id <WebResourceDelegate> delegate;
+}
+- (void)setDelegate:(id <WebResourceDelegate>)theDelegate;
+ at end
+
@implementation WebMainResourceClient
- initWithDataSource:(WebDataSource *)ds
@@ -43,16 +50,17 @@
if (self) {
resourceData = [[NSMutableData alloc] init];
[self setDataSource:ds];
+ proxy = [[WebResourceDelegateProxy alloc] init];
+ [proxy setDelegate:self];
}
return self;
}
- (void)dealloc
-{
- ASSERT(download == nil);
-
+{
[resourceData release];
+ [proxy release];
[super dealloc];
}
@@ -62,27 +70,9 @@
return resourceData;
}
-- (WebDownload *)download
-{
- return download;
-}
-
-- (BOOL)isDownload
-{
- return download != nil;
-}
-
- (void)receivedError:(WebError *)error complete:(BOOL)isComplete
{
- if (download) {
- ASSERT(isComplete);
- [download cancel];
- [download release];
- download = nil;
- [dataSource _setPrimaryLoadComplete:YES];
- } else {
- [dataSource _receivedError:error complete:isComplete];
- }
+ [dataSource _receivedError:error complete:isComplete];
}
- (void)cancel
@@ -180,34 +170,20 @@
break;
case WebPolicySave:
- [dataSource _setIsDownloading:YES];
-
- NSString *path = [dataSource downloadPath];
- if (path == nil || ![path isAbsolutePath]) {
- NSString *directory = [dataSource _downloadDirectory];
- if (directory != nil && [directory isAbsolutePath]) {
- path = [directory stringByAppendingPathComponent:[r suggestedFilenameForSaving]];
- } else {
- id pd = [[dataSource _controller] policyDelegate];
-
- if ([pd respondsToSelector: @selector(savePathForResponse:andRequest:)])
- path = [pd savePathForResponse:r andRequest:req];
- // FIXME: Maybe there a cleaner way handle the bad filename case?
- if (path == nil || ![path isAbsolutePath]) {
- ERROR("Nil or non-absolute path returned from savePathForResponse:andRequest:.");
- [self stopLoadingForPolicyChange];
- return;
- }
- }
-
- [dataSource _setDownloadPath:path];
- }
+ ASSERT([self downloadDelegate]);
- [self interruptForPolicyChangeAndKeepLoading:YES];
+ WebDownload *download = [[WebDownload alloc] _initWithLoadingResource:resource dataSource:dataSource];
+ NSString *directory = [dataSource _downloadDirectory];
+ if (directory != nil && [directory isAbsolutePath]) {
+ // FIXME: Predetermined downloads should not be using this code path (3191052).
+ NSString *path = [directory stringByAppendingPathComponent:[r suggestedFilenameForSaving]];
+ [download _setPath:path];
+ }
+
+ [proxy setDelegate:(id <WebResourceDelegate>)download];
+ [download release];
- // Hand off the dataSource to the download handler. This will cause the remaining
- // handle delegate callbacks to go to the controller's download delegate.
- download = [[WebDownload alloc] initWithDataSource:dataSource];
+ [self interruptForPolicyChangeAndKeepLoading:YES];
break;
case WebPolicyOpenURL:
@@ -245,10 +221,10 @@
ERROR("contentPolicyForMIMEType:andRequest:inFrame: returned an invalid content policy.");
}
- [super resource:handle didReceiveResponse:r];
+ [super resource:resource didReceiveResponse:r];
if ([[req URL] _web_shouldLoadAsEmptyDocument]) {
- [self resourceDidFinishLoading:handle];
+ [self resourceDidFinishLoading:resource];
}
}
@@ -277,10 +253,11 @@
ASSERT([dataSource isDownloading] || ![[dataSource _controller] defersCallbacks]);
[dataSource _setResponse:r];
- LOG(Download, "main content type: %@", [r contentType]);
+ LOG(Loading, "main content type: %@", [r contentType]);
[[dataSource _controller] setDefersCallbacks:YES];
+ // FIXME: Predetermined downloads should not be using this code path (3191052).
// Figure out the content policy.
if (![dataSource isDownloading]) {
[self checkContentPolicyForResponse:r andCallSelector:@selector(continueAfterContentPolicy:response:)];
@@ -297,64 +274,39 @@
ASSERT([data length] != 0);
ASSERT(![h defersCallbacks]);
ASSERT(![self defersCallbacks]);
- ASSERT([self isDownload] || ![[dataSource _controller] defersCallbacks]);
+ ASSERT(![[dataSource _controller] defersCallbacks]);
LOG(Loading, "URL = %@, data = %p, length %d", [dataSource _URL], data, [data length]);
- WebError *downloadError= nil;
-
- if (download) {
- downloadError = [download receivedData:data];
- } else {
- [resourceData appendData:data];
- [dataSource _receivedData:data];
- [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
- fromDataSource:dataSource
- complete:NO];
- }
-
+ [resourceData appendData:data];
+ [dataSource _receivedData:data];
+ [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
+ fromDataSource:dataSource
+ complete:NO];
+
[super resource:h didReceiveData:data];
_bytesReceived += [data length];
-
- if(downloadError){
- // Cancel download after calling didReceiveData to preserve ordering of calls.
- [self cancelWithError:downloadError];
- }
- LOG(Download, "%d of %d", _bytesReceived, _contentLength);
+ LOG(Loading, "%d of %d", _bytesReceived, _contentLength);
}
- (void)resourceDidFinishLoading:(WebResource *)h
{
ASSERT(![h defersCallbacks]);
ASSERT(![self defersCallbacks]);
- ASSERT([self isDownload] || ![[dataSource _controller] defersCallbacks]);
+ ASSERT(![[dataSource _controller] defersCallbacks]);
+
LOG(Loading, "URL = %@", [dataSource _URL]);
// Calls in this method will most likely result in a call to release, so we must retain.
[self retain];
- WebError *downloadError = nil;
-
- if (download) {
- downloadError = [download finishedLoading];
- [dataSource _setPrimaryLoadComplete:YES];
- } else {
- [dataSource _setResourceData:resourceData];
- [dataSource _finishedLoading];
- [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
- fromDataSource:dataSource
- complete:YES];
- }
-
- if(downloadError){
- [super resource:h didFailLoadingWithError:downloadError];
- } else {
- [super resourceDidFinishLoading:h];
- }
-
- [download release];
- download = nil;
+ [dataSource _setResourceData:resourceData];
+ [dataSource _finishedLoading];
+ [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
+ fromDataSource:dataSource
+ complete:YES];
+ [super resourceDidFinishLoading:h];
[self release];
}
@@ -363,7 +315,8 @@
{
ASSERT(![h defersCallbacks]);
ASSERT(![self defersCallbacks]);
- ASSERT([self isDownload] || ![[dataSource _controller] defersCallbacks]);
+ ASSERT(![[dataSource _controller] defersCallbacks]);
+
LOG(Loading, "URL = %@, error = %@", [error failingURL], [error errorDescription]);
// Calling receivedError will likely result in a call to release, so we must retain.
@@ -378,16 +331,16 @@
- (void)startLoading:(WebRequest *)r
{
if ([[r URL] _web_shouldLoadAsEmptyDocument]) {
- [self resource:handle willSendRequest:r];
+ [self resource:resource willSendRequest:r];
WebResponse *rsp = [[WebResponse alloc] init];
[rsp setURL:[r URL]];
[rsp setContentType:@"text/html"];
[rsp setContentLength:0];
- [self resource:handle didReceiveResponse:rsp];
+ [self resource:resource didReceiveResponse:rsp];
[rsp release];
} else {
- [super startLoading:r];
+ [resource loadWithDelegate:proxy];
}
}
@@ -400,3 +353,42 @@
@end
+
+ at implementation WebResourceDelegateProxy
+
+- (void)setDelegate:(id <WebResourceDelegate>)theDelegate
+{
+ if (delegate != theDelegate) {
+ [delegate release];
+ delegate = [theDelegate retain];
+ }
+}
+
+- (WebRequest *)resource:(WebResource *)resource willSendRequest:(WebRequest *)request
+{
+ return [delegate resource:resource willSendRequest:request];
+}
+
+-(void)resource:(WebResource *)resource didReceiveResponse:(WebResponse *)response
+{
+ [delegate resource:resource didReceiveResponse:response];
+}
+
+-(void)resource:(WebResource *)resource didReceiveData:(NSData *)data
+{
+ [delegate resource:resource didReceiveData:data];
+}
+
+-(void)resourceDidFinishLoading:(WebResource *)resource
+{
+ [delegate resourceDidFinishLoading:resource];
+ [delegate release];
+}
+
+-(void)resource:(WebResource *)resource didFailLoadingWithError:(WebError *)error
+{
+ [delegate resource:resource didFailLoadingWithError:error];
+ [delegate release];
+}
+
+ at end
diff --git a/WebKit/WebView.subproj/WebMainResourceLoader.h b/WebKit/WebView.subproj/WebMainResourceLoader.h
index 4e018f8..d5a17f4 100644
--- a/WebKit/WebView.subproj/WebMainResourceLoader.h
+++ b/WebKit/WebView.subproj/WebMainResourceLoader.h
@@ -14,19 +14,19 @@
@class WebDownload;
@class WebDataSource;
@class WebResource;
+ at class WebResourceDelegateProxy;
@class WebRequest;
@class WebResponse;
@interface WebMainResourceClient : WebBaseResourceHandleDelegate
{
- WebDownload *download;
NSMutableData *resourceData;
int _contentLength; // for logging only
int _bytesReceived; // for logging only
+ WebResourceDelegateProxy *proxy;
}
- initWithDataSource:(WebDataSource *)dataSource;
-- (WebDownload *)download;
- (NSData *)resourceData;
@end
diff --git a/WebKit/WebView.subproj/WebMainResourceLoader.m b/WebKit/WebView.subproj/WebMainResourceLoader.m
index 2fea522..9ee3901 100644
--- a/WebKit/WebView.subproj/WebMainResourceLoader.m
+++ b/WebKit/WebView.subproj/WebMainResourceLoader.m
@@ -34,6 +34,13 @@
// FIXME: More that is in common with WebSubresourceClient should move up into WebBaseResourceHandleDelegate.
+ at interface WebResourceDelegateProxy : NSObject <WebResourceDelegate>
+{
+ id <WebResourceDelegate> delegate;
+}
+- (void)setDelegate:(id <WebResourceDelegate>)theDelegate;
+ at end
+
@implementation WebMainResourceClient
- initWithDataSource:(WebDataSource *)ds
@@ -43,16 +50,17 @@
if (self) {
resourceData = [[NSMutableData alloc] init];
[self setDataSource:ds];
+ proxy = [[WebResourceDelegateProxy alloc] init];
+ [proxy setDelegate:self];
}
return self;
}
- (void)dealloc
-{
- ASSERT(download == nil);
-
+{
[resourceData release];
+ [proxy release];
[super dealloc];
}
@@ -62,27 +70,9 @@
return resourceData;
}
-- (WebDownload *)download
-{
- return download;
-}
-
-- (BOOL)isDownload
-{
- return download != nil;
-}
-
- (void)receivedError:(WebError *)error complete:(BOOL)isComplete
{
- if (download) {
- ASSERT(isComplete);
- [download cancel];
- [download release];
- download = nil;
- [dataSource _setPrimaryLoadComplete:YES];
- } else {
- [dataSource _receivedError:error complete:isComplete];
- }
+ [dataSource _receivedError:error complete:isComplete];
}
- (void)cancel
@@ -180,34 +170,20 @@
break;
case WebPolicySave:
- [dataSource _setIsDownloading:YES];
-
- NSString *path = [dataSource downloadPath];
- if (path == nil || ![path isAbsolutePath]) {
- NSString *directory = [dataSource _downloadDirectory];
- if (directory != nil && [directory isAbsolutePath]) {
- path = [directory stringByAppendingPathComponent:[r suggestedFilenameForSaving]];
- } else {
- id pd = [[dataSource _controller] policyDelegate];
-
- if ([pd respondsToSelector: @selector(savePathForResponse:andRequest:)])
- path = [pd savePathForResponse:r andRequest:req];
- // FIXME: Maybe there a cleaner way handle the bad filename case?
- if (path == nil || ![path isAbsolutePath]) {
- ERROR("Nil or non-absolute path returned from savePathForResponse:andRequest:.");
- [self stopLoadingForPolicyChange];
- return;
- }
- }
-
- [dataSource _setDownloadPath:path];
- }
+ ASSERT([self downloadDelegate]);
- [self interruptForPolicyChangeAndKeepLoading:YES];
+ WebDownload *download = [[WebDownload alloc] _initWithLoadingResource:resource dataSource:dataSource];
+ NSString *directory = [dataSource _downloadDirectory];
+ if (directory != nil && [directory isAbsolutePath]) {
+ // FIXME: Predetermined downloads should not be using this code path (3191052).
+ NSString *path = [directory stringByAppendingPathComponent:[r suggestedFilenameForSaving]];
+ [download _setPath:path];
+ }
+
+ [proxy setDelegate:(id <WebResourceDelegate>)download];
+ [download release];
- // Hand off the dataSource to the download handler. This will cause the remaining
- // handle delegate callbacks to go to the controller's download delegate.
- download = [[WebDownload alloc] initWithDataSource:dataSource];
+ [self interruptForPolicyChangeAndKeepLoading:YES];
break;
case WebPolicyOpenURL:
@@ -245,10 +221,10 @@
ERROR("contentPolicyForMIMEType:andRequest:inFrame: returned an invalid content policy.");
}
- [super resource:handle didReceiveResponse:r];
+ [super resource:resource didReceiveResponse:r];
if ([[req URL] _web_shouldLoadAsEmptyDocument]) {
- [self resourceDidFinishLoading:handle];
+ [self resourceDidFinishLoading:resource];
}
}
@@ -277,10 +253,11 @@
ASSERT([dataSource isDownloading] || ![[dataSource _controller] defersCallbacks]);
[dataSource _setResponse:r];
- LOG(Download, "main content type: %@", [r contentType]);
+ LOG(Loading, "main content type: %@", [r contentType]);
[[dataSource _controller] setDefersCallbacks:YES];
+ // FIXME: Predetermined downloads should not be using this code path (3191052).
// Figure out the content policy.
if (![dataSource isDownloading]) {
[self checkContentPolicyForResponse:r andCallSelector:@selector(continueAfterContentPolicy:response:)];
@@ -297,64 +274,39 @@
ASSERT([data length] != 0);
ASSERT(![h defersCallbacks]);
ASSERT(![self defersCallbacks]);
- ASSERT([self isDownload] || ![[dataSource _controller] defersCallbacks]);
+ ASSERT(![[dataSource _controller] defersCallbacks]);
LOG(Loading, "URL = %@, data = %p, length %d", [dataSource _URL], data, [data length]);
- WebError *downloadError= nil;
-
- if (download) {
- downloadError = [download receivedData:data];
- } else {
- [resourceData appendData:data];
- [dataSource _receivedData:data];
- [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
- fromDataSource:dataSource
- complete:NO];
- }
-
+ [resourceData appendData:data];
+ [dataSource _receivedData:data];
+ [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
+ fromDataSource:dataSource
+ complete:NO];
+
[super resource:h didReceiveData:data];
_bytesReceived += [data length];
-
- if(downloadError){
- // Cancel download after calling didReceiveData to preserve ordering of calls.
- [self cancelWithError:downloadError];
- }
- LOG(Download, "%d of %d", _bytesReceived, _contentLength);
+ LOG(Loading, "%d of %d", _bytesReceived, _contentLength);
}
- (void)resourceDidFinishLoading:(WebResource *)h
{
ASSERT(![h defersCallbacks]);
ASSERT(![self defersCallbacks]);
- ASSERT([self isDownload] || ![[dataSource _controller] defersCallbacks]);
+ ASSERT(![[dataSource _controller] defersCallbacks]);
+
LOG(Loading, "URL = %@", [dataSource _URL]);
// Calls in this method will most likely result in a call to release, so we must retain.
[self retain];
- WebError *downloadError = nil;
-
- if (download) {
- downloadError = [download finishedLoading];
- [dataSource _setPrimaryLoadComplete:YES];
- } else {
- [dataSource _setResourceData:resourceData];
- [dataSource _finishedLoading];
- [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
- fromDataSource:dataSource
- complete:YES];
- }
-
- if(downloadError){
- [super resource:h didFailLoadingWithError:downloadError];
- } else {
- [super resourceDidFinishLoading:h];
- }
-
- [download release];
- download = nil;
+ [dataSource _setResourceData:resourceData];
+ [dataSource _finishedLoading];
+ [[dataSource _controller] _mainReceivedBytesSoFar:[resourceData length]
+ fromDataSource:dataSource
+ complete:YES];
+ [super resourceDidFinishLoading:h];
[self release];
}
@@ -363,7 +315,8 @@
{
ASSERT(![h defersCallbacks]);
ASSERT(![self defersCallbacks]);
- ASSERT([self isDownload] || ![[dataSource _controller] defersCallbacks]);
+ ASSERT(![[dataSource _controller] defersCallbacks]);
+
LOG(Loading, "URL = %@, error = %@", [error failingURL], [error errorDescription]);
// Calling receivedError will likely result in a call to release, so we must retain.
@@ -378,16 +331,16 @@
- (void)startLoading:(WebRequest *)r
{
if ([[r URL] _web_shouldLoadAsEmptyDocument]) {
- [self resource:handle willSendRequest:r];
+ [self resource:resource willSendRequest:r];
WebResponse *rsp = [[WebResponse alloc] init];
[rsp setURL:[r URL]];
[rsp setContentType:@"text/html"];
[rsp setContentLength:0];
- [self resource:handle didReceiveResponse:rsp];
+ [self resource:resource didReceiveResponse:rsp];
[rsp release];
} else {
- [super startLoading:r];
+ [resource loadWithDelegate:proxy];
}
}
@@ -400,3 +353,42 @@
@end
+
+ at implementation WebResourceDelegateProxy
+
+- (void)setDelegate:(id <WebResourceDelegate>)theDelegate
+{
+ if (delegate != theDelegate) {
+ [delegate release];
+ delegate = [theDelegate retain];
+ }
+}
+
+- (WebRequest *)resource:(WebResource *)resource willSendRequest:(WebRequest *)request
+{
+ return [delegate resource:resource willSendRequest:request];
+}
+
+-(void)resource:(WebResource *)resource didReceiveResponse:(WebResponse *)response
+{
+ [delegate resource:resource didReceiveResponse:response];
+}
+
+-(void)resource:(WebResource *)resource didReceiveData:(NSData *)data
+{
+ [delegate resource:resource didReceiveData:data];
+}
+
+-(void)resourceDidFinishLoading:(WebResource *)resource
+{
+ [delegate resourceDidFinishLoading:resource];
+ [delegate release];
+}
+
+-(void)resource:(WebResource *)resource didFailLoadingWithError:(WebError *)error
+{
+ [delegate resource:resource didFailLoadingWithError:error];
+ [delegate release];
+}
+
+ at end
diff --git a/WebKit/WebView.subproj/WebPolicyDelegate.h b/WebKit/WebView.subproj/WebPolicyDelegate.h
index 46fdad5..de07d81 100644
--- a/WebKit/WebView.subproj/WebPolicyDelegate.h
+++ b/WebKit/WebView.subproj/WebPolicyDelegate.h
@@ -117,18 +117,6 @@ typedef enum {
andRequest:(WebRequest *)request
inFrame:(WebFrame *)frame;
-
-/*!
- @method saveFilenameForResponse:andRequest:
- @discussion Returns the filename to use for a load that's being saved.
- @param response The response for the partially loaded content.
- @param request A WebResourceRequest for the partially loaded content.
- @result The filename to use to save a loaded resource.
-*/
-- (NSString *)savePathForResponse:(WebResponse *)response
- andRequest:(WebRequest *)request;
-
-
/*!
@method unableToImplementPolicy:error:forURL:inFrame:
@discussion Called when a WebPolicy could not be implemented. It is up to the client to display appropriate feedback.
diff --git a/WebKit/WebView.subproj/WebView.h b/WebKit/WebView.subproj/WebView.h
index 0ce09ae..f325c6f 100644
--- a/WebKit/WebView.subproj/WebView.h
+++ b/WebKit/WebView.subproj/WebView.h
@@ -146,15 +146,15 @@ extern NSString *WebElementLinkLabelKey; // NSString of the text within the anch
/*!
@method setDownloadDelegate:
- @abstract Set the controller's WebResourceLoadDelegate download delegate.
- @param delegate The WebResourceLoadDelegate to set as the download delegate.
+ @abstract Set the controller's WebDownloadDelegate.
+ @param delegate The WebDownloadDelegate to set as the download delegate.
*/
- (void)setDownloadDelegate: (id)delegate;
/*!
@method downloadDelegate
- @abstract Return the controller's WebResourceLoadDelegate download delegate.
- @result The controller's WebResourceLoadDelegate download delegate.
+ @abstract Return the controller's WebDownloadDelegate.
+ @result The controller's WebDownloadDelegate.
*/
- (id)downloadDelegate;
diff --git a/WebKit/WebView.subproj/WebView.m b/WebKit/WebView.subproj/WebView.m
index 827b5dc..362bfaf 100644
--- a/WebKit/WebView.subproj/WebView.m
+++ b/WebKit/WebView.subproj/WebView.m
@@ -167,13 +167,13 @@ NSString *WebElementLinkTitleKey = @"WebElementLinkTitle";
- (void)setDownloadDelegate: delegate
{
- _private->downloadProgressDelegate = delegate;
+ _private->downloadDelegate = delegate;
}
- downloadDelegate
{
- return _private->downloadProgressDelegate;
+ return _private->downloadDelegate;
}
- (void)setContextMenuDelegate: delegate
diff --git a/WebKit/WebView.subproj/WebViewPrivate.h b/WebKit/WebView.subproj/WebViewPrivate.h
index 19bd75f..c2d3cf5 100644
--- a/WebKit/WebView.subproj/WebViewPrivate.h
+++ b/WebKit/WebView.subproj/WebViewPrivate.h
@@ -24,7 +24,7 @@ enum { NumUserAgentStringTypes = WinIE + 1 };
id windowContext;
id resourceProgressDelegate;
- id downloadProgressDelegate;
+ id downloadDelegate;
id contextMenuDelegate;
id policyDelegate;
id locationChangeDelegate;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list