OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [rtems_webserver/] [handler.c] - Rev 373

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * handler.c -- URL handler support
 *
 * Copyright (c) Go Ahead Software Inc., 1995-1999. All Rights Reserved.
 *
 * See the file "license.txt" for usage and redistribution license requirements
 */
 
/******************************** Description *********************************/
 
/*
 *	This module implements a URL handler interface and API to permit
 *	the addition of user definable URL processors.
 */
 
/********************************* Includes ***********************************/
 
#include	"wsIntrn.h"
 
/*********************************** Locals ***********************************/
 
static websUrlHandlerType*	websUrlHandler;				/* URL handler list */
static int					websUrlHandlerMax;			/* Number of entries */
 
/**************************** Forward Declarations ****************************/
 
static int 	websUrlHandlerSort(const void* p1, const void* p2);
static int 	websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, 
				int sid, char_t *url, char_t *path, char_t *query);
 
/*********************************** Code *************************************/
/*
 *	Initialize the URL handler module
 */
 
int websUrlHandlerOpen()
{
	websAspOpen();
	return 0;
}
 
/******************************************************************************/
/*
 *	Close the URL handler module
 */
 
void websUrlHandlerClose()
{
	websUrlHandlerType*	sp;
 
	websAspClose();
	for (sp = websUrlHandler; sp < &websUrlHandler[websUrlHandlerMax]; sp++) {
		bfree(B_L, sp->urlPrefix);
		if (sp->webDir) {
			bfree(B_L, sp->webDir);
		}
	}
	bfree(B_L, websUrlHandler);
	websUrlHandlerMax = 0;
}
 
/******************************************************************************/
/*
 *	Define a new URL handler. urlPrefix is the URL prefix to match. webDir is 
 *	an optional root directory path for a web directory. arg is an optional
 *	arg to pass to the URL handler. flags defines the matching order. Valid
 *	flags include WEBS_HANDLER_LAST, WEBS_HANDLER_FIRST. If multiple users 
 *	specify last or first, their order is defined alphabetically by the 
 *	urlPrefix.
 */
 
int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg,
		int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg, 
		char_t *url, char_t *path, char_t *query), int flags)
{
	websUrlHandlerType	*sp;
	int					len;
 
	a_assert(urlPrefix);
	a_assert(handler);
 
/*
 *	Grow the URL handler array to create a new slot
 */
	len = (websUrlHandlerMax + 1) * sizeof(websUrlHandlerType);
	if ((websUrlHandler = brealloc(B_L, websUrlHandler, len)) == NULL) {
		return -1;
	}
	sp = &websUrlHandler[websUrlHandlerMax++];
	memset(sp, 0, sizeof(websUrlHandlerType));
 
	sp->urlPrefix = bstrdup(B_L, urlPrefix);
	sp->len = gstrlen(sp->urlPrefix);
	if (webDir) {
		sp->webDir = bstrdup(B_L, webDir);
	} else {
		sp->webDir = bstrdup(B_L, T(""));
	}
	sp->handler = handler;
	sp->arg = arg;
	sp->flags = flags;
 
/*
 *	Sort in decreasing URL length order observing the flags for first and last
 */
	qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType), 
		websUrlHandlerSort);
	return 0;
}
 
/******************************************************************************/
/*
 *	Delete an existing URL handler. We don't reclaim the space of the old 
 *	handler, just NULL the entry. Return -1 if handler is not found.
 */
 
int websUrlHandlerDelete(int (*handler)(webs_t wp, char_t *urlPrefix, 
	char_t *webDir, int arg, char_t *url, char_t *path, char_t *query))
{
	websUrlHandlerType	*sp;
	int					i;
 
	for (i = 0; i < websUrlHandlerMax; i++) {
		sp = &websUrlHandler[i];
		if (sp->handler == handler) {
			sp->handler = NULL;
			return 0;
		}
	}
	return -1;
}
 
/******************************************************************************/
/*
 *	Sort in decreasing URL length order observing the flags for first and last
 */
 
static int websUrlHandlerSort(const void* p1, const void* p2)
{
	websUrlHandlerType	*s1, *s2;
	int					rc;
 
	a_assert(p1);
	a_assert(p2);
 
	s1 = (websUrlHandlerType*) p1;
	s2 = (websUrlHandlerType*) p2;
 
	if ((s1->flags & WEBS_HANDLER_FIRST) || (s2->flags & WEBS_HANDLER_LAST)) {
		return -1;
	}
 
	if ((s2->flags & WEBS_HANDLER_FIRST) || (s1->flags & WEBS_HANDLER_LAST)) {
		return 1;
	}
 
	if ((rc = gstrcmp(s1->urlPrefix, s2->urlPrefix)) == 0) {
		if (s1->len < s2->len) {
			return 1;
		} else if (s1->len > s2->len) {
			return -1;
		}
	}
	return -rc; 
}
 
/******************************************************************************/
/*
 *	Publish a new web directory (Use the default URL handler)
 */
 
int websPublish(char_t *urlPrefix, char_t *path)
{
	return websUrlHandlerDefine(urlPrefix, path, 0, websPublishHandler, 0);
}
 
/******************************************************************************/
/*
 *	Return the directory for a given prefix. Ignore empty prefixes
 */
 
char_t *websGetPublishDir(char_t *path, char_t **urlPrefix)
{
	websUrlHandlerType	*sp;
	int					i;
 
	for (i = 0; i < websUrlHandlerMax; i++) {
		sp = &websUrlHandler[i];
		if (sp->urlPrefix[0] == '\0') {
			continue;
		}
		if (sp->handler && gstrncmp(sp->urlPrefix, path, sp->len) == 0) {
			if (urlPrefix) {
				*urlPrefix = sp->urlPrefix;
			}
			return sp->webDir;
		}
	}
	return NULL;
}
 
/******************************************************************************/
/*
 *	Publish URL handler. We just patch the web page Directory and let the
 *	default handler do the rest.
 */
 
static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, 
	int sid, char_t *url, char_t *path, char_t *query)
{
	int		len;
 
	a_assert(websValid(wp));
	a_assert(path);
 
/*
 *	Trim the urlPrefix off the path and set the webdirectory. Add one to step 
 *	over the trailing '/'
 */
	len = gstrlen(urlPrefix) + 1;
	websSetRequestPath(wp, webDir, &path[len]);
	return 0;
}
 
/******************************************************************************/
/*
 *	See if any valid handlers are defined for this request. If so, call them
 *	and continue calling valid handlers until one accepts the request. 
 *	Return true if a handler was invoked, else return FALSE.
 */
 
int websUrlHandlerRequest(webs_t wp)
{
	websUrlHandlerType	*sp;
	int					i, first;
 
	a_assert(websValid(wp));
 
/*
 *	Delete the socket handler as we don't want to start reading any
 *	data on the connection as it may be for the next pipelined HTTP/1.1
 *	request if using Keep Alive
 */
	socketDeleteHandler(wp->sid);
	wp->state = WEBS_PROCESSING;
	websStats.handlerHits++;
 
	websSetRequestPath(wp, websGetDefaultDir(), NULL);
 
/*
 *	We loop over each handler in order till one accepts the request. 
 *	The security handler will handle the request if access is NOT allowed.
 */
	first = 1;
	for (i = 0; i < websUrlHandlerMax; i++) {
		sp = &websUrlHandler[i];
		if (sp->handler && gstrncmp(sp->urlPrefix, wp->path, sp->len) == 0) {
			if (first) {
				websSetEnv(wp);
				first = 0;
			}
			if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg, 
					wp->url, wp->path, wp->query)) {
				return 1;
			}
			if (!websValid(wp)) {
				goahead_trace(0, 
				T("webs: handler %s called websDone, but didn't return 1\n"),
					sp->urlPrefix);
				return 1;
			}
		}
	}
/*
 *	If no handler processed the request, then return an error. Note: It was 
 *	the handlers responsibility to call websDone
 */
	if (i >= websUrlHandlerMax) {
		websError(wp, 200, T("No handler for this URL %s"), wp->url);
	}
	return 0;
}
 
/******************************************************************************/
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.