GSWAdaptors/Apache2/mod_gsw.c

* make load-balancing work
* add refusing to app status

GSWeb.framework/...
* rewrote GSWComponentRequestHandler to make refusing work



git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@26404 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Dave Wetzel 2008-03-30 22:10:20 +00:00
parent fe4f1484fc
commit a24b60e6f4
11 changed files with 603 additions and 655 deletions

View file

@ -1,3 +1,19 @@
2008-03-31 David Wetzel <dave@turbocat.de>
GSWAdaptors/Apache2/mod_gsw.c
* make load-balancing work
* add refusing to app status
GSWeb.framework/GSWApplication.m
GSWeb.framework/GSWRequestHandler.h
GSWeb.framework/GSWComponentRequestHandler.h
GSWeb.framework/GSWComponentRequestHandler.m
GSWeb.framework/GSWResponse.m
GSWeb.framework/GSWConstants.h
GSWeb.framework/GSWConstants.m
GSWeb.framework/GSWPrivate.h
GSWeb.framework/GSWApplication.h
* rewrote GSWComponentRequestHandler to make refusing work
2008-03-17 David Wetzel <dave@turbocat.de>
GSWeb.framework/GSWAssociation.h/m
+ bindingInComponent

View file

@ -111,6 +111,7 @@ typedef struct gsw_app_conf {
} gsw_app_conf;
#define GSW_INST_CACHE "gsw_inst_cache"
#define X_WO_VERSION_HEADER "x-webobjects-adaptor-version: 20071201\r\n"
#define SERVER_SOFTWARE "SERVER_SOFTWARE"
@ -170,10 +171,11 @@ char *mutexfilename;
typedef struct exipc_data {
apr_time_t last_response_time; // in sec since January 1, 1970
apr_time_t last_response_time; // in sec since January 1, 1970
apr_time_t last_request_time; // in sec since January 1, 1970
u_int32_t load;
u_int8_t unreachable; // 0=online 1=unreachable
u_int8_t unreachable; // 0=online 1=unreachable
u_int8_t refusing; // 0=serving new sessions 1=refusing
} exipc_data;
/*
@ -302,6 +304,21 @@ void mark_unreachable(gsw_app_conf * app)
apr_global_mutex_unlock(exipc_mutex);
}
void mark_refusing(gsw_app_conf * app)
{
exipc_data * mem = NULL;
apr_time_t now = apr_time_now();
u_int16_t index = app->total_index;
apr_global_mutex_lock(exipc_mutex);
mem = (exipc_data *) apr_shm_baseaddr_get(exipc_shm);
mem[index].last_request_time = now;
mem[index].refusing = 1;
apr_global_mutex_unlock(exipc_mutex);
}
void update_app_statistics(gsw_app_conf * app, apr_time_t last_request_time, apr_time_t last_response_time, u_int32_t load)
{
exipc_data * mem = NULL;
@ -314,6 +331,7 @@ void update_app_statistics(gsw_app_conf * app, apr_time_t last_request_time, apr
mem[index].last_request_time = last_request_time;
mem[index].last_response_time = last_response_time;
mem[index].load = load;
mem[index].unreachable = 0;
apr_global_mutex_unlock(exipc_mutex);
}
@ -359,13 +377,15 @@ gsw_app_conf * find_app_by_name(char * name, gsw_cfg *cfg, request_rec *r)
if ((strcasecmp(appconf->app_name, name) == 0)) {
// enable unreachable instances after some time
if ((mem[i].unreachable == 1) && (mem[i].last_request_time < t)) {
if (mem[i].last_request_time < t) {
mem[i].unreachable = 0;
mem[i].refusing = 0;
}
if (mem[i].unreachable == 0) {
if ((mem[i].unreachable == 0) && (mem[i].refusing == 0)) {
if (mem[i].load <= lastload) {
lastindex = i;
lastindex = i;
lastload = mem[i].load;
}
}
}
@ -399,20 +419,20 @@ gsw_app_conf * find_app(request_rec *r)
strncpy(app_name, appName, sizeof(app_name));
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "app_name '%s'", app_name);
if ((appName = index(app_name, '.'))) {
*appName = '\0';
} else {
return NULL;
}
appName++;
// now get the instance number if any
appName++;
if ((instance_str = index(appName, '/'))) {
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "instance_str '%s'", instance_str);
instance_str++;
if (appName = index(instance_str, '/')) {
*appName = '\0';
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "appName '%s'", appName);
instance_nr = atoi(instance_str);
// parse error?
if (instance_nr == 0) {
@ -421,9 +441,16 @@ gsw_app_conf * find_app(request_rec *r)
}
}
} else {
// return NULL;
}
cfg = our_dconfig(r);
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "instance_nr '%d'", instance_nr);
if (instance_nr != -1) {
char tmp_key[128];
@ -436,7 +463,7 @@ gsw_app_conf * find_app(request_rec *r)
}
app_conf = find_app_by_name(app_name, cfg, r);
return app_conf;
}
@ -594,7 +621,64 @@ static int send_header_string(int soc, const char * key, const char * value, req
retval = write_sock(soc, tmpStr, strlen(tmpStr), r);
}
static int send_headers(int soc, request_rec *r)
const char * fixRequestString(request_rec *r, gsw_app_conf *app)
{
char * req_str = r->the_request;
size_t len = strlen(req_str);
char * appName = apr_palloc(r->pool,len+5);
char * spaceStr;
char * instanceStr;
char * restStr = NULL;
int instance_nr = -1;
char * newString = NULL;
strncpy(appName, req_str, len);
// GET /wo/PBX HTTP/1.1
if (appName = index(appName, '/')) {
appName++;
if (appName = index(appName, '/')) {
appName++;
if (spaceStr = index(appName, ' ')) {
*spaceStr = '\0';
instanceStr = appName;
instanceStr++;
if (instanceStr = index(appName, '/')) {
*instanceStr = '\0';
instanceStr++;
if (spaceStr = index(instanceStr, '/')) {
*spaceStr = '\0';
restStr = spaceStr;
restStr++;
}
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "instanceStr:'%s'", instanceStr);
}
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "appName:'%s'", appName);
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "restStr:'%s'", restStr);
}
}
}
if (!restStr) {
restStr = "";
}
if (spaceStr = index(appName, '.')) {
*spaceStr = '\0';
}
newString = apr_psprintf(r->pool, "%s %s%s.woa/%d/%s HTTP/1.1\r\n", r->method, ADAPTOR_PREFIX, appName, app->instance_number
,restStr);
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "newString:'%s'", newString);
return newString;
}
static int send_headers(int soc, gsw_app_conf *app, request_rec *r)
{
apr_array_header_t * hdrs_arr = NULL;
apr_table_entry_t * hdrs = NULL;
@ -607,9 +691,16 @@ static int send_headers(int soc, request_rec *r)
hdrs_arr = (apr_array_header_t*) apr_table_elts(r->headers_in);
hdrs = (apr_table_entry_t *) hdrs_arr->elts;
snprintf(tmpStr, sizeof(tmpStr), "%s\r\n", r->the_request);
// GET /wo/PBX HTTP/1.1
//snprintf(tmpStr, sizeof(tmpStr), "%s\r\n", r->the_request);
strncpy(tmpStr, fixRequestString(r,app), sizeof(tmpStr));
retval = write_sock(soc,tmpStr,strlen(tmpStr), r);
// ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "send_headers:'%s'", tmpStr);
if (retval != 0) {
return retval;
}
@ -746,7 +837,7 @@ static int handle_request(request_rec *r, gsw_app_conf * app, void * postdata, u
soc = connect_host(app->host_name, app->port);
if (soc != -1) {
if (send_headers(soc, r) == 0) {
if (send_headers(soc, app, r) == 0) {
int headers_done = 0;
request_time = apr_time_now();
@ -768,13 +859,15 @@ static int handle_request(request_rec *r, gsw_app_conf * app, void * postdata, u
http_status = atoi(newBuf+9);
if (http_status==200) {
http_status=OK;
}
}
if (http_status == 302) {
r->status = http_status;
}
}
}
while (headers_done == 0) {
newBuf = read_sock_line(soc, r, sub_pool);
if (newBuf != NULL) {
if (load_avr_seen == 0) {
if (strncmp(newBuf, "x-webobjects-loadaverage: ", 26) == 0) {
@ -802,9 +895,11 @@ static int handle_request(request_rec *r, gsw_app_conf * app, void * postdata, u
}
}
if (location == NULL) {
if (strncmp(newBuf, "location: ", 10) == 0) {
// Apple has a bug, giving us a 'L', so we do that too but accept a 'l' too -- dw
if (strncasecmp(newBuf, "location: ", 10) == 0) {
location = newBuf+10;
apr_table_set(r->headers_out, "location", location);
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "location '%s'", location);
}
}
} else {
@ -813,14 +908,16 @@ static int handle_request(request_rec *r, gsw_app_conf * app, void * postdata, u
} // while
// do the request
if ((content_type != NULL) && (content_length > 0)) {
if ((content_length > 0)) {
size_t bytesDone = 0;
size_t blockSize = 1024;
size_t rval=1;
char * transferBuf = NULL;
ap_set_content_type(r, content_type);
if (content_type != NULL) {
ap_set_content_type(r, content_type);
}
if (content_length < blockSize) {
blockSize = content_length;
}
@ -844,7 +941,11 @@ static int handle_request(request_rec *r, gsw_app_conf * app, void * postdata, u
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Request took %d ms", apr_time_msec(done_time - request_time));
update_app_statistics(app, request_time, done_time, newload);
if (http_status==302) {
mark_refusing(app);
} else {
update_app_statistics(app, request_time, done_time, newload);
}
} else { // -1
http_status = UNREACHABLE;
@ -1075,6 +1176,8 @@ static int gsw_handler(request_rec *r)
break;
case OK:
return handle_status;
case HTTP_MOVED_TEMPORARILY:
return OK; // otherwise, we get a apache error doc!
default:
break;
}
@ -1122,7 +1225,7 @@ static int gsw_handler(request_rec *r)
if (mem) {
ap_rputs("<table border=1>\n",r);
ap_rputs("<tr><td>Name</td><td>Instance</td><td>Host</td><td>Port</td><td>Load</td><td> Unreachable</td><td>Last Request</td><td>Last Response</td></tr>\n",r);
ap_rputs("<tr><td>Name</td><td>Instance</td><td>Host</td><td>Port</td><td>Load</td><td> Unreachable</td><td>Refusing</td><td>Last Request</td><td>Last Response</td></tr>\n",r);
for (i = 0; i < tarr->nelts; i++) {
gsw_app_conf *appconf = (gsw_app_conf *) telts[i].val;
@ -1136,6 +1239,7 @@ static int gsw_handler(request_rec *r)
ap_rprintf(r, "<td>%u</td>", appconf->port);
ap_rprintf(r, "<td>%u</td>", mem[i].load);
ap_rprintf(r, "<td>%s</td>", (mem[i].unreachable == 1) ? "YES": "NO");
ap_rprintf(r, "<td>%s</td>", (mem[i].refusing == 1) ? "YES": "NO");
apr_ctime(timestr, mem[i].last_request_time);
ap_rprintf(r, "<td>%s</td>", timestr);
apr_ctime(timestr, mem[i].last_response_time);
@ -1437,6 +1541,7 @@ void init_shared_mem(const apr_shm_t * xxx, int count, server_rec * s)
currentRecord[i].last_response_time = 0;
currentRecord[i].load = 0;
currentRecord[i].unreachable = 0;
currentRecord[i].refusing = 0;
}
}

View file

@ -123,6 +123,7 @@ GSWEB_EXPORT BOOL WOStrictFlag;
BOOL _isTracingObjectiveCMessagesEnabled;
BOOL _isTracingScriptedMessagesEnabled;
BOOL _isTracingStatementsEnabled;
BOOL _allowsConcurrentRequestHandling;
NSRunLoop* _currentRunLoop;
NSDate* _runLoopDate;
NSTimer* _initialTimer;
@ -135,10 +136,11 @@ GSWEB_EXPORT BOOL WOStrictFlag;
-(void)dealloc;
-(id)init;
-(BOOL) shouldRestoreSessionOnCleanEntry:(GSWRequest*) aRequest;
-(BOOL)allowsConcurrentRequestHandling;
-(BOOL)adaptorsDispatchRequestsConcurrently;
-(BOOL)isConcurrentRequestHandlingEnabled;
-(NSLock *) requestHandlingLock;
-(BOOL)isRequestHandlingLocked;
-(void)lockRequestHandling;
-(void)unlockRequestHandling;
@ -163,6 +165,8 @@ GSWEB_EXPORT BOOL WOStrictFlag;
-(NSString*)defaultRequestHandlerClassName;
-(Class)defaultRequestHandlerClass;
- (NSString*) sessionIdKey;
- (NSString*) instanceIdKey;
@end
//
////====================================================================

View file

@ -301,6 +301,7 @@ int GSWApplicationMain(NSString* applicationClassName,
_minimumActiveSessionsCount = 0; // 0 is default
_dynamicLoadingEnabled=YES;
_printsHTMLParserDiagnostics=YES;
_allowsConcurrentRequestHandling = NO;
[[self class] _setApplication:self];
[self _touchPrincipalClasses];
@ -453,6 +454,12 @@ int GSWApplicationMain(NSString* applicationClassName,
return dscr;
};
-(BOOL) shouldRestoreSessionOnCleanEntry:(GSWRequest*) aRequest
{
return NO;
}
//--------------------------------------------------------------------
// allowsConcurrentRequestHandling
-(BOOL)allowsConcurrentRequestHandling
@ -464,21 +471,24 @@ int GSWApplicationMain(NSString* applicationClassName,
// adaptorsDispatchRequestsConcurrently
-(BOOL)adaptorsDispatchRequestsConcurrently
{
//TODO: use isMultiThreaded ?
BOOL adaptorsDispatchRequestsConcurrently=NO;
int i=0;
int adaptorsCount=[_adaptors count];
for(i=0;!adaptorsDispatchRequestsConcurrently && i<adaptorsCount;i++)
adaptorsDispatchRequestsConcurrently=[[_adaptors objectAtIndex:i]dispatchesRequestsConcurrently];
return adaptorsDispatchRequestsConcurrently;
};
return _isMultiThreaded;
}
//--------------------------------------------------------------------
// isConcurrentRequestHandlingEnabled
-(BOOL)isConcurrentRequestHandlingEnabled
{
return [self allowsConcurrentRequestHandling];
};
return (_isMultiThreaded && _allowsConcurrentRequestHandling);
}
- (NSLock *) requestHandlingLock
{
if (_isMultiThreaded && (!_allowsConcurrentRequestHandling)) {
return _globalLock;
}
return nil;
}
//--------------------------------------------------------------------
// calls the class because on MacOSX KVC does not support "application.class.isDebuggingEnabled"
@ -2294,7 +2304,7 @@ to another instance **/
//terminate
-(void)terminate
{
NSTimer* timer=nil;
// NSTimer* timer=nil;
_terminating = YES;
/*
timer=[NSTimer timerWithTimeInterval:0
@ -2456,120 +2466,37 @@ to another instance **/
};
-(GSWResponse*)checkAppIfRefused:(GSWRequest*)aRequest
{
NSDictionary* requestHandlerValues=nil;
GSWResponse* response=nil;
NSString* sessionID=nil;
BOOL refuseRequest = NO;
NS_DURING
{
// NSLog(@"Application : checkAppIfRefused");
// NSLog(@"Application : allSessionIDs = %@", [_sessionStore allSessionIDs]);
requestHandlerValues=[GSWComponentRequestHandler _requestHandlerValuesForRequest:aRequest];
if (requestHandlerValues)
{
// NSLog(@"Application : requestHandlerValues is set");
sessionID=[requestHandlerValues objectForKey:GSWKey_SessionID[GSWebNamingConv]];
if (!sessionID)
{
if ([self isRefusingNewSessions])
{
NSLog(@"refuseRequest !");
refuseRequest = YES;
};
}
else
{
// NSLog(@"Application : sessionID found : %@", sessionID);
// NSLog(@"Application : allSessionIDs = %@", [_sessionStore allSessionIDs]);
// check for existing session ID
if (![_sessionStore containsSessionID:sessionID])
{
// NSLog(@"Application : sessionStore does not contain _sessionID");
if ([self isRefusingNewSessions])
refuseRequest = YES;
}
}
if (refuseRequest)
{
NSLog(@"Application : refuseRequest == YES ,generate Response");
// generate response, to refuse the request
response=[GSWResponse generateRefusingResponseInContext:nil
forRequest:aRequest];
if (response)
[response _finalizeInContext:nil]; //DO Call _finalizeInContext: !
}
}
}
NS_HANDLER
{
}
NS_ENDHANDLER;
return response;
}
-(GSWResponse*)dispatchRequest:(GSWRequest*)aRequest
{
//OK
GSWResponse* response=nil;
GSWRequestHandler* requestHandler=nil;
GSWResponse * response=nil;
GSWRequestHandler * requestHandler=nil;
NSNotificationCenter * noteCenter = [NSNotificationCenter defaultCenter];
#ifndef NDEBUG
[self lock];
GSWeb_ApplicationDebugSetChange();
[self unlock];
#endif
NS_DURING
{
ASSIGN(_lastAccessDate,[NSDate date]);
[[NSNotificationCenter defaultCenter]postNotificationName:@"ApplicationWillDispatchRequestNotification"
object:aRequest];
response = [self checkAppIfRefused:aRequest];
if (!response)
{
NSDebugMLLog(@"requests",@"aRequest=%@",aRequest);
requestHandler=[self handlerForRequest:aRequest];
NSDebugMLLog(@"requests",@"requestHandler=%@",requestHandler);
if (!requestHandler)
requestHandler=[self defaultRequestHandler];
NSDebugMLLog(@"requests",@"requestHandler=%@",requestHandler);
if (!requestHandler)
{
NSDebugMLLog0(@"application",@"GSWApplication dispatchRequest: no request handler");
//TODO error
}
else
{
NSDebugMLLog(@"requests",@"sessionStore=%@",_sessionStore);
response=[requestHandler handleRequest:aRequest];
NSDebugMLLog(@"requests",@"sessionStore=%@",_sessionStore);
[self _resetCache];
NSDebugMLLog(@"requests",@"sessionStore=%@",_sessionStore);
};
if (!response)
{
//TODO RESPONSE_PB
};
[[NSNotificationCenter defaultCenter]postNotificationName:@"ApplicationDidDispatchRequestNotification"
object:response];
[aRequest _setContext:nil];
};
{
ASSIGN(_lastAccessDate,[NSDate date]);
[noteCenter postNotificationName:@"ApplicationWillDispatchRequestNotification"
object:aRequest];
requestHandler = [self handlerForRequest:aRequest];
if (!requestHandler)
requestHandler = [self defaultRequestHandler];
response = [requestHandler handleRequest:aRequest];
if (!response) {
NSDebugLog(@"%s !!! Response is null !!!", __PRETTY_FUNCTION__);
response = [self createResponseInContext:nil];
}
[self _resetCache];
[noteCenter postNotificationName:@"ApplicationDidDispatchRequestNotification"
object:response];
[aRequest _setContext:nil];
}
NS_HANDLER
{
NSLog(@"EXCEPTION: %@",localException);
@ -2577,7 +2504,7 @@ to another instance **/
NS_ENDHANDLER;
return response;
};
}
//--------------------------------------------------------------------
//awake
@ -4210,5 +4137,15 @@ to another instance **/
return languages;
};
- (NSString*) sessionIdKey
{
return @"wosid";
}
- (NSString*) instanceIdKey
{
return @"woinst";
}
@end

