--- /dev/null
+*.apache
+*_module_structure.m
+logs
+shared_debug_obj
--- /dev/null
+// $Id: AWODirectoryConfig.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __AWODirectoryConfig_H__
+#define __AWODirectoryConfig_H__
+
+#import <Foundation/NSObject.h>
+
+@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__ */
--- /dev/null
+// $Id: AWODirectoryConfig.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "AWODirectoryConfig.h"
+#include "ApacheWO.h"
+#include <ApacheAPI/ApacheResourcePool.h>
+#include <NGObjWeb/WOApplication.h>
+#include <NGObjWeb/WORequestHandler.h>
+#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 */
--- /dev/null
+// $Id: AWOServerConfig.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __AWOServerConfig_H__
+#define __AWOServerConfig_H__
+
+#import <Foundation/NSObject.h>
+
+@class AliasMap;
+@class NSMutableDictionary, NSMutableArray;
+@class WOApplication, WORequestHandler;
+@class ApacheResourcePool, ApacheServer, ApacheCmdParms;
+
+@interface AWOServerConfig : NSObject
+{
+@public
+ AliasMap *appAlias;
+ AliasMap *handlerAlias;
+}
+
+@end
+
+#endif /* __AWOServerConfig_H__ */
--- /dev/null
+// $Id: AWOServerConfig.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "AWOServerConfig.h"
+#include "AliasMap.h"
+#include <ApacheAPI/ApacheResourcePool.h>
+#include <ApacheAPI/ApacheServer.h>
+#include <ApacheAPI/ApacheCmdParms.h>
+#include <NGObjWeb/WOApplication.h>
+#include <NGObjWeb/WORequestHandler.h>
+#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 */
--- /dev/null
+// $Id: AliasMap.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __AliasMap_H__
+#define __AliasMap_H__
+
+#import <Foundation/NSObject.h>
+
+/*
+ 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__ */
--- /dev/null
+// $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 */
--- /dev/null
+{
+ DirectoryConfigClass = "AWODirectoryConfig";
+ ServerConfigClass = "AWOServerConfig";
+
+ /* directory config */
+ SetSxApplication = {
+ selector = "SetSxApplication:";
+ overrides = ( ACCESS_CONF, OR_OPTIONS );
+ argspec = "TAKE1";
+ usage = "usage: SetSxApplication <appname>";
+ };
+ SetSxRequestHandler = {
+ selector = "SetSxRequestHandler:";
+ overrides = ( ACCESS_CONF, OR_OPTIONS );
+ argspec = "TAKE1";
+ usage = "usage: SetSxRequestHandler <rqhandlerclass>";
+ };
+ LogText = {
+ selector = "LogText:";
+ overrides = ( ACCESS_CONF, OR_OPTIONS );
+ argspec = "TAKE1";
+ usage = "usage: LogText <sometext>";
+ };
+
+ /* server config */
+
+ LoadBundle = {
+ selector = "LoadBundle:";
+ overrides = ( RSRC_CONF );
+ argspec = "TAKE1";
+ usage = "usage: LoadBundle <bundleName|bundlePath>";
+ };
+
+ SxApplicationAlias = {
+ selector = "SxApplicationAlias::";
+ overrides = ( RSRC_CONF );
+ argspec = "TAKE2";
+ usage = "usage: SxApplicationAlias <appkey> <baseuri>";
+ };
+ SxHandlerAlias = {
+ selector = "SxHandlerAlias::";
+ overrides = ( RSRC_CONF );
+ argspec = "TAKE2";
+ usage = "usage: SxHandlerAlias <handlerkey> <baseuri>";
+ };
+}
--- /dev/null
+{
+ 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:";
+ };
+}
--- /dev/null
+// $Id: ApacheResourceManager.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __ApacheResourceManager_H__
+#define __ApacheResourceManager_H__
+
+#include <NGObjWeb/WOResourceManager.h>
+
+@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__ */
--- /dev/null
+// $Id: ApacheResourceManager.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "ApacheResourceManager.h"
+#include "AWODirectoryConfig.h"
+#include <ApacheAPI/ApacheRequest.h>
+#include <ApacheAPI/ApacheServer.h>
+#include <ApacheAPI/ApacheTable.h>
+#include <NGObjWeb/WOComponent.h>
+#include <NGObjWeb/WOApplication.h>
+#include <NGObjWeb/WOContext.h>
+#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 */
--- /dev/null
+// $Id: ApacheWO+Echo.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "ApacheWO.h"
+#include "common.h"
+#include <ApacheAPI/ApacheAPI.h>
+
+@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:"<h3>\n"];
+ [_rq rputs:"echo !"];
+ [_rq rputs:"</h3>\n"];
+
+ s = [cfg stringValue];
+ if ([s length] > 0)
+ [_rq rputs:[s cString]];
+ [_rq rputs:"<br />\n\n"];
+
+ [_rq rputs:"<b>URI:</b><pre>"];
+ [_rq rputs:[[_rq uri] cString]];
+ [_rq rputs:"</pre>\n"];
+
+ [_rq rputs:"<b>description:</b><pre>"];
+ [_rq rputs:[[_rq description] cString]];
+ [_rq rputs:"</pre>\n"];
+
+ [_rq rputs:"<b>headers-in:</b><pre>"];
+ [_rq rputs:[[[_rq headersIn] description] cString]];
+ [_rq rputs:"</pre>\n"];
+
+ [_rq rputs:"<b>headers-in-dict:</b><pre>"];
+ [_rq rputs:[[[[_rq headersIn] asDictionary] description] cString]];
+ [_rq rputs:"</pre>\n"];
+
+ RELEASE(pool);
+
+ /* say we are done ... */
+ return ApacheHandledRequest;
+}
+
+@end /* ApacheWO(EchoHandler) */
--- /dev/null
+// $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 <ApacheAPI/ApacheRequest.h>
+#include "common.h"
+
+@implementation ApacheWO(Echo2Handler)
+
+- (WOResponse *)echoResponseForRequest:(WORequest *)woRequest
+ apacheRequest:(ApacheRequest *)_rq
+ config:(id)cfg
+{
+ WOResponse *woResponse;
+
+ [self logWithFormat:@"generated response was <nil> .."];
+ woResponse = [[[WOResponse alloc] initWithRequest:woRequest] autorelease];
+
+ /* construct response */
+
+ [woResponse setHeader:@"text/html" forKey:@"content-type"];
+ [woResponse appendContentString:@"<h3>WOResponse Content</h3>"];
+
+ [woResponse appendContentHTMLString:[cfg stringValue]];
+ [woResponse appendContentString:@"<br />\n\n"];
+
+ [woResponse appendContentString:@"<b>URI:</b><pre>"];
+ [woResponse appendContentHTMLString:[woRequest uri]];
+ [woResponse appendContentString:@"</pre>\n"];
+
+ [woResponse appendContentString:@"<b>Description:</b><pre>"];
+ [woResponse appendContentHTMLString:[woRequest description]];
+ [woResponse appendContentString:@"</pre>\n"];
+
+ [woResponse appendContentString:@"<b>Request Headers:</b><pre>"];
+ [woResponse appendContentHTMLString:[[woRequest headers] description]];
+ [woResponse appendContentString:@"</pre>\n"];
+
+ [woResponse appendApacheResponseInfo:
+ [_rq subRequestLookupURI:@"/docs/subdir/test.wox"]];
+ [woResponse appendContentString:@"<br />"];
+
+ [woResponse appendApacheResponseInfo:
+ [_rq subRequestLookupFile:@"test.wox"]];
+ [woResponse appendContentString:@"<br />"];
+
+ [woResponse appendApacheResponseInfo:
+ [_rq subRequestLookupURI:@"/docs/subdir/non_existent.wox"]];
+ [woResponse appendContentString:@"<br />"];
+
+ [woResponse appendApacheResponseInfo:
+ [_rq subRequestLookupURI:@"/docs/subdir/"]];
+ [woResponse appendContentString:@"<br />"];
+
+ [woResponse appendApacheResponseInfo:
+ [_rq subRequestLookupURI:@"/docs/bigimg.gif"]];
+ [woResponse appendContentString:@"<br />"];
+
+ return woResponse;
+}
+
+@end /* ApacheWO(Echo2Handler) */
--- /dev/null
+// $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 <NGObjWeb/WOApplication.h>
+#include <NGObjWeb/WORequestHandler.h>
+#include <ApacheAPI/ApacheAPI.h>
+
+/*
+ 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) */
--- /dev/null
+// $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 <ApacheAPI/ApacheRequest.h>
+#include <ApacheAPI/ApacheTable.h>
+#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) */
--- /dev/null
+// $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 <NGObjWeb/WOApplication.h>
+#include <NGObjWeb/WORequestHandler.h>
+#include <ApacheAPI/ApacheAPI.h>
+
+@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) */
--- /dev/null
+// $Id: ApacheWO.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __ApacheWOMod_H__
+#define __ApacheWOMod_H__
+
+#include <ApacheAPI/ApacheModule.h>
+
+@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__ */
--- /dev/null
+// $Id: ApacheWO.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "ApacheWO.h"
+#include "common.h"
+#include <ApacheAPI/ApacheAPI.h>
+#include <NGObjWeb/WOApplication.h>
+#include <NGObjWeb/WORequestHandler.h>
+
+@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 */
--- /dev/null
+// $Id: ApacheWOTransaction.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __ApacheWOTransaction_H__
+#define __ApacheWOTransaction_H__
+
+#import <Foundation/NSObject.h>
+
+@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__ */
--- /dev/null
+// $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 <ApacheAPI/ApacheRequest.h>
+#include <NGObjWeb/WORequest.h>
+#include <NGObjWeb/WOResponse.h>
+#include <NGObjWeb/WOApplication.h>
+
+@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 */
--- /dev/null
+2004-06-14 Helge Hess <helge.hess@skyrix.com>
+
+ * created ChangeLog
+
+
--- /dev/null
+# $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
--- /dev/null
+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.
--- /dev/null
+# $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
--- /dev/null
+// $Id: TestApp.m,v 1.1 2004/06/14 14:59:26 helge Exp $
+
+#include <NGObjWeb/WOApplication.h>
+
+@interface TestApp : WOApplication
+@end
+
+@implementation TestApp
+@end
--- /dev/null
+// $Id: WOComponent+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include <NGObjWeb/WOComponent.h>
+#include <NGObjWeb/WOContext.h>
+#include <NGObjWeb/WORequest.h>
+#include <ApacheAPI/ApacheRequest.h>
+#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) */
--- /dev/null
+// $Id: WORequest+Apache.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __WORequest_Apache_H__
+#define __WORequest_Apache_H__
+
+#include <NGObjWeb/WORequest.h>
+
+@class ApacheRequest;
+
+@interface WORequest(Apache)
+
+- (id)initWithApacheRequest:(ApacheRequest *)_rq;
+
+@end /* WORequest(Apache) */
+
+#endif /* __WORequest_Apache_H__ */
--- /dev/null
+// $Id: WORequest+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "WORequest+Apache.h"
+#include <ApacheAPI/ApacheRequest.h>
+#include <ApacheAPI/ApacheTable.h>
+#include <ApacheAPI/ApacheConnection.h>
+#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) */
--- /dev/null
+// $Id: WORequestHandler+Apache.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __WORequestHandler_ApacheExt_H__
+#define __WORequestHandler_ApacheExt_H__
+
+#include <NGObjWeb/WORequestHandler.h>
+
+@class NSDictionary;
+
+@interface WORequestHandler(ApacheExt)
+
++ (WORequestHandler *)requestHandlerForConfig:(NSDictionary *)_plist;
+- (id)initWithConfig:(NSDictionary *)_cfg;
+
+@end
+
+#endif /* __WORequestHandler_ApacheExt_H__ */
--- /dev/null
+// $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) */
--- /dev/null
+// $Id: WOResponse+Apache.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#ifndef __WOResponse_Apache_H__
+#define __WOResponse_Apache_H__
+
+#include <NGObjWeb/WOResponse.h>
+
+@class ApacheRequest;
+
+@interface WOResponse(Apache)
+
+- (int)sendResponseUsingApacheRequest:(ApacheRequest *)_rq;
+
+@end /* WOResponse(Apache) */
+
+@interface WOResponse(ApacheInfo)
+- (void)appendApacheResponseInfo:(ApacheRequest *)_request;
+@end
+
+#endif /* __WOResponse_Apache_H__ */
--- /dev/null
+// $Id: WOResponse+Apache.m,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#include "WOResponse+Apache.h"
+#include <ApacheAPI/ApacheRequest.h>
+#include <ApacheAPI/ApacheModule.h>
+#include <ApacheAPI/ApacheTable.h>
+#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:@"<table border='1' width=\"100%\">"];
+
+#if 0
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>Description:</td><td><pre>"];
+ [self appendContentHTMLString:[_request description]];
+ [self appendContentString:@"</pre></td></tr>"];
+#endif
+
+ [self appendContentString:
+ @"<tr><td width='25%' valign='top' align='right'>Status:</td><td>"];
+ [self appendContentHTMLString:[NSString stringWithFormat:@"%i",[_request status]]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td width='25%' valign='top' align='right'>unparsed URI:</td><td>"];
+ [self appendContentHTMLString:[_request unparsedURI]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>URI:</td><td>"];
+ [self appendContentHTMLString:[_request uri]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>filename:</td><td>"];
+ [self appendContentHTMLString:[_request filename]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>filetype:</td><td>"];
+ [self appendContentHTMLString:[_request fileType]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>content-type:</td><td>"];
+ [self appendContentHTMLString:[_request contentType]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>queryargs:</td><td>"];
+ [self appendContentHTMLString:[_request queryArgs]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>pathinfo:</td><td>"];
+ [self appendContentHTMLString:[_request pathInfo]];
+ [self appendContentString:@"</td></tr>"];
+
+ [self appendContentString:
+ @"<tr><td valign='top' align='right'>Headers:</td><td><pre>"];
+ [self appendContentHTMLString:
+ [[[_request headersOut] asDictionary] description]];
+ [self appendContentString:@"</pre></td></tr>"];
+
+ [self appendContentString:@"</table>"];
+}
+
+@end /* WOResponse(ApacheAppend) */
--- /dev/null
+// $Id: common.h,v 1.1 2004/06/08 11:06:00 helge Exp $
+
+#import <Foundation/Foundation.h>
+#include <NGExtensions/NGExtensions.h>
--- /dev/null
+<?xml version="1.0"?>
+<span xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant">
+ I'm a reusable component.
+</span>
--- /dev/null
+<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant">
+ <head>
+ <title>Page: <var:string value="context.page.name"/></title>
+ </head>
+ <body bgcolor="#BBBBBB">
+ <b><var:string value="context.page.name"/></b>
+ <hr/>
+
+ <var:component-content/>
+
+ <hr/>
+
+ <a href=".">docs</a> |
+ <a href="test.wox">test</a> |
+ <a href="requests.wox">requests</a> |
+ <a href="Page2.wox">Page2</a> |
+ <a href="Page3.wox">Page3</a> |
+ <a href="WoPage1.wo">WoPage1</a>
+ </body>
+
+ <var:script><![CDATA[
+ var title = "<no title>";
+ ]]></var:script>
+</html>
--- /dev/null
+<?xml version="1.0"?>
+<var:component className="Frame" title="name"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant">
+ Seite 2 ...
+
+ Zur Index-Seite: <a href="/docs/">/docs</a><br/>
+ Zu test.wox: <a href="test.wox">test.wox</a><br/>
+ <br/>
+ Embed: |<var:component className="Embed"/>|
+ <br/>
+ <br/>
+ <img src="SlowMarket.gif" alt="bigimg.gif"/>
+ <hr/>
+ <img filename="SlowMarket.gif" alt="bigimg.gif"/>
+ <hr/>
+ <var:component className="imgs/SlowMarket.wox"/>
+</var:component>
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<var:component className="Frame" title="name"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:js="http://www.skyrix.com/od/javascript"
+ xmlns:const="http://www.skyrix.com/od/constant">
+
+ <form href="Page3.wox/add" method="post">
+ <input type="text" name="a" var:value="a"/><br/>
+ <input type="text" name="b" var:value="b"/><br/>
+ <input type="submit" name="ok" value="ok"/><br/>
+ <var:string value="c"/>
+ </form>
+
+ <var:script><![CDATA[
+ var a = 3;
+ var b = 10;
+ var c = 0;
+
+ function addAction() {
+ c = a + b;
+ return this;
+ }
+ function calcC() {
+ return a + b;
+ }
+ ]]></var:script>
+
+ a: <var:string value="a"/><br/>
+ b: <var:string value="b"/><br/>
+ c: <var:string value="calcC"/><br/>
+</var:component>
--- /dev/null
+<?xml version="1.0"?>
+<span xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:js="http://www.skyrix.com/od/javascript"
+ xmlns:const="http://www.skyrix.com/od/constant">
+
+ <table style="font-size: 10">
+ <tr>
+ <td colspan="6" bgcolor="#CCCCCC">
+ Info on <var:string value="rq.uri"/></td>
+ </tr>
+
+ <tr>
+ <td valign="top" width="20%">filename</td>
+ <td colspan="5">
+ <var:string value="rq.filename"/>
+ (<var:string value="rq.fileType"/>)
+ <var:if js:condition="rq.pathInfo.length > 0">
+ [<var:string value="rq.pathInfo"/>]
+ </var:if>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">method</td>
+ <td><var:string value="rq.method"/></td>
+ <td valign="top">status</td>
+ <td><var:string value="rq.status"/></td>
+ <td valign="top">content-type</td>
+ <td><var:string value="rq.contentType"/></td>
+ </tr>
+ <tr>
+ <td valign="top">headers-in</td>
+ <td colspan="5">
+ <table border="0" style="font-size: 8">
+ <var:foreach-key dictionary="rq.headersIn" key="header" item="value">
+ <tr>
+ <td valign="top"><var:string value="header"/></td>
+ <td><var:foreach const:count="3" js:list="value.split(',')" item="valuePart"><var:string value="valuePart"/><br/></var:foreach></td>
+ </tr>
+ </var:foreach-key>
+ </table>
+ </td>
+ </tr>
+<!--
+ <tr>
+ <td valign="top">headers-out</td>
+ <td colspan="3">
+ <var:foreach-key dictionary="rq.headersOut" key="header" item="value">
+ <li><var:string value="header"/>: <var:string value="value"/></li>
+ </var:foreach-key></td>
+ </tr>
+-->
+ </table>
+
+ <var:script>
+ var rq, value;
+ var value="";
+ </var:script>
+</span>
--- /dev/null
+<html>
+ <head>
+ <title>Server Side Include</title>
+ </head>
+
+ <body>
+ <h3>Server Side Include</h3>
+
+ Today is <!--#echo var="DATE_LOCAL" -->
+ <br/>
+ <br/>
+ Inluded .wox page:
+ <table border="1" width="100%"><tr><td>
+ <!--#include virtual="Page2.wox" -->
+ </td></tr></table>
+ </body>
+</html>
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<var:component className="Frame" title="name"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant">
+
+ <var:table maxColumns="maxColumns" col="col" row="row"
+ index="index" item="item"
+ list="listAsArray" horizontal="horizontal"
+ border="border">
+ (<var:string value="row"/>/<var:string value="col"/>)
+ = <var:string value="index"/>
+ <b><var:string value="item"/></b>
+ </var:table>
+
+ <var:table maxColumns="maxColumns" col="col" row="row"
+ index="index" item="item"
+ list="listAsArray" horizontal="horizontal"
+ border="border"
+ const:hasOwnTDs="4" width="100%">
+ <td><var:string value="row"/></td>
+ <td><var:string value="col"/></td>
+ <td><var:string value="index"/></td>
+ <td><b><var:string value="item"/></b></td>
+ </var:table>
+
+ <form var:action="self">
+ <hr/>
+ <table border="0">
+ <tr><td><i>Config Bindings</i></td></tr>
+ <tr>
+ <td>MaxColumns:</td>
+ <td><input type="text" var:value="maxColumns" size="4"/></td>
+ </tr>
+ <tr>
+ <td>Horizontal:</td>
+ <td><input type="checkbox" var:checked="horizontal"/></td>
+ </tr>
+ </table>
+ <input type="submit" var:action="self" value="apply"/>
+ </form>
+</var:component>
--- /dev/null
+<WEBOBJECT NAME="Frame">
+ .wo based page
+
+ a: <WEBOBJECT NAME="a"></WEBOBJECT><br />
+ b: <WEBOBJECT NAME="b"></WEBOBJECT><br />
+ c: <WEBOBJECT NAME="AddAB"></WEBOBJECT><br />
+
+ Action Link to Page2: <WEBOBJECT NAME="Page2">Page2</WEBOBJECT>
+</WEBOBJECT>
--- /dev/null
+
+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;
+}
--- /dev/null
+Frame: Frame {
+ title = name;
+}
+
+AddAB: WOString {
+ value = addAB;
+}
+
+a: WOString {
+ value = a;
+}
+b: WOString {
+ value = b;
+}
+
+Page2: WOHyperlink {
+ action = gotoPage2;
+}
--- /dev/null
+<?xml version="1.0"?>
+<span xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant">
+ <img width="220" height="65" filename="../SlowMarket.gif" alt="bigimg.gif"/>
+</span>
--- /dev/null
+# $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
--- /dev/null
+<?xml version="1.0"?>
+<var:component className="Frame" title="name"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:js="http://www.skyrix.com/od/javascript"
+ xmlns:const="http://www.skyrix.com/od/constant">
+ <h3>Check Apache Internal Subrequests ..</h3>
+
+ <table border="0">
+ <tr>
+ <td valign="top">Filename: </td>
+ <td><var:string value="apacheRequest.filename"/></td>
+ </tr>
+ <tr>
+ <td valign="top">Pathinfo: </td>
+ <td><var:string value="apacheRequest.pathInfo"/></td>
+ </tr>
+ <tr>
+ <td valign="top">ApacheRequest:</td>
+ <td><code><var:string value="apacheRequest"/></code></td>
+ </tr>
+ <tr>
+ <td valign="top">ApacheConnection:</td>
+ <td><code><var:string value="apacheRequest.connection"/></code></td>
+ </tr>
+
+ <tr>
+ <td valign="top">test.wox:</td>
+ <td><var:component className="RqInfo" rq="testRq"/></td>
+ </tr>
+ <tr>
+ <td valign="top">test.wox (file):</td>
+ <td><var:component className="RqInfo" rq="testRqFile"/></td>
+ </tr>
+ <tr>
+ <td valign="top">test.wox/add:</td>
+ <td><var:component className="RqInfo" rq="testRqAdd"/></td>
+ </tr>
+ <tr>
+ <td valign="top">WoPage1.wo:</td>
+ <td><var:component className="RqInfo" rq="testWO"/></td>
+ </tr>
+ <tr>
+ <td valign="top">blah.wo/:</td>
+ <td><var:component className="RqInfo" rq="testNo"/></td>
+ </tr>
+ <tr>
+ <td valign="top">SSIPage.shtml:</td>
+ <td><var:component className="RqInfo" rq="testSSI"/></td>
+ </tr>
+ <tr>
+ <td valign="top">/docs/:</td>
+ <td><var:component className="RqInfo" rq="docs"/></td>
+ </tr>
+ <tr>
+ <td valign="top">/docs/manage:</td>
+ <td>
+ <i>Note:</i> pathInfo doesn't work on directories :-(<br/>
+ <var:component className="RqInfo" rq="docsMg"/>
+ </td>
+ </tr>
+ </table>
+
+ <var:script><![CDATA[
+ var rq = this.apacheRequest;
+
+ print("run requests setup ...");
+ var testRq = rq.subRequestLookupURI('test.wox', 'HEAD');
+ var testRqAdd = rq.subRequestLookupURI('test.wox/add', 'HEAD');
+ var testRqFile = rq.subRequestLookupFile('test.wox');
+ var testWO = rq.subRequestLookupURI('WoPage1.wo', 'HEAD');
+ var testNo = rq.subRequestLookupURI('blah.wo/', 'HEAD');
+ var testSSI = rq.subRequestLookupURI('SSIPage.shtml','HEAD');
+ var docs = rq.subRequestLookupURI('/docs/', 'HEAD');
+ var docsMg = rq.subRequestLookupURI('/docs/manage', 'HEAD');
+
+ if (0) {
+ print("run test.wox as subreq ...");
+ var res = testRq.runSubRequest();
+ print(" result: " + res);
+ }
+ ]]></var:script>
+
+</var:component>
--- /dev/null
+# $Id: .htaccess,v 1.1 2004/06/14 14:59:48 helge Exp $
+
+LogText "configured in docs/subdir/.htaccess"
--- /dev/null
+<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <body bgcolor="red">
+
+in subdir ...
+
+ </body>
+</html>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>My HTML Page</title>
+ </head>
+
+ <body>
+ <h1>My HTML Page</h1>
+
+
+
+ <hr>
+ <address><a href="mailto:helge.hess@skyrix.com">Helge Hess</a></address>
+<!-- Created: Mon Jun 17 21:10:15 CEST 2002 -->
+<!-- hhmts start -->
+Last modified: Mon Jun 17 21:10:16 CEST 2002
+<!-- hhmts end -->
+ </body>
+</html>
--- /dev/null
+<?xml version="1.0"?>
+<var:component className="Frame" title="name"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:js="http://www.skyrix.com/od/javascript"
+ xmlns:const="http://www.skyrix.com/od/constant">
+ <h3>Apache served .wox page</h3>
+
+ <table border="0">
+ <tr>
+ <td>ComponentName: </td>
+ <td><var:string value="name"/></td>
+ </tr>
+ <tr>
+ <td>Filename: </td>
+ <td><var:string value="context.request.userInfo.ApacheRequest.filename"/></td>
+ </tr>
+ <tr>
+ <td>Pathinfo: </td>
+ <td><var:string value="context.request.userInfo.ApacheRequest.pathInfo"/></td>
+ </tr>
+ <tr>
+ <td>Context:</td>
+ <td><var:string value="context"/></td>
+ </tr>
+ <tr>
+ <td>Request:</td>
+ <td><var:string value="context.request"/></td>
+ </tr>
+ <tr>
+ <td>FormValues Keys:</td>
+ <td><var:string value="context.request.formValueKeys"/></td>
+ </tr>
+ <tr>
+ <td>ApacheRequest:</td>
+ <td><var:string value="context.request.userInfo.ApacheRequest"/></td>
+ </tr>
+ <tr>
+ <td>ApacheConnection:</td>
+ <td><var:string value="context.request.userInfo.ApacheRequest.connection"/></td>
+ </tr>
+ </table>
+
+ <!-- var:script>print('init test');</var:script -->
+
+</var:component>
--- /dev/null
+{
+ class = "WODirectActionRequestHandler";
+}
--- /dev/null
+{
+ class = "XmlRpcRequestHandler";
+}
--- /dev/null
+# $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
+
+<Directory />
+ Options FollowSymLinks
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+</Directory>
+
+Alias /docs/ "/HOME/helge/mdev/helge/ApacheWO/docs/"
+
+<Directory "/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
+</Directory>
+
+<Files ".htaccess">
+ order allow,deny
+ deny from all
+</Files>
+
+<LocationMatch "^.*/CVS/$">
+ order allow,deny
+ deny from all
+</LocationMatch>
+
+<LocationMatch "/sx*">
+ SetSxApplication lapp
+ SetSxRequestHandler WODirectActionRequestHandler
+ SetHandler sx-handler
+</LocationMatch>
+
+# Directory-Index could help ... ?
+#<LocationMatch "^.*/[a-z][a-z0-9_]*.wox/$">
+# ForceType application/x-httpd-wox
+# SetHandler wox-page
+#</LocationMatch>
--- /dev/null
+#!/bin/sh
+
+rm -f core
+httpd -X -f $PWD/httpd.conf
+
--- /dev/null
+// $Id: ApModuleBaseClass+Callbacks.m,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#include "ApModuleBaseClass.h"
+#include <httpd.h>
+#include "http_config.h"
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSAutoreleasePool.h>
+#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) */
--- /dev/null
+// $Id: ApModuleBaseClass+Cmds.m,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#include "ApModuleBaseClass.h"
+#include <httpd.h>
+#include "http_config.h"
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSAutoreleasePool.h>
+#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. </Directory>
+ 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 <Directory> or <Location>
+ * (req_override & ACCESS_CONF) => *.conf inside <Directory> or <Location>
+ * (req_override & OR_AUTHCFG) => *.conf inside <Directory> or <Location>
+ * and .htaccess when AllowOverride
+ * AuthConfig
+ * (req_override & OR_LIMIT) => *.conf inside <Directory> or <Location>
+ * 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) */
--- /dev/null
+// $Id: ApModuleBaseClass+Handler.m,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#include "ApModuleBaseClass.h"
+#include <httpd.h>
+#include "http_config.h"
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSAutoreleasePool.h>
+#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) : "<NULL>",
+ 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) */
--- /dev/null
+// $Id: ApModuleBaseClass.h,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#ifndef __ApModuleBaseClass_H__
+#define __ApModuleBaseClass_H__
+
+#import <Foundation/NSObject.h>
+
+@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 */
--- /dev/null
+// $Id: ApModuleBaseClass.m,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#include "ApModuleBaseClass.h"
+#include <httpd.h>
+#include "http_config.h"
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSAutoreleasePool.h>
+#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) */
--- /dev/null
+// $Id: ApTest.m,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#include "ApacheModule.h"
+#import <Foundation/Foundation.h>
+
+@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 */
--- /dev/null
+// $Id: ApacheCmdParms.h,v 1.1 2004/06/08 11:15:58 helge Exp $
+
+#ifndef __ApacheCmdParms_H__
+#define __ApacheCmdParms_H__
+
+#include <ApacheAPI/ApacheObject.h>
+
+@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__ */
--- /dev/null
+// $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 <Foundation/Foundation.h>
+
+@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 */
--- /dev/null
+// $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__ */
--- /dev/null
+// $Id: ApacheConnection.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "ApacheConnection.h"
+#import <Foundation/NSString.h>
+#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 */
--- /dev/null
+// $Id: ApacheModule.h,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#ifndef __ApacheModule_H__
+#define __ApacheModule_H__
+
+#import <Foundation/NSObject.h>
+
+@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__ */
--- /dev/null
+// $Id: ApacheModule.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "ApacheModule.h"
+#include "ApacheCmdParms.h"
+#include "ApacheResourcePool.h"
+#import <Foundation/Foundation.h>
+#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 */
--- /dev/null
+// $Id: ApacheObject.h,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#ifndef __ApacheObject_H__
+#define __ApacheObject_H__
+
+#import <Foundation/NSObject.h>
+
+@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__ */
--- /dev/null
+// $Id: ApacheObject.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "ApacheObject.h"
+#import <Foundation/Foundation.h>
+
+@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 */
--- /dev/null
+// $Id: ApacheRequest.h,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#ifndef __ApacheRequest_H__
+#define __ApacheRequest_H__
+
+#include "ApacheObject.h"
+#include <stdio.h>
+
+@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__ */
--- /dev/null
+// $Id: ApacheRequest.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "ApacheRequest.h"
+#import <Foundation/Foundation.h>
+#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 */
--- /dev/null
+// $Id: ApacheResourcePool.h,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#ifndef __ApacheResourcePool_H__
+#define __ApacheResourcePool_H__
+
+#include "ApacheObject.h"
+#include <stdio.h>
+
+/*
+ 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__ */
--- /dev/null
+// $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 <Foundation/Foundation.h>
+
+@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 */
--- /dev/null
+// $Id: ApacheServer.h,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#ifndef __ApacheServer_H__
+#define __ApacheServer_H__
+
+#include <ApacheAPI/ApacheObject.h>
+
+@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__ */
--- /dev/null
+// $Id: ApacheServer.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "ApacheServer.h"
+#include <httpd.h>
+#import <Foundation/Foundation.h>
+
+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 */
--- /dev/null
+// $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__ */
--- /dev/null
+// $Id: ApacheTable.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "ApacheTable.h"
+#import <Foundation/NSString.h>
+#include <NGExtensions/NGExtensions.h>
+#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 */
--- /dev/null
+# $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
--- /dev/null
+// $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 <Foundation/Foundation.h>
+
+/*
+ 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;
+}
--- /dev/null
+# $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?
+
--- /dev/null
+#!/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 <<EOF
+/*
+ DO NOT EDIT, automagically generated !!
+
+ Apache module: ${MODULENAME}
+ Module file: ${MFILE}
+ Module class: ${MODULECLASS}
+ Date: `date`
+ Generated By: ${USER}
+ Generator: $0
+*/
+
+#include "ApModuleBaseClass.h"
+#include <httpd.h>
+#include "http_config.h"
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSString.h>
+#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
--- /dev/null
+// $Id: mod_gsbundle.m,v 1.1 2004/06/08 11:15:59 helge Exp $
+
+#include "httpd.h"
+#include "http_config.h"
+#include <dlfcn.h>
+
+/*
+ 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 */
+};
--- /dev/null
+# $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
+
+<Directory />
+ Options FollowSymLinks
+ AllowOverride None
+ MyDirAlias diraliasaa documents
+ MyDirAlias diralias2aa documents2
+ PrintDirConfig 1
+</Directory>
+
+MyServerAlias server alias
+
+<Directory "/HOME/helge/mdev/SkyrixRoot/Library/WebServer/Documents">
+ Options Indexes FollowSymLinks MultiViews
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+ #SetHandler ap-test
+ MyDirAlias diralias documents
+ MyDirAlias diralias2 documents2
+ PrintDirConfig 1
+</Directory>
+
+<IfModule mod_dir.c>
+ DirectoryIndex index.xhtml index.html
+</IfModule>
+
+<Files ~ "^\.ht">
+ Order allow,deny
+ Deny from all
+</Files>
+
+UseCanonicalName On
+
+<IfModule mod_mime.c>
+ TypesConfig /HOME/helge/mdev/SkyrixRoot/Library/WebServer/mime.types
+</IfModule>
+
+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
+<IfModule mod_alias.c>
+</IfModule>
+
+<IfModule mod_mime.c>
+ 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
+</IfModule>
+
+<IfModule mod_setenvif.c>
+ 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
+</IfModule>