nil,
};
+static char *mtpt;
+static char *service;
static long time0;
static char *user;
static char *agent;
static Client client[64];
static int nclient;
-#define CLIENTID(c) (((Client*)(c)) - client)
+#define CLIENTID(c) ((int)(((Client*)(c)) - client))
Client*
newclient(void)
case Qclient:
q->type = QTDIR;
default:
- q->path = (level<<24) | (((ulong)aux ^ time0) & 0x00ffffff);
+ q->path = (level<<24) | (((uintptr)aux ^ time0) & 0x00ffffff);
}
}
d->length = strlen(((Key*)aux)->val);
break;
case Qclient:
- snprint(buf, sizeof(buf), "%ld", CLIENTID(aux));
+ snprint(buf, sizeof(buf), "%d", CLIENTID(aux));
d->name = estrdup(buf);
break;
case Qctl:
if(cl->request[0])
m = cl->request;
- if(!lookkey(cl->hdr, "Referer")){
- char *r;
- Url *u;
-
- /*
- * Referer header is often required on broken
- * websites even if the spec makes them optional,
- * so we make one up.
- */
- if(u = url("/", cl->url)){
- if(r = smprint("%U", u)){
- cl->hdr = addkey(cl->hdr, "Referer", r);
- free(r);
- }
- freeurl(u);
- }
- }
+ /*
+ * some sites give a 403 Forbidden if we dont include
+ * a meaningless Accept header in the request.
+ */
+ if(!lookkey(cl->hdr, "Accept"))
+ cl->hdr = addkey(cl->hdr, "Accept", "*/*");
if(!lookkey(cl->hdr, "Connection"))
cl->hdr = addkey(cl->hdr, "Connection", "keep-alive");
respond(r, nil);
return;
case Qctl:
- snprint(buf, sizeof(buf), "%ld\n", CLIENTID(f->client));
+ snprint(buf, sizeof(buf), "%d\n", CLIENTID(f->client));
goto String;
case Qheader:
snprint(buf, sizeof(buf), "%s", f->key->val);
}
static char*
-rootctl(char *ctl, char *arg)
+rootctl(Srv *fs, char *ctl, char *arg)
{
Url *u;
return nil;
}
+ /* ppreemptive authentication only basic
+ * auth supported, ctl message of the form:
+ * preauth url realm
+ */
+ if(!strcmp(ctl, "preauth")){
+ char *a[3], buf[256];
+ int rc;
+
+ if(tokenize(arg, a, nelem(a)) != 2)
+ return "preauth - bad field count";
+ if((u = saneurl(url(a[0], 0))) == nil)
+ return "preauth - malformed url";
+ snprint(buf, sizeof(buf), "BASIC realm=\"%s\"", a[1]);
+ srvrelease(fs);
+ rc = authenticate(u, u, "GET", buf);
+ srvacquire(fs);
+ freeurl(u);
+ if(rc == -1)
+ return "preauth failed";
+ return nil;
+ }
+
return "bad ctl message";
}
else if(!strcmp(ctl, "headers")){
while(arg && *arg){
ctl = arg;
- while(*ctl && strchr("\r\n\t ", *ctl))
+ while(*ctl && strchr(whitespace, *ctl))
ctl++;
if(arg = strchr(ctl, '\n'))
*arg++ = 0;
n--;
s[n] = 0;
t = s;
- while(*t && strchr("\r\n\t ", *t)==0)
+ while(*t && strchr(whitespace, *t)==0)
t++;
- while(*t && strchr("\r\n\t ", *t))
+ while(*t && strchr(whitespace, *t))
*t++ = 0;
if(f->level == Qctl)
t = clientctl(f->client, s, t);
else
- t = rootctl(s, t);
+ t = rootctl(r->srv, s, t);
free(s);
respond(r, t);
return;
}
}
+static void
+fsstart(Srv*)
+{
+ /* drop reference to old webfs mount */
+ if(mtpt != nil)
+ unmount(nil, mtpt);
+}
+
+static void
+fsend(Srv*)
+{
+ postnote(PNGROUP, getpid(), "shutdown");
+ exits(nil);
+}
+
Srv fs =
{
+ .start=fsstart,
.attach=fsattach,
.stat=fsstat,
.walk1=fswalk1,
.write=fswrite,
.flush=fsflush,
.destroyfid=fsdestroyfid,
+ .end=fsend,
};
void
usage(void)
{
- fprint(2, "usage: %s [-D] [-A useragent] [-T timeout] [-m mtpt] [-s srv]\n", argv0);
+ fprint(2, "usage: %s [-Dd] [-A useragent] [-T timeout] [-m mtpt] [-s service]\n", argv0);
exits("usage");
}
void
main(int argc, char *argv[])
{
- char *srv, *mtpt, *s;
+ char *s;
quotefmtinstall();
fmtinstall('U', Ufmt);
+ fmtinstall('N', Nfmt);
+ fmtinstall(']', Mfmt);
fmtinstall('E', Efmt);
+ fmtinstall('[', encodefmt);
+ fmtinstall('H', encodefmt);
- srv = nil;
mtpt = "/mnt/web";
user = getuser();
time0 = time(0);
timeout = 10000;
- agent = nil;
ARGBEGIN {
case 'D':
mtpt = EARGF(usage());
break;
case 's':
- srv = EARGF(usage());
+ service = EARGF(usage());
break;
case 'd':
debug++;
rfork(RFNOTEG);
if(agent == nil)
- agent = "hjdicks";
+ agent = "Mozilla/5.0 (compatible; hjdicks)";
agent = estrdup(agent);
if(s = getenv("httpproxy")){
proxy = saneurl(url(s, 0));
+ if(proxy == nil || strcmp(proxy->scheme, "http") && strcmp(proxy->scheme, "https"))
+ sysfatal("invalid httpproxy url: %s", s);
free(s);
}
- postmountsrv(&fs, srv, mtpt, MREPL);
+ postmountsrv(&fs, service, mtpt, MREPL);
+ exits(nil);
}