[macruby-changes] [4278] ControlTower/trunk/ext/CTParser/CTParser.m
source_changes at macosforge.org
source_changes at macosforge.org
Fri Jun 25 14:03:33 PDT 2010
Revision: 4278
http://trac.macosforge.org/projects/ruby/changeset/4278
Author: lsansonetti at apple.com
Date: 2010-06-25 14:03:30 -0700 (Fri, 25 Jun 2010)
Log Message:
-----------
fix ugly coding style + smarter http field parser
Modified Paths:
--------------
ControlTower/trunk/ext/CTParser/CTParser.m
Modified: ControlTower/trunk/ext/CTParser/CTParser.m
===================================================================
--- ControlTower/trunk/ext/CTParser/CTParser.m 2010-06-25 09:44:59 UTC (rev 4277)
+++ ControlTower/trunk/ext/CTParser/CTParser.m 2010-06-25 21:03:30 UTC (rev 4278)
@@ -9,22 +9,22 @@
#define DEF_MAX_LENGTH(N, val) const size_t MAX_##N##_LENGTH = val
-#define VALIDATE_MAX_LENGTH(len, N)\
- if(len > MAX_##N##_LENGTH) {\
- [NSException raise:@"ParserFieldLengthError"\
- format:@"HTTP element " # N " is longer than the " # len " character allowed length."];\
- }
+#define VALIDATE_MAX_LENGTH(len, N) \
+ if (len > MAX_##N##_LENGTH) { \
+ [NSException raise:@"ParserFieldLengthError" \
+ format:@"HTTP element " # N " is longer than the " \
+ # len " character allowed length."]; \
+ }
-#define PARSE_FIELD(field)\
- void parse_##field (void *env, const char *at, size_t length)\
- {\
- VALIDATE_MAX_LENGTH(length, field)\
- [(NSMutableDictionary *)env setObject:[[NSString alloc] initWithBytes:at\
- length:length\
- encoding:NSUTF8StringEncoding ]\
- forKey:@"" #field];\
- return;\
- }
+#define PARSE_FIELD(field) \
+ static void \
+ parse_##field(void *env, const char *at, size_t length) \
+ { \
+ VALIDATE_MAX_LENGTH(length, field) \
+ NSString *val = [[NSString alloc] initWithBytes:at length:length \
+ encoding:NSUTF8StringEncoding]; \
+ [(NSMutableDictionary *)env setObject:val forKey:@"" #field]; \
+ }
// Max field lengths
DEF_MAX_LENGTH(FIELD_NAME, 256);
@@ -37,17 +37,37 @@
DEF_MAX_LENGTH(HTTP_VERSION, 256);
DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
-void parse_HTTP_FIELD(void *env, const char *field, size_t flen, const char *value, size_t vlen)
+static void
+parse_HTTP_FIELD(void *env, const char *field, size_t flen, const char *value,
+ size_t vlen)
{
- VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
- VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE);
- [(NSMutableDictionary *)env setObject:[[NSString alloc] initWithBytes:value
- length:vlen
- encoding:NSUTF8StringEncoding]
- forKey:[@"HTTP_" stringByAppendingString:[[NSString alloc] initWithBytes:field
- length:flen
- encoding:NSUTF8StringEncoding]]];
- return;
+ VALIDATE_MAX_LENGTH(flen, FIELD_NAME);
+ VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE);
+
+ NSString *val = [[NSString alloc] initWithBytes:value length:vlen
+ encoding:NSUTF8StringEncoding];
+
+ NSString *key;
+ if (strncmp(field, "HOST", 4) == 0) {
+ key = @"HTTP_HOST";
+ }
+ else if (strncmp(field, "REFERER", 4) == 0) {
+ key = @"HTTP_REFERER";
+ }
+ else if (strncmp(field, "CACHE_CONTROL", 4) == 0) {
+ key = @"HTTP_CACHE_CONTROL";
+ }
+ else if (strncmp(field, "COOKIE", 4) == 0) {
+ key = @"HTTP_COOKIE";
+ }
+ else if (strncmp(field, "CONNECTION", 4) == 0) {
+ key = @"HTTP_CONNECTION";
+ }
+ else {
+ key = [@"HTTP_" stringByAppendingString:[[NSString alloc]
+ initWithBytes:field length:flen encoding:NSUTF8StringEncoding]];
+ }
+ [(NSMutableDictionary *)env setObject:val forKey:key];
}
// Parsing callback functions
@@ -58,135 +78,142 @@
PARSE_FIELD(QUERY_STRING);
PARSE_FIELD(HTTP_VERSION);
-void header_done(void *env, const char *at, size_t length)
+static void
+header_done(void *env, const char *at, size_t length)
{
- NSMutableDictionary *environment = (NSMutableDictionary *)env;
- NSString *contentLength = [environment objectForKey:@"HTTP_CONTENT_LENGTH"];
- if (contentLength != nil) {
- [environment setObject:contentLength forKey:@"CONTENT_LENGTH"];
- }
+ NSMutableDictionary *environment = (NSMutableDictionary *)env;
+ NSString *contentLength = [environment objectForKey:@"HTTP_CONTENT_LENGTH"];
+ if (contentLength != nil) {
+ [environment setObject:contentLength forKey:@"CONTENT_LENGTH"];
+ }
- NSString *contentType = [environment objectForKey:@"HTTP_CONTENT_TYPE"];
- if (contentType != nil) {
- [environment setObject:contentType forKey:@"CONTENT_TYPE"];
- }
+ NSString *contentType = [environment objectForKey:@"HTTP_CONTENT_TYPE"];
+ if (contentType != nil) {
+ [environment setObject:contentType forKey:@"CONTENT_TYPE"];
+ }
- [environment setObject:@"CGI/1.2" forKey:@"GATEWAY_INTERFACE"];
+ [environment setObject:@"CGI/1.2" forKey:@"GATEWAY_INTERFACE"];
- NSString *hostString = [environment objectForKey:@"HTTP_HOST"];
- NSString *serverName = nil;
- NSString *serverPort = nil;
- if (hostString != nil) {
- NSRange colon_pos = [hostString rangeOfString:@":"];
- if (colon_pos.location != NSNotFound) {
- serverName = [hostString substringToIndex:colon_pos.location];
- serverPort = [hostString substringFromIndex:(colon_pos.location + 1)];
+ NSString *hostString = [environment objectForKey:@"HTTP_HOST"];
+ NSString *serverName = nil;
+ NSString *serverPort = nil;
+ if (hostString != nil) {
+ NSRange colon_pos = [hostString rangeOfString:@":"];
+ if (colon_pos.location != NSNotFound) {
+ serverName = [hostString substringToIndex:colon_pos.location];
+ serverPort = [hostString substringFromIndex:colon_pos.location+1];
+ }
+ else {
+ serverName = [NSString stringWithString:hostString];
+ serverPort = @"80";
+ }
+ [environment setObject:serverName forKey:@"SERVER_NAME"];
+ [environment setObject:serverPort forKey:@"SERVER_PORT"];
}
- else {
- serverName = [NSString stringWithString:hostString];
- serverPort = @"80";
- }
- [environment setObject:serverName forKey:@"SERVER_NAME"];
- [environment setObject:serverPort forKey:@"SERVER_PORT"];
- }
- [environment setObject:@"HTTP/1.1" forKey:@"SERVER_PROTOCOL"];
- [environment setObject:SERVER_SOFTWARE forKey:@"SERVER_SOFTWARE"];
+ [environment setObject:@"HTTP/1.1" forKey:@"SERVER_PROTOCOL"];
+ [environment setObject:SERVER_SOFTWARE forKey:@"SERVER_SOFTWARE"];
- // We don't do tls yet
- [environment setObject:@"http" forKey:@"rack.url_scheme"];
+ // We don't do tls yet
+ [environment setObject:@"http" forKey:@"rack.url_scheme"];
- // To satisfy Rack specs...
- if ([environment objectForKey:@"QUERY_STRING"] == nil) {
- [environment setObject:@"" forKey:@"QUERY_STRING"];
- }
+ // To satisfy Rack specs...
+ if ([environment objectForKey:@"QUERY_STRING"] == nil) {
+ [environment setObject:@"" forKey:@"QUERY_STRING"];
+ }
- // If we've been given any part of the body, put it here
- NSMutableArray *body = [environment objectForKey:@"rack.input"];
- if (body != nil) {
- [body addObject:[NSData dataWithBytes:at length:length]];
- }
- else {
- NSLog(@"Hmm...you seem to have body data but no where to put it. That's probably an error.");
- }
-
- return;
+ // If we've been given any part of the body, put it here
+ NSMutableArray *body = [environment objectForKey:@"rack.input"];
+ if (body != nil) {
+ [body addObject:[NSData dataWithBytes:at length:length]];
+ }
+ else {
+ NSLog(@"Hmm...you seem to have body data but no where to put it. That's probably an error.");
+ }
}
@implementation CTParser
@synthesize body = _body;
-- (id)init {
- [super init];
- _parser = malloc(sizeof(http_parser));
+- (id)init
+{
+ self = [super init];
+ if (self != nil) {
+ _parser = malloc(sizeof(http_parser));
+ assert(_parser != NULL);
- // Setup the callbacks
- _parser->http_field = parse_HTTP_FIELD;
- _parser->request_method = parse_REQUEST_METHOD;
- _parser->request_uri = parse_REQUEST_URI;
- _parser->fragment = parse_FRAGMENT;
- _parser->request_path = parse_PATH_INFO;
- _parser->query_string = parse_QUERY_STRING;
- _parser->http_version = parse_HTTP_VERSION;
- _parser->header_done = header_done;
+ // Setup the callbacks
+ _parser->http_field = parse_HTTP_FIELD;
+ _parser->request_method = parse_REQUEST_METHOD;
+ _parser->request_uri = parse_REQUEST_URI;
+ _parser->fragment = parse_FRAGMENT;
+ _parser->request_path = parse_PATH_INFO;
+ _parser->query_string = parse_QUERY_STRING;
+ _parser->http_version = parse_HTTP_VERSION;
+ _parser->header_done = header_done;
- http_parser_init(_parser);
- return self;
+ http_parser_init(_parser);
+ }
+ return self;
}
- (void)reset
{
- http_parser_init(_parser);
- return;
+ http_parser_init(_parser);
}
-
-- (NSNumber *)parseData:(NSData *)dataBuf forEnvironment:(NSMutableDictionary *)env startingAt:(NSNumber *)startingPos
+- (NSNumber *)parseData:(NSData *)dataBuf
+ forEnvironment:(NSMutableDictionary *)env
+ startingAt:(NSNumber *)startingPos
{
- NSMutableData *dataForParser = [NSMutableData dataWithLength:([dataBuf length] + 1)];
- [dataForParser setData:dataBuf];
- [dataForParser appendData:'\0'];
- const char *data = [dataForParser bytes];
- size_t length = [dataForParser length];
- size_t offset = [startingPos unsignedLongValue];
- _parser->data = env;
+ NSMutableData *dataForParser = [NSMutableData dataWithLength:
+ [dataBuf length] + 1];
+ [dataForParser setData:dataBuf];
+ [dataForParser appendData:'\0'];
+ const char *data = [dataForParser bytes];
+ size_t length = [dataForParser length];
+ size_t offset = [startingPos unsignedLongValue];
+ _parser->data = env;
- http_parser_execute(_parser, data, length, offset);
- if (http_parser_has_error(_parser)) {
- [NSException raise:@"CTParserError" format:@"Invalid HTTP format, parsing failed."];
- }
+ http_parser_execute(_parser, data, length, offset);
+ if (http_parser_has_error(_parser)) {
+ [NSException raise:@"CTParserError"
+ format:@"Invalid HTTP format, parsing failed."];
+ }
- NSNumber *headerLength = [NSNumber numberWithUnsignedLong:_parser->nread];
- VALIDATE_MAX_LENGTH([headerLength unsignedLongValue], HEADER);
- return headerLength;
+ NSNumber *headerLength = [NSNumber numberWithUnsignedLong:_parser->nread];
+ VALIDATE_MAX_LENGTH([headerLength unsignedLongValue], HEADER);
+ return headerLength;
}
- (NSNumber *)parseData:(NSData *)dataBuf forEnvironment:(NSDictionary *)env
{
- return [self parseData:dataBuf forEnvironment:env startingAt:0];
+ return [self parseData:dataBuf forEnvironment:env startingAt:0];
}
- (BOOL)errorCond
{
- return http_parser_has_error(_parser);
+ return http_parser_has_error(_parser);
}
- (BOOL)finished
{
- return http_parser_is_finished(_parser);
+ return http_parser_is_finished(_parser);
}
- (NSNumber *)nread
{
- return [NSNumber numberWithInt:_parser->nread];
+ return [NSNumber numberWithInt:_parser->nread];
}
- (void)finalize
{
- if (_parser != NULL)
- free(_parser);
- [super finalize];
+ if (_parser != NULL) {
+ free(_parser);
+ _parser = NULL;
+ }
+ [super finalize];
}
@end
@@ -194,6 +221,6 @@
void
Init_CTParser(void)
{
- // Do nothing. This function is required by the MacRuby runtime when this
- // file is compiled as a C extension bundle.
+ // Do nothing. This function is required by the MacRuby runtime when this
+ // file is compiled as a C extension bundle.
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100625/9dc07ff1/attachment-0001.html>
More information about the macruby-changes
mailing list