1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 #include <memdraw.h> 5 #include <thread.h> 6 #include <cursor.h> 7 #include <mouse.h> 8 #include <keyboard.h> 9 #include <frame.h> 10 #include <plumb.h> 11 #include <html.h> 12 #include "dat.h" 13 #include "fns.h" 14 15 Url * 16 urlalloc(Runestr *src, Runestr *post, int m) 17 { 18 Url *u; 19 20 u = emalloc(sizeof(Url)); 21 copyrunestr(&u->src, src); 22 if(m==HPost) 23 copyrunestr(&u->post, post); 24 u->method = m; 25 incref(u); 26 return u; 27 } 28 29 void 30 urlfree(Url *u) 31 { 32 if(u && decref(u)==0){ 33 closerunestr(&u->src); 34 closerunestr(&u->act); 35 closerunestr(&u->post); 36 closerunestr(&u->ctype); 37 free(u); 38 } 39 } 40 41 Url * 42 urldup(Url *a) 43 { 44 Url *b; 45 46 b = emalloc(sizeof(Url)); 47 b->method = a->method; 48 copyrunestr(&b->src, &a->src); 49 copyrunestr(&b->act, &a->act); 50 copyrunestr(&b->post, &a->post); 51 copyrunestr(&b->ctype, &a->ctype); 52 return b; 53 } 54 55 static 56 Runestr 57 getattr(int conn, char *s) 58 { 59 char buf[BUFSIZE]; 60 int fd, n; 61 62 snprint(buf, sizeof(buf), "%s/%d/%s", webmountpt, conn, s); 63 fd = open(buf, OREAD); 64 if(fd < 0) 65 error("can't open attr file"); 66 67 n = read(fd, buf, sizeof(buf)-1); 68 if(n < 0) 69 error("can't read"); 70 71 close(fd); 72 buf[n] = '\0'; 73 return (Runestr){runesmprint("%s", buf), n}; 74 } 75 76 int 77 urlopen(Url *u) 78 { 79 char buf[BUFSIZE]; 80 int cfd, fd, conn, n; 81 82 snprint(buf, sizeof(buf), "%s/clone", webmountpt); 83 cfd = open(buf, ORDWR); 84 if(cfd < 0) 85 error("can't open clone file"); 86 87 n = read(cfd, buf, sizeof(buf)-1); 88 if(n <= 0) 89 error("reading clone"); 90 91 buf[n] = '\0'; 92 conn = atoi(buf); 93 94 snprint(buf, sizeof(buf), "url %S", u->src.r); 95 if(write(cfd, buf, strlen(buf)) < 0){ 96 // fprint(2, "write: %s: %r\n", buf); 97 Err: 98 close(cfd); 99 return -1; 100 } 101 if(u->method==HPost && u->post.r != nil){ 102 snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn); 103 fd = open(buf, OWRITE); 104 if(fd < 0){ 105 // fprint(2, "urlopen: bad query: %s: %r\n", buf); 106 goto Err; 107 } 108 snprint(buf, sizeof(buf), "%S", u->post.r); 109 if(write(fd, buf, strlen(buf)) < 0) 110 fprint(2, "urlopen: bad query: %s: %r\n", buf); 111 112 close(fd); 113 } 114 snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn); 115 fd = open(buf, OREAD); 116 if(fd < 0){ 117 // fprint(2, "open: %S: %r\n", u->src.r); 118 goto Err; 119 } 120 u->ctype = getattr(conn, "contenttype"); 121 u->act = getattr(conn, "parsed/url"); 122 if(u->act.nr == 0) 123 copyrunestr(&u->act, &u->src); 124 close(cfd); 125 return fd; 126 } 127 128 void 129 urlcanon(Rune *name){ 130 Rune *s, *t; 131 Rune **comp, **p, **q; 132 int rooted; 133 134 name = runestrchr(name, L'/')+2; 135 rooted=name[0]==L'/'; 136 /* 137 * Break the name into a list of components 138 */ 139 comp=emalloc(runestrlen(name)*sizeof(char *)); 140 p=comp; 141 *p++=name; 142 for(s=name;;s++){ 143 if(*s==L'/'){ 144 *p++=s+1; 145 *s='\0'; 146 } 147 else if(*s=='\0') 148 break; 149 } 150 *p=0; 151 /* 152 * go through the component list, deleting components that are empty (except 153 * the last component) or ., and any .. and its non-.. predecessor. 154 */ 155 p=q=comp; 156 while(*p){ 157 if(runestrcmp(*p, L"")==0 && p[1]!=0 158 || runestrcmp(*p, L".")==0) 159 p++; 160 else if(runestrcmp(*p, L"..")==0 && q!=comp && runestrcmp(q[-1], L"..")!=0){ 161 --q; 162 p++; 163 } 164 else 165 *q++=*p++; 166 } 167 *q=0; 168 /* 169 * rebuild the path name 170 */ 171 s=name; 172 if(rooted) *s++='/'; 173 for(p=comp;*p;p++){ 174 t=*p; 175 while(*t) *s++=*t++; 176 if(p[1]!=0) *s++='/'; 177 } 178 *s='\0'; 179 free(comp); 180 } 181 182 /* this is a HACK */ 183 Rune * 184 urlcombine(Rune *b, Rune *u) 185 { 186 Rune *p, *q, *sep, *s; 187 Rune endrune[] = { L'?', L'#' }; 188 int i, restore; 189 190 if(u == nil) 191 error("urlcombine: u == nil"); 192 193 if(validurl(u)) 194 return erunestrdup(u); 195 196 if(b==nil || !validurl(b)) 197 error("urlcombine: b==nil || !validurl(b)"); 198 199 if(runestrncmp(u, L"//", 2) == 0){ 200 q = runestrchr(b, L':'); 201 return runesmprint("%.*S:%S", (int)(q-b), b, u); 202 } 203 p = runestrstr(b, L"://")+3; 204 sep = L""; 205 q = nil; 206 if(*u ==L'/') 207 q = runestrchr(p, L'/'); 208 else if(*u==L'#' || *u==L'?'){ 209 for(i=0; i<nelem(endrune); i++) 210 if(q = runestrchr(p, endrune[i])) 211 break; 212 }else{ 213 sep = L"/"; 214 restore = 0; 215 s = runestrchr(p, L'?'); 216 if(s != nil){ 217 *s = '\0'; 218 restore = 1; 219 } 220 q = runestrrchr(p, L'/'); 221 if(restore) 222 *s = L'?'; 223 } 224 if(q == nil) 225 p = runesmprint("%S%S%S", b, sep, u); 226 else 227 p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u); 228 urlcanon(p); 229 return p; 230 } 231