Skip to content

Commit

Permalink
Brought in changes from Kobo application, including a few new feature…
Browse files Browse the repository at this point in the history
…s and many bug fixes. AQXMLParser in particular is much more resistant to stream errors and timeouts now, and there is a subclass available which allows the caller to explicitly specify a timeout.
  • Loading branch information
Jim Dovey committed Dec 14, 2010
1 parent 081d518 commit 2bb3a90
Show file tree
Hide file tree
Showing 12 changed files with 449 additions and 69 deletions.
2 changes: 1 addition & 1 deletion Compression/AQGzipFileStream.m
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ - (void) postStreamEvent: (NSStreamEvent) event

// it's a fire-and-forget message, no reply
kern_return_t kr = mach_msg( (mach_msg_header_t *) &msg, MACH_SEND_MSG, msg.header.msgh_size,
0, MACH_PORT_NULL, 0, MACH_PORT_NULL );
0, MACH_PORT_NULL, 0, MACH_PORT_NULL );
if ( kr != KERN_SUCCESS )
{
_error = [[NSError errorWithDomain: NSMachErrorDomain code: kr userInfo: nil] retain];
Expand Down
6 changes: 6 additions & 0 deletions HTTPMessage/HTTPMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@

#if TARGET_OS_IPHONE
#import <CFNetwork/CFHTTPMessage.h>
#import <CFNetwork/CFHTTPStream.h>
#else
#import <CoreServices/../Frameworks/CFNetwork.framework/Headers/CFHTTPMessage.h>
#import <CoreServices/../Frameworks/CFNetwork.framework/Headers/CFHTTPStream.h>
#endif

#import "HTTPAuthentication.h"
Expand All @@ -57,10 +59,12 @@
+ (HTTPMessage *) responseMessageWithHTTPStatus: (NSInteger) statusCode
description: (NSString *) statusDescription
version: (NSString *) httpVersion;
+ (HTTPMessage *) responseMessageFromInputStream: (NSInputStream *) stream;

// designated initializer
- (id) initWithCFHTTPMessageRef: (CFHTTPMessageRef) messageRef;
- (id) initAsRequest: (BOOL) isRequest;
- (id) initResponseFromInputStream: (NSInputStream *) stream;

// append data manually
- (BOOL) appendData: (NSData *) messageData;
Expand All @@ -76,6 +80,8 @@
@property (nonatomic, readonly, copy) NSString * requestMethod;
@property (nonatomic, readonly, copy) NSURL * requestURL;

@property (nonatomic, assign) BOOL useGzipEncoding;

- (NSData *) serializedMessage;

@property (nonatomic, readonly, copy) NSString * version;
Expand Down
35 changes: 34 additions & 1 deletion HTTPMessage/HTTPMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ + (HTTPMessage *) requestMessageWithMethod: (NSString *) method
url: (NSURL *) url
version: (NSString *) httpVersion
{
// crash fix
if ( url == nil )
return nil;

CFHTTPMessageRef message = CFHTTPMessageCreateRequest( kCFAllocatorDefault, (CFStringRef)method,
(CFURLRef)[url absoluteURL], (CFStringRef)httpVersion );
HTTPMessage * result = [[self alloc] initWithCFHTTPMessageRef: message];
Expand All @@ -80,6 +84,11 @@ + (HTTPMessage *) responseMessageWithHTTPStatus: (NSInteger) statusCode
return ( [result autorelease] );
}

+ (HTTPMessage *) responseMessageFromInputStream: (NSInputStream *) stream
{
return ( [[[self alloc] initResponseFromInputStream: stream] autorelease] );
}

- (id) initWithCFHTTPMessageRef: (CFHTTPMessageRef) message
{
if ( message == NULL )
Expand All @@ -96,7 +105,18 @@ - (id) initWithCFHTTPMessageRef: (CFHTTPMessageRef) message
- (id) initAsRequest: (BOOL) asRequest
{
CFHTTPMessageRef message = CFHTTPMessageCreateEmpty( kCFAllocatorDefault, asRequest );
return ( [self initWithCFHTTPMessageRef: message] );
self = [self initWithCFHTTPMessageRef: message];
CFRelease( message );
return ( self );
}

- (id) initResponseFromInputStream: (NSInputStream *) stream
{
CFReadStreamRef s = (CFReadStreamRef)stream;
CFHTTPMessageRef message = (CFHTTPMessageRef)CFReadStreamCopyProperty(s, kCFStreamPropertyHTTPResponseHeader);
self = [self initWithCFHTTPMessageRef: message];
CFRelease( message );
return ( self );
}

- (void) dealloc
Expand Down Expand Up @@ -174,6 +194,19 @@ - (NSURL *) requestURL
return ( [url autorelease] );
}

- (BOOL) useGzipEncoding
{
return ( [[self valueForHeaderField: @"Accept-Encoding"] isEqualToString: @"gzip"] );
}

- (void) setUseGzipEncoding: (BOOL) useGzip
{/*
if ( useGzip )
[self setValue: @"gzip" forHeaderField: @"Accept-Encoding"];
else
[self setValue: nil forHeaderField: @"Accept-Encoding"];*/
}

- (NSData *) serializedMessage
{
NSData * data = (NSData *) NSMakeCollectable( CFHTTPMessageCopySerializedMessage(_internal) );
Expand Down
19 changes: 19 additions & 0 deletions HTTPMessage/NSStream+HTTPMessage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// NSStream+HTTPMessage.h
// Kobov3
//
// Created by Jim Dovey on 10-04-08.
// Copyright 2010 Kobo Inc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "HTTPMessage.h"

@interface NSStream (HTTPMessage)

- (HTTPMessage *) finalRequestMessage;
- (HTTPMessage *) responseMessageHeader;

- (NSURL *) finalURL;

@end
56 changes: 56 additions & 0 deletions HTTPMessage/NSStream+HTTPMessage.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// NSStream+HTTPMessage.m
// Kobov3
//
// Created by Jim Dovey on 10-04-08.
// Copyright 2010 Kobo Inc. All rights reserved.
//

#import "NSStream+HTTPMessage.h"

#if TARGET_OS_IPHONE
#import <CFNetwork/CFNetwork.h>
#else
#import <CoreServices/CoreServices.h>
#endif

@implementation NSStream (HTTPMessage)

- (HTTPMessage *) finalRequestMessage
{
CFHTTPMessageRef cf = NULL;
if ( [self isKindOfClass: [NSInputStream class]] )
cf = (CFHTTPMessageRef)CFReadStreamCopyProperty( (CFReadStreamRef)self, kCFStreamPropertyHTTPFinalRequest );
else
cf = (CFHTTPMessageRef)CFWriteStreamCopyProperty( (CFWriteStreamRef)self, kCFStreamPropertyHTTPFinalRequest );
if ( cf == NULL )
return ( nil );

HTTPMessage * result = [[HTTPMessage alloc] initWithCFHTTPMessageRef: cf];
CFRelease( cf );

return ( [result autorelease] );
}

- (HTTPMessage *) responseMessageHeader
{
CFHTTPMessageRef cf = NULL;
if ( [self isKindOfClass: [NSInputStream class]] )
cf = (CFHTTPMessageRef)CFReadStreamCopyProperty( (CFReadStreamRef)self, kCFStreamPropertyHTTPResponseHeader );
else
cf = (CFHTTPMessageRef)CFWriteStreamCopyProperty( (CFWriteStreamRef)self, kCFStreamPropertyHTTPResponseHeader );
if ( cf == NULL )
return ( nil );

HTTPMessage * result = [[HTTPMessage alloc] initWithCFHTTPMessageRef: cf];
CFRelease( cf );

return ( [result autorelease] );
}

- (NSURL *) finalURL
{
return ( (NSURL *)[self propertyForKey: (NSString *)kCFStreamPropertyHTTPFinalURL] );
}

@end
10 changes: 9 additions & 1 deletion StreamingXMLParser/AQXMLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ extern NSString * const AQXMLParserParsingRunLoopMode;

// delegates should implement the same functions used by AQXMLParser

@interface AQXMLParser : NSObject
@interface AQXMLParser : NSObject <NSStreamDelegate>
{
void * _parser;
id<AQXMLParserDelegate> __weak _delegate;
Expand Down Expand Up @@ -91,6 +91,14 @@ extern NSString * const AQXMLParserParsingRunLoopMode;
@property (nonatomic, readonly, retain) NSString * systemID;
@property (nonatomic, readonly) NSInteger lineNumber;
@property (nonatomic, readonly) NSInteger columnNumber;
@property (NS_NONATOMIC_IPHONEONLY assign) BOOL debugLogInput;
@end

@class HTTPMessage;

@interface AQXMLParser (AQXMLParserHTTPStreamAdditions)
@property (nonatomic, readonly) HTTPMessage * finalRequest;
@property (nonatomic, readonly) HTTPMessage * finalResponse;
@end

// parser reports progress as a value between 0.0 and 1.0
Expand Down
Loading

0 comments on commit 2bb3a90

Please sign in to comment.