summaryrefslogtreecommitdiffstats
path: root/cpukit/httpd/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/httpd/url.c')
-rw-r--r--cpukit/httpd/url.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/cpukit/httpd/url.c b/cpukit/httpd/url.c
new file mode 100644
index 0000000000..75746fd490
--- /dev/null
+++ b/cpukit/httpd/url.c
@@ -0,0 +1,203 @@
+/*
+ * 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;
+}
+
+/******************************************************************************/