Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for Mac and binary transfer #147

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Core/Mime/MultipartFormDataParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ + (NSData*) decodedDataFromData:(NSData*) data encoding:(int) encoding;
- (int) findHeaderEnd:(NSData*) workingData fromOffset:(int) offset;
- (int) findContentEnd:(NSData*) data fromOffset:(int) offset;

- (int) numberOfBytesToLeavePendingWithData:(NSData*) data length:(NSUInteger) length encoding:(int) encoding;
- (NSInteger) numberOfBytesToLeavePendingWithData:(NSData*) data length:(NSInteger) length encoding:(int) encoding;
- (int) offsetTillNewlineSinceOffset:(int) offset inData:(NSData*) data;

- (int) processPreamble:(NSData*) workingData;
Expand Down Expand Up @@ -244,10 +244,10 @@ - (BOOL) appendData:(NSData *)data {
// this case, we didn't find the boundary, so the data is related to the current part.
// we leave the sizeToLeavePending amount of bytes to make sure we don't include
// boundary part in processed data.
NSUInteger sizeToPass = workingData.length - offset - sizeToLeavePending;
NSInteger sizeToPass = workingData.length - offset - sizeToLeavePending;

// if we parse BASE64 encoded data, or Quoted-Printable data, we will make sure we don't break the format
int leaveTrailing = [self numberOfBytesToLeavePendingWithData:data length:sizeToPass encoding:currentEncoding];
NSInteger leaveTrailing = [self numberOfBytesToLeavePendingWithData:data length:sizeToPass encoding:currentEncoding];
sizeToPass -= leaveTrailing;

if( sizeToPass <= 0 ) {
Expand Down Expand Up @@ -417,14 +417,14 @@ - (int) findContentEnd:(NSData*) data fromOffset:(int) offset {
}


- (int) numberOfBytesToLeavePendingWithData:(NSData*) data length:(int) length encoding:(int) encoding {
- (NSInteger) numberOfBytesToLeavePendingWithData:(NSData*) data length:(NSInteger) length encoding:(int) encoding {
// If we have BASE64 or Quoted-Printable encoded data, we have to be sure
// we don't break the format.
int sizeToLeavePending = 0;
NSInteger sizeToLeavePending = 0;

if( encoding == contentTransferEncoding_base64 ) {
char* bytes = (char*) data.bytes;
int i;
NSInteger i;
for( i = length - 1; i > 0; i++ ) {
if( * (uint16_t*) (bytes + i) == 0x0A0D ) {
break;
Expand Down
3 changes: 2 additions & 1 deletion Core/Mime/MultipartMessageHeaderField.m
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ -(BOOL) parseHeaderValueBytes:(char*) bytes length:(NSUInteger) length encoding:
HTTPLogWarn(@"MultipartFormDataParser: param %@ mentioned more then once in one header",currentParam);
}
#endif
[params setObject:paramValue forKey:currentParam];
if(paramValue != nil)
[params setObject:paramValue forKey:currentParam];
HTTPLogVerbose(@"MultipartFormDataParser: header param: %@ = %@",currentParam,paramValue);
currentParam = nil;
}
Expand Down
7 changes: 5 additions & 2 deletions Core/WebSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

+ (BOOL)isWebSocketRequest:(HTTPMessage *)request;

- (id)initWithRequest:(HTTPMessage *)request socket:(GCDAsyncSocket *)socket;
- (id)initWithRequest:(HTTPMessage *)request socket:(GCDAsyncSocket *)socket NS_DESIGNATED_INITIALIZER;

/**
* Delegate option.
Expand Down Expand Up @@ -64,7 +64,7 @@
* Sends a message over the WebSocket.
* This method is thread-safe.
**/
- (void)sendData:(NSData *)msg;
- (void)sendData:(NSData *)msg isBinary:(BOOL)binary;

/**
* Subclass API
Expand All @@ -73,6 +73,7 @@
**/
- (void)didOpen;
- (void)didReceiveMessage:(NSString *)msg;
- (void)didReceiveData:(NSData *)data;
- (void)didClose;

@end
Expand Down Expand Up @@ -102,4 +103,6 @@

- (void)webSocketDidClose:(WebSocket *)ws;

- (void)webSocket:(WebSocket *)ws didReceiveData:(NSData *)data;

@end
68 changes: 52 additions & 16 deletions Core/WebSocket.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@
#define WS_OP_PING 9
#define WS_OP_PONG 10

static inline BOOL WS_OP_IS_FINAL_FRAGMENT(UInt8 frame)
{
return (frame & 0x80) ? YES : NO;
}

static inline BOOL WS_PAYLOAD_IS_MASKED(UInt8 frame)
{
return (frame & 0x80) ? YES : NO;
Expand Down Expand Up @@ -108,7 +103,7 @@ + (BOOL)isWebSocketRequest:(HTTPMessage *)request
if (!upgradeHeaderValue || !connectionHeaderValue) {
isWebSocket = NO;
}
else if (![upgradeHeaderValue caseInsensitiveCompare:@"WebSocket"] == NSOrderedSame) {
else if ([upgradeHeaderValue caseInsensitiveCompare:@"WebSocket"] != NSOrderedSame) {
isWebSocket = NO;
}
else if ([connectionHeaderValue rangeOfString:@"Upgrade" options:NSCaseInsensitiveSearch].location == NSNotFound) {
Expand Down Expand Up @@ -155,6 +150,12 @@ + (BOOL)isRFC6455Request:(HTTPMessage *)request

@synthesize websocketQueue;

- (instancetype)init
{
[NSException raise:NSInternalInconsistencyException format:@"Initializer disallowed: %s", __PRETTY_FUNCTION__];
return [self initWithRequest:nil socket:nil];
}

- (id)initWithRequest:(HTTPMessage *)aRequest socket:(GCDAsyncSocket *)socket
{
HTTPLogTrace();
Expand Down Expand Up @@ -536,10 +537,10 @@ - (void)didOpen
- (void)sendMessage:(NSString *)msg
{
NSData *msgData = [msg dataUsingEncoding:NSUTF8StringEncoding];
[self sendData:msgData];
[self sendData:msgData isBinary:NO];
}

- (void)sendData:(NSData *)msgData
- (void)sendData:(NSData *)msgData isBinary:(BOOL)binary
{
HTTPLogTrace();

Expand All @@ -548,26 +549,33 @@ - (void)sendData:(NSData *)msgData
if (isRFC6455)
{
NSUInteger length = msgData.length;
UInt8 firstByte = 0x80;
if(binary)
firstByte |= WS_OP_BINARY_FRAME;
else
firstByte |= WS_OP_TEXT_FRAME;

if (length <= 125)
{
data = [NSMutableData dataWithCapacity:(length + 2)];
[data appendBytes: "\x81" length:1];

[data appendBytes: &firstByte length:1];
UInt8 len = (UInt8)length;
[data appendBytes: &len length:1];
[data appendData:msgData];
}
else if (length <= 0xFFFF)
{
data = [NSMutableData dataWithCapacity:(length + 4)];
[data appendBytes: "\x81\x7E" length:2];
[data appendBytes: (UInt8[]){firstByte, 0x7e} length:2];
UInt16 len = (UInt16)length;
[data appendBytes: (UInt8[]){len >> 8, len & 0xFF} length:2];
[data appendData:msgData];
}
else
{
data = [NSMutableData dataWithCapacity:(length + 10)];
[data appendBytes: "\x81\x7F" length:2];
[data appendBytes: (UInt8[]){firstByte, 0x7f} length:2];
[data appendBytes: (UInt8[]){0, 0, 0, 0, (UInt8)(length >> 24), (UInt8)(length >> 16), (UInt8)(length >> 8), length & 0xFF} length:8];
[data appendData:msgData];
}
Expand Down Expand Up @@ -602,6 +610,22 @@ - (void)didReceiveMessage:(NSString *)msg
}
}

- (void)didReceiveData:(NSData *)data
{
HTTPLogTrace();

// Override me to process incoming data.
// This method is invoked on the websocketQueue.
//
// For completeness, you should invoke [super didReceiveData:data] in your method.

// Notify delegate
if ([delegate respondsToSelector:@selector(webSocket:didReceiveData:)])
{
[delegate webSocket:self didReceiveData:data];
}
}

- (void)didClose
{
HTTPLogTrace();
Expand Down Expand Up @@ -754,6 +778,10 @@ - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)t
NSString *msg = [[NSString alloc] initWithBytes:[data bytes] length:msgLength encoding:NSUTF8StringEncoding];
[self didReceiveMessage:msg];
}
else if (nextOpCode == WS_OP_BINARY_FRAME)
{
[self didReceiveData:data];
}
else
{
[self didClose];
Expand All @@ -770,11 +798,19 @@ - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)t
else
{
NSUInteger msgLength = [data length] - 1; // Excluding ending 0xFF frame

NSString *msg = [[NSString alloc] initWithBytes:[data bytes] length:msgLength encoding:NSUTF8StringEncoding];

[self didReceiveMessage:msg];


if (nextOpCode == WS_OP_TEXT_FRAME)
{
NSString *msg = [[NSString alloc] initWithBytes:[data bytes] length:msgLength encoding:NSUTF8StringEncoding];

[self didReceiveMessage:msg];
}
else if(nextOpCode == WS_OP_BINARY_FRAME)
{
NSData *msg = [data subdataWithRange:NSMakeRange(0, msgLength)];

[self didReceiveData:msg];
}

// Read next message
[asyncSocket readDataToLength:1 withTimeout:TIMEOUT_NONE tag:TAG_PREFIX];
Expand Down
4 changes: 2 additions & 2 deletions Vendor/CocoaAsyncSocket/GCDAsyncSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@
// Compiling for Mac OS X

#define IS_SECURE_TRANSPORT_AVAILABLE YES
#define SECURE_TRANSPORT_MAYBE_AVAILABLE 1
#define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 0
#define SECURE_TRANSPORT_MAYBE_AVAILABLE 0
#define SECURE_TRANSPORT_MAYBE_UNAVAILABLE 1

#endif

Expand Down
5 changes: 2 additions & 3 deletions Vendor/CocoaAsyncSocket/GCDAsyncSocket.m
Original file line number Diff line number Diff line change
Expand Up @@ -4263,10 +4263,9 @@ - (void)doReadData
}
else
{
#if SECURE_TRANSPORT_MAYBE_AVAILABLE

estimatedBytesAvailable = socketFDBytesAvailable;

#if SECURE_TRANSPORT_MAYBE_AVAILABLE
if (flags & kSocketSecure)
{
// There are 2 buffers to be aware of here.
Expand Down Expand Up @@ -4303,9 +4302,9 @@ - (void)doReadData
estimatedBytesAvailable += sslInternalBufSize;
}

#endif
hasBytesAvailable = (estimatedBytesAvailable > 0);

#endif
}

if ((hasBytesAvailable == NO) && ([preBuffer availableBytes] == 0))
Expand Down
12 changes: 6 additions & 6 deletions Vendor/CocoaLumberjack/DDTTYLogger.m
Original file line number Diff line number Diff line change
Expand Up @@ -822,12 +822,12 @@ - (id)init
calendar = [NSCalendar autoupdatingCurrentCalendar];

calendarUnitFlags = 0;
calendarUnitFlags |= NSYearCalendarUnit;
calendarUnitFlags |= NSMonthCalendarUnit;
calendarUnitFlags |= NSDayCalendarUnit;
calendarUnitFlags |= NSHourCalendarUnit;
calendarUnitFlags |= NSMinuteCalendarUnit;
calendarUnitFlags |= NSSecondCalendarUnit;
calendarUnitFlags |= NSCalendarUnitYear;
calendarUnitFlags |= NSCalendarUnitMonth;
calendarUnitFlags |= NSCalendarUnitDay;
calendarUnitFlags |= NSCalendarUnitHour;
calendarUnitFlags |= NSCalendarUnitMinute;
calendarUnitFlags |= NSCalendarUnitSecond;

// Initialze 'app' variable (char *)

Expand Down