Files
rtems/cpukit/httpd/url.c
Joel Sherrill ee3afa2e2a 2002-04-10 Mike Siers <mikes@poliac.com>
* rtems_webserver/NOTES, rtems_webserver/asp.c,
	rtems_webserver/balloc.c, rtems_webserver/default.c,
	rtems_webserver/ej.h, rtems_webserver/ejIntrn.h,
	rtems_webserver/ejlex.c, rtems_webserver/ejparse.c,
	rtems_webserver/emfdb.c, rtems_webserver/emfdb.h,
	rtems_webserver/form.c, rtems_webserver/h.c,
	rtems_webserver/handler.c, rtems_webserver/license.txt,
	rtems_webserver/md5.h, rtems_webserver/md5c.c,
	rtems_webserver/mime.c, rtems_webserver/misc.c,
	rtems_webserver/ringq.c, rtems_webserver/rom.c,
	rtems_webserver/security.c, rtems_webserver/sock.c,
	rtems_webserver/sym.c, rtems_webserver/uemf.c,
	rtems_webserver/uemf.h, rtems_webserver/um.c, rtems_webserver/um.h,
	rtems_webserver/url.c, rtems_webserver/value.c,
	rtems_webserver/wbase64.c, rtems_webserver/webcomp.c,
	rtems_webserver/webpage.c, rtems_webserver/webrom.c,
	rtems_webserver/webs.c, rtems_webserver/webs.h,
	rtems_webserver/websuemf.c, rtems_webserver/wsIntrn.h:
	Update to GoAhead Webserver 2.1.4. The following URL is
	the release notes from GoAhead.

	    http://data.goahead.com/Software/Webserver/2.1.4/release.htm

	I have only done a minimal amount of testing (i.e. the network
	demo program works fine).  Please try this out and let me know
	if it works.  The patch needs to be applied on the
	c/src/libnetworking/rtems_webserver directory.
2003-04-11 14:46:55 +00:00

213 lines
4.5 KiB
C

/*
* url.c -- Parse URLs
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id$
*/
/******************************** Description *********************************/
/*
* This module parses URLs into their components.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/********************************* Statics ************************************/
/*
* htmExt is declared in this way to avoid a Linux and Solaris segmentation
* fault when a constant string is passed to strlower which could change its
* argument.
*/
char_t htmExt[] = T(".htm");
/*********************************** Code *************************************/
/*
* Return the mime type for the given URL given a URL.
* The caller supplies the buffer to hold the result.
* charCnt is the number of characters the buffer will hold, ascii or UNICODE.
*/
char_t *websUrlType(char_t *url, char_t *buf, int charCnt)
{
sym_t *sp;
char_t *ext, *parsebuf;
a_assert(url && *url);
a_assert(buf && charCnt > 0);
if (url == NULL || *url == '\0') {
gstrcpy(buf, T("text/plain"));
return buf;
}
if (websUrlParse(url, &parsebuf, NULL, NULL, NULL, NULL, NULL,
NULL, &ext) < 0) {
gstrcpy(buf, T("text/plain"));
return buf;
}
strlower(ext);
/*
* Lookup the mime type symbol table to find the relevant content type
*/
if ((sp = symLookup(websMime, ext)) != NULL) {
gstrncpy(buf, sp->content.value.string, charCnt);
} else {
gstrcpy(buf, T("text/plain"));
}
bfree(B_L, parsebuf);
return buf;
}
/******************************************************************************/
/*
* Parse the URL. A buffer is allocated to store the parsed URL in *pbuf.
* This must be freed by the caller. NOTE: tag is not yet fully supported.
*/
int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath,
char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag,
char_t **pext)
{
char_t *tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext;
char_t *last_delim, *hostbuf, *portbuf, *buf;
int c, len, ulen;
a_assert(url);
a_assert(pbuf);
ulen = gstrlen(url);
/*
* We allocate enough to store separate hostname and port number fields.
* As there are 3 strings in the one buffer, we need room for 3 null chars.
* We allocate MAX_PORT_LEN char_t's for the port number.
*/
len = ulen * 2 + MAX_PORT_LEN + 3;
if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) {
return -1;
}
portbuf = &buf[len - MAX_PORT_LEN - 1];
hostbuf = &buf[ulen+1];
gstrcpy(buf, url);
url = buf;
/*
* Convert the current listen port to a string. We use this if the URL has
* no explicit port setting
*/
stritoa(websGetPort(), portbuf, MAX_PORT_LEN);
port = portbuf;
path = T("/");
proto = T("http");
host = T("localhost");
query = T("");
ext = htmExt;
tag = T("");
if (gstrncmp(url, T("http://"), 7) == 0) {
tok = &url[7];
tok[-3] = '\0';
proto = url;
host = tok;
for (cp = tok; *cp; cp++) {
if (*cp == '/') {
break;
}
if (*cp == ':') {
*cp++ = '\0';
port = cp;
tok = cp;
}
}
if ((cp = gstrchr(tok, '/')) != NULL) {
/*
* If a full URL is supplied, we need to copy the host and port
* portions into static buffers.
*/
c = *cp;
*cp = '\0';
gstrncpy(hostbuf, host, ulen);
gstrncpy(portbuf, port, MAX_PORT_LEN);
*cp = c;
host = hostbuf;
port = portbuf;
path = cp;
tok = cp;
}
} else {
path = url;
tok = url;
}
/*
* Parse the query string
*/
if ((cp = gstrchr(tok, '?')) != NULL) {
*cp++ = '\0';
query = cp;
path = tok;
tok = query;
}
/*
* Parse the fragment identifier
*/
if ((cp = gstrchr(tok, '#')) != NULL) {
*cp++ = '\0';
if (*query == 0) {
path = tok;
}
}
/*
* Only do the following if asked for the extension
*/
if (pext) {
if ((cp = gstrrchr(path, '.')) != NULL) {
if ((last_delim = gstrrchr(path, '/')) != NULL) {
if (last_delim > cp) {
ext = htmExt;
} else {
ext = cp;
}
} else {
ext = cp;
}
} else {
if (path[gstrlen(path) - 1] == '/') {
ext = htmExt;
}
}
}
/*
* Pass back the fields requested (if not NULL)
*/
if (phost)
*phost = host;
if (ppath)
*ppath = path;
if (pport)
*pport = port;
if (pproto)
*pproto = proto;
if (pquery)
*pquery = query;
if (ptag)
*ptag = tag;
if (pext)
*pext = ext;
*pbuf = buf;
return 0;
}
/******************************************************************************/