forked from Imagelibrary/rtems
<valette@crf.canon.fr> to add a port of the GoAhead web server (httpd) to the RTEMS build tree. They have successfully used this BSP on i386/pc386 and PowerPC/mcp750. Mark and Joel spoke with Nick Berliner <nickb@goahead.com> on 26 Oct 1999 about this port and got verbal approval to include it in RTEMS distributions.
204 lines
4.4 KiB
C
204 lines
4.4 KiB
C
/*
|
|
* url.c -- Parse URLs
|
|
*
|
|
* 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 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 a 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 tag and the query
|
|
*/
|
|
if ((cp = gstrchr(tok, '#')) != NULL) {
|
|
*cp++ = '\0';
|
|
path = tok;
|
|
tok = cp;
|
|
}
|
|
if ((cp = gstrchr(tok, '?')) != NULL) {
|
|
*cp++ = '\0';
|
|
query = cp;
|
|
}
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
|
|
/******************************************************************************/
|