]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/abaco/urls.c
cc: use 7 octal digits for 21 bit runes
[plan9front.git] / sys / src / cmd / abaco / urls.c
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==nil || decref(u) > 0)
33                 return;
34
35         closerunestr(&u->src);
36         closerunestr(&u->act);
37         closerunestr(&u->post);
38         closerunestr(&u->ctype);
39         free(u);
40 }
41
42 Url *
43 urldup(Url *a)
44 {
45         Url *b;
46
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);
53         return b;
54 }
55
56 static Runestr
57 getattr(int conn, char *s)
58 {
59         char buf[BUFSIZE];
60         int fd, n;
61
62         n = 0;
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)
66                         n = 0;
67                 close(fd);
68         }
69         buf[n] = '\0';
70         return (Runestr){runesmprint("%s", buf), n};
71 }
72
73 int
74 urlopen(Url *u)
75 {
76         char buf[BUFSIZE];
77         int cfd, fd, conn, n;
78
79         snprint(buf, sizeof(buf), "%s/clone", webmountpt);
80         cfd = open(buf, ORDWR);
81         if(cfd < 0)
82                 error("can't open clone file");
83
84         n = read(cfd, buf, sizeof(buf)-1);
85         if(n <= 0)
86                 error("reading clone");
87
88         buf[n] = '\0';
89         conn = atoi(buf);
90
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);
94     Err:
95                 close(cfd);
96                 return -1;
97         }
98         if(u->method==HPost && u->post.r != nil){
99                 snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn);
100                 fd = open(buf, OWRITE);
101                 if(fd < 0){
102 //                      fprint(2, "urlopen: bad query: %s: %r\n", buf);
103                         goto Err;
104                 }
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);
108
109                 close(fd);
110         }
111         snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn);
112         fd = open(buf, OREAD);
113         if(fd < 0){
114 //              fprint(2, "open: %S: %r\n", u->src.r);
115                 goto Err;
116         }
117         u->ctype = getattr(conn, "contenttype");
118         u->act = getattr(conn, "parsed/url");
119         if(u->act.nr == 0)
120                 copyrunestr(&u->act, &u->src);
121         close(cfd);
122         return fd;
123 }
124
125 void
126 urlcanon(Rune *name)
127 {
128         Rune *s, *e, *tail, tailr;
129         Rune **comp, **p, **q;
130         int n;
131
132         name = runestrstr(name, L"://");
133         if(name == nil)
134                 return;
135         name = runestrchr(name+3, '/');
136         if(name == nil)
137                 return;
138         if(*name == L'/')
139                 name++;
140
141         n = 0;
142         for(e = name; *e != 0; e++)
143                 if(*e == L'/')
144                         n++;
145         comp = emalloc((n+2)*sizeof *comp);
146
147         /*
148          * Break the name into a list of components
149          */
150         p = comp;
151         *p++ = name;
152         tail = nil;
153         tailr = L'☺'; /* silence compiler */
154         for(s = name; *s != 0; s++){
155                 if(*s == '?' || *s == '#'){
156                         tail = s+1;
157                         tailr = *s;
158                         *s = 0;
159                         break;
160                 }
161                 else if(*s == L'/'){
162                         *p++ = s+1;
163                         *s = 0;
164                 }
165         }
166
167         /*
168          * go through the component list, deleting components that are empty (except
169          * the last component) or ., and any .. and its predecessor.
170          */
171         for(p = q = comp; *p != nil; p++){
172                 if(runestrcmp(*p, L"") == 0 && p[1] != nil
173                 || runestrcmp(*p, L".") == 0)
174                         continue;
175                 else if(q>comp && runestrcmp(*p, L"..") == 0 && runestrcmp(q[-1], L"..") != 0)
176                         q--;
177                 else
178                         *q++ = *p;
179         }
180         *q = nil;
181
182         /*
183          * rebuild the path name
184          */
185         s = name;
186         for(p = comp; p<q; p++){
187                 n = runestrlen(*p);
188                 memmove(s, *p, sizeof(Rune)*n);
189                 s += n;
190                 if(p[1] != nil)
191                         *s++ = '/';
192         }
193         *s = 0;
194         if(tail)
195                 runeseprint(s, e+1, "%C%S", tailr, tail);
196         free(comp);
197 }
198
199 /* this is a HACK */
200 Rune*
201 urlcombine(Rune *b, Rune *u)
202 {
203         Rune *p, *q, *sep, *s;
204         Rune endrune[] = { L'?', L'#' };
205         int i, restore;
206
207         if(u == nil)
208                 error("urlcombine: u == nil");
209
210         if(validurl(u))
211                 return erunestrdup(u);
212
213         if(b==nil || !validurl(b))
214                 error("urlcombine: b==nil || !validurl(b)");
215
216         if(runestrncmp(u, L"//", 2) == 0){
217                 q =  runestrchr(b, L':');
218                 return runesmprint("%.*S:%S", (int)(q-b), b, u);
219         }
220         p = runestrstr(b, L"://");
221         if(p != nil)
222                 p += 3;
223         sep = L"";
224         q = nil;
225         if(*u ==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]))
230                                 break;
231         }else if(p != nil){
232                 sep = L"/";
233                 restore = 0;
234                 s = runestrchr(p, L'?');
235                 if(s != nil){
236                         *s = '\0';
237                         restore = 1;
238                 }
239                 q = runestrrchr(p, L'/');
240                 if(restore)
241                         *s = L'?';
242         }else
243                 sep = L"/";
244         if(q == nil)
245                 p = runesmprint("%S%S%S", b, sep, u);
246         else
247                 p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u);
248         urlcanon(p);
249         return p;
250 }