ref: a57a6e511f15c02b4fd2690197b6f1333b171193
dir: /sys/src/cmd/abaco/urls.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <memdraw.h> #include <thread.h> #include <cursor.h> #include <mouse.h> #include <keyboard.h> #include <frame.h> #include <plumb.h> #include <html.h> #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<q; p++){ n = runestrlen(*p); memmove(s, *p, sizeof(Rune)*n); s += n; if(p[1] != nil) *s++ = '/'; } *s = 0; if(tail) runeseprint(s, e+1, "%C%S", tailr, tail); free(comp); } /* this is a HACK */ Rune* urlcombine(Rune *b, Rune *u) { Rune *p, *q, *sep, *s; Rune endrune[] = { L'?', L'#' }; int i, restore; if(u == nil) error("urlcombine: u == nil"); if(validurl(u)) return erunestrdup(u); if(b==nil || !validurl(b)) error("urlcombine: b==nil || !validurl(b)"); if(runestrncmp(u, L"//", 2) == 0){ q = runestrchr(b, L':'); return runesmprint("%.*S:%S", (int)(q-b), b, u); } p = runestrstr(b, L"://"); if(p != nil) p += 3; sep = L""; q = nil; if(*u ==L'/') q = runestrchr(p, L'/'); else if(*u==L'#' || *u==L'?'){ for(i=0; i<nelem(endrune); i++) if(q = runestrchr(p, endrune[i])) break; }else if(p != nil){ sep = L"/"; restore = 0; s = runestrchr(p, L'?'); if(s != nil){ *s = '\0'; restore = 1; } q = runestrrchr(p, L'/'); if(restore) *s = L'?'; }else sep = L"/"; if(q == nil) p = runesmprint("%S%S%S", b, sep, u); else p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u); urlcanon(p); return p; }