From efc0780d866ae0590621b0d50bc413a517043bcd Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 25 May 2012 10:52:10 +0200 Subject: [PATCH] mothra: changes toward multipart/formdata --- sys/src/cmd/mothra/forms.c | 8 +- sys/src/cmd/mothra/getpix.c | 2 +- sys/src/cmd/mothra/mkfile | 1 + sys/src/cmd/mothra/mothra.c | 136 ++++---------------------------- sys/src/cmd/mothra/mothra.h | 6 +- sys/src/cmd/mothra/url.c | 150 ++++++++++++++++++++++++++++++++++++ 6 files changed, 178 insertions(+), 125 deletions(-) create mode 100644 sys/src/cmd/mothra/url.c diff --git a/sys/src/cmd/mothra/forms.c b/sys/src/cmd/mothra/forms.c index febf1e8d3..b6b4f60d8 100644 --- a/sys/src/cmd/mothra/forms.c +++ b/sys/src/cmd/mothra/forms.c @@ -612,11 +612,15 @@ void h_submitinput(Panel *p, int){ } if(form->method==GET){ if(debug)fprint(2, "GET %s\n", buf); - geturl(buf, GET, 0, 0, 0); + geturl(buf, -1, 0, 0); } else{ + int post; + if(debug)fprint(2, "POST %s: %s\n", form->action, buf); - geturl(form->action, POST, buf, 0, 0); + if((post = urlpost(selurl(form->action), nil)) >= 0) + write(post, buf, strlen(buf)); + geturl(form->action, post, 0, 0); } free(buf); } diff --git a/sys/src/cmd/mothra/getpix.c b/sys/src/cmd/mothra/getpix.c index 5782b5fc8..762b69fb0 100644 --- a/sys/src/cmd/mothra/getpix.c +++ b/sys/src/cmd/mothra/getpix.c @@ -39,7 +39,7 @@ void getimage(Rtext *t, Www *w){ update(w); return; } - fd=urlopen(&url, GET, 0); + fd=urlget(&url, -1); if(fd==-1){ Err: snprint(err, sizeof(err), "[%s: %r]", url.fullname); diff --git a/sys/src/cmd/mothra/mkfile b/sys/src/cmd/mothra/mkfile index 5e1b57deb..3eb71e48a 100644 --- a/sys/src/cmd/mothra/mkfile +++ b/sys/src/cmd/mothra/mkfile @@ -9,6 +9,7 @@ CFILES= \ html.syntax.c \ mothra.c \ rdhtml.c \ + url.c \ OFILES=${CFILES:%.c=%.$O} version.$O HFILES=mothra.h html.h libpanel/panel.h libpanel/rtext.h diff --git a/sys/src/cmd/mothra/mothra.c b/sys/src/cmd/mothra/mothra.c index 5ffc74018..b44831d8f 100644 --- a/sys/src/cmd/mothra/mothra.c +++ b/sys/src/cmd/mothra/mothra.c @@ -71,7 +71,7 @@ Cursor mothcurs={ 0x37, 0xec, 0x17, 0xe8, 0x1b, 0xd8, 0x0e, 0x70, 0x0c, 0x30, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, } }; -char *mtpt="/mnt/web"; + Www *current=0; Url *selection=0; int logfile; @@ -81,7 +81,6 @@ int kickpipe[2]; void docmd(Panel *, char *); void doprev(Panel *, int, int); char *urlstr(Url *); -void selurl(char *); void setcurrent(int, char *); char *genwww(Panel *, int); void updtext(Www *); @@ -239,6 +238,7 @@ void donecurs(void){ } void scrollto(char *tag); +extern char *mtpt; /* url */ void main(int argc, char *argv[]){ Event e; @@ -318,7 +318,7 @@ void main(int argc, char *argv[]){ lockdisplay(display); if(url && url[0]) - geturl(url, GET, 0, 1, 0); + geturl(url, -1, 1, 0); if(logfile==-1) message("Can't open log file"); mouse.buttons=0; @@ -386,7 +386,7 @@ void main(int argc, char *argv[]){ case Eplumb: pm=e.v; if(pm->ndata > 0) - geturl(pm->data, GET, 0, 1, 0); + geturl(pm->data, -1, 1, 0); plumbfree(pm); break; } @@ -613,7 +613,7 @@ void docmd(Panel *p, char *s){ * Non-command does a get on the url */ if(s[0]!='\0' && s[1]!='\0' && s[1]!=' ') - geturl(s, GET, 0, 0, 0); + geturl(s, -1, 0, 0); else switch(c = s[0]){ default: message("Unknown command %s, type h for help", s); @@ -632,7 +632,7 @@ void docmd(Panel *p, char *s){ else message("no url selected"); } - geturl(s, GET, 0, 0, 0); + geturl(s, -1, 0, 0); break; case 'j': s = arg(s); @@ -670,7 +670,7 @@ void docmd(Panel *p, char *s){ break; s = buf; } - save(urlopen(selection, GET, 0), s); + save(urlget(selection, -1), s); break; case 'q': exits(0); @@ -678,13 +678,15 @@ void docmd(Panel *p, char *s){ plinitentry(cmd, EXPAND, 0, "", docmd); if(defdisplay) pldraw(cmd, screen); } + void hiturl(int buttons, char *url, int map){ switch(buttons){ - case 1: geturl(url, GET, 0, 0, map); break; + case 1: geturl(url, -1, 0, map); break; case 2: selurl(url); break; case 4: message("Button 3 hit on url can't happen!"); break; } } + /* * user selected from the list of available pages */ @@ -773,113 +775,6 @@ void freetext(Rtext *t){ plrtfree(tt); } -int fileurlopen(Url *url){ - char *rel, *base, *x; - int fd; - - rel = base = nil; - if(cistrncmp(url->basename, "file:", 5) == 0) - base = url->basename+5; - if(cistrncmp(url->reltext, "file:", 5) == 0) - rel = url->reltext+5; - if(rel == nil && base == nil) - return -1; - if(rel == nil) - rel = url->reltext; - if(base && base[0] == '/' && rel[0] != '/'){ - if(x = strrchr(base, '/')) - *x = 0; - snprint(url->fullname, sizeof(url->fullname), "%s/%s", base, rel); - if(x) *x = '/'; - }else - snprint(url->fullname, sizeof(url->fullname), "%s", rel); - url->tag[0] = 0; - if(x = strrchr(url->fullname, '#')){ - *x++ = 0; - nstrcpy(url->tag, x, sizeof(url->tag)); - } - fd = open(cleanname(url->fullname), OREAD); - if(fd < 0) - return -1; - memset(url->fullname, 0, sizeof(url->fullname)); - strcpy(url->fullname, "file:"); - fd2path(fd, url->fullname+5, sizeof(url->fullname)-6); - return fd; -} - -int readstr(char *buf, int nbuf, char *base, char *name){ - char path[128]; - int n, fd; - - n = 0; - snprint(path, sizeof path, "%s/%s", base, name); - if((fd = open(path, OREAD)) >= 0){ - if((n = read(fd, buf, nbuf-1)) < 0) - n = 0; - close(fd); - } - buf[n] = 0; - return n; -} - -int urlopen(Url *url, int method, char *body){ - int conn, ctlfd, fd, n; - char buf[1024+1], *p; - char encoding[64]; - - if(debug) fprint(2, "urlopen %s (%s)\n", url->reltext, url->basename); - - if(method == GET) - if((fd = fileurlopen(url)) >= 0) - return fd; - snprint(buf, sizeof buf, "%s/clone", mtpt); - if((ctlfd = open(buf, ORDWR)) < 0) - return -1; - if((n = read(ctlfd, buf, sizeof buf-1)) <= 0){ - close(ctlfd); - return -1; - } - buf[n] = 0; - conn = atoi(buf); - if(url->basename[0]){ - n = snprint(buf, sizeof buf, "baseurl %s", url->basename); - write(ctlfd, buf, n); - } - n = snprint(buf, sizeof buf, "url %s", url->reltext); - if(write(ctlfd, buf, n) != n){ - ErrOut: - close(ctlfd); - return -1; - } - if(method == POST && body){ - snprint(buf, sizeof buf, "%s/%d/postbody", mtpt, conn); - if((fd = open(buf, OWRITE)) < 0) - goto ErrOut; - n = strlen(body); - if(write(fd, body, n) != n){ - close(fd); - goto ErrOut; - } - close(fd); - } - snprint(buf, sizeof buf, "%s/%d/body", mtpt, conn); - if((fd = open(buf, OREAD)) < 0) - goto ErrOut; - snprint(buf, sizeof buf, "%s/%d/parsed", mtpt, conn); - readstr(url->fullname, sizeof(url->fullname), buf, "url"); - readstr(url->tag, sizeof(url->tag), buf, "fragment"); - snprint(buf, sizeof buf, "%s/%d", mtpt, conn); - readstr(encoding, sizeof(encoding), buf, "contentencoding"); - close(ctlfd); - if(!cistrcmp(encoding, "compress")) - fd = pipeline("/bin/uncompress", fd); - else if(!cistrcmp(encoding, "gzip")) - fd = pipeline("/bin/gunzip", fd); - else if(!cistrcmp(encoding, "bzip2")) - fd = pipeline("/bin/bunzip2", fd); - return fd; -} - int pipeline(char *cmd, int fd) { int pfd[2]; @@ -914,11 +809,12 @@ urlstr(Url *url){ return url->fullname; return url->reltext; } -void selurl(char *urlname){ +Url* selurl(char *urlname){ static Url url; seturl(&url, urlname, current ? current->url->fullname : ""); selection=&url; message("selected: %s", urlstr(selection)); + return selection; } void seturl(Url *url, char *urlname, char *base){ nstrcpy(url->reltext, urlname, sizeof(url->reltext)); @@ -940,13 +836,13 @@ void freeurl(Url *u){ /* * get the file at the given url */ -void geturl(char *urlname, int method, char *body, int plumb, int map){ +void geturl(char *urlname, int post, int plumb, int map){ int i, fd, typ, pfd[2]; char cmd[NNAME]; ulong n; Www *w; - if(*urlname == '#'){ + if(*urlname == '#' && post < 0){ scrollto(urlname+1); return; } @@ -957,7 +853,7 @@ void geturl(char *urlname, int method, char *body, int plumb, int map){ message("getting %s", selection->reltext); esetcursor(&patientcurs); for(;;){ - if((fd=urlopen(selection, method, body)) < 0){ + if((fd=urlget(selection, post)) < 0){ message("%r"); break; } @@ -1177,7 +1073,7 @@ void hit3(int button, int item){ break; case 5: snprint(name, sizeof(name), "file:%s/hit.html", home); - geturl(name, GET, 0, 1, 0); + geturl(name, -1, 1, 0); break; case 6: if(confirm(3)) diff --git a/sys/src/cmd/mothra/mothra.h b/sys/src/cmd/mothra/mothra.h index 230f91c32..697d4f309 100644 --- a/sys/src/cmd/mothra/mothra.h +++ b/sys/src/cmd/mothra/mothra.h @@ -83,11 +83,11 @@ void plrdhtml(char *, int, Www *); void plrdplain(char *, int, Www *); void htmlerror(char *, int, char *, ...); /* user-supplied routine */ void seturl(Url *, char *, char *); +Url *selurl(char *); void getpix(Rtext *, Www *); ulong countpix(void *p); void freepix(void *p); int pipeline(char *, int); -int urlopen(Url *, int, char *); void getfonts(void); void *emalloc(int); void *emallocz(int, int); @@ -96,5 +96,7 @@ void freeform(void *p); void message(char *, ...); int snooptype(int fd); void mkfieldpanel(Rtext *); -void geturl(char *, int, char *, int, int); +void geturl(char *, int, int, int); +int urlpost(Url*, char*); +int urlget(Url*, int); char version[]; diff --git a/sys/src/cmd/mothra/url.c b/sys/src/cmd/mothra/url.c new file mode 100644 index 000000000..9773f15e9 --- /dev/null +++ b/sys/src/cmd/mothra/url.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include "mothra.h" + +static int +fileget(Url *url) +{ + char *rel, *base, *x; + + rel = base = nil; + if(cistrncmp(url->basename, "file:", 5) == 0) + base = url->basename+5; + if(cistrncmp(url->reltext, "file:", 5) == 0) + rel = url->reltext+5; + if(rel == nil && base == nil) + return -1; + if(rel == nil) + rel = url->reltext; + if(base && base[0] == '/' && rel[0] != '/'){ + if(x = strrchr(base, '/')) + *x = 0; + snprint(url->fullname, sizeof(url->fullname), "%s/%s", base, rel); + if(x) *x = '/'; + }else + snprint(url->fullname, sizeof(url->fullname), "%s", rel); + url->tag[0] = 0; + if(x = strrchr(url->fullname, '#')){ + *x++ = 0; + nstrcpy(url->tag, x, sizeof(url->tag)); + } + base = cleanname(url->fullname); + x = base + strlen(base)+1; + if((x - base) > sizeof(url->fullname)-5) + return -1; + memmove(url->fullname+5, base, x - base); + memmove(url->fullname, "file:", 5); + return open(url->fullname+5, OREAD); +} + +char *mtpt="/mnt/web"; + +static int +webclone(Url *url, char *buf, int nbuf) +{ + int n, fd; + + snprint(buf, nbuf, "%s/clone", mtpt); + if((fd = open(buf, ORDWR)) < 0) + return -1; + if((n = read(fd, buf, nbuf-1)) <= 0){ + close(fd); + return -1; + } + buf[n] = 0; + n = atoi(buf); + snprint(buf, nbuf, "%s/%d", mtpt, n); + if(url && url->reltext[0]){ + if(url->basename[0]) + fprint(fd, "baseurl %s", url->basename); + if(fprint(fd, "url %s", url->reltext) < 0){ + close(fd); + return -1; + } + } + return fd; +} + +static int +readstr(char *path, char *buf, int nbuf){ + int n, fd; + + n = 0; + if((fd = open(path, OREAD)) >= 0){ + if((n = read(fd, buf, nbuf-1)) < 0) + n = 0; + close(fd); + } + buf[n] = 0; + return n; +} + +int +urlpost(Url *url, char *ctype) +{ + char buf[1024]; + int n, fd; + + if((fd = webclone(url, buf, sizeof(buf))) < 0) + return -1; + if(ctype && *ctype) + fprint(fd, "contenttype %s", ctype); + n = strlen(buf); + snprint(buf+n, sizeof(buf)-n, "/postbody"); + n = open(buf, OWRITE); + close(fd); + return n; +} + +int +urlget(Url *url, int body) +{ + char buf[1024]; + int n, fd; + + if(body < 0){ + if((fd = fileget(url)) >= 0) + return fd; + if((fd = webclone(url, buf, sizeof(buf))) < 0) + return -1; + }else{ + char *x; + + if(fd2path(body, buf, sizeof(buf))){ + close(body); + return -1; + } + if(x = strrchr(buf, '/')) + *x = 0; + fd = open(buf, OREAD); + close(body); + } + n = strlen(buf); + snprint(buf+n, sizeof(buf)-n, "/body"); + body = open(buf, OREAD); + close(fd); + fd = body; + if(fd < 0) + return -1; + + snprint(buf+n, sizeof(buf)-n, "/parsed/url"); + readstr(buf, url->fullname, sizeof(url->fullname)); + + snprint(buf+n, sizeof(buf)-n, "/parsed/fragment"); + readstr(buf, url->tag, sizeof(url->tag)); + + snprint(buf+n, sizeof(buf)-n, "/contentencoding"); + readstr(buf, buf, sizeof(buf)); + + if(!cistrcmp(buf, "compress")) + fd = pipeline("/bin/uncompress", fd); + else if(!cistrcmp(buf, "gzip")) + fd = pipeline("/bin/gunzip", fd); + else if(!cistrcmp(buf, "bzip2")) + fd = pipeline("/bin/bunzip2", fd); + + return fd; +}