View file

@ -38,26 +38,8 @@
}
-(GSWResponse*)handleRequest:(GSWRequest*)aRequest;
-(GSWResponse*)lockedHandleRequest:(GSWRequest*)aRequest;
-(GSWResponse*)lockedDispatchWithPreparedApplication:(GSWApplication*)application
inContext:(GSWContext*)aContext
elements:(NSDictionary*)elements;
-(GSWResponse*)lockedDispatchWithPreparedSession:(GSWSession*)aSession
inContext:(GSWContext*)aContext
elements:(NSDictionary*)elements;
-(GSWResponse*)lockedDispatchWithPreparedPage:(GSWComponent*)_component
inSession:(GSWSession*)aSession
inContext:(GSWContext*)aContext
elements:(NSDictionary*)elements;
-(GSWComponent*)lockedRestorePageForContextID:(NSString*)aContextID
inSession:(GSWSession*)aSession;
@end
//====================================================================
@interface GSWComponentRequestHandler (GSWRequestHandlerClassA)
+(id)handler;
+(NSDictionary*)_requestHandlerValuesForRequest:(GSWRequest*)aRequest;
@end
#endif //_GSWComponentRequestHandler_h__

View file

@ -2,8 +2,8 @@
Copyright (C) 1999-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Feb 1999
Written by: David Wetzel <dave@turbocat.de>
Date: Mar 2008
$Revision$
$Date$
@ -32,506 +32,390 @@
RCS_ID("$Id$")
#include "GSWeb.h"
#include "GSWPrivate.h"
//====================================================================
@implementation GSWComponentRequestHandler
//--------------------------------------------------------------------
// note: we are NOT looking at [WORequest _lookForIDsInCookiesFirst] since it is always NO -- dw
- (NSDictionary*) requestHandlerValuesForRequest:(GSWRequest *) aRequest
{
NSMutableDictionary * aDictionary = [NSMutableDictionary dictionary];
NSArray * pathArray = [aRequest requestHandlerPathArray];
NSString * lastObject = nil;
NSString * penultElement = nil;
NSString * aSessionID = nil;
NSString * aContextID = nil;
NSString * aSenderID = nil;
NSMutableString * pageName = nil;
NSString * sessionIdKey = [GSWApp sessionIdKey];
int p = 0;
int count = 0;
int length = 0;
int pageNameLocation = 0;
int pageNameLength = 0;
if ((pathArray))
{
count = [pathArray count];
}
if (count != 0)
{
lastObject = [pathArray lastObject];
if(count > 1)
{
penultElement = [pathArray objectAtIndex:count - 2];
}
for (length = [lastObject length]; ((p < length) && (isdigit([lastObject characterAtIndex:p]) != 0)); p++) { }
if ((p < length) && ([lastObject characterAtIndex:p] == '.')) {
aContextID = [lastObject substringToIndex:p];
p++;
aSenderID = [lastObject substringFromIndex:p];
if ((penultElement != nil) && ([penultElement hasSuffix:GSWPagePSuffix[GSWebNamingConv]])) {
if (GSWebNamingConv == 1) {
pageNameLength = count - 2; // .wo
} else {
pageNameLength = count - 4; // .gswc
}
} else {
if (penultElement != nil) {
aSessionID = penultElement;
pageNameLength = count - 2; // TODO:check if that works with GSWNAMES.
} else {
pageNameLength = 0;
}
}
if (aContextID != nil)
{
[aDictionary setObject:aContextID forKey:GSWKey_ContextID[GSWebNamingConv]]; // wocid
[aDictionary setObject:aSenderID forKey:GSWKey_ElementID[GSWebNamingConv]]; // woeid
}
} else {
if ([lastObject hasSuffix:GSWPagePSuffix[GSWebNamingConv]]) {
pageNameLength = count;
} else {
aSessionID = lastObject;
pageNameLength = count - 1;
}
}
if (pageNameLength != 0) {
if (pageNameLength == 1) {
pageName = [pathArray objectAtIndex:0];
} else {
int i;
pageName = [[NSMutableString alloc] initWithCapacity:256];
[pageName autorelease];
for (i = pageNameLocation; i < pageNameLength - pageNameLocation; i++) {
[pageName appendString:[pathArray objectAtIndex:i]];
[pageName appendString:@"/"];
}
[pageName appendString:[pathArray objectAtIndex:i]];
}
if ([pageName hasSuffix:GSWPagePSuffix[GSWebNamingConv]]) {
if (GSWebNamingConv == 1) {
pageName = (NSMutableString*) [pageName substringToIndex:[pageName length] - 3]; // .wo
} else {
pageName = (NSMutableString*) [pageName substringToIndex:[pageName length] - 5]; // .gswc
}
}
[aDictionary setObject:pageName
forKey:GSWKey_PageName[GSWebNamingConv]];
}
if (aSessionID == nil) {
aSessionID = [aRequest stringFormValueForKey:sessionIdKey];
if(aSessionID == nil) {
aSessionID = [aRequest cookieValueForKey:sessionIdKey];
}
}
} else {
if ([GSWApp shouldRestoreSessionOnCleanEntry:aRequest]) {
aSessionID = [aRequest cookieValueForKey:sessionIdKey];
}
}
if ((aSessionID != nil) && ([aSessionID length] > 0)) {
[aDictionary setObject:aSessionID forKey:sessionIdKey];
}
return aDictionary;
}
GSWResponse * _dispatchWithPreparedPage(GSWComponent * aPage, GSWSession * aSession, GSWContext * aContext, NSDictionary * someElements)
{
GSWRequest * aRequest = [aContext request];
GSWApplication * anApplication = GSWApp;
GSWResponse * aResponse = [anApplication createResponseInContext:aContext];
NSString * aSenderID = [aContext senderID];
NSString * oldContextID = [aSession _contextIDMatchingIDsInContext:aContext];
BOOL didPageChange = NO;
[aResponse setHTTPVersion:[aRequest httpVersion]];
[aResponse setHeader:@"text/html"
forKey:@"content-type"];
[aContext _setResponse:aResponse];
if (oldContextID == nil) {
if ((aSenderID != nil) && ([aRequest _hasFormValues])) {
[anApplication takeValuesFromRequest:aRequest inContext:aContext];
}
[aContext _setPageChanged:NO];
if (aSenderID != nil) {
GSWElement * anActionResults = [anApplication invokeActionForRequest:aRequest inContext:aContext];
if ((anActionResults == nil) || ([anActionResults isKindOfClass: [GSWComponent class]])) {
GSWComponent * aResultComponent = (GSWComponent*) anActionResults;
if ((aResultComponent != nil) && ([aResultComponent context] != aContext)) {
[aResultComponent _awakeInContext:aContext];
}
if ((aResultComponent != nil) && (aResultComponent != [aContext _pageElement])) {
didPageChange = YES;
}
[aContext _setPageChanged:didPageChange];
if (didPageChange) {
[aContext _setPageElement:aResultComponent];
}
} else {
GSWResponse * theResponse = [anActionResults generateResponse];
return theResponse;
}
}
} else {
GSWComponent * responsePage = [aSession restorePageForContextID:oldContextID];
[aContext _setPageElement:responsePage];
}
[anApplication appendToResponse:aResponse inContext: aContext];
return aResponse;
}
GSWResponse * _dispatchWithPreparedSession(GSWSession * aSession, GSWContext * aContext, NSDictionary * someElements)
{
GSWComponent * aPage = nil;
GSWResponse * aResponse = nil;
NSString * aPageName = [someElements objectForKey:GSWKey_PageName[GSWebNamingConv]]; // "wopage"
NSString * oldContextID = [aContext _requestContextID];
GSWApplication * anApplication = GSWApp;
NSString * sessionIdKey = [anApplication sessionIdKey];
NSString * oldSessionID = [someElements objectForKey:sessionIdKey];
BOOL clearIDsInCookies = NO;
BOOL storesIDsInCookies = [aSession storesIDsInCookies];
if ((oldSessionID == nil) || (oldContextID == nil)) {
if ((aPageName == nil) && (!storesIDsInCookies))
{
GSWRequest * request = [aContext request];
NSString * cookieHeader = [request headerForKey:GSWHTTPHeader_Cookie]; //"cookie"
if ((cookieHeader != nil) && ([cookieHeader length] > 0)) {
NSDictionary * cookieDict = [request cookieValues];
if (([cookieDict objectForKey:sessionIdKey] != nil) ||
([cookieDict objectForKey:[anApplication instanceIdKey]] != nil)) {
clearIDsInCookies = YES;
}
}
}
aPage = [anApplication pageWithName:aPageName inContext:aContext];
} else {
aPage = [aSession restorePageForContextID:oldContextID];
if (aPage == nil) {
if ([anApplication _isPageRecreationEnabled]) {
aPage = [anApplication pageWithName:aPageName inContext: aContext];
} else {
return [anApplication handlePageRestorationErrorInContext:aContext];
}
}
}
[aContext _setPageElement:aPage];
aResponse = _dispatchWithPreparedPage(aPage, aSession, aContext, someElements);
if ([anApplication isPageRefreshOnBacktrackEnabled]) {
[aResponse disableClientCaching];
}
[aSession _saveCurrentPage];
if ((clearIDsInCookies) && (!storesIDsInCookies)) {
[aSession _clearCookieFromResponse:aResponse];
}
return aResponse;
}
GSWResponse * _dispatchWithPreparedApplication(GSWApplication *app, GSWContext * aContext, NSDictionary * requestHandlerDict)
{
GSWSession * session = nil;
GSWResponse * response = nil;
GSWRequest * request = [aContext request];
NSString * sessionID;
sessionID = [requestHandlerDict objectForKey:GSWKey_SessionID[GSWebNamingConv]]; //@"wosid"
if ((!sessionID)) {
session = [app _initializeSessionInContext:aContext];
} else {
session = [app restoreSessionWithID:sessionID inContext:aContext];
}
if (session == nil) {
response = [app handleSessionCreationErrorInContext:aContext];
} else {
response = _dispatchWithPreparedSession(session, aContext, requestHandlerDict);
}
[aContext _putAwakeComponentsToSleep];
[app saveSessionForContext:aContext];
return response;
}
- (GSWResponse*) _handleRequest:(GSWRequest*) aRequest
{
GSWContext * aContext = nil;
NSDictionary * requestHandlerValues;
NSString * aSessionID;
NSString * aSenderID;
NSString * oldContextID;
GSWStatisticsStore * aStatisticsStore;
GSWResponse * aResponse;
GSWApplication * app = GSWApp; // is there any reason not to use the global var? -- dw
requestHandlerValues = [self requestHandlerValuesForRequest:aRequest];
aSessionID = [requestHandlerValues objectForKey:[app sessionIdKey]];
if ((aSessionID == nil) && [app isRefusingNewSessions])
{
NSString * newLocationURL = [app _newLocationForRequest:aRequest];
NSString * msgString = [NSString stringWithFormat:@"Sorry, your request could not immediately be processed. Please try this URL: <a href=\"%@\">%@</a>",
newLocationURL, newLocationURL];
aResponse = [app createResponseInContext:nil];
[aResponse _redirectResponse:newLocationURL contentString:msgString];
[aResponse _finalizeInContext:nil];
return aResponse;
}
aSenderID = [requestHandlerValues objectForKey:GSWKey_ElementID[GSWebNamingConv]];
oldContextID = [requestHandlerValues objectForKey:GSWKey_ContextID[GSWebNamingConv]];
if ((aStatisticsStore = [app statisticsStore]))
{
[aStatisticsStore applicationWillHandleComponentActionRequest];
}
NS_DURING {
aContext = [app createContextForRequest:aRequest];
[aContext _setRequestContextID:oldContextID];
[aContext _setSenderID:aSenderID];
[app awake];
aResponse = _dispatchWithPreparedApplication(app, aContext, requestHandlerValues);
[[NSNotificationCenter defaultCenter] postNotificationName:DidHandleRequestNotification
object:aContext];
[app sleep];
} NS_HANDLER {
GSWSession * aSession = nil;
NSLog(@"%s: Exception occurred while handling request:%@", __PRETTY_FUNCTION__, [localException reason]);
if(aContext == nil)
{
aContext = [app createContextForRequest:aRequest];
} else {
[aContext _putAwakeComponentsToSleep];
}
aSession = [aContext _session];
aResponse = [app handleException:localException
inContext:aContext];
if (aSession) {
NS_DURING {
[app saveSessionForContext:aContext];
[app sleep];
} NS_HANDLER {
NSLog(@"WOApplication '%@': Another Exception occurred while trying to clean the application :%@", [app name], [localException reason]);
} NS_ENDHANDLER;
}
} NS_ENDHANDLER;
if ((aContext) && ([aContext _session]))
{
[app saveSessionForContext:aContext];
}
if ((aResponse))
{
[aResponse _finalizeInContext:aContext];
}
if ((aStatisticsStore))
{
GSWComponent * aPage = [aContext page];
NSString * pageName = nil;
if ((aPage))
{
pageName = [aPage name];
}
[aStatisticsStore applicationDidHandleComponentActionRequestWithPageNamed:pageName];
}
return aResponse;
}
/** Handle request aRequest and return the response
This lock application
This may lock the application
**/
-(GSWResponse*)handleRequest:(GSWRequest*)aRequest
{
//OK
GSWResponse* response=nil;
GSWApplication* application=[GSWApplication application];
NSLock * lock;
[application lockRequestHandling];
response=[self lockedHandleRequest:aRequest];
if (!response)
{
response=[GSWResponse responseWithMessage:@"Component Handle request failed. No Response"
inContext:nil
forRequest:aRequest];
[response _finalizeInContext:nil]; //DO Call _finalizeInContext: !
};
[application unlockRequestHandling];
return response;
};
//--------------------------------------------------------------------
/** Handle request aRequest and return the response
Application should be locked before this
**/
-(GSWResponse*)lockedHandleRequest:(GSWRequest*)aRequest
{
//OK
//GSWStatisticsStore* statisticsStore=nil;
GSWApplication* application=[GSWApplication application];
GSWContext* aContext=nil;
GSWResponse* response=nil;
NSDictionary* requestHandlerValues=nil;
BOOL exceptionRaised=NO;
// NSLog(@"%s %@",__PRETTY_FUNCTION__, aRequest);
NS_DURING
{
requestHandlerValues=[GSWComponentRequestHandler _requestHandlerValuesForRequest:aRequest];
}
NS_HANDLER
{
exceptionRaised=YES;
LOGException(@"%@ (%@)",
localException,
[localException reason]);
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"In -lockedHandleRequest:");
LOGException(@"exception=%@",localException);
[application awake];
response=[application handleException:localException
inContext:nil];
[application sleep];
[response _finalizeInContext:aContext];//DO Call _finalizeInContext: !
NSAssert(!response || [response isFinalizeInContextHasBeenCalled],@"_finalizeInContext not called for GSWResponse");
};
NS_ENDHANDLER;
if (!exceptionRaised)
{
NSString* senderID=nil;
NSString* requestContextID=nil;
aContext=[[GSWApplication application]createContextForRequest:aRequest];
senderID=[requestHandlerValues objectForKey:GSWKey_ElementID[GSWebNamingConv]];
[aContext _setSenderID:senderID];
requestContextID=[requestHandlerValues objectForKey:GSWKey_ContextID[GSWebNamingConv]];
[aContext _setRequestContextID:requestContextID];
[application _setContext:aContext];
//====>
NS_DURING
{
[application awake];
response=[self lockedDispatchWithPreparedApplication:application
inContext:aContext
elements:requestHandlerValues];
}
NS_HANDLER
{
exceptionRaised=YES;
LOGException(@"%@ (%@)",
localException,
[localException reason]);
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"In lockedDispatchWithPreparedApplication");
LOGException(@"exception=%@",localException);
response=[application handleException:localException
inContext:aContext];
[application sleep];
[response _finalizeInContext:aContext]; //DO Call _finalizeInContext: !
NSAssert(!response || [response isFinalizeInContextHasBeenCalled],
@"_finalizeInContext not called for GSWResponse");
};
NS_ENDHANDLER;
if (!exceptionRaised)
{
NS_DURING
{
[application sleep];
[response _finalizeInContext:aContext];//LAST //CLEAN
}
NS_HANDLER
{
LOGException(@"%@ (%@)",
localException,
[localException reason]);
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"In [application sleep] or [response _finalizeInContext:aContext]");
LOGException(@"exception=%@",localException);
response=[application handleException:localException
inContext:nil];
[response _finalizeInContext:aContext]; //DO Call _finalizeInContext: !
NSAssert(!response || [response isFinalizeInContextHasBeenCalled],
@"_finalizeInContext not called for GSWResponse");
};
NS_ENDHANDLER;
};
//<===========
};
lock = [GSWApp requestHandlingLock];
if (lock) {
SYNCHRONIZED(lock) {
response = [self _handleRequest:aRequest];
}
END_SYNCHRONIZED;
} else {
// no locking
response = [self _handleRequest:aRequest];
}
[application _setContext:nil];
return response;
};
}
//--------------------------------------------------------------------
-(GSWResponse*)lockedDispatchWithPreparedApplication:(GSWApplication*)application
inContext:(GSWContext*)aContext
elements:(NSDictionary*)elements
{
//OK
GSWResponse* response=nil;
GSWResponse* errorResponse=nil;
GSWSession* session=nil;
NSString* sessionID=nil;
NS_DURING
{
sessionID=[elements objectForKey:GSWKey_SessionID[GSWebNamingConv]];
if (sessionID)
{
session=[application restoreSessionWithID:sessionID
inContext:aContext];
if (!session)
{
// check for refuseNewSessions
errorResponse=[application handleSessionRestorationErrorInContext:aContext];
};
}
else
{
// check for refuseNewSessions
session=[application _initializeSessionInContext:aContext];
}
}
NS_HANDLER
{
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"in session create/restore");
LOGException(@"exception=%@",localException);
errorResponse=[application handleException:localException
inContext:aContext];
}
NS_ENDHANDLER;
if (!response && !errorResponse)
{
if (session)
{
NS_DURING
{
response=[self lockedDispatchWithPreparedSession:session
inContext:aContext
elements:elements];
}
NS_HANDLER
{
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"in lockedDispatchWithPreparedSession");
LOGException(@"exception=%@",localException);
errorResponse=[application handleException:localException
inContext:aContext];
}
NS_ENDHANDLER;
};
};
//======LAST //CLEAN
if (response || errorResponse)
{
RETAIN(response);
[aContext _putAwakeComponentsToSleep];
[application saveSessionForContext:aContext];
AUTORELEASE(response);
};
return response ? response : errorResponse;
};
//--------------------------------------------------------------------
-(GSWResponse*)lockedDispatchWithPreparedSession:(GSWSession*)aSession
inContext:(GSWContext*)aContext
elements:(NSDictionary*)elements
{
//OK
GSWResponse* errorResponse=nil;
GSWResponse* response=nil;
GSWComponent* page=nil;
BOOL storesIDsInCookies=NO;
NSString* contextID=nil;
storesIDsInCookies=[aSession storesIDsInCookies]; //For What ?
contextID=[elements objectForKey:GSWKey_ContextID[GSWebNamingConv]];//use aContext requestContextID instead ?
if (contextID) // ??
{
NSAssert([contextID length]>0,@"contextID empty");
page=[self lockedRestorePageForContextID:contextID
inSession:aSession];
if (!page)
{
GSWApplication* application=[aSession application];
errorResponse=[application handlePageRestorationErrorInContext:aContext];
};
}
else
{
NSString* pageName=[elements objectForKey:GSWKey_PageName[GSWebNamingConv]];
NSException* exception=nil;
NS_DURING
{
page=[[GSWApplication application] pageWithName:pageName
inContext:aContext];
}
NS_HANDLER
{
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,
@"In pageWithName");
LOGException(@"exception=%@",localException);
ASSIGN(exception,localException);
}
NS_ENDHANDLER;
if (!page)
{
errorResponse=[[GSWApplication application] handleException:exception
inContext:aContext];
};
DESTROY(exception);
};
if (!response && !errorResponse && page)
{
[aContext _setPageElement:page];
response=[self lockedDispatchWithPreparedPage:page
inSession:aSession
inContext:aContext
elements:elements];
};
if (response)
{
BOOL isPageRefreshOnBacktrackEnabled=[[GSWApplication application] isPageRefreshOnBacktrackEnabled];
if (isPageRefreshOnBacktrackEnabled)
[response disableClientCaching];
[aSession _saveCurrentPage];
#if 0
if (!contextID) // ??
{
if (![aSession storesIDsInCookies])//??
[aSession clearCookieFromResponse:response];
};
#endif
};
return response ? response : errorResponse;
};
//--------------------------------------------------------------------
-(GSWResponse*)lockedDispatchWithPreparedPage:(GSWComponent*)aComponent
inSession:(GSWSession*)aSession
inContext:(GSWContext*)aContext
elements:(NSDictionary*)elements
{
//OK
GSWRequest* request=nil;
GSWResponse* response=nil;
GSWResponse* errorResponse=nil;
NSString* senderID=nil;
NSString* contextID=nil;
NSString* httpVersion=nil;
GSWComponent* page=nil;
GSWComponent* responsePage=nil;
BOOL isFromClientComponent=NO;
BOOL hasFormValues=NO;
GSWContext* responseContext=nil;
GSWComponent* responsePageElement=nil;
GSWRequest* responseRequest=nil;
NSString* matchingContextID=nil;
request=[aContext request];
contextID=[elements objectForKey:GSWKey_ContextID[GSWebNamingConv]];
response=[GSWApp createResponseInContext:aContext];
senderID=GSWContext_senderID(aContext);
matchingContextID=[aSession _contextIDMatchingIDsInContext:aContext];
httpVersion=[request httpVersion];
[response setHTTPVersion:httpVersion];
[response setAcceptedEncodings:[request browserAcceptedEncodings]];
[response setHeader:@"text/html"
forKey:@"content-type"];
[aContext _setResponse:response];
if (matchingContextID)
{
page = [self lockedRestorePageForContextID:matchingContextID
inSession:aSession];
[aContext _setPageElement:page];
[GSWApp appendToResponse:response
inContext:aContext];
}
else
{
page=[aContext page];
if (contextID)//??
{
hasFormValues=[request _hasFormValues];
}
else
{
[aContext _setPageChanged:NO];
isFromClientComponent=[request isFromClientComponent];
//??
[aContext _setPageReplaced:NO];
isFromClientComponent=[request isFromClientComponent];
};
if (hasFormValues)
{
NSAssert([GSWContext_elementID(aContext) length]==0,
@"1 lockedDispatchWithPreparedPage elementID length>0");
[GSWApp takeValuesFromRequest:request
inContext:aContext];
if (![GSWContext_elementID(aContext) length]==0)
{
LOGSeriousError0(@"2 lockedDispatchWithPreparedPage elementID length>0");
GSWContext_deleteAllElementIDComponents(aContext);//NDFN
};
[aContext _setPageChanged:NO];//???
isFromClientComponent=[request isFromClientComponent];
[aContext _setPageReplaced:NO];
};
if (senderID) //??
{
BOOL pageChanged=NO;
NSException* exception=nil;
NSAssert([GSWContext_elementID(aContext) length]==0,
@"3 lockedDispatchWithPreparedPage elementID length>0");
// Exception catching here ?
NS_DURING
{
responsePage=(GSWComponent*)[GSWApp invokeActionForRequest:request
inContext:aContext];
NSAssert([GSWContext_elementID(aContext) length]==0,@"4 lockedDispatchWithPreparedPage elementID length>0");
}
NS_HANDLER
{
LOGException0(@"exception in invokeActionForRequest");
LOGException(@"exception=%@",localException);
localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
@"In invokeActionForRequest component=%@ of Class %@",
[aComponent name],
[aComponent class]);
LOGException(@"exception=%@",localException);
ASSIGN(exception,localException);
if (!responsePage)
{
errorResponse=[[GSWApplication application] handleException:exception
inContext:aContext];
};
DESTROY(exception);
}
NS_ENDHANDLER;
if (errorResponse)
{
response=errorResponse;
responseContext=aContext;
}
else
{
if (!responsePage)
responsePage=page;
responseContext=[(GSWComponent*)responsePage context];//So what ?
[responseContext _setPageReplaced:NO];
responsePageElement=(GSWComponent*)[responseContext _pageElement];
pageChanged=(responsePage!=responsePageElement);
[responseContext _setPageChanged:pageChanged];//??
if (pageChanged)
{
[responseContext _setPageElement:responsePage];
};
responseRequest=[responseContext request];//SoWhat ?
[responseRequest isFromClientComponent];//SoWhat
};
}
else
{
responseContext=aContext;
responsePageElement=page;
responsePage=aComponent;
responseRequest=request;
};
if (!errorResponse)
{
NS_DURING
{
NSAssert([GSWContext_elementID(aContext) length]==0,
@"5 lockedDispatchWithPreparedPage elementID length>0");
[GSWApp appendToResponse:response
inContext:responseContext];
NSAssert([GSWContext_elementID(aContext) length]==0,
@"6 lockedDispatchWithPreparedPage elementID length>0");
responseRequest=[responseContext request];//SoWhat ?
}
NS_HANDLER
{
localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
@"In appendToResponse page=%@ of Class %@",
[page name],
[page class]);
LOGException(@"exception=%@",localException);
errorResponse=[[GSWApplication application] handleException:localException
inContext:aContext];
}
NS_ENDHANDLER;
};
};
return errorResponse ? errorResponse : response;
};
//--------------------------------------------------------------------
-(GSWComponent*)lockedRestorePageForContextID:(NSString*)aContextID
inSession:(GSWSession*)aSession
{
//OK
GSWComponent* page=[aSession restorePageForContextID:aContextID];
return page;
};
@end
//====================================================================
@implementation GSWComponentRequestHandler (GSWRequestHandlerClassA)
//--------------------------------------------------------------------
// do we need this? -- dw
+(id)handler
{
return [[GSWComponentRequestHandler new] autorelease];
};
//--------------------------------------------------------------------
+(NSDictionary*)_requestHandlerValuesForRequest:(GSWRequest*)aRequest
{
//OK
NSDictionary* values=nil;
NS_DURING
{
values=[aRequest uriOrFormOrCookiesElements];
}
NS_HANDLER
{
localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException,@"In +_requestHandlerValuesForRequest:");
LOGException(@"exception=%@",localException);
[localException raise];
};
NS_ENDHANDLER;
return values;
};
@end

