Files
cappuccino/Foundation/CPURLConnection.j
T
Francisco Ryan Tolmasky I a97bb72800 Initial commit.
Reviewed by francisco, ross and tom.
2008-09-04 03:52:20 -07:00

182 lines
4.7 KiB
Plaintext

/*
* CPURLConnection.j
* Foundation
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import "CPObject.j"
import "CPRunLoop.j"
import "CPURLRequest.j"
import "CPURLResponse.j"
var XMLHTTPRequestUninitialized = 0,
XMLHTTPRequestLoading = 1,
XMLHTTPRequestLoaded = 2,
XMLHTTPRequestInteractive = 3,
XMLHTTPRequestComplete = 4;
var CPURLConnectionDelegate = nil;
@implementation CPURLConnection : CPObject
{
CPURLRequest _request;
id _delegate;
BOOL _isCanceled;
XMLHTTPRequest _XMLHTTPRequest;
}
+ (void)setClassDelegate:(id)delegate
{
CPURLConnectionDelegate = delegate;
}
+ (CPData)sendSynchronousRequest:(CPURLRequest)aRequest returningResponse:(CPURLResponse **)aURLResponse error:(CPError **)anError
{
try
{
var request = objj_request_xmlhttp();
request.open([aRequest HTTPMethod], [aRequest URL], NO);
var fields = [aRequest allHTTPHeaderFields],
key = nil,
keys = [fields keyEnumerator];
while (key = [keys nextObject])
request.setRequestHeader(key, [fields objectForKey:key]);
request.send([aRequest HTTPBody]);
return [CPData dataWithString:request.responseText];
}
catch (anException)
{
}
return nil;
}
+ (CPURLConnection)connectionWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate
{
return [[self alloc] initWithRequest:aRequest delegate:aDelegate];
}
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
{
self = [super init];
if (self)
{
_request = aRequest;
_delegate = aDelegate;
_isCanceled = NO;
_XMLHTTPRequest = objj_request_xmlhttp();
if (shouldStartImmediately)
[self start];
}
return self;
}
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate
{
return [self initWithRequest:aRequest delegate:aDelegate startImmediately:YES];
}
- (id)delegate
{
return _delegate;
}
- (void)start
{
_isCanceled = NO;
try
{
_XMLHTTPRequest.open([_request HTTPMethod], [_request URL], YES);
_XMLHTTPRequest.onreadystatechange = function() { [self _readyStateDidChange]; }
var fields = [_request allHTTPHeaderFields],
key = nil,
keys = [fields keyEnumerator];
while (key = [keys nextObject])
_XMLHTTPRequest.setRequestHeader(key, [fields objectForKey:key]);
_XMLHTTPRequest.send([_request HTTPBody]);
}
catch (anException)
{
[_delegate connection:self didFailWithError:anException];
}
}
- (void)cancel
{
_isCanceled = YES;
try
{
_XMLHTTPRequest.abort();
}
// We expect an exception in some browsers like FireFox.
catch (anException)
{
}
}
- (void)_readyStateDidChange
{
if (_XMLHTTPRequest.readyState == XMLHTTPRequestComplete)
{
var statusCode = _XMLHTTPRequest.status;
if ([_delegate respondsToSelector:@selector(connection:didReceiveResponse:)])
[_delegate connection:self didReceiveResponse:[[CPHTTPURLResponse alloc] _initWithStatusCode:statusCode]];
if (!_isCanceled)
{
if (statusCode == 200)
{
[_delegate connection:self didReceiveData:_XMLHTTPRequest.responseText];
[_delegate connectionDidFinishLoading:self];
}
else if (statusCode == 401 && [CPURLConnectionDelegate respondsToSelector:@selector(connectionDidReceiveAuthenticationChallenge:)])
[CPURLConnectionDelegate connectionDidReceiveAuthenticationChallenge:self];
else
[_delegate connection:self didFailWithError:_XMLHTTPRequest.status]
}
}
[[CPRunLoop currentRunLoop] performSelectors];
}
- (void)_XMLHTTPRequest
{
return _XMLHTTPRequest;
}
@end