mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
fix to reture respnse for synchronous request.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@33949 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c71ffe21e9
commit
04c72fb364
4 changed files with 88 additions and 96 deletions
|
@ -1,3 +1,10 @@
|
|||
2011-10-07 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSURLProtocol.m:
|
||||
* Source/NSURLConnection.m:
|
||||
Ensure that a synchronous load returns the response.
|
||||
* Tests/base/NSURLConnection/basic.m: add test for above change.
|
||||
|
||||
2011-10-04 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSURL.h: Document that methods creating file URLs
|
||||
|
|
|
@ -28,108 +28,69 @@
|
|||
#import "Foundation/NSRunLoop.h"
|
||||
#import "GSURLPrivate.h"
|
||||
|
||||
@interface _NSURLConnectionDataCollector : NSObject <NSURLProtocolClient>
|
||||
@interface _NSURLConnectionDataCollector : NSObject
|
||||
{
|
||||
NSURLConnection *_connection; // Not retained
|
||||
NSMutableData *_data;
|
||||
NSError **_error;
|
||||
NSURLResponse **_response;
|
||||
NSError *_error;
|
||||
NSURLResponse *_response;
|
||||
BOOL _done;
|
||||
}
|
||||
|
||||
- (id) initWithResponsePointer: (NSURLResponse **)response
|
||||
andErrorPointer: (NSError **)error;
|
||||
- (NSData*) _data;
|
||||
- (BOOL) _done;
|
||||
- (void) _setConnection: (NSURLConnection *)c;
|
||||
- (NSData*) data;
|
||||
- (BOOL) done;
|
||||
- (NSError*) error;
|
||||
- (NSURLResponse*) response;
|
||||
- (void) setConnection: (NSURLConnection *)c;
|
||||
|
||||
@end
|
||||
|
||||
@implementation _NSURLConnectionDataCollector
|
||||
|
||||
- (id) initWithResponsePointer: (NSURLResponse **)response
|
||||
andErrorPointer: (NSError **)error
|
||||
{
|
||||
if ((self = [super init]) != nil)
|
||||
{
|
||||
_response = response;
|
||||
_error = error;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_data);
|
||||
[_data release];
|
||||
[_error release];
|
||||
[_response release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL) _done
|
||||
- (BOOL) done
|
||||
{
|
||||
return _done;
|
||||
}
|
||||
|
||||
- (NSData*) _data
|
||||
- (NSData*) data
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
- (void) _setConnection: (NSURLConnection*)c
|
||||
- (NSError*) error
|
||||
{
|
||||
return _error;
|
||||
}
|
||||
|
||||
- (NSURLResponse*) response
|
||||
{
|
||||
return _response;
|
||||
}
|
||||
|
||||
- (void) setConnection: (NSURLConnection*)c
|
||||
{
|
||||
_connection = c;
|
||||
}
|
||||
|
||||
// notification handler
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
cachedResponseIsValid: (NSCachedURLResponse*)resp
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
didCancelAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
wasRedirectedToRequest: (NSURLRequest*)request
|
||||
redirectResponse: (NSURLResponse*)redirectResponse
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
didFailWithError: (NSError*)error
|
||||
{
|
||||
*_error = error;
|
||||
_done = YES;
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection *)connection
|
||||
didFailWithError: (NSError *)error
|
||||
{
|
||||
*_error = error;
|
||||
ASSIGN(_error, error);
|
||||
_done = YES;
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
didReceiveResponse: (NSURLResponse*)response
|
||||
cacheStoragePolicy: (NSURLCacheStoragePolicy)policy
|
||||
- (void) connection: (NSURLConnection *)connection
|
||||
didReceiveResponse: (NSURLResponse*)response
|
||||
{
|
||||
*_response = response;
|
||||
}
|
||||
|
||||
- (void) URLProtocolDidFinishLoading: (NSURLProtocol*)proto
|
||||
{
|
||||
_done = YES;
|
||||
ASSIGN(_response, response);
|
||||
}
|
||||
|
||||
- (void) connectionDidFinishLoading: (NSURLConnection *)connection
|
||||
|
@ -138,23 +99,10 @@ redirectResponse: (NSURLResponse*)redirectResponse
|
|||
}
|
||||
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol*)proto
|
||||
didLoadData: (NSData*)data
|
||||
{
|
||||
if (_data == nil)
|
||||
{
|
||||
_data = [data mutableCopy];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_data appendData: data];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) connection: (NSURLConnection *)connection
|
||||
didReceiveData: (NSData *)data
|
||||
{
|
||||
if (_data == nil)
|
||||
if (nil == _data)
|
||||
{
|
||||
_data = [data mutableCopy];
|
||||
}
|
||||
|
@ -320,20 +268,26 @@ typedef struct
|
|||
{
|
||||
NSData *data = nil;
|
||||
|
||||
if (0 != response)
|
||||
{
|
||||
*response = nil;
|
||||
}
|
||||
if (0 != error)
|
||||
{
|
||||
*error = nil;
|
||||
}
|
||||
if ([self canHandleRequest: request] == YES)
|
||||
{
|
||||
_NSURLConnectionDataCollector *collector;
|
||||
NSURLConnection *conn;
|
||||
NSRunLoop *loop;
|
||||
|
||||
collector = [_NSURLConnectionDataCollector alloc];
|
||||
collector = [collector initWithResponsePointer: response
|
||||
andErrorPointer: error];
|
||||
collector = [_NSURLConnectionDataCollector new];
|
||||
conn = [self alloc];
|
||||
conn = [conn initWithRequest: request delegate: AUTORELEASE(collector)];
|
||||
[collector _setConnection: conn];
|
||||
conn = [conn initWithRequest: request delegate: [collector autorelease]];
|
||||
[collector setConnection: conn];
|
||||
loop = [NSRunLoop currentRunLoop];
|
||||
while ([collector _done] == NO)
|
||||
while ([collector done] == NO)
|
||||
{
|
||||
NSDate *limit;
|
||||
|
||||
|
@ -341,10 +295,18 @@ typedef struct
|
|||
[loop runMode: NSDefaultRunLoopMode beforeDate: limit];
|
||||
RELEASE(limit);
|
||||
}
|
||||
data = RETAIN([collector _data]);
|
||||
data = [[[collector data] retain] autorelease];
|
||||
if (0 != response)
|
||||
{
|
||||
*response = [[[collector response] retain] autorelease];
|
||||
}
|
||||
if (0 != error)
|
||||
{
|
||||
*error = [[[collector error] retain] autorelease];
|
||||
}
|
||||
[conn release];
|
||||
}
|
||||
return AUTORELEASE(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -355,7 +317,7 @@ typedef struct
|
|||
- (void) URLProtocol: (NSURLProtocol *)protocol
|
||||
cachedResponseIsValid: (NSCachedURLResponse *)cachedResponse
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol *)protocol
|
||||
|
@ -374,7 +336,7 @@ typedef struct
|
|||
didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
|
||||
{
|
||||
[this->_delegate connection: self
|
||||
didReceiveAuthenticationChallenge: challenge];
|
||||
didReceiveAuthenticationChallenge: challenge];
|
||||
}
|
||||
|
||||
- (void) URLProtocol: (NSURLProtocol *)protocol
|
||||
|
|
|
@ -679,10 +679,15 @@ static NSURLProtocol *placeholder = nil;
|
|||
wasRedirectedToRequest: request
|
||||
redirectResponse: nil];
|
||||
}
|
||||
if (_isLoading == NO)
|
||||
if (NO == _isLoading)
|
||||
{
|
||||
return;
|
||||
return; // Loading cancelled
|
||||
}
|
||||
if (nil != this->input)
|
||||
{
|
||||
return; // Following redirection
|
||||
}
|
||||
// Fall through to continue original connect.
|
||||
}
|
||||
|
||||
if (0 && this->cachedResponse)
|
||||
|
@ -843,6 +848,8 @@ static NSURLProtocol *placeholder = nil;
|
|||
GSMimeHeader *info;
|
||||
NSString *enc;
|
||||
int len = -1;
|
||||
NSString *ct;
|
||||
NSString *st;
|
||||
NSString *s;
|
||||
|
||||
info = [document headerNamed: @"http"];
|
||||
|
@ -878,11 +885,22 @@ static NSURLProtocol *placeholder = nil;
|
|||
enc = [[document headerNamed: @"transfer-encoding"] value];
|
||||
}
|
||||
|
||||
info = [document headerNamed: @"content-type"];
|
||||
ct = [document contentType];
|
||||
st = [document contentSubtype];
|
||||
if (ct && st)
|
||||
{
|
||||
ct = [ct stringByAppendingFormat: @"/%@", st];
|
||||
}
|
||||
else
|
||||
{
|
||||
ct = nil;
|
||||
}
|
||||
_response = [[NSHTTPURLResponse alloc]
|
||||
initWithURL: [this->request URL]
|
||||
MIMEType: nil
|
||||
MIMEType: ct
|
||||
expectedContentLength: len
|
||||
textEncodingName: nil];
|
||||
textEncodingName: [info parameterForKey: @"charset"]];
|
||||
[_response _setStatusCode: _statusCode text: s];
|
||||
[document deleteHeaderNamed: @"http"];
|
||||
[_response _setHeaders: [document allHeaders]];
|
||||
|
@ -1237,7 +1255,8 @@ static NSURLProtocol *placeholder = nil;
|
|||
IF_NO_GC([[self retain] autorelease];)
|
||||
|
||||
#if 0
|
||||
NSLog(@"stream: %@ handleEvent: %x for: %@", stream, event, self);
|
||||
NSLog(@"stream: %@ handleEvent: %x for: %@ (ip %p, op %p)",
|
||||
stream, event, self, this->input, this->output);
|
||||
#endif
|
||||
|
||||
if (stream == this->input)
|
||||
|
@ -1479,6 +1498,7 @@ static NSURLProtocol *placeholder = nil;
|
|||
}
|
||||
if (_shouldClose == YES)
|
||||
{
|
||||
[this->output setDelegate: nil];
|
||||
[this->output removeFromRunLoop:
|
||||
[NSRunLoop currentRunLoop]
|
||||
forMode: NSDefaultRunLoopMode];
|
||||
|
|
|
@ -30,11 +30,14 @@ int main()
|
|||
PASS(connection != nil,
|
||||
"NSURLConnection +connectionWithRequest: delegate: with nil as delegate returns a instance");
|
||||
|
||||
response = nil;
|
||||
data = [NSURLConnection sendSynchronousRequest: mutable
|
||||
returningResponse: &response
|
||||
error: &error];
|
||||
PASS(data != nil && [data length] > 0,
|
||||
"NSURLConnection synchronously load data from an http URL");
|
||||
PASS(response != nil && [response statusCode] > 0,
|
||||
"NSURLConnection synchronous load returns a response");
|
||||
|
||||
path = [[NSFileManager defaultManager] currentDirectoryPath];
|
||||
path = [path stringByAppendingPathComponent: @"basic.m"];
|
||||
|
|
Loading…
Reference in a new issue