mothra: changes toward multipart/formdata

This commit is contained in:
cinap_lenrek 2012-05-25 10:52:10 +02:00
parent 9f150d42a3
commit efc0780d86
6 changed files with 178 additions and 125 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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))

View file

@ -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[];

150
sys/src/cmd/mothra/url.c Normal file
View file

@ -0,0 +1,150 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <panel.h>
#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;
}