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>
* Examples/WebBookStore1: New example.

View file

@ -1,7 +1,7 @@
/* 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
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_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);
iReturn=dieSendResponse(p_pRequestRec,&pResponse,p_fDecline);
GSWLog(GSW_DEBUG,pServerRec,"Stop dieWithMessage");

View file

@ -1,7 +1,7 @@
/* 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
This file is part of the GNUstep Web Library.
@ -35,6 +35,7 @@ typedef struct _GSWApp
BOOL fSwitchToKnownInstance;
char *pszAdaptorTemplatesPath;
int iLastInstanceIndex;//Last Instance Index
time_t unavailableUntil; // Application is unavailable unti this date. Config format is YYYYMMDD-HHMMSS
} GSWApp;
typedef struct _GSWAppInstance

View file

@ -1,7 +1,7 @@
/* 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
This file is part of the GNUstep Web Library.
@ -88,81 +88,96 @@ GSWAppRequest_SendAppRequestToApp(GSWHTTPRequest **p_ppHTTPRequest,
if (!fAppFound)
{
GSWLog(GSW_WARNING,p_pLogServerData,"App not found");
GSWLog(GSW_WARNING,p_pLogServerData,
"App '%s' not found",
p_pAppRequest->pszName);
//TODO
// 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;
GSWLog(GSW_INFO,p_pLogServerData,"Attempt# %d: Trying to contact %s:%d on %s(%d)",
(int)(APP_CONNECT_RETRIES_NB-iAttemptsRemaining),
p_pAppRequest->pszName,
p_pAppRequest->iInstance,
p_pAppRequest->pszHost,
p_pAppRequest->iPort);
hConnect = GSWApp_Open(p_pAppRequest,p_pLogServerData);
if (hConnect)
pHTTPResponse=GSWHTTPResponse_BuildServiceUnavailableResponse(p_pAppRequest,
p_pAppRequest->pAppInstance->pApp->unavailableUntil,
p_pLogServerData);
}
else
{
while (!pHTTPResponse && fAppFound && iAttemptsRemaining-->0)
{
if (p_pAppRequest->eType==EAppType_LoadBalanced)
GSWLoadBalancing_StartAppRequest(p_pAppRequest,
p_pLogServerData);
GSWLog(GSW_INFO,p_pLogServerData,"%s:%d on %s(%d) connected",
fAppNotResponding=FALSE;
GSWLog(GSW_INFO,p_pLogServerData,"Attempt# %d: Trying to contact %s:%d on %s(%d)",
(int)(APP_CONNECT_RETRIES_NB-iAttemptsRemaining),
p_pAppRequest->pszName,
p_pAppRequest->iInstance,
p_pAppRequest->pszHost,
p_pAppRequest->iPort);
GSWHTTPRequest_HTTPToAppRequest(*p_ppHTTPRequest,
p_pAppRequest,
p_pURLComponents,
p_pszHTTPVersion,
p_pLogServerData);
if (GSWHTTPRequest_SendRequest(*p_ppHTTPRequest,
hConnect,
p_pLogServerData) != 0)
hConnect = GSWApp_Open(p_pAppRequest,p_pLogServerData);
if (hConnect)
{
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->iInstance,
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)
GSWHTTPRequest_HTTPToAppRequest(*p_ppHTTPRequest,
p_pAppRequest,
p_pURLComponents,
p_pszHTTPVersion,
p_pLogServerData);
if (GSWHTTPRequest_SendRequest(*p_ppHTTPRequest,
hConnect,
p_pLogServerData) != 0)
{
char *value =
GSWDict_ValueForKey(pHTTPResponse->pHeaders,
"x-gsweb-refusing-redirection");
if (value && (strncmp(value,"YES",3)==0))
GSWLog(GSW_ERROR,p_pLogServerData,"Failed to send request to application %s:%d on %s(%d)",
p_pAppRequest->pszName,
p_pAppRequest->iInstance,
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
GSWLog(GSW_INFO,p_pLogServerData,
@ -171,74 +186,82 @@ GSWAppRequest_SendAppRequestToApp(GSWHTTPRequest **p_ppHTTPRequest,
GSWAppInfo_Set(appName, appInstance, TRUE);
}
GSWLog(GSW_INFO,p_pLogServerData,
"received: %d %s",
pHTTPResponse->uStatus,
pHTTPResponse->pszStatusMessage);
GSWLog(GSW_INFO,p_pLogServerData,
"received: %d %s",
pHTTPResponse->uStatus,
pHTTPResponse->pszStatusMessage);
};
if (appName)
{
free(appName);
appName = NULL;
}
};
if (appName)
{
free(appName);
appName = NULL;
}
};
}
else
{
fAppNotResponding=TRUE;
GSWLog(GSW_WARNING,p_pLogServerData,
"%s:%d NOT LISTENING on %s:%d",
p_pAppRequest->pszName,
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)
{
}
else
{
fAppNotResponding=TRUE;
GSWLog(GSW_WARNING,p_pLogServerData,
"%s:%d NOT LISTENING on %s:%d",
p_pAppRequest->pszName,
p_pAppRequest->iInstance,
p_pAppRequest->pszHost,
p_pAppRequest->iPort);
//TODO
/*
if (p_pAppRequest->eType == EAppType_Auto)
GSWLoadBalancing_MarkNotRespondingApp(p_pAppRequest,
p_pLogServerData);
if (iAttemptsRemaining-->0)
fAppFound=GSWLoadBalancing_FindApp(p_pAppRequest,
p_pLogServerData,
p_pURLComponents);
};
p_pLogServerData);
else*/ if (p_pAppRequest->eType==EAppType_LoadBalanced)
{
GSWLoadBalancing_MarkNotRespondingApp(p_pAppRequest,
p_pLogServerData);
if (iAttemptsRemaining-->0)
fAppFound=GSWLoadBalancing_FindApp(p_pAppRequest,
p_pLogServerData,
p_pURLComponents);
};
};
};
};
if (fAppNotResponding)
{
GSWApp *pApp=(p_pAppRequest ?
(p_pAppRequest->pAppInstance ?
p_pAppRequest->pAppInstance->pApp : NULL) : NULL);
char *pszString=GSWTemplate_ErrorNoResponseMessage(TRUE,pApp);
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
pszString,
p_pLogServerData);
free(pszString);
};
if (!pHTTPResponse)
{
GSWLog(GSW_WARNING,p_pLogServerData,
"Application %s not found or not responding",
p_pAppRequest->pszName);
pHTTPResponse = GSWDumpConfigFile(p_pURLComponents,p_pLogServerData);
if (fAppNotResponding)
{
GSWApp *pApp=(p_pAppRequest ?
(p_pAppRequest->pAppInstance ?
p_pAppRequest->pAppInstance->pApp : NULL) : NULL);
char *pszString=GSWTemplate_ErrorNoResponseIncludedMessage(TRUE,pApp);
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
200, // Status
NULL, // Headers
&GSWTemplate_ErrorNoResponse, // Template
pszString, // Message
p_pLogServerData);
free(pszString);
};
if (!pHTTPResponse)
{
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
"No App Found",
p_pLogServerData);
pHTTPResponse->uStatus = 404;
if (pHTTPResponse->pszStatusMessage)
{
free(pHTTPResponse->pszStatusMessage);
pHTTPResponse->pszStatusMessage=NULL;
};
pHTTPResponse->pszStatusMessage = strdup("File Not found");
}
{
GSWLog(GSW_WARNING,p_pLogServerData,
"Application %s not found or not responding",
p_pAppRequest->pszName);
pHTTPResponse = GSWDumpConfigFile(p_pURLComponents,p_pLogServerData);
if (!pHTTPResponse)
{
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(p_pAppRequest,
200, // Status
NULL, // Headers
&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);
*p_ppHTTPRequest=NULL;
@ -270,8 +293,11 @@ GSWAppRequest_HandleRequest(GSWHTTPRequest **p_ppHTTPRequest,
|| !p_pURLComponents->stAppName.pszStart)
{
pHTTPResponse=GSWHTTPResponse_BuildErrorResponse(NULL,
"No Application Name",
p_pLogServerData);
200, // Status
NULL, // Headers
&GSWTemplate_ErrorResponse, // Template
"No Application Name", // Message
p_pLogServerData);
}
else
{

View file

@ -462,6 +462,7 @@ GSWConfig_PropListApplicationToApplication(GSWApp *p_pApp,
proplist_t pValueCanDump=NULL;
proplist_t pValueSwitchToKnownInstance=NULL;
proplist_t pValueAdaptorTemplatesPath=NULL;
proplist_t pValueUnavailableUntil=NULL;
if (p_pApp->pszName)
{
@ -486,6 +487,105 @@ GSWConfig_PropListApplicationToApplication(GSWApp *p_pApp,
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
pValueSwitchToKnownInstance=GSWPropList_GetDictionaryEntry(p_propListApp,
"switchToKnownInstance",

View file

@ -1,7 +1,7 @@
/* 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
This file is part of the GNUstep Web Library.
@ -269,6 +269,28 @@ GSWDict_AllKeys(GSWDict *p_pDict)
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,
void *p_pLogServerData)
{

View file

@ -1,7 +1,7 @@
/* 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
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,
CONST char *p_pszKey,
CONST char *p_pValue);
void GSWDict_AddStringDupFromDict(GSWDict *p_pDictDst,GSWDict *p_pDictSrc);
void GSWDict_RemoveKey(GSWDict *p_pDict,
CONST char *p_pszKey);
CONST void* GSWDict_ValueForKey(GSWDict *p_pDict,

View file

@ -1,7 +1,7 @@
/* GSWHTTPResponse.c - GSWeb: Adaptors: HTTP Response
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
This file is part of the GNUstep Web Library.
@ -99,6 +99,9 @@ GSWHTTPResponse_New(CONST char *p_pszStatus,
//--------------------------------------------------------------------
GSWHTTPResponse *
GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
unsigned int p_uStatus,
GSWDict *p_pHeaders,
GSWTemplate_FN pTemplateFN,
CONST char *p_pszMessage,
void *p_pLogServerData)
{
@ -111,20 +114,30 @@ GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
GSWLog(GSW_DEBUG,p_pLogServerData,
"Start GSWHTTPResponse_BuildErrorResponse");
if (p_pAppRequest && p_pAppRequest->pAppInstance)
pApp=p_pAppRequest->pAppInstance->pApp;
#ifdef DEBUG
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
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->pHeaders = GSWDict_New(2);
GSWDict_Add(pHTTPResponse->pHeaders,
g_szHeader_ContentType,
g_szContentType_TextHtml,
FALSE);
if (p_pHeaders)
GSWDict_AddStringDupFromDict(pHTTPResponse->pHeaders,p_pHeaders);
GSWString_Append(pBufferMessage,p_pszMessage);
if (p_pAppRequest)
{
GSWString_SearchReplace(pBufferMessage,"##APP_NAME##",
@ -136,12 +149,20 @@ GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
sprintf(szBuffer,"%d",p_pAppRequest->iPort);
GSWString_SearchReplace(pBufferMessage,"##APP_PORT##",szBuffer);
};
GSWTemplate_ReplaceStd(pBufferMessage,pApp);
pszString=GSWTemplate_ErrorResponseText(TRUE,pApp);
GSWString_Append(pBuffer,pszString);
free(pszString);
GSWString_SearchReplace(pBuffer,"##TEXT##",pBufferMessage->pszData);
if (pTemplateFN)
{
pszString=(*pTemplateFN)(TRUE,pApp);
GSWString_Append(pBuffer,pszString);
free(pszString);
pszString=NULL;
GSWString_SearchReplace(pBuffer,"##TEXT##",pBufferMessage->pszData);
}
else
GSWString_Append(pBuffer,pBufferMessage->pszData);
GSWTemplate_ReplaceStd(pBuffer,pApp);
pHTTPResponse->uContentLength = GSWString_Len(pBuffer);
@ -156,6 +177,7 @@ GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
GSWDict_AddStringDup(pHTTPResponse->pHeaders,
g_szHeader_ContentLength,szBuffer);
GSWLog(GSW_DEBUG,p_pLogServerData,"Stop GSWHTTPResponse_BuildErrorResponse");
return pHTTPResponse;
};
@ -178,6 +200,73 @@ GSWHTTPResponse_BuildRedirectedResponse(CONST char *p_pszRedirectPath,
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
GSWHTTPResponse_Free(GSWHTTPResponse *p_pHTTPResponse,
@ -256,7 +345,11 @@ GSWHTTPResponse_GetResponse(AppConnectHandle p_socket,
#endif
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);
else
{
@ -295,7 +388,11 @@ GSWHTTPResponse_GetResponse(AppConnectHandle p_socket,
GSWHTTPResponse_Free(pHTTPResponse,p_pLogServerData);
pHTTPResponse=NULL;
pHTTPResponse = GSWHTTPResponse_BuildErrorResponse(NULL,
"Invalid Response",p_pLogServerData);
200, // Status
NULL, // Headers
&GSWTemplate_ErrorResponse, // Template
"Invalid Response", // Message
p_pLogServerData);
}
else

View file

@ -1,7 +1,7 @@
/* 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
This file is part of the GNUstep Web Library.
@ -28,6 +28,8 @@
extern "C" {
#endif // __cplusplus
#include "GSWTemplates.h"
typedef struct _GSWHTTPResponse
{
unsigned int uStatus;
@ -48,6 +50,9 @@ GSWHTTPResponse *GSWHTTPResponse_GetResponse(AppConnectHandle p_socket,
// Build an error response
GSWHTTPResponse *GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest,
unsigned int p_uStatus,
GSWDict *p_pHeaders,
GSWTemplate_FN pTemplateFN,
CONST char *p_pszMessage,
void *p_pLogServerData);
@ -55,6 +60,11 @@ GSWHTTPResponse *GSWHTTPResponse_BuildErrorResponse(GSWAppRequest *p_pAppRequest
GSWHTTPResponse *GSWHTTPResponse_BuildRedirectedResponse(CONST char *p_pszRedirectPath,
void *p_pLogServerData);
// Service Unavailabel Response
GSWHTTPResponse *GSWHTTPResponse_BuildServiceUnavailableResponse(GSWAppRequest *p_pAppRequest,
time_t unavailableUntil,
void *p_pLogServerData);
// Add Header
void GSWHTTPResponse_AddHeader(GSWHTTPResponse *p_pHTTPResponse,
char *p_pszHeader);

View file

@ -1,7 +1,7 @@
/* 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
This file is part of the GNUstep Web Library.
@ -34,7 +34,7 @@
#include "GSWTemplates.h"
//--------------------------------------------------------------------
const char *g_szErrorResponseTextTemplate[2]={
const char *g_szErrorResponseTemplate[2]={
"##TEXT##",
"<HTML><BODY BGCOLOR=\"#FFFFFF\">\n"
"<CENTER><H1>##TEXT##</H1></CENTER>\n"
@ -43,7 +43,16 @@ const char *g_szErrorResponseTextTemplate[2]={
"</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"};
@ -131,6 +140,17 @@ char *g_szDump_AppInstanceTemplate[2]={
"<TD>##PORT##</TD>\n"
"</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 *
GSWTemplate_GetTemplate(BOOL p_fHTML,
@ -138,10 +158,13 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
CONST char *p_pszTemplateName)
{
char *pszTemplate=NULL;
if (pApp && pApp->pszAdaptorTemplatesPath && p_pszTemplateName)
GSWConfig *gswConfig=GSWConfig_GetConfig();
if (p_pszTemplateName
&& ((pApp && pApp->pszAdaptorTemplatesPath)
|| gswConfig->pszAdaptorTemplatesPath))
{
FILE *fd=NULL;
GSWConfig *gswConfig=GSWConfig_GetConfig();
int applen = 0;
int globallen = 0;
int maxlen = 0;
@ -163,6 +186,7 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
else
sprintf(pathName,"%s/%s.txt",pApp->pszAdaptorTemplatesPath,
p_pszTemplateName);
fd=fopen(pathName,"r");
if (!fd)
{
@ -172,8 +196,10 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
else
sprintf(pathName,"%s/%s.txt",
gswConfig->pszAdaptorTemplatesPath,p_pszTemplateName);
fd=fopen(pathName,"r");
}
};
if (fd)
{
char buff[4096]="";
@ -191,31 +217,44 @@ GSWTemplate_GetTemplate(BOOL p_fHTML,
pathName=NULL;
};
};
return pszTemplate;
};
//--------------------------------------------------------------------
char *
GSWTemplate_ErrorResponseText(BOOL p_fHTML,
GSWApp *pApp)
GSWTemplate_ErrorResponse(BOOL p_fHTML,
GSWApp *pApp)
{
char *pszString=NULL;
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorResponseText");
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorResponse");
if (!pszString)
pszString=strdup(g_szErrorResponseTextTemplate[p_fHTML ? 1 : 0]);
pszString=strdup(g_szErrorResponseTemplate[p_fHTML ? 1 : 0]);
return pszString;
};
//--------------------------------------------------------------------
char *
GSWTemplate_ErrorNoResponseMessage(BOOL p_fHTML,
GSWApp *pApp)
GSWTemplate_ErrorNoResponse(BOOL p_fHTML,
GSWApp *pApp)
{
char *pszString=NULL;
pszString=GSWTemplate_GetTemplate(p_fHTML,pApp,"ErrorNoResponse");
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;
};
@ -243,6 +282,18 @@ GSWTemplate_StatusDeniedResponse(BOOL p_fHTML,
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 *
GSWTemplate_GetDumpHead(BOOL p_fHTML)

View file

@ -1,7 +1,7 @@
/* 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
This file is part of the GNUstep Web Library.
@ -25,12 +25,17 @@
#define _GSWTemplates_h__
#include "GSWApp.h"
#include "GSWString.h"
typedef char* (*GSWTemplate_FN)(BOOL p_fHTML, GSWApp *pApp);
//You need to free returned char
char *GSWTemplate_ErrorResponseText(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_ErrorNoResponseMessage(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_ErrorResponse(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_StatusDeniedResponse(BOOL p_fHTML, GSWApp *pApp);
char *GSWTemplate_ServiceUnavailableResponse(BOOL p_fHTML,GSWApp *pApp);
char *GSWTemplate_GetDumpHead(BOOL p_fHTML);
char *GSWTemplate_GetDumpFoot(BOOL p_fHTML);
char *GSWTemplate_GetDumpApp(BOOL p_fHTML);