In WebKit, how do I get the contents of a resource?

I wrote a Mac application to validate every HTTP request, so I use WebView to load the request.

The problem is that I cannot figure out how to get the contents of each of the elements of the resource.

I am trying to get the contents of a resource using the WebResourceLoadDelegate method:

 - (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource 

This does not work.

I also looked at [dataSource data] , but that just gave me the HTML for the request, and not the data for the resource element.

Any ideas on how I can get the content of the resource?

+7
objective-c webview webkit
source share
2 answers

Yes, it should work, and it seems that once it was. You can get around this by running custom NSURLProtocol.

First, you need to find out what requests you want to intercept (or all of them, it doesn't matter). I do this in my WebResourceLoadDelegate. If I take care of the request, I will replace it with one of mine, joining myself as a property. I will use this property in NSURLProtocol later.

 - (NSURLRequest*) webView:(WebView*)sender resource:(id)identifier willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse fromDataSource:(WebDataSource*)dataSource { // Am I interested in this request? if (/* figure out if you want it or not */) { NSMutableURLRequest* newRequest = [[request mutableCopy] autorelease]; [NSURLProtocol setProperty:self forKey:@"MyApp" inRequest:newRequest]; return newRequest; } else { // Not interested, let it go through normally return request; } } 

My NSURLProtocol looks like this.

 @interface MyURLProtocol : NSURLProtocol { id _delegate; NSURLConnection* _connection; NSMutableData* _data; } @end 

In my subclass of NSURLProtocol, I can use the attached property to check if the response should be intercepted.

 + (BOOL) canInitWithRequest:(NSURLRequest*)request { id delegate = [NSURLProtocol propertyForKey:@"MyApp" inRequest:request]; return (delegate != nil); } 

In initWithRequest, I move the delegate to my NSURLProtocol instance and remove the property from the request. This will prevent an endless loop later when I'm really trying to load this request.

 - (id) initWithRequest:(NSURLRequest*)theRequest cachedResponse:(NSCachedURLResponse*)cachedResponse client:(id<NSURLProtocolClient>)client { // Move the delegate from the request to this instance NSMutableURLRequest* req = (NSMutableURLRequest*)theRequest; _delegate = [NSURLProtocol propertyForKey:@"MyApp" inRequest:req]; [NSURLProtocol removePropertyForKey:@"MyApp" inRequest:req]; // Complete my setup self = [super initWithRequest:req cachedResponse:cachedResponse client:client]; if (self) { _data = [[NSMutableData data] retain]; } return self; } 

The rest of the content loads the url.

 - (void) startLoading { _connection = [[NSURLConnection connectionWithRequest:[self request] delegate:self] retain]; } - (void) stopLoading { [_connection cancel]; } - (void)connection:(NSURLConnection*)conn didReceiveResponse:(NSURLResponse*)response { [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:[[self request] cachePolicy]]; [_data setLength:0]; } - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { [[self client] URLProtocol:self didLoadData:data]; [_data appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection*)conn { [[self client] URLProtocolDidFinishLoading:self]; // Forward the response to your delegate however you like if (_delegate && [_delegate respondsToSelector:@selector(...)]) { [_delegate ... withRequest:[self request] withData:_data]; } } - (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)theRequest redirectResponse:(NSURLResponse*)redirectResponse { return theRequest; } - (void)connection:(NSURLConnection*)conn didFailWithError:(NSError*)error { [[self client] URLProtocol:self didFailWithError:error]; } 
+18
source share

use this method inside the delegate method

  for(NSString *s in [dataSource subresources]) NSLog(@"resource : %@",s); 

it will display all resources loaded in WebDataSource

0
source share

All Articles