From 7ac47ed9fcaef5fa5c140363a78fa095c5d91797 Mon Sep 17 00:00:00 2001 From: helge Date: Wed, 16 Nov 2005 13:26:01 +0000 Subject: [PATCH] added mod_objc git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1175 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- Recycler/ApacheWO/.cvsignore | 4 + Recycler/ApacheWO/20040608 | 0 Recycler/ApacheWO/AWODirectoryConfig.h | 27 + Recycler/ApacheWO/AWODirectoryConfig.m | 137 +++ Recycler/ApacheWO/AWOServerConfig.h | 22 + Recycler/ApacheWO/AWOServerConfig.m | 104 +++ Recycler/ApacheWO/AliasMap.h | 40 + Recycler/ApacheWO/AliasMap.m | 139 +++ Recycler/ApacheWO/ApacheCommands.plist | 46 + Recycler/ApacheWO/ApacheHandlers.plist | 20 + Recycler/ApacheWO/ApacheResourceManager.h | 26 + Recycler/ApacheWO/ApacheResourceManager.m | 227 +++++ Recycler/ApacheWO/ApacheWO+Echo.m | 61 ++ Recycler/ApacheWO/ApacheWO+Echo2.m | 65 ++ Recycler/ApacheWO/ApacheWO+RequestHandler.m | 83 ++ Recycler/ApacheWO/ApacheWO+hooks.m | 76 ++ Recycler/ApacheWO/ApacheWO+woxpage.m | 144 +++ Recycler/ApacheWO/ApacheWO.h | 30 + Recycler/ApacheWO/ApacheWO.m | 115 +++ Recycler/ApacheWO/ApacheWOTransaction.h | 47 + Recycler/ApacheWO/ApacheWOTransaction.m | 116 +++ Recycler/ApacheWO/ChangeLog | 5 + Recycler/ApacheWO/GNUmakefile | 46 + Recycler/ApacheWO/README | 17 + Recycler/ApacheWO/TestApp/GNUmakefile | 12 + Recycler/ApacheWO/TestApp/TestApp.m | 9 + Recycler/ApacheWO/WOComponent+Apache.m | 35 + Recycler/ApacheWO/WORequest+Apache.h | 16 + Recycler/ApacheWO/WORequest+Apache.m | 117 +++ Recycler/ApacheWO/WORequestHandler+Apache.h | 17 + Recycler/ApacheWO/WORequestHandler+Apache.m | 28 + Recycler/ApacheWO/WOResponse+Apache.h | 20 + Recycler/ApacheWO/WOResponse+Apache.m | 146 +++ Recycler/ApacheWO/common.h | 4 + Recycler/ApacheWO/docs/Embed.wox | 6 + Recycler/ApacheWO/docs/Frame.wox | 27 + Recycler/ApacheWO/docs/Page2.wox | 19 + Recycler/ApacheWO/docs/Page3.wox | 32 + Recycler/ApacheWO/docs/RqInfo.wox | 59 ++ Recycler/ApacheWO/docs/SSIPage.shtml | 17 + Recycler/ApacheWO/docs/SlowMarket.gif | Bin 0 -> 16479 bytes Recycler/ApacheWO/docs/Table.wox | 42 + .../ApacheWO/docs/WoPage1.wo/WoPage1.html | 9 + Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.js | 19 + Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.wod | 18 + Recycler/ApacheWO/docs/bigimg.gif | Bin 0 -> 15906 bytes Recycler/ApacheWO/docs/imgs/SlowMarket.wox | 6 + Recycler/ApacheWO/docs/renameme-.htaccess | 25 + Recycler/ApacheWO/docs/requests.wox | 84 ++ .../ApacheWO/docs/subdir/renameme-.htaccess | 3 + Recycler/ApacheWO/docs/subdir/test.wox | 8 + Recycler/ApacheWO/docs/test.html | 19 + Recycler/ApacheWO/docs/test.wox | 46 + Recycler/ApacheWO/docs/wa.rqh | 3 + Recycler/ApacheWO/docs/xmlrpc.rqh | 3 + Recycler/ApacheWO/httpd.conf | 77 ++ Recycler/ApacheWO/httpd.sh | 5 + .../mod_objc/ApModuleBaseClass+Callbacks.m | 396 ++++++++ Recycler/mod_objc/ApModuleBaseClass+Cmds.m | 864 ++++++++++++++++++ Recycler/mod_objc/ApModuleBaseClass+Handler.m | 359 ++++++++ Recycler/mod_objc/ApModuleBaseClass.h | 66 ++ Recycler/mod_objc/ApModuleBaseClass.m | 129 +++ Recycler/mod_objc/ApTest.m | 101 ++ Recycler/mod_objc/ApacheCmdParms.h | 33 + Recycler/mod_objc/ApacheCmdParms.m | 66 ++ Recycler/mod_objc/ApacheConnection.h | 46 + Recycler/mod_objc/ApacheConnection.m | 110 +++ Recycler/mod_objc/ApacheModule.h | 116 +++ Recycler/mod_objc/ApacheModule.m | 59 ++ Recycler/mod_objc/ApacheObject.h | 27 + Recycler/mod_objc/ApacheObject.m | 79 ++ Recycler/mod_objc/ApacheRequest.h | 200 ++++ Recycler/mod_objc/ApacheRequest.m | 457 +++++++++ Recycler/mod_objc/ApacheResourcePool.h | 134 +++ Recycler/mod_objc/ApacheResourcePool.m | 179 ++++ Recycler/mod_objc/ApacheServer.h | 57 ++ Recycler/mod_objc/ApacheServer.m | 151 +++ Recycler/mod_objc/ApacheTable.h | 28 + Recycler/mod_objc/ApacheTable.m | 50 + Recycler/mod_objc/GNUmakefile | 50 + Recycler/mod_objc/GSBundleModule.m | 407 +++++++++ Recycler/mod_objc/README | 7 + Recycler/mod_objc/genApacheModule.sh | 146 +++ Recycler/mod_objc/mod_gsbundle.m | 91 ++ Recycler/mod_objc/test.conf | 121 +++ 85 files changed, 7057 insertions(+) create mode 100644 Recycler/ApacheWO/.cvsignore create mode 100644 Recycler/ApacheWO/20040608 create mode 100644 Recycler/ApacheWO/AWODirectoryConfig.h create mode 100644 Recycler/ApacheWO/AWODirectoryConfig.m create mode 100644 Recycler/ApacheWO/AWOServerConfig.h create mode 100644 Recycler/ApacheWO/AWOServerConfig.m create mode 100644 Recycler/ApacheWO/AliasMap.h create mode 100644 Recycler/ApacheWO/AliasMap.m create mode 100644 Recycler/ApacheWO/ApacheCommands.plist create mode 100644 Recycler/ApacheWO/ApacheHandlers.plist create mode 100644 Recycler/ApacheWO/ApacheResourceManager.h create mode 100644 Recycler/ApacheWO/ApacheResourceManager.m create mode 100644 Recycler/ApacheWO/ApacheWO+Echo.m create mode 100644 Recycler/ApacheWO/ApacheWO+Echo2.m create mode 100644 Recycler/ApacheWO/ApacheWO+RequestHandler.m create mode 100644 Recycler/ApacheWO/ApacheWO+hooks.m create mode 100644 Recycler/ApacheWO/ApacheWO+woxpage.m create mode 100644 Recycler/ApacheWO/ApacheWO.h create mode 100644 Recycler/ApacheWO/ApacheWO.m create mode 100644 Recycler/ApacheWO/ApacheWOTransaction.h create mode 100644 Recycler/ApacheWO/ApacheWOTransaction.m create mode 100644 Recycler/ApacheWO/ChangeLog create mode 100644 Recycler/ApacheWO/GNUmakefile create mode 100644 Recycler/ApacheWO/README create mode 100644 Recycler/ApacheWO/TestApp/GNUmakefile create mode 100644 Recycler/ApacheWO/TestApp/TestApp.m create mode 100644 Recycler/ApacheWO/WOComponent+Apache.m create mode 100644 Recycler/ApacheWO/WORequest+Apache.h create mode 100644 Recycler/ApacheWO/WORequest+Apache.m create mode 100644 Recycler/ApacheWO/WORequestHandler+Apache.h create mode 100644 Recycler/ApacheWO/WORequestHandler+Apache.m create mode 100644 Recycler/ApacheWO/WOResponse+Apache.h create mode 100644 Recycler/ApacheWO/WOResponse+Apache.m create mode 100644 Recycler/ApacheWO/common.h create mode 100644 Recycler/ApacheWO/docs/Embed.wox create mode 100644 Recycler/ApacheWO/docs/Frame.wox create mode 100644 Recycler/ApacheWO/docs/Page2.wox create mode 100644 Recycler/ApacheWO/docs/Page3.wox create mode 100644 Recycler/ApacheWO/docs/RqInfo.wox create mode 100644 Recycler/ApacheWO/docs/SSIPage.shtml create mode 100644 Recycler/ApacheWO/docs/SlowMarket.gif create mode 100644 Recycler/ApacheWO/docs/Table.wox create mode 100644 Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.html create mode 100644 Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.js create mode 100644 Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.wod create mode 100644 Recycler/ApacheWO/docs/bigimg.gif create mode 100644 Recycler/ApacheWO/docs/imgs/SlowMarket.wox create mode 100644 Recycler/ApacheWO/docs/renameme-.htaccess create mode 100644 Recycler/ApacheWO/docs/requests.wox create mode 100644 Recycler/ApacheWO/docs/subdir/renameme-.htaccess create mode 100644 Recycler/ApacheWO/docs/subdir/test.wox create mode 100644 Recycler/ApacheWO/docs/test.html create mode 100644 Recycler/ApacheWO/docs/test.wox create mode 100644 Recycler/ApacheWO/docs/wa.rqh create mode 100644 Recycler/ApacheWO/docs/xmlrpc.rqh create mode 100644 Recycler/ApacheWO/httpd.conf create mode 100755 Recycler/ApacheWO/httpd.sh create mode 100644 Recycler/mod_objc/ApModuleBaseClass+Callbacks.m create mode 100644 Recycler/mod_objc/ApModuleBaseClass+Cmds.m create mode 100644 Recycler/mod_objc/ApModuleBaseClass+Handler.m create mode 100644 Recycler/mod_objc/ApModuleBaseClass.h create mode 100644 Recycler/mod_objc/ApModuleBaseClass.m create mode 100644 Recycler/mod_objc/ApTest.m create mode 100644 Recycler/mod_objc/ApacheCmdParms.h create mode 100644 Recycler/mod_objc/ApacheCmdParms.m create mode 100644 Recycler/mod_objc/ApacheConnection.h create mode 100644 Recycler/mod_objc/ApacheConnection.m create mode 100644 Recycler/mod_objc/ApacheModule.h create mode 100644 Recycler/mod_objc/ApacheModule.m create mode 100644 Recycler/mod_objc/ApacheObject.h create mode 100644 Recycler/mod_objc/ApacheObject.m create mode 100644 Recycler/mod_objc/ApacheRequest.h create mode 100644 Recycler/mod_objc/ApacheRequest.m create mode 100644 Recycler/mod_objc/ApacheResourcePool.h create mode 100644 Recycler/mod_objc/ApacheResourcePool.m create mode 100644 Recycler/mod_objc/ApacheServer.h create mode 100644 Recycler/mod_objc/ApacheServer.m create mode 100644 Recycler/mod_objc/ApacheTable.h create mode 100644 Recycler/mod_objc/ApacheTable.m create mode 100644 Recycler/mod_objc/GNUmakefile create mode 100644 Recycler/mod_objc/GSBundleModule.m create mode 100644 Recycler/mod_objc/README create mode 100755 Recycler/mod_objc/genApacheModule.sh create mode 100644 Recycler/mod_objc/mod_gsbundle.m create mode 100644 Recycler/mod_objc/test.conf diff --git a/Recycler/ApacheWO/.cvsignore b/Recycler/ApacheWO/.cvsignore new file mode 100644 index 00000000..e0d38cd4 --- /dev/null +++ b/Recycler/ApacheWO/.cvsignore @@ -0,0 +1,4 @@ +*.apache +*_module_structure.m +logs +shared_debug_obj diff --git a/Recycler/ApacheWO/20040608 b/Recycler/ApacheWO/20040608 new file mode 100644 index 00000000..e69de29b diff --git a/Recycler/ApacheWO/AWODirectoryConfig.h b/Recycler/ApacheWO/AWODirectoryConfig.h new file mode 100644 index 00000000..567bffc8 --- /dev/null +++ b/Recycler/ApacheWO/AWODirectoryConfig.h @@ -0,0 +1,27 @@ +// $Id: AWODirectoryConfig.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __AWODirectoryConfig_H__ +#define __AWODirectoryConfig_H__ + +#import + +@class WOApplication, WORequestHandler; +@class ApacheResourcePool, ApacheCmdParms; + +@interface AWODirectoryConfig : NSObject +{ + WOApplication *application; + WORequestHandler *rqHandler; +} + +/* configuration */ + +- (void)setApplication:(WOApplication *)_app; +- (WOApplication *)application; + +- (void)setRequestHandler:(WORequestHandler *)_handler; +- (WORequestHandler *)requestHandler; + +@end + +#endif /* __AWODirectoryConfig_H__ */ diff --git a/Recycler/ApacheWO/AWODirectoryConfig.m b/Recycler/ApacheWO/AWODirectoryConfig.m new file mode 100644 index 00000000..33eb7454 --- /dev/null +++ b/Recycler/ApacheWO/AWODirectoryConfig.m @@ -0,0 +1,137 @@ +// $Id: AWODirectoryConfig.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "AWODirectoryConfig.h" +#include "ApacheWO.h" +#include +#include +#include +#include "common.h" + +@implementation AWODirectoryConfig + +- (id)init { + return self; +} + +- (id)initWithConfig:(AWODirectoryConfig *)_cfg { + if ((self = [self init])) { + self->application = [_cfg->application retain]; + self->rqHandler = [_cfg->rqHandler retain]; + } + return self; +} + +- (id)initWithBaseConfig:(AWODirectoryConfig *)_base + andConfig:(AWODirectoryConfig *)_new +{ + if ((self = [self initWithConfig:_base])) { + if (_new->application) + ASSIGN(self->application, _new->application); + if (_new->rqHandler) + ASSIGN(self->rqHandler, _new->rqHandler); + } + return self; +} + +- (void)dealloc { + RELEASE(self->application); + RELEASE(self->rqHandler); + [super dealloc]; +} ++ (id)mergeBaseConfig:(AWODirectoryConfig *)_base + withNewConfig:(AWODirectoryConfig *)_new +{ + return [[[self alloc] initWithBaseConfig:_base andConfig:_new] autorelease]; +} + +- (NSString *)stringValue { + return [self description]; +} +- (NSString *)description { + NSMutableString *ms; + id tmp; + + ms = [NSMutableString stringWithCapacity:64]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + + if ((tmp = [self application])) + [ms appendFormat:@" app=%@(0x%08X)", [(WOApplication *)tmp name], tmp]; + if ((tmp = [self requestHandler])) + [ms appendFormat:@" rqh=%@", tmp]; + + [ms appendString:@">"]; + return ms; +} + +/* configuration */ + +- (void)setApplication:(WOApplication *)_app { + ASSIGN(self->application, _app); +} +- (WOApplication *)application { + return self->application; +} + +- (void)setRequestHandler:(WORequestHandler *)_handler { + ASSIGN(self->rqHandler, _handler); +} +- (WORequestHandler *)requestHandler { + return self->rqHandler; +} + +/* commands */ + +- (id)SetSxApplication:(NSString *)_key { + WOApplication *app; + + if ((app = [self application])) { + [self logWithFormat:@"application already set !"]; + } + + if ((app = [ApacheWO applicationForKey:_key className:nil]) == nil) { + [self logWithFormat:@"got no application for key '%@'", _key]; + } + else { + [self setApplication:app]; + } + + return nil /* nil means 'no error' */; +} + +- (id)SetSxRequestHandler:(NSString *)_className { + WORequestHandler *rqh; + Class rqhClazz; + + if ((rqh = [self requestHandler])) { + [self logWithFormat:@"requestHandler already set !"]; + } + + if ((rqhClazz = NSClassFromString(_className)) == Nil) { + return [NSString stringWithFormat: + @"did not find request handler for class '%@'", + _className]; + } + + if ((rqh = [[rqhClazz alloc] init]) == nil) { + return [NSString stringWithFormat: + @"could not allocate request handler of class '%@'", + _className]; + } + + [self setRequestHandler:rqh]; + RELEASE(rqh); + + return nil /* nil means 'no error' */; +} + +- (id)LogText:(NSString *)_txt { + if ([_txt length] == 0) + /* return an error text */ + return @"missing echo text !"; + + //[self appendString:_txt]; + + return nil /* nil means 'no error' */; +} + +@end /* AWODirectoryConfig */ diff --git a/Recycler/ApacheWO/AWOServerConfig.h b/Recycler/ApacheWO/AWOServerConfig.h new file mode 100644 index 00000000..bf968e99 --- /dev/null +++ b/Recycler/ApacheWO/AWOServerConfig.h @@ -0,0 +1,22 @@ +// $Id: AWOServerConfig.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __AWOServerConfig_H__ +#define __AWOServerConfig_H__ + +#import + +@class AliasMap; +@class NSMutableDictionary, NSMutableArray; +@class WOApplication, WORequestHandler; +@class ApacheResourcePool, ApacheServer, ApacheCmdParms; + +@interface AWOServerConfig : NSObject +{ +@public + AliasMap *appAlias; + AliasMap *handlerAlias; +} + +@end + +#endif /* __AWOServerConfig_H__ */ diff --git a/Recycler/ApacheWO/AWOServerConfig.m b/Recycler/ApacheWO/AWOServerConfig.m new file mode 100644 index 00000000..9b2f20e6 --- /dev/null +++ b/Recycler/ApacheWO/AWOServerConfig.m @@ -0,0 +1,104 @@ +// $Id: AWOServerConfig.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "AWOServerConfig.h" +#include "AliasMap.h" +#include +#include +#include +#include +#include +#include "common.h" + +@implementation AWOServerConfig + +- (id)initWithServer:(ApacheServer *)_server { + //NSLog(@"%s: init with server: %@", __PRETTY_FUNCTION__, _server); + self->appAlias = [[AliasMap alloc] initWithCapacity:8]; + self->handlerAlias = [[AliasMap alloc] initWithCapacity:8]; + return self; +} + +- (id)initWithConfig:(AWOServerConfig *)_cfg { + if ((self = [self init])) { + self->appAlias = [[AliasMap alloc] initWithAliasMap:_cfg->appAlias]; + self->handlerAlias = + [[AliasMap alloc] initWithAliasMap:_cfg->handlerAlias]; + } + return self; +} + +- (id)initWithBaseConfig:(AWOServerConfig *)_base + andConfig:(AWOServerConfig *)_new +{ + if ((self = [self initWithConfig:_base])) { + [self->appAlias addEntriesFromAliasMap:_new->appAlias]; + [self->handlerAlias addEntriesFromAliasMap:_new->handlerAlias]; + } + return self; +} + +- (void)dealloc { + RELEASE(self->appAlias); + RELEASE(self->handlerAlias); + [super dealloc]; +} + ++ (id)mergeBaseConfig:(AWOServerConfig *)_base + withNewConfig:(AWOServerConfig *)_new +{ + return [[[self alloc] initWithBaseConfig:_base andConfig:_new] autorelease]; +} + +- (NSString *)stringValue { + return [self description]; +} +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:64]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + + [ms appendFormat:@" appAlias=%@", self->appAlias]; + + [ms appendString:@">"]; + return ms; +} + +/* commands */ + +- (id)SxApplicationAlias:(NSString *)_name:(NSString *)_uri { + NSString *tmp; + + if ((tmp = [self->appAlias uriForKey:_name baseURI:@"/"])) { + return [NSString stringWithFormat:@"app %@ already mapped to %@", + _name, tmp]; + } + + //[self logWithFormat:@"aliasing app %@ to %@", _name, _uri]; + + [self->appAlias mapKey:_name toURI:_uri]; + + return nil /* nil means 'no error' */; +} + +- (id)SxHandlerAlias:(NSString *)_handler:(NSString *)_uri { + NSString *tmp; + + if ((tmp = [self->handlerAlias uriForKey:_handler baseURI:@"/"])) { + return [NSString stringWithFormat:@"handler %@ already mapped to %@", + _handler, tmp]; + } + + //[self logWithFormat:@"aliasing handler %@ to %@", _handler, _uri]; + + [self->handlerAlias mapKey:_handler toURI:_uri]; + + return nil /* nil means 'no error' */; +} + +- (id)LoadBundle:(NSString *)_bundleName { + [self logWithFormat:@"should load bundle %@", _bundleName]; + return nil; +} + +@end /* AWOServerConfig */ diff --git a/Recycler/ApacheWO/AliasMap.h b/Recycler/ApacheWO/AliasMap.h new file mode 100644 index 00000000..0cb9225b --- /dev/null +++ b/Recycler/ApacheWO/AliasMap.h @@ -0,0 +1,40 @@ +// $Id: AliasMap.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __AliasMap_H__ +#define __AliasMap_H__ + +#import + +/* + An alias-map maps some kind of key to a URI. During lookups the + URI is processed to find the longest matching prefix. + + Note: a URI may be mapped to only one key, but a key can be mapped + to multiple URIs ! (key<->URI is 1:n) +*/ + +@class NSMutableDictionary, NSMutableArray; + +@interface AliasMap : NSObject < NSCopying > +{ + NSMutableArray *uris; + NSMutableDictionary *uri2key; + NSMutableDictionary *key2uris; +} + +- (id)initWithCapacity:(unsigned)_capacity; +- (id)initWithAliasMap:(AliasMap *)_map; + +/* modification */ + +- (BOOL)mapKey:(id)_key toURI:(NSString *)_uri; +- (BOOL)addEntriesFromAliasMap:(AliasMap *)_map; + +/* query */ + +- (id)keyForURI:(NSString *)_uri; +- (NSString *)uriForKey:(id)_key baseURI:(NSString *)_uri; + +@end + +#endif /* __AliasMap_H__ */ diff --git a/Recycler/ApacheWO/AliasMap.m b/Recycler/ApacheWO/AliasMap.m new file mode 100644 index 00000000..31e16891 --- /dev/null +++ b/Recycler/ApacheWO/AliasMap.m @@ -0,0 +1,139 @@ +// $Id: AliasMap.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "AliasMap.h" +#include "common.h" + +@implementation AliasMap + +- (id)initWithCapacity:(unsigned)_capacity { + self->uri2key = [[NSMutableDictionary alloc] initWithCapacity:_capacity]; + self->key2uris = [[NSMutableDictionary alloc] initWithCapacity:_capacity]; + self->uris = [[NSMutableArray alloc] initWithCapacity:_capacity]; + return self; +} +- (id)initWithAliasMap:(AliasMap *)_map { + self->uri2key = [_map->uri2key mutableCopy]; + self->key2uris = [_map->key2uris mutableCopy]; + self->uris = [_map->uris mutableCopy]; + return self; +} + +- (id)init { + return [self initWithCapacity:16]; +} + +- (void)dealloc { + RELEASE(self->key2uris); + RELEASE(self->uri2key); + RELEASE(self->uris); + [super dealloc]; +} + +/* modification */ + +- (BOOL)mapKey:(id)_key toURI:(NSString *)_uri { + id tmp; + NSMutableArray *kuris; + + if (_uri == nil) return NO; + if (_key == nil) return NO; + + if ((tmp = [self->uri2key objectForKey:_uri])) + /* already mapped !!! */ + return NO; + + [self->uri2key setObject:_key forKey:_uri]; + [self->uris addObject:_uri]; + + if ((kuris = [self->key2uris objectForKey:_key]) == nil) + kuris = [[NSMutableArray alloc] initWithCapacity:4]; + else + kuris = [kuris mutableCopy]; + + [kuris addObject:_uri]; + + [self->key2uris setObject:kuris forKey:_key]; + RELEASE(kuris); + + return YES; +} + +- (BOOL)addEntriesFromAliasMap:(AliasMap *)_map { + [self->uri2key addEntriesFromDictionary:_map->uri2key]; + [self->key2uris addEntriesFromDictionary:_map->key2uris]; + [self->uris addObjectsFromArray:_map->uris]; + return YES; +} + +/* query */ + +- (NSString *)longestMatchingURIForURI:(NSString *)_uri + fromArray:(NSArray *)_baseSet +{ + NSEnumerator *e; + NSString *auri, *longest = nil; + unsigned max = 0, len; + + if ((len = [_uri length]) == 0) + return nil; + + /* foreach registered URI */ + e = [_baseSet objectEnumerator]; + + while ((auri = [e nextObject])) { + unsigned l = [auri length]; + + /* quick precondition: prefix can't be longer than the string .. */ + if (l > len) + continue; + + if ([_uri hasPrefix:auri]) { + if (len == l) /* found an exact match */ + return auri; + + if (l > max) { /* found a new longer uri ... */ + longest = auri; + max = len; + } + } + } + + return longest; +} + +- (id)keyForURI:(NSString *)_uri { + NSString *aliasURI; + + aliasURI = [self longestMatchingURIForURI:_uri fromArray:self->uris]; + if ([aliasURI length] == 0) + return nil; + + return [self->uri2key objectForKey:aliasURI]; +} + +- (NSString *)uriForKey:(id)_key baseURI:(NSString *)_uri { + NSArray *kuris; + NSString *aliasURI; + unsigned kcount; + + kuris = [self->key2uris objectForKey:_key]; + if ((kcount = [kuris count] == 0)) + return nil; + + if (kcount == 1) /* only one possibility */ + aliasURI = [kuris objectAtIndex:0]; + else { + aliasURI = [self longestMatchingURIForURI:_uri fromArray:kuris]; + NSAssert(aliasURI != nil, @"no matching URI in structure ???"); + } + + return aliasURI; +} + +/* copying */ + +- (id)copyWithZone:(NSZone *)_zone { + return [[AliasMap alloc] initWithAliasMap:self]; +} + +@end /* AliasMap */ diff --git a/Recycler/ApacheWO/ApacheCommands.plist b/Recycler/ApacheWO/ApacheCommands.plist new file mode 100644 index 00000000..49569660 --- /dev/null +++ b/Recycler/ApacheWO/ApacheCommands.plist @@ -0,0 +1,46 @@ +{ + DirectoryConfigClass = "AWODirectoryConfig"; + ServerConfigClass = "AWOServerConfig"; + + /* directory config */ + SetSxApplication = { + selector = "SetSxApplication:"; + overrides = ( ACCESS_CONF, OR_OPTIONS ); + argspec = "TAKE1"; + usage = "usage: SetSxApplication "; + }; + SetSxRequestHandler = { + selector = "SetSxRequestHandler:"; + overrides = ( ACCESS_CONF, OR_OPTIONS ); + argspec = "TAKE1"; + usage = "usage: SetSxRequestHandler "; + }; + LogText = { + selector = "LogText:"; + overrides = ( ACCESS_CONF, OR_OPTIONS ); + argspec = "TAKE1"; + usage = "usage: LogText "; + }; + + /* server config */ + + LoadBundle = { + selector = "LoadBundle:"; + overrides = ( RSRC_CONF ); + argspec = "TAKE1"; + usage = "usage: LoadBundle "; + }; + + SxApplicationAlias = { + selector = "SxApplicationAlias::"; + overrides = ( RSRC_CONF ); + argspec = "TAKE2"; + usage = "usage: SxApplicationAlias "; + }; + SxHandlerAlias = { + selector = "SxHandlerAlias::"; + overrides = ( RSRC_CONF ); + argspec = "TAKE2"; + usage = "usage: SxHandlerAlias "; + }; +} diff --git a/Recycler/ApacheWO/ApacheHandlers.plist b/Recycler/ApacheWO/ApacheHandlers.plist new file mode 100644 index 00000000..2b42d6dd --- /dev/null +++ b/Recycler/ApacheWO/ApacheHandlers.plist @@ -0,0 +1,20 @@ +{ + CVSID="$Id: ApacheHandlers.plist,v 1.1 2004/06/08 11:06:00 helge Exp $"; + + /* Note: only lowercase letters are allowed in handler names ! */ + + Name2Selector = { + "objc-echo" = "performObjcEchoRequest:"; + "sx-handler" = "performSxHandlerRequest:config:"; + "wox-page" = "performWoxPageRequest:"; + "sx-alias-handler" = "performSxAliasHandlerRequest:"; + }; + + MimeType2Selector = { + "application/x-httpd-wox" = "performWoxPageRequest:"; + "application/x-httpd-wo" = "handleApplicationXHttpdWoRequest:config:"; + "httpd/unix-directory" = "handleDirectoryRequest:config:"; + "skyrix/request-handler" = "handleSkyrixRqHandler:config:"; +// "*/*" = "handleGenericRequest:config:"; + }; +} diff --git a/Recycler/ApacheWO/ApacheResourceManager.h b/Recycler/ApacheWO/ApacheResourceManager.h new file mode 100644 index 00000000..89ed51e0 --- /dev/null +++ b/Recycler/ApacheWO/ApacheResourceManager.h @@ -0,0 +1,26 @@ +// $Id: ApacheResourceManager.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __ApacheResourceManager_H__ +#define __ApacheResourceManager_H__ + +#include + +@class NSMutableDictionary; +@class ApacheRequest; +@class AWODirectoryConfig; +@class WOComponent; + +@interface ApacheResourceManager : WOResourceManager +{ + ApacheRequest *request; + AWODirectoryConfig *config; + NSMutableDictionary *nameToURL; + WOComponent *component; /* non-retained */ +} + +- (id)initWithApacheRequest:(ApacheRequest *)_rq + config:(AWODirectoryConfig *)_cfg; + +@end + +#endif /* __ApacheResourceManager_H__ */ diff --git a/Recycler/ApacheWO/ApacheResourceManager.m b/Recycler/ApacheWO/ApacheResourceManager.m new file mode 100644 index 00000000..5967f92c --- /dev/null +++ b/Recycler/ApacheWO/ApacheResourceManager.m @@ -0,0 +1,227 @@ +// $Id: ApacheResourceManager.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheResourceManager.h" +#include "AWODirectoryConfig.h" +#include +#include +#include +#include +#include +#include +#include "common.h" + +@interface NSObject(UsedARPrivates) + +- (void)setComponentClass:(Class)_class; + +- (id)_definitionWithName:(NSString *)_name + url:(NSURL *)_url + baseURL:(NSURL *)_burl + frameworkName:(NSString *)_fwname; + +@end + +@implementation ApacheResourceManager + +static NSMutableDictionary *md = nil; + +- (id)initWithURI:(NSString *)_uri { + return self; +} ++ (id)resourceManagerForURI:(NSString *)_uri { + ApacheResourceManager *rm; + NSRange r; + + if ([_uri length] > 1) { + r = [_uri rangeOfString:@"/" options:NSBackwardsSearch]; + if (r.length == 0) { + NSLog(@"%s: strange uri: %@", __PRETTY_FUNCTION__, _uri); + return nil; + } + + _uri = [_uri substringToIndex:(r.location + r.length)]; + } + + if ((rm = [md objectForKey:_uri])) + return rm; + + if ((rm = [[ApacheResourceManager alloc] initWithURI:_uri]) == nil) + return nil; + + if (md == nil) + md = [[NSMutableDictionary alloc] init]; + [md setObject:rm forKey:_uri]; + return AUTORELEASE(rm); +} + +- (id)initWithApacheRequest:(ApacheRequest *)_rq + config:(AWODirectoryConfig *)_cfg +{ + self->request = [_rq retain]; + self->config = [_cfg retain]; + return self; +} +- (void)dealloc { + RELEASE(self->nameToURL); + RELEASE(self->request); + RELEASE(self->config); + [super dealloc]; +} + +/* URLs */ + +- (NSURL *)refererURL { + id rurl; + + if ((rurl = [[self->request headersIn] objectForKey:@"Referer"])) + rurl = [NSURL URLWithString:rurl]; + return rurl; +} + +- (NSURL *)requestURL { + ApacheServer *srv = [self->request server]; + id rurl; + + rurl = [NSString stringWithFormat:@"http://%@:%i%@", + [srv serverHostName], + [srv port], + [self->request uri]]; + rurl = [NSURL URLWithString:rurl]; + return rurl; +} + +/* operations */ + +- (NSURL *)_templateBaseURLForComponentNamed:(id)_name { + ApacheRequest *srq; + NSURL *url = nil; + + if (_name == nil || [_name isEqual:[self->request uri]]) + return [self requestURL]; + + if ([_name isKindOfClass:[NSURL class]]) { + srq = [self->request subRequestLookupURI:[_name uri]]; + } + else { + if ([[_name pathExtension] length] == 0) + _name = [_name stringByAppendingPathExtension:@"wox"]; + + srq = [self->request subRequestLookupURI:_name]; + } + + if ([srq doesFileExist]) { + url = [[[NSURL alloc] initWithString:[srq uri] + relativeToURL:[self requestURL]] + autorelease]; + } + else { + [self logWithFormat:@"file does not exist: %@ (%@)", + [srq filename], [srq fileType]]; + } + return url; +} + +- (id)definitionForComponent:(id)_name + languages:(NSArray *)_languages +{ + id cdef; + NSURL *url, *baseURL; + + if ((baseURL = [self->nameToURL objectForKey:_name]) == nil) { + //[self logWithFormat:@"def for component: %@)", _name]; + + if ((baseURL = [self _templateBaseURLForComponentNamed:_name]) == nil) { + [self logWithFormat:@"did not find template URL for component %@",_name]; + return nil; + } + + if (self->nameToURL == nil) + self->nameToURL = [[NSMutableDictionary alloc] initWithCapacity:16]; + + [self->nameToURL setObject:baseURL forKey:_name]; + } + + /* lookup file for URI */ + + if (baseURL == nil) + return nil; + else if ([baseURL isFileURL]) { + [self logWithFormat:@"baseURL(%@) cannot be a file URL !", baseURL]; +#if DEBUG + exit(1); +#endif + } + else { + ApacheRequest *srq; + NSString *fn; + + fn = [baseURL path]; +#if DEBUG + if ([fn indexOfString:@"INTERNALLY GENERATED"] != NSNotFound) { + [self logWithFormat:@"baseURL(%@) broken !", baseURL]; + exit(2); + } +#endif + + //[self logWithFormat:@"LOOKUP: %@", fn]; + srq = [self->request subRequestLookupURI:[baseURL path] method:@"HEAD"]; + + fn = [srq filename]; + //[self logWithFormat:@"File: %@", fn]; + + url = [[[NSURL alloc] initFileURLWithPath:fn] autorelease]; + + //NSLog(@"mapped:\n base %@\n content %@", baseURL, url); + } + + /* create definition */ + + cdef = [self _definitionWithName:_name + url:url + baseURL:baseURL + frameworkName:nil]; + + [cdef setComponentClass:[WOComponent class]]; + + return cdef; +} + +- (NSString *)urlForResourceNamed:(NSString *)_name + inFramework:(NSString *)_frameworkName + languages:(NSArray *)_languages + request:(WORequest *)_request +{ + NSURL *compURL, *rURL; + + //[self logWithFormat:@"URL for resource named %@", _name]; + + if ((compURL = [self->component baseURL]) == nil) { + compURL = [[[[WOApplication application] context] component] baseURL]; + + if (compURL) { +#if 0 + [self logWithFormat:@"use current component URL: %@", + [compURL absoluteString]]; +#endif + } + } + + if (compURL == nil) { + compURL = [[[WOApplication application] context] baseURL]; + if (self->component) + [self logWithFormat:@"component has no base, using context: %@", + [compURL absoluteString]]; + else + [self logWithFormat:@"using component URL as base: %@", + [compURL absoluteString]]; + } + + //[self logWithFormat:@" relative to %@", [compURL absoluteString]]; + + rURL = [NSURL URLWithString:_name relativeToURL:compURL]; + //[self logWithFormat:@" URL: %@", [rURL absoluteString]]; + + return [rURL absoluteString]; +} + +@end /* ApacheResourceManager */ diff --git a/Recycler/ApacheWO/ApacheWO+Echo.m b/Recycler/ApacheWO/ApacheWO+Echo.m new file mode 100644 index 00000000..d1565234 --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO+Echo.m @@ -0,0 +1,61 @@ +// $Id: ApacheWO+Echo.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheWO.h" +#include "common.h" +#include + +@implementation ApacheWO(EchoHandler) + +- (int)performObjcEchoRequest:(ApacheRequest *)_rq { + NSAutoreleasePool *pool; + id cfg; + NSString *s; + + pool = [[NSAutoreleasePool alloc] init]; + + /* get directory specific info ! */ + cfg = [self configForDirectory:_rq]; + + [self performWoxPageRequest:_rq]; + + NSLog(@"CFG: %@", cfg); + + /* setup header */ + [_rq setContentType:@"text/html"]; + + /* send header to client */ + [_rq sendHttpHeader]; + + /* send body to client */ + [_rq rputs:"

\n"]; + [_rq rputs:"echo !"]; + [_rq rputs:"

\n"]; + + s = [cfg stringValue]; + if ([s length] > 0) + [_rq rputs:[s cString]]; + [_rq rputs:"
\n\n"]; + + [_rq rputs:"URI:
"];
+  [_rq rputs:[[_rq uri] cString]];
+  [_rq rputs:"
\n"]; + + [_rq rputs:"description:
"];
+  [_rq rputs:[[_rq description] cString]];
+  [_rq rputs:"
\n"]; + + [_rq rputs:"headers-in:
"];
+  [_rq rputs:[[[_rq headersIn] description] cString]];
+  [_rq rputs:"
\n"]; + + [_rq rputs:"headers-in-dict:
"];
+  [_rq rputs:[[[[_rq headersIn] asDictionary] description] cString]];
+  [_rq rputs:"
\n"]; + + RELEASE(pool); + + /* say we are done ... */ + return ApacheHandledRequest; +} + +@end /* ApacheWO(EchoHandler) */ diff --git a/Recycler/ApacheWO/ApacheWO+Echo2.m b/Recycler/ApacheWO/ApacheWO+Echo2.m new file mode 100644 index 00000000..97db9ee9 --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO+Echo2.m @@ -0,0 +1,65 @@ +// $Id: ApacheWO+Echo2.m,v 1.1 2004/06/14 15:02:00 helge Exp $ + +#include "ApacheWO.h" +#include "AWODirectoryConfig.h" +#include "ApacheResourceManager.h" +#include "WORequest+Apache.h" +#include "WOResponse+Apache.h" +#include +#include "common.h" + +@implementation ApacheWO(Echo2Handler) + +- (WOResponse *)echoResponseForRequest:(WORequest *)woRequest + apacheRequest:(ApacheRequest *)_rq + config:(id)cfg +{ + WOResponse *woResponse; + + [self logWithFormat:@"generated response was .."]; + woResponse = [[[WOResponse alloc] initWithRequest:woRequest] autorelease]; + + /* construct response */ + + [woResponse setHeader:@"text/html" forKey:@"content-type"]; + [woResponse appendContentString:@"

WOResponse Content

"]; + + [woResponse appendContentHTMLString:[cfg stringValue]]; + [woResponse appendContentString:@"
\n\n"]; + + [woResponse appendContentString:@"URI:
"];
+  [woResponse appendContentHTMLString:[woRequest uri]];
+  [woResponse appendContentString:@"
\n"]; + + [woResponse appendContentString:@"Description:
"];
+  [woResponse appendContentHTMLString:[woRequest description]];
+  [woResponse appendContentString:@"
\n"]; + + [woResponse appendContentString:@"Request Headers:
"];
+  [woResponse appendContentHTMLString:[[woRequest headers] description]];
+  [woResponse appendContentString:@"
\n"]; + + [woResponse appendApacheResponseInfo: + [_rq subRequestLookupURI:@"/docs/subdir/test.wox"]]; + [woResponse appendContentString:@"
"]; + + [woResponse appendApacheResponseInfo: + [_rq subRequestLookupFile:@"test.wox"]]; + [woResponse appendContentString:@"
"]; + + [woResponse appendApacheResponseInfo: + [_rq subRequestLookupURI:@"/docs/subdir/non_existent.wox"]]; + [woResponse appendContentString:@"
"]; + + [woResponse appendApacheResponseInfo: + [_rq subRequestLookupURI:@"/docs/subdir/"]]; + [woResponse appendContentString:@"
"]; + + [woResponse appendApacheResponseInfo: + [_rq subRequestLookupURI:@"/docs/bigimg.gif"]]; + [woResponse appendContentString:@"
"]; + + return woResponse; +} + +@end /* ApacheWO(Echo2Handler) */ diff --git a/Recycler/ApacheWO/ApacheWO+RequestHandler.m b/Recycler/ApacheWO/ApacheWO+RequestHandler.m new file mode 100644 index 00000000..3c84f8b9 --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO+RequestHandler.m @@ -0,0 +1,83 @@ +// $Id: ApacheWO+RequestHandler.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheWO.h" +#include "AWODirectoryConfig.h" +#include "ApacheResourceManager.h" +#include "WORequest+Apache.h" +#include "WOResponse+Apache.h" +#include "common.h" +#include +#include +#include + +/* + implements a WORequestHandler "dispatcher" + + All WORequestHandler classes are registered in the ApacheHandlers.plist + with the single dispatchRequest: selector. This method creates an object + of the request handler class and let it dispatch the request. +*/ + +@implementation ApacheWO(RequestHandler) + +- (int)dispatchRequest:(ApacheRequest *)_rq + usingHandlerNamed:(NSString *)_hname + inApplication:(WOApplication *)_app +{ + WORequestHandler *handler; + WORequest *woRequest; + WOResponse *woResponse; + int result; + + if ((handler = [_app requestHandlerForKey:_hname]) == nil) { + [self logWithFormat:@"did not find request handler for key '%@'", + _hname]; + return ApacheDeclineRequest; + } + + woRequest = [[[WORequest alloc] initWithApacheRequest:_rq] autorelease]; + + woResponse = [_app dispatchRequest:woRequest usingHandler:handler]; + + /* send response */ + + if (woResponse) + result = [woResponse sendResponseUsingApacheRequest:_rq]; + else + result = 500; + + return result; +} + +- (int)dispatchRequestHandler:(ApacheRequest *)_rq { + NSAutoreleasePool *pool; + AWODirectoryConfig *cfg; + WOApplication *app; + int result; + + if (_rq == NULL) + return ApacheDeclineRequest; + + pool = [[NSAutoreleasePool alloc] init]; + + /* get directory specific info (app, request-handler) ! */ + + cfg = [self configForDirectory:_rq]; + + if ((app = [cfg application]) == nil) { + [self logWithFormat:@"missing app .."]; + goto done; + } + + result = [self dispatchRequest:_rq + usingHandlerNamed:[_rq handler] + inApplication:app]; + + done: + RELEASE(pool); + + /* say we are done ... */ + return result; +} + +@end /* ApacheWO(WoxPageHandler) */ diff --git a/Recycler/ApacheWO/ApacheWO+hooks.m b/Recycler/ApacheWO/ApacheWO+hooks.m new file mode 100644 index 00000000..7072cf9c --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO+hooks.m @@ -0,0 +1,76 @@ +// $Id: ApacheWO+hooks.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheWO.h" +#include "AliasMap.h" +#include "AWOServerConfig.h" +#include +#include +#include "common.h" + +@implementation ApacheWO(Hooks) + +- (int)handleTranslationForRequest:(ApacheRequest *)_rq { + AWOServerConfig *cfg; + NSString *uri = [_rq uri]; + NSString *app, *rqh; + + cfg = [self configForServer:_rq]; + + //[self logWithFormat:@"translate URI '%@' (cfg=%@) ...", uri, cfg]; + + /* check handler aliases */ + + if ((rqh = [cfg->handlerAlias keyForURI:uri])) { + NSString *prefix; + + prefix = [cfg->handlerAlias uriForKey:rqh baseURI:uri]; + //[self logWithFormat:@"found handler: %@ (prefix=%@)", rqh, prefix]; + + [_rq setFilename:prefix]; + [_rq setPathInfo:[uri substringFromIndex:[prefix length]]]; + [_rq setHandler:@"sx-alias-handler"]; + return ApacheHandledRequest; + } + + /* check app aliases */ + + if ((app = [cfg->appAlias keyForURI:uri])) { + NSString *prefix; + + prefix = [cfg->appAlias uriForKey:app baseURI:uri]; + [self logWithFormat:@"found app: %@ (prefix=%@)", app, prefix]; + + [_rq setFilename:prefix]; + [_rq setPathInfo:[uri substringFromIndex:[prefix length]]]; + [_rq setHandler:@"sx-application"]; + return ApacheHandledRequest; + } + + return ApacheDeclineRequest; +} + +#if 0 +- (int)checkUserIdFromRequest:(ApacheRequest *)_req { + [self logWithFormat:@"check uid for URI '%@' ...", [_req uri]]; + return ApacheDeclineRequest; +} +#endif + +- (int)checkTypeForRequest:(ApacheRequest *)_req { + /* do not process .wo directories as simple directories .. */ + + //[self logWithFormat:@"check type for URI '%@' ...", [_req uri]]; + + if ([_req isDirectory]) { + NSString *fext; + + fext = [[[_req filename] lastPathComponent] pathExtension]; + if ([fext isEqualToString:@"wo"]) { + [_req setContentType:@"application/x-httpd-wo"]; + return ApacheHandledRequest; + } + } + return ApacheDeclineRequest; +} + +@end /* ApacheWO(Hooks) */ diff --git a/Recycler/ApacheWO/ApacheWO+woxpage.m b/Recycler/ApacheWO/ApacheWO+woxpage.m new file mode 100644 index 00000000..a106a7dd --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO+woxpage.m @@ -0,0 +1,144 @@ +// $Id: ApacheWO+woxpage.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheWO.h" +#include "AliasMap.h" +#include "WORequestHandler+Apache.h" +#include "AWODirectoryConfig.h" +#include "AWOServerConfig.h" +#include "ApacheWOTransaction.h" +#include "ApacheResourceManager.h" +#include "WORequest+Apache.h" +#include "WOResponse+Apache.h" +#include "common.h" +#include +#include +#include + +@interface WORequest(UsedPrivatesApache) +- (void)setRequestHandlerPath:(NSString *)_path; +- (ApacheRequest *)apacheRequest; +@end + +@interface ApacheWO(EchoResponseE) +- (WOResponse *)echoResponseForRequest:(WORequest *)woRequest + apacheRequest:(ApacheRequest *)_rq + config:(id)cfg; +@end + +@implementation ApacheWO(WoxPageHandler) + +- (int)performSxApplicationRequest:(ApacheRequest *)_rq { + AWOServerConfig *cfg; + NSString *uri = [_rq uri]; + NSString *appKey; + WOApplication *app; + WORequest *woRequest; + WOResponse *woResponse; + int result; + + if (uri == nil) + return ApacheDeclineRequest; + + woRequest = [[[WORequest alloc] initWithApacheRequest:_rq] autorelease]; + + cfg = [self configForServer:_rq]; + appKey = [cfg->appAlias keyForURI:uri]; + app = [ApacheWO applicationForKey:appKey className:nil]; + + [self logWithFormat:@"performSxApplicationRequest on app %@ ...", app]; + woResponse = [app dispatchRequest:woRequest]; + + /* send response */ + + if (woResponse) + result = [woResponse sendResponseUsingApacheRequest:_rq]; + else + result = 500; + + return result; +} + +- (int)performSxHandlerRequest:(ApacheRequest *)_rq + config:(AWODirectoryConfig *)cfg +{ + WORequestHandler *handler; + + if ((handler = [cfg requestHandler]) == nil) { + handler = [[cfg application] defaultRequestHandler]; + [self logWithFormat:@"using default request handler ..."]; + } + + return [[self currentWOTransaction] dispatchUsingHandler:handler]; +} + +- (int)performSxAliasHandlerRequest:(ApacheRequest *)_rq { + ApacheWOTransaction *tx; + WORequestHandler *handler; + NSString *key; + + tx = [self currentWOTransaction]; + key = [tx->serverConfig->handlerAlias keyForURI:[_rq uri]]; + handler = [[tx application] requestHandlerForKey:key]; + + return [tx dispatchUsingHandler:handler]; +} + +- (int)performWoxPageRequest:(ApacheRequest *)_rq { + WORequestHandler *rh; + WORequest *woRq; + + rh = [[[NSClassFromString(@"WOPageRequestHandler") alloc] init] autorelease]; + if (rh == nil) + [self logWithFormat:@"couldn't allocate page request handler .."]; + + /* fill request special vars */ + woRq = [[self currentWOTransaction] request]; + [woRq setHeader: [woRq uri] forKey:@"x-httpd-pagename"]; + [woRq setRequestHandlerPath:[[woRq uri] lastPathComponent]]; + + return [[self currentWOTransaction] dispatchUsingHandler:rh]; +} + +- (int)handleApplicationXHttpdWoRequest:(ApacheRequest *)_rq config:_cfg { + NSString *uri = [_rq uri]; + + [self logWithFormat:@"handleApplicationXHttpdWoxRequest (uri=%@) ...",uri]; + + /* remove the slash of .wo directories, deny access to contents .. */ + if ([uri hasSuffix:@".wo/"]) { + uri = [uri substringToIndex:([uri length] - 1)]; + [self logWithFormat:@"redirect to %@...", uri]; + + [[_rq headersOut] setObject:uri forKey:@"location"]; + [_rq setStatus:302]; + [_rq sendHttpHeader]; + return ApacheHandledRequest; /* redirect */ + } + + return [self performWoxPageRequest:_rq]; +} + +- (int)handleSkyrixRqHandler:(ApacheRequest *)_rq config:(id)_cfg { + NSDictionary *plist; + WORequestHandler *rh; + + plist = [NSDictionary dictionaryWithContentsOfFile:[_rq filename]]; + [self logWithFormat:@"plist: %@", plist]; + + if ((rh = [WORequestHandler requestHandlerForConfig:plist]) == nil) + return ApacheDeclineRequest; + + return [[self currentWOTransaction] dispatchUsingHandler:rh]; +} + +- (int)handleDirectoryRequest:(ApacheRequest *)_rq config:(id)_cfg { + [self logWithFormat:@"check directory: %@", [_rq filename]]; + return ApacheDeclineRequest; +} +- (int)handleGenericRequest:(ApacheRequest *)_rq config:(id)_cfg { + [self logWithFormat:@"(generic) check file: %@ (%@)", + [_rq filename], [_rq contentType]]; + return ApacheDeclineRequest; +} + +@end /* ApacheWO(WoxPageHandler) */ diff --git a/Recycler/ApacheWO/ApacheWO.h b/Recycler/ApacheWO/ApacheWO.h new file mode 100644 index 00000000..5ddbb85a --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO.h @@ -0,0 +1,30 @@ +// $Id: ApacheWO.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __ApacheWOMod_H__ +#define __ApacheWOMod_H__ + +#include + +@class NSString, NSMutableArray; +@class WOApplication; +@class ApacheWOTransaction; + +@interface ApacheWO : ApacheModule +{ + NSMutableArray *woTxStack; +} + +/* WO transactions */ + +- (ApacheWOTransaction *)currentWOTransaction; + +/* application management */ + ++ (WOApplication *)applicationForKey:(NSString *)_key + className:(NSString *)_className; + +@end + +#include "ApacheWOTransaction.h" + +#endif /* __ApacheWOMod_H__ */ diff --git a/Recycler/ApacheWO/ApacheWO.m b/Recycler/ApacheWO/ApacheWO.m new file mode 100644 index 00000000..9e69d6bd --- /dev/null +++ b/Recycler/ApacheWO/ApacheWO.m @@ -0,0 +1,115 @@ +// $Id: ApacheWO.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheWO.h" +#include "common.h" +#include +#include +#include + +@interface WOApplication(UsedPrivates) +- (id)initWithName:(NSString *)_name; +@end + +@implementation ApacheWO + +- (id)init { + if ((self = [super init])) { + self->woTxStack = [[NSMutableArray alloc] initWithCapacity:4]; + } + return self; +} +- (void)dealloc { + RELEASE(self->woTxStack); + [super dealloc]; +} + +/* transactions */ + +- (ApacheWOTransaction *)currentWOTransaction { + if ([self->woTxStack count] == 0) return nil; + return [self->woTxStack lastObject]; +} + +- (BOOL)willDispatchRequest:(ApacheRequest *)_rq { + /* this is called before a handler is invoked */ + ApacheWOTransaction *tx; + + if (![super willDispatchRequest:_rq]) + return NO; + + tx = [[ApacheWOTransaction alloc] + initWithApacheRequest:_rq + config:[self configForDirectory:_rq] + serverConfig:[self configForServer:_rq]]; + if (tx == nil) + return NO; + + //[self logWithFormat:@"pushing WO transaction: %@", tx]; + + [self->woTxStack addObject:tx]; + + [tx activate]; + + RELEASE(tx); + return YES; +} + +- (void)didDispatchRequest:(ApacheRequest *)_rq { + /* this is called after a handler was invoked */ + unsigned idx; + ApacheWOTransaction *tx; + + if ((idx = [self->woTxStack count]) == 0) { + [self logWithFormat: + @"tx stack broken, tried to pop tx from empty stack !"]; + return; + } + idx--; + + tx = RETAIN([self->woTxStack objectAtIndex:idx]); + //[self logWithFormat:@"popping WO transaction: %@.", tx]; + [tx deactivate]; + [self->woTxStack removeObjectAtIndex:idx]; + RELEASE(tx); +} + +/* application management */ + ++ (WOApplication *)applicationForKey:(NSString *)_key + className:(NSString *)_className +{ + static NSMutableDictionary *keyToApp = nil; // THREAD + WOApplication *app; + Class clazz; + + if (keyToApp == nil) + keyToApp = [[NSMutableDictionary alloc] initWithCapacity:16]; + + if ((app = [keyToApp objectForKey:_key])) + return app; + + if (_className == nil) _className = @"WOApplication"; + if ((clazz = NSClassFromString(_className)) == nil) { + [self logWithFormat:@"did not find class named '%@'", _className]; + return nil; + } + + if ((app = [[clazz alloc] initWithName:_key]) == nil) { + [self logWithFormat: + @"couldn't create instance for application of class %@", + clazz]; + return nil; + } + + /* resource managers are request dependend with our Apache module :-) */ + [app setResourceManager:nil]; + + //[self logWithFormat:@"added application %@ for key %@", app, _key]; + + [keyToApp setObject:app forKey:_key]; + RELEASE(app); + + return app; +} + +@end /* ApacheWO */ diff --git a/Recycler/ApacheWO/ApacheWOTransaction.h b/Recycler/ApacheWO/ApacheWOTransaction.h new file mode 100644 index 00000000..d8d62994 --- /dev/null +++ b/Recycler/ApacheWO/ApacheWOTransaction.h @@ -0,0 +1,47 @@ +// $Id: ApacheWOTransaction.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __ApacheWOTransaction_H__ +#define __ApacheWOTransaction_H__ + +#import + +@class ApacheRequest; +@class WORequest, WOResponse, WOApplication, WORequestHandler; +@class AWODirectoryConfig, AWOServerConfig; +@class ApacheResourceManager; + +@interface ApacheWOTransaction : NSObject +{ +@public + ApacheRequest *request; + WORequest *woRequest; + WOResponse *woResponse; + AWODirectoryConfig *config; + AWOServerConfig *serverConfig; + WOApplication *application; + ApacheResourceManager *resourceManager; +} + +- (id)initWithApacheRequest:(ApacheRequest *)_rq + config:(AWODirectoryConfig *)_cfg + serverConfig:(AWOServerConfig *)_srvcfg; + +/* accessors */ + +- (WORequest *)request; +- (WOResponse *)response; +- (WOApplication *)application; +- (ApacheRequest *)apacheRequest; + +/* activation */ + +- (void)activate; +- (void)deactivate; + +/* dispatch */ + +- (int)dispatchUsingHandler:(WORequestHandler *)_handler; + +@end + +#endif /* __ApacheWOTransaction_H__ */ diff --git a/Recycler/ApacheWO/ApacheWOTransaction.m b/Recycler/ApacheWO/ApacheWOTransaction.m new file mode 100644 index 00000000..1f8b2341 --- /dev/null +++ b/Recycler/ApacheWO/ApacheWOTransaction.m @@ -0,0 +1,116 @@ +// $Id: ApacheWOTransaction.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "ApacheWOTransaction.h" +#include "common.h" + +#include "AWODirectoryConfig.h" +#include "AWOServerConfig.h" +#include "ApacheResourceManager.h" +#include "WORequest+Apache.h" +#include "WOResponse+Apache.h" +#include +#include +#include +#include + +@implementation ApacheWOTransaction + +- (id)initWithApacheRequest:(ApacheRequest *)_rq + config:(AWODirectoryConfig *)_cfg + serverConfig:(AWOServerConfig *)_srvcfg +{ + if (_rq == nil) { + RELEASE(self); + return nil; + } + self->config = RETAIN(_cfg); + self->serverConfig = RETAIN(_srvcfg); + self->request = RETAIN(_rq); + + if ((self->woRequest = [[WORequest alloc] initWithApacheRequest:_rq])==nil) { + NSLog(@"%s: could not create WO request ...", __PRETTY_FUNCTION__); + RELEASE(self); + return nil; + } + + if ((self->application = [[_cfg application] retain]) == nil) { + NSLog(@"%s: no app is configured ...", __PRETTY_FUNCTION__); + RELEASE(self); + return nil; + } + + self->resourceManager = + [[ApacheResourceManager alloc] initWithApacheRequest:_rq config:_cfg]; + + if (self->resourceManager == nil) { + NSLog(@"%s: could not create resource manager ...", __PRETTY_FUNCTION__); + RELEASE(self); + return nil; + } + + return self; +} + +- (void)dealloc { + RELEASE(self->resourceManager); + RELEASE(self->woRequest); + RELEASE(self->woResponse); + RELEASE(self->application); + RELEASE(self->serverConfig); + RELEASE(self->config); + RELEASE(self->request); + [super dealloc]; +} + +/* accessors */ + +- (WOApplication *)application { + return [self->config application]; +} +- (WORequest *)request { + return self->woRequest; +} +- (WOResponse *)response { + return self->woResponse; +} + +- (ApacheRequest *)apacheRequest { + return self->request; +} + +/* activation */ + +- (void)activate { + [self->application activateApplication]; + // should use stack ?? + [self->application setResourceManager:self->resourceManager]; +} +- (void)deactivate { + [self->application setResourceManager:nil]; + [self->application deactivateApplication]; +} + +/* dispatch */ + +- (int)dispatchUsingHandler:(WORequestHandler *)_handler { + WOResponse *response; + + response = [self->application + dispatchRequest:self->woRequest + usingHandler:_handler]; + return [response sendResponseUsingApacheRequest:self->request]; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:64]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + [ms appendFormat:@" uri=%@", [[self request] uri]]; + [ms appendString:@">"]; + return ms; +} + +@end /* ApacheWOTransaction */ diff --git a/Recycler/ApacheWO/ChangeLog b/Recycler/ApacheWO/ChangeLog new file mode 100644 index 00000000..0c05d7e8 --- /dev/null +++ b/Recycler/ApacheWO/ChangeLog @@ -0,0 +1,5 @@ +2004-06-14 Helge Hess + + * created ChangeLog + + diff --git a/Recycler/ApacheWO/GNUmakefile b/Recycler/ApacheWO/GNUmakefile new file mode 100644 index 00000000..d38c8ef7 --- /dev/null +++ b/Recycler/ApacheWO/GNUmakefile @@ -0,0 +1,46 @@ +# $Id: GNUmakefile,v 1.2 2004/06/14 15:02:00 helge Exp $ + +include $(GNUSTEP_MAKEFILES)/common.make + +BUNDLE_NAME = ApacheWO + +ApacheWO_PRINCIPAL_CLASS = ApacheWO +BUNDLE_EXTENSION = .apache + +# NOTE: Ordering seems to be important !!! (sometimes the ObjC runtime +# doesn't find all categories ?!) +ApacheWO_OBJC_FILES += \ + ApacheWO+Echo.m \ + ApacheWO+woxpage.m \ + ApacheWO+Echo2.m \ + ApacheWO+hooks.m \ + ApacheWO+RequestHandler.m \ + ApacheWO.m \ + AWODirectoryConfig.m \ + AWOServerConfig.m \ + WORequest+Apache.m \ + WOResponse+Apache.m \ + WOComponent+Apache.m \ + WORequestHandler+Apache.m \ + ApacheResourceManager.m \ + AliasMap.m \ + ApacheWOTransaction.m \ + +ApacheWO_BUNDLE_LIBS += \ + -lApacheAPI \ + -lNGExtensions \ + -lNGObjWeb \ + +ApacheWO_RESOURCE_FILES = ApacheCommands.plist ApacheHandlers.plist + +# auto info + +ApacheWO_OBJC_FILES += ApacheWO_module_structure.m + +ApacheWO_module_structure.m : + $(GNUSTEP_MAKEFILES)/genApacheModule.sh ApacheWO $@ + +after-clean :: + rm -f ApacheWO_module_structure.m + +include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/Recycler/ApacheWO/README b/Recycler/ApacheWO/README new file mode 100644 index 00000000..3e9fb93a --- /dev/null +++ b/Recycler/ApacheWO/README @@ -0,0 +1,17 @@ +last change: +20040608? + +How to start +============ + +First you need to tweek httpd.conf to reflect you pathes ... +Important: you probably need to *install* the bundle before it works, +Apache doesn't search for the bundle in the current directory ... + +The easiest way to start it is to invoke: + +# httpd -X -f $PWD/httpd.conf + +The -X option starts Apache in single-process mode (no children are +forked) and the -f specifies the local server config file. Note that +the server config file needs to be specified as an absolute path. diff --git a/Recycler/ApacheWO/TestApp/GNUmakefile b/Recycler/ApacheWO/TestApp/GNUmakefile new file mode 100644 index 00000000..5cc22416 --- /dev/null +++ b/Recycler/ApacheWO/TestApp/GNUmakefile @@ -0,0 +1,12 @@ +# $Id: GNUmakefile,v 1.1 2004/06/14 14:59:26 helge Exp $ + +include $(GNUSTEP_MAKEFILES)/common.make + +BUNDLE_NAME = TestApp + +TestApp_OBJC_FILES = \ + TestApp.m \ + +TestApp_RESOURCE_FILES = \ + +include $(GNUSTEP_MAKEFILES)/bundle.make diff --git a/Recycler/ApacheWO/TestApp/TestApp.m b/Recycler/ApacheWO/TestApp/TestApp.m new file mode 100644 index 00000000..2b7fbb76 --- /dev/null +++ b/Recycler/ApacheWO/TestApp/TestApp.m @@ -0,0 +1,9 @@ +// $Id: TestApp.m,v 1.1 2004/06/14 14:59:26 helge Exp $ + +#include + +@interface TestApp : WOApplication +@end + +@implementation TestApp +@end diff --git a/Recycler/ApacheWO/WOComponent+Apache.m b/Recycler/ApacheWO/WOComponent+Apache.m new file mode 100644 index 00000000..149e813f --- /dev/null +++ b/Recycler/ApacheWO/WOComponent+Apache.m @@ -0,0 +1,35 @@ +// $Id: WOComponent+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include +#include +#include +#include +#include "common.h" + +@interface WOContext(Apache) +- (ApacheRequest *)apacheRequest; +@end + +@implementation WOContext(Apache) + +- (ApacheRequest *)apacheRequest { + return [[[self request] userInfo] objectForKey:@"ApacheRequest"]; +} + +- (id)_jsprop_apacheRequest { + return [self apacheRequest]; +} + +@end /* WOContext(Apache) */ + +@implementation WOComponent(Apache) + +- (ApacheRequest *)apacheRequest { + return [[self context] apacheRequest]; +} + +- (id)_jsprop_apacheRequest { + return [self apacheRequest]; +} + +@end /* WOComponent(Apache) */ diff --git a/Recycler/ApacheWO/WORequest+Apache.h b/Recycler/ApacheWO/WORequest+Apache.h new file mode 100644 index 00000000..91c6407a --- /dev/null +++ b/Recycler/ApacheWO/WORequest+Apache.h @@ -0,0 +1,16 @@ +// $Id: WORequest+Apache.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __WORequest_Apache_H__ +#define __WORequest_Apache_H__ + +#include + +@class ApacheRequest; + +@interface WORequest(Apache) + +- (id)initWithApacheRequest:(ApacheRequest *)_rq; + +@end /* WORequest(Apache) */ + +#endif /* __WORequest_Apache_H__ */ diff --git a/Recycler/ApacheWO/WORequest+Apache.m b/Recycler/ApacheWO/WORequest+Apache.m new file mode 100644 index 00000000..ef8c5380 --- /dev/null +++ b/Recycler/ApacheWO/WORequest+Apache.m @@ -0,0 +1,117 @@ +// $Id: WORequest+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "WORequest+Apache.h" +#include +#include +#include +#include "common.h" + +@interface WORequest(ApachePrivates) + +- (NSData *)readDataFromApacheRequest:(ApacheRequest *)_rq; + +@end + +@implementation WORequest(Apache) + +- (id)initWithApacheRequest:(ApacheRequest *)_rq { + NSMutableDictionary *headers; + NSAutoreleasePool *pool; + NSString *httpVersion = nil; + NSData *contentData; + NSDictionary *ui; + NGHashMap *form; + + if (_rq == nil) { + RELEASE(self); + return nil; + } + + pool = [[NSAutoreleasePool alloc] init]; + headers = [[NSMutableDictionary alloc] initWithCapacity:32]; + + /* the values need to be parsed ! */ + { + ApacheTable *hin; + NSEnumerator *keys; + NSString *key; + + hin = [_rq headersIn]; + keys = [hin keyEnumerator]; + while ((key = [keys nextObject])) { + NSString *value; + + if ((value = [hin objectForKey:key]) == nil) { + [self logWithFormat:@"got no value for key '%@' ..", key]; + continue; + } + + /* NGObjWeb expects all keys to be lowercase .. */ + key = [key lowercaseString]; + [headers setObject:value forKey:key]; + } + } + + /* setup "special" headers */ + { + ApacheConnection *con = [_rq connection]; + NSString *tmp; + + if ((tmp = [headers objectForKey:@"host"])) { + tmp = [@"http://" stringByAppendingString:tmp]; + [headers setObject:tmp forKey:@"x-webobjects-server-url"]; + } + if ([(tmp = [con remoteHost]) length] > 0) + [headers setObject:tmp forKey:@"x-webobjects-remote-host"]; + if ([(tmp = [con user]) length] > 0) + [headers setObject:tmp forKey:@"x-webobjects-remote-user"]; + if ([(tmp = [con authorizationType]) length] > 0) + [headers setObject:tmp forKey:@"x-webobjects-auth-type"]; + } + + /* content, this is to be done ... (libapr ?, hm) */ + contentData = [self readDataFromApacheRequest:_rq]; + + /* userinfo */ + + ui = [NSDictionary dictionaryWithObject:_rq forKey:@"ApacheRequest"]; + + /* form values */ + + { + const char *cstr = [[_rq unparsedURI] cString]; + const char *pos = index(cstr, '?'); + + if (pos) { + pos++; + form = NGDecodeUrlFormParameters(pos, strlen(pos)); + } + else + form = nil; + } + + /* construct */ + + self = [self initWithMethod:[_rq method] + uri:[_rq uri] + httpVersion:httpVersion + headers:headers + content:contentData + userInfo:ui]; + ASSIGN(self->formContent, form); + + RELEASE(headers); + RELEASE(pool); + return self; +} + +- (NSData *)readDataFromApacheRequest:(ApacheRequest *)_rq { +#warning read request content if available ... + return nil; +} + +- (ApacheRequest *)apacheRequest { + return [[self userInfo] objectForKey:@"ApacheRequest"]; +} + +@end /* WORequest(Apache) */ diff --git a/Recycler/ApacheWO/WORequestHandler+Apache.h b/Recycler/ApacheWO/WORequestHandler+Apache.h new file mode 100644 index 00000000..2af89dc8 --- /dev/null +++ b/Recycler/ApacheWO/WORequestHandler+Apache.h @@ -0,0 +1,17 @@ +// $Id: WORequestHandler+Apache.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __WORequestHandler_ApacheExt_H__ +#define __WORequestHandler_ApacheExt_H__ + +#include + +@class NSDictionary; + +@interface WORequestHandler(ApacheExt) + ++ (WORequestHandler *)requestHandlerForConfig:(NSDictionary *)_plist; +- (id)initWithConfig:(NSDictionary *)_cfg; + +@end + +#endif /* __WORequestHandler_ApacheExt_H__ */ diff --git a/Recycler/ApacheWO/WORequestHandler+Apache.m b/Recycler/ApacheWO/WORequestHandler+Apache.m new file mode 100644 index 00000000..0c9096bf --- /dev/null +++ b/Recycler/ApacheWO/WORequestHandler+Apache.m @@ -0,0 +1,28 @@ +// $Id: WORequestHandler+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "WORequestHandler+Apache.h" +#include "common.h" + +@implementation WORequestHandler(ApacheExt) + +- (id)initWithConfig:(NSDictionary *)_cfg { + return [self init]; +} + ++ (WORequestHandler *)requestHandlerForConfig:(NSDictionary *)_plist { + NSString *className; + Class clazz; + + className = [_plist objectForKey:@"class"]; + if ([className length] == 0) + return nil; + + if ((clazz = NSClassFromString(className)) == Nil) { + [self logWithFormat:@"did not find request handler class %@", className]; + return nil; + } + + return [[[clazz alloc] initWithConfig:_plist] autorelease]; +} + +@end /* WORequestHandler(ApacheExt) */ diff --git a/Recycler/ApacheWO/WOResponse+Apache.h b/Recycler/ApacheWO/WOResponse+Apache.h new file mode 100644 index 00000000..28eda798 --- /dev/null +++ b/Recycler/ApacheWO/WOResponse+Apache.h @@ -0,0 +1,20 @@ +// $Id: WOResponse+Apache.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#ifndef __WOResponse_Apache_H__ +#define __WOResponse_Apache_H__ + +#include + +@class ApacheRequest; + +@interface WOResponse(Apache) + +- (int)sendResponseUsingApacheRequest:(ApacheRequest *)_rq; + +@end /* WOResponse(Apache) */ + +@interface WOResponse(ApacheInfo) +- (void)appendApacheResponseInfo:(ApacheRequest *)_request; +@end + +#endif /* __WOResponse_Apache_H__ */ diff --git a/Recycler/ApacheWO/WOResponse+Apache.m b/Recycler/ApacheWO/WOResponse+Apache.m new file mode 100644 index 00000000..48f201ce --- /dev/null +++ b/Recycler/ApacheWO/WOResponse+Apache.m @@ -0,0 +1,146 @@ +// $Id: WOResponse+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#include "WOResponse+Apache.h" +#include +#include +#include +#include "common.h" + +@implementation WOResponse(Apache) + +- (BOOL)applyHeadersOnApacheRequest:(ApacheRequest *)_rq { + static NSMutableSet *ignoredHeaders = nil; + ApacheTable *apHeaders; + NSString *ctype; + NSEnumerator *keys; + NSString *key; + + if (_rq == nil) + return NO; + + if (ignoredHeaders == nil) { + ignoredHeaders = [[NSMutableSet alloc] initWithObjects: + @"content-type", + nil]; + } + + if ((ctype = [self headerForKey:@"content-type"])) + [_rq setContentType:ctype]; + + /* apply all headers ... */ + + apHeaders = [_rq headersOut]; + + keys = [[self headerKeys] objectEnumerator]; + while ((key = [keys nextObject])) { + NSString *svalue; + + if ([ignoredHeaders containsObject:key]) + continue; + + svalue = [[self headersForKey:key] componentsJoinedByString:@", "]; + [apHeaders setObject:svalue forKey:key]; + } + return YES; +} + +- (int)sendContentUsingApacheRequest:(ApacheRequest *)_rq { + return [_rq rwriteData:[self content]]; +} + +- (int)sendResponseUsingApacheRequest:(ApacheRequest *)_rq { + NSAutoreleasePool *pool; + int result; + + result = [self status]; + + pool = [[NSAutoreleasePool alloc] init]; + + [_rq setStatus:[self status]]; + + if (![self applyHeadersOnApacheRequest:_rq]) + result = 500; + else { +#if DONT_SEND_CONTENT_IN_SUBREQUESTS + if ([_rq mainRequest]) { + [self logWithFormat:@"is subrequest (no content is send) ..."]; + } + else { +#endif + [_rq sendHttpHeader]; + + if (![_rq isHeadRequest]) + result = [self sendContentUsingApacheRequest:_rq]; +#if DONT_SEND_CONTENT_IN_SUBREQUESTS + } +#endif + } + + RELEASE(pool); + return ApacheHandledRequest; +} + +@end /* WOResponse(Apache) */ + +@implementation WOResponse(ApacheAppend) + +- (void)appendApacheResponseInfo:(ApacheRequest *)_request { + [self appendContentString:@""]; + +#if 0 + [self appendContentString: + @""]; +#endif + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString: + @""]; + + [self appendContentString:@"
Description:
"];
+  [self appendContentHTMLString:[_request description]];
+  [self appendContentString:@"
Status:"]; + [self appendContentHTMLString:[NSString stringWithFormat:@"%i",[_request status]]]; + [self appendContentString:@"
unparsed URI:"]; + [self appendContentHTMLString:[_request unparsedURI]]; + [self appendContentString:@"
URI:"]; + [self appendContentHTMLString:[_request uri]]; + [self appendContentString:@"
filename:"]; + [self appendContentHTMLString:[_request filename]]; + [self appendContentString:@"
filetype:"]; + [self appendContentHTMLString:[_request fileType]]; + [self appendContentString:@"
content-type:"]; + [self appendContentHTMLString:[_request contentType]]; + [self appendContentString:@"
queryargs:"]; + [self appendContentHTMLString:[_request queryArgs]]; + [self appendContentString:@"
pathinfo:"]; + [self appendContentHTMLString:[_request pathInfo]]; + [self appendContentString:@"
Headers:
"];
+  [self appendContentHTMLString:
+          [[[_request headersOut] asDictionary] description]];
+  [self appendContentString:@"
"]; +} + +@end /* WOResponse(ApacheAppend) */ diff --git a/Recycler/ApacheWO/common.h b/Recycler/ApacheWO/common.h new file mode 100644 index 00000000..dc5d269f --- /dev/null +++ b/Recycler/ApacheWO/common.h @@ -0,0 +1,4 @@ +// $Id: common.h,v 1.1 2004/06/08 11:06:00 helge Exp $ + +#import +#include diff --git a/Recycler/ApacheWO/docs/Embed.wox b/Recycler/ApacheWO/docs/Embed.wox new file mode 100644 index 00000000..700ede60 --- /dev/null +++ b/Recycler/ApacheWO/docs/Embed.wox @@ -0,0 +1,6 @@ + + + I'm a reusable component. + diff --git a/Recycler/ApacheWO/docs/Frame.wox b/Recycler/ApacheWO/docs/Frame.wox new file mode 100644 index 00000000..47ab8599 --- /dev/null +++ b/Recycler/ApacheWO/docs/Frame.wox @@ -0,0 +1,27 @@ + + + + Page: <var:string value="context.page.name"/> + + + +
+ + + +
+ + docs | + test | + requests | + Page2 | + Page3 | + WoPage1 + + + "; + ]]> + diff --git a/Recycler/ApacheWO/docs/Page2.wox b/Recycler/ApacheWO/docs/Page2.wox new file mode 100644 index 00000000..9c0f9196 --- /dev/null +++ b/Recycler/ApacheWO/docs/Page2.wox @@ -0,0 +1,19 @@ + + + Seite 2 ... + + Zur Index-Seite: /docs
+ Zu test.wox: test.wox
+
+ Embed: || +
+
+ bigimg.gif +
+ bigimg.gif +
+ + diff --git a/Recycler/ApacheWO/docs/Page3.wox b/Recycler/ApacheWO/docs/Page3.wox new file mode 100644 index 00000000..0b6c6254 --- /dev/null +++ b/Recycler/ApacheWO/docs/Page3.wox @@ -0,0 +1,32 @@ + + + +
+
+
+
+ + + + + + a:
+ b:
+ c:
+
diff --git a/Recycler/ApacheWO/docs/RqInfo.wox b/Recycler/ApacheWO/docs/RqInfo.wox new file mode 100644 index 00000000..425bda35 --- /dev/null +++ b/Recycler/ApacheWO/docs/RqInfo.wox @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Info on
filename + + () + + [] + +
methodstatuscontent-type
headers-in + + + + + + + +

+
+ + + var rq, value; + var value=""; + +
diff --git a/Recycler/ApacheWO/docs/SSIPage.shtml b/Recycler/ApacheWO/docs/SSIPage.shtml new file mode 100644 index 00000000..cc0afc2c --- /dev/null +++ b/Recycler/ApacheWO/docs/SSIPage.shtml @@ -0,0 +1,17 @@ + + + Server Side Include + + + +

Server Side Include

+ + Today is +
+
+ Inluded .wox page: +
+ +
+ + diff --git a/Recycler/ApacheWO/docs/SlowMarket.gif b/Recycler/ApacheWO/docs/SlowMarket.gif new file mode 100644 index 0000000000000000000000000000000000000000..32e5c48af82012af74cc8b283f0de3c9febdbfa8 GIT binary patch literal 16479 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 K9_c-h0027!-Ppze literal 0 HcmV?d00001 diff --git a/Recycler/ApacheWO/docs/Table.wox b/Recycler/ApacheWO/docs/Table.wox new file mode 100644 index 00000000..c6e2f2ec --- /dev/null +++ b/Recycler/ApacheWO/docs/Table.wox @@ -0,0 +1,42 @@ + + + + + (/) + = + + + + + + + + + + +
+
+ + + + + + + + + + +
Config Bindings
MaxColumns:
Horizontal:
+ +
+
diff --git a/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.html b/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.html new file mode 100644 index 00000000..d722e4cf --- /dev/null +++ b/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.html @@ -0,0 +1,9 @@ + + .wo based page + + a:
+ b:
+ c:
+ + Action Link to Page2: Page2 +
diff --git a/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.js b/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.js new file mode 100644 index 00000000..074205e6 --- /dev/null +++ b/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.js @@ -0,0 +1,19 @@ + +print("setup WoPage1 ..."); + +var a = 3; +var b = 5; +var c = 0; +var txt = "Hello World !" + +function addAB() { + c = a + b; + return c; +} + +function gotoPage2() { + print("goto page 2 ..."); + var page = pageWithName("Page2"); + print(" page: " + page); + return page; +} diff --git a/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.wod b/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.wod new file mode 100644 index 00000000..6c761f87 --- /dev/null +++ b/Recycler/ApacheWO/docs/WoPage1.wo/WoPage1.wod @@ -0,0 +1,18 @@ +Frame: Frame { + title = name; +} + +AddAB: WOString { + value = addAB; +} + +a: WOString { + value = a; +} +b: WOString { + value = b; +} + +Page2: WOHyperlink { + action = gotoPage2; +} diff --git a/Recycler/ApacheWO/docs/bigimg.gif b/Recycler/ApacheWO/docs/bigimg.gif new file mode 100644 index 0000000000000000000000000000000000000000..425efe13acc03397d9873918e023a668a917d75f GIT binary patch literal 15906 zcmV+-KHb4bNk%v~VORpz0HOc@|NsBn+uOFbwvv*PZEbByNl7FmBme*aEC2ui09XRn z06+u(2)f+}*y*TU5yZ>M)j$~<`XsSlSaTIGT&oSW!RD0lb@BbPd!Q$EhkI3Yr za2PslFQs%kgYpysf%Y134XEI7$>pRJa|A+xa231V%rZjYjO$#h7JO0wVDk& z2c@l;s0vI)ld`0TrUd~3Hawy(pq2}xw7!9`B6Jm9E)+QJYGP})CQ%=2riZiHI>N4SP8tA z?6P~+AS<1{zKDgWj>G_rj9f0r+XNs%00@^9{!tXd&mQvB;A64H!hp@DCX>jb)d3HQ zC@yzWQx6ruiLk}+8H*63kO^X$`ucYDYwX_^Do@>3MW6v>0q&G3q=gAHNOv|X*!9`Q zmt|SJI<$s1>0){;Z8~YvoU1ovGgOoNW}a-t4>WbJ&oj<}0i@Ji(v7eR0>@ncENNlN zQ}zS{L44x$LW^%J$kad~2*&cB1k!1dh;;58H^7ECSoI(bT^Qxw1Auvz#uX>lBbo== zh#1WcD`>+9B>&OJ7ceL~A%IcJxF^p@0f@pNaApw4)DZivgIW(uS|AaI{`rGNXB(0A z#9HUXQGswQv}c|US6~vPX|G8|WIjz{sNMaoY2P;s89rn#Pr!@mgGxfEjWu5pejXdr3N_1K_p!fj@+l+pn?iQ(kzdK2mz-diDD00l|sUf7~?tw5k{x# zn*y>EmHfwzTNZ*P4MWl}CXxS6kdDbXPYmTT{JnUWMZM-s!q2~{Y@>?=K*^2LASC@m z%=*+k-6I^r`mxYQ^lLMGO}%iOA1s^YsDy5Hz%SNIFug>R74!#82u6qWv3EU_g#+8E zkz$aGaznkC$x;IobgXDkAj=wjXW%qEi9ZO?t{ypHX&yM}baQY2B|&!Y2!0Fg98egy z5-Y!6iDHyi%J>l(i$V9*URe{ck%bSkIOWvOK{};%H1!S~4G)jy8$yJEc!1tQt6wEB*uA20a`aSznG9u=UBf>qK#ppCQE zH@?AR5IiDh{P!CV0zA(6L0~;bi3l4}t6QyM_)+)p|i~_yA=q91iR>$``|JMuY4wSxmaHRaIym!1aER8V4y=tC<9GtMOcpz zkQO#X0Dkc+dpJ@BB^)M{q$NWG#~W3ZtR%Nd5UmHDTLl0AOn{g=z`%JLu)+2?pbd3= zA{SXC2M;e$2`g0&Jtu756-U$oqCu}KTsTY$Js3M9J)~J{37ZF?u&XEPTT(3KY>+da|J$pa6;$l7Lcw;E4=(1Q|YlKv-bhLkK)sB))NJ3EXp} zeOeNWO+aQn3d_zDy!Hb2%?AV4fmVe!X^&Y5D_BMX*LwsRMqDB90hcVn8q`IB0(Kyn z*)YU?Bsi^E@CyorVxWM!HnMNXBn{lM)f}sMl^#ei4S$p+Q`VTnt9)S+i~CA6BTWWZ>j2Sr7P$i#^) zD1pNb*h7Pv$e$^v=Q=kn(FslAU~*iz8QcA;gcJ~jG714tPzJ$^C5^=$dr~|QY_5Z3 zd=rAKS;y17$(-?--8Ec9j1QcvQde_`JO`pW^8D|fAmRZnTY=Ga*~N*;k!0@f6RU7A zXDhpq1y4n16l%^Pad)ih9MU+vU#$TjYq|gf`C5Xc1mkM@gTP9=W;-YeWGF_V7YC9g z#tPJ`0fc>(je@!gU$D#+-zef1ZF1X646B z*GhK4&?H50Cjz}7Ef|4{oWNzL7gz40&bkQnV;T!@>y%<+F8~SEBA+jO$(xME} z`h(UONR9pqV+=oLNtS=SQo|Lva9|Fzn8!@!GMo9#Xil@5*Bl!f^3JocO(}8UoX~{Q zInHLl=~V12=RWIMvvS77o$DNDJPi8(MRR^LPVa1JK^NLGiMF$&8NKL76Z+6BbuFI> z&E`&fItJ$5vZzN*>QbBf)TmCis!6@tb*%c;TV}|%K1}Oce|W^W1|T4F-7FI4dKbTD z7_74#>Z?Xd*UeJHAK_W9A`a2TNp5kAp$+Y6*LaBJGh&iIW5gY8cbuQ$?zYE$?Q#q8 zxpvF3x}SKrbSv~w#{M+cI5`LI997iWA<;(RKM-373ls&!4WZcpRzQ zSnYDi0r?R?nksQJUT|S{n+OpNLR(~m0ZL=>MYDHe+Y)$)%854uek5YwgQ7axqW+Io zTeVdWhtw|!9Vh(3)?J*A3KygS4fX)f9({P2ZY^L}uY8G>Bt?lVG~^n3=F}*@%s5u% zAQgXxd=$_~Y$w!?3B*%EL}hVHjpSr+YRm!}cesw(ybqjGZMc{vnRe?=7W)*A~oHn7rtQ~+&$;ABO$3DR~pLVt}^L5<5tF7{VIV;21;TezO&KYKIY} z@HwWp9mP;7haiPZ0V*h%5m|+E2)H6BVF`+H9GZ}D%69}N_#djG2BUy@g2q-j(N>TL zZ2h5EMz$APM{mCWqJ?Z`ieWHeW+4#BC4~PbPy;o3pGI7A1B+b)3hzZ+wbLs+W?=6j zU!=q<-g6N=7+_}-IFKX z0Cz+rGlDPiAjSkEiy;tY!ztOf5YRz@Jm`E)QHT>TQ=G>-YIp+nI0eWUC?DsFZ}5&d zqC-gdX$U3;+CYJ=1q=a+JxE|kv7w3=1B(JF0|~cCyMYDBAV>=&5DV#wsAv`!6eRno zkqM|i))Ghe_(k9)15K9@h1HL;@hc!jkY?5e&elXDZm?Hf@7o+IZx0W zR--jdagu=lwq^+lAk+vH2Z#Y!sFF0oN*j|kH-;}xAxl;H8$)(1I3z$H@H1=Y25ET# zF-ZutB|oWf3%akB(9gK6L^W1ObclWg0+>c@U7z_)UI5L|WG)19yWG)&>_v z4k?Knb!9F0VQ8)s2F7>+4>@#W0fkUhn9HRO{6`-bM48y*l!|bfo$y8+5Q%7%lqv9; z1!sed$v3tzN*5+oRqz<0H<25kUNZ2RfyX2pZ-~_h?qM(VQLS;@)1R$Oynis&DeAj|1kR0|Cm78FX z$-!cDIS>bk3Fj#%k%^Ow5H!eH0)5BYD6JRr=$F4M)$^58BnIU z0V1t{1wxuUG#U;#pfEs z3vC)+bmRf?Rz?rtrL5E%vr}_+1CQ3RL#Uc19b&cf>asn<0dRVrDE{GFu{i#v?IRXU|RC1Cz)aio9 zl}QreLVfUMA!E7St6$;}Yn))K@zQgCr?VIP~3dw3(GKNcJ}cAKfDo%Ja#8Ce2% z0Hvt0D@@v~U_)A0TWrJTq`rcrRG4no^+Q`g8rMZW;?`v5W?@O@ZRF-{q|s#I#=09; zyWEz$w9C2}wt~@>yRDmT;5KgG#B9vAZ7~MA7wHC9OT5u$yvM6;F;=|LTfNq6ytd|H zxYldjTROS+z2F;c!#2LB22#s=zUZ62>bt(|+rIAmzHWdlLb*zT1;3g91_W$tzxuns z{M*0&`@dkI3)efq1YE!de8327yfK(<$Qx}j7`??Sz1;>+wA-KLCSAJwy1C1(ELOmW zr8Y{}z|X6|9DBWlQN2V&!QWIJ)%yw|Hccj$y&_g(-Meft9K8dqyU(V>*!FGLC0)s2 zy4j{|+SZ>OYmS&jzG1j6O5DVa>$FZB#i_=pZwtUlkgEeRQe>mNR*XI)2nz+%#iH`I zP;jAQthc|?mIrypGk~U|<%E&T#tlNoNE`wToMh|5WKyP@Qz9UW<-EtTB2J4$+QkBv z1W>_{NqSsIzY-!P!K`wO1d!|yEO>M_ zDFbG8_2$yb>%5@A(zt;Sn}K)Mb1tfyt@Hye+h#@FmiGNfivT*}K6CplBJe`4ph{MHCY=UqdB`@PF=s zB7!hJjWT?9GY)+q7O~PKB8>&ziB-@yhnYb!q(?y%^D)Pq0xuWOCzY~!n+bjWp1>7! z9^C=Xm)!4T4JZ*!xwAg7@Lq8QE=%{yk{dLKwMioXVncG#Xkz=(!V{ANrW!%S2Go+; zp}>mdQMnf*4}j3g%3@o13^Ylzc{(FO1tBorLvYaC3qk4%rO_Qa#xVsk3BBZV?lBYt z(j*?4Fm|nGv5f~RHxh^t9V|I3qI}H_dDu3Mk+0>_dV1r$d^Ohf58(|QX}uB3)&^pY zA;uyFJ&IM~tdWqASV8@=@u$o42PGB*N#Y<@t3n*wfK`Kll>eupzMz;sLIZ0O#0a?6 z{uNNAL(R5h2)1WM1~J+;%cr+V*{~SY(cF9L_+mhn-=M~Ge^JLY8yE3R5;e5rRy^MI zo1riV#)2{B)1iq_5-x~GaHdQtt_Kn}8_|^iz;IW=Y$l){FLy@*ZUGT$d48}x(0Sqg zHQmO>2N(jUkeRPba2?sjAgM0vuErC99s|pm&8Jhx7G5a`KI1Xs7Q5+)s%j?1o|1`G z-Eh;Vh<3FZAXTQJyr?0uL&xp%GrBjemu-R{vk65-U_OUMLXYfbt|rjtOP0u>grUOU zh-nwYy*Iu%xgtP>A|n{qw`M};Pqt$&5&;;;oEW?w(})ztJZ|Pg>Ai$Z?G3L2m9-dz zNz*)3#xfa;*iK|nd&U8}qx$Z(m%H5(36Fmm^-VO#zFLgnFCQ0HhWr0K>0ZKN9S{6@x3i|1%B=MFk zgrGfvpGbN6YAp;{I{+NM>_?C0+em^P)Kq_)FgiRcA7J*HQi*q%9Ap{Ex zeh&kXd77J?H<@r2cbqmqNCcRlbp&0hqc8yh0zZ7NwM8y_wYs~!y|`*JDL0nB#hU}f z#+!hxiL^OL5(8PI0iwz%r`VdeEewL&;o_RI$O6Z-U*YH7}D8npM^BU;e z^7=8|STJz+ub{XY`~(vJ<70u(Bm)Jm0ZM34A2K{k7Jyi#2Ar#QC=$6tQt{8aUI9*) zRN=&s3Uw=EzEJtXnvgCV&_HNt!rG5QZDi{6htEJOZzp~R0pt+?0Sn+Rwy>6kqAsGl zlnV7`;fR_fHDGQX+Y@WNMrhN9T95=PhgecL5c*~U%@UwibqHum_LWN%e|1!NaHq>s z3+|pCu(SbJUSC-1Dk8`ua9DNn%4V9DksHL^IPPy&NNjW4Sg_jDv< zL+B2)V2y^L_;C)tpLeuWtB5TKRMcdxinyTR)1xr%olp#9unRDheIXgH2zU_-zC||< z9^uK(EUO5c7qXZCd6G%t-`(BuMe2$Hs#kna6O;n+^_LJs7isU20Ny6^(Kiig=fF|g zJWkZ0Q*7WkVbxwD48cq`P(gsub@2SBMl=$9hgN)N0N0miHfa?~9z@;710-a8P=bvF zpg0|LEF_qReM7*OffIaP(~>JQz(5lZX4%rnNlr*`3MLWSa1I?BBF14*{iOh8F&=#2 zfMSh2b_0MaSV!IoM`i#BFlC@QqdSrDum%_(3@JpDENGR77appWgHc1urpJN1H0Xjh zcEZEw4v+d}s0oT?f+apny24p}OYjs%cu^cfs67zXqSz5|)Zi%|SVbBRqdR;##CUk5 zG%5f@k}v`Peg;}54r`5$gP{p~(V9b@Sx(xkAaTTJY%e+HplEHrYQSR*NnF8@E~jRo zY@C_G0BBO#T~UVv5b3mB2*aimgsef(+7eqy)Jq9-UQooVdV+BF!!_OhV+9W?_VTP0 zq3RW`3mZX~d}TKZQo zZ!h=IMJxyR5Vn7Iw&G(79FHQhX8DN#=bvVGy-SybrnGfk9HbnQC99aDcTyqb!rL4c zgCfTN!mb$hg#@YT$TKz|aF(PLIm2qtLkn6B+QXD`o-^Wq>yddmTGTvM639fOU(zZZ zo#_%f?y&Z#Ist5N%;`uKzrN{Ke1Q^L?AMah(yE-O0k^gW;g-CDJ^RVD@L|Bu|i+SLk?sZ zR%BptC6En^Btk$VP*P#U7r>B+6O7Af)aMi|N7H z7K!-O=cHgVugT0QW~<`ws*^C$h;kNac+0~4l!7Tz>NQMA-gG#~w{Wm>Ml!^M4l zxqJ*nQgEf)nj#$;o_`r=X2zarluR%tB%*OMF2_yvSq< z#??vT#IO!n`J)Bp@uq9Y0#{^GXKkW)fook7FqH6!HJbCZ%}j4TvaF%UdgCVlQTD(z zL6Q>>d`P5eWKjbATFe)|_yz`x=s%ohH^qes+%>3&BBWeyP%uW@D_u<)gM z?Mea`n!^T0@P!0^G$B}N9F4;&ENidNjGBMMi?Ex9fd5`|i zqLzf z(`afG7aJm>MzKHyV<`tOdutG7$0FM0#01<1EJbcB5xQV0VgWd zG3R{MQk&2P1-!v_Kl)Ezc=jd8a^nneiiHAa`%YYG7J>)$$J!?0f#F>Lt37tH2XVxT zTZTm|o6#Wd3|$El(F8R>J(y}zB9b{jye13Qy+j1mp-LJ|qI#i-q-v~@iS)dLvZA0_ zGANjp+j>Z7&utB*v^k1zo~c8IK^T@MxFjGYLM_nA-W;&V3Hv-{4Jk1~AKNrvI}Hyl zd{6>+z$Yz609aZibjma)C{H~ommMGlM2wE9f?^SO5;xLoKmy= z>VP?ExM~|6RF{#aRvr;iK(s`Bg%3~XWoA(zTG>i0nrx5+FZ0oa8=*ADxmI_4bFUO= z_*Khv_yphCo?PJCfshbOMUMOr9)NVSZ;s+Ha24_X;Qr_*EEI=!Xl{fS6K_u33v&_?Hq=Byz>hDg51p&F%5 zf*3kA2~ylv)eoj+GmJgX0`buvO`sMqU?mNS%}lJK8Tkbh6~PRC&4woI8U|lh!P@4P zx%hrY4v$+0mjM%(VhKY;!2S<1E{*9{uIC4nkc`Km1q64nR|}c?!JE=T?CKM!V)nm}~tIMeZUn1~y#-zIvbWGqv}&cD?O{OXHs8MYzE54VR*!q$S8(^X(|zx5 z-zMPo9w!#K-S8g^d)X&X`N~`V@|e%O<~M&Cjhf@+CttMaDYu)qaGo8fPkkOl&idB7 z{`CzH&wXJ}``X*S_6r;M?RU@n-sjug^j7_42->Gy3;#1Wkf9>dlycFhd@6ZaGzDlo znsb=``h9hN4Xv;87&u=R)TblLzb}642bLO(=Dv#mX=`!~VglSrEdnt?dVI1}%7VtP zKUtFR$NcMmD;NY6$M%2kaDQ;X89Z|Xj7EUrz!bvZCW^3t42TT@=t3_&+ru95*BX| z1(O394p3T5^#)h9j1@o`Srq}1SYiQmau9flr-3W@0|uMOEQRKQ1JW^}h)ISJPsw16 z<#7tWF^VF<592l@=R+76poUga0X4ubMzD+@RR-u_9qK4HxkiU;;EPPc4=q@Utk^N% zK@i#Ghw)el#s&+_BN4~AFJ#tPJ`pIIBwR!ghxqqd+xRFSGBTwzB$fb=o_HNn$bXqd z8gmg8S;dg8V+gCL0cOFDq~#P_LpKBeBnWUKL~wN}t^p}p)`%{2jkxj&(gc!9BW;H^ zhjNevv7i8NK?qsZ0BI3RH-jkSBUy!jQzF?T&Ndq)xq(G+O^rYd)!32(A%(Yw60|@I znGRL=?#;9dVS- z80MyhB8aiB#rKqY8kLf~j5MqoRhK>|?%4y96G!3TtC375uDjwLCZI7mQ+R4Gx9`s7(N5&AjVh@HWpqAdCIVjIm@0Uk##t*tvnz5SS+rp&YO)BO2uFWGVE{>wDKclu zvB^IsRx~ z=TQb!G6La7M^-Rw(-H{VK@1+llA~f2Pk{(sb($EuFlY)-!^TNF5P<~Z1qb<}dtwR7 zB1A*t1#RFD=hmo_3Qwy4DO3O0iXVfF9YYN^X$PXv7*9C|MsQD(SeLTE2Smm&0~4x( z+CFEHW%753m_ULIb1$E8CXr>AyXlh~aUAf_fnvG~3>li8;s=a+I1AyWu6QjT(*~uK zANc`?chHsBvnWQw1U33)N2omJSe9T01S+bFK4g(%HXCr)F~(M@_mx7$p(<218`N-M zurfIdU|An}24gar1^PXaGMC;Euc8o|AN2XC6m1zmce`hbw( zGmgKL8*Q+h>$xAwR3U<3Uj6ZzU_%JjfGh{3QM9q3IH01y5D2rCCVARFrWr!p>W%N` zq8(V-r|boK@f#gw5Rb#)&;4nN;IBOb zIFYsleyLsD`TPKen5e`$QKH$LNh^DR3AG@7F)U*<2Jqf zx&}9uYZyLaE4+iU9zkYT{iz?|06!lCw=qbu^){xNFgg3gnSu}+o_dZl*%pv+U`lv^ zCVGrxG=gKky0bWdk!*HPT0( z{A(~N$VhyU2nFK|S2-z3D|tdly};WG0xKjZIfa+dG}D>|j0&P3v$JgD0nzgYE$FhM z%Sq^98)zsB`beBp$$|3Ab*%uU3+g7Yz>)XrjfAm|1EZol!37+I4j6Q9UGk^T)DHk+ zBi=-Rn-xrW5)`S4yxT|+XUPcx!;lcwi9+%fH#!IjAzAx!q^?L-pO(a|%EDn#RM(q_ zoRFIDQ&*bHNyuPhNc_7!>@A#%tz&4J;kFu0F&Ho01o)FaF|rt@fL*qsng@))^6%^r0m=w}8$J>wy&2f(-K|jO+aS^x{cM4N@yg6-Kv*ARd!RbWt$^-+GgOeP+N{cJS z_?6C;H<2X=IB5ucTZQhG5{*2=1Y-opYPs=iepteiI658cuohX9U)gGD8tfI@5G5|) zy23yd3yRER!Kkt_7)eVuNpTGytc<~1S4UyWS&=>6ff=Jk$fRKw!$G1?s0z#&Qj`(` z|8*yA$w88QGX95_mK-4{>y@xjyf1-ZF7c*K!aYRdG@Oyp30f$eR!10+!6-?Ap_pI@ zy~{o~FOhLeUz1?)O38&1T%R@>wLrmyO2xgf(w7i|x16(r(L+Kfy`x}8t0U7shs4wW zmccx!!X(Wb&u~@a+X?dP(k#7n#s>@f1FT713jqiQkY~KFfO8tv6M_l0_nerjMgf8u z38+$FN6n4oK)Z1nR1O$Zb(17rA+UgIVQrbs_X426ks&i~8} zr6>wd5uB)CtbPy$T+GVp7y_tKTR(@+7>BbY_+&?L4h%sJ%~Drs;U)7(lY9YTQ>X~? z+z9YP+8fx}@8HVLrPJTMFP@sFn58v5Y@2`027#?h^Czmjkt2HnKgx6mi(Lkbvq|;^ zXEy3geR>Npi$A;X{jxD3MC34QY@5ksKZ)#fnNs6I0a z2IJu?fd&uButDmXVY%70FN?$c+n8>w1Gh~CWDN!GZ~;L^5hLKT8U#m8!^*CB3hR)Q zJI5mUd8m@NLLaLH)GBOhN-0eu1{;YkctR7QGHtpXuN7h`CLoInCf!h)+5TLpdk7fm8FpU;&pc;^gw0O5Ox&{Io z<167AcFWu$!;d8DsPFt$e8|^k@tNQ@l)Xffqc}c4?W|<`Q~!X|D%RRv!*XHmAs#Ha zq#@;afN|?v7jcx(gb@}18x24};1u8wbe`du z?m60cFfXDCxFXngpFkTwjTv;hGpre<#ZhmZ!yTvf9X-D0bX5-b$ z4I@ICNlqyX!<*ZP>^w)RebEx=kVtmi-^rf0lSl~w3VqMF7v4U7vX!+s90|zn3(+^z z2LbGF!g=y76b!Z#nAv5>*R_WJBgrtOWD$Tq(dit`;7h(qVNh;Sm$7I2QQ<9g`e}~j zo^vHm>{I!<98@vS-G(Sf1Xf`f&oPDEIRcw~sqIb4sIW9O&Xa}z^UVM#>z3HSwz0?Q ziWzr1s}Pi691sOk?CeMP@jwysH#hPmKN~0pTf($sLamEOKe{aIM5?l+HM%-%vc1rD z2VyA`6{rNAh_yD*9}z+`V204CKs!>>=R-??;_gCFUvqmO4yieskU-5h!Nx*8jSIgI zI}!LBA?js7Pb&<#gx3Wd^w~*&0kK&StPRlkFprm_o*v>FPBezpAVfpyFF0+#nMb`h zAoViG`bs=*tgB;}-y?;AD1_47IjWO$aSk2ysm9vM>8lbU`@@bPjqBl{6;Xjx((Ie( z*5lyRC++&eutWYcV-V7BQsw-x+uwqJ<>&zs=<|q_1p+ev%Q1Zuke5{lku{!|BSyq9 z>`)zw+;< zW-QNQVbORQP{Kn{DOq4pFc4t5U5>_DIxmxhXF_;duh^^%#V8sKLBQ_N)0(x-b9P*A z{4}Eg;XAl#303t)s&_`G2S|N`gjaJ1cmo3j83cA5KprlEg_R{~mNb)(3j>iIb4Qi} zVTA>PnU@rRd8w|i4*>?K5iV_=t)B`30=|&$LkzkK1U;Bz(%z%jB6D>R17K_a%nqK2^zf;UmEqi7$e;}hC4mSb zl#_wSL_IMZTv#|qt^u2buSAVtBx0Nud=2zHTM&@MNE{{2Xv7$SU`PrS@^E8Gvmc0b zGbkA7Aty?yVxAaWq``|OiH9I6=m;Zg#u!=(L^`l(QCYhj)cPnf3c)17o}`I1~^ z4ouoIb|shSH6Yo7UNRboh}jt#!7ou@sy^6-#bYWAT%<*nmnc=u8_%8)kS=Qs#Q9=& z(H)W}zz0#TlCXh0tl=VfUW;vR!Y|1nJDAJ=s>eIx5ox?f&qWt7LoiP#0r*M*d%=;k z&-5wpNPY7cwWa5Gh%|)lyb+U}rI-SSMKG2c;gO?SdY}E*fnfFh(Sd~Z(HFxrDed&Z z1W26nfO!tU;eZ7Vtsr7-o^?Wjeju1tVGR}VV%BM^)o7zmWq?BzNDK@JK!IHeMI06y zzMoPnOz6DT zH6m=^E=+Jix zyXfCqDB>pvZ|K_Nwp-$Gt3})y!n%8yNghK~PMTo6#Fs_<2!e&ox914+Wb4|UK3?b8P;;0MA%$S+=OJK$&VRtw>^KvxR9 z(BsmBHRECGY+8U<`l$E+IrU+#UoAQWw0<<1?U7_}!`Pt*dWZ!awkZZ10Gs$Y0$yfP<@-x|g@+e>r!Xp$VNv9k1ppYjt*%!%GNiqT{7&WvF z1QIDYj^N=2i)e!!2XceH5fKDYtWLkAU~bA??S=z~Esv zb~FnvUAclCO;I0lv|GeUJ0663z zQg*Wy^id43gs6i0hdWf%lQGs*-}javO*#QED&4A9NKP8SGJXM)nK1zd9jXSHNx&Q+ zkcIbz5C&?RJ43k9J9-3ubi6rfSjanya!_^1cwmV8lBdn7HDq@-?-JEp^QKM5XYoLxTJVG06{7n-G_?0SnHKK5eXjA#; zo>p*5Rg}a5AL>B~H${yXi|~RI#WdI-UDZdz(jr(JsUFP1V0U8L~&4C zbR>3^oB^jyTegtBDgqBMsX`3@K|$WgLASxp+{H@Bu1^PXI?t2__|6 zEvt#*bBef%P;`3WNCcs?DZc`BBf6zokUy{{>ZT{dLiuimTQWFHip~PPkds;RpkTci zVZ7!45?6gk#E6%YI5B~>XLKIJ)(|wIeQP#BH+lO+8SFTKZIB-@!OWl@hKH98;=~(T zF|NwEGA|)N?)5L z2V;#;he=!~HF-*>*>a@9SZ_fSX{^W0kbz724Ph&w)z_h~>VP*OEYwMHg0Puw1<}fr zs>TIEBfglRSc<39()?nGLSq3W*sIio34$%VN$a=Bq6*2_GI=mHy>NKqzehBKt=VO! zKGsw3CJ)`zNzTscmNqD=-ELZ`m)Ha2Qu8Rn4k1I>k8)ph z8L_k7#dasRfxetv70W%cqqti#P%nAO%Ref^c;js=uYqAqXzGD2gTuu0eLCMyCu{El zOI0KMz{9%UlpvZgKF85!8as?%+1Y!6Uw$sC44*eiy@Bu!+AF2)>J}zF6PUgN#2iH5Shx7%2q*ZiS-n z2Tilb*VrK-Z&f?sQ7KT(DbjLyCOua<$=hO1dp@FmcT;CFk=&j47RR<%CkN%%Kz+g+ z(ZLfM;Vt(RGTzoB@K#kyw+pvpdfPBE8X*WCqDr6PaL@G*I`wY$L>cKo1cvn;KY$vI zW)ZMe9J;iCOHdol_Fmv8VP0Zxjk0&+L>mhd8;SrbFkvV-GhR#s6E;CSif3;&m}ae) z5|1Eb%|sMDbPV1UfG>DXa`s#?5(u1eYRJVT`E&%4RX9^~3Z&+MSEV;BcP!tfG{)y8 zy@5){*L=;lej_vsQqWr4r5>#{2^tV+kTiF_M<*cybsw;A?hyq*^KW_oqi$aJbAs46 z43lvy#%U_HOhbYwW5X=3q)brMAu%`@Fc1bz=yc)IgcEoe!Zt+1XJ@Xm7Nklml95N4X`Kz-ZvRQB?i<;d65?bOg9!q#bR!;2tLt@ z%@B?OhCn&>BaB1}vIu;!kQu3EV~H^j#=#RFV=CNbDcr>q(GWUHb00sX0r2xMh1Xaf zaSbPEZ&2ZD53)SqkZYY7Kz6W7df+TEks!q|4yqx0*=8e#luzvcw{Y$uh@?0*+>%xi zW;kN>Wi=844>K>1SURg0NpiSpY(>xm_ak-dM1E;<5>~e_kHc6RkaQL_A$~{*>9QJy1v!gx z0ifX?cxf~}WmtAOjmU`!4_ON2^qVesTl;=L6+A z2C_Jko~Q-v7Mi1(fqiEUF#%?=!d|5kW^E>PV6h#LfMI<3i_M^&YVeG$#};;?p0yw& zK_LNRI1RwK8erjtg+m6MNiaj%g9hRTc(9fc)dnTlBfGFY%fo`I!WK1x2~zN#OGF%; zcO#UfQ*SndBV`uchd{E2o&l+zdDcQ0bSkrOi+(pIbX17!S0;36p!Ex6|Gti1S;bCi8TvF5ziW!$WfPbm~W}IV!mA7y_;2=ExAr>r94`Ajg zF2GVdkOznG4DtmP(f0)Wax{&EphsCSa#AulvqSSjHEW7k&HVyk_wFI`Od@3}kNako?pd5-?W7yF}co7+X*%2;@ zV$znIrvWxEa9&*4l@E#IXWzw8sUjOE3l*t5QRkQ?=wJuz9F4Ksc==VknVrS>S7KdNCr& zp?$yynY2MYic1t}u3NZKHY*8uc?3*rBZ*Q-b?R}DKo7Hn6UnKxbNjbUN&-+ze(X3# zj#jJsRycl8SZbP*|HcRKbSB*M4*%;c0P}`H#ahfahs=qTergzf~&KyyWkc} ziHTxR65b}2QVAbmm@|D#Qu?YEfQzA65mOL)u4}=5@SzBV*>4{vsT4;?!aI+o0!LyEnZN zybYE&oG}MZ*CbXUEYo5b`#HM+n6sceweyu)*wtaI|iKpezEJj9aG!5!RnNx8ucymmy~#7_LgP#nclJjGO8 z#a4X9Se(ULyv1DH#a{fyU>wF`JjP^P#%6rRXq?7syvA(Y#%}z^a2&^SJjZlQ7R>67 z)3i1ycgK^W4R86!;p4}7?6|b=86x0`a%%+3})KlhvzoP5!CSJ5Ki(HtGp-H-qP EJFmAIeE + + bigimg.gif + diff --git a/Recycler/ApacheWO/docs/renameme-.htaccess b/Recycler/ApacheWO/docs/renameme-.htaccess new file mode 100644 index 00000000..ae03b60f --- /dev/null +++ b/Recycler/ApacheWO/docs/renameme-.htaccess @@ -0,0 +1,25 @@ +# $Id: .htaccess,v 1.1 2004/06/14 14:59:38 helge Exp $ + +Options FollowSymLinks Indexes Includes + +AddIcon /icons/image2.gif .gif +AddIcon /icons/image1.gif .wox +AddIcon /icons/dir.gif ^^DIRECTORY^^ + +AddDescription "SKYRiX XML template" .wox +AddDescription "SKYRiX WO template" .wo +AddDescription "GIF Image" .gif +AddDescription "Server Side Include" .shtml +AddDescription "SKYRiX Request Handler" .rqh + +FancyIndexing on +IndexOptions FoldersFirst + +#IconHeight 16 +#IconWidth 16 + +SetSxApplication app1 + +AddType text/html .shtml +AddHandler server-parsed .shtml +AddType skyrix/request-handler .rqh diff --git a/Recycler/ApacheWO/docs/requests.wox b/Recycler/ApacheWO/docs/requests.wox new file mode 100644 index 00000000..95c46ce9 --- /dev/null +++ b/Recycler/ApacheWO/docs/requests.wox @@ -0,0 +1,84 @@ + + +

Check Apache Internal Subrequests ..

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Filename:
Pathinfo:
ApacheRequest:
ApacheConnection:
test.wox:
test.wox (file):
test.wox/add:
WoPage1.wo:
blah.wo/:
SSIPage.shtml:
/docs/:
/docs/manage: + Note: pathInfo doesn't work on directories :-(
+ +
+ + + +
diff --git a/Recycler/ApacheWO/docs/subdir/renameme-.htaccess b/Recycler/ApacheWO/docs/subdir/renameme-.htaccess new file mode 100644 index 00000000..e55df2cb --- /dev/null +++ b/Recycler/ApacheWO/docs/subdir/renameme-.htaccess @@ -0,0 +1,3 @@ +# $Id: .htaccess,v 1.1 2004/06/14 14:59:48 helge Exp $ + +LogText "configured in docs/subdir/.htaccess" diff --git a/Recycler/ApacheWO/docs/subdir/test.wox b/Recycler/ApacheWO/docs/subdir/test.wox new file mode 100644 index 00000000..d2eb60cd --- /dev/null +++ b/Recycler/ApacheWO/docs/subdir/test.wox @@ -0,0 +1,8 @@ + + + + +in subdir ... + + + diff --git a/Recycler/ApacheWO/docs/test.html b/Recycler/ApacheWO/docs/test.html new file mode 100644 index 00000000..44e1d919 --- /dev/null +++ b/Recycler/ApacheWO/docs/test.html @@ -0,0 +1,19 @@ + + + + My HTML Page + + + +

My HTML Page

+ + + +
+
Helge Hess
+ + +Last modified: Mon Jun 17 21:10:16 CEST 2002 + + + diff --git a/Recycler/ApacheWO/docs/test.wox b/Recycler/ApacheWO/docs/test.wox new file mode 100644 index 00000000..3ac794ac --- /dev/null +++ b/Recycler/ApacheWO/docs/test.wox @@ -0,0 +1,46 @@ + + +

Apache served .wox page

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ComponentName:
Filename:
Pathinfo:
Context:
Request:
FormValues Keys:
ApacheRequest:
ApacheConnection:
+ + + +
diff --git a/Recycler/ApacheWO/docs/wa.rqh b/Recycler/ApacheWO/docs/wa.rqh new file mode 100644 index 00000000..3eef00e7 --- /dev/null +++ b/Recycler/ApacheWO/docs/wa.rqh @@ -0,0 +1,3 @@ +{ + class = "WODirectActionRequestHandler"; +} diff --git a/Recycler/ApacheWO/docs/xmlrpc.rqh b/Recycler/ApacheWO/docs/xmlrpc.rqh new file mode 100644 index 00000000..b5d4a93f --- /dev/null +++ b/Recycler/ApacheWO/docs/xmlrpc.rqh @@ -0,0 +1,3 @@ +{ + class = "XmlRpcRequestHandler"; +} diff --git a/Recycler/ApacheWO/httpd.conf b/Recycler/ApacheWO/httpd.conf new file mode 100644 index 00000000..81a4a163 --- /dev/null +++ b/Recycler/ApacheWO/httpd.conf @@ -0,0 +1,77 @@ +# $Id: httpd.conf,v 1.1 2004/06/08 11:06:00 helge Exp $ + +# globals +ServerType standalone +ServerRoot "/HOME/helge/mdev/SkyrixRoot" +PidFile /HOME/helge/mdev/SkyrixRoot/logs/httpd8090.pid +ScoreBoardFile /HOME/helge/mdev/SkyrixRoot/logs/httpd8090.scoreboard +DocumentRoot "/HOME/helge/mdev/SkyrixRoot/Library/WebServer/Documents" +ErrorLog /HOME/helge/mdev/SkyrixRoot/logs/error8090_log +AccessFileName .htaccess +Timeout 300 +KeepAlive On +MaxKeepAliveRequests 100 +KeepAliveTimeout 15 +MinSpareServers 1 +MaxSpareServers 1 +StartServers 1 +MaxClients 150 +MaxRequestsPerChild 0 +ExtendedStatus On +Port 8090 +User helge +Group dev +ServerAdmin helge.hess@skyrix.com +HostnameLookups Off +ServerSignature On + +# load Objective-C bundle loader ... + +LoadModule gsbundle_module \ + Libraries/ix86/linux-gnu/apache/mod_gsbundle.so +#AddModule mod_gsbundle.c + +# load a bundle + +LoadApacheBundle ApacheWO.apache +#LoadSxApplication Test.sxa + +AddType application/x-httpd-wox .wox + + + Options FollowSymLinks + AllowOverride None + Order allow,deny + Allow from all + + +Alias /docs/ "/HOME/helge/mdev/helge/ApacheWO/docs/" + + + # This may also be "None", "All", or any combination of "Indexes", + # "Includes", "FollowSymLinks", "ExecCGI", or "MultiViews". + Options FollowSymLinks + AllowOverride All + + + + order allow,deny + deny from all + + + + order allow,deny + deny from all + + + + SetSxApplication lapp + SetSxRequestHandler WODirectActionRequestHandler + SetHandler sx-handler + + +# Directory-Index could help ... ? +# +# ForceType application/x-httpd-wox +# SetHandler wox-page +# diff --git a/Recycler/ApacheWO/httpd.sh b/Recycler/ApacheWO/httpd.sh new file mode 100755 index 00000000..2fe49545 --- /dev/null +++ b/Recycler/ApacheWO/httpd.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +rm -f core +httpd -X -f $PWD/httpd.conf + diff --git a/Recycler/mod_objc/ApModuleBaseClass+Callbacks.m b/Recycler/mod_objc/ApModuleBaseClass+Callbacks.m new file mode 100644 index 00000000..a69a7182 --- /dev/null +++ b/Recycler/mod_objc/ApModuleBaseClass+Callbacks.m @@ -0,0 +1,396 @@ +// $Id: ApModuleBaseClass+Callbacks.m,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#include "ApModuleBaseClass.h" +#include +#include "http_config.h" +#import +#import +#import +#include "ApacheServer.h" +#include "ApacheResourcePool.h" +#include "ApacheModule.h" +#include "ApacheRequest.h" + +@implementation ApModuleBaseClass(BasicModuleCallbacks) + ++ (void)_moduleInit:(void *)s pool:(void *)p { + NSAutoreleasePool *pool; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheServer *os; + ApacheResourcePool *op; + + os = [[ApacheServer alloc] initWithHandle:s]; + op = [[ApacheResourcePool alloc] initWithHandle:p]; + [bundleHandler initializeModuleForServer:os inPool:op]; + RELEASE(op); op = nil; + RELEASE(os); os = nil; + } + RELEASE(pool); +} + ++ (void *)_perDirConfCreate:(void *)dirspec pool:(void *)p { + NSAutoreleasePool *pool; + id result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return NULL; + } + + result = nil; + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheResourcePool *op; + + op = [[ApacheResourcePool alloc] initWithHandle:p]; + + result = [bundleHandler createPerDirectoryConfigInPool:op]; + if (result) { + /* let apache release config ... */ + RETAIN(result); + [op releaseObject:result]; + } + + RELEASE(op); op = nil; + } + RELEASE(pool); + return result; +} + ++ (void *)_perDirConfMerge:(void *)baseCconf with:(void *)newCconf + pool:(void *)p +{ + NSAutoreleasePool *pool; + id result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return NULL; + } + + result = nil; + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheResourcePool *op; + + op = [[ApacheResourcePool alloc] initWithHandle:p]; + + result = [bundleHandler mergePerDirectoryBaseConfig:baseCconf + withNewConfig:newCconf + inPool:op]; + if (result) { + /* let apache release config ... */ + RETAIN(result); + [op releaseObject:result]; + } + + RELEASE(op); op = nil; + } + RELEASE(pool); + return result; +} + ++ (void *)_perServerConfCreate:(void *)s pool:(void *)p { + NSAutoreleasePool *pool; + id result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return NULL; + } + + result = nil; + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheServer *os; + ApacheResourcePool *op; + + os = [[ApacheServer alloc] initWithHandle:s]; + op = [[ApacheResourcePool alloc] initWithHandle:p]; + + result = [bundleHandler createPerServerConfig:os inPool:op]; + if (result) { + /* let apache release config ... */ + RETAIN(result); + [op releaseObject:result]; + } + + RELEASE(op); op = nil; + RELEASE(os); os = nil; + } + RELEASE(pool); + return result; +} ++ (void *)_perServerConfMerge:(void *)baseConf with:(void *)newConf + pool:(void *)p +{ + NSAutoreleasePool *pool; + id result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return NULL; + } + + result = nil; + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheResourcePool *op; + + op = [[ApacheResourcePool alloc] initWithHandle:p]; + + result = [bundleHandler mergePerServerBaseConfig:baseConf + withNewConfig:newConf + inPool:op]; + if (result) { + /* let apache release config ... */ + RETAIN(result); + [op releaseObject:result]; + } + + RELEASE(op); op = nil; + } + RELEASE(pool); + return result; +} + ++ (int)_translateHandler:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler handleTranslationForRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_apCheckUserId:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler checkUserIdFromRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_authChecker:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler checkAuthForRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_accessChecker:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler checkAccessForRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_typeChecker:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler checkTypeForRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_fixerUpper:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler fixupRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_logger:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler logRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} ++ (int)_headerParser:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler parseHeadersOfRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} + ++ (void)_childInit:(void *)_server pool:(void *)_pool { + NSAutoreleasePool *pool; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheResourcePool *op; + ApacheServer *sr; + + op = [[ApacheResourcePool alloc] initWithHandle:_pool]; + sr = [[ApacheServer alloc] initWithHandle:_server]; + [bundleHandler initializeChildProcessWithServer:sr inPool:op]; + RELEASE(sr); + RELEASE(op); + } + RELEASE(pool); +} ++ (void)_childExit:(void *)_server pool:(void *)_pool { + NSAutoreleasePool *pool; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheResourcePool *op; + ApacheServer *sr; + + op = [[ApacheResourcePool alloc] initWithHandle:_pool]; + sr = [[ApacheServer alloc] initWithHandle:_server]; + [bundleHandler exitChildProcessWithServer:sr inPool:op]; + RELEASE(sr); + RELEASE(op); + } + RELEASE(pool); +} + ++ (int)_postReadRequest:(void *)_request { + NSAutoreleasePool *pool; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return DECLINED; + } + + pool = [[NSAutoreleasePool alloc] init]; + { + ApacheRequest *or; + or = [[ApacheRequest alloc] initWithHandle:_request]; + result = [bundleHandler postProcessRequest:or]; + RELEASE(or); + } + RELEASE(pool); + return result; +} + +@end /* ApModuleBaseClass(BasicModuleCallbacks) */ diff --git a/Recycler/mod_objc/ApModuleBaseClass+Cmds.m b/Recycler/mod_objc/ApModuleBaseClass+Cmds.m new file mode 100644 index 00000000..9a6684ee --- /dev/null +++ b/Recycler/mod_objc/ApModuleBaseClass+Cmds.m @@ -0,0 +1,864 @@ +// $Id: ApModuleBaseClass+Cmds.m,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#include "ApModuleBaseClass.h" +#include +#include "http_config.h" +#import +#import +#import +#include "ApacheServer.h" +#include "ApacheResourcePool.h" +#include "ApacheModule.h" +#include "ApacheCmdParms.h" + +@implementation ApModuleBaseClass(ConfigCommands) + +static const char *configStubRaw(cmd_parms *p, void *d, char *a0); +static const char *configStubFlag(cmd_parms *p, void *d, int flag); +static const char *configStubTake0(cmd_parms *p, void *d); +static const char *configStubTake1(cmd_parms *p, void *d, char *a0); +static const char *configStubTake2(cmd_parms *p, void *d, char *a0, char *a1); +static const char *configStubTake12(cmd_parms *p, void *d, char *a0, char *a1); +static const char * + configStubTake3(cmd_parms *p, void *d, char *a0, char *a1, char *a3); +static const char * + configStubTake123(cmd_parms *p, void *d, char *a0, char *a1, char *a3); + +static const char * + configStubIterate(cmd_parms *p, void *d, char *a0); +static const char * + configStubIterate2(cmd_parms *p, void *d, char *a0, char *a1); + +static const char *serverConfigStubRaw(cmd_parms *p, void *d, char *a0); +static const char *serverConfigStubFlag(cmd_parms *p, void *d, int flag); +static const char *serverConfigStubTake0(cmd_parms *p, void *d); +static const char *serverConfigStubTake1(cmd_parms *p, void *d, char *a0); +static const char * + serverConfigStubTake2(cmd_parms *p, void *d, char *a0, char *a1); +static const char * + serverConfigStubTake12(cmd_parms *p, void *d, char *a0, char *a1); +static const char * + serverConfigStubTake3(cmd_parms *p, void *d, char *a0, char *a1, char *a3); +static const char * + serverConfigStubTake123(cmd_parms *p, void *d, char *a0, char *a1, char *a3); + +static const char * + serverConfigStubIterate(cmd_parms *p, void *d, char *a0); +static const char * + serverConfigStubIterate2(cmd_parms *p, void *d, char *a0, char *a1); + +typedef struct _ObjCmdDispatchInfo { + Class moduleClass; + SEL sel; + const char *methodName; + const char *command; + enum cmd_how argsHow; + int location; + BOOL isIterate; + BOOL isFlag; + BOOL isRaw; +} ApObjCCmdDispatchInfo; + ++ (BOOL)logConfigCommandRegistration { + return NO; +} + ++ (command_rec *)apacheCommandTable { + /* + How to map selectors to commands ? + + All command selectors start with 'configure', eg: + + paras TAKE2, location ACCESS_CONF + - configureDirectory_ScriptAlias:(NSString *)_fake:(NSString *)_real + directoryConfig:(id)_cfg + parameters:(ApacheCmdParms *)_params; + + paras TAKE2, location RSRC_CONF + - configureServer_ScriptAlias:(NSString *)_fake:(NSString *)_real + parameters:(ApacheCmdParms *)_params; + + paras TAKE1, location OR_FILEINFO + - configureFileInfo_PassEnv:(NSString *)_arg + directoryConfig:(id)_cfg + parameters:(ApacheCmdParms *)_params; + + paras FLAG, location OR_FILEINFO + - configureFileInfo_PassEnvFlag:(BOOL)_flag + directoryConfig:(id)_cfg + parameters:(ApacheCmdParms *)_params; + + paras ITERATE, location OR_INDEXES + - configureIndexes_DirectoryIndexIterate:(NSString *)_dir + directoryConfig:(id)_cfg + parameters:(ApacheCmdParms *)_params; + + Allowed Prefixes: + configureDirectory_ + configureServer_ + configureFileInfo_ + configureIndexes_ + + Parameters: + RAW_ARGS, // cmd_func parses command line itself + TAKE1, // one argument only + TAKE2, // two arguments only + ITERATE, // one argument, occuring multiple times + // (e.g., IndexIgnore) + ITERATE2, // two arguments, 2nd occurs multiple times + // (e.g., AddIcon) + FLAG, // One of 'On' or 'Off' + NO_ARGS, // No args at all, e.g. + TAKE12, // one or two arguments + TAKE3, // three arguments only + TAKE23, // two or three arguments + TAKE123, // one, two or three arguments + TAKE13 // one or three arguments + + Request Overrides + * The allowed locations for a configuration directive are the union of + * those indicated by each set bit in the req_override mask. + * + * (req_override & RSRC_CONF) => *.conf outside or + * (req_override & ACCESS_CONF) => *.conf inside or + * (req_override & OR_AUTHCFG) => *.conf inside or + * and .htaccess when AllowOverride + * AuthConfig + * (req_override & OR_LIMIT) => *.conf inside or + * and .htaccess when AllowOverride Limit + * (req_override & OR_OPTIONS) => *.conf anywhere + * and .htaccess when AllowOverride Options + * (req_override & OR_FILEINFO) => *.conf anywhere + * and .htaccess when AllowOverride FileInfo + * (req_override & OR_INDEXES) => *.conf anywhere + * and .htaccess when AllowOverride Indexes + + typedef struct command_struct { + const char *name; // Name of this command + const char *(*func) (); // Function invoked + void *cmd_data; // Extra data, for functions which + // implement multiple commands... + int req_override; // What overrides need to be allowed to + // enable this command. + enum cmd_how args_how; // What the command expects as arguments + + const char *errmsg; // 'usage' message, in case of syntax errors + } command_rec; + */ + ApacheModule *bundleHandler = [self bundleHandler]; + command_rec *cmdtable; + + unsigned count, capacity; + Class c; + + if (bundleHandler == nil) + return NULL; + + count = 0; + capacity = 16; + cmdtable = calloc(capacity + 1, sizeof(command_rec)); + +#if GNU_RUNTIME + /* for the class and each superclass ... */ + for (c = [bundleHandler class]; c != Nil; c = c->super_class) { + struct objc_method_list *cm; + + /* for each method list of the class */ + for (cm = c->methods; cm != NULL; cm = cm->method_next) { + register unsigned i; + + /* for each method in the list */ + for (i = 0; i < cm->method_count; i++) { + const char *methodName; + const char *tmp; + char *tmp2, *tmp3; + unsigned len, argumentCount; + char *configName; + int reqOverride = 0; + enum cmd_how argsHow = 0; + BOOL hasParametersArg; + BOOL hasDirConfigArg; + BOOL isIterate; + BOOL isFlag; + BOOL isRaw; + + if ((methodName = sel_get_name(cm->method_list[i].method_name))==NULL) + continue; + if (methodName[0] != 'c') + /* quick check for 'configure' prefix */ + continue; + + if (strstr(methodName, "configure") != methodName) + /* long check for 'configure' prefix */ + continue; + + tmp = methodName + 9; + + /* search for start of config name, eg _PassEnv */ + + if ((tmp2 = index(tmp, '_')) == NULL) + continue; + tmp2++; // skip underscore + + /* search for end of config name, copy config name */ + + if ((tmp3 = index(tmp2, ':')) == NULL) + continue; + if ((len = (tmp3 - tmp2)) < 3) + /* config name to short ... */ + continue; + + configName = malloc(len + 2); + memcpy(&(configName[0]), tmp2, len); + configName[len] = '\0'; + + /* count args */ + + for (argumentCount = 0; *tmp3 == ':'; tmp3++) + argumentCount++; + tmp3 = NULL; + + if (argumentCount == 0 || argumentCount > 3) { + printf("ERROR(%s): flag and raw configuration selectors " + "only take exactly one argument (sel=%s, command=%s) !!!\n", + __PRETTY_FUNCTION__, methodName, configName); + continue; + } + + /* check suffix (Iterate, Flag) */ + + isIterate = NO; + isFlag = NO; + isRaw = NO; + if ((tmp3 = rindex(configName, 'I'))) { + if (strcmp(tmp3, "Iterate") == 0) { + *tmp3 = '\0'; + isIterate = YES; + } + } + if ((tmp3 = rindex(configName, 'F'))) { + if (strcmp(tmp3, "Flag") == 0) { + *tmp3 = '\0'; + isFlag = YES; + } + } + if ((tmp3 = rindex(configName, 'R'))) { + if (strcmp(tmp3, "Raw") == 0) { + *tmp3 = '\0'; + isRaw = YES; + } + } + + /* derive argument style info */ + + if ((isFlag || isRaw) && (argumentCount != 1)) { + if (argumentCount != 1) { + printf("ERROR(%s): flag and raw configuration selectors " + "only take exactly one argument (sel=%s, command=%s) !!!\n", + __PRETTY_FUNCTION__, methodName, configName); + continue; + } + } + + if (isFlag) { + argsHow = FLAG; + } + else if (isIterate) { + if (argumentCount == 1) + argsHow = ITERATE; + else if (argumentCount == 2) + argsHow = ITERATE2; + else { + printf("ERROR(%s): iterate configuration selectors " + "only take one or two arguments (sel=%s, command=%s) !!!\n", + __PRETTY_FUNCTION__, methodName, configName); + continue; + } + } + else if (isRaw) { + argsHow = RAW_ARGS; + } + else { + switch (argumentCount) { + case 0: + argsHow = NO_ARGS; + break; + case 1: + argsHow = TAKE1; + break; + case 2: + argsHow = TAKE2; + break; + case 3: + argsHow = TAKE3; + break; + default: + printf("ERROR(%s): configuration selectors " + "only take 1-3 arguments (sel=%s, command=%s) !!!\n", + __PRETTY_FUNCTION__, methodName, configName); + continue; + } + } + + /* search for standard parameters */ + + hasParametersArg = strstr(tmp2, "parameters:") != NULL ? YES : NO; + hasDirConfigArg = strstr(tmp2, "directoryConfig:") != NULL ? YES : NO; + + if ([self logConfigCommandRegistration]) { + printf("Found config selector '%s', command '%s' (%i args) ...\n", + methodName, configName, argumentCount); + } + + /* check allowed location */ + + switch (tmp[0]) { + case 'D': + if (strstr(tmp, "Directory") == tmp) { + reqOverride = ACCESS_CONF; + break; + } + case 'S': + if (strstr(tmp, "Server") == tmp) { + reqOverride = RSRC_CONF; + break; + } + case 'I': + if (strstr(tmp, "Indexes") == tmp) { + reqOverride = OR_INDEXES; + break; + } + case 'F': + if (strstr(tmp, "FileInfo") == tmp) { + reqOverride = OR_FILEINFO; + break; + } + case 'O': + if (strstr(tmp, "Options") == tmp) { + reqOverride = OR_OPTIONS; + break; + } + case 'L': + if (strstr(tmp, "Limit") == tmp) { + reqOverride = OR_OPTIONS; + break; + } + case 'A': + if (strstr(tmp, "AuthConfig") == tmp) { + reqOverride = OR_AUTHCFG; + break; + } + default: + printf("%s: invalid directory location in selector '%s' !\n", + __PRETTY_FUNCTION__, methodName); + continue; + } + + /* should check for duplicate entries */ + { + int i; + + for (i = 0; i < count; i++) { + if (strcmp(cmdtable[i].name, configName) == 0) { + /* this should check for alternate argument counts */ + printf("WARNING(%s): found duplicate entry '%s' ...\n", + __PRETTY_FUNCTION__, configName); + i = -1; + break; + } + } + if (i == -1) continue; + } + + /* check command table capacity */ + + if (count >= capacity) { + /* resize command table ... */ + command_rec *old = cmdtable; + unsigned oldCapacity = capacity; + + capacity *= 2; + cmdtable = calloc(capacity + 1,sizeof(command_rec)); + memcpy(cmdtable, old, oldCapacity * sizeof(command_rec)); + if (old) free(old); + } + + /* fill command table entry */ + + cmdtable[count].name = configName /* malloced */; + cmdtable[count].args_how = argsHow; + cmdtable[count].req_override = reqOverride; + + { + NSString *err; + + err = [bundleHandler usageForConfigSelector: + cm->method_list[i].method_name]; + + cmdtable[count].errmsg = [err length] > 0 + ? strdup([err cString]) + : NULL; + } + + { + ApObjCCmdDispatchInfo *info; + + info = calloc(1, sizeof(ApObjCCmdDispatchInfo)); + info->moduleClass = self; + info->sel = cm->method_list[i].method_name; + info->methodName = methodName; + info->command = configName; + info->argsHow = cmdtable[count].args_how; + info->location = cmdtable[count].req_override; + info->isRaw = isRaw; + info->isIterate = isIterate; + info->isFlag = isFlag; + + cmdtable[count].cmd_data = info; + } + + { + void *func; + + func = NULL; + if (reqOverride != RSRC_CONF) { + switch (cmdtable[count].args_how) { + case NO_ARGS: func = configStubTake0; break; + case RAW_ARGS: func = configStubRaw; break; + case TAKE1: func = configStubTake1; break; + case ITERATE: func = configStubIterate; break; + case TAKE2: func = configStubTake2; break; + case TAKE12: func = configStubTake12; break; + case ITERATE2: func = configStubIterate2; break; + case TAKE3: func = configStubTake3; break; + case TAKE23: break; + case TAKE123: func = configStubTake123; break; + case TAKE13: break; + case FLAG: func = configStubFlag; break; + + default: + printf("ERROR(%s): unknown argument style %i !!\n", + __PRETTY_FUNCTION__, cmdtable[count].args_how); + break; + } + } + else { + switch (cmdtable[count].args_how) { + case NO_ARGS: func = serverConfigStubTake0; break; + case RAW_ARGS: func = serverConfigStubRaw; break; + case TAKE1: func = serverConfigStubTake1; break; + case ITERATE: func = serverConfigStubIterate; break; + case TAKE2: func = serverConfigStubTake2; break; + case TAKE12: func = serverConfigStubTake12; break; + case ITERATE2: func = serverConfigStubIterate2; break; + case TAKE3: func = serverConfigStubTake3; break; + case TAKE23: break; + case TAKE123: func = serverConfigStubTake123; break; + case TAKE13: break; + case FLAG: func = serverConfigStubFlag; break; + + default: + printf("ERROR(%s): unknown argument style %i !!\n", + __PRETTY_FUNCTION__, cmdtable[count].args_how); + break; + } + } + cmdtable[count].func = func; + } + if (cmdtable[count].func) + count++; + else { + printf("ERROR(%s): internal error during cmd table setup ...\n", + __PRETTY_FUNCTION__); + } + } + } + } +#else +# warning not ported to this runtime yet ... +#endif + + if (count == 0) { + /* found no commands ... */ + if (cmdtable) { + free(cmdtable); + cmdtable = NULL; + } + } +#if 0 + printf("found %i commands ...\n", count); +#endif + return cmdtable; +} + +#define OBJC_CONFIG_BEGIN \ + NSAutoreleasePool *pool;\ + ApObjCCmdDispatchInfo *info;\ + ApacheCmdParms *paras;\ + ApacheModule *bundleHandler;\ + const char *ares;\ + if ((info = p->info) == NULL)\ + return ap_pstrdup(p->pool, "missing Objective-C dispatch info !");\ + pool = [[NSAutoreleasePool alloc] init];\ + paras = [[ApacheCmdParms alloc] initWithHandle:p];\ + bundleHandler = [[info->moduleClass bundleHandler] retain];\ + { id result; result = nil; + +#define OBJC_CONFIG_END \ + if (result == nil) ares = NULL;\ + else ares = ap_pstrdup(p->pool, [[result description] cString]);\ + }\ + RELEASE(bundleHandler);\ + RELEASE(paras);\ + RELEASE(pool); \ + return ares; + +static const char *configStubRaw(cmd_parms *p, void *d, char *a0) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, id, ApacheCmdParms *); + NSString *s0; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char *configStubFlag(cmd_parms *p, void *d, int flag) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, BOOL, id, ApacheCmdParms *); + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, flag?YES:NO, d, paras); + else + result = @"did not find method for config call .."; + } + OBJC_CONFIG_END; +} +static const char *configStubTake1(cmd_parms *p, void *d, char *a0) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, id, ApacheCmdParms *); + NSString *s0; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +static const char *configStubIterate(cmd_parms *p, void *d, char *a0) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, id, ApacheCmdParms *); + NSString *s0; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char + *configStubIterate2(cmd_parms *p, void *d, char *a0, char *a1) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, id, ApacheCmdParms *); + NSString *s0, *s1; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +static const char *configStubTake0(cmd_parms *p, void *d) { + return NULL; +} + +static const char *configStubTake2(cmd_parms *p, void *d, char *a0, char *a1) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, id, ApacheCmdParms *); + NSString *s0, *s1; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +static const char *configStubTake12(cmd_parms *p, void *d, char *a0, char *a1){ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, id, ApacheCmdParms *); + NSString *s0, *s1; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char * + configStubTake3(cmd_parms *p, void *d, char *a0, char *a1, char *a2) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, NSString *,id, ApacheCmdParms *); + NSString *s0, *s1, *s2; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + s2 = a2 ? [[NSString alloc] initWithCString:a2] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, s2, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s2); + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char * + configStubTake123(cmd_parms *p, void *d, char *a0, char *a1, char *a2) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, NSString *,id, ApacheCmdParms *); + NSString *s0, *s1, *s2; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + s2 = a2 ? [[NSString alloc] initWithCString:a2] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, s2, d, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s2); + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +/* server stubs */ + +static const char *serverConfigStubRaw(cmd_parms *p, void *d, char *a0) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, ApacheCmdParms *); + NSString *s0; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char *serverConfigStubFlag(cmd_parms *p, void *d, int flag) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, BOOL, ApacheCmdParms *); + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, flag?YES:NO, paras); + else + result = @"did not find method for config call .."; + } + OBJC_CONFIG_END; +} +static const char *serverConfigStubTake1(cmd_parms *p, void *d, char *a0) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, ApacheCmdParms *); + NSString *s0; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +static const char *serverConfigStubIterate(cmd_parms *p, void *d, char *a0) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, ApacheCmdParms *); + NSString *s0; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char + *serverConfigStubIterate2(cmd_parms *p, void *d, char *a0, char *a1) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, ApacheCmdParms *); + NSString *s0, *s1; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +static const char *serverConfigStubTake0(cmd_parms *p, void *d) { + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, ApacheCmdParms *); + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, paras); + else + result = @"did not find method for config call .."; + } + OBJC_CONFIG_END; +} + +static const char * +serverConfigStubTake2(cmd_parms *p, void *d, char *a0, char *a1) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, ApacheCmdParms *); + NSString *s0, *s1; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +static const char * +serverConfigStubTake12(cmd_parms *p, void *d, char *a0, char *a1) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, ApacheCmdParms *); + NSString *s0, *s1; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char * + serverConfigStubTake3(cmd_parms *p, void *d, char *a0, char *a1, char *a2) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, NSString *, ApacheCmdParms *); + NSString *s0, *s1, *s2; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + s2 = a2 ? [[NSString alloc] initWithCString:a2] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, s2, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s2); + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} +static const char * + serverConfigStubTake123(cmd_parms *p, void *d, char *a0, char *a1, char *a2) +{ + OBJC_CONFIG_BEGIN { + id (*m)(id, SEL, NSString *, NSString *, NSString *, ApacheCmdParms *); + NSString *s0, *s1, *s2; + + s0 = a0 ? [[NSString alloc] initWithCString:a0] : nil; + s1 = a1 ? [[NSString alloc] initWithCString:a1] : nil; + s2 = a2 ? [[NSString alloc] initWithCString:a2] : nil; + + if ((m = (void *)[bundleHandler methodForSelector:info->sel])) + result = m(bundleHandler, info->sel, s0, s1, s2, paras); + else + result = @"did not find method for config call .."; + + RELEASE(s2); + RELEASE(s1); + RELEASE(s0); + } + OBJC_CONFIG_END; +} + +@end /* ApModuleBaseClass(ConfigCommands) */ diff --git a/Recycler/mod_objc/ApModuleBaseClass+Handler.m b/Recycler/mod_objc/ApModuleBaseClass+Handler.m new file mode 100644 index 00000000..9a59f53f --- /dev/null +++ b/Recycler/mod_objc/ApModuleBaseClass+Handler.m @@ -0,0 +1,359 @@ +// $Id: ApModuleBaseClass+Handler.m,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#include "ApModuleBaseClass.h" +#include +#include "http_config.h" +#import +#import +#import +#include "ApacheServer.h" +#include "ApacheResourcePool.h" +#include "ApacheModule.h" +#include "ApacheRequest.h" + +@implementation ApModuleBaseClass(HandlerCallback) + ++ (BOOL)logHandlerRegistration { + return NO; +} + ++ (handler_rec *)apacheHandlerTable { + /* + KNOWN problem: this method produces memory leaks !! + + How to map selectors to handlers ? + + There are two-kinds, content-type handlers and named handlers: + + text/plain -> + - (int)handleTextPlainRequest:(ApacheRequest *)_rq; + ngobjweb-adaptor -> + - (int)performNgobjwebAdaptorRequest:(ApacheRequest *)_rq; + + // This structure records the existence of handlers in a module... + + typedef struct { + const char *content_type; // MUST be all lower case + int (*handler) (request_rec *); + } handler_rec; + */ + ApacheModule *bundleHandler = [self bundleHandler]; + handler_rec *handlerTable = NULL; + unsigned count, capacity; + Class c; + + if (bundleHandler == nil) + return NULL; + + count = 0; + capacity = 16; + handlerTable = calloc(capacity + 1, sizeof(handler_rec)); + +#if GNU_RUNTIME + /* for the class and each superclass ... */ + for (c = [bundleHandler class]; c != Nil; c = c->super_class) { + struct objc_method_list *cm; + + /* for each method list of the class */ + for (cm = c->methods; cm != NULL; cm = cm->method_next) { + register unsigned i; + + /* for each method in the list */ + for (i = 0; i < cm->method_count; i++) { + const char *methodName; + + if ((methodName = sel_get_name(cm->method_list[i].method_name))) { + if (strstr(methodName, "handle") == methodName) { + /* could be a MIME-type handler ... */ + const unsigned char *rq, *spec; + unsigned j, len, n, bufLen; + unsigned char *buf; + + if ((rq = strstr(methodName, "Request:")) == NULL) + continue; + + spec = methodName + 6; /* skip 'handle' */ + if ((len = (rq - spec)) == 0) { + /* type spec too long or too short ... */ + continue; + } + + bufLen = len * 2 + 2; + buf = malloc(bufLen); + + buf[0] = tolower(spec[0]); + for (j = 1, n = 1; j < len; j++) { + if (isupper(spec[j])) { + buf[n] = '/'; + n++; + buf[n] = tolower(spec[j]); + n++; + } + else { + buf[n] = spec[j]; + n++; + } + } + buf[n] = '\0'; + + if (count >= capacity) { + /* resize handler table ... */ + handler_rec *old = handlerTable; + unsigned oldCapacity = capacity; + + capacity *= 2; + handlerTable = calloc(capacity + 1,sizeof(handler_rec)); + memcpy(handlerTable, old, oldCapacity * sizeof(handler_rec)); + if (old) free(old); + } + + /* memory dup'ed is currently never freed ! */ + + handlerTable[count].content_type = buf; + handlerTable[count].handler = [self handleRequestStubFunction]; + count++; + + if ([self logHandlerRegistration]) { + printf("%s: found method '%s' for MIME handler '%s' ...\n", + __PRETTY_FUNCTION__, methodName, buf); + } + } + else if (strstr(methodName, "perform") == methodName) { + /* could be a named handler ... */ + const unsigned char *rq, *spec; + unsigned j, len, n, bufLen; + unsigned char *buf; + + if ((rq = strstr(methodName, "Request:")) == NULL) + continue; + spec = methodName + 7; /* skip 'perform' */ + if ((len = (rq - spec)) == 0) { + /* type spec too long or too short ... */ + continue; + } + + bufLen = len * 2 + 2; + buf = malloc(bufLen); + + buf[0] = tolower(spec[0]); + for (j = 1, n = 1; j < len; j++) { + if (isupper(spec[j])) { + buf[n] = '-'; + n++; + buf[n] = tolower(spec[j]); + n++; + } + else { + buf[n] = spec[j]; + n++; + } + } + buf[n] = '\0'; + + if (count >= capacity) { + /* resize handler table ... */ + handler_rec *old = handlerTable; + unsigned oldCapacity = capacity; + + capacity *= 2; + handlerTable = calloc(capacity + 1,sizeof(handler_rec)); + memcpy(handlerTable, old, oldCapacity * sizeof(handler_rec)); + if (old) free(old); + } + + /* memory dup'ed is currently never freed ! */ + + handlerTable[count].content_type = buf; + handlerTable[count].handler = [self handleRequestStubFunction]; + count++; + + if ([self logHandlerRegistration]) { + printf("%s: found method '%s' for named handler '%s' ...\n", + __PRETTY_FUNCTION__, methodName, buf); + } + } + } + } + } + } + +#else +# warning not ported to this runtime yet ... +#endif + + if (count == 0) { + /* found no handlers ... */ + if (handlerTable) { + free(handlerTable); + handlerTable = NULL; + } + } +#if 0 + printf("found %i handlers ...\n", count); +#endif + return handlerTable; +} + +/* the request dispatcher */ + ++ (int)_handleRequest:(void *)_request { + request_rec *req = _request; + int result; + ApacheModule *bundleHandler = [self bundleHandler]; + + if (bundleHandler == nil) { + printf("%s: missing bundle handler !!!\n", __PRETTY_FUNCTION__); + return 500; + } + + result = DECLINED; + + if (req->handler) { + /* dispatch based on handler set ... */ + unsigned len; + + if ((len = strlen(req->handler)) > 0) { + unsigned char *buf; + unsigned i, j; + int (*h)(id,SEL,id); + SEL sel; + BOOL nextUpper; + + buf = calloc(len + 64, sizeof(char)); + strcpy(buf, "perform"); + for (i = 0, j = strlen(buf), nextUpper = YES; i < len; i++) { + if (req->handler[i] == '-') { + /* skip dash and add next char in uppercase */ + nextUpper = YES; + } + else { + buf[j] = (nextUpper) + ? toupper(req->handler[i]) + : req->handler[i]; + j++; + nextUpper = NO; + } + } + buf[j] = '\0'; + strcat(buf, "Request:"); + sel = sel_get_any_uid(buf); + free(buf); + buf = NULL; + +#if 0 + printf("CALL: %s\n", sel_get_name(sel)); + fflush(stdout); +#endif + + if (sel == NULL) { + fprintf(stderr, + "%s: did not find selector for handler '%s' !\n", + __PRETTY_FUNCTION__, req->handler); + result = 500; + } + else if ((h = (void *)[bundleHandler methodForSelector:sel])) { + NSAutoreleasePool *pool; + ApacheRequest *or; + + pool = [[NSAutoreleasePool alloc] init]; + or = [[ApacheRequest alloc] initWithHandle:_request]; + + result = h(bundleHandler, sel, or); + + if (result == ApacheDeclineRequest) + result = DECLINED; + else if (result == ApacheHandledRequest) + result = OK; + + RELEASE(or); + RELEASE(pool); + } + else { + fprintf(stderr, + "%s: did not find handler method '%s' for name '%s' !\n", + __PRETTY_FUNCTION__, sel_get_name(sel), req->handler); + result = 500; + } + } + } + else if (req->content_type) { + /* dispatch based on MIME-type ... */ + unsigned len; + + if ((len = strlen(req->content_type)) > 0) { + unsigned char *buf; + unsigned i, j; + int (*h)(id,SEL,id); + SEL sel; + BOOL nextUpper; + + buf = calloc(len + 64, sizeof(char)); + strcpy(buf, "handle"); + for (i = 0, j = strlen(buf), nextUpper = YES; i < len; i++) { + if (req->content_type[i] == '/') { + /* skip slash and add next char in uppercase */ + nextUpper = YES; + } + else { + buf[j] = (nextUpper) + ? toupper(req->content_type[i]) + : req->content_type[i]; + j++; + nextUpper = NO; + } + } + buf[j] = '\0'; + strcat(buf, "Request:"); + sel = sel_get_any_uid(buf); + free(buf); + buf = NULL; + +#if 0 + printf("CALL: %s\n", sel_get_name(sel)); + fflush(stdout); +#endif + + if (sel == NULL) { + fprintf(stderr, + "%s: did not find selector for mime type '%s' !\n", + __PRETTY_FUNCTION__, req->content_type); + result = 500; + } + else if ((h = (void *)[bundleHandler methodForSelector:sel])) { + NSAutoreleasePool *pool; + ApacheRequest *or; + + pool = [[NSAutoreleasePool alloc] init]; + or = [[ApacheRequest alloc] initWithHandle:_request]; + + result = h(bundleHandler, sel, or); + + if (result == ApacheDeclineRequest) + result = DECLINED; + else if (result == ApacheHandledRequest) + result = OK; + + RELEASE(or); + RELEASE(pool); + } + else { + fprintf(stderr, + "%s: did not find handler method '%s' for mime type '%s' !\n", + __PRETTY_FUNCTION__, sel ? sel_get_name(sel) : "", + req->content_type); + result = 500; + } + } + } + else { + /* nothing to dispatch on ... */ + fprintf(stderr, + "%s: found nothing to dispatch on " + "(neither handler type nor name) !\n", + __PRETTY_FUNCTION__); + result = DECLINED; + } + return result; +} + +@end /* ApModuleBaseClass(HandlerCallback) */ diff --git a/Recycler/mod_objc/ApModuleBaseClass.h b/Recycler/mod_objc/ApModuleBaseClass.h new file mode 100644 index 00000000..f5c3ba1e --- /dev/null +++ b/Recycler/mod_objc/ApModuleBaseClass.h @@ -0,0 +1,66 @@ +// $Id: ApModuleBaseClass.h,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#ifndef __ApModuleBaseClass_H__ +#define __ApModuleBaseClass_H__ + +#import + +@class ApacheModule; + +@interface ApModuleBaseClass : NSObject + ++ (void)setBundleHandler:(ApacheModule *)_handler; ++ (ApacheModule *)bundleHandler; + +/* return an initialized Apache module structure ... */ ++ (void *)apacheModule; + +@end + +@interface ApModuleBaseClass(SubclassOverrides) + +/* return an Apache module structure with all callback wrappers set ... */ ++ (void *)apacheTemplateModule; + +/* return the uninitialized Apache module structure */ ++ (void *)apacheModuleStructure; + +/* the stub to dispatch handlers (placed in the handler_rec structure) */ ++ (void *)handleRequestStubFunction; + +@end + +@interface ApModuleBaseClass(BasicModuleCallbacks) + ++ (void)_moduleInit:(void *)s pool:(void *)p; + ++ (void *)_perDirConfCreate:(void *)dirspec pool:(void *)p; ++ (void *)_perDirConfMerge:(void *)baseCconf with:(void *)newCconf + pool:(void *)p; ++ (void *)_perServerConfCreate:(void *)s pool:(void *)p; ++ (void *)_perServerConfMerge:(void *)baseConf with:(void *)newConf + pool:(void *)p; + ++ (int)_translateHandler:(void *)_request; ++ (int)_apCheckUserId:(void *)_request; ++ (int)_authChecker:(void *)_request; ++ (int)_accessChecker:(void *)_request; ++ (int)_typeChecker:(void *)_request; ++ (int)_fixerUpper:(void *)_request; ++ (int)_logger:(void *)_request; ++ (int)_headerParser:(void *)_request; + ++ (void)_childInit:(void *)_server pool:(void *)_pool; ++ (void)_childExit:(void *)_server pool:(void *)_pool; + ++ (int)_postReadRequest:(void *)_request; + +@end + +@interface ApModuleBaseClass(HandlerCallback) + ++ (int)_handleRequest:(void *)_request; + +@end + +#endif /* ApModuleBaseClass */ diff --git a/Recycler/mod_objc/ApModuleBaseClass.m b/Recycler/mod_objc/ApModuleBaseClass.m new file mode 100644 index 00000000..3919907a --- /dev/null +++ b/Recycler/mod_objc/ApModuleBaseClass.m @@ -0,0 +1,129 @@ +// $Id: ApModuleBaseClass.m,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#include "ApModuleBaseClass.h" +#include +#include "http_config.h" +#import +#import +#import +#include "ApacheServer.h" +#include "ApacheResourcePool.h" +#include "ApacheModule.h" +#include "ApacheRequest.h" + +@interface ApModuleBaseClass(Privates) + ++ (handler_rec *)apacheHandlerTable; ++ (command_rec *)apacheCommandTable; + +@end + +@implementation ApModuleBaseClass + ++ (void)setBundleHandler:(ApacheModule *)_handler { + [self subclassResponsibility:_cmd]; +} ++ (ApacheModule *)bundleHandler { + return [self subclassResponsibility:_cmd]; +} + ++ (void *)apacheModule { + ApacheModule *bundleHandler = [self bundleHandler]; + module *mod, *tmpl; + + if (bundleHandler == nil) { + NSLog(@"%s: missing bundle handler !!!", __PRETTY_FUNCTION__); + return NULL; + } + + mod = [self apacheModuleStructure]; + tmpl = [self apacheTemplateModule]; + + mod->cmds = [self apacheCommandTable]; + mod->handlers = [self apacheHandlerTable]; + + /* fill module based on handler reflection ... */ + + mod->init = + [bundleHandler respondsToSelector: + @selector(initializeModuleForServer:inPool:)] + ? tmpl->init : NULL; + + mod->create_dir_config = + [bundleHandler respondsToSelector: + @selector(createPerDirectoryConfigInPool:)] + ? tmpl->create_dir_config : NULL; + + mod->merge_dir_config = + [bundleHandler respondsToSelector: + @selector(mergePerDirectoryBaseConfig:withNewConfig:inPool:)] + ? tmpl->merge_dir_config : NULL; + + mod->create_server_config = + [bundleHandler respondsToSelector: + @selector(createPerServerConfig:inPool:)] + ? tmpl->create_server_config : NULL; + + mod->merge_server_config = + [bundleHandler respondsToSelector: + @selector(mergePerServerBaseConfig:withNewConfig:inPool:)] + ? tmpl->merge_server_config : NULL; + + mod->translate_handler = + [bundleHandler respondsToSelector:@selector(handleTranslationForRequest:)] + ? tmpl->translate_handler : NULL; + mod->ap_check_user_id = + [bundleHandler respondsToSelector:@selector(checkUserIdFromRequest:)] + ? tmpl->ap_check_user_id : NULL; + mod->auth_checker = + [bundleHandler respondsToSelector:@selector(checkAuthForRequest:)] + ? tmpl->auth_checker : NULL; + mod->access_checker = + [bundleHandler respondsToSelector:@selector(checkAccessForRequest:)] + ? tmpl->access_checker : NULL; + mod->type_checker = + [bundleHandler respondsToSelector:@selector(checkTypeForRequest:)] + ? tmpl->type_checker : NULL; + mod->logger = + [bundleHandler respondsToSelector:@selector(logRequest:)] + ? tmpl->logger : NULL; + + mod->fixer_upper = + [bundleHandler respondsToSelector:@selector(fixupRequest:)] + ? tmpl->fixer_upper : NULL; + + mod->header_parser = + [bundleHandler respondsToSelector:@selector(parseHeadersOfRequest:)] + ? tmpl->header_parser : NULL; + + mod->post_read_request = + [bundleHandler respondsToSelector:@selector(postProcessRequest:)] + ? tmpl->post_read_request : NULL; + + mod->child_init = + [bundleHandler respondsToSelector: + @selector(initializeChildProcessWithServer:inPool:)] + ? tmpl->child_init : NULL; + mod->child_exit = + [bundleHandler respondsToSelector: + @selector(exitChildProcessWithServer:inPool:)] + ? tmpl->child_exit : NULL; + + return mod; +} + +@end /* ApModuleBaseClass */ + +@implementation ApModuleBaseClass(SubclassOverrides) + ++ (void *)apacheTemplateModule { + return [self subclassResponsibility:_cmd]; +} ++ (void *)apacheModuleStructure { + return [self subclassResponsibility:_cmd]; +} ++ (void *)handleRequestStubFunction { + return [self subclassResponsibility:_cmd]; +} + +@end /* ApModuleBaseClass(SubclassOverrides) */ diff --git a/Recycler/mod_objc/ApTest.m b/Recycler/mod_objc/ApTest.m new file mode 100644 index 00000000..3940a2aa --- /dev/null +++ b/Recycler/mod_objc/ApTest.m @@ -0,0 +1,101 @@ +// $Id: ApTest.m,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#include "ApacheModule.h" +#import + +@interface ApTest : ApacheModule +@end + +#include "ApacheResourcePool.h" + +@implementation ApTest + +- (id)init { + //printf("INIT 0x%08X ..\n", (unsigned int)self); + return self; +} +- (void)dealloc { + //printf("DEALLOC 0x%08X ..\n", (unsigned int)self); + [super dealloc]; +} + +/* config commands */ + +- (id)configureDirectory_MyDirAlias:(NSString *)_fake:(NSString *)_real + directoryConfig:(id)_cfg + parameters:(ApacheCmdParms *)_params +{ + [self logWithFormat:@"MyDirAlias(%@,%@,config=%@)", _fake, _real, _cfg]; + [_cfg setObject:_real forKey:_fake]; + return nil; +} +- (id)configureServer_MyServerAlias:(NSString *)_fake:(NSString *)_real + parameters:(ApacheCmdParms *)_params +{ + [self logWithFormat:@"MyServerAlias(%@,%@)", _fake, _real]; + return nil; +} + +- (id)configureDirectory_PrintDirConfig:(NSString *)_fake + directoryConfig:(id)_cfg + parameters:(ApacheCmdParms *)_params +{ + [self logWithFormat:@"DIR: %@", _cfg]; + return nil; +} + +/* handlers */ + +- (int)handleTextHtmlRequest:(ApacheRequest *)_rq { + printf("%s ...\n", __PRETTY_FUNCTION__); + return ApacheDeclineRequest; +} +- (int)performApTestRequest:(ApacheRequest *)_rq { + printf("%s ...\n", __PRETTY_FUNCTION__); + return ApacheDeclineRequest; +} + +/* callbacks */ + +#if 0 +- (void)initializeModuleForServer:(ApacheServer *)_server + inPool:(ApacheResourcePool *)_pool +{ + [self debugWithFormat:@"init module for server %@", _server]; +} +#endif + +- (id)createPerDirectoryConfigInPool:(ApacheResourcePool *)_pool { + NSMutableDictionary *md; + + md = [[NSMutableDictionary alloc] initWithCapacity:128]; + [_pool releaseObject:md]; + return md; +} +- (id)mergePerDirectoryBaseConfig:(id)_base withNewConfig:(id)_new + inPool:(ApacheResourcePool *)_pool +{ + [self debugWithFormat:@"merge dir config %@ with %@ ..", + _base, _new]; + return _base; +} + +- (id)createPerServerConfig:(ApacheServer *)_server + inPool:(ApacheResourcePool *)_pool +{ + return [NSMutableDictionary dictionaryWithCapacity:128]; +} +- (id)mergePerServerBaseConfig:(id)_base withNewConfig:(id)_new + inPool:(ApacheResourcePool *)_pool +{ + [self debugWithFormat:@"merge server config %@ with %@ ..", + _base, _new]; + return nil; +} + +- (int)logRequest:(ApacheRequest *)_rq { + [self logWithFormat:@"REQUEST: %@", _rq]; + return ApacheDeclineRequest; +} + +@end /* ApTest */ diff --git a/Recycler/mod_objc/ApacheCmdParms.h b/Recycler/mod_objc/ApacheCmdParms.h new file mode 100644 index 00000000..433b52f0 --- /dev/null +++ b/Recycler/mod_objc/ApacheCmdParms.h @@ -0,0 +1,33 @@ +// $Id: ApacheCmdParms.h,v 1.1 2004/06/08 11:15:58 helge Exp $ + +#ifndef __ApacheCmdParms_H__ +#define __ApacheCmdParms_H__ + +#include + +@class ApacheResourcePool, ApacheServer; + +@interface ApacheCmdParms : ApacheObject +{ +} + +/* accessors */ + +- (void *)userInfo; + +/* Pool to allocate new storage in */ +- (ApacheResourcePool *)pool; + +/* + Pool for scratch memory; persists during + configuration, but wiped before the first + request is served... +*/ +- (ApacheResourcePool *)temporaryPool; + +/* Server_rec being configured for */ +- (ApacheServer *)server; + +@end + +#endif /* __ApacheCmdParms_H__ */ diff --git a/Recycler/mod_objc/ApacheCmdParms.m b/Recycler/mod_objc/ApacheCmdParms.m new file mode 100644 index 00000000..e88d4543 --- /dev/null +++ b/Recycler/mod_objc/ApacheCmdParms.m @@ -0,0 +1,66 @@ +// $Id: ApacheCmdParms.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheCmdParms.h" +#include "ApacheResourcePool.h" +#include "httpd.h" +#include "http_config.h" +#import + +@implementation ApacheCmdParms + +#define AP_HANDLE ((cmd_parms *)self->handle) + +- (void *)userInfo { + /* Argument to command from cmd_table */ + return AP_HANDLE->info; +} + +- (ApacheResourcePool *)pool { + ApacheResourcePool *pool; + + pool = [[ApacheResourcePool alloc] + initWithHandle:AP_HANDLE->pool freeWhenDone:NO]; + return AUTORELEASE(pool); +} +- (ApacheResourcePool *)temporaryPool { + ApacheResourcePool *pool; + + pool = [[ApacheResourcePool alloc] + initWithHandle:AP_HANDLE->temp_pool + freeWhenDone:NO]; + return AUTORELEASE(pool); +} + +- (ApacheServer *)server { + return [[[ApacheServer alloc] initWithHandle:AP_HANDLE->server] autorelease]; +} + +- (NSString *)path { + const unsigned char *c; + + if ((c = AP_HANDLE->path) == NULL) + return nil; + return [[[NSString alloc] initWithCString:c] autorelease]; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + id tmp; + + ms = [NSMutableString stringWithCapacity:256]; + [ms appendFormat:@"<0x%08X[%@]: ", self, NSStringFromClass([self class])]; + + [ms appendFormat:@" 0x%08X ui=0x%08X", self->handle, [self userInfo]]; + + if ((tmp = [self path])) + [ms appendFormat:@" path=%@", tmp]; + if ((tmp = [self server])) + [ms appendFormat:@" server=%@", tmp]; + + [ms appendString:@">"]; + return ms; +} + +@end /* ApacheCmdParms */ diff --git a/Recycler/mod_objc/ApacheConnection.h b/Recycler/mod_objc/ApacheConnection.h new file mode 100644 index 00000000..f2e8f61e --- /dev/null +++ b/Recycler/mod_objc/ApacheConnection.h @@ -0,0 +1,46 @@ +// $Id: ApacheConnection.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheConnection_H__ +#define __ApacheConnection_H__ + +#include "ApacheObject.h" + +@class NSString; +@class ApacheResourcePool, ApacheServer; + +@interface ApacheConnection : ApacheObject + +/* accessors */ + +- (ApacheResourcePool *)connectionPool; +- (ApacheServer *)server; +- (ApacheServer *)baseServer; + +/* Information about the connection itself */ + +- (int)childNumber; + +/* Who is the client? */ + +- (NSString *)remoteIP; +- (NSString *)remoteHost; +- (NSString *)remoteLogName; +- (NSString *)user; +- (NSString *)authorizationType; + +- (NSString *)localIP; +- (NSString *)localHost; + +- (BOOL)isAborted; + +- (BOOL)usesKeepAlive; +- (BOOL)doesNotUseKeepAlive; +- (BOOL)didUseKeepAlive; +- (int)numberOfKeepAlives; + +- (BOOL)isValidDoubleReverseDNS; +- (BOOL)isInvalidDoubleReverseDNS; + +@end + +#endif /* __ApacheConnection_H__ */ diff --git a/Recycler/mod_objc/ApacheConnection.m b/Recycler/mod_objc/ApacheConnection.m new file mode 100644 index 00000000..b7b102b8 --- /dev/null +++ b/Recycler/mod_objc/ApacheConnection.m @@ -0,0 +1,110 @@ +// $Id: ApacheConnection.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheConnection.h" +#import +#include "httpd.h" + +@implementation ApacheConnection +#define AP_HANDLE ((conn_rec *)self->handle) + +/* accessors */ + +- (ApacheResourcePool *)connectionPool { + return [ApacheResourcePool objectWithHandle:AP_HANDLE->pool]; +} +- (ApacheServer *)server { + return [ApacheServer objectWithHandle:AP_HANDLE->server]; +} +- (ApacheServer *)baseServer { + return [ApacheServer objectWithHandle:AP_HANDLE->base_server]; +} + +/* Information about the connection itself */ + +- (int)childNumber { + return AP_HANDLE->child_num; +} + +/* Who is the client? */ + +// struct sockaddr_in local_addr; +// struct sockaddr_in remote_addr; +- (NSString *)remoteIP { + return [NSString stringWithCString:AP_HANDLE->remote_ip]; +} +- (NSString *)remoteHost { + return [NSString stringWithCString:AP_HANDLE->remote_host]; +} +- (NSString *)remoteLogName { + return [NSString stringWithCString:AP_HANDLE->remote_logname]; +} +- (NSString *)user { + return [NSString stringWithCString:AP_HANDLE->user]; +} +- (NSString *)authorizationType { + return [NSString stringWithCString:AP_HANDLE->ap_auth_type]; +} + +- (NSString *)localIP { + return [NSString stringWithCString:AP_HANDLE->local_ip]; +} +- (NSString *)localHost { + return [NSString stringWithCString:AP_HANDLE->local_host]; +} + +- (BOOL)isAborted { + return AP_HANDLE->aborted ? YES : NO; +} +- (BOOL)usesKeepAlive { + return AP_HANDLE->keepalive == 1 ? YES : NO; +} +- (BOOL)doesNotUseKeepAlive { + return AP_HANDLE->keepalive == -1 ? YES : NO; +} +- (BOOL)didUseKeepAlive { + return AP_HANDLE->keptalive ? YES : NO; +} + +- (int)numberOfKeepAlives { + return AP_HANDLE->keepalives; +} + +- (BOOL)isValidDoubleReverseDNS { + return AP_HANDLE->double_reverse == 1 ? YES : NO; +} +- (BOOL)isInvalidDoubleReverseDNS { + return AP_HANDLE->double_reverse == -1 ? YES : NO; +} + +#undef AP_HANDLE + + +- (NSString *)description { + NSMutableString *ms; + id tmp; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + [ms appendFormat:@" 0x%08X", self->handle]; + + if ([self isAborted]) [ms appendString:@" aborted"]; + if ([self usesKeepAlive]) [ms appendString:@" keepalive"]; + if ([self didUseKeepAlive]) [ms appendString:@" did-keepalive"]; + + if ([self numberOfKeepAlives] > 0) + [ms appendFormat:@" #keepalives=%i", [self numberOfKeepAlives]]; + + tmp = [self remoteIP]; + if ([tmp length] > 0) [ms appendFormat:@" remoteIP=%@", tmp]; + + tmp = [self user]; + if ([tmp length] > 0) [ms appendFormat:@" user=%@", tmp]; + + tmp = [self authorizationType]; + if ([tmp length] > 0) [ms appendFormat:@" auth=%@", tmp]; + + [ms appendString:@">"]; + return ms; +} + +@end /* ApacheConnection */ diff --git a/Recycler/mod_objc/ApacheModule.h b/Recycler/mod_objc/ApacheModule.h new file mode 100644 index 00000000..cb3402dd --- /dev/null +++ b/Recycler/mod_objc/ApacheModule.h @@ -0,0 +1,116 @@ +// $Id: ApacheModule.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheModule_H__ +#define __ApacheModule_H__ + +#import + +@class NSString; +@class ApacheCmdParms, ApacheResourcePool, ApacheServer; + +@interface ApacheModule : NSObject + +/* return the usage string for config commands */ +- (NSString *)usageForConfigSelector:(SEL)_selector; + +/* logging */ + +- (void)logWithFormat:(NSString *)_format, ...; +- (void)debugWithFormat:(NSString *)_format, ...; + +@end + +@class ApacheRequest; + +/* + Note: Modules should not rely on the order in which create_server_config + and create_dir_config are called. +*/ + +@interface ApacheModule(ConfigOperations) + +- (id)createPerDirectoryConfigInPool:(ApacheResourcePool *)_pool; +- (id)mergePerDirectoryBaseConfig:(id)_base withNewConfig:(id)_new + inPool:(ApacheResourcePool *)_pool; + +- (id)createPerServerConfig:(ApacheServer *)_server + inPool:(ApacheResourcePool *)_pool; +- (id)mergePerServerBaseConfig:(id)_base withNewConfig:(id)_new + inPool:(ApacheResourcePool *)_pool; + +/* + -initializeModuleForServer:inPool: occurs after config parsing, but + before any children are forked. +*/ +- (void)initializeModuleForServer:(ApacheServer *)_server + inPool:(ApacheResourcePool *)_pool; + +@end + +/* Hooks for getting into the middle of server ops ... */ + +extern int ApacheDeclineRequest; +extern int ApacheHandledRequest; + +@interface ApacheModule(ServerOperations) + +/* translate_handler --- translate URI to filename */ +- (int)handleTranslationForRequest:(ApacheRequest *)_req; + +/* + access_checker --- check access by host address, etc. All of these + run; if all decline, that's still OK. +*/ +- (int)checkAccessForRequest:(ApacheRequest *)_req; + +/* check_user_id --- get and validate user id from the HTTP request */ +- (int)checkUserIdFromRequest:(ApacheRequest *)_req; + +/* + auth_checker --- see if the user (from check_user_id) is OK *here*. + If all of *these* decline, the request is rejected + (as a SERVER_ERROR, since the module which was + supposed to handle this was configured wrong). +*/ +- (int)checkAuthForRequest:(ApacheRequest *)_req; + +/* + type_checker --- Determine MIME type of the requested entity; + sets content_type, _encoding and _language fields. +*/ +- (int)checkTypeForRequest:(ApacheRequest *)_req; + +/* logger --- log a transaction. */ +- (int)logRequest:(ApacheRequest *)_req; + +- (int)fixupRequest:(ApacheRequest *)_req; +- (int)parseHeadersOfRequest:(ApacheRequest *)_req; + +/* + post_read_request --- run right after read_request or internal_redirect, + and not run during any subrequests. +*/ +- (int)postProcessRequest:(ApacheRequest *)_req; + +@end + +/* Regardless of the model the server uses for managing "units of + * execution", i.e. multi-process, multi-threaded, hybrids of those, + * there is the concept of a "heavy weight process". That is, a + * process with its own memory space, file spaces, etc. This method, + * child_init, is called once for each heavy-weight process before + * any requests are served. Note that no provision is made yet for + * initialization per light-weight process (i.e. thread). The + * parameters passed here are the same as those passed to the global + * init method above. + */ +@interface ApacheModule(ForkOperations) + +- (void)initializeChildProcessWithServer:(ApacheServer *)_server + inPool:(ApacheResourcePool *)_pool; +- (void)exitChildProcessWithServer:(ApacheServer *)_server + inPool:(ApacheResourcePool *)_pool; + +@end + +#endif /* __ApacheModule_H__ */ diff --git a/Recycler/mod_objc/ApacheModule.m b/Recycler/mod_objc/ApacheModule.m new file mode 100644 index 00000000..76e254a0 --- /dev/null +++ b/Recycler/mod_objc/ApacheModule.m @@ -0,0 +1,59 @@ +// $Id: ApacheModule.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheModule.h" +#include "ApacheCmdParms.h" +#include "ApacheResourcePool.h" +#import +#include "httpd.h" + +int ApacheDeclineRequest = DECLINED; +int ApacheHandledRequest = OK; + +@implementation ApacheModule + +- (NSString *)usageForConfigSelector:(SEL)_selector { + return nil; +} + +/* logging */ + +- (void)logWithFormat:(NSString *)_format, ... { + NSString *value = nil; + va_list ap; + + va_start(ap, _format); + value = [NSString stringWithFormat:_format arguments:ap]; + va_end(ap); + +#if DEBUG + printf("|0x%08X| %s\n", (unsigned int)self, [[value description] cString]); +#else + NSLog(@"|0x%08X| %@", self, value); +#endif +} +- (void)debugWithFormat:(NSString *)_format, ... { + static char showDebug = 2; + NSString *value = nil; + va_list ap; + + if (showDebug == 2) { +#if 0 + showDebug = [WOApplication isDebuggingEnabled] ? 1 : 0; +#endif + } + + if (showDebug) { + va_start(ap, _format); + value = [NSString stringWithFormat:_format arguments:ap]; + va_end(ap); + +#if DEBUG + printf("|0x%08X|D %s\n", (unsigned int)self, + [[value description] cString]); +#else + NSLog(@"|0x%08X|D %@", self, value); +#endif + } +} + +@end /* ApacheModule */ diff --git a/Recycler/mod_objc/ApacheObject.h b/Recycler/mod_objc/ApacheObject.h new file mode 100644 index 00000000..93f1df7a --- /dev/null +++ b/Recycler/mod_objc/ApacheObject.h @@ -0,0 +1,27 @@ +// $Id: ApacheObject.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheObject_H__ +#define __ApacheObject_H__ + +#import + +@interface ApacheObject : NSObject +{ + void *handle; + BOOL freeWhenDone; // if yes, call destroyHandle in -dealloc +} + ++ (id)objectWithHandle:(void *)_handle; + +- (id)initWithHandle:(void *)_handle freeWhenDone:(BOOL)_flag; // designated +- (id)initWithHandle:(void *)_handle; // freeWhenDone:NO + +/* destroy a handle (needs to be overidden by subclasses) */ +- (void)destroyHandle; + +/* accessors */ +- (void *)handle; + +@end + +#endif /* __ApacheObject_H__ */ diff --git a/Recycler/mod_objc/ApacheObject.m b/Recycler/mod_objc/ApacheObject.m new file mode 100644 index 00000000..53a40c1b --- /dev/null +++ b/Recycler/mod_objc/ApacheObject.m @@ -0,0 +1,79 @@ +// $Id: ApacheObject.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheObject.h" +#import + +@implementation ApacheObject + +static NSMapTable *proxyRegistry = NULL; // THREAD + ++ (void)initialize { + if (proxyRegistry == NULL) { + proxyRegistry = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, + NSNonOwnedPointerMapValueCallBacks, + 128); + } +} + ++ (id)objectWithHandle:(void *)_handle { + id proxy; + + if (_handle == NULL) return nil; + + if ((proxy = NSMapGet(proxyRegistry, _handle))) + return proxy; + + return [[[self alloc] initWithHandle:_handle freeWhenDone:NO] autorelease]; +} + +- (id)initWithHandle:(void *)_handle freeWhenDone:(BOOL)_flag { + if (_handle == NULL) { + RELEASE(self); + return nil; + } + + self->handle = _handle; + self->freeWhenDone = _flag; + + NSMapInsert(proxyRegistry, _handle, self); + + return self; +} +- (id)initWithHandle:(void *)_handle { + return [self initWithHandle:_handle freeWhenDone:NO]; +} +- (id)init { + return [self initWithHandle:NULL freeWhenDone:NO]; +} + +- (void)dealloc { + if (self->handle) { + NSMapRemove(proxyRegistry, self->handle); + + if (self->freeWhenDone) { + [self destroyHandle]; + self->handle = NULL; + } + } + [super dealloc]; +} + +- (void)destroyHandle { + [self subclassResponsibility:_cmd]; +} + +/* accessors */ + +- (void *)handle { + return self->handle; +} + +/* description */ + +- (NSString *)description { + return [NSString stringWithFormat:@"<0x%08X[%@]: apache=0x%08X>", + self, NSStringFromClass([self class]), + self->handle]; +} + +@end /* ApacheObject */ diff --git a/Recycler/mod_objc/ApacheRequest.h b/Recycler/mod_objc/ApacheRequest.h new file mode 100644 index 00000000..c9819066 --- /dev/null +++ b/Recycler/mod_objc/ApacheRequest.h @@ -0,0 +1,200 @@ +// $Id: ApacheRequest.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheRequest_H__ +#define __ApacheRequest_H__ + +#include "ApacheObject.h" +#include + +@class NSString, NSDate, NSData; +@class ApacheResourcePool, ApacheConnection, ApacheServer; +@class ApacheTable; + +/* + An Objective-C wrapper for the Apache request structure. + + Note: the Apache request itself is allocated from it's + request resource pool ! +*/ + +@interface ApacheRequest : ApacheObject +{ +} + +/* accessors */ + +- (ApacheResourcePool *)requestPool; +- (ApacheConnection *)connection; +- (ApacheServer *)server; + +/* requests */ + +/* + If we wind up getting redirected, pointer to the request we redirected to. +*/ +- (ApacheRequest *)redirectToRequest; + +/* If this is an internal redirect, pointer to where we redirected *from*. */ +- (ApacheRequest *)redirectFromRequest; + +/* + If this is a sub_request (see request.h) pointer back to the main request. +*/ +- (ApacheRequest *)mainRequest; + +/* + Info about the request itself... we begin with stuff that only + protocol.c should ever touch... +*/ +- (NSString *)firstRequestLine; +- (BOOL)isBackwards; +- (BOOL)isHeadRequest; +- (NSString *)protocol; +- (int)protocolNumber; +- (NSString *)hostName; +- (NSDate *)requestTime; +- (NSString *)statusLine; +- (int)status; + +/* + Request method, two ways; also, protocol, etc.. Outside of protocol.c, + look, but don't touch. +*/ +- (NSString *)method; +- (int)methodNumber; ++ (int)numberForMethod:(NSString *)_method; + +/* modifying the allowed-method set */ +- (void)allowMethodNumber:(int)_num; +- (BOOL)isMethodNumberAllowed:(int)_num; + +- (unsigned int)bytesSent; +- (NSDate *)lastModified; + +/* HTTP/1.1 connection-level features */ + +- (BOOL)isChunkedSending; +- (int)byteRangeCount; +- (NSString *)byteRangeBoundary; +- (NSString *)range; +- (unsigned int)contentLength; + +- (unsigned int)numberOfRemainingBytes; +- (unsigned int)numberOfReadBytes; +- (BOOL)isChunkedReceiving; +- (BOOL)isExpecting100; + +/* MIME tables */ + +- (ApacheTable *)headersIn; +- (ApacheTable *)headersOut; +- (ApacheTable *)errorHeadersOut; +- (ApacheTable *)subprocessEnvironment; +- (ApacheTable *)notes; + +/* content-info */ + +- (void)setContentType:(NSString *)_ctype; +- (NSString *)contentType; +- (void)setContentEncoding:(NSString *)_cencoding; +- (NSString *)contentEncoding; +- (void)setContentLanguage:(NSString *)_clanguage; +- (NSString *)contentLanguage; +- (NSArray *)contentLanguages; +- (NSString *)vlistValidator; + +- (void)setHandler:(NSString *)_value; +- (NSString *)handler; + +- (BOOL)noCache; +- (BOOL)noLocalCopy; + +/* + What object is being requested (either directly, or via include + or content-negotiation mapping). +*/ +- (NSString *)unparsedURI; +- (NSString *)uri; +- (NSString *)filename; +- (NSString *)pathInfo; +- (NSString *)queryArgs; +- (NSString *)casePreservedFilename; + +- (void)parseURI:(NSString *)_uri; + +/* sub-requests */ + +- (ApacheRequest *)subRequestLookupURI:(NSString *)_newfile; +- (ApacheRequest *)subRequestLookupURI:(NSString *)_newfile + method:(NSString *)_method; +- (ApacheRequest *)subRequestLookupFile:(NSString *)_newfile; + +/* operations */ + +- (int)runSubRequest; +- (void)destroySubRequest; + +- (void)internalRedirect:(NSString *)_uri; +- (void)internalRedirectHandler:(NSString *)_uri; + +- (int)someAuthorizationRequired; +- (BOOL)isInitialRequest; + +- (NSDate *)updateModificationTime:(NSDate *)_date; + +/* sending headers */ + +- (void)sendBasicHttpHeader; +- (void)sendHttpHeader; +- (int)sendHttpTrace; +- (int)sendHttpOptions; + +/* Finish up stuff after a request */ +- (void)finalizeRequestProtocol; + +- (void)sendErrorResponse; +- (void)sendErrorResponseWithRecursiveFailStatus:(int)_state; + +/* modifying headers */ + +- (int)setContentLength:(unsigned int)_len; +- (int)setKeepAlive; +- (NSDate *)rationalizeModificationTime:(NSDate *)_mtime; +- (NSString *)makeETag:(BOOL)_forceWeak; +- (void)setETag; +- (void)setLastModified; +- (int)meetsConditions; + +/* sending content */ + +- (long)sendFile:(FILE *)_file; +- (long)sendFile:(FILE *)_file length:(long)_len; +- (unsigned int)sendMMap:(void *)_mm + offset:(unsigned int)_off length:(unsigned int)_len; + +- (int)rputc:(int)_c; +- (int)rputs:(const char *)_cstr; +- (int)rwrite:(const void *)_buf length:(unsigned int)_len; +- (int)rflush; +- (int)rwriteData:(NSData *)_data; + +/* Reading a block of data from the client connection (e.g., POST arg) */ + +- (int)setupClientBlock:(int)_readPolicy; +- (int)shouldClientBlock; +- (long)getClientBlock:(char *)_buffer length:(int)_bufsiz; +- (int)discardRequestBody; + +/* Sending a byterange */ + +- (int)setByteRange; + +/* basic authentication */ + +- (void)noteAuthFailure; +- (void)noteBasicAuthFailure; +- (int)getBasicAuthPassword:(const char **)_pwd; + +@end + +#endif /* __ApacheRequest_H__ */ diff --git a/Recycler/mod_objc/ApacheRequest.m b/Recycler/mod_objc/ApacheRequest.m new file mode 100644 index 00000000..c4d17cde --- /dev/null +++ b/Recycler/mod_objc/ApacheRequest.m @@ -0,0 +1,457 @@ +// $Id: ApacheRequest.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheRequest.h" +#import +#include "httpd.h" +#include "http_request.h" +#include "http_protocol.h" + +#define ApCharSetAccessor(_field, _val_) \ + {\ + char *val;\ + unsigned len;\ + \ + len = [_val_ cStringLength];\ + val = ap_palloc(AP_HANDLE->pool, len + 1);\ + [_val_ getCString:val];\ + val[len] = '\0';\ + \ + AP_HANDLE->_field = val;\ + } + +@implementation ApacheRequest +#define AP_HANDLE ((request_rec *)self->handle) + +/* accessors */ + +- (ApacheResourcePool *)requestPool { + return [ApacheResourcePool objectWithHandle:AP_HANDLE->pool]; +} +- (ApacheConnection *)connection { + return [ApacheConnection objectWithHandle:AP_HANDLE->connection]; +} +- (ApacheServer *)server { + return [ApacheServer objectWithHandle:AP_HANDLE->server]; +} + +/* requests */ + +- (ApacheRequest *)redirectToRequest { + return [ApacheRequest objectWithHandle:AP_HANDLE->next]; +} +- (ApacheRequest *)redirectFromRequest { + return [ApacheRequest objectWithHandle:AP_HANDLE->prev]; +} +- (ApacheRequest *)mainRequest { + return [ApacheRequest objectWithHandle:AP_HANDLE->main]; +} + +/* + Info about the request itself... we begin with stuff that only + protocol.c should ever touch... +*/ + +- (NSString *)firstRequestLine { + return [NSString stringWithCString:AP_HANDLE->the_request]; +} +- (BOOL)isBackwards { + return AP_HANDLE->assbackwards ? YES : NO; +} +/* proxy ? */ +- (BOOL)isHeadRequest { + return AP_HANDLE->header_only ? YES : NO; +} + +- (NSString *)protocol { + return [NSString stringWithCString:AP_HANDLE->protocol]; +} +- (int)protocolNumber { + return AP_HANDLE->proto_num; +} + +- (NSString *)hostName { + return [NSString stringWithCString:AP_HANDLE->hostname]; +} + +- (NSDate *)requestTime { + return [NSDate dateWithTimeIntervalSince1970:AP_HANDLE->request_time]; +} + +- (NSString *)statusLine { + return [NSString stringWithCString:AP_HANDLE->status_line]; +} +- (int)status { + return AP_HANDLE->status; +} + +/* + Request method, two ways; also, protocol, etc.. Outside of protocol.c, + look, but don't touch. +*/ +- (NSString *)method { + return [NSString stringWithCString:AP_HANDLE->method]; +} +- (int)methodNumber { + return AP_HANDLE->method_number; +} ++ (int)numberForMethod:(NSString *)_method { + return ap_method_number_of([_method cString]); +} + +- (void)allowMethodNumber:(int)_num { + AP_HANDLE->allowed |= (1 << _num); +} +- (BOOL)isMethodNumberAllowed:(int)_num { + return (AP_HANDLE->allowed & (1 << _num)) ? YES : NO; +} + +- (unsigned int)bytesSent { + return AP_HANDLE->bytes_sent; +} +- (NSDate *)lastModified { + return [NSDate dateWithTimeIntervalSince1970:AP_HANDLE->mtime]; +} + +/* HTTP/1.1 connection-level features */ + +- (BOOL)isChunkedSending { + return AP_HANDLE->chunked ? YES : NO; +} +- (int)byteRangeCount { + return AP_HANDLE->byterange; +} +- (NSString *)byteRangeBoundary { + return [NSString stringWithCString:AP_HANDLE->boundary]; +} +- (NSString *)range { + return [NSString stringWithCString:AP_HANDLE->range]; +} +- (unsigned int)contentLength { + return AP_HANDLE->clength; +} + +- (unsigned int)numberOfRemainingBytes { + return AP_HANDLE->remaining; +} +- (unsigned int)numberOfReadBytes { + return AP_HANDLE->read_length; +} +- (BOOL)isChunkedReceiving { + return AP_HANDLE->read_chunked ? YES : NO; +} +- (BOOL)isExpecting100 { + return AP_HANDLE->expecting_100 ? YES : NO; +} + +/* + MIME header environments, in and out. Also, an array containing + environment variables to be passed to subprocesses, so people can + write modules to add to that environment. + + The difference between headers_out and err_headers_out is that the + latter are printed even on error, and persist across internal redirects + (so the headers printed for ErrorDocument handlers will have them). + + The 'notes' table is for notes from one module to another, with no + other set purpose in mind... +*/ + +- (ApacheTable *)headersIn { + return [ApacheTable objectWithHandle:AP_HANDLE->headers_in]; +} +- (ApacheTable *)headersOut { + return [ApacheTable objectWithHandle:AP_HANDLE->headers_out]; +} +- (ApacheTable *)errorHeadersOut { + return [ApacheTable objectWithHandle:AP_HANDLE->err_headers_out]; +} +- (ApacheTable *)subprocessEnvironment { + return [ApacheTable objectWithHandle:AP_HANDLE->subprocess_env]; +} +- (ApacheTable *)notes { + return [ApacheTable objectWithHandle:AP_HANDLE->notes]; +} + +/* + content_type, handler, content_encoding, content_language, and all + content_languages MUST be lowercased strings. They may be pointers + to static strings; they should not be modified in place. +*/ + +- (void)setContentType:(NSString *)_ctype { + _ctype = [_ctype lowercaseString]; + ApCharSetAccessor(content_type, _ctype); +} +- (NSString *)contentType { + return [NSString stringWithCString:AP_HANDLE->content_type]; +} + +- (void)setContentEncoding:(NSString *)_cencoding { + _cencoding = [_cencoding lowercaseString]; + ApCharSetAccessor(content_encoding, _cencoding); +} +- (NSString *)contentEncoding { + return [NSString stringWithCString:AP_HANDLE->content_encoding]; +} + +- (void)setContentLanguage:(NSString *)_clanguage { + _clanguage = [_clanguage lowercaseString]; + ApCharSetAccessor(content_language, _clanguage); +} +- (NSString *)contentLanguage { + return [NSString stringWithCString:AP_HANDLE->content_language]; +} + +- (NSString *)vlistValidator { + return [NSString stringWithCString:AP_HANDLE->vlist_validator]; +} + +- (NSArray *)contentLanguages { + // array_header *content_languages; /* array of (char*) */ + + return [self notImplemented:_cmd]; +} + +- (void)setHandler:(NSString *)_value { + ApCharSetAccessor(handler, _value); +} +- (NSString *)handler { + return [NSString stringWithCString:AP_HANDLE->handler]; +} + +- (BOOL)noCache { + return AP_HANDLE->no_cache ? YES : NO; +} +- (BOOL)noLocalCopy { + return AP_HANDLE->no_local_copy ? YES : NO; +} + +/* + What object is being requested (either directly, or via include + or content-negotiation mapping). +*/ +- (NSString *)unparsedURI { + return [NSString stringWithCString:AP_HANDLE->unparsed_uri]; +} +- (NSString *)uri { + return [NSString stringWithCString:AP_HANDLE->uri]; +} +- (NSString *)filename { + return [NSString stringWithCString:AP_HANDLE->filename]; +} +- (NSString *)pathInfo { + return [NSString stringWithCString:AP_HANDLE->path_info]; +} +- (NSString *)queryArgs { + return [NSString stringWithCString:AP_HANDLE->args]; +} +// finfo, parse_uri + +- (NSString *)casePreservedFilename { + return [NSString stringWithCString:AP_HANDLE->case_preserved_filename]; +} + +- (void)parseURI:(NSString *)_uri { + ap_parse_uri(AP_HANDLE, [_uri cString]); +} + +/* sub-requests */ + +- (ApacheRequest *)subRequestLookupURI:(NSString *)_newfile { + request_rec *sr; + sr = ap_sub_req_lookup_uri([_newfile cString], AP_HANDLE); + return [ApacheRequest objectWithHandle:sr]; +} +- (ApacheRequest *)subRequestLookupURI:(NSString *)_newfile + method:(NSString *)_method +{ + request_rec *sr; + sr = ap_sub_req_method_uri([_method cString], [_newfile cString], AP_HANDLE); + return [ApacheRequest objectWithHandle:sr]; +} +- (ApacheRequest *)subRequestLookupFile:(NSString *)_newfile { + request_rec *sr; + sr = ap_sub_req_lookup_file([_newfile cString], AP_HANDLE); + return [ApacheRequest objectWithHandle:sr]; +} + +/* operations */ + +- (int)runSubRequest { + return ap_run_sub_req(AP_HANDLE); +} +- (void)destroySubRequest { + ap_destroy_sub_req(AP_HANDLE); +} + +- (void)internalRedirect:(NSString *)_uri { + ap_internal_redirect([_uri cString], AP_HANDLE); +} +- (void)internalRedirectHandler:(NSString *)_uri { + ap_internal_redirect_handler([_uri cString], AP_HANDLE); +} + +- (int)someAuthorizationRequired { + return ap_some_auth_required(AP_HANDLE); +} +- (BOOL)isInitialRequest { + return ap_is_initial_req(AP_HANDLE); +} + +- (NSDate *)updateModificationTime:(NSDate *)_date { + return [NSDate dateWithTimeIntervalSince1970: + ap_update_mtime(AP_HANDLE, [_date timeIntervalSince1970])]; +} + +/* sending headers */ + +- (void)sendBasicHttpHeader { + ap_basic_http_header(AP_HANDLE); +} +- (void)sendHttpHeader { + ap_send_http_header(AP_HANDLE); +} +- (int)sendHttpTrace { + return ap_send_http_trace(AP_HANDLE); +} +- (int)sendHttpOptions { + return ap_send_http_options(AP_HANDLE); +} + +- (void)finalizeRequestProtocol { + ap_finalize_request_protocol(AP_HANDLE); +} + +- (void)sendErrorResponse { + [self sendErrorResponseWithRecursiveFailStatus:500]; +} +- (void)sendErrorResponseWithRecursiveFailStatus:(int)_state { + ap_send_error_response(AP_HANDLE, _state); +} + +/* modifying headers */ + +- (int)setContentLength:(unsigned int)_len { + return ap_set_content_length(AP_HANDLE, _len); +} +- (int)setKeepAlive { + return ap_set_keepalive(AP_HANDLE); +} +- (NSDate *)rationalizeModificationTime:(NSDate *)_mtime { + time_t t; + t = ap_rationalize_mtime(AP_HANDLE, [_mtime timeIntervalSince1970]); + return [NSDate dateWithTimeIntervalSince1970:t]; +} +- (NSString *)makeETag:(BOOL)_forceWeak { + return [NSString stringWithCString:ap_make_etag(AP_HANDLE, _forceWeak)]; +} +- (void)setETag { + ap_set_etag(AP_HANDLE); +} +- (void)setLastModified { + ap_set_last_modified(AP_HANDLE); +} +- (int)meetsConditions { + return ap_meets_conditions(AP_HANDLE); +} + +/* sending content */ + +- (long)sendFile:(FILE *)_file { + return ap_send_fd(_file, AP_HANDLE); +} +- (long)sendFile:(FILE *)_file length:(long)_len { + return ap_send_fd_length(_file, AP_HANDLE, _len); +} +- (unsigned int)sendMMap:(void *)_mm + offset:(unsigned int)_off length:(unsigned int)_len +{ + return ap_send_mmap(_mm, AP_HANDLE, _off, _len); +} + +- (int)rputc:(int)_c { + return ap_rputc(_c, AP_HANDLE); +} +- (int)rputs:(const char *)_cstr { + return ap_rputs(_cstr, AP_HANDLE); +} +- (int)rwrite:(const void *)_buf length:(unsigned int)_len { + return ap_rwrite(_buf, _len, AP_HANDLE); +} +- (int)rflush { + return ap_rflush(AP_HANDLE); +} + +- (int)rwriteData:(NSData *)_data { + return ap_rwrite([_data bytes], [_data length], AP_HANDLE); +} + +/* Reading a block of data from the client connection (e.g., POST arg) */ + +- (int)setupClientBlock:(int)_readPolicy { + return ap_setup_client_block(AP_HANDLE, _readPolicy); +} +- (int)shouldClientBlock { + return ap_should_client_block(AP_HANDLE); +} +- (long)getClientBlock:(char *)_buffer length:(int)_bufsiz { + return ap_get_client_block(AP_HANDLE, _buffer, _bufsiz); +} +- (int)discardRequestBody { + return ap_discard_request_body(AP_HANDLE); +} + +/* Sending a byterange */ + +- (int)setByteRange { + return ap_set_byterange(AP_HANDLE); +} +// ap_each_byterange(request_rec *r, long *offset, long *length); + +/* basic authentication */ + +- (void)noteAuthFailure { + ap_note_auth_failure(AP_HANDLE); +} +- (void)noteBasicAuthFailure { + ap_note_basic_auth_failure(AP_HANDLE); +} +- (int)getBasicAuthPassword:(const char **)_pwd { + return ap_get_basic_auth_pw(AP_HANDLE, _pwd); +} + +#undef AP_HANDLE + +- (NSString *)description { + NSMutableString *ms; + id tmp; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + [ms appendFormat:@" 0x%08X", self->handle]; + + if ([self isHeadRequest]) [ms appendString:@" head"]; + + tmp = [self method]; + if ([tmp length] > 0) [ms appendFormat:@" %@", tmp]; + tmp = [self uri]; + if ([tmp length] > 0) [ms appendFormat:@" uri='%@'", tmp]; + + if ([self isChunkedReceiving]) [ms appendString:@" in-chunked"]; + if ([self isChunkedSending]) [ms appendString:@" out-chunked"]; + + if ([self numberOfReadBytes] > 0) + [ms appendFormat:@" bytesRead=%i", [self numberOfReadBytes]]; + if ([self numberOfRemainingBytes] > 0) + [ms appendFormat:@" remainingBytes=%i", [self numberOfRemainingBytes]]; + if ([self bytesSent] > 0) + [ms appendFormat:@" bytesSent=%i", [self bytesSent]]; + + if ((tmp = [self connection])) + [ms appendFormat:@" con=%@", tmp]; + + [ms appendString:@">"]; + return ms; +} + +@end /* ApacheRequest */ diff --git a/Recycler/mod_objc/ApacheResourcePool.h b/Recycler/mod_objc/ApacheResourcePool.h new file mode 100644 index 00000000..b1593b0e --- /dev/null +++ b/Recycler/mod_objc/ApacheResourcePool.h @@ -0,0 +1,134 @@ +// $Id: ApacheResourcePool.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheResourcePool_H__ +#define __ApacheResourcePool_H__ + +#include "ApacheObject.h" +#include + +/* + Note: Apache resource pools are some kind of mixture between an + FoundationNSAutoreleasePool and a Foundation NSZone. You should mix + up Apache resource pools and autorelease pools ! + + Objective-C support: ApacheResourcePool can register release + callbacks for Foundation objects. + Eg: + ApacheResourcePool *p; + id s = [[NSString alloc] initWithCString:"blah"]; + [p releaseObject:s]; + + This will release the string (but not necessarily -dealloc !!!) if the + resource pool is freed by Apache. + + Most commonly used Apache resource pools (info take from API notes): + + permanent-pool: + - the "root" pool + + pconf + - subpool of permanent-pool + - created at the beginning of the config cycle + - exists until the server is restarted or terminated + - passed to all config routines via [cmd pool] or inPool:pool + - passed to the module init function + + ptemp + - subpool of permanent-pool + - created at the beginning of the config cycle + - exists until the end of the config parsing + - passed to config routines via [cmd temporaryPool] + + pchild + - subpool of permanent-pool + - created when a child is forked + - exists until child exits + - passedto -initializeChildProcessWithServer:inPool: and + -exitChildProcessWithServer:inPool: + + ptrans + - subpool of permanent-pool + - created by child before going into the accept loop + - passed in with [connection pool] + + r->pool + - for the main request a subpool of ptrans + for sub requests a subpool of the parent request pool + - exist until the end of the processing of the request + - note: the request itself is allocated from this pool !! +*/ + +@interface ApacheResourcePool : ApacheObject +{ +} + +- (id)makeSubPool; + +/* Clearing out EVERYTHING in an pool... destroys any sub-pools */ +- (void)clearPool; + +- (BOOL)isAncestorOf:(ApacheResourcePool *)_pool; + +/* stats */ + +- (unsigned int)bytesInPool; ++ (unsigned int)bytesInFreeBlocks; + +/* memory blocks */ + +- (void *)malloc:(unsigned)size; +- (void *)mallocAtomic:(unsigned)size; +- (void *)calloc:(unsigned)numElems byteSize:(unsigned)byteSize; +- (void *)callocAtomic:(unsigned)numElems byteSize:(unsigned)byteSize; + +- (void *)realloc:(void*)pointer size:(unsigned)size; +- (void)freePointer:(void *)pointer; + +/* string allocations */ + +- (unsigned char *)strdup:(const unsigned char *)_cstr; +- (unsigned char *)strdup:(const unsigned char *)_cstr length:(unsigned)_l; +- (unsigned char *)strcat:(const unsigned char *)_cstr; +- (unsigned char *)pvsprintf:(const unsigned char *)_fmt arguments:(va_list)va; + +/* file allocations */ + +- (FILE *)openFile:(NSString *)_name mode:(NSString *)_mode; +- (FILE *)openFD:(int)_fd mode:(NSString *)_mode; +- (int)popenf:(NSString *)_name flag:(int)_flg mode:(int)_mode; + +- (void)closeFile:(FILE *)_file; +- (void)pclosef:(int)_fd; +#ifdef WIN32 +- (void)closeHandle:(HANDLE)_h; +#endif + +- (void)noteCleanUpsForFile:(FILE *)_file; +- (void)noteCleanUpsForFD:(int)_fd; +#ifdef WIN32 +- (void)noteCleanUpsForHandle:(HANDLE)_h; +#endif +- (void)killCleanUpsForFD:(int)_fd; + +/* process management */ + +/* + Preparing for exec() --- close files, etc., but *don't* flush I/O + buffers, *don't* wait for subprocesses, and *don't* free any memory. +*/ ++ (void)cleanUpForExec; + +/* Objective-C objects */ + +- (void)releaseObject:(id)_object; +- (void)unreleaseObject:(id)_object; + +@end + +@interface NSObject(PoolRelease) + +- (void)cleanupForApacheExec; /* called before exec() */ + +@end + +#endif /* __ApacheResourcePool_H__ */ diff --git a/Recycler/mod_objc/ApacheResourcePool.m b/Recycler/mod_objc/ApacheResourcePool.m new file mode 100644 index 00000000..39657b6f --- /dev/null +++ b/Recycler/mod_objc/ApacheResourcePool.m @@ -0,0 +1,179 @@ +// $Id: ApacheResourcePool.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheResourcePool.h" +#include "httpd.h" +#include "ap_alloc.h" +#include + +@implementation ApacheResourcePool + +- (void)destroyHandle { + if (self->handle) { + ap_destroy_pool(self->handle); + self->handle = NULL; + } +} +- (id)makeSubPool { + ap_pool *p; + + if (self->handle == NULL) + return nil; + + if ((p = ap_make_sub_pool(self->handle)) == NULL) + return nil; + + return [[[ApacheResourcePool alloc] + initWithHandle:p freeWhenDone:YES] + autorelease]; +} +- (void)clearPool { + if (self->handle) ap_clear_pool(self->handle); +} + +- (BOOL)isAncestorOf:(ApacheResourcePool *)_pool { +#ifdef POOL_DEBUG + if (_pool == NULL) return NO; + if (self->handle == NULL) return NO; + + return ap_pool_is_ancestor(self->handle, _pool) ? YES : NO; +#else + return NO; +#endif +} + +/* stats */ + +- (unsigned int)bytesInPool { + if (self->handle == NULL) return 0; + return ap_bytes_in_pool(self->handle); +} ++ (unsigned int)bytesInFreeBlocks { + return ap_bytes_in_free_blocks(); +} + +/* memory blocks */ + +- (void *)malloc:(unsigned)size { + if (self->handle == NULL) return NULL; + return ap_palloc(self->handle, size); +} +- (void *)mallocAtomic:(unsigned)size { + if (self->handle == NULL) return NULL; + return ap_palloc(self->handle, size); +} +- (void *)calloc:(unsigned)numElems byteSize:(unsigned)byteSize { + if (self->handle == NULL) return NULL; + return ap_pcalloc(self->handle, byteSize * numElems); +} +- (void *)callocAtomic:(unsigned)numElems byteSize:(unsigned)byteSize { + if (self->handle == NULL) return NULL; + return ap_pcalloc(self->handle, byteSize * numElems); +} + +- (void *)realloc:(void*)pointer size:(unsigned)size { + return NULL; +} +- (void)freePointer:(void *)pointer { +} + +/* string allocations */ + +- (unsigned char *)strdup:(const unsigned char *)_cstr { + if (self->handle == NULL) return NULL; + return ap_pstrdup(self->handle, _cstr); +} +- (unsigned char *)strdup:(const unsigned char *)_cstr length:(unsigned)_l { + if (self->handle == NULL) return NULL; + return ap_pstrndup(self->handle, _cstr, _l); +} +- (unsigned char *)strcat:(const unsigned char *)_cstr { + if (self->handle == NULL) return NULL; + return ap_pstrcat(self->handle, _cstr, NULL); +} +- (unsigned char *)pvsprintf:(const unsigned char *)_fmt arguments:(va_list)va{ + if (self->handle == NULL) return NULL; + return ap_pvsprintf(self->handle, _fmt, va); +} + +/* file allocations */ + +- (FILE *)openFile:(NSString *)_name mode:(NSString *)_mode { + return ap_pfopen(self->handle, [_name cString], [_mode cString]); +} +- (FILE *)openFD:(int)_fd mode:(NSString *)_mode { + return ap_pfdopen(self->handle, _fd, [_mode cString]); +} +- (int)popenf:(NSString *)_name flag:(int)_flg mode:(int)_mode { + return ap_popenf(self->handle, [_name cString], _flg, _mode); +} + +- (void)closeFile:(FILE *)_file { + ap_pfclose(self->handle, _file); +} +- (void)pclosef:(int)_fd { + ap_pclosef(self->handle, _fd); +} +#ifdef WIN32 +- (void)closeHandle:(HANDLE)_h { + ap_pcloseh(self->handle, _h); +} +#endif + +- (void)noteCleanUpsForFile:(FILE *)_file { + ap_note_cleanups_for_file(self->handle, _file); +} +- (void)noteCleanUpsForFD:(int)_fd { + ap_note_cleanups_for_fd(self->handle, _fd); +} +#ifdef WIN32 +- (void)noteCleanUpsForHandle:(HANDLE)_h { + ap_note_cleanups_for_h(self->handle, _h); +} +#endif +- (void)killCleanUpsForFD:(int)_fd { + ap_kill_cleanups_for_fd(self->handle, _fd); +} + +/* process management */ + ++ (void)cleanUpForExec { + ap_cleanup_for_exec(); +} + ++ (void)blockAlarms { + ap_block_alarms(); +} ++ (void)unlockAlarms { + ap_unblock_alarms(); +} + +/* Objective-C objects */ + +static void plainReleaseCleanup(void *data) { + if (data) [(id)data release]; +} +static void childReleaseCleanup(void *data) { + if (data) { + if ([(id)data respondsToSelector:@selector(cleanupForApacheExec)]) + [(id)data cleanupForApacheExec]; + } +} + +- (void)releaseObject:(id)_object { + if (_object == nil) return; + + ap_block_alarms(); + ap_register_cleanup(self->handle, _object, + plainReleaseCleanup, + childReleaseCleanup); + ap_unblock_alarms(); +} +- (void)unreleaseObject:(id)_object { + if (_object == nil) return; + + ap_block_alarms(); + ap_kill_cleanup(self->handle, _object, plainReleaseCleanup); + ap_unblock_alarms(); +} + +@end /* ApacheResourcePool */ diff --git a/Recycler/mod_objc/ApacheServer.h b/Recycler/mod_objc/ApacheServer.h new file mode 100644 index 00000000..1d41070d --- /dev/null +++ b/Recycler/mod_objc/ApacheServer.h @@ -0,0 +1,57 @@ +// $Id: ApacheServer.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheServer_H__ +#define __ApacheServer_H__ + +#include + +@interface ApacheServer : ApacheObject +{ +} + +/* accessors */ + +- (ApacheServer *)nextServer; + +/* description of where the definition came from */ + +- (NSString *)definitionName; +- (unsigned int)definitionLineNumber; + +/* locations of server config info */ + +- (NSString *)srmConfigName; +- (NSString *)accessConfigName; + +- (NSString *)serverAdmin; +- (NSString *)serverHostName; +- (unsigned short)port; + +/* log files */ + +- (NSString *)errorFileName; +- (FILE *)errorLogFile; +- (int)logLevel; + +/* module-specific configuration for server, and defaults... */ + +- (BOOL)isVirtual; + +/* transaction handling */ + +- (NSTimeInterval)timeout; +- (NSTimeInterval)keepAliveTimeout; +- (int)keepAliveMax; +- (BOOL)keepAlive; +- (int)sendBufferSize; + +- (id)serverUserId; +- (id)serverGroupId; + +- (int)requestLineLimit; +- (int)requestFieldSizeLimit; +- (int)requestFieldCountLimit; + +@end + +#endif /* __ApacheServer_H__ */ diff --git a/Recycler/mod_objc/ApacheServer.m b/Recycler/mod_objc/ApacheServer.m new file mode 100644 index 00000000..3317ee7d --- /dev/null +++ b/Recycler/mod_objc/ApacheServer.m @@ -0,0 +1,151 @@ +// $Id: ApacheServer.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheServer.h" +#include +#import + +static NSString *mkString(const char *str) { + static Class NSStringClass = Nil; + unsigned len; + + if (str == NULL) return nil; + if (NSStringClass == Nil) NSStringClass = [NSString class]; + if ((len = strlen(str)) == 0) return nil; + + return [[[NSStringClass alloc] initWithCString:str] autorelease]; +} + +@implementation ApacheServer +#define AP_HANDLE ((server_rec *)self->handle) + +/* accessors */ + +- (ApacheServer *)nextServer { + return [[[ApacheServer alloc] initWithHandle:AP_HANDLE->next] autorelease]; +} + +/* description of where the definition came from */ + +- (NSString *)definitionName { + return mkString(AP_HANDLE->defn_name); +} +- (unsigned int)definitionLineNumber { + return AP_HANDLE->defn_line_number; +} + +/* Full locations of server config info */ + +- (NSString *)srmConfigName { + return mkString(AP_HANDLE->srm_confname); +} +- (NSString *)accessConfigName { + return mkString(AP_HANDLE->access_confname); +} + +- (NSString *)serverAdmin { + return mkString(AP_HANDLE->server_admin); +} +- (NSString *)serverHostName { + return mkString(AP_HANDLE->server_hostname); +} +- (unsigned short)port { + return AP_HANDLE->port; +} + +/* log files */ + +- (NSString *)errorFileName { + return mkString(AP_HANDLE->error_fname); +} +- (FILE *)errorLogFile { + return AP_HANDLE->error_log; +} +- (int)logLevel { + return AP_HANDLE->loglevel; +} + +/* module-specific configuration for server, and defaults... */ + +- (BOOL)isVirtual { + return AP_HANDLE->is_virtual ? YES : NO; +} + +/* transaction handling */ + +- (NSTimeInterval)timeout { + return AP_HANDLE->timeout; +} +- (NSTimeInterval)keepAliveTimeout { + return AP_HANDLE->keep_alive_timeout; +} +- (int)keepAliveMax { + return AP_HANDLE->keep_alive_max; +} +- (BOOL)keepAlive { + return AP_HANDLE->keep_alive ? YES : NO; +} +- (int)sendBufferSize { + return AP_HANDLE->send_buffer_size; +} + +- (NSString *)serverPath { + return [NSString stringWithCString:AP_HANDLE->path + length:AP_HANDLE->pathlen]; +} + +#warning names, wild_names + +- (id)serverUserId { + return [NSNumber numberWithInt:AP_HANDLE->server_uid]; +} +- (id)serverGroupId { + return [NSNumber numberWithInt:AP_HANDLE->server_gid]; +} + +- (int)requestLineLimit { + return AP_HANDLE->limit_req_line; +} +- (int)requestFieldSizeLimit { + return AP_HANDLE->limit_req_fieldsize; +} +- (int)requestFieldCountLimit { + return AP_HANDLE->limit_req_fields; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + id tmp; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + [ms appendFormat:@" 0x%08X", self->handle]; + + if ([self isVirtual]) + [ms appendString:@" virtual"]; + + [ms appendFormat:@" uid=%@ gid=%@", + [self serverUserId], [self serverGroupId]]; + + if ([(tmp = [self definitionName]) length] > 0) + [ms appendFormat:@" def=%@:%i", tmp, [self definitionLineNumber]]; + + if ((tmp = [self serverHostName])) + [ms appendFormat:@" host=%@:%i", tmp, [self port]]; + +#if 0 + if ((tmp = [self serverAdmin])) + [ms appendFormat:@" admin=%@", tmp]; +#endif + + [ms appendFormat:@" loglevel=%i", [self logLevel]]; + + if ((tmp = [self nextServer])) + [ms appendFormat:@" next=%@", tmp]; + + [ms appendString:@">"]; + return ms; +} + +@end /* ApacheServer */ diff --git a/Recycler/mod_objc/ApacheTable.h b/Recycler/mod_objc/ApacheTable.h new file mode 100644 index 00000000..6a71d1e2 --- /dev/null +++ b/Recycler/mod_objc/ApacheTable.h @@ -0,0 +1,28 @@ +// $Id: ApacheTable.h,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#ifndef __ApacheTable_H__ +#define __ApacheTable_H__ + +#include "ApacheObject.h" + +@interface ApacheTable : ApacheObject +{ +} + +/* query */ + +- (id)objectForKey:(NSString *)_key; + +/* modification */ + +- (void)setObject:(id)_obj forKey:(NSString *)_key; + +- (void)mergeObject:(id)_obj forKey:(NSString *)_key; +- (void)addObject:(id)_obj forKey:(NSString *)_key; + +- (void)removeAllObjects; +- (void)removeObjectForKey:(NSString *)_key; + +@end + +#endif /* __ApacheTable_H__ */ diff --git a/Recycler/mod_objc/ApacheTable.m b/Recycler/mod_objc/ApacheTable.m new file mode 100644 index 00000000..f0f2a64b --- /dev/null +++ b/Recycler/mod_objc/ApacheTable.m @@ -0,0 +1,50 @@ +// $Id: ApacheTable.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "ApacheTable.h" +#import +#include +#include "httpd.h" +#include "ap_alloc.h" + +@implementation ApacheTable +#define AP_HANDLE ((table *)self->handle) + +/* query */ + +- (id)objectForKey:(NSString *)_key { + return [NSString stringWithCString:ap_table_get(AP_HANDLE, [_key cString])]; +} + +/* modification */ + +- (void)setObject:(id)_obj forKey:(NSString *)_key { + const char *v; + + if ((v = [[_obj stringValue] cString])) + ap_table_set(AP_HANDLE, [_key cString], v); + else + ap_table_unset(AP_HANDLE, [_key cString]); +} + +- (void)mergeObject:(id)_obj forKey:(NSString *)_key { + const char *v; + + if ((v = [[_obj stringValue] cString])) + ap_table_merge(AP_HANDLE, [_key cString], v); +} +- (void)addObject:(id)_obj forKey:(NSString *)_key { + const char *v; + + if ((v = [[_obj stringValue] cString])) + ap_table_add(AP_HANDLE, [_key cString], v); +} + +- (void)removeAllObjects { + ap_clear_table(AP_HANDLE); +} +- (void)removeObjectForKey:(NSString *)_key { + ap_table_unset(AP_HANDLE, [_key cString]); +} + +#undef AP_HANDLE +@end /* ApacheTable */ diff --git a/Recycler/mod_objc/GNUmakefile b/Recycler/mod_objc/GNUmakefile new file mode 100644 index 00000000..13732541 --- /dev/null +++ b/Recycler/mod_objc/GNUmakefile @@ -0,0 +1,50 @@ +# $Id: GNUmakefile,v 1.1 2004/06/08 11:15:59 helge Exp $ + +include $(GNUSTEP_MAKEFILES)/common.make + +LIBRARY_NAME = libApacheAPI libApHelper +BUNDLE_NAME = ApTest +MODULE_NAME = gsbundle + +libApacheAPI_OBJC_FILES = \ + ApacheCmdParms.m \ + ApacheConnection.m \ + ApacheObject.m \ + ApacheRequest.m \ + ApacheResourcePool.m \ + ApacheServer.m \ + ApacheTable.m \ + ApacheModule.m \ + ApModuleBaseClass.m \ + ApModuleBaseClass+Callbacks.m \ + ApModuleBaseClass+Handler.m \ + ApModuleBaseClass+Cmds.m \ + +libApHelper_OBJC_FILES = \ + GSBundleModule.m \ + +gsbundle_OBJC_FILES = \ + mod_gsbundle.m \ + +ApTest_PRINCIPAL_CLASS = ApTest +ApTest_OBJC_FILES = \ + ApTest.m \ + ApTest_module_structure.m \ + +libApHelper_LIBRARIES_DEPEND_UPON += \ + -lApacheAPI \ + -lFoundation \ + -lobjc \ + -lpthread + +ADDITIONAL_LIB_DIRS += -L./$(GNUSTEP_OBJ_DIR) +ApTest_BUNDLE_LIBS += -lApacheAPI + +gsbundle_TOOL_LIBS += -lpthread -ldl + +include $(GNUSTEP_MAKEFILES)/library.make +include $(GNUSTEP_MAKEFILES)/apache.make +include $(GNUSTEP_MAKEFILES)/bundle.make + +before-ApTest-all:: + genApacheModule.sh ApTest ApTest_module_structure.m diff --git a/Recycler/mod_objc/GSBundleModule.m b/Recycler/mod_objc/GSBundleModule.m new file mode 100644 index 00000000..bf803d5f --- /dev/null +++ b/Recycler/mod_objc/GSBundleModule.m @@ -0,0 +1,407 @@ +// $Id: GSBundleModule.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "httpd.h" +#include "http_config.h" +#include "http_log.h" +#include "ap_config.h" + +#include "ApacheCmdParms.h" +#include "ApacheServer.h" +#include "ApacheModule.h" +#include "ApacheResourcePool.h" +#import + +/* + Note: + + an Apache module gets *unloaded* during the config process !!! + + This is why we have this helper shared object which is not unloaded :-) +*/ + +@interface NSObject(ModuleClass) ++ (void)setBundleHandler:(id)_handler; +- (module *)apacheModule; +@end + +static void _ensureObjCEnvironment(void) { +#if LIB_FOUNDATION_LIBRARY + extern char **environ; /* man 5 environ */ + static char *argv[2] = { "apache", NULL }; + [NSProcessInfo initializeWithArguments:argv + count:1 + environment:environ]; +#endif +} + +@interface ApBundleInfo : NSObject +{ +@public + ApacheResourcePool *configPool; + NSString *bundlePath; + NSString *bundleName; + NSBundle *bundle; + module *apacheModule; + ApacheModule *bundleHandler; + BOOL moduleAdded; + BOOL bundleLoaded; +} + ++ (NSString *)makeBundlePathAbsolute:(NSString *)_relpath; ++ (ApBundleInfo *)bundleInfoForPath:(NSString *)_relpath; + +/* accessors */ + +- (NSBundle *)bundle; +- (NSString *)bundleModuleClassName; +- (Class)bundleModuleClass; + +- (BOOL)isBundleLoaded; +- (BOOL)isApacheModuleInitialized; + +/* operations */ + +- (NSString *)setUpWithArgs:(NSString *)_args + inPool:(ApacheResourcePool *)_pool; +- (void)tearDown; + +- (void)configureForServer:(ApacheServer *)_server; + +@end + +@implementation ApBundleInfo + ++ (ApBundleInfo *)bundleInfoForPath:(NSString *)_relpath { + static NSMutableDictionary *pathToInfo = nil; + NSString *p; + ApBundleInfo *bi; + + p = [self makeBundlePathAbsolute:_relpath]; + if ([p length] == 0) return nil; + + if (pathToInfo == nil) + pathToInfo = [[NSMutableDictionary alloc] initWithCapacity:16]; + + if ((bi = [pathToInfo objectForKey:p])) + return bi; + + if ((bi = [[self alloc] initWithPath:p])) { + [pathToInfo setObject:bi forKey:p]; + RELEASE(bi); + } + return bi; +} ++ (NSString *)makeBundlePathAbsolute:(NSString *)_relpath { + NSString *s; + + if ([_relpath length] == 0) return nil; + + s = [[[NSProcessInfo processInfo] + environment] + objectForKey:@"GNUSTEP_SYSTEM_ROOT"]; + s = [s stringByAppendingPathComponent:@"Library/Bundles"]; + s = [s stringByAppendingPathComponent:_relpath]; + + return s; +} + +- (id)initWithPath:(NSString *)_path { + if ([_path length] == 0) { + RELEASE(self); + return nil; + } + if (![_path isAbsolutePath]) { + NSLog(@"bundle path '%@' is not absolute ...", _path); + RELEASE(self); + return nil; + } + + self->bundlePath = [_path copy]; + self->bundleName = + [[[_path lastPathComponent] stringByDeletingPathExtension] copy]; + self->bundle = [[NSBundle bundleWithPath:self->bundlePath] retain]; + + if (self->bundle == nil) { + NSLog(@"missing bundle at path %@", self->bundlePath); + RELEASE(self); + return nil; + } + + return self; +} + +- (void)dealloc { + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + RELEASE(self->configPool); + RELEASE(self->bundleHandler); + RELEASE(self->bundlePath); + RELEASE(self->bundleName); + RELEASE(self->bundle); + RELEASE(pool); + [super dealloc]; +} + +/* accessors */ + +- (BOOL)isBundleLoaded { + if (self->bundle == nil) return NO; + return self->bundleLoaded; +} +- (BOOL)isApacheModuleInitialized { + if (self->apacheModule == NULL) return NO; + return self->moduleAdded; +} + +- (NSBundle *)bundle { + return self->bundle; +} + +- (NSString *)bundleModuleClassName { + return [self->bundleName stringByAppendingString:@"Mod_Module_Class"]; +} +- (Class)bundleModuleClass { + /* the class which manages the module structure (helper class) */ + return NSClassFromString([self bundleModuleClassName]); +} + +- (Class)bundleHandlerClass { + /* the class which represents the apache module itself */ + Class c; + + if ((c = [self->bundle principalClass]) == Nil) + return nil; + if (![c isKindOfClass:[ApacheModule class]]) + return nil; + + return c; +} + +/* operations */ + +- (NSString *)setUpWithArgs:(NSString *)_args + inPool:(ApacheResourcePool *)_pool +{ + NSAutoreleasePool *pool; + Class modClass; + + /* check pre-conditions */ + + if (self->bundle == nil) { + return [NSString stringWithFormat:@"%s: missing bundle info", + __PRETTY_FUNCTION__]; + } + if (self->configPool) + return @"config pool is already setup"; + if (self->bundleHandler) + return @"bundle handler is already set up !!!"; + + pool = [[NSAutoreleasePool alloc] init]; + +#if 0 + printf("\nSETUP 0x%08X (loaded=%s) ...\n", (unsigned int)self, + self->bundleLoaded ? "yes" : "no"); + fflush(stdout); +#endif + + /* Step 0: setup resource pool wrapper */ + + self->configPool = RETAIN(_pool); + + /* Step 1: Load bundle if not done already ... */ + + if (!self->bundleLoaded) { + if (![self->bundle load]) { + return + [NSString stringWithFormat:@"couldn't load bundle %@", self->bundle]; + } + self->bundleLoaded = YES; + } + + if ((modClass = [self bundleModuleClass]) == Nil) { + RELEASE(pool); + return [NSString stringWithFormat: + @"did not find bundle module class (name=%@) ...", + [self bundleModuleClassName]]; + } + + /* Step 2: Initialize bundle handler object ... */ + + self->bundleHandler = [[[self bundleHandlerClass] alloc] init]; + if (self->bundleHandler == nil) { + RELEASE(pool); + return [NSString stringWithFormat: + @"couldn't initialize bundle handler of class '%@'", + [self bundleHandlerClass]]; + } + + /* Step 3: Remember bundle handler in module-handler class ... */ + + [modClass setBundleHandler:self->bundleHandler]; + + /* Step 4: add Apache C module structure */ + + if ((self->apacheModule = [modClass apacheModule]) == NULL) { + RELEASE(pool); + return @"did not find apache module structure of bundle"; + } + if (self->apacheModule->magic != MODULE_MAGIC_COOKIE) { + RELEASE(pool); + return [NSString stringWithFormat: + @"API module structure of bundle is broken !"]; + } + + /* Step 5: register module with apache ... */ + + ap_add_loaded_module(self->apacheModule); + self->moduleAdded = YES; + + /* release pool & done */ + + RELEASE(pool); + + return nil; +} + +- (void)tearDown { + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; + +#if 0 + printf("TEARDOWN 0x%08X ...\n", (unsigned int)self); + fflush(stdout); +#endif + + /* Reverse Step 5: unregister module with apache */ + + if ((self->apacheModule != NULL) && self->moduleAdded) + ap_remove_loaded_module(self->apacheModule); + + self->moduleAdded = NO; + + /* Reverse Step 4: reset apache module structure */ + self->apacheModule = NULL; + + /* Reverse Step 3: reset bundle handler in module-handler class ... */ + [[self bundleModuleClass] setBundleHandler:nil]; + + /* Reverse Step 2: release bundle handler object ... */ + RELEASE(self->bundleHandler); + self->bundleHandler = nil; + + /* DO NOT reverse Step 1 ... */ + + /* Reverse Step 0: release config pool proxy */ + RELEASE(self->configPool); self->configPool = nil; + + RELEASE(pool); +} + +- (void)configureForServer:(ApacheServer *)_server { + if (self->apacheModule == NULL) { + NSLog(@"missing bundle module ..."); + return; + } + if (self->configPool == NULL) { + NSLog(@"missing config pool ..."); + return; + } + +#if DEBUG && 0 + printf("CONFIGURE 0x%08X ...\n", (unsigned int)self); + fflush(stdout); +#endif + + ap_single_module_configure([self->configPool handle], + [_server handle], + self->apacheModule); +} + +@end /* ApBundleInfo */ + +static void unloadModule(void *data) { + ApBundleInfo *binfo; + + if ((binfo = (void *)data)) { + [binfo tearDown]; + } +} + +static int callCount = 0; + +/* Called when the LoadBundle config directive is found */ +const char *GSBundleModuleLoadBundleCommand +(module *module, cmd_parms *cmd, char *bundlePath) +{ + const char *result = NULL; + ApacheCmdParms *paras; + NSAutoreleasePool *opool; + NSString *bp, *args; + ApBundleInfo *bi; + id tmp; + + _ensureObjCEnvironment(); + callCount++; + +#if HEAVY_GSBUNDLE_DEBUG + printf("%s: #%i module=0x%08X pid=%i " + "(cmd=0x%08X,bp=0x%08X) ...\n", + __PRETTY_FUNCTION__, callCount, (unsigned int)module, getpid(), + (unsigned int)cmd, (unsigned int)bundlePath); + fflush(stdout); fflush(stderr); +#endif + + opool = [[NSAutoreleasePool alloc] init]; + paras = [[ApacheCmdParms alloc] initWithHandle:cmd]; + + /* separate bundle path from bundle args */ + + tmp = [NSString stringWithCString:bundlePath]; +#if HEAVY_GSBUNDLE_DEBUG + printf("%s: %s\n", __PRETTY_FUNCTION__, [[s description] cString]); + printf(" paras: %s\n", [[paras description] cString]); + printf(" server: %s\n", [[[paras server] description] cString]); + fflush(stdout); fflush(stderr); +#endif + + /* separate bundle path and load arguments ... */ + { + unsigned idx; + + if ((idx = [tmp indexOfString:@" "]) == NSNotFound) { + bp = tmp; + args = nil; + } + else { + bp = [tmp substringToIndex:idx]; + args = [tmp substringFromIndex:(idx + 1)]; + } + } + + /* makeup absolute bundle path */ + + if ((bi = [ApBundleInfo bundleInfoForPath:bp]) == nil) { + result = ap_pstrcat(cmd->pool, "bundle at '", [bp cString], "' could " + "not find info !"); + goto done; + } + + if ((tmp = [bi setUpWithArgs:args inPool:[paras pool]])) { + result = ap_pstrdup(cmd->pool, [tmp cString]); + goto done; + } + + /* register cleanup */ + ap_register_cleanup(cmd->pool, bi, + (void (*)(void*))unloadModule, ap_null_cleanup); + + /* run module configuration */ + [bi configureForServer:[paras server]]; + + done: + RELEASE(paras); + RELEASE(opool); + return result; +} diff --git a/Recycler/mod_objc/README b/Recycler/mod_objc/README new file mode 100644 index 00000000..21bd560b --- /dev/null +++ b/Recycler/mod_objc/README @@ -0,0 +1,7 @@ +# $Id: README,v 1.1 2004/06/08 11:15:59 helge Exp $ + +TODO +- resolve mem-leaks created by handler and command tables + +Last change: 20011126? + diff --git a/Recycler/mod_objc/genApacheModule.sh b/Recycler/mod_objc/genApacheModule.sh new file mode 100755 index 00000000..e338b49c --- /dev/null +++ b/Recycler/mod_objc/genApacheModule.sh @@ -0,0 +1,146 @@ +#!/bin/sh + +MODULENAME=$1 +MFILE=$2 +MODULECLASS="${MODULENAME}Mod_Module_Class" + +# +# This tool is used to generate Apache module stub structures and classes. +# +# An Objective-C class is used to "emulate" a module object. +# + +echo "creating structure for Apache module ${MODULENAME} in file ${MFILE} ..." + +cat >$MFILE < +#include "http_config.h" +#import +#import +#include "ApacheModule.h" + +static module ${MODULENAME}_module_template; +module MODULE_VAR_EXPORT ${MODULENAME}_module; + +@interface ${MODULECLASS} : ApModuleBaseClass +@end + +@implementation ${MODULECLASS} + +static ApacheModule *bundleHandler = nil; + ++ (void)setBundleHandler:(ApacheModule *)_handler { + if (_handler == bundleHandler) + return; + + if ((bundleHandler != nil) && (_handler != nil)) { + printf("WARNING(%s): handler of bundle %s already set !\n", + __PRETTY_FUNCTION__, + [[[NSBundle bundleForClass:self] description] cString]); + } + + ASSIGN(bundleHandler, _handler); +} ++ (ApacheModule *)bundleHandler { + return bundleHandler; +} + ++ (void *)apacheTemplateModule { + return &(${MODULENAME}_module_template); +} ++ (void *)apacheModuleStructure { + return &${MODULENAME}_module; +} + +static int _handleRequest(request_rec *_request) { + return [${MODULECLASS} _handleRequest:_request]; +} ++ (void *)handleRequestStubFunction { + return &_handleRequest; +} + +@end /* ${MODULECLASS} */ + +static void _moduleInit(server_rec *s, pool *p) { + [${MODULECLASS} _moduleInit:s pool:p]; +} + +static void *_perDirConfCreate(pool *p, char *dirspec) { + return [${MODULECLASS} _perDirConfCreate:dirspec pool:p]; +} +static void *_perDirConfMerge(pool *p, void *baseConf, void *newConf) { + return [${MODULECLASS} _perDirConfMerge:baseConf with:newConf pool:p]; +} + +static void *_perServerConfCreate(pool *p, server_rec *s) { + return [${MODULECLASS} _perServerConfCreate:s pool:p]; +} +static void *_perServerConfMerge(pool *p, void *baseConf, void *newConf) { + return [${MODULECLASS} _perServerConfMerge:baseConf with:newConf pool:p]; +} + +static int _translateHandler(request_rec *_request) { + return [${MODULECLASS} _translateHandler:_request]; +} +static int _apCheckUserId(request_rec *_request) { + return [${MODULECLASS} _apCheckUserId:_request]; +} +static int _authChecker(request_rec *_request) { + return [${MODULECLASS} _authChecker:_request]; +} +static int _accessChecker(request_rec *_request) { + return [${MODULECLASS} _accessChecker:_request]; +} +static int _typeChecker(request_rec *_request) { + return [${MODULECLASS} _typeChecker:_request]; +} +static int _fixerUpper(request_rec *_request) { + return [${MODULECLASS} _fixerUpper:_request]; +} +static int _logger(request_rec *_request) { + return [${MODULECLASS} _logger:_request]; +} +static int _headerParser(request_rec *_request) { + return [${MODULECLASS} _headerParser:_request]; +} + +static void _childInit(server_rec *_server, pool *_pool) { + [${MODULECLASS} _childInit:_server pool:_pool]; +} +static void _childExit(server_rec *_server, pool *_pool) { + [${MODULECLASS} _childExit:_server pool:_pool]; +} + +static int _postReadRequest(request_rec *_request) { + return [${MODULECLASS} _postReadRequest:_request]; +} + +static module ${MODULENAME}_module_template = { + STANDARD_MODULE_STUFF, + _moduleInit, _perDirConfCreate, _perDirConfMerge, + _perServerConfCreate, _perServerConfMerge, + NULL, /* table of config file commands */ + NULL, /* [#8] MIME-typed-dispatched handlers */ + _translateHandler, _apCheckUserId, _authChecker, _accessChecker, + _typeChecker, _fixerUpper, _logger, _headerParser, + _childInit, _childExit, _postReadRequest +}; + +module MODULE_VAR_EXPORT ${MODULENAME}_module = { + STANDARD_MODULE_STUFF, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +EOF diff --git a/Recycler/mod_objc/mod_gsbundle.m b/Recycler/mod_objc/mod_gsbundle.m new file mode 100644 index 00000000..cafda6a6 --- /dev/null +++ b/Recycler/mod_objc/mod_gsbundle.m @@ -0,0 +1,91 @@ +// $Id: mod_gsbundle.m,v 1.1 2004/06/08 11:15:59 helge Exp $ + +#include "httpd.h" +#include "http_config.h" +#include + +/* + Note: + + an Apache bundle gets *unloaded* during the config process !!! +*/ + +module MODULE_VAR_EXPORT gsbundle_module; + +static void *helperLib = NULL; + +static const char *(*GSBundleModuleLoadBundleCommand) +(module *module, cmd_parms *cmd, char *bundlePath) = NULL; + +/* Called when the LoadBundle config directive is found */ +static const char *loadBundle +(cmd_parms *cmd, void *dummy, char *bundlePath) +{ + if (helperLib == NULL) { + const char *path; + const char *dirpath; + + dirpath = ap_pstrcat(cmd->pool, + getenv("GNUSTEP_SYSTEM_ROOT"), "/Libraries/", + getenv("GNUSTEP_HOST_CPU"), "/", + getenv("GNUSTEP_HOST_OS"), "/", + getenv("LIBRARY_COMBO"), "/", + NULL); + path = ap_pstrcat(cmd->pool, dirpath, "libApHelper_d.so", NULL); + + helperLib = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (helperLib == NULL) { + return ap_pstrcat(cmd->pool, + "couldn't load ObjC bundle helper lib:\n '", + path, + "' ..." , NULL); + } + + GSBundleModuleLoadBundleCommand = + dlsym(helperLib, "GSBundleModuleLoadBundleCommand"); + } + + if (GSBundleModuleLoadBundleCommand == NULL){ + return ap_pstrcat(cmd->pool, + "couldn't find load bundle command in helper lib ...", + NULL); + } + + return GSBundleModuleLoadBundleCommand(&gsbundle_module, cmd, bundlePath); +} + +/* Config file commands we recognize */ +static const command_rec gsbundle_cmds[] = +{ + { + "LoadBundle", + loadBundle, + "my userinfo", + RSRC_CONF, + RAW_ARGS, + "takes bundle-path as arg" + }, + {NULL} +}; + +module MODULE_VAR_EXPORT gsbundle_module = { + STANDARD_MODULE_STUFF, + NULL, /* module initializer */ + NULL, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + gsbundle_cmds, /* table of config file commands */ + NULL, /* [#8] MIME-typed-dispatched handlers */ + NULL, /* [#1] URI to filename translation */ + NULL, /* [#4] validate user id from request */ + NULL, /* [#5] check if the user is ok _here_ */ + NULL, /* [#3] check access by host address */ + NULL, /* [#6] determine MIME type */ + NULL, /* [#7] pre-run fixups */ + NULL, /* [#9] log a transaction */ + NULL, /* [#2] header parser */ + NULL, /* child_init */ + NULL, /* child_exit */ + NULL /* [#0] post read-request */ +}; diff --git a/Recycler/mod_objc/test.conf b/Recycler/mod_objc/test.conf new file mode 100644 index 00000000..58b513f8 --- /dev/null +++ b/Recycler/mod_objc/test.conf @@ -0,0 +1,121 @@ +# $Id: test.conf,v 1.1 2004/06/08 11:15:59 helge Exp $ + +# globals +ServerType standalone +ServerRoot "/HOME/helge/mdev/SkyrixRoot" +PidFile /HOME/helge/mdev/SkyrixRoot/logs/httpd.pid +ScoreBoardFile /HOME/helge/mdev/SkyrixRoot/logs/httpd.scoreboard +DocumentRoot "/HOME/helge/mdev/SkyrixRoot/Library/WebServer/Documents" +ErrorLog /HOME/helge/mdev/SkyrixRoot/logs/error_log +AccessFileName .htaccess +Timeout 300 +KeepAlive On +MaxKeepAliveRequests 100 +KeepAliveTimeout 15 +MinSpareServers 1 +MaxSpareServers 1 +StartServers 1 +MaxClients 150 +MaxRequestsPerChild 0 +ExtendedStatus On +Port 8090 +User helge +Group dev +ServerAdmin helge.hess@skyrix.com +HostnameLookups Off +ServerSignature On + +#LoadModule dav_module Libraries/ix86/linux-gnu/apache/libdav.so +#AddModule mod_dav.c + +LoadModule gnustep_conf_module \ + Libraries/ix86/linux-gnu/apache/mod_gnustep_conf.so + +# GNUstep Config + +#GNUstepRootPath /HOME/helge/mdev/SkyrixRoot + +# load bundle loader ... + +LoadModule gsbundle_module \ + Libraries/ix86/linux-gnu/apache/mod_gsbundle.so +AddModule mod_gsbundle.m + +# load a bundle ... + +LoadBundle ApTest.bundle +#a=10 b=20 + + + Options FollowSymLinks + AllowOverride None + MyDirAlias diraliasaa documents + MyDirAlias diralias2aa documents2 + PrintDirConfig 1 + + +MyServerAlias server alias + + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Order allow,deny + Allow from all + #SetHandler ap-test + MyDirAlias diralias documents + MyDirAlias diralias2 documents2 + PrintDirConfig 1 + + + + DirectoryIndex index.xhtml index.html + + + + Order allow,deny + Deny from all + + +UseCanonicalName On + + + TypesConfig /HOME/helge/mdev/SkyrixRoot/Library/WebServer/mime.types + + +DefaultType text/plain + +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %b" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +CustomLog /HOME/helge/mdev/SkyrixRoot/logs/access_log common + +# Alias fakename realname + + + + + AddEncoding x-compress Z + AddEncoding x-gzip gz tgz + AddLanguage en .en + AddLanguage fr .fr + AddLanguage de .de + AddCharset UCS-2 .ucs2 + AddCharset UCS-4 .ucs4 + AddCharset UTF-8 .utf8 + + + + BrowserMatch "Mozilla/2" nokeepalive + BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 + BrowserMatch "RealPlayer 4\.0" force-response-1.0 + BrowserMatch "Java/1\.0" force-response-1.0 + BrowserMatch "JDK/1\.0" force-response-1.0 + -- 2.39.5