#include #include #include #include #include #include #include #include #include #include #include #include "dat.h" #include "fns.h" Url * urlalloc(Runestr *src, Runestr *post, int m) { Url *u; u = emalloc(sizeof(Url)); copyrunestr(&u->src, src); if(m==HPost) copyrunestr(&u->post, post); u->method = m; incref(u); return u; } void urlfree(Url *u) { if(u==nil || decref(u) > 0) return; closerunestr(&u->src); closerunestr(&u->act); closerunestr(&u->post); closerunestr(&u->ctype); free(u); } Url * urldup(Url *a) { Url *b; b = emalloc(sizeof(Url)); b->method = a->method; copyrunestr(&b->src, &a->src); copyrunestr(&b->act, &a->act); copyrunestr(&b->post, &a->post); copyrunestr(&b->ctype, &a->ctype); return b; } static Runestr getattr(int conn, char *s) { char buf[BUFSIZE]; int fd, n; n = 0; snprint(buf, sizeof buf, "%s/%d/%s", webmountpt, conn, s); if((fd = open(buf, OREAD)) >= 0){ if((n = read(fd, buf, sizeof(buf)-1)) < 0) n = 0; close(fd); } buf[n] = '\0'; return (Runestr){runesmprint("%s", buf), n}; } int urlopen(Url *u) { char buf[BUFSIZE]; int cfd, fd, conn, n; snprint(buf, sizeof(buf), "%s/clone", webmountpt); cfd = open(buf, ORDWR); if(cfd < 0) error("can't open clone file"); n = read(cfd, buf, sizeof(buf)-1); if(n <= 0) error("reading clone"); buf[n] = '\0'; conn = atoi(buf); snprint(buf, sizeof(buf), "url %S", u->src.r); if(write(cfd, buf, strlen(buf)) < 0){ // fprint(2, "write: %s: %r\n", buf); Err: close(cfd); return -1; } if(u->method==HPost && u->post.r != nil){ snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn); fd = open(buf, OWRITE); if(fd < 0){ // fprint(2, "urlopen: bad query: %s: %r\n", buf); goto Err; } snprint(buf, sizeof(buf), "%S", u->post.r); if(write(fd, buf, strlen(buf)) < 0) fprint(2, "urlopen: bad query: %s: %r\n", buf); close(fd); } snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn); fd = open(buf, OREAD); if(fd < 0){ // fprint(2, "open: %S: %r\n", u->src.r); goto Err; } u->ctype = getattr(conn, "contenttype"); u->act = getattr(conn, "parsed/url"); if(u->act.nr == 0) copyrunestr(&u->act, &u->src); close(cfd); return fd; } void urlcanon(Rune *name) { Rune *s, *e, *tail, tailr; Rune **comp, **p, **q; int n; name = runestrstr(name, L"://"); if(name == nil) return; name = runestrchr(name+3, '/'); if(name == nil) return; if(*name == L'/') name++; n = 0; for(e = name; *e != 0; e++) if(*e == L'/') n++; comp = emalloc((n+2)*sizeof *comp); /* * Break the name into a list of components */ p = comp; *p++ = name; tail = nil; tailr = L'☺'; /* silence compiler */ for(s = name; *s != 0; s++){ if(*s == '?' || *s == '#'){ tail = s+1; tailr = *s; *s = 0; break; } else if(*s == L'/'){ *p++ = s+1; *s = 0; } } /* * go through the component list, deleting components that are empty (except * the last component) or ., and any .. and its predecessor. */ for(p = q = comp; *p != nil; p++){ if(runestrcmp(*p, L"") == 0 && p[1] != nil || runestrcmp(*p, L".") == 0) continue; else if(q>comp && runestrcmp(*p, L"..") == 0 && runestrcmp(q[-1], L"..") != 0) q--; else *q++ = *p; } *q = nil; /* * rebuild the path name */ s = name; for(p = comp; p