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