]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/abaco/urls.c
merge
[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 // tired of typing http://, tired of going to google first.
74 void
75 justgoogleit(Url *u)
76 {
77         Rune *s;
78         
79         s = ucvt(u->src.r+2);
80         free(u->src.r);
81         u->src.r = runesmprint("http://www.google.com/search?hl=en&ie=UTF-8&q=%S", s);
82         free(s);
83         u->src.nr = runestrlen(u->src.r);
84 }
85
86 void
87 addhttp(Url *u)
88 {
89         Rune *s;
90         if(validurl(u->src.r))
91                 return;
92         s = u->src.r;
93         u->src.r = runesmprint("http://%S", u->src.r);
94         free(s);
95         u->src.nr = runestrlen(u->src.r);
96 }
97
98 struct{
99         void    (*f)(Url*);
100         Rune    *lead;
101         int     len;
102 } ctab[] = {
103         justgoogleit,   L"g ",          2,
104         addhttp,                L"",            0,
105 };
106
107 void
108 urlconvience(Url *u)
109 {
110         int i;
111
112         for(i = 0; u->src.nr >= ctab[i].len && runestrncmp(u->src.r, ctab[i].lead, ctab[i].len) != 0; i++)
113                 ;
114         ctab[i].f(u);
115 }
116
117 int
118 urlopen(Url *u)
119 {
120         char buf[BUFSIZE];
121         int cfd, fd, conn, n;
122
123         urlconvience(u);
124         snprint(buf, sizeof(buf), "%s/clone", webmountpt);
125         cfd = open(buf, ORDWR);
126         if(cfd < 0)
127                 error("can't open clone file");
128
129         n = read(cfd, buf, sizeof(buf)-1);
130         if(n <= 0)
131                 error("reading clone");
132
133         buf[n] = '\0';
134         conn = atoi(buf);
135
136         snprint(buf, sizeof(buf), "url %S", u->src.r);
137         if(write(cfd, buf, strlen(buf)) < 0){
138 //              fprint(2, "write: %s: %r\n", buf);
139     Err:
140                 close(cfd);
141                 return -1;
142         }
143         if(u->method==HPost && u->post.r != nil){
144                 snprint(buf, sizeof(buf), "%s/%d/postbody", webmountpt, conn);
145                 fd = open(buf, OWRITE);
146                 if(fd < 0){
147 //                      fprint(2, "urlopen: bad query: %s: %r\n", buf);
148                         goto Err;
149                 }
150                 snprint(buf, sizeof(buf), "%S", u->post.r);
151                 if(write(fd, buf, strlen(buf)) < 0)
152                         fprint(2, "urlopen: bad query: %s: %r\n", buf);
153
154                 close(fd);
155         }
156         snprint(buf, sizeof(buf), "%s/%d/body", webmountpt, conn);
157         fd = open(buf, OREAD);
158         if(fd < 0){
159 //              fprint(2, "open: %S: %r\n", u->src.r);
160                 goto Err;
161         }
162         u->ctype = getattr(conn, "contenttype");
163         u->act = getattr(conn, "parsed/url");
164         if(u->act.nr == 0)
165                 copyrunestr(&u->act, &u->src);
166         close(cfd);
167         return fd;
168 }
169
170 void
171 urlcanon(Rune *name)
172 {
173         Rune *s, *e, *tail, tailr;
174         Rune **comp, **p, **q;
175         int n;
176
177         name = runestrstr(name, L"://");
178         if(name == nil)
179                 return;
180         name = runestrchr(name+3, '/');
181         if(name == nil)
182                 return;
183         if(*name == L'/')
184                 name++;
185
186         n = 0;
187         for(e = name; *e != 0; e++)
188                 if(*e == L'/')
189                         n++;
190         comp = emalloc((n+2)*sizeof *comp);
191
192         /*
193          * Break the name into a list of components
194          */
195         p = comp;
196         *p++ = name;
197         tail = nil;
198         tailr = L'☺'; /* silence compiler */
199         for(s = name; *s != 0; s++){
200                 if(*s == '?' || *s == '#'){
201                         tail = s+1;
202                         tailr = *s;
203                         *s = 0;
204                         break;
205                 }
206                 else if(*s == L'/'){
207                         *p++ = s+1;
208                         *s = 0;
209                 }
210         }
211
212         /*
213          * go through the component list, deleting components that are empty (except
214          * the last component) or ., and any .. and its predecessor.
215          */
216         for(p = q = comp; *p != nil; p++){
217                 if(runestrcmp(*p, L"") == 0 && p[1] != nil
218                 || runestrcmp(*p, L".") == 0)
219                         continue;
220                 else if(q>comp && runestrcmp(*p, L"..") == 0 && runestrcmp(q[-1], L"..") != 0)
221                         q--;
222                 else
223                         *q++ = *p;
224         }
225         *q = nil;
226
227         /*
228          * rebuild the path name
229          */
230         s = name;
231         for(p = comp; p<q; p++){
232                 n = runestrlen(*p);
233                 memmove(s, *p, sizeof(Rune)*n);
234                 s += n;
235                 if(p[1] != nil)
236                         *s++ = '/';
237         }
238         *s = 0;
239         if(tail)
240                 runeseprint(s, e+1, "%C%S", tailr, tail);
241         free(comp);
242 }
243
244 /* this is a HACK */
245 Rune*
246 urlcombine(Rune *b, Rune *u)
247 {
248         Rune *p, *q, *sep, *s;
249         Rune endrune[] = { L'?', L'#' };
250         int i, restore;
251
252         if(u == nil)
253                 error("urlcombine: u == nil");
254
255         if(validurl(u))
256                 return erunestrdup(u);
257
258         if(b==nil || !validurl(b))
259                 error("urlcombine: b==nil || !validurl(b)");
260
261         if(runestrncmp(u, L"//", 2) == 0){
262                 q =  runestrchr(b, L':');
263                 return runesmprint("%.*S:%S", (int)(q-b), b, u);
264         }
265         p = runestrstr(b, L"://");
266         if(p != nil)
267                 p += 3;
268         sep = L"";
269         q = nil;
270         if(*u ==L'/')
271                 q = runestrchr(p, L'/');
272         else if(*u==L'#' || *u==L'?'){
273                 for(i=0; i<nelem(endrune); i++)
274                         if(q = runestrchr(p, endrune[i]))
275                                 break;
276         }else if(p != nil){
277                 sep = L"/";
278                 restore = 0;
279                 s = runestrchr(p, L'?');
280                 if(s != nil){
281                         *s = '\0';
282                         restore = 1;
283                 }
284                 q = runestrrchr(p, L'/');
285                 if(restore)
286                         *s = L'?';
287         }else
288                 sep = L"/";
289         if(q == nil)
290                 p = runesmprint("%S%S%S", b, sep, u);
291         else
292                 p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u);
293         urlcanon(p);
294         return p;
295 }