View file

@ -141,8 +141,8 @@ GSWEB_EXPORT NSString* GSWHTTPHeader_RecordingSessionID[2];
GSWEB_EXPORT NSString* GSWHTTPHeader_RecordingIDsURL[2];
GSWEB_EXPORT NSString* GSWHTTPHeader_RecordingIDsCookie[2];
GSWEB_EXPORT NSString* GSWHTTPHeader_RecordingApplicationNumber[2];
GSWEB_EXPORT NSString* GSWHTTPHeader_LoadAverage[2];
GSWEB_EXPORT NSString* GSWHTTPHeader_RefuseSessions[2];
GSWEB_EXPORT NSString* GSWHTTPHeader_LoadAverage;
GSWEB_EXPORT NSString* GSWHTTPHeader_RefuseSessions;
// Header key to return statistics to Adaptor
GSWEB_EXPORT NSString* GSWHTTPHeader_AdaptorStats[2];

View file

@ -140,8 +140,8 @@ NSString* GSWHTTPHeader_RecordingSessionID[2]={ @"x-gsweb-session-id", @"x-webob
NSString* GSWHTTPHeader_RecordingIDsURL[2]={ @"x-gsweb-ids-url", @"x-webobjects-ids-url" };
NSString* GSWHTTPHeader_RecordingIDsCookie[2]={ @"x-gsweb-ids-url", @"x-webobjects-ids-cookie" };
NSString* GSWHTTPHeader_RecordingApplicationNumber[2]={ @"x-gsweb-application-number", @"x-webobjects-application-number" };
NSString* GSWHTTPHeader_LoadAverage[2] = { @"x-gsweb-loadaverage", @"x-webobjects-loadaverage" };
NSString* GSWHTTPHeader_RefuseSessions[2] = { @"x-gsweb-refusenewsessions", @"x-webobjects-refusenewsessions" };
NSString* GSWHTTPHeader_LoadAverage = @"x-webobjects-loadaverage";
NSString* GSWHTTPHeader_RefuseSessions = @"x-webobjects-refusenewsessions";
NSString* GSWHTTPHeader_AdaptorStats[2] = { @"x-gsweb-adaptorstats", @"x-webobjects-adaptorstats" };
NSString* GSWHTTPHeader_MethodPost=@"POST";

View file

@ -77,5 +77,11 @@ static inline void GSWeb_appendStringWithImpPtr(NSMutableString* object,IMP* imp
inContext:(GSWContext*)context;
@end
@interface GSWResponse (PrivateDeclarations)
- (void) _redirectResponse:(NSString *) location contentString:(NSString *) content;
@end
#endif // _GSWPrivate_h__

View file

@ -32,7 +32,7 @@
#ifndef _GSWRequestHandler_h__
#define _GSWRequestHandler_h__
#define DidHandleRequestNotification "WORequestHandlerDidHandleRequestNotification"
#define DidHandleRequestNotification @"WORequestHandlerDidHandleRequestNotification"
//====================================================================

View file

@ -34,6 +34,7 @@ RCS_ID("$Id$")
#include "GSWeb.h"
#include "NSData+Compress.h"
#include "GSWPrivate.h"
//====================================================================
@implementation GSWResponse
@ -228,7 +229,20 @@ void GSWResponse_appendTagAttributeValueEscapingHTMLAttributeValue(GSWResponse*
(void*)_userInfo];
LOGObjectFnStop();
return description;
};
}
// it seems that in WO, this is a class method, which makes no sense
- (void) _redirectResponse:(NSString *) location contentString:(NSString *) content
{
GSWResponse_appendContentString(self, content);
[self setStatus:302];
[self setHeader:location
forKey:@"Location"];
[self setHeader:@"YES"
forKey:@"x-webobjects-refusing-redirection"];
}
@end
//====================================================================
@ -332,15 +346,15 @@ void GSWResponse_appendTagAttributeValueEscapingHTMLAttributeValue(GSWResponse*
[self _finalizeCookiesInContext:aContext];
// Add load info to headers
if (![self headersForKey:GSWHTTPHeader_LoadAverage[GSWebNamingConv]])
if (![self headersForKey:GSWHTTPHeader_LoadAverage])
[self setHeader:GSWIntToNSString([GSWApp activeSessionsCount])
forKey:GSWHTTPHeader_LoadAverage[GSWebNamingConv]];
forKey:GSWHTTPHeader_LoadAverage];
// Add refusing new sessions info to headers
if ([GSWApp isRefusingNewSessions]
&& ![self headersForKey:GSWHTTPHeader_RefuseSessions[GSWebNamingConv]])
&& ![self headersForKey:GSWHTTPHeader_RefuseSessions])
[self setHeader:GSWIntToNSString((int)[GSWApp _refuseNewSessionsTimeInterval])
forKey:GSWHTTPHeader_RefuseSessions[GSWebNamingConv]];
forKey:GSWHTTPHeader_RefuseSessions];
[self _finalizeContentEncodingInContext:aContext];
@ -673,7 +687,7 @@ escapingHTMLAttributeValue:(BOOL)escape
forRequest:nil];
LOGClassFnStop();
return response;
};
}
@end