mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
networking improvements
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@25887 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
3d12feda98
commit
14b54a6b44
10 changed files with 549 additions and 368 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2008-01-07 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source\GSSocketStream.h: simplify socket address handling
|
||||||
|
* Source\GSSocketStream.m: ditto + more work on socks
|
||||||
|
* Source\GSStream.h: minor tweaks
|
||||||
|
* Source\GSStream.m:minor tweaks
|
||||||
|
* Source\unix\NSStream.m: simplified socket address handling
|
||||||
|
* Source\GSNetwork.h: add macro to get socket address length
|
||||||
|
* Source\GSHTTPAuthentication.m: Handle arg classh check in init
|
||||||
|
* Source\NSURLRequest.m: ditto
|
||||||
|
* Source\NSURLProtocol.m: attempt to add support for authentication
|
||||||
|
|
||||||
2008-01-07 Fred Kiefer <FredKiefer@gmx.de>
|
2008-01-07 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/NSFileManager.m (-fileSystemAttributesAtPath:): Correct
|
* Source/NSFileManager.m (-fileSystemAttributesAtPath:): Correct
|
||||||
|
|
|
@ -150,7 +150,7 @@ static GSMimeParser *mimeParser = nil;
|
||||||
+ (NSURLProtectionSpace*) protectionSpaceForAuthentication: (NSString*)auth
|
+ (NSURLProtectionSpace*) protectionSpaceForAuthentication: (NSString*)auth
|
||||||
requestURL: (NSURL*)URL;
|
requestURL: (NSURL*)URL;
|
||||||
{
|
{
|
||||||
if (auth != nil)
|
if ([auth isKindOfClass: [NSString class]] == YES)
|
||||||
{
|
{
|
||||||
NSString *method = nil;
|
NSString *method = nil;
|
||||||
NSURLProtectionSpace *space;
|
NSURLProtectionSpace *space;
|
||||||
|
|
|
@ -50,6 +50,11 @@
|
||||||
#define BADSOCKET(X) ((X) == INVALID_SOCKET)
|
#define BADSOCKET(X) ((X) == INVALID_SOCKET)
|
||||||
#define GSNETERROR WSAGetLastError()
|
#define GSNETERROR WSAGetLastError()
|
||||||
#define GSWOULDBLOCK (GSNETERROR == WSAEWOULDBLOCK || GSNETERROR == WSAEINPROGRESS)
|
#define GSWOULDBLOCK (GSNETERROR == WSAEWOULDBLOCK || GSNETERROR == WSAEINPROGRESS)
|
||||||
|
#ifdef AF_INET6
|
||||||
|
#define SOCKLEN(X) ((X->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
|
||||||
|
#else
|
||||||
|
#define SOCKLEN(X) sizeof(struct sockaddr_in)
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -66,6 +71,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SOCKET int /* Socket type */
|
#define SOCKET int /* Socket type */
|
||||||
|
#define SOCKLEN(X) (X->sa_len)
|
||||||
#define BADSOCKET(X) ((X) < 0)
|
#define BADSOCKET(X) ((X) < 0)
|
||||||
#define GSNETERROR errno
|
#define GSNETERROR errno
|
||||||
#define GSWOULDBLOCK (errno == EINPROGRESS)
|
#define GSWOULDBLOCK (errno == EINPROGRESS)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
BOOL _closing; /* Must close on next failure. */\
|
BOOL _closing; /* Must close on next failure. */\
|
||||||
SOCKET _sock; /* Needed for ms-windows. */\
|
SOCKET _sock; /* Needed for ms-windows. */\
|
||||||
id _handler; /* TLS/SOCKS handler. */\
|
id _handler; /* TLS/SOCKS handler. */\
|
||||||
|
struct sockaddr *_address; /* Socket address info. */\
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The semi-abstract GSSocketStream class is not intended to be subclassed
|
/* The semi-abstract GSSocketStream class is not intended to be subclassed
|
||||||
|
@ -48,7 +49,12 @@ SOCKIVARS
|
||||||
/**
|
/**
|
||||||
* get the sockaddr
|
* get the sockaddr
|
||||||
*/
|
*/
|
||||||
- (struct sockaddr*) _peerAddr;
|
- (struct sockaddr*) _address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the sockaddr
|
||||||
|
*/
|
||||||
|
- (void) _setAddress: (struct sockaddr*)address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setter for closing flag ... the remote end has stopped either sending
|
* setter for closing flag ... the remote end has stopped either sending
|
||||||
|
@ -82,11 +88,6 @@ SOCKIVARS
|
||||||
*/
|
*/
|
||||||
- (SOCKET) _sock;
|
- (SOCKET) _sock;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the length of the socket addr
|
|
||||||
*/
|
|
||||||
- (socklen_t) _sockLen;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +99,8 @@ SOCKIVARS
|
||||||
SOCKIVARS
|
SOCKIVARS
|
||||||
@end
|
@end
|
||||||
@interface GSSocketInputStream (AddedBehaviors)
|
@interface GSSocketInputStream (AddedBehaviors)
|
||||||
- (struct sockaddr*) _peerAddr;
|
- (struct sockaddr*) _address;
|
||||||
|
- (void) _setAddress: (struct sockaddr*)address;
|
||||||
- (int) _read: (uint8_t *)buffer maxLength: (unsigned int)len;
|
- (int) _read: (uint8_t *)buffer maxLength: (unsigned int)len;
|
||||||
- (void) _setClosing: (BOOL)passive;
|
- (void) _setClosing: (BOOL)passive;
|
||||||
- (void) _setHandler: (id)h;
|
- (void) _setHandler: (id)h;
|
||||||
|
@ -106,14 +108,9 @@ SOCKIVARS
|
||||||
- (void) _setSibling: (GSSocketStream*)sibling;
|
- (void) _setSibling: (GSSocketStream*)sibling;
|
||||||
- (void) _setSock: (SOCKET)sock;
|
- (void) _setSock: (SOCKET)sock;
|
||||||
- (SOCKET) _sock;
|
- (SOCKET) _sock;
|
||||||
- (socklen_t) _sockLen;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSInetInputStream : GSSocketInputStream
|
@interface GSInetInputStream : GSSocketInputStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
struct sockaddr_in _peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the designated initializer
|
* the designated initializer
|
||||||
|
@ -124,12 +121,6 @@ SOCKIVARS
|
||||||
|
|
||||||
|
|
||||||
@interface GSInet6InputStream : GSSocketInputStream
|
@interface GSInet6InputStream : GSSocketInputStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
#if defined(AF_INET6)
|
|
||||||
struct sockaddr_in6 _peerAddr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the designated initializer
|
* the designated initializer
|
||||||
|
@ -147,22 +138,18 @@ SOCKIVARS
|
||||||
SOCKIVARS
|
SOCKIVARS
|
||||||
@end
|
@end
|
||||||
@interface GSSocketOutputStream (AddedBehaviors)
|
@interface GSSocketOutputStream (AddedBehaviors)
|
||||||
- (struct sockaddr*) _peerAddr;
|
- (struct sockaddr*) _address;
|
||||||
|
- (void) _setAddress: (struct sockaddr*)address;
|
||||||
- (void) _setClosing: (BOOL)passive;
|
- (void) _setClosing: (BOOL)passive;
|
||||||
- (void) _setHandler: (id)h;
|
- (void) _setHandler: (id)h;
|
||||||
- (void) _setPassive: (BOOL)passive;
|
- (void) _setPassive: (BOOL)passive;
|
||||||
- (void) _setSibling: (GSSocketStream*)sibling;
|
- (void) _setSibling: (GSSocketStream*)sibling;
|
||||||
- (void) _setSock: (SOCKET)sock;
|
- (void) _setSock: (SOCKET)sock;
|
||||||
- (SOCKET) _sock;
|
- (SOCKET) _sock;
|
||||||
- (socklen_t) _sockLen;
|
|
||||||
- (int) _write: (const uint8_t *)buffer maxLength: (unsigned int)len;
|
- (int) _write: (const uint8_t *)buffer maxLength: (unsigned int)len;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSInetOutputStream : GSSocketOutputStream
|
@interface GSInetOutputStream : GSSocketOutputStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
struct sockaddr_in _peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the designated initializer
|
* the designated initializer
|
||||||
|
@ -172,12 +159,6 @@ SOCKIVARS
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSInet6OutputStream : GSSocketOutputStream
|
@interface GSInet6OutputStream : GSSocketOutputStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
#if defined(AF_INET6)
|
|
||||||
struct sockaddr_in6 _peerAddr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the designated initializer
|
* the designated initializer
|
||||||
|
@ -208,37 +189,22 @@ SOCKIVARS
|
||||||
*/
|
*/
|
||||||
- (Class) _outputStreamClass;
|
- (Class) _outputStreamClass;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the sockaddr for this server
|
|
||||||
*/
|
|
||||||
- (struct sockaddr*) _serverAddr;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@interface GSSocketServerStream (AddedBehaviors)
|
@interface GSSocketServerStream (AddedBehaviors)
|
||||||
- (struct sockaddr*) _peerAddr;
|
- (struct sockaddr*) _address;
|
||||||
|
- (void) _setAddress: (struct sockaddr*)address;
|
||||||
- (void) _setClosing: (BOOL)passive;
|
- (void) _setClosing: (BOOL)passive;
|
||||||
- (void) _setHandler: (id)h;
|
- (void) _setHandler: (id)h;
|
||||||
- (void) _setPassive: (BOOL)passive;
|
- (void) _setPassive: (BOOL)passive;
|
||||||
- (void) _setSibling: (GSSocketStream*)sibling;
|
- (void) _setSibling: (GSSocketStream*)sibling;
|
||||||
- (void) _setSock: (SOCKET)sock;
|
- (void) _setSock: (SOCKET)sock;
|
||||||
- (SOCKET) _sock;
|
- (SOCKET) _sock;
|
||||||
- (socklen_t) _sockLen;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSInetServerStream : GSSocketServerStream
|
@interface GSInetServerStream : GSSocketServerStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
struct sockaddr_in _serverAddr;
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSInet6ServerStream : GSSocketServerStream
|
@interface GSInet6ServerStream : GSSocketServerStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
#if defined(AF_INET6)
|
|
||||||
struct sockaddr_in6 _serverAddr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,16 +56,16 @@
|
||||||
*/
|
*/
|
||||||
@interface GSStreamHandler : NSObject
|
@interface GSStreamHandler : NSObject
|
||||||
{
|
{
|
||||||
GSSocketInputStream *input; // Not retained
|
GSSocketInputStream *istream; // Not retained
|
||||||
GSSocketOutputStream *output; // Not retained
|
GSSocketOutputStream *ostream; // Not retained
|
||||||
BOOL initialised;
|
BOOL initialised;
|
||||||
BOOL handshake;
|
BOOL handshake;
|
||||||
BOOL active;
|
BOOL active;
|
||||||
}
|
}
|
||||||
- (id) initWithInput: (GSSocketInputStream*)i
|
- (id) initWithInput: (GSSocketInputStream*)i
|
||||||
output: (GSSocketOutputStream*)o;
|
output: (GSSocketOutputStream*)o;
|
||||||
- (GSSocketInputStream*) input;
|
- (GSSocketInputStream*) istream;
|
||||||
- (GSSocketOutputStream*) output;
|
- (GSSocketOutputStream*) ostream;
|
||||||
|
|
||||||
- (void) bye; /* Close down the handled session. */
|
- (void) bye; /* Close down the handled session. */
|
||||||
- (BOOL) handshake; /* A handshake/hello is in progress. */
|
- (BOOL) handshake; /* A handshake/hello is in progress. */
|
||||||
|
@ -96,19 +96,19 @@
|
||||||
- (id) initWithInput: (GSSocketInputStream*)i
|
- (id) initWithInput: (GSSocketInputStream*)i
|
||||||
output: (GSSocketOutputStream*)o
|
output: (GSSocketOutputStream*)o
|
||||||
{
|
{
|
||||||
input = i;
|
istream = i;
|
||||||
output = o;
|
ostream = o;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GSSocketInputStream*) input
|
- (GSSocketInputStream*) istream
|
||||||
{
|
{
|
||||||
return input;
|
return istream;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GSSocketOutputStream*) output
|
- (GSSocketOutputStream*) ostream
|
||||||
{
|
{
|
||||||
return output;
|
return ostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
|
- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
|
@ -184,14 +184,14 @@ GSTLSPull(gnutls_transport_ptr_t handle, void *buffer, size_t len)
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
GSTLS *tls = (GSTLS*)handle;
|
GSTLS *tls = (GSTLS*)handle;
|
||||||
|
|
||||||
result = [[tls input] _read: buffer maxLength: len];
|
result = [[tls istream] _read: buffer maxLength: len];
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
|
|
||||||
if ([[tls input] streamStatus] == NSStreamStatusError)
|
if ([[tls istream] streamStatus] == NSStreamStatusError)
|
||||||
{
|
{
|
||||||
e = [[[(GSTLS*)handle input] streamError] code];
|
e = [[[(GSTLS*)handle istream] streamError] code];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -211,14 +211,14 @@ GSTLSPush(gnutls_transport_ptr_t handle, const void *buffer, size_t len)
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
GSTLS *tls = (GSTLS*)handle;
|
GSTLS *tls = (GSTLS*)handle;
|
||||||
|
|
||||||
result = [[tls output] _write: buffer maxLength: len];
|
result = [[tls ostream] _write: buffer maxLength: len];
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
{
|
||||||
int e;
|
int e;
|
||||||
|
|
||||||
if ([[tls output] streamStatus] == NSStreamStatusError)
|
if ([[tls ostream] streamStatus] == NSStreamStatusError)
|
||||||
{
|
{
|
||||||
e = [[[tls output] streamError] code];
|
e = [[[tls ostream] streamError] code];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -418,14 +418,14 @@ static gnutls_anon_client_credentials_t anoncred;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GSSocketInputStream*) input
|
- (GSSocketInputStream*) istream
|
||||||
{
|
{
|
||||||
return input;
|
return istream;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GSSocketOutputStream*) output
|
- (GSSocketOutputStream*) ostream
|
||||||
{
|
{
|
||||||
return output;
|
return ostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
|
- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
|
@ -442,8 +442,8 @@ static gnutls_anon_client_credentials_t anoncred;
|
||||||
[self hello]; /* try to complete the handshake */
|
[self hello]; /* try to complete the handshake */
|
||||||
if (handshake == NO)
|
if (handshake == NO)
|
||||||
{
|
{
|
||||||
[input _sendEvent: NSStreamEventOpenCompleted];
|
[istream _sendEvent: NSStreamEventOpenCompleted];
|
||||||
[output _sendEvent: NSStreamEventOpenCompleted];
|
[ostream _sendEvent: NSStreamEventOpenCompleted];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,44 +484,126 @@ static NSString * const GSSOCKSAckAuth = @"GSSOCKSAckAuth";
|
||||||
static NSString * const GSSOCKSSendConn = @"GSSOCKSSendConn";
|
static NSString * const GSSOCKSSendConn = @"GSSOCKSSendConn";
|
||||||
static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
|
|
||||||
@interface GSSOCKS : NSObject
|
@interface GSSOCKS : GSStreamHandler
|
||||||
{
|
{
|
||||||
NSString *state;
|
NSString *state; /* Not retained */
|
||||||
NSString *addr;
|
NSString *address;
|
||||||
int port;
|
NSString *port;
|
||||||
int roffset;
|
int roffset;
|
||||||
int woffset;
|
int woffset;
|
||||||
int rwant;
|
int rwant;
|
||||||
unsigned char rbuffer[128];
|
unsigned char rbuffer[128];
|
||||||
NSInputStream *istream;
|
|
||||||
NSOutputStream *ostream;
|
|
||||||
}
|
}
|
||||||
- (NSString*) addr;
|
- (void) stream: (NSStream*)stream handleEvent: (NSStreamEvent)event;
|
||||||
- (id) initToAddr: (NSString*)_addr port: (int)_port;
|
|
||||||
- (int) port;
|
|
||||||
- (NSString*) stream: (NSStream*)stream SOCKSEvent: (NSStreamEvent)event;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GSSOCKS
|
@implementation GSSOCKS
|
||||||
- (NSString*) addr
|
- (void) bye
|
||||||
{
|
{
|
||||||
return addr;
|
if (handshake == YES)
|
||||||
|
{
|
||||||
|
NSString *tls;
|
||||||
|
GSTLS *t = nil;
|
||||||
|
|
||||||
|
handshake = NO;
|
||||||
|
tls = [ostream propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||||
|
if (tls == nil && istream != nil)
|
||||||
|
{
|
||||||
|
tls = [istream propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||||
|
if (tls != nil)
|
||||||
|
{
|
||||||
|
[ostream setProperty: tls forKey: NSStreamSocketSecurityLevelKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tls != nil)
|
||||||
|
{
|
||||||
|
t = [[GSTLS alloc] initWithInput: istream output: ostream];
|
||||||
|
}
|
||||||
|
if (t == nil)
|
||||||
|
{
|
||||||
|
GSSocketInputStream *is = RETAIN(istream);
|
||||||
|
GSSocketOutputStream *os = RETAIN(ostream);
|
||||||
|
|
||||||
|
/* No TLS required ... simply remove SOCKS handler from streams
|
||||||
|
* and let the streams know that the open has completed.
|
||||||
|
* NB. Removing SOCKS handle from streams may cause it to be
|
||||||
|
* deallocated, so we work with local variables to hold the
|
||||||
|
* streams long enough to send events to them.
|
||||||
|
*/
|
||||||
|
[is _setHandler: nil];
|
||||||
|
[os _setHandler: nil];
|
||||||
|
[is _sendEvent: NSStreamEventOpenCompleted];
|
||||||
|
[os _sendEvent: NSStreamEventOpenCompleted];
|
||||||
|
RELEASE(is);
|
||||||
|
RELEASE(os);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Replace SOCKS handler wth TLS handler and start TLS handshake.
|
||||||
|
*/
|
||||||
|
[istream _setHandler: t];
|
||||||
|
[ostream _setHandler: t];
|
||||||
|
[t hello];
|
||||||
|
RELEASE(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)_addr port: (int)_port
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
ASSIGNCOPY(addr, _addr);
|
RELEASE(address);
|
||||||
port = _port;
|
RELEASE(port);
|
||||||
state = GSSOCKSOfferAuth;
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) hello
|
||||||
|
{
|
||||||
|
if (handshake == NO)
|
||||||
|
{
|
||||||
|
handshake = YES;
|
||||||
|
/* Now send self an event to say we can write, to kick off the
|
||||||
|
* handshake with the SOCKS server.
|
||||||
|
*/
|
||||||
|
[self stream: ostream handleEvent: NSStreamEventHasSpaceAvailable];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithInput: (GSSocketInputStream*)i
|
||||||
|
output: (GSSocketOutputStream*)o
|
||||||
|
{
|
||||||
|
if ((self = [super initWithInput: i output: o]) != nil)
|
||||||
|
{
|
||||||
|
if ([istream isKindOfClass: [GSInetInputStream class]] == NO)
|
||||||
|
{
|
||||||
|
NSLog(@"Attempt to use SOCKS with non-INET stream ignored");
|
||||||
|
DESTROY(self);
|
||||||
|
}
|
||||||
|
#if defined(AF_INET6)
|
||||||
|
else if ([istream isKindOfClass: [GSInet6InputStream class]] == YES)
|
||||||
|
{
|
||||||
|
GSOnceMLog(@"INET6 not supported with SOCKS yet...");
|
||||||
|
DESTROY(self);
|
||||||
|
}
|
||||||
|
#endif /* AF_INET6 */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct sockaddr_in *addr = (struct sockaddr_in*)[istream _address];
|
||||||
|
|
||||||
|
address = [[NSString alloc] initWithUTF8String:
|
||||||
|
(char*)inet_ntoa(addr->sin_addr)];
|
||||||
|
port = [[NSString alloc] initWithFormat: @"%d",
|
||||||
|
(int)GSSwapBigI16ToHost(addr->sin_port)];
|
||||||
|
}
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) port
|
- (int) read: (uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
{
|
{
|
||||||
return port;
|
return [istream _read: buffer maxLength: len];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) stream: (NSStream*)stream SOCKSEvent: (NSStreamEvent)event
|
- (void) stream: (NSStream*)stream handleEvent: (NSStreamEvent)event
|
||||||
{
|
{
|
||||||
NSString *error = nil;
|
NSString *error = nil;
|
||||||
NSDictionary *conf;
|
NSDictionary *conf;
|
||||||
|
@ -532,7 +614,8 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
|| [stream streamStatus] == NSStreamStatusError
|
|| [stream streamStatus] == NSStreamStatusError
|
||||||
|| [stream streamStatus] == NSStreamStatusClosed)
|
|| [stream streamStatus] == NSStreamStatusClosed)
|
||||||
{
|
{
|
||||||
return @"SOCKS errur during negotiation";
|
[self bye];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
conf = [stream propertyForKey: NSStreamSOCKSProxyConfigurationKey];
|
conf = [stream propertyForKey: NSStreamSOCKSProxyConfigurationKey];
|
||||||
|
@ -574,12 +657,8 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
want = 3;
|
want = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = [ostream write: buf + woffset maxLength: 4 - woffset];
|
result = [ostream _write: buf + woffset maxLength: 4 - woffset];
|
||||||
if (result == 0)
|
if (result > 0)
|
||||||
{
|
|
||||||
error = @"end-of-file during SOCKS negotiation";
|
|
||||||
}
|
|
||||||
else if (result > 0)
|
|
||||||
{
|
{
|
||||||
woffset += result;
|
woffset += result;
|
||||||
if (woffset == want)
|
if (woffset == want)
|
||||||
|
@ -594,7 +673,7 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = [istream read: rbuffer + roffset maxLength: 2 - roffset];
|
result = [istream _read: rbuffer + roffset maxLength: 2 - roffset];
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
error = @"SOCKS end-of-file during negotiation";
|
error = @"SOCKS end-of-file during negotiation";
|
||||||
|
@ -652,7 +731,8 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
memcpy(buf + 2, [u bytes], ul);
|
memcpy(buf + 2, [u bytes], ul);
|
||||||
buf[ul + 2] = pl;
|
buf[ul + 2] = pl;
|
||||||
memcpy(buf + ul + 3, [p bytes], pl);
|
memcpy(buf + ul + 3, [p bytes], pl);
|
||||||
result = [ostream write: buf + woffset maxLength: want - woffset];
|
result = [ostream _write: buf + woffset
|
||||||
|
maxLength: want - woffset];
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
error = @"SOCKS end-of-file during negotiation";
|
error = @"SOCKS end-of-file during negotiation";
|
||||||
|
@ -672,7 +752,7 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = [istream read: rbuffer + roffset maxLength: 2 - roffset];
|
result = [istream _read: rbuffer + roffset maxLength: 2 - roffset];
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
error = @"SOCKS end-of-file during negotiation";
|
error = @"SOCKS end-of-file during negotiation";
|
||||||
|
@ -719,7 +799,7 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
buf[1] = 1; // Connect command
|
buf[1] = 1; // Connect command
|
||||||
buf[2] = 0; // Reserved
|
buf[2] = 0; // Reserved
|
||||||
buf[3] = 1; // Address type (IPV4)
|
buf[3] = 1; // Address type (IPV4)
|
||||||
ptr = [addr lossyCString];
|
ptr = [address UTF8String];
|
||||||
buf[4] = atoi(ptr);
|
buf[4] = atoi(ptr);
|
||||||
while (isdigit(*ptr))
|
while (isdigit(*ptr))
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -733,10 +813,11 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
ptr++;
|
ptr++;
|
||||||
ptr++;
|
ptr++;
|
||||||
buf[7] = atoi(ptr);
|
buf[7] = atoi(ptr);
|
||||||
buf[8] = ((port & 0xff00) >> 8);
|
result = [port intValue];
|
||||||
buf[9] = (port & 0xff);
|
buf[8] = ((result & 0xff00) >> 8);
|
||||||
|
buf[9] = (result & 0xff);
|
||||||
|
|
||||||
result = [ostream write: buf + woffset maxLength: want - woffset];
|
result = [ostream _write: buf + woffset maxLength: want - woffset];
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
error = @"SOCKS end-of-file during negotiation";
|
error = @"SOCKS end-of-file during negotiation";
|
||||||
|
@ -756,7 +837,7 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = [istream read: rbuffer + roffset maxLength: rwant - roffset];
|
result = [istream _read: rbuffer + roffset maxLength: rwant - roffset];
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
error = @"SOCKS end-of-file during negotiation";
|
error = @"SOCKS end-of-file during negotiation";
|
||||||
|
@ -861,8 +942,22 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
a = [NSString stringWithUTF8String:
|
a = [NSString stringWithUTF8String:
|
||||||
(const char*)buf];
|
(const char*)buf];
|
||||||
}
|
}
|
||||||
ASSIGN(addr, a);
|
|
||||||
port = rbuffer[rwant-1] * 256 * rbuffer[rwant-2];
|
[istream setProperty: a
|
||||||
|
forKey: GSStreamRemoteAddressKey];
|
||||||
|
[ostream setProperty: a
|
||||||
|
forKey: GSStreamRemoteAddressKey];
|
||||||
|
a = [NSString stringWithFormat: @"%d",
|
||||||
|
rbuffer[rwant-1] * 256 * rbuffer[rwant-2]];
|
||||||
|
[istream setProperty: a
|
||||||
|
forKey: GSStreamRemotePortKey];
|
||||||
|
[ostream setProperty: a
|
||||||
|
forKey: GSStreamRemotePortKey];
|
||||||
|
/* Return immediately after calling -bye as it
|
||||||
|
* will cause this instance to be deallocted.
|
||||||
|
*/
|
||||||
|
[self bye];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -870,7 +965,29 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
if ([error length] > 0)
|
||||||
|
{
|
||||||
|
NSError *theError;
|
||||||
|
|
||||||
|
theError = [NSError errorWithDomain: NSCocoaErrorDomain
|
||||||
|
code: 0
|
||||||
|
userInfo: [NSDictionary dictionaryWithObject: error
|
||||||
|
forKey: NSLocalizedDescriptionKey]];
|
||||||
|
if ([istream streamStatus] != NSStreamStatusError)
|
||||||
|
{
|
||||||
|
[istream _recordError: theError];
|
||||||
|
}
|
||||||
|
if ([ostream streamStatus] != NSStreamStatusError)
|
||||||
|
{
|
||||||
|
[ostream _recordError: theError];
|
||||||
|
}
|
||||||
|
[self bye];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) write: (const uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
|
{
|
||||||
|
return [ostream _write: buffer maxLength: len];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -930,6 +1047,10 @@ setNonBlocking(SOCKET fd)
|
||||||
[_sibling _setSibling: nil];
|
[_sibling _setSibling: nil];
|
||||||
_sibling = nil;
|
_sibling = nil;
|
||||||
DESTROY(_handler);
|
DESTROY(_handler);
|
||||||
|
if (_address != 0)
|
||||||
|
{
|
||||||
|
NSZoneFree(NSDefaultMallocZone(), _address);
|
||||||
|
}
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,10 +1074,9 @@ setNonBlocking(SOCKET fd)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
- (struct sockaddr*) _address
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
return (struct sockaddr*)_address;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) _read: (uint8_t *)buffer maxLength: (unsigned int)len
|
- (int) _read: (uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
|
@ -988,6 +1108,21 @@ setNonBlocking(SOCKET fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) _setAddress: (struct sockaddr*)address
|
||||||
|
{
|
||||||
|
if (_address != 0 && SOCKLEN(_address) != SOCKLEN(address))
|
||||||
|
{
|
||||||
|
NSZoneFree(NSDefaultMallocZone(), _address);
|
||||||
|
_address = 0;
|
||||||
|
}
|
||||||
|
if (_address == 0)
|
||||||
|
{
|
||||||
|
_address = (struct sockaddr*)
|
||||||
|
NSZoneMalloc(NSDefaultMallocZone(), SOCKLEN(address));
|
||||||
|
}
|
||||||
|
memcpy(_address, address, SOCKLEN(address));
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _setLoopID: (void *)ref
|
- (void) _setLoopID: (void *)ref
|
||||||
{
|
{
|
||||||
#if !defined(__MINGW32__)
|
#if !defined(__MINGW32__)
|
||||||
|
@ -1038,12 +1173,6 @@ setNonBlocking(SOCKET fd)
|
||||||
return _sock;
|
return _sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
[self subclassResponsibility: _cmd];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int) _write: (const uint8_t *)buffer maxLength: (unsigned int)len
|
- (int) _write: (const uint8_t *)buffer maxLength: (unsigned int)len
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
|
@ -1080,7 +1209,7 @@ setNonBlocking(SOCKET fd)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = connect([self _sock], [self _peerAddr], [self _sockLen]);
|
result = connect([self _sock], _address, SOCKLEN(_address));
|
||||||
if (socketError(result))
|
if (socketError(result))
|
||||||
{
|
{
|
||||||
if (!socketWouldBlock())
|
if (!socketWouldBlock())
|
||||||
|
@ -1523,7 +1652,7 @@ setNonBlocking(SOCKET fd)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = connect([self _sock], [self _peerAddr], [self _sockLen]);
|
result = connect([self _sock], _address, SOCKLEN(_address));
|
||||||
if (socketError(result))
|
if (socketError(result))
|
||||||
{
|
{
|
||||||
if (!socketWouldBlock())
|
if (!socketWouldBlock())
|
||||||
|
@ -1859,12 +1988,6 @@ setNonBlocking(SOCKET fd)
|
||||||
return Nil;
|
return Nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (struct sockaddr*) _serverAddr
|
|
||||||
{
|
|
||||||
[self subclassResponsibility: _cmd];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SOCKET_BACKLOG 256
|
#define SOCKET_BACKLOG 256
|
||||||
|
|
||||||
- (void) open
|
- (void) open
|
||||||
|
@ -1885,7 +2008,7 @@ setNonBlocking(SOCKET fd)
|
||||||
(char *)&status, sizeof(status));
|
(char *)&status, sizeof(status));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bindReturn = bind([self _sock], [self _serverAddr], [self _sockLen]);
|
bindReturn = bind([self _sock], _address, SOCKLEN(_address));
|
||||||
if (socketError(bindReturn))
|
if (socketError(bindReturn))
|
||||||
{
|
{
|
||||||
[self _recordError];
|
[self _recordError];
|
||||||
|
@ -1934,9 +2057,12 @@ setNonBlocking(SOCKET fd)
|
||||||
{
|
{
|
||||||
GSSocketStream *ins = AUTORELEASE([[self _inputStreamClass] new]);
|
GSSocketStream *ins = AUTORELEASE([[self _inputStreamClass] new]);
|
||||||
GSSocketStream *outs = AUTORELEASE([[self _outputStreamClass] new]);
|
GSSocketStream *outs = AUTORELEASE([[self _outputStreamClass] new]);
|
||||||
socklen_t len = [ins _sockLen];
|
uint8_t buf[BUFSIZ];
|
||||||
int acceptReturn = accept([self _sock], [ins _peerAddr], &len);
|
struct sockaddr *addr = (struct sockaddr*)buf;
|
||||||
|
socklen_t len = sizeof(buf);
|
||||||
|
int acceptReturn;
|
||||||
|
|
||||||
|
acceptReturn = accept([self _sock], addr, &len);
|
||||||
_events &= ~NSStreamEventHasBytesAvailable;
|
_events &= ~NSStreamEventHasBytesAvailable;
|
||||||
if (socketError(acceptReturn))
|
if (socketError(acceptReturn))
|
||||||
{ // test for real error
|
{ // test for real error
|
||||||
|
@ -1953,7 +2079,8 @@ setNonBlocking(SOCKET fd)
|
||||||
[ins _setPassive: YES];
|
[ins _setPassive: YES];
|
||||||
[outs _setPassive: YES];
|
[outs _setPassive: YES];
|
||||||
// copy the addr to outs
|
// copy the addr to outs
|
||||||
memcpy([outs _peerAddr], [ins _peerAddr], len);
|
[ins _setAddress: addr];
|
||||||
|
[outs _setAddress: addr];
|
||||||
[ins _setSock: acceptReturn];
|
[ins _setSock: acceptReturn];
|
||||||
[outs _setSock: acceptReturn];
|
[outs _setSock: acceptReturn];
|
||||||
}
|
}
|
||||||
|
@ -2097,16 +2224,6 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
@implementation GSInetInputStream
|
@implementation GSInetInputStream
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||||
{
|
{
|
||||||
int ptonReturn;
|
int ptonReturn;
|
||||||
|
@ -2114,24 +2231,30 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
_peerAddr.sin_family = AF_INET;
|
struct sockaddr_in peer;
|
||||||
_peerAddr.sin_port = GSSwapHostI16ToBig(port);
|
|
||||||
ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
|
peer.sin_family = AF_INET;
|
||||||
|
peer.sin_port = GSSwapHostI16ToBig(port);
|
||||||
|
ptonReturn = inet_pton(AF_INET, addr_c, &peer.sin_addr);
|
||||||
if (ptonReturn == 0) // error
|
if (ptonReturn == 0) // error
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[self _setAddress: (struct sockaddr*)&peer];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) propertyForKey: (NSString *)key
|
- (id) propertyForKey: (NSString *)key
|
||||||
{
|
{
|
||||||
id result = propertyForInet4Stream((intptr_t)_loopID, key);
|
id result = [super propertyForKey: key];
|
||||||
|
|
||||||
if (result == nil)
|
if (result == nil)
|
||||||
{
|
{
|
||||||
result = [super propertyForKey: key];
|
result = propertyForInet4Stream((intptr_t)_loopID, key);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2140,15 +2263,6 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
@implementation GSInet6InputStream
|
@implementation GSInet6InputStream
|
||||||
#if defined(AF_INET6)
|
#if defined(AF_INET6)
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_in6);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||||
{
|
{
|
||||||
|
@ -2157,24 +2271,30 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
_peerAddr.sin6_family = AF_INET6;
|
struct sockaddr_in6 peer;
|
||||||
_peerAddr.sin6_port = GSSwapHostI16ToBig(port);
|
|
||||||
ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
|
peer.sin6_family = AF_INET6;
|
||||||
|
peer.sin6_port = GSSwapHostI16ToBig(port);
|
||||||
|
ptonReturn = inet_pton(AF_INET6, addr_c, &peer.sin6_addr);
|
||||||
if (ptonReturn == 0) // error
|
if (ptonReturn == 0) // error
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[self _setAddress: (struct sockaddr*)&peer];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) propertyForKey: (NSString *)key
|
- (id) propertyForKey: (NSString *)key
|
||||||
{
|
{
|
||||||
id result = propertyForInet6Stream((intptr_t)_loopID, key);
|
id result = [super propertyForKey: key];
|
||||||
|
|
||||||
if (result == nil)
|
if (result == nil)
|
||||||
{
|
{
|
||||||
result = [super propertyForKey: key];
|
result = propertyForInet6Stream((intptr_t)_loopID, key);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2190,16 +2310,6 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
@implementation GSInetOutputStream
|
@implementation GSInetOutputStream
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||||
{
|
{
|
||||||
int ptonReturn;
|
int ptonReturn;
|
||||||
|
@ -2207,24 +2317,30 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
_peerAddr.sin_family = AF_INET;
|
struct sockaddr_in peer;
|
||||||
_peerAddr.sin_port = GSSwapHostI16ToBig(port);
|
|
||||||
ptonReturn = inet_pton(AF_INET, addr_c, &(_peerAddr.sin_addr));
|
peer.sin_family = AF_INET;
|
||||||
|
peer.sin_port = GSSwapHostI16ToBig(port);
|
||||||
|
ptonReturn = inet_pton(AF_INET, addr_c, &peer.sin_addr);
|
||||||
if (ptonReturn == 0) // error
|
if (ptonReturn == 0) // error
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[self _setAddress: (struct sockaddr*)&peer];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) propertyForKey: (NSString *)key
|
- (id) propertyForKey: (NSString *)key
|
||||||
{
|
{
|
||||||
id result = propertyForInet4Stream((intptr_t)_loopID, key);
|
id result = [super propertyForKey: key];
|
||||||
|
|
||||||
if (result == nil)
|
if (result == nil)
|
||||||
{
|
{
|
||||||
result = [super propertyForKey: key];
|
result = propertyForInet4Stream((intptr_t)_loopID, key);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2233,15 +2349,6 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
@implementation GSInet6OutputStream
|
@implementation GSInet6OutputStream
|
||||||
#if defined(AF_INET6)
|
#if defined(AF_INET6)
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_in6);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||||
{
|
{
|
||||||
|
@ -2250,24 +2357,30 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
|
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
_peerAddr.sin6_family = AF_INET6;
|
struct sockaddr_in6 peer;
|
||||||
_peerAddr.sin6_port = GSSwapHostI16ToBig(port);
|
|
||||||
ptonReturn = inet_pton(AF_INET6, addr_c, &(_peerAddr.sin6_addr));
|
peer.sin6_family = AF_INET6;
|
||||||
|
peer.sin6_port = GSSwapHostI16ToBig(port);
|
||||||
|
ptonReturn = inet_pton(AF_INET6, addr_c, &peer.sin6_addr);
|
||||||
if (ptonReturn == 0) // error
|
if (ptonReturn == 0) // error
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[self _setAddress: (struct sockaddr*)&peer];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) propertyForKey: (NSString *)key
|
- (id) propertyForKey: (NSString *)key
|
||||||
{
|
{
|
||||||
id result = propertyForInet6Stream((intptr_t)_loopID, key);
|
id result = [super propertyForKey: key];
|
||||||
|
|
||||||
if (result == nil)
|
if (result == nil)
|
||||||
{
|
{
|
||||||
result = [super propertyForKey: key];
|
result = propertyForInet6Stream((intptr_t)_loopID, key);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2293,30 +2406,21 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
return [GSInetOutputStream class];
|
return [GSInetOutputStream class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_in);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _serverAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_serverAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||||
{
|
{
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
int ptonReturn;
|
int ptonReturn;
|
||||||
const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
|
const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
_serverAddr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
_serverAddr.sin_port = GSSwapHostI16ToBig(port);
|
addr.sin_port = GSSwapHostI16ToBig(port);
|
||||||
if (addr_c == 0)
|
if (addr_c == 0)
|
||||||
{
|
{
|
||||||
addr_c = "0.0.0.0"; /* Bind on all addresses */
|
addr_c = "0.0.0.0"; /* Bind on all addresses */
|
||||||
}
|
}
|
||||||
ptonReturn = inet_pton(AF_INET, addr_c, &(_serverAddr.sin_addr));
|
ptonReturn = inet_pton(AF_INET, addr_c, &addr.sin_addr);
|
||||||
if (ptonReturn == 0) // error
|
if (ptonReturn == 0) // error
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
|
@ -2332,6 +2436,7 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
[self _setAddress: (struct sockaddr*)&addr];
|
||||||
[self _setSock: s];
|
[self _setSock: s];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2353,30 +2458,21 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
return [GSInet6OutputStream class];
|
return [GSInet6OutputStream class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_in6);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _serverAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_serverAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr port: (int)port
|
- (id) initToAddr: (NSString*)addr port: (int)port
|
||||||
{
|
{
|
||||||
if ([super init] != nil)
|
if ([super init] != nil)
|
||||||
{
|
{
|
||||||
int ptonReturn;
|
int ptonReturn;
|
||||||
const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
|
const char *addr_c = [addr cStringUsingEncoding: NSUTF8StringEncoding];
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
|
||||||
_serverAddr.sin6_family = AF_INET6;
|
addr.sin6_family = AF_INET6;
|
||||||
_serverAddr.sin6_port = GSSwapHostI16ToBig(port);
|
addr.sin6_port = GSSwapHostI16ToBig(port);
|
||||||
if (addr_c == 0)
|
if (addr_c == 0)
|
||||||
{
|
{
|
||||||
addr_c = "0:0:0:0:0:0:0:0"; /* Bind on all addresses */
|
addr_c = "0:0:0:0:0:0:0:0"; /* Bind on all addresses */
|
||||||
}
|
}
|
||||||
ptonReturn = inet_pton(AF_INET6, addr_c, &(_serverAddr.sin6_addr));
|
ptonReturn = inet_pton(AF_INET6, addr_c, &addr.sin6_addr);
|
||||||
if (ptonReturn == 0) // error
|
if (ptonReturn == 0) // error
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
|
@ -2392,6 +2488,7 @@ static id propertyForInet6Stream(int descriptor, NSString *key)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
[self _setAddress: (struct sockaddr*)&addr];
|
||||||
[self _setSock: s];
|
[self _setSock: s];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,7 @@ IVARS
|
||||||
* record an error based on errno
|
* record an error based on errno
|
||||||
*/
|
*/
|
||||||
- (void) _recordError;
|
- (void) _recordError;
|
||||||
|
- (void) _recordError: (NSError*)anError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* say whether there is unhandled data for the stream.
|
* say whether there is unhandled data for the stream.
|
||||||
|
|
|
@ -335,6 +335,11 @@ static RunLoopEventType typeForStream(NSStream *aStream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) _recordError: (NSError*)anError
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _schedule
|
- (void) _schedule
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -381,8 +386,13 @@ static RunLoopEventType typeForStream(NSStream *aStream)
|
||||||
NSError *theError;
|
NSError *theError;
|
||||||
|
|
||||||
theError = [NSError _last];
|
theError = [NSError _last];
|
||||||
// NSLog(@"%@ - %@", self, theError);
|
[self _recordError: theError];
|
||||||
ASSIGN(_lastError, theError);
|
}
|
||||||
|
|
||||||
|
- (void) _recordError: (NSError*)anError
|
||||||
|
{
|
||||||
|
// NSLog(@"%@ - %@", self, anError);
|
||||||
|
ASSIGN(_lastError, anError);
|
||||||
_currentStatus = NSStreamStatusError;
|
_currentStatus = NSStreamStatusError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface _NSHTTPURLProtocol : NSURLProtocol
|
@interface _NSHTTPURLProtocol : NSURLProtocol
|
||||||
|
<NSURLAuthenticationChallengeSender>
|
||||||
{
|
{
|
||||||
GSMimeParser *_parser; // Parser handling incoming data
|
GSMimeParser *_parser; // Parser handling incoming data
|
||||||
unsigned _parseOffset; // Bytes of body loaded in parser.
|
unsigned _parseOffset; // Bytes of body loaded in parser.
|
||||||
|
@ -55,6 +56,9 @@
|
||||||
BOOL _debug;
|
BOOL _debug;
|
||||||
BOOL _isLoading;
|
BOOL _isLoading;
|
||||||
BOOL _shouldClose;
|
BOOL _shouldClose;
|
||||||
|
NSURLAuthenticationChallenge *_challenge;
|
||||||
|
NSURLCredential *_credential;
|
||||||
|
NSHTTPURLResponse *_response;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -295,6 +299,23 @@ static NSURLProtocol *placeholder = nil;
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) cancelAuthenticationChallenge: (NSURLAuthenticationChallenge*)c
|
||||||
|
{
|
||||||
|
if (c == _challenge)
|
||||||
|
{
|
||||||
|
DESTROY(_challenge); // We should cancel the download
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) continueWithoutCredentialForAuthenticationChallenge:
|
||||||
|
(NSURLAuthenticationChallenge*)c
|
||||||
|
{
|
||||||
|
if (c == _challenge)
|
||||||
|
{
|
||||||
|
DESTROY(_credential); // We download the challenge page
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _didInitializeOutputStream: (NSOutputStream*)stream
|
- (void) _didInitializeOutputStream: (NSOutputStream*)stream
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -304,6 +325,9 @@ static NSURLProtocol *placeholder = nil;
|
||||||
{
|
{
|
||||||
[_parser release]; // received headers
|
[_parser release]; // received headers
|
||||||
[_body release]; // for sending the body
|
[_body release]; // for sending the body
|
||||||
|
[_response release];
|
||||||
|
[_credential release];
|
||||||
|
[_credential release];
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,6 +372,7 @@ static NSURLProtocol *placeholder = nil;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_statusCode = 0; /* No status returned yet. */
|
||||||
_isLoading = YES;
|
_isLoading = YES;
|
||||||
_complete = NO;
|
_complete = NO;
|
||||||
_debug = NO;
|
_debug = NO;
|
||||||
|
@ -357,7 +382,6 @@ static NSURLProtocol *placeholder = nil;
|
||||||
*/
|
*/
|
||||||
if ([[[this->request URL] path] length] == 0)
|
if ([[[this->request URL] path] length] == 0)
|
||||||
{
|
{
|
||||||
NSURLRequest *request;
|
|
||||||
NSString *s = [[this->request URL] absoluteString];
|
NSString *s = [[this->request URL] absoluteString];
|
||||||
NSURL *url;
|
NSURL *url;
|
||||||
|
|
||||||
|
@ -374,8 +398,7 @@ static NSURLProtocol *placeholder = nil;
|
||||||
s = [s stringByAppendingString: @"/"];
|
s = [s stringByAppendingString: @"/"];
|
||||||
}
|
}
|
||||||
url = [NSURL URLWithString: s];
|
url = [NSURL URLWithString: s];
|
||||||
request = [NSURLRequest requestWithURL: url];
|
if (url == nil)
|
||||||
if (request == nil)
|
|
||||||
{
|
{
|
||||||
NSError *e;
|
NSError *e;
|
||||||
|
|
||||||
|
@ -388,6 +411,10 @@ static NSURLProtocol *placeholder = nil;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
NSMutableURLRequest *request;
|
||||||
|
|
||||||
|
request = [this->request mutableCopy];
|
||||||
|
[request setURL: url];
|
||||||
[this->client URLProtocol: self
|
[this->client URLProtocol: self
|
||||||
wasRedirectedToRequest: request
|
wasRedirectedToRequest: request
|
||||||
redirectResponse: nil];
|
redirectResponse: nil];
|
||||||
|
@ -546,7 +573,6 @@ static NSURLProtocol *placeholder = nil;
|
||||||
|
|
||||||
if (wasInHeaders == YES && isInHeaders == NO)
|
if (wasInHeaders == YES && isInHeaders == NO)
|
||||||
{
|
{
|
||||||
NSHTTPURLResponse *response;
|
|
||||||
GSMimeHeader *info;
|
GSMimeHeader *info;
|
||||||
NSString *enc;
|
NSString *enc;
|
||||||
int len = -1;
|
int len = -1;
|
||||||
|
@ -585,13 +611,14 @@ static NSURLProtocol *placeholder = nil;
|
||||||
enc = [[document headerNamed: @"transfer-encoding"] value];
|
enc = [[document headerNamed: @"transfer-encoding"] value];
|
||||||
}
|
}
|
||||||
|
|
||||||
response = [[NSHTTPURLResponse alloc] initWithURL: [this->request URL]
|
_response = [[NSHTTPURLResponse alloc]
|
||||||
MIMEType: nil
|
initWithURL: [this->request URL]
|
||||||
expectedContentLength: len
|
MIMEType: nil
|
||||||
textEncodingName: nil];
|
expectedContentLength: len
|
||||||
[response _setStatusCode: _statusCode text: s];
|
textEncodingName: nil];
|
||||||
|
[_response _setStatusCode: _statusCode text: s];
|
||||||
[document deleteHeaderNamed: @"http"];
|
[document deleteHeaderNamed: @"http"];
|
||||||
[response _setHeaders: [document allHeaders]];
|
[_response _setHeaders: [document allHeaders]];
|
||||||
|
|
||||||
if (_statusCode == 204 || _statusCode == 304)
|
if (_statusCode == 204 || _statusCode == 304)
|
||||||
{
|
{
|
||||||
|
@ -606,17 +633,18 @@ static NSURLProtocol *placeholder = nil;
|
||||||
_complete = YES; // Had EOF ... terminate
|
_complete = YES; // Had EOF ... terminate
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a redirect.
|
if (_statusCode == 401)
|
||||||
*/
|
|
||||||
s = [[document headerNamed: @"location"] value];
|
|
||||||
if ([s length] > 0)
|
|
||||||
{
|
{
|
||||||
NSURLRequest *request;
|
/* This is an authentication challenge, so we keep reading
|
||||||
NSURL *url;
|
* until the challenge is complete, then try to deal with it.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else if ((s = [[document headerNamed: @"location"] value]) != nil)
|
||||||
|
{
|
||||||
|
NSURL *url;
|
||||||
|
|
||||||
url = [NSURL URLWithString: s];
|
url = [NSURL URLWithString: s];
|
||||||
request = [NSURLRequest requestWithURL: url];
|
if (url == nil)
|
||||||
if (request == nil)
|
|
||||||
{
|
{
|
||||||
NSError *e;
|
NSError *e;
|
||||||
|
|
||||||
|
@ -629,9 +657,13 @@ static NSURLProtocol *placeholder = nil;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
NSMutableURLRequest *request;
|
||||||
|
|
||||||
|
request = [this->request mutableCopy];
|
||||||
|
[request setURL: url];
|
||||||
[this->client URLProtocol: self
|
[this->client URLProtocol: self
|
||||||
wasRedirectedToRequest: request
|
wasRedirectedToRequest: request
|
||||||
redirectResponse: response];
|
redirectResponse: _response];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -660,13 +692,173 @@ static NSURLProtocol *placeholder = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[this->client URLProtocol: self
|
[this->client URLProtocol: self
|
||||||
didReceiveResponse: response
|
didReceiveResponse: _response
|
||||||
cacheStoragePolicy: policy];
|
cacheStoragePolicy: policy];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_complete == YES)
|
if (_complete == YES)
|
||||||
{
|
{
|
||||||
|
if (_statusCode == 401)
|
||||||
|
{
|
||||||
|
NSURLProtectionSpace *space;
|
||||||
|
NSString *hdr;
|
||||||
|
NSURL *url;
|
||||||
|
int failures = 0;
|
||||||
|
|
||||||
|
/* This was an authentication challenge.
|
||||||
|
*/
|
||||||
|
hdr = [[document headerNamed: @"WWW-Authenticate"] value];
|
||||||
|
url = [this->request URL];
|
||||||
|
space = [GSHTTPAuthentication
|
||||||
|
protectionSpaceForAuthentication: hdr requestURL: url];
|
||||||
|
DESTROY(_credential);
|
||||||
|
if (space != nil)
|
||||||
|
{
|
||||||
|
/* Create credential from user and password
|
||||||
|
* stored in the URL.
|
||||||
|
* Returns nil if we have no username or password.
|
||||||
|
*/
|
||||||
|
_credential = [[NSURLCredential alloc]
|
||||||
|
initWithUser: [url user]
|
||||||
|
password: [url password]
|
||||||
|
persistence: NSURLCredentialPersistenceForSession];
|
||||||
|
if (_credential == nil)
|
||||||
|
{
|
||||||
|
/* No credential from the URL, so we try using the
|
||||||
|
* default credential for the protection space.
|
||||||
|
*/
|
||||||
|
ASSIGN(_credential,
|
||||||
|
[[NSURLCredentialStorage sharedCredentialStorage]
|
||||||
|
defaultCredentialForProtectionSpace: space]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_challenge != nil)
|
||||||
|
{
|
||||||
|
/* The failure count is incremented if we have just
|
||||||
|
* tried a request in the same protection space.
|
||||||
|
*/
|
||||||
|
if (YES == [[_challenge protectionSpace] isEqual: space])
|
||||||
|
{
|
||||||
|
failures = [_challenge previousFailureCount] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ([this->request valueForHTTPHeaderField:@"Authorization"])
|
||||||
|
{
|
||||||
|
/* Our request had an authorization header, so we should
|
||||||
|
* count that as a failure or we wouldn't have been
|
||||||
|
* challenged.
|
||||||
|
*/
|
||||||
|
failures = 1;
|
||||||
|
}
|
||||||
|
DESTROY(_challenge);
|
||||||
|
|
||||||
|
_challenge = [[NSURLAuthenticationChallenge alloc]
|
||||||
|
initWithProtectionSpace: space
|
||||||
|
proposedCredential: _credential
|
||||||
|
previousFailureCount: failures
|
||||||
|
failureResponse: _response
|
||||||
|
error: nil
|
||||||
|
sender: self];
|
||||||
|
|
||||||
|
/* Allow the client to control the credential we send
|
||||||
|
* or whether we actually send at all.
|
||||||
|
*/
|
||||||
|
[this->client URLProtocol: self
|
||||||
|
didReceiveAuthenticationChallenge: _challenge];
|
||||||
|
|
||||||
|
if (_challenge == nil)
|
||||||
|
{
|
||||||
|
NSError *e;
|
||||||
|
|
||||||
|
/* The client cancelled the authentication challenge
|
||||||
|
* so we must cancel the download.
|
||||||
|
*/
|
||||||
|
e = [NSError errorWithDomain: @"Authentication cancelled"
|
||||||
|
code: 0
|
||||||
|
userInfo: nil];
|
||||||
|
[self stopLoading];
|
||||||
|
[this->client URLProtocol: self
|
||||||
|
didFailWithError: e];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSString *auth = nil;
|
||||||
|
|
||||||
|
if (_credential != nil)
|
||||||
|
{
|
||||||
|
GSHTTPAuthentication *authentication;
|
||||||
|
|
||||||
|
/* Get information about basic or
|
||||||
|
* digest authentication.
|
||||||
|
*/
|
||||||
|
authentication = [GSHTTPAuthentication
|
||||||
|
authenticationWithCredential: _credential
|
||||||
|
inProtectionSpace: space];
|
||||||
|
|
||||||
|
/* Generate authentication header value for the
|
||||||
|
* authentication type in the challenge.
|
||||||
|
*/
|
||||||
|
auth = [authentication
|
||||||
|
authorizationForAuthentication: hdr
|
||||||
|
method: [this->request HTTPMethod]
|
||||||
|
path: [url path]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth == nil)
|
||||||
|
{
|
||||||
|
NSURLCacheStoragePolicy policy;
|
||||||
|
|
||||||
|
/* We have no authentication credentials so we
|
||||||
|
* treat this as a download of the challenge page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Tell the client that we have a response and how
|
||||||
|
* it should be cached.
|
||||||
|
*/
|
||||||
|
policy = [this->request cachePolicy];
|
||||||
|
if (policy == NSURLRequestUseProtocolCachePolicy)
|
||||||
|
{
|
||||||
|
if ([self isKindOfClass: [_NSHTTPSURLProtocol class]])
|
||||||
|
{
|
||||||
|
/* For HTTPS we should not allow caching unless
|
||||||
|
* the request explicitly wants it.
|
||||||
|
*/
|
||||||
|
policy = NSURLCacheStorageNotAllowed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For HTTP we allow caching unless the request
|
||||||
|
* specifically denies it.
|
||||||
|
*/
|
||||||
|
policy = NSURLCacheStorageAllowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[this->client URLProtocol: self
|
||||||
|
didReceiveResponse: _response
|
||||||
|
cacheStoragePolicy: policy];
|
||||||
|
/* Fall through to code providing page data.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSMutableURLRequest *request;
|
||||||
|
|
||||||
|
/* To answer the authentication challenge,
|
||||||
|
* we must retry with a modified request and
|
||||||
|
* with the cached response cleared.
|
||||||
|
*/
|
||||||
|
request = [this->request mutableCopy];
|
||||||
|
[request setValue: auth
|
||||||
|
forHTTPHeaderField: @"Authorization"];
|
||||||
|
[self stopLoading];
|
||||||
|
DESTROY(this->cachedResponse);
|
||||||
|
[self startLoading];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[self _unschedule];
|
[self _unschedule];
|
||||||
if (_shouldClose == YES)
|
if (_shouldClose == YES)
|
||||||
{
|
{
|
||||||
|
@ -676,88 +868,6 @@ static NSURLProtocol *placeholder = nil;
|
||||||
DESTROY(this->output);
|
DESTROY(this->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* Retrieve essential keys from document
|
|
||||||
*/
|
|
||||||
if (_statusCode == 401 && self->challenged < 2)
|
|
||||||
{
|
|
||||||
GSMimeHeader *ah;
|
|
||||||
|
|
||||||
self->challenged++; // Prevent repeated challenge/auth
|
|
||||||
if ((ah = [document headerNamed: @"WWW-Authenticate"]) != nil)
|
|
||||||
{
|
|
||||||
NSURLProtectionSpace *space;
|
|
||||||
NSString *ac;
|
|
||||||
GSHTTPAuthentication *authentication;
|
|
||||||
NSString *method;
|
|
||||||
NSString *auth;
|
|
||||||
|
|
||||||
ac = [ah value];
|
|
||||||
space = [GSHTTPAuthentication
|
|
||||||
protectionSpaceForAuthentication: ac requestURL: url];
|
|
||||||
if (space == nil)
|
|
||||||
{
|
|
||||||
authentication = nil;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSURLCredential *cred;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create credential from user and password
|
|
||||||
* stored in the URL.
|
|
||||||
* Returns nil if we have no username or password.
|
|
||||||
*/
|
|
||||||
cred = [[NSURLCredential alloc]
|
|
||||||
initWithUser: [url user]
|
|
||||||
password: [url password]
|
|
||||||
persistence: NSURLCredentialPersistenceForSession];
|
|
||||||
|
|
||||||
if (cred == nil)
|
|
||||||
{
|
|
||||||
authentication = nil;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Get the digest object and ask it for a header
|
|
||||||
* to use for authorisation.
|
|
||||||
* Returns nil if we have no credential.
|
|
||||||
*/
|
|
||||||
authentication = [GSHTTPAuthentication
|
|
||||||
authenticationWithCredential: cred
|
|
||||||
inProtectionSpace: space];
|
|
||||||
RELEASE(cred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
method = [request objectForKey: GSHTTPPropertyMethodKey];
|
|
||||||
if (method == nil)
|
|
||||||
{
|
|
||||||
if ([wData length] > 0)
|
|
||||||
{
|
|
||||||
method = @"POST";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
method = @"GET";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auth = [authentication authorizationForAuthentication: ac
|
|
||||||
method: method
|
|
||||||
path: [url path]];
|
|
||||||
if (auth != nil)
|
|
||||||
{
|
|
||||||
[self writeProperty: auth forKey: @"Authorization"];
|
|
||||||
[self _tryLoadInBackground: u];
|
|
||||||
return; // Retrying.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell superclass that we have successfully loaded the data
|
* Tell superclass that we have successfully loaded the data
|
||||||
* (as long as we haven't had the load terminated by the client).
|
* (as long as we haven't had the load terminated by the client).
|
||||||
|
@ -787,7 +897,7 @@ static NSURLProtocol *placeholder = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_isLoading == YES)
|
else if (_isLoading == YES && _statusCode != 401)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Report partial data if possible.
|
* Report partial data if possible.
|
||||||
|
@ -1074,6 +1184,14 @@ static NSURLProtocol *placeholder = nil;
|
||||||
[this->client URLProtocol: self didFailWithError: [stream streamError]];
|
[this->client URLProtocol: self didFailWithError: [stream streamError]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) useCredential: (NSURLCredential*)credential
|
||||||
|
forAuthenticationChallenge: (NSURLAuthenticationChallenge*)challenge
|
||||||
|
{
|
||||||
|
if (challenge == _challenge)
|
||||||
|
{
|
||||||
|
ASSIGN(_credential, credential);
|
||||||
|
}
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation _NSHTTPSURLProtocol
|
@implementation _NSHTTPSURLProtocol
|
||||||
|
|
|
@ -183,7 +183,11 @@ typedef struct {
|
||||||
cachePolicy: (NSURLRequestCachePolicy)cachePolicy
|
cachePolicy: (NSURLRequestCachePolicy)cachePolicy
|
||||||
timeoutInterval: (NSTimeInterval)timeoutInterval
|
timeoutInterval: (NSTimeInterval)timeoutInterval
|
||||||
{
|
{
|
||||||
if ((self = [super init]) != nil)
|
if ([URL isKindOfClass: [NSURL class]] == NO)
|
||||||
|
{
|
||||||
|
DESTROY(self);
|
||||||
|
}
|
||||||
|
else if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
this->URL = RETAIN(URL);
|
this->URL = RETAIN(URL);
|
||||||
this->cachePolicy = cachePolicy;
|
this->cachePolicy = cachePolicy;
|
||||||
|
|
|
@ -49,11 +49,6 @@
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSLocalInputStream : GSSocketInputStream
|
@interface GSLocalInputStream : GSSocketInputStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
struct sockaddr_un _peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the designated initializer
|
* the designated initializer
|
||||||
*/
|
*/
|
||||||
|
@ -73,11 +68,6 @@
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSLocalOutputStream : GSSocketOutputStream
|
@interface GSLocalOutputStream : GSSocketOutputStream
|
||||||
{
|
|
||||||
@private
|
|
||||||
struct sockaddr_un _peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the designated initializer
|
* the designated initializer
|
||||||
*/
|
*/
|
||||||
|
@ -218,29 +208,22 @@
|
||||||
|
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
_peerAddr.sun_family = AF_LOCAL;
|
struct sockaddr_un peer;
|
||||||
if (strlen(real_addr)>sizeof(_peerAddr.sun_path)-1) // too long
|
|
||||||
|
peer.sun_family = AF_LOCAL;
|
||||||
|
if (strlen(real_addr) > sizeof(peer.sun_path)-1) // too long
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strncpy(_peerAddr.sun_path, real_addr, sizeof(_peerAddr.sun_path)-1);
|
strncpy(peer.sun_path, real_addr, sizeof(peer.sun_path)-1);
|
||||||
|
[self _setAddress: (struct sockaddr)&peer];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_un);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GSFileOutputStream
|
@implementation GSFileOutputStream
|
||||||
|
@ -364,29 +347,22 @@
|
||||||
|
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
_peerAddr.sun_family = AF_LOCAL;
|
struct sockaddr_un peer;
|
||||||
if (strlen(real_addr) > sizeof(_peerAddr.sun_path)-1) // too long
|
|
||||||
|
peer.sun_family = AF_LOCAL;
|
||||||
|
if (strlen(real_addr) > sizeof(peer.sun_path)-1) // too long
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strncpy(_peerAddr.sun_path, real_addr, sizeof(_peerAddr.sun_path)-1);
|
strncpy(peer.sun_path, real_addr, sizeof(peer.sun_path)-1);
|
||||||
|
[self _setAddress: (struct sockaddr*)&peer];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (struct sockaddr*) _peerAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_peerAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (socklen_t) sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_un);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSStream
|
@implementation NSStream
|
||||||
|
@ -657,23 +633,14 @@
|
||||||
return [GSLocalOutputStream class];
|
return [GSLocalOutputStream class];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (socklen_t) _sockLen
|
|
||||||
{
|
|
||||||
return sizeof(struct sockaddr_un);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (struct sockaddr*) _serverAddr
|
|
||||||
{
|
|
||||||
return (struct sockaddr*)&_serverAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) initToAddr: (NSString*)addr
|
- (id) initToAddr: (NSString*)addr
|
||||||
{
|
{
|
||||||
if ((self = [super init]) != nil)
|
if ((self = [super init]) != nil)
|
||||||
{
|
{
|
||||||
const char* real_addr = [addr fileSystemRepresentation];
|
const char* real_addr = [addr fileSystemRepresentation];
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
if (strlen(real_addr) > sizeof(_serverAddr.sun_path)-1)
|
if (strlen(real_addr) > sizeof(addr.sun_path)-1)
|
||||||
{
|
{
|
||||||
DESTROY(self);
|
DESTROY(self);
|
||||||
}
|
}
|
||||||
|
@ -681,7 +648,7 @@
|
||||||
{
|
{
|
||||||
SOCKET s;
|
SOCKET s;
|
||||||
|
|
||||||
_serverAddr.sun_family = AF_LOCAL;
|
addr.sun_family = AF_LOCAL;
|
||||||
s = socket(AF_LOCAL, SOCK_STREAM, 0);
|
s = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
{
|
{
|
||||||
|
@ -690,8 +657,8 @@
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[(GSSocketStream*)self _setSock: s];
|
[(GSSocketStream*)self _setSock: s];
|
||||||
strncpy(_serverAddr.sun_path, real_addr,
|
strncpy(addr.sun_path, real_addr, sizeof(addr.sun_path)-1);
|
||||||
sizeof(_serverAddr.sun_path)-1);
|
[self _setAddress: (struct sockaddr)&addr];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue