16 urlalloc(Runestr *src, Runestr *post, int m)
20 u = emalloc(sizeof(Url));
21 copyrunestr(&u->src, src);
23 copyrunestr(&u->post, post);
32 if(u==nil || decref(u) > 0)
35 closerunestr(&u->src);
36 closerunestr(&u->act);
37 closerunestr(&u->post);
38 closerunestr(&u->ctype);
47 b = emalloc(sizeof(Url));
48 b->method = a->method;
49 copyrunestr(&b->src, &a->src);
50 copyrunestr(&b->act, &a->act);
51 copyrunestr(&b->post, &a->post);
52 copyrunestr(&b->ctype, &a->ctype);
57 getattr(int conn, char *s)
63 snprint(buf, sizeof buf, "%s/%d/%s", webmountpt, conn, s);
64 if((fd = open(buf, OREAD)) >= 0){
65 if((n = read(fd, buf, sizeof(buf)-1)) < 0)
70 return (Runestr){runesmprint("%s", buf), n};
79 snprint(buf, sizeof(buf), "%s/clone", webmountpt);
80 cfd = open(buf, ORDWR);
82 error("can't open clone file");
84 n = read(cfd, buf, sizeof(buf)-1);
86 error("reading clone");
91 snprint(buf, sizeof(buf), "url %S", u->src.r);
92 if(write(cfd, buf, strlen(buf)) < 0){
93 // fprint(2, "write: %s: %r\n", buf);
98 if(u->method==HPost && u->post.r != nil){
99 snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn);
100 fd = open(buf, OWRITE);
102 // fprint(2, "urlopen: bad query: %s: %r\n", buf);
105 snprint(buf, sizeof(buf), "%S", u->post.r);
106 if(write(fd, buf, strlen(buf)) < 0)
107 fprint(2, "urlopen: bad query: %s: %r\n", buf);
111 snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn);
112 fd = open(buf, OREAD);
114 // fprint(2, "open: %S: %r\n", u->src.r);
117 u->ctype = getattr(conn, "contenttype");
118 u->act = getattr(conn, "parsed/url");
120 copyrunestr(&u->act, &u->src);
128 Rune *s, *e, *tail, tailr;
129 Rune **comp, **p, **q;
132 name = runestrstr(name, L"://");
135 name = runestrchr(name+3, '/');
142 for(e = name; *e != 0; e++)
145 comp = emalloc((n+2)*sizeof *comp);
148 * Break the name into a list of components
153 tailr = L'☺'; /* silence compiler */
154 for(s = name; *s != 0; s++){
155 if(*s == '?' || *s == '#'){
168 * go through the component list, deleting components that are empty (except
169 * the last component) or ., and any .. and its predecessor.
171 for(p = q = comp; *p != nil; p++){
172 if(runestrcmp(*p, L"") == 0 && p[1] != nil
173 || runestrcmp(*p, L".") == 0)
175 else if(q>comp && runestrcmp(*p, L"..") == 0 && runestrcmp(q[-1], L"..") != 0)
183 * rebuild the path name
186 for(p = comp; p<q; p++){
188 memmove(s, *p, sizeof(Rune)*n);
195 runeseprint(s, e+1, "%C%S", tailr, tail);
201 urlcombine(Rune *b, Rune *u)
203 Rune *p, *q, *sep, *s;
204 Rune endrune[] = { L'?', L'#' };
208 error("urlcombine: u == nil");
211 return erunestrdup(u);
213 if(b==nil || !validurl(b))
214 error("urlcombine: b==nil || !validurl(b)");
216 if(runestrncmp(u, L"//", 2) == 0){
217 q = runestrchr(b, L':');
218 return runesmprint("%.*S:%S", (int)(q-b), b, u);
220 p = runestrstr(b, L"://");
226 q = runestrchr(p, L'/');
227 else if(*u==L'#' || *u==L'?'){
228 for(i=0; i<nelem(endrune); i++)
229 if(q = runestrchr(p, endrune[i]))
234 s = runestrchr(p, L'?');
239 q = runestrrchr(p, L'/');
245 p = runesmprint("%S%S%S", b, sep, u);
247 p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u);