return os.path.join(cwd, path)
return path
+def unquoteurl(url):
+ buf = ""
+ i = 0
+ while i < len(url):
+ c = url[i]
+ i += 1
+ if c == '%':
+ if len(url) > i + 2:
+ c = 0
+ if '0' <= url[i] <= '9':
+ c |= (ord(url[i]) - ord('0')) << 4
+ elif 'a' <= url[i] <= 'f':
+ c |= (ord(url[i]) - ord('a')) << 4
+ elif 'A' <= url[i] <= 'F':
+ c |= (ord(url[i]) - ord('A')) << 4
+ else:
+ raise ValueError("Illegal URL escape character")
+ if '0' <= url[i + 1] <= '9':
+ c |= ord(url[i + 1]) - ord('0')
+ elif 'a' <= url[i + 1] <= 'f':
+ c |= ord(url[i + 1]) - ord('a')
+ elif 'A' <= url[i + 1] <= 'F':
+ c |= ord(url[i + 1]) - ord('A')
+ else:
+ raise ValueError("Illegal URL escape character")
+ buf += chr(c)
+ i += 2
+ else:
+ raise ValueError("Incomplete URL escape character")
+ else:
+ buf += c
+ return buf
+
def dowsgi(req):
env = {}
env["wsgi.version"] = 1, 0
env["SERVER_PROTOCOL"] = req.ver
env["REQUEST_METHOD"] = req.method
env["REQUEST_URI"] = req.url
- env["PATH_INFO"] = req.rest
+ try:
+ env["PATH_INFO"] = unquoteurl(req.rest)
+ except:
+ env["PATH_INFO"] = req.rest
name = req.url
p = name.find('?')
if p >= 0:
#endif
#include <utils.h>
#include <log.h>
+#include <req.h>
static char **environ;
char *qp, **env, *name;
int inp[2], outp[2];
pid_t pid;
+ char *unqr;
pipe(inp);
pipe(outp);
if(getenv("HTTP_VERSION"))
putenv(sprintf2("SERVER_PROTOCOL=%s", getenv("HTTP_VERSION")));
putenv(sprintf2("REQUEST_METHOD=%s", method));
- putenv(sprintf2("PATH_INFO=%s", rest));
+ unqr = unquoteurl(rest);
+ putenv(sprintf2("PATH_INFO=%s", unqr?unqr:rest));
name = url;
/* XXX: This is an ugly hack (I think), but though I can think
* of several alternatives, none seem to be better. */
for(p = buf->b + buf->d - 1; (p > buf->b) && isspace(*p); p--, buf->d--);
}
-static char **parseheaders(FILE *s)
+static char **parsecgiheaders(FILE *s)
{
int c, state;
struct charvbuf hbuf;
passdata(stdin, in); /* Ignore errors, perhaps? */
fclose(in);
out = fdopen(outfd, "r");
- if((headers = parseheaders(out)) == NULL) {
+ if((headers = parsecgiheaders(out)) == NULL) {
flog(LOG_WARNING, "CGI handler returned invalid headers");
exit(1);
}
static void mkcgienv(struct hthead *req, struct charbuf *dst)
{
int i;
- char *url, *qp, *h, *p;
+ char *url, *unq, *qp, *h, *p;
bufaddenv(dst, "SERVER_SOFTWARE", "ashd/%s", VERSION);
bufaddenv(dst, "GATEWAY_INTERFACE", "CGI/1.1");
bufaddenv(dst, "SERVER_PROTOCOL", "%s", req->ver);
bufaddenv(dst, "REQUEST_METHOD", "%s", req->method);
bufaddenv(dst, "REQUEST_URI", "%s", req->url);
- bufaddenv(dst, "PATH_INFO", req->rest);
+ if((unq = unquoteurl(req->rest)) != NULL) {
+ bufaddenv(dst, "PATH_INFO", unq);
+ free(unq);
+ } else {
+ bufaddenv(dst, "PATH_INFO", req->rest);
+ }
url = sstrdup(req->url);
if((qp = strchr(url, '?')) != NULL)
*(qp++) = 0;
static void mkcgienv(struct hthead *req, struct charbuf *dst)
{
int i;
- char *url, *qp, *h, *p;
+ char *url, *unq, *qp, *h, *p;
bufaddenv(dst, "SERVER_SOFTWARE", "ashd/%s", VERSION);
bufaddenv(dst, "GATEWAY_INTERFACE", "CGI/1.1");
bufaddenv(dst, "SERVER_PROTOCOL", "%s", req->ver);
bufaddenv(dst, "REQUEST_METHOD", "%s", req->method);
bufaddenv(dst, "REQUEST_URI", "%s", req->url);
- bufaddenv(dst, "PATH_INFO", req->rest);
+ if((unq = unquoteurl(req->rest)) != NULL) {
+ bufaddenv(dst, "PATH_INFO", unq);
+ free(unq);
+ } else {
+ bufaddenv(dst, "PATH_INFO", req->rest);
+ }
url = sstrdup(req->url);
if((qp = strchr(url, '?')) != NULL)
*(qp++) = 0;