示例#1
0
文件: default.c 项目: epicsdeb/rtems
int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
						char_t *url, char_t *path, char_t *query)
{
	websStatType	sbuf;
	char_t			*lpath, *tmp, *date;
	int				bytes, flags, nchars;

	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path);
	a_assert(query);

/*
 *	Validate the URL and ensure that ".."s don't give access to unwanted files
 */
	flags = websGetRequestFlags(wp);

	if (websValidateUrl(wp, path) < 0) {
		websError(wp, 500, T("Invalid URL %s"), url);
		return 1;
	}
	lpath = websGetRequestLpath(wp);
	nchars = gstrlen(lpath) - 1;
	if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
		lpath[nchars] = '\0';
	}

/*
 *	If the file is a directory, redirect using the nominated default page
 */
	if (websPageIsDirectory(lpath)) {
		nchars = gstrlen(path);
		if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
			path[--nchars] = '\0';
		}
		nchars += gstrlen(websDefaultPage) + 2;
		fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
		websRedirect(wp, tmp);
		bfreeSafe(B_L, tmp);
		return 1;
	}

/*
 *	Open the document. Stat for later use.
 */
	if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY,
		0666) < 0) {
		websError(wp, 400, T("Cannot open URL <b>%s</b>"), url);
		return 1;
	}

	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
		websError(wp, 400, T("Cannot stat page for URL <b>%s</b>"), url);
		return 1;
	}

/*
 *	If the page has not been modified since the user last received it and it
 *	is not dynamically generated each time (ASP), then optimize request by
 *	sending a 304 Use local copy response
 */
	websStats.localHits++;
#ifdef WEBS_IF_MODIFIED_SUPPORT
	if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
		if (sbuf.mtime <= wp->since) {
			websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));

/*
 *			by license terms the following line of code must
 *			not be modified.
 */
			websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);

			if (flags & WEBS_KEEP_ALIVE) {
				websWrite(wp, T("Connection: keep-alive\r\n"));
			}
			websWrite(wp, T("\r\n"));
			websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
			websDone(wp, 304);
			return 1;
		}
	}
#endif

/*
 *	Output the normal HTTP response header
 */
	if ((date = websGetDateString(NULL)) != NULL) {
		websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);

/*
 *		By license terms the following line of code must not be modified.
 */
		websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
		bfree(B_L, date);
	}
	flags |= WEBS_HEADER_DONE;

/*
 *	If this is an ASP request, ensure the remote browser doesn't cache it.
 *	Send back both HTTP/1.0 and HTTP/1.1 cache control directives
 */
	if (flags & WEBS_ASP) {
		bytes = 0;
		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));

	} else {
		if ((date = websGetDateString(&sbuf)) != NULL) {
			websWrite(wp, T("Last-modified: %s\r\n"), date);
			bfree(B_L, date);
		}
		bytes = sbuf.size;
	}

	if (bytes) {
		websWrite(wp, T("Content-length: %d\r\n"), bytes);
		websSetRequestBytes(wp, bytes);
	}
	websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));

	if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {
		websWrite(wp, T("Connection: keep-alive\r\n"));
	}
	websWrite(wp, T("\r\n"));

/*
 *	All done if the browser did a HEAD request
 */
	if (flags & WEBS_HEAD_REQUEST) {
		websDone(wp, 200);
		return 1;
	}

/*
 *	Evaluate ASP requests
 */
	if (flags & WEBS_ASP) {
		if (websAspRequest(wp, lpath) < 0) {
			return 1;
		}
		websDone(wp, 200);
		return 1;
	}

#ifdef WEBS_SSL_SUPPORT
	if (wp->flags & WEBS_SECURE) {
		websDefaultWriteEvent(wp);
	} else {
		websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
	}
#else
/*
 *	For normal web documents, return the data via background write
 */
	websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
#endif
	return 1;
}
示例#2
0
文件: default.c 项目: morrisxd/PMC
int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
						char_t *url, char_t *path, char_t *query)
{
	websStatType	sbuf;
	char_t			*lpath, *tmp, *date;
	int				bytes, flags, nchars, rc;

	a_assert(websValid(wp));
	a_assert(url && *url);
	a_assert(path);
	a_assert(query);

	flags = websGetRequestFlags(wp);
/*
 *	We do whitelist validation in addition to standard URL validation.
 *	The whitelist should really catch anything invalid first.
 *	If the whitelist check fails, rebuild the list and try again.
 *	Also validate if we are not on a secure connection, but the whitelist
 *	entry has the SSL flag set, do not serve the page.
 */
#ifdef WEBS_WHITELIST_SUPPORT
printf ("wp->url: (%s)\n", wp->url);
	if ((rc = websWhitelistCheck(wp->url)) < 0) {
		websBuildWhitelist();
		if ((rc = websWhitelistCheck(wp->url)) < 0) {
			websError(wp, 404, T("Cannot open URL: type 1"));
			return 1;
		}
	}
	if (!(flags & WEBS_SECURE) && (rc & WHITELIST_SSL)) {
		websError(wp, 500, T("HTTPS access required"));
		return 1;
	}
#endif /* WEBS_WHITELIST_SUPPORT */
/*
 *	Validate the URL and ensure that ".."s don't give access to unwanted files
 */
	if (websValidateUrl(wp, path) < 0) {
      /* 
       * preventing a cross-site scripting exploit -- you may restore the
       * following line of code to revert to the original behavior...
		websError(wp, 500, T("Invalid URL %s"), url);
       */
		websError(wp, 500, T("Invalid URL"));
		websBuildWhitelist();
		return 1;
	}
	lpath = websGetRequestLpath(wp);
	nchars = gstrlen(lpath) - 1;
	if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
		lpath[nchars] = '\0';
	}

/*
 *	If the file is a directory, redirect using the nominated default page
 */
	if (websPageIsDirectory(lpath)) {
		nchars = gstrlen(path);
		if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
			path[--nchars] = '\0';
		}
		nchars += gstrlen(websDefaultPage) + 2;
		fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
printf ("websDefaultHandler: tmp(%s)\n", tmp);
		websRedirect(wp, tmp);
		bfreeSafe(B_L, tmp);
		return 1;
	}

printf ("we now open the web pages\n");
printf ("lpath(%s), path(%s)\n", lpath, path);

/*
 *	Open the document. Stat for later use.
 */
	if (websPageOpen(wp, lpath, path, O_RDONLY | O_BINARY, 
		0666) < 0) 
   {
      /* 10 Dec 02 BgP -- according to 
       * <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>, 
       * the proper code to return here is NOT 400 (old code), which is used
       * to indicate a malformed request. Here, the request is good, but the
       * error we need to tell the client about is 404 (Not Found).
       */
      /* 
       * 17 Mar 03 BgP -- prevent a cross-site scripting exploit
		websError(wp, 404, T("Cannot open URL %s"), url);
       */
      
		websError(wp, 404, T("Cannot open URL, type 2"));
		websBuildWhitelist();
		return 1;
	} 

printf ("lpath(%s), path(%s)\n", lpath, path);
	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
      /*
       * 17 Mar 03 BgP
       * prevent a cross-site scripting exploit
		websError(wp, 400, T("Cannot stat page for URL %s"), url);
       */
		websError(wp, 400, T("Cannot stat page for URL"));
		websBuildWhitelist();
		return 1;
	}

/*
 *	If the page has not been modified since the user last received it and it
 *	is not dynamically generated each time (ASP), then optimize request by
 *	sending a 304 Use local copy response
 */
	websStats.localHits++;
#ifdef WEBS_IF_MODIFIED_SUPPORT
	if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
		if (sbuf.mtime <= wp->since) {
			websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));

/*
 *			by license terms the following line of code must
 *			not be modified.
 */
			websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);

			if (flags & WEBS_KEEP_ALIVE) {
				websWrite(wp, T("Connection: keep-alive\r\n"));
			}
			websWrite(wp, T("\r\n"));
			websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
			websDone(wp, 304);
			return 1;
		}
	}
#endif

/*
 *	Output the normal HTTP response header
 */
	if ((date = websGetDateString(NULL)) != NULL) {
		websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);
/*
 *		The Server HTTP header below must not be modified unless
 *		explicitly allowed by licensing terms.
 */
#ifdef WEBS_SSL_SUPPORT
		websWrite(wp, T("Server: %s/%s %s/%s\r\n"), 
			WEBS_NAME, WEBS_VERSION, SSL_NAME, SSL_VERSION);
#else
		websWrite(wp, T("Server: %s/%s\r\n"), WEBS_NAME, WEBS_VERSION);
#endif
		bfree(B_L, date);
	}
	flags |= WEBS_HEADER_DONE;

/*
 *	If this is an ASP request, ensure the remote browser doesn't cache it.
 *	Send back both HTTP/1.0 and HTTP/1.1 cache control directives
 */
	if (flags & WEBS_ASP) {
		bytes = 0;
		websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));

	} else {
		if ((date = websGetDateString(&sbuf)) != NULL) {
			websWrite(wp, T("Last-modified: %s\r\n"), date);
			bfree(B_L, date);
		}
		bytes = sbuf.size;
	}

	if (bytes) {
		websWrite(wp, T("Content-length: %d\r\n"), bytes);
		websSetRequestBytes(wp, bytes);
	}
	websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));

	if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {
		websWrite(wp, T("Connection: keep-alive\r\n"));
	}
	websWrite(wp, T("\r\n"));

/*
 *	All done if the browser did a HEAD request
 */
	if (flags & WEBS_HEAD_REQUEST) {
		websDone(wp, 200);
		return 1;
	}

/*
 *	Evaluate ASP requests
 */
	if (flags & WEBS_ASP) {
		if (websAspRequest(wp, lpath) < 0) {
			return 1;
		}
		websDone(wp, 200);
		return 1;
	}
/*
 *	Return the data via background write
 */
	websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
	return 1;
}
示例#3
0
int websAspRequest(webs_t wp, char_t *lpath)
{
	websStatType	sbuf;
	char			*rbuf;
	char_t			*token, *lang, *result, *path, *ep, *cp, *buf, *nextp;
	char_t			*last;
	int				rc, engine, len, ejid;

	a_assert(websValid(wp));
	a_assert(lpath && *lpath);

	rc = -1;
	buf = NULL;
	rbuf = NULL;
	engine = EMF_SCRIPT_EJSCRIPT;
	wp->flags |= WEBS_HEADER_DONE;
	path = websGetRequestPath(wp);

/*
 *	Create Ejscript instance in case it is needed
 */
	ejid = ejOpenEngine(wp->cgiVars, websAspFunctions);
	if (ejid < 0) {
		websError(wp, 200, T("Can't create Ejscript engine"));
		goto done;
	}
	ejSetUserHandle(ejid, (int) wp);

	if (websPageStat(wp, lpath, path, &sbuf) < 0) {
		websError(wp, 200, T("Can't stat %s"), lpath);
		goto done;
	}

/*
 *	Create a buffer to hold the ASP file in-memory
 */
	len = sbuf.size * sizeof(char);
	if ((rbuf = balloc(B_L, len + 1)) == NULL) {
		websError(wp, 200, T("Can't get memory"));
		goto done;
	}
	rbuf[len] = '\0';

	if (websPageReadData(wp, rbuf, len) != len) {
		websError(wp, 200, T("Cant read %s"), lpath);
		goto done;
	}
	websPageClose(wp);

/*
 *	Convert to UNICODE if necessary.
 */
	if ((buf = ballocAscToUni(rbuf, len)) == NULL) {
		websError(wp, 200, T("Can't get memory"));
		goto done;
	}

/*
 *	Scan for the next "<%"
 */
	last = buf;
	rc = 0;
	while (rc == 0 && *last && ((nextp = gstrstr(last, T("<%"))) != NULL)) {
		websWriteBlock(wp, last, (nextp - last));
		nextp = skipWhite(nextp + 2);

/*
 *		Decode the language
 */
		token = T("language");

		if ((lang = strtokcmp(nextp, token)) != NULL) {
			if ((cp = strtokcmp(lang, T("=javascript"))) != NULL) {
				engine = EMF_SCRIPT_EJSCRIPT;
			} else {
				cp = nextp;
			}
			nextp = cp;
		}

/*
 *		Find tailing bracket and then evaluate the script
 */
		if ((ep = gstrstr(nextp, T("%>"))) != NULL) {

			*ep = '\0';
			last = ep + 2;
			nextp = skipWhite(nextp);
/*
 *			Handle backquoted newlines
 */
			for (cp = nextp; *cp; ) {
				if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) {
					*cp++ = ' ';
					while (*cp == '\r' || *cp == '\n') {
						*cp++ = ' ';
					}
				} else {
					cp++;
				}
			}

/*
 *			Now call the relevant script engine. Output is done directly
 *			by the ASP script procedure by calling websWrite()
 */
			if (*nextp) {
				result = NULL;
				if (engine == EMF_SCRIPT_EJSCRIPT) {
					rc = scriptEval(engine, nextp, &result, ejid);
				} else {
					rc = scriptEval(engine, nextp, &result, (int) wp);
				}
				if (rc < 0) {
/*
 *					On an error, discard all output accumulated so far
 *					and store the error in the result buffer. Be careful if the
 *					user has called websError() already.
 */
					if (websValid(wp)) {
						if (result) {
							websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"), 
								result);
							websWrite(wp, T("<pre>%s</pre>"), nextp);
							bfree(B_L, result);
						} else {
							websWrite(wp, T("<h2><b>ASP Error</b></h2>\n%s\n"),
								nextp);
						}
						websWrite(wp, T("</body></html>\n"));
						rc = 0;
					}
					goto done;
				}
			}

		} else {
			websError(wp, 200, T("Unterminated script in %s: \n"), lpath);
			rc = -1;
			goto done;
		}
	}
/*
 *	Output any trailing HTML page text
 */
	if (last && *last && rc == 0) {
		websWriteBlock(wp, last, gstrlen(last));
	}
	rc = 0;

/*
 *	Common exit and cleanup
 */
done:
	if (websValid(wp)) {
		websPageClose(wp);
		if (ejid >= 0) {
			ejCloseEngine(ejid);
		}
	}
	bfreeSafe(B_L, buf);
	bfreeSafe(B_L, rbuf);
	return rc;
}
示例#4
0
文件: file.c 项目: blueskit/goahead
/*
    Serve static files
 */
static bool fileHandler(Webs *wp)
{
    WebsFileInfo    info;
    char            *tmp, *date;
    ssize           nchars;
    int             code;

    assert(websValid(wp));
    assert(wp->method);
    assert(wp->filename && wp->filename[0]);

#if !ME_ROM
    if (smatch(wp->method, "DELETE")) {
        if (unlink(wp->filename) < 0) {
            websError(wp, HTTP_CODE_NOT_FOUND, "Cannot delete the URI");
        } else {
            /* No content */
            websResponse(wp, 204, 0);
        }
    } else if (smatch(wp->method, "PUT")) {
        /* Code is already set for us by processContent() */
        websResponse(wp, wp->code, 0);

    } else 
#endif /* !ME_ROM */
    {
        /*
            If the file is a directory, redirect using the nominated default page
         */
        if (websPageIsDirectory(wp)) {
            nchars = strlen(wp->path);
            if (wp->path[nchars - 1] == '/' || wp->path[nchars - 1] == '\\') {
                wp->path[--nchars] = '\0';
            }
            tmp = sfmt("%s/%s", wp->path, websIndex);
            websRedirect(wp, tmp);
            wfree(tmp);
            return 1;
        }
        if (websPageOpen(wp, O_RDONLY | O_BINARY, 0666) < 0) {
#if ME_DEBUG
            if (wp->referrer) {
                trace(1, "From %s", wp->referrer);
            }
#endif
            websError(wp, HTTP_CODE_NOT_FOUND, "Cannot open document for: %s", wp->path);
            return 1;
        }
        if (websPageStat(wp, &info) < 0) {
            websError(wp, HTTP_CODE_NOT_FOUND, "Cannot stat page for URL");
            return 1;
        }
        code = 200;
        if (wp->since && info.mtime <= wp->since) {
            code = 304;
            info.size = 0;
        }
        websSetStatus(wp, code);
        websWriteHeaders(wp, info.size, 0);
        if ((date = websGetDateString(&info)) != NULL) {
            websWriteHeader(wp, "Last-Modified", "%s", date);
            wfree(date);
        }
        websWriteEndHeaders(wp);

        /*
            All done if the browser did a HEAD request
         */
        if (smatch(wp->method, "HEAD")) {
            websDone(wp);
            return 1;
        }
        if (info.size > 0) {
            websSetBackgroundWriter(wp, fileWriteEvent);
        } else {
            websDone(wp);
        }
    }
    return 1;
}
示例#5
0
/*
    Process requests and expand all scripting commands. We read the entire web page into memory and then process. If
    you have really big documents, it is better to make them plain HTML files rather than Javascript web pages.
 */
static bool jstHandler(Webs *wp)
{
    WebsFileInfo    sbuf;
    char            *token, *lang, *result, *ep, *cp, *buf, *nextp, *last;
    ssize           len;
    int             rc, jid;

    assert(websValid(wp));
    assert(wp->filename && *wp->filename);
    assert(wp->ext && *wp->ext);

    buf = 0;
    if ((jid = jsOpenEngine(wp->vars, websJstFunctions)) < 0) {
        websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot create JavaScript engine");
        goto done;
    }
    jsSetUserHandle(jid, wp);

    if (websPageStat(wp, &sbuf) < 0) {
        websError(wp, HTTP_CODE_NOT_FOUND, "Cannot stat %s", wp->filename);
        goto done;
    }
    if (websPageOpen(wp, O_RDONLY | O_BINARY, 0666) < 0) {
        websError(wp, HTTP_CODE_NOT_FOUND, "Cannot open URL: %s", wp->filename);
        goto done;
    }
    /*
        Create a buffer to hold the web page in-memory
     */
    len = sbuf.size;
    if ((buf = walloc(len + 1)) == NULL) {
        websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot get memory");
        goto done;
    }
    buf[len] = '\0';

    if (websPageReadData(wp, buf, len) != len) {
        websError(wp, HTTP_CODE_NOT_FOUND, "Cannot read %s", wp->filename);
        goto done;
    }
    websPageClose(wp);
    websWriteHeaders(wp, (ssize) -1, 0);
    websWriteHeader(wp, "Pragma", "no-cache");
    websWriteHeader(wp, "Cache-Control", "no-cache");
    websWriteEndHeaders(wp);

    /*
        Scan for the next "<%"
     */
    last = buf;
    for (rc = 0; rc == 0 && *last && ((nextp = strstr(last, "<%")) != NULL); ) {
        websWriteBlock(wp, last, (nextp - last));
        nextp = skipWhite(nextp + 2);
        /*
            Decode the language
         */
        token = "language";
        if ((lang = strtokcmp(nextp, token)) != NULL) {
            if ((cp = strtokcmp(lang, "=javascript")) != NULL) {
                /* Ignore */;
            } else {
                cp = nextp;
            }
            nextp = cp;
        }

        /*
            Find tailing bracket and then evaluate the script
         */
        if ((ep = strstr(nextp, "%>")) != NULL) {

            *ep = '\0';
            last = ep + 2;
            nextp = skipWhite(nextp);
            /*
                Handle backquoted newlines
             */
            for (cp = nextp; *cp; ) {
                if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) {
                    *cp++ = ' ';
                    while (*cp == '\r' || *cp == '\n') {
                        *cp++ = ' ';
                    }
                } else {
                    cp++;
                }
            }
            if (*nextp) {
                result = NULL;

                if (jsEval(jid, nextp, &result) == 0) {
                    /*
                         On an error, discard all output accumulated so far and store the error in the result buffer.
                         Be careful if the user has called websError() already.
                     */
                    rc = -1;
                    if (websValid(wp)) {
                        if (result) {
                            websWrite(wp, "<h2><b>Javascript Error: %s</b></h2>\n", result);
                            websWrite(wp, "<pre>%s</pre>", nextp);
                            wfree(result);
                        } else {
                            websWrite(wp, "<h2><b>Javascript Error</b></h2>\n%s\n", nextp);
                        }
                        websWrite(wp, "</body></html>\n");
                        rc = 0;
                    }
                    goto done;
                }
            }

        } else {
            websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Unterminated script in %s: \n", wp->filename);
            goto done;
        }
    }
    /*
        Output any trailing HTML page text
     */
    if (last && *last && rc == 0) {
        websWriteBlock(wp, last, strlen(last));
    }

/*
    Common exit and cleanup
 */
done:
    if (websValid(wp)) {
        websPageClose(wp);
        if (jid >= 0) {
            jsCloseEngine(jid);
        }
    }
    websDone(wp);
    wfree(buf);
    return 1;
}