Changeset 10489 in webkit


Ignore:
Timestamp:
Sep 8, 2005 2:35:08 PM (19 years ago)
Author:
justing
Message:

Reviewed by darin

WebKit portion of multipart/x-mixed-replace support

  • WebCoreSupport.subproj/WebSubresourceLoader.m: (+[WebSubresourceLoader startLoadingResource:withRequest:customHeaders:referrer:forDataSource:]): Subresource case: Check for Foundation level multipart support (-[WebSubresourceLoader didReceiveResponse:]): Send previously received data in a multipart section to the coreLoader (-[WebSubresourceLoader didReceiveData:lengthReceived:]): Don't send data to the coreLoader until it has been completely received
  • WebView.subproj/WebDataSource.m: (-[WebDataSource _startLoading:]): Main resource case: check for Foundation level multipart support (+[WebDataSource _repTypesAllowImageTypeOmission:]): Some server apps send data right after declaring content multipart/x-mixed-replace, and expect it to be treated as html (-[WebDataSource _commitIfReady:]): Don't ask the WebFrame to close its old WebDataSource when loading a multipart section, because we're going to reuse it (-[WebDataSource _receivedData:]): For non text/html multipart sections, we commit the data all at once, at the end (-[WebDataSource _doesProgressiveLoadWithMIMEType:]): Added heuristic for when to commit the load incrementally (-[WebDataSource _commitLoadWithData:]): Moved from _receivedData into its own function (-[WebDataSource _revertToProvisionalState]): (-[WebDataSource _setupForReplaceByMIMEType:]): Commits the data received for the previous multipart section if it wasn't loaded progresively, clears out the WebFrame and WebDatasource for the next multipart section
  • WebView.subproj/WebDataSourcePrivate.h:
  • WebView.subproj/WebFrame.m: (-[WebFrame _transitionToCommitted:]): The very first multipart section is treated as a normal load, so that the back/forward list and history are updated. All later sections have a new load type, WebFrameLoadTypeReplace, and are treated like reloads (-[WebFrame _checkLoadCompleteForThisFrame]): Ditto (-[WebFrame _itemForRestoringDocState]): Ditto (-[WebFrame _setupForReplace]): Clears out the WebFrame for the next multipart section
  • WebView.subproj/WebFrameInternal.h:
  • WebView.subproj/WebFramePrivate.h:
  • WebView.subproj/WebFrameView.m: (+[WebFrameView _viewTypesAllowImageTypeOmission:]): See above
  • WebView.subproj/WebLoader.h:
  • WebView.subproj/WebLoader.m: (-[NSURLProtocol clearResourceData]): (-[NSURLProtocol setSupportsMultipartContent:]):
  • WebView.subproj/WebMainResourceLoader.m: Straightforward (-[WebMainResourceLoader didReceiveResponse:]):
Location:
trunk/WebKit
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKit/ChangeLog

    r10477 r10489  
     12005-09-08  Justin Garcia  <justin.garcia@apple.com>
     2
     3        Reviewed by darin
     4       
     5        WebKit portion of multipart/x-mixed-replace support
     6
     7        * WebCoreSupport.subproj/WebSubresourceLoader.m:
     8        (+[WebSubresourceLoader startLoadingResource:withRequest:customHeaders:referrer:forDataSource:]):
     9        Subresource case: Check for Foundation level multipart support
     10        (-[WebSubresourceLoader didReceiveResponse:]):
     11        Send previously received data in a multipart section to the coreLoader
     12        (-[WebSubresourceLoader didReceiveData:lengthReceived:]):
     13        Don't send data to the coreLoader until it has been completely received
     14        * WebView.subproj/WebDataSource.m:
     15        (-[WebDataSource _startLoading:]):
     16        Main resource case: check for Foundation level multipart support
     17        (+[WebDataSource _repTypesAllowImageTypeOmission:]):
     18        Some server apps send data right after declaring content multipart/x-mixed-replace, and expect it to be treated as html
     19        (-[WebDataSource _commitIfReady:]):
     20        Don't ask the WebFrame to close its old WebDataSource when loading a multipart section, because we're going to reuse it
     21        (-[WebDataSource _receivedData:]):
     22        For non text/html multipart sections, we commit the data all at once, at the end
     23        (-[WebDataSource _doesProgressiveLoadWithMIMEType:]):
     24        Added heuristic for when to commit the load incrementally
     25        (-[WebDataSource _commitLoadWithData:]):
     26        Moved from _receivedData into its own function
     27        (-[WebDataSource _revertToProvisionalState]):
     28        (-[WebDataSource _setupForReplaceByMIMEType:]):
     29        Commits the data received for the previous multipart section if it wasn't loaded progresively, clears out the WebFrame and WebDatasource for the next multipart section
     30        * WebView.subproj/WebDataSourcePrivate.h:
     31        * WebView.subproj/WebFrame.m:
     32        (-[WebFrame _transitionToCommitted:]):
     33        The very first multipart section is treated as a normal load, so that the back/forward list and history are updated.
     34        All later sections have a new load type, WebFrameLoadTypeReplace, and are treated like reloads
     35        (-[WebFrame _checkLoadCompleteForThisFrame]): Ditto
     36        (-[WebFrame _itemForRestoringDocState]): Ditto
     37        (-[WebFrame _setupForReplace]):
     38        Clears out the WebFrame for the next multipart section
     39        * WebView.subproj/WebFrameInternal.h:
     40        * WebView.subproj/WebFramePrivate.h:
     41        * WebView.subproj/WebFrameView.m:
     42        (+[WebFrameView _viewTypesAllowImageTypeOmission:]): See above
     43        * WebView.subproj/WebLoader.h:
     44        * WebView.subproj/WebLoader.m:
     45        (-[NSURLProtocol clearResourceData]):
     46        (-[NSURLProtocol setSupportsMultipartContent:]):
     47        * WebView.subproj/WebMainResourceLoader.m: Straightforward
     48        (-[WebMainResourceLoader didReceiveResponse:]):
     49
    1502005-09-06  Geoffrey Garen  <ggaren@apple.com>
    251
  • trunk/WebKit/WebCoreSupport.subproj/WebSubresourceLoader.m

    r9971 r10489  
    4141
    4242#import <WebCore/WebCoreResourceLoader.h>
     43#import <WebKitSystemInterface.h>
    4344
    4445@implementation WebSubresourceLoader
     
    6970    WebSubresourceLoader *loader = [[[self alloc] initWithLoader:rLoader dataSource:source] autorelease];
    7071   
     72    [loader setSupportsMultipartContent:WKSupportsMultipartXMixedReplace(newRequest)];
    7173    [source _addSubresourceLoader:loader];
    7274
     
    149151{
    150152    ASSERT(r);
    151    
    152     // FIXME: Since we're not going to fix <rdar://problem/3087535> for Tiger, we should not
    153     // load multipart/x-mixed-replace content.  Pages with such content contain what is
    154     // essentially an infinite load and therefore a memory leak. Both this code and code in
    155     // WebMainRecoureClient must be removed once multipart/x-mixed-replace is fully implemented.
     153
    156154    if ([[r MIMEType] isEqualToString:@"multipart/x-mixed-replace"]) {
    157         [dataSource _removeSubresourceLoader:self];
    158         [[[dataSource _webView] mainFrame] _checkLoadComplete];
    159         [self cancelWithError:[NSError _webKitErrorWithDomain:NSURLErrorDomain
    160                                                          code:NSURLErrorUnsupportedURL
    161                                                           URL:[r URL]]];
    162         return;
    163     }   
    164    
     155        if (!supportsMultipartContent) {
     156            [dataSource _removeSubresourceLoader:self];
     157            [[[dataSource _webView] mainFrame] _checkLoadComplete];
     158            [self cancelWithError:[NSError _webKitErrorWithDomain:NSURLErrorDomain
     159                                                             code:NSURLErrorUnsupportedURL
     160                                                              URL:[r URL]]];
     161            return;
     162        }   
     163        loadingMultipartContent = YES;
     164    }
     165
    165166    // retain/release self in this delegate method since the additional processing can do
    166167    // anything including possibly releasing self; one example of this is 3266216
    167168    [self retain];
    168169    [coreLoader receivedResponse:r];
     170    // The coreLoader can cancel a load if it receives a multipart response for a non-image
     171    if (reachedTerminalState) {
     172        [self release];
     173        return;
     174    }
    169175    [super didReceiveResponse:r];
    170176    [self release];
     177   
     178    if (loadingMultipartContent && [[self resourceData] length]) {
     179        // A subresource loader does not load multipart sections progressively, deliver the previously received data to the coreLoader all at once
     180        [coreLoader addData:[self resourceData]];
     181        [self clearResourceData];
     182    }
    171183}
    172184
     
    176188    // anything including possibly releasing self; one example of this is 3266216
    177189    [self retain];
    178     [coreLoader addData:data];
     190    // A subresource loader does not load multipart sections progressively, don't deliver any data to the coreLoader yet
     191    if (!loadingMultipartContent)
     192        [coreLoader addData:data];
    179193    [super didReceiveData:data lengthReceived:lengthReceived];
    180194    [self release];
  • trunk/WebKit/WebView.subproj/WebDataSource.m

    r10273 r10489  
    3838#import <WebKit/WebDOMOperationsPrivate.h>
    3939#import <WebKit/WebFrameLoadDelegate.h>
    40 #import <WebKit/WebFramePrivate.h>
     40#import <WebKit/WebFrameInternal.h>
    4141#import <WebKit/WebFrameView.h>
    4242#import <WebKit/WebHistory.h>
     
    398398           
    399399        _private->mainResourceLoader = [[WebMainResourceLoader alloc] initWithDataSource:self];
     400        [_private->mainResourceLoader setSupportsMultipartContent:WKSupportsMultipartXMixedReplace(_private->request)];
    400401        [_private->mainResourceLoader setIdentifier: identifier];
    401402        [[self webFrame] _addExtraFieldsToRequest:_private->request alwaysFromRequest: NO];
     
    666667            [WebHTMLRepresentation class], @"application/atom+xml",
    667668            [WebHTMLRepresentation class], @"application/x-webarchive",
     669            [WebHTMLRepresentation class], @"multipart/x-mixed-replace",
    668670            [WebTextRepresentation class], @"text/",
    669671            [WebTextRepresentation class], @"application/x-javascript",
     
    721723            ? [(NSHTTPURLResponse *)_private->response allHeaderFields] : nil;
    722724
    723         [frame _closeOldDataSources];
     725        if (loadType != WebFrameLoadTypeReplace)
     726            [frame _closeOldDataSources];
    724727
    725728        LOG(Loading, "committed resource = %@", [[self request] URL]);
     
    731734
    732735        NSURL *baseURL = [[self request] _webDataRequestBaseURL];       
    733         NSURL *URL = nil;
    734        
    735         if (baseURL)
    736             URL = baseURL;
    737         else
    738             URL = [_private->response URL];
     736        NSURL *URL = baseURL ? baseURL : [_private->response URL];
    739737           
    740738        // WebCore will crash if given an empty URL here.
     
    776774{   
    777775    _private->gotFirstByte = YES;
    778     [self _commitIfReady];
    779 
    780     // parsing some of the page can result in running a script which
    781     // could possibly destroy the frame and data source. So retain
    782     // self temporarily.
    783     [self retain];
    784     [[self representation] receivedData:data withDataSource:self];
    785     [[[[self webFrame] frameView] documentView] dataSourceUpdated:self];
    786     [self release];
     776   
     777    if ([self _doesProgressiveLoadWithMIMEType:[[self response] MIMEType]])
     778        [self _commitLoadWithData:data];
    787779}
    788780
     
    10231015}
    10241016
     1017- (BOOL)_doesProgressiveLoadWithMIMEType:(NSString *)MIMEType
     1018{
     1019    return [[self webFrame] _loadType] != WebFrameLoadTypeReplace || [MIMEType isEqualToString:@"text/html"];
     1020}
     1021
     1022- (void)_commitLoadWithData:(NSData *)data
     1023{
     1024    [self _commitIfReady];
     1025    // Parsing the page may result in running a script which could destroy the datasource, so retain temporarily
     1026    [self retain];
     1027    [[self representation] receivedData:data withDataSource:self];
     1028    [[[[self webFrame] frameView] documentView] dataSourceUpdated:self];
     1029    [self release];
     1030}
     1031
     1032- (void)_revertToProvisionalState
     1033{
     1034    [self _setRepresentation:nil];
     1035    [[self webFrame] _setupForReplace];
     1036    _private->committed = NO;
     1037}
     1038
     1039- (void)_setupForReplaceByMIMEType:(NSString *)newMIMEType
     1040{
     1041    if (!_private->gotFirstByte)
     1042        return;
     1043   
     1044    WebFrame *frame = [self webFrame];
     1045    NSString *oldMIMEType = [[self response] MIMEType];
     1046   
     1047    if (![self _doesProgressiveLoadWithMIMEType:oldMIMEType]) {
     1048        [self _revertToProvisionalState];
     1049        [self _commitLoadWithData:[self data]];
     1050        [frame _transitionToLayoutAcceptable];
     1051    }
     1052   
     1053    [[self representation] finishedLoadingWithDataSource:self];
     1054    [[self _bridge] end];
     1055
     1056    [frame _setLoadType:WebFrameLoadTypeReplace];
     1057    _private->gotFirstByte = NO;
     1058
     1059    if ([self _doesProgressiveLoadWithMIMEType:newMIMEType])
     1060        [self _revertToProvisionalState];
     1061
     1062    [_private->subresourceLoaders makeObjectsPerformSelector:@selector(cancel)];
     1063    [_private->subresourceLoaders removeAllObjects];
     1064    [_private->plugInStreamLoaders makeObjectsPerformSelector:@selector(cancel)];
     1065    [_private->plugInStreamLoaders removeAllObjects];
     1066    [_private->subresources removeAllObjects];
     1067    [_private->pendingSubframeArchives removeAllObjects];
     1068}
     1069
    10251070@end
    10261071
  • trunk/WebKit/WebView.subproj/WebDataSourcePrivate.h

    r10273 r10489  
    218218- (NSString *)_title;
    219219
     220- (void)_setupForReplaceByMIMEType:(NSString *)mimeType;
     221- (BOOL)_doesProgressiveLoadWithMIMEType:(NSString *)MIMEType;
     222- (void)_commitLoadWithData:(NSData *)data;
    220223@end
  • trunk/WebKit/WebView.subproj/WebFrame.m

    r10273 r10489  
    800800            case WebFrameLoadTypeReload:
    801801            case WebFrameLoadTypeSame:
     802            case WebFrameLoadTypeReplace:
    802803            {
    803804                WebHistoryItem *currItem = [_private currentItem];
     
    11921193                    case WebFrameLoadTypeReloadAllowingStaleData:
    11931194                    case WebFrameLoadTypeSame:
     1195                    case WebFrameLoadTypeReplace:
    11941196                        // Do nothing.
    11951197                        break;
     
    23062308        case WebFrameLoadTypeReloadAllowingStaleData:
    23072309        case WebFrameLoadTypeSame:
     2310        case WebFrameLoadTypeReplace:
    23082311            // Don't restore any form state on reload or loadSame
    23092312            return nil;
     
    27502753}
    27512754
     2755- (void)_setupForReplace
     2756{
     2757    [self _setState:WebFrameStateProvisional];
     2758    WebDataSource *old = _private->provisionalDataSource;
     2759    _private->provisionalDataSource = _private->dataSource;
     2760    _private->dataSource = nil;
     2761    [old release];
     2762       
     2763    [self _detachChildren];
     2764}
     2765
    27522766@end
    27532767
  • trunk/WebKit/WebView.subproj/WebFrameInternal.h

    r9926 r10489  
    4949                                                            data:(NSData *)data
    5050                                                           error:(NSError *)error;
     51- (void)_setupForReplace;
    5152@end
    5253
  • trunk/WebKit/WebView.subproj/WebFramePrivate.h

    r10273 r10489  
    7070    WebFrameLoadTypeReloadAllowingStaleData,
    7171    WebFrameLoadTypeSame,               // user loads same URL again (but not reload button)
    72     WebFrameLoadTypeInternal
     72    WebFrameLoadTypeInternal,
     73    WebFrameLoadTypeReplace
    7374} WebFrameLoadType;
    7475
     
    151152- (WebFrame *)_descendantFrameNamed:(NSString *)name sourceFrame:(WebFrame *)source;
    152153- (void)_detachFromParent;
     154- (void)_detachChildren;
    153155- (void)_closeOldDataSources;
    154156- (void)_setDataSource:(WebDataSource *)d;
  • trunk/WebKit/WebView.subproj/WebFrameView.m

    r10215 r10489  
    255255            [WebHTMLView class], @"application/atom+xml",
    256256            [WebHTMLView class], @"application/x-webarchive",
     257            [WebHTMLView class], @"multipart/x-mixed-replace",
    257258            [WebTextView class], @"text/",
    258259            [WebTextView class], @"application/x-javascript",
  • trunk/WebKit/WebView.subproj/WebLoader.h

    r9552 r10489  
    4949    NSURLRequest *request;
    5050    BOOL reachedTerminalState;
     51    BOOL loadingMultipartContent;
     52    BOOL supportsMultipartContent;
    5153@private
    5254    WebView *webView;
     
    6971#endif
    7072}
     73- (void)setSupportsMultipartContent:(BOOL)flag;
    7174
    7275- (BOOL)loadWithRequest:(NSURLRequest *)request;
     
    9396- (void)addData:(NSData *)data;
    9497- (NSData *)resourceData;
     98- (void)clearResourceData;
    9599
    96100// Connection-less callbacks allow us to send callbacks using data attained from a WebResource instead of an NSURLConnection.
  • trunk/WebKit/WebView.subproj/WebLoader.m

    r9552 r10489  
    378378}
    379379
     380- (void)clearResourceData
     381{
     382    [resourceData setLength:0];
     383}
     384
    380385- (NSURLRequest *)willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
    381386{
     
    733738}
    734739
     740- (void)setSupportsMultipartContent:(BOOL)flag
     741{
     742    supportsMultipartContent = flag;
     743}
     744
    735745@end
  • trunk/WebKit/WebView.subproj/WebMainResourceLoader.m

    r10246 r10489  
    321321    LOG(Loading, "main content type: %@", [r MIMEType]);
    322322   
    323     // FIXME: Since we're not going to fix <rdar://problem/3087535> for Tiger, we should not
    324     // load multipart/x-mixed-replace content.  Pages with such content contain what is
    325     // essentially an infinite load and therefore a memory leak. Both this code and code in
    326     // SubresourceLoader must be removed once multipart/x-mixed-replace is fully implemented.
     323    if (loadingMultipartContent) {
     324        [[self dataSource] _setupForReplaceByMIMEType:[r MIMEType]];
     325        [self clearResourceData];
     326    }
     327   
    327328    if ([[r MIMEType] isEqualToString:@"multipart/x-mixed-replace"]) {
    328         [dataSource _removeSubresourceLoader:self];
    329         [[[dataSource _webView] mainFrame] _checkLoadComplete];
    330         [self cancelWithError:[NSError _webKitErrorWithDomain:NSURLErrorDomain
    331                                                          code:NSURLErrorUnsupportedURL
    332                                                           URL:[r URL]]];
    333         return;
     329        if (!supportsMultipartContent) {
     330            [dataSource _removeSubresourceLoader:self];
     331            [[[dataSource _webView] mainFrame] _checkLoadComplete];
     332            [self cancelWithError:[NSError _webKitErrorWithDomain:NSURLErrorDomain
     333                                                             code:NSURLErrorUnsupportedURL
     334                                                              URL:[r URL]]];
     335            return;
     336        }
     337        loadingMultipartContent = YES;
    334338    }
    335339       
Note: See TracChangeset for help on using the changeset viewer.