Changes in GSWAdaptor:

o to handle unavailableUntil configuration parameters
o to better handle templates


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@20317 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Manuel Guesdon 2004-11-08 14:15:59 +00:00
parent 24f81b918b
commit ba53f7538a
11 changed files with 507 additions and 167 deletions

View file

@ -1,3 +1,24 @@
2004-11-08 Manuel Guesdon <mguesdon@orange-concept.com>
* GSWAdaptors/Apache/mod_gsweb.c: change in
GSWHTTPResponse_BuildErrorResponse call for templates
* GSWAdaptors/common/GSWApp.h: added unavailableUntil
* GSWAdaptors/common/GSWAppRequest.c:
o changes in GSWHTTPResponse_BuildErrorResponse
call for templates
o handle unavailableUntil
* GSWAdaptors/common/GSWConfig.c:
o handle unavailableUntil configuration directive
* GSWAdaptors/common/GSWDict.[ch]:
o added GSWDict_AddStringDupFromDict
* GSWAdaptors/common/GSWHTTPResponse.[hc]:
o renamed some templates
o changes to handle templates function pointers
o added GSWHTTPResponse_BuildServiceUnavailableResponse
* GSWAdaptors/common/GSWTemplates.[ch]:
o renamed some templates
o changes to handle templates function pointers
o added UnavailableResponseTemplate
2004-11-08 David Ayers <d.ayers@inode.at> 2004-11-08 David Ayers <d.ayers@inode.at>
* Examples/WebBookStore1: New example. * Examples/WebBookStore1: New example.

View file

@ -1,7 +1,7 @@
/* mod_gsweb.c - GSWeb: Apache Module /* mod_gsweb.c - GSWeb: Apache Module
Copyright (C) 1999 Free Software Foundation, Inc. Copyright (C) 1999-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: July 1999 Date: July 1999
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -578,7 +578,11 @@ dieWithMessage(request_rec *p_pRequestRec,
GSWLog(GSW_DEBUG,pServerRec,"Start dieWithMessage"); GSWLog(GSW_DEBUG,pServerRec,"Start dieWithMessage");
GSWLog(GSW_ERROR,pServerRec,"Send Error Response: %s",p_pszMessage); GSWLog(GSW_ERROR,pServerRec,"Send Error Response: %s",p_pszMessage);
pResponse = GSWHTTPResponse_BuildErrorResponse(NULL,p_pszMessage, pResponse = GSWHTTPResponse_BuildErrorResponse(NULL,
200, // Status
NULL, // Headers
&GSWTemplate_ErrorResponse, // Template
p_pszMessage, // Message
p_pRequestRec->server); p_pRequestRec->server);
iReturn=dieSendResponse(p_pRequestRec,&pResponse,p_fDecline); iReturn=dieSendResponse(p_pRequestRec,&pResponse,p_fDecline);
GSWLog(GSW_DEBUG,pServerRec,"Stop dieWithMessage"); GSWLog(GSW_DEBUG,pServerRec,"Stop dieWithMessage");

View file

@ -1,7 +1,7 @@
/* GSWApp.h - GSWeb: Adaptors: GSWApp & GSWAppInstance /* GSWApp.h - GSWeb: Adaptors: GSWApp & GSWAppInstance
Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. Copyright (C) 2000, 2001, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: March 2000 Date: March 2000
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -35,6 +35,7 @@ typedef struct _GSWApp
BOOL fSwitchToKnownInstance; BOOL fSwitchToKnownInstance;
char *pszAdaptorTemplatesPath; char *pszAdaptorTemplatesPath;
int iLastInstanceIndex;//Last Instance Index int iLastInstanceIndex;//Last Instance Index
time_t unavailableUntil; // Application is unavailable unti this date. Config format is YYYYMMDD-HHMMSS
} GSWApp; } GSWApp;
typedef struct _GSWAppInstance typedef struct _GSWAppInstance

View file

@ -1,7 +1,7 @@
/* GSWAppRequest.c - GSWeb: Adaptors: App Request /* GSWAppRequest.c - GSWeb: Adaptors: App Request
Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: July 1999 Date: July 1999
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -88,81 +88,96 @@ GSWAppRequest_SendAppRequestToApp(GSWHTTPRequest **p_ppHTTPRequest,
if (!fAppFound) if (!fAppFound)
{ {
GSWLog(GSW_WARNING,p_pLogServerData,"App not found"); GSWLog(GSW_WARNING,p_pLogServerData,
"App '%s' not found",
p_pAppRequest->pszName);
//TODO //TODO
// Call AppStart daemon // Call AppStart daemon
}; };
while (!pHTTPResponse && fAppFound && iAttemptsRemaining-->0) // Check if application is unavailable
if (fAppFound
&& p_pAppRequest->pAppInstance
&& p_pAppRequest->pAppInstance->pApp
&& p_pAppRequest->pAppInstance->pApp->unavailableUntil>0
&& p_pAppRequest->pAppInstance->pApp->unavailableUntil>time(NULL))
{ {
fAppNotResponding=FALSE; pHTTPResponse=GSWHTTPResponse_BuildServiceUnavailableResponse(p_pAppRequest,
GSWLog(GSW_INFO,p_pLogServerData,"Attempt# %d: Trying to contact %s:%d on %s(%d)", p_pAppRequest->pAppInstance->pApp->unavailableUntil,
(int)(APP_CONNECT_RETRIES_NB-iAttemptsRemaining), p_pLogServerData);
p_pAppRequest->pszName, }
p_pAppRequest->iInstance, else
p_pAppRequest->pszHost, {
p_pAppRequest->iPort); while (!pHTTPResponse && fAppFound && iAttemptsRemaining-->0)
hConnect = GSWApp_Open(p_pAppRequest,p_pLogServerData);
if (hConnect)
{ {
if (p_pAppRequest->eType==EAppType_LoadBalanced) fAppNotResponding=FALSE;
GSWLoadBalancing_StartAppRequest(p_pAppRequest, GSWLog(GSW_INFO,p_pLogServerData,"Attempt# %d: Trying to contact %s:%d on %s(%d)",
p_pLogServerData); (int)(APP_CONNECT_RETRIES_NB-iAttemptsRemaining),
GSWLog(GSW_INFO,p_pLogServerData,"%s:%d on %s(%d) connected",
p_pAppRequest->pszName, p_pAppRequest->pszName,
p_pAppRequest->iInstance, p_pAppRequest->iInstance,
p_pAppRequest->pszHost, p_pAppRequest->pszHost,
p_pAppRequest->iPort); p_pAppRequest->iPort);
GSWHTTPRequest_HTTPToAppRequest(*p_ppHTTPRequest, hConnect = GSWApp_Open(p_pAppRequest,p_pLogServerData);
p_pAppRequest, if (hConnect)
p_pURLComponents,
p_pszHTTPVersion,
p_pLogServerData);
if (GSWHTTPRequest_SendRequest(*p_ppHTTPRequest,
hConnect,
p_pLogServerData) != 0)
{ {
GSWLog(GSW_ERROR,p_pLogServerData,"Failed to send request to application %s:%d on %s(%d)", if (p_pAppRequest->eType==EAppType_LoadBalanced)
GSWLoadBalancing_StartAppRequest(p_pAppRequest,
p_pLogServerData);
GSWLog(GSW_INFO,p_pLogServerData,"%s:%d on %s(%d) connected",
p_pAppRequest->pszName, p_pAppRequest->pszName,
p_pAppRequest->iInstance, p_pAppRequest->iInstance,
p_pAppRequest->pszHost, p_pAppRequest->pszHost,
p_pAppRequest->iPort); p_pAppRequest->iPort);
GSWApp_Close(hConnect,p_pLogServerData); GSWHTTPRequest_HTTPToAppRequest(*p_ppHTTPRequest,
hConnect=NULL; p_pAppRequest,
fAppNotResponding=TRUE; p_pURLComponents,
} p_pszHTTPVersion,
else p_pLogServerData);
{ if (GSWHTTPRequest_SendRequest(*p_ppHTTPRequest,
GSWLog(GSW_INFO,p_pLogServerData, hConnect,
"Request %s sent, awaiting response", p_pLogServerData) != 0)
(*p_ppHTTPRequest)->pszRequest);
appName = strdup(p_pAppRequest->pszName);
appInstance = p_pAppRequest->iInstance;
p_pAppRequest->pRequest = NULL;
pHTTPResponse = GSWHTTPResponse_GetResponse(hConnect,
p_pLogServerData);
p_pAppRequest->pResponse = pHTTPResponse;
if (p_pAppRequest->eType == EAppType_LoadBalanced)
GSWLoadBalancing_StopAppRequest(p_pAppRequest,
p_pLogServerData);
GSWApp_Close(hConnect,p_pLogServerData);
hConnect=NULL;
glbResponsesNb++;
if (pHTTPResponse)
{ {
char *value = GSWLog(GSW_ERROR,p_pLogServerData,"Failed to send request to application %s:%d on %s(%d)",
GSWDict_ValueForKey(pHTTPResponse->pHeaders, p_pAppRequest->pszName,
"x-gsweb-refusing-redirection"); p_pAppRequest->iInstance,
if (value && (strncmp(value,"YES",3)==0)) p_pAppRequest->pszHost,
p_pAppRequest->iPort);
GSWApp_Close(hConnect,p_pLogServerData);
hConnect=NULL;
fAppNotResponding=TRUE;
}
else
{
GSWLog(GSW_INFO,p_pLogServerData,
"Request %s sent, awaiting response",
(*p_ppHTTPRequest)->pszRequest);
appName = strdup(p_pAppRequest->pszName);
appInstance = p_pAppRequest->iInstance;
p_pAppRequest->pRequest = NULL;
pHTTPResponse = GSWHTTPResponse_GetResponse(hConnect,
p_pLogServerData);
p_pAppRequest->pResponse = pHTTPResponse;
if (p_pAppRequest->eType == EAppType_LoadBalanced)
GSWLoadBalancing_StopAppRequest(p_pAppRequest,
p_pLogServerData);
GSWApp_Close(hConnect,p_pLogServerData);
hConnect=NULL;
glbResponsesNb++;
if (pHTTPResponse)
{
char *value =
GSWDict_ValueForKey(pHTTPResponse->pHeaders,
"x-gsweb-refusing-redirection");
if (value && (strncmp(value,"YES",3)==0))
{ {
// refuseNewSessions == YES in app // refuseNewSessions == YES in app
GSWLog(GSW_INFO,p_pLogServerData, GSWLog(GSW_INFO,p_pLogServerData,
@ -171,74 +186,82 @@ GSWAppRequest_SendAppRequestToApp(GSWHTTPRequest **p_ppHTTPRequest,
GSWAppInfo_Set(appName, appInstance, TRUE); GSWAppInfo_Set(appName, appInstance, TRUE);
} }
GSWLog(GSW_INFO,p_pLogServerData, GSWLog(GSW_INFO,p_pLogServerData,
"received: %d %s", "received: %d %s",
pHTTPResponse->uStatus, pHTTPResponse->uStatus,
pHTTPResponse->pszStatusMessage); pHTTPResponse->pszStatusMessage);
};
if (appName)
{
free(appName);
appName = NULL;
}
}; };
if (appName) }
{ else
free(appName); {
appName = NULL; fAppNotResponding=TRUE;
} GSWLog(GSW_WARNING,p_pLogServerData,
}; "%s:%d NOT LISTENING on %s:%d",
} p_pAppRequest->pszName,
else p_pAppRequest->iInstance,
{ p_pAppRequest->pszHost,
fAppNotResponding=TRUE; p_pAppRequest->iPort);
GSWLog(GSW_WARNING,p_pLogServerData, //TODO
"%s:%d NOT LISTENING on %s:%d", /*
p_pAppRequest->pszName, if (p_pAppRequest->eType == EAppType_Auto)
p_pAppRequest->iInstance,
p_pAppRequest->pszHost,
p_pAppRequest->iPort);
//TODO
/*
if (p_pAppRequest->eType == EAppType_Auto)
GSWLoadBalancing_MarkNotRespondingApp(p_pAppRequest,
p_pLogServerData);
else*/ if (p_pAppRequest->eType==EAppType_LoadBalanced)
{
GSWLoadBalancing_MarkNotRespondingApp(p_pAppRequest, GSWLoadBalancing_MarkNotRespondingApp(p_pAppRequest,
p_pLogServerData); p_pLogServerData);
if (iAttemptsRemaining-->0)
fAppFound=GSWLoadBalancing_FindApp(p_pAppRequest, else*/ if (p_pAppRequest->eType==EAppType_LoadBalanced)
p_pLogServerData, {
p_pURLComponents); GSWLoadBalancing_MarkNotRespondingApp(p_pAppRequest,
}; p_pLogServerData);
if (iAttemptsRemaining-->0)
fAppFound=GSWLoadBalancing_FindApp(p_pAppRequest,
p_pLogServerData,
p_pURLComponents);
};
};
}; };
}; if (fAppNotResponding)
if (fAppNotResponding) {
{ GSWApp *pApp=(p_pAppRequest ?
GSWApp *pApp=(p_pAppRequest ? (p_pAppRequest->pAppInstance ?
(p_pAppRequest->pAppInstance ? p_pAppRequest->pAppInstance->pApp : NULL) : NULL);
p_pAppRequest->pAppInstance->pApp : NULL) : NULL); char *pszString=GSWTemplate_ErrorNoResponseIncludedMessage(TRUE,pApp);
char *pszString=GSWTemplate_ErrorNoResponseMessage(TRUE,pApp); pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest, 200, // Status
pszString, NULL, // Headers
p_pLogServerData); &GSWTemplate_ErrorNoResponse, // Template
free(pszString); pszString, // Message
}; p_pLogServerData);
if (!pHTTPResponse) free(pszString);
{ };
GSWLog(GSW_WARNING,p_pLogServerData,
"Application %s not found or not responding",
p_pAppRequest->pszName);
pHTTPResponse = GSWDumpConfigFile(p_pURLComponents,p_pLogServerData);
if (!pHTTPResponse) if (!pHTTPResponse)
{ {
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest, GSWLog(GSW_WARNING,p_pLogServerData,
"No App Found", "Application %s not found or not responding",
p_pLogServerData); p_pAppRequest->pszName);
pHTTPResponse->uStatus = 404; pHTTPResponse = GSWDumpConfigFile(p_pURLComponents,p_pLogServerData);
if (pHTTPResponse->pszStatusMessage) if (!pHTTPResponse)
{ {
free(pHTTPResponse->pszStatusMessage); pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
pHTTPResponse->pszStatusMessage=NULL; 200, // Status
}; NULL, // Headers
pHTTPResponse->pszStatusMessage = strdup("File Not found"); &GSWTemplate_ErrorResponse, // Template
} "No App Found", // Message
p_pLogServerData);
pHTTPResponse->uStatus = 404;
if (pHTTPResponse->pszStatusMessage)
{
free(pHTTPResponse->pszStatusMessage);
pHTTPResponse->pszStatusMessage=NULL;
};
pHTTPResponse->pszStatusMessage = strdup("File Not found");
}
};
}; };
GSWHTTPRequest_Free(*p_ppHTTPRequest,p_pLogServerData); GSWHTTPRequest_Free(*p_ppHTTPRequest,p_pLogServerData);
*p_ppHTTPRequest=NULL; *p_ppHTTPRequest=NULL;
@ -270,8 +293,11 @@ GSWAppRequest_HandleRequest(GSWHTTPRequest **p_ppHTTPRequest,
|| !p_pURLComponents->stAppName.pszStart) || !p_pURLComponents->stAppName.pszStart)
{ {
pHTTPResponse=GSWHTTPResponse_BuildErrorResponse(NULL, pHTTPResponse=GSWHTTPResponse_BuildErrorResponse(NULL,
"No Application Name", 200, // Status
p_pLogServerData); NULL, // Headers
&GSWTemplate_ErrorResponse, // Template
"No Application Name", // Message
p_pLogServerData);
} }
else else
{ {

View file

@ -462,6 +462,7 @@ GSWConfig_PropListApplicationToApplication(GSWApp *p_pApp,
proplist_t pValueCanDump=NULL; proplist_t pValueCanDump=NULL;
proplist_t pValueSwitchToKnownInstance=NULL; proplist_t pValueSwitchToKnownInstance=NULL;
proplist_t pValueAdaptorTemplatesPath=NULL; proplist_t pValueAdaptorTemplatesPath=NULL;
proplist_t pValueUnavailableUntil=NULL;
if (p_pApp->pszName) if (p_pApp->pszName)
{ {
@ -486,6 +487,105 @@ GSWConfig_PropListApplicationToApplication(GSWApp *p_pApp,
p_pApp->fCanDump=(strcasecmp(pszCanDump,"YES")==0); p_pApp->fCanDump=(strcasecmp(pszCanDump,"YES")==0);
}; };
// Unavailable Date
pValueUnavailableUntil=GSWPropList_GetDictionaryEntry(p_propListApp,
"unavailableUntil",
pszParents,
FALSE,//No Error If Not Exists
GSWPropList_TestString,
p_pLogServerData);
p_pApp->unavailableUntil=0;
if (pValueUnavailableUntil)
{
CONST char *pszUnavailableUntil=PLGetString(pValueUnavailableUntil);//Do Not Free It
if (pszUnavailableUntil)
{
if (strlen(pszUnavailableUntil)<8)
{
GSWLog(GSW_WARNING,NULL,
"Bad format for unavailableUntil ('%s'). Should be YYYYMMDD or YYYYMMDD-HHMMSS",
pszUnavailableUntil);
}
else // At least YYYYMMDD
{
struct tm tmStruct;
memset(&tmStruct,0,sizeof(tmStruct));
//1900 Based
tmStruct.tm_year=((pszUnavailableUntil[0]-'0')*1000
+(pszUnavailableUntil[1]-'0')*100
+(pszUnavailableUntil[2]-'0')*10
+(pszUnavailableUntil[3]-'0'))-1900;
if (tmStruct.tm_year<0)
{
GSWLog(GSW_WARNING,p_pLogServerData,
"Bad year (%d) in unavailableUntil ('%s')",
(int)(tmStruct.tm_year+1900),
pszUnavailableUntil);
}
else
{
//0 based
tmStruct.tm_mon=((pszUnavailableUntil[4]-'0')*10
+(pszUnavailableUntil[5]-'0'))-1;
if (tmStruct.tm_mon<0 || tmStruct.tm_mon>11)
{
GSWLog(GSW_WARNING,p_pLogServerData,
"Bad month (%d) in unavailableUntil ('%s')",
(int)(tmStruct.tm_mon+1),
pszUnavailableUntil);
}
else
{
tmStruct.tm_mday=((pszUnavailableUntil[6]-'0')*10
+(pszUnavailableUntil[7]-'0'));
if (tmStruct.tm_mday<1 || tmStruct.tm_mday>31)
{
GSWLog(GSW_WARNING,p_pLogServerData,
"Bad month day (%d) in unavailableUntil ('%s')",
(int)(tmStruct.tm_mday),
pszUnavailableUntil);
}
else
{
if (strlen(pszUnavailableUntil)>=15) // YYYYMMDD-HHMMSS
{
tmStruct.tm_hour=((pszUnavailableUntil[9]-'0')*10
+(pszUnavailableUntil[10]-'0'));
if (tmStruct.tm_hour<0 || tmStruct.tm_hour>23)
{
tmStruct.tm_hour=23;
}
else
{
tmStruct.tm_min=((pszUnavailableUntil[11]-'0')*10
+(pszUnavailableUntil[12]-'0'));
if (tmStruct.tm_min<0 || tmStruct.tm_hour>59)
{
tmStruct.tm_min=59;
}
else
{
tmStruct.tm_sec=((pszUnavailableUntil[13]-'0')*10
+(pszUnavailableUntil[14]-'0'));
if (tmStruct.tm_sec<0 || tmStruct.tm_sec>59)
{
tmStruct.tm_sec=59;
};
};
};
};
p_pApp->unavailableUntil=mktime(&tmStruct);
if (p_pApp->unavailableUntil<0) // Invalid
p_pApp->unavailableUntil=0;
};
};
};
};
};
};
// SwitchToKnownInstance // SwitchToKnownInstance
pValueSwitchToKnownInstance=GSWPropList_GetDictionaryEntry(p_propListApp, pValueSwitchToKnownInstance=GSWPropList_GetDictionaryEntry(p_propListApp,
"switchToKnownInstance", "switchToKnownInstance",

View file

@ -1,7 +1,7 @@
/* GSWDict.c - GSWeb: Dictionary /* GSWDict.c - GSWeb: Dictionary
Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: July 1999 Date: July 1999
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -269,6 +269,28 @@ GSWDict_AllKeys(GSWDict *p_pDict)
return pList; return pList;
}; };
void GSWDict_AddStringDupFromDict(GSWDict *p_pDictDst,GSWDict *p_pDictSrc)
{
if (!p_pDictSrc)
{
GSWLog(GSW_CRITICAL,NULL,"NULL GSWDict src");
}
else if (!p_pDictDst)
{
GSWLog(GSW_CRITICAL,NULL,"NULL GSWDict dst");
}
else
{
int i=0;
GSWDictElem *pElem=NULL;
for (pElem=p_pDictSrc->pElems;i<p_pDictSrc->uCount;i++,pElem++)
{
if (pElem->pszKey)
GSWDict_AddStringDup(p_pDictDst,pElem->pszKey,pElem->pValue);
};
};
};
static void GSWDict_LogStringElem(GSWDictElem *p_pElem, static void GSWDict_LogStringElem(GSWDictElem *p_pElem,
void *p_pLogServerData) void *p_pLogServerData)
{ {

View file

@ -1,7 +1,7 @@
/* GSWDict.h - GSWeb: Dictionary /* GSWDict.h - GSWeb: Dictionary
Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: July 1999 Date: July 1999
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -61,6 +61,9 @@ void GSWDict_AddString(GSWDict *p_pDict,
void GSWDict_AddStringDup(GSWDict *p_pDict, void GSWDict_AddStringDup(GSWDict *p_pDict,
CONST char *p_pszKey, CONST char *p_pszKey,
CONST char *p_pValue); CONST char *p_pValue);
void GSWDict_AddStringDupFromDict(GSWDict *p_pDictDst,GSWDict *p_pDictSrc);
void GSWDict_RemoveKey(GSWDict *p_pDict, void GSWDict_RemoveKey(GSWDict *p_pDict,
CONST char *p_pszKey); CONST char *p_pszKey);
CONST void* GSWDict_ValueForKey(GSWDict *p_pDict, CONST void* GSWDict_ValueForKey(GSWDict *p_pDict,

View file

@ -1,7 +1,7 @@
/* GSWHTTPResponse.c - GSWeb: Adaptors: HTTP Response /* GSWHTTPResponse.c - GSWeb: Adaptors: HTTP Response
Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: July 1999 Date: July 1999
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -99,6 +99,9 @@ GSWHTTPResponse_New(CONST char *p_pszStatus,
//-------------------------------------------------------------------- //--------------------------------------------------------------------
GSWHTTPResponse * GSWHTTPResponse *
GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest, GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
unsigned int p_uStatus,
GSWDict *p_pHeaders,
GSWTemplate_FN pTemplateFN,
CONST char *p_pszMessage, CONST char *p_pszMessage,
void *p_pLogServerData) void *p_pLogServerData)
{ {
@ -111,20 +114,30 @@ GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
GSWLog(GSW_DEBUG,p_pLogServerData, GSWLog(GSW_DEBUG,p_pLogServerData,
"Start GSWHTTPResponse_BuildErrorResponse"); "Start GSWHTTPResponse_BuildErrorResponse");
if (p_pAppRequest && p_pAppRequest->pAppInstance)
pApp=p_pAppRequest->pAppInstance->pApp;
#ifdef DEBUG #ifdef DEBUG
GSWLog(GSW_INFO,p_pLogServerData, GSWLog(GSW_INFO,p_pLogServerData,
"Build Error Response [%s] pApp=%p",p_pszMessage,pApp); "Build Error Response [%s] p_pAppRequest=%p p_pAppRequest->pAppInstance=%p pApp=%p",
p_pszMessage,p_pAppRequest,
((p_pAppRequest) ? p_pAppRequest->pAppInstance : NULL),
((p_pAppRequest && p_pAppRequest->pAppInstance) ? p_pAppRequest->pAppInstance->pApp : NULL));
#endif #endif
pHTTPResponse->uStatus = 200;
if (p_pAppRequest && p_pAppRequest->pAppInstance)
pApp=p_pAppRequest->pAppInstance->pApp;
pHTTPResponse->uStatus = p_uStatus;
pHTTPResponse->pszStatusMessage = strdup(g_szOKGSWeb[GSWNAMES_INDEX]); pHTTPResponse->pszStatusMessage = strdup(g_szOKGSWeb[GSWNAMES_INDEX]);
pHTTPResponse->pHeaders = GSWDict_New(2); pHTTPResponse->pHeaders = GSWDict_New(2);
GSWDict_Add(pHTTPResponse->pHeaders, GSWDict_Add(pHTTPResponse->pHeaders,
g_szHeader_ContentType, g_szHeader_ContentType,
g_szContentType_TextHtml, g_szContentType_TextHtml,
FALSE); FALSE);
if (p_pHeaders)
GSWDict_AddStringDupFromDict(pHTTPResponse->pHeaders,p_pHeaders);
GSWString_Append(pBufferMessage,p_pszMessage); GSWString_Append(pBufferMessage,p_pszMessage);
if (p_pAppRequest) if (p_pAppRequest)
{ {
GSWString_SearchReplace(pBufferMessage,"##APP_NAME##", GSWString_SearchReplace(pBufferMessage,"##APP_NAME##",
@ -136,12 +149,20 @@ GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
sprintf(szBuffer,"%d",p_pAppRequest->iPort); sprintf(szBuffer,"%d",p_pAppRequest->iPort);
GSWString_SearchReplace(pBufferMessage,"##APP_PORT##",szBuffer); GSWString_SearchReplace(pBufferMessage,"##APP_PORT##",szBuffer);
}; };
GSWTemplate_ReplaceStd(pBufferMessage,pApp); GSWTemplate_ReplaceStd(pBufferMessage,pApp);
pszString=GSWTemplate_ErrorResponseText(TRUE,pApp); if (pTemplateFN)
GSWString_Append(pBuffer,pszString); {
free(pszString); pszString=(*pTemplateFN)(TRUE,pApp);
GSWString_SearchReplace(pBuffer,"##TEXT##",pBufferMessage->pszData); GSWString_Append(pBuffer,pszString);
free(pszString);
pszString=NULL;
GSWString_SearchReplace(pBuffer,"##TEXT##",pBufferMessage->pszData);
}
else
GSWString_Append(pBuffer,pBufferMessage->pszData);
GSWTemplate_ReplaceStd(pBuffer,pApp); GSWTemplate_ReplaceStd(pBuffer,pApp);
pHTTPResponse->uContentLength = GSWString_Len(pBuffer); pHTTPResponse->uContentLength = GSWString_Len(pBuffer);
@ -156,6 +177,7 @@ GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
GSWDict_AddStringDup(pHTTPResponse->pHeaders, GSWDict_AddStringDup(pHTTPResponse->pHeaders,
g_szHeader_ContentLength,szBuffer); g_szHeader_ContentLength,szBuffer);
GSWLog(GSW_DEBUG,p_pLogServerData,"Stop GSWHTTPResponse_BuildErrorResponse"); GSWLog(GSW_DEBUG,p_pLogServerData,"Stop GSWHTTPResponse_BuildErrorResponse");
return pHTTPResponse; return pHTTPResponse;
}; };
@ -178,6 +200,73 @@ GSWHTTPResponse_BuildRedirectedResponse(CONST char *p_pszRedirectPath,
return pHTTPResponse; return pHTTPResponse;
}; };
//--------------------------------------------------------------------
GSWHTTPResponse *
GSWHTTPResponse_BuildServiceUnavailableResponse(GSWAppRequest *p_pAppRequest,
time_t unavailableUntil,
void *p_pLogServerData)
{
GSWDict* pHeaders = NULL;
GSWHTTPResponse *pHTTPResponse = NULL;
char szUnavailableUntil[100] = "";
GSWString *pContent = GSWString_New();
char *pszString=NULL;
GSWApp *pApp=NULL;
GSWLog(GSW_DEBUG,p_pLogServerData,
"Start GSWHTTPResponse_BuildServiceUnavailableResponse");
if (p_pAppRequest && p_pAppRequest->pAppInstance)
pApp=p_pAppRequest->pAppInstance->pApp;
if (unavailableUntil>0)
{
char retryAfterString[25]="";
pHeaders = GSWDict_New(1);
sprintf(retryAfterString,"%d",(int)(unavailableUntil-time(NULL)));
GSWDict_AddStringDup(pHeaders,
"Retry-After",
retryAfterString);
ctime_r(&unavailableUntil,szUnavailableUntil);
}
else
strcpy(szUnavailableUntil,"unknown date");
// Get the template string
pszString=GSWTemplate_ServiceUnavailableResponse(TRUE,pApp);
// Append it to GSWString pContent
GSWString_Append(pContent,pszString);
// Free The template
free(pszString);
// Replace texts
GSWString_SearchReplace(pContent,"##UNAVAILABLE_UNTIL##",szUnavailableUntil);
pHTTPResponse=GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
503, // Status
pHeaders, // Headers
NULL, // Template
pContent->pszData,
p_pLogServerData);
if (pContent)
{
GSWString_Free(pContent);
pContent=NULL;
};
if (pHeaders)
{
GSWDict_Free(pHeaders);
pHeaders=NULL;
};
GSWLog(GSW_DEBUG,p_pLogServerData,
"Stop GSWHTTPResponse_BuildServiceUnavailableResponse");
return pHTTPResponse;
};
//-------------------------------------------------------------------- //--------------------------------------------------------------------
void void
GSWHTTPResponse_Free(GSWHTTPResponse *p_pHTTPResponse, GSWHTTPResponse_Free(GSWHTTPResponse *p_pHTTPResponse,
@ -256,7 +345,11 @@ GSWHTTPResponse_GetResponse(AppConnectHandle p_socket,
#endif #endif
if (!pHTTPResponse) //Error if (!pHTTPResponse) //Error
pHTTPResponse=GSWHTTPResponse_BuildErrorResponse(NULL,"Invalid Response", pHTTPResponse=GSWHTTPResponse_BuildErrorResponse(NULL,
200, // Status
NULL, // Headers
&GSWTemplate_ErrorResponse, // Template
"Invalid Response", // Message
p_pLogServerData); p_pLogServerData);
else else
{ {
@ -295,7 +388,11 @@ GSWHTTPResponse_GetResponse(AppConnectHandle p_socket,
GSWHTTPResponse_Free(pHTTPResponse,p_pLogServerData); GSWHTTPResponse_Free(pHTTPResponse,p_pLogServerData);
pHTTPResponse=NULL; pHTTPResponse=NULL;
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(NULL, pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(NULL,
"Invalid Response",p_pLogServerData); 200, // Status
NULL, // Headers
&GSWTemplate_ErrorResponse, // Template
"Invalid Response", // Message
p_pLogServerData);
} }
else else

View file

@ -1,7 +1,7 @@
/* GSWHTTPResponse.h - GSWeb: GSWeb Request /* GSWHTTPResponse.h - GSWeb: GSWeb Request
Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: July 1999 Date: July 1999
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -28,6 +28,8 @@
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
#include "GSWTemplates.h"
typedef struct _GSWHTTPResponse typedef struct _GSWHTTPResponse
{ {
unsigned int uStatus; unsigned int uStatus;
@ -48,6 +50,9 @@ GSWHTTPResponse *GSWHTTPResponse_GetResponse(AppConnectHandle p_socket,
// Build an error response // Build an error response
GSWHTTPResponse *GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest, GSWHTTPResponse *GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
unsigned int p_uStatus,
GSWDict *p_pHeaders,
GSWTemplate_FN pTemplateFN,
CONST char *p_pszMessage, CONST char *p_pszMessage,
void *p_pLogServerData); void *p_pLogServerData);
@ -55,6 +60,11 @@ GSWHTTPResponse *GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest
GSWHTTPResponse *GSWHTTPResponse_BuildRedirectedResponse(CONST char *p_pszRedirectPath, GSWHTTPResponse *GSWHTTPResponse_BuildRedirectedResponse(CONST char *p_pszRedirectPath,
void *p_pLogServerData); void *p_pLogServerData);
// Service Unavailabel Response
GSWHTTPResponse *GSWHTTPResponse_BuildServiceUnavailableResponse(GSWAppRequest *p_pAppRequest,
time_t unavailableUntil,
void *p_pLogServerData);
// Add Header // Add Header
void GSWHTTPResponse_AddHeader(GSWHTTPResponse *p_pHTTPResponse, void GSWHTTPResponse_AddHeader(GSWHTTPResponse *p_pHTTPResponse,
char *p_pszHeader); char *p_pszHeader);

View file

@ -1,7 +1,7 @@
/* GSWTemplates.c - GSWeb: GSWTemplates /* GSWTemplates.c - GSWeb: GSWTemplates
Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Copyright (C) 2000, 2001, 2002, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: March 2000 Date: March 2000
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -34,7 +34,7 @@
#include "GSWTemplates.h" #include "GSWTemplates.h"
//-------------------------------------------------------------------- //--------------------------------------------------------------------
const char *g_szErrorResponseTextTemplate[2]={ const char *g_szErrorResponseTemplate[2]={
"##TEXT##", "##TEXT##",
"<HTML><BODY BGCOLOR=\"#FFFFFF\">\n" "<HTML><BODY BGCOLOR=\"#FFFFFF\">\n"
"<CENTER><H1>##TEXT##</H1></CENTER>\n" "<CENTER><H1>##TEXT##</H1></CENTER>\n"
@ -43,7 +43,16 @@ const char *g_szErrorResponseTextTemplate[2]={
"</BODY></HTML>\n"}; "</BODY></HTML>\n"};
//-------------------------------------------------------------------- //--------------------------------------------------------------------
const char *g_szErrorNoResponseMessageTemplate[2]={ const char *g_szErrorNoResponseTemplate[2]={
"##TEXT##",
"<HTML><BODY BGCOLOR=\"#FFFFFF\">\n"
"<CENTER><H1>##TEXT##</H1></CENTER>\n"
"<BR>\n"
"<CENTER><A HREF=\"http://www.gnustepweb.org\"><IMG SRC=\"##GSWEXTFWKWSR##/PoweredByGNUstepWeb.png\" ALT=\"Powered By GNUstepWeb\" BORDER=0></A></CENTER>\n"
"</BODY></HTML>\n"};
//--------------------------------------------------------------------
const char *g_szErrorNoResponseIncludedMessageTemplate[2]={
"##APP_NAME##:##APP_INSTANCE## (##APP_HOST##:##APP_PORT##) doesn't respond", "##APP_NAME##:##APP_INSTANCE## (##APP_HOST##:##APP_PORT##) doesn't respond",
"##APP_NAME##:##APP_INSTANCE## (##APP_HOST##:##APP_PORT##) doesn't respond"}; "##APP_NAME##:##APP_INSTANCE## (##APP_HOST##:##APP_PORT##) doesn't respond"};
@ -131,6 +140,17 @@ char *g_szDump_AppInstanceTemplate[2]={
"<TD>##PORT##</TD>\n" "<TD>##PORT##</TD>\n"
"</TR>"}; "</TR>"};
//--------------------------------------------------------------------
char *g_szServiceUnavailableResponseTemplate[2]={
"Application ##APP_NAME## is unavailable until ##UNAVAILABLE_UNTIL##.\n",
"<HTML><HEAD><TITLE>Application ##APP_NAME## is unavailable until ##UNAVAILABLE_UNTIL##</TITLE></HEAD>\n"
"<BODY BGCOLOR=\"#FFFFFF\">\n"
"<CENTER><H1>Application ##APP_NAME##</H1><H3>is unavailable until ##UNAVAILABLE_UNTIL##</H3></CENTER>"
"<BR>\n"
"<CENTER><A HREF=\"http://www.gnustepweb.org\"><IMG SRC=\"##GSWEXTFWKWSR##/PoweredByGNUstepWeb.png\" ALT=\"Powered By GNUstepWeb\" BORDER=0></A></CENTER>\n"
"</BODY></HTML>\n"};
//-------------------------------------------------------------------- //--------------------------------------------------------------------
char * char *
GSWTemplate_GetTemplate(BOOL p_fHTML, GSWTemplate_GetTemplate(BOOL p_fHTML,
@ -138,10 +158,13 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
CONST char *p_pszTemplateName) CONST char *p_pszTemplateName)
{ {
char *pszTemplate=NULL; char *pszTemplate=NULL;
if (pApp && pApp->pszAdaptorTemplatesPath && p_pszTemplateName) GSWConfig *gswConfig=GSWConfig_GetConfig();
if (p_pszTemplateName
&& ((pApp && pApp->pszAdaptorTemplatesPath)
|| gswConfig->pszAdaptorTemplatesPath))
{ {
FILE *fd=NULL; FILE *fd=NULL;
GSWConfig *gswConfig=GSWConfig_GetConfig();
int applen = 0; int applen = 0;
int globallen = 0; int globallen = 0;
int maxlen = 0; int maxlen = 0;
@ -163,6 +186,7 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
else else
sprintf(pathName,"%s/%s.txt",pApp->pszAdaptorTemplatesPath, sprintf(pathName,"%s/%s.txt",pApp->pszAdaptorTemplatesPath,
p_pszTemplateName); p_pszTemplateName);
fd=fopen(pathName,"r"); fd=fopen(pathName,"r");
if (!fd) if (!fd)
{ {
@ -172,8 +196,10 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
else else
sprintf(pathName,"%s/%s.txt", sprintf(pathName,"%s/%s.txt",
gswConfig->pszAdaptorTemplatesPath,p_pszTemplateName); gswConfig->pszAdaptorTemplatesPath,p_pszTemplateName);
fd=fopen(pathName,"r"); fd=fopen(pathName,"r");
} };
if (fd) if (fd)
{ {
char buff[4096]=""; char buff[4096]="";
@ -191,31 +217,44 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
pathName=NULL; pathName=NULL;
}; };
}; };
return pszTemplate; return pszTemplate;
}; };
//-------------------------------------------------------------------- //--------------------------------------------------------------------
char * char *
GSWTemplate_ErrorResponseText(BOOL p_fHTML, GSWTemplate_ErrorResponse(BOOL p_fHTML,
GSWApp *pApp) GSWApp *pApp)
{ {
char *pszString=NULL; char *pszString=NULL;
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorResponseText"); pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorResponse");
if (!pszString) if (!pszString)
pszString=strdup(g_szErrorResponseTextTemplate[p_fHTML ? 1 : 0]); pszString=strdup(g_szErrorResponseTemplate[p_fHTML ? 1 : 0]);
return pszString; return pszString;
}; };
//-------------------------------------------------------------------- //--------------------------------------------------------------------
char * char *
GSWTemplate_ErrorNoResponseMessage(BOOL p_fHTML, GSWTemplate_ErrorNoResponse(BOOL p_fHTML,
GSWApp *pApp) GSWApp *pApp)
{ {
char *pszString=NULL; char *pszString=NULL;
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorNoResponse"); pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorNoResponse");
if (!pszString) if (!pszString)
pszString=strdup(g_szErrorNoResponseMessageTemplate[p_fHTML ? 1 : 0]); pszString=strdup(g_szErrorNoResponseTemplate[p_fHTML ? 1 : 0]);
return pszString;
};
//--------------------------------------------------------------------
char *
GSWTemplate_ErrorNoResponseIncludedMessage(BOOL p_fHTML,
GSWApp *pApp)
{
char *pszString=NULL;
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorNoResponseIncludedMessage");
if (!pszString)
pszString=strdup(g_szErrorNoResponseIncludedMessageTemplate[p_fHTML ? 1 : 0]);
return pszString; return pszString;
}; };
@ -243,6 +282,18 @@ GSWTemplate_StatusDeniedResponse(BOOL p_fHTML,
return pszString; return pszString;
}; };
//--------------------------------------------------------------------
char *
GSWTemplate_ServiceUnavailableResponse(BOOL p_fHTML,
GSWApp *pApp)
{
char *pszString=NULL;
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ServiceUnavailableResponse");
if (!pszString)
pszString=strdup(g_szServiceUnavailableResponseTemplate[p_fHTML ? 1 : 0]);
return pszString;
};
//-------------------------------------------------------------------- //--------------------------------------------------------------------
char * char *
GSWTemplate_GetDumpHead(BOOL p_fHTML) GSWTemplate_GetDumpHead(BOOL p_fHTML)

View file

@ -1,7 +1,7 @@
/* GSWTemplates.h - GSWeb: GSWTemplates /* GSWTemplates.h - GSWeb: GSWTemplates
Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. Copyright (C) 2000, 2001, 2003-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@sbuilders.com> Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: March 2000 Date: March 2000
This file is part of the GNUstep Web Library. This file is part of the GNUstep Web Library.
@ -25,12 +25,17 @@
#define _GSWTemplates_h__ #define _GSWTemplates_h__
#include "GSWApp.h" #include "GSWApp.h"
#include "GSWString.h"
typedef char* (*GSWTemplate_FN)(BOOL p_fHTML, GSWApp *pApp);
//You need to free returned char //You need to free returned char
char *GSWTemplate_ErrorResponseText(BOOL p_fHTML, GSWApp *pApp); char *GSWTemplate_ErrorResponse(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_ErrorNoResponseMessage(BOOL p_fHTML, GSWApp *pApp); char *GSWTemplate_ErrorNoResponse(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_ErrorNoResponseIncludedMessage(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_StatusAllowedResponse(BOOL p_fHTML, GSWApp *pApp); char *GSWTemplate_StatusAllowedResponse(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_StatusDeniedResponse(BOOL p_fHTML, GSWApp *pApp); char *GSWTemplate_StatusDeniedResponse(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_ServiceUnavailableResponse(BOOL p_fHTML,GSWApp *pApp);
char *GSWTemplate_GetDumpHead(BOOL p_fHTML); char *GSWTemplate_GetDumpHead(BOOL p_fHTML);
char *GSWTemplate_GetDumpFoot(BOOL p_fHTML); char *GSWTemplate_GetDumpFoot(BOOL p_fHTML);
char *GSWTemplate_GetDumpApp(BOOL p_fHTML); char *GSWTemplate_GetDumpApp(BOOL p_fHTML);