ref: fd7780e65a6516f7cf68ca14a21eee0f32e40704
dir: /http.c/
#include <u.h> #include <libc.h> #include <stdio.h> #include <json.h> #include "masto9.h" #define BOUNDARY "--------HJBOUNDARY" int webclone(int *c) { char buf[128]; int n, fd; if((fd = open("/mnt/web/clone", ORDWR)) < 0) sysfatal("webclone: couldn't open %s: %r", buf); if((n = read(fd, buf, sizeof buf - 1)) < 0) sysfatal("webclone: reading clone: %r"); if(n == 0) sysfatal("webclone: short read on clone"); buf[n] = '\0'; *c = atoi(buf); return fd; } char * httpget(char *token, char *url) { int ctlfd, bodyfd, conn, n; char buf[1024]; char body[TLBUFSIZE]; char *bearer_token; ctlfd = webclone(&conn); snprint(buf, sizeof buf, "url %s", url); if(write(ctlfd, buf, n = strlen(buf)) != n) sysfatal("httpget: write url: %r"); /* Request */ bearer_token = esmprint("Authorization: Bearer %s", token); if(fprint(ctlfd, "headers %s", bearer_token) <= 0) sysfatal("httpget: write headers: %r"); snprint(buf, sizeof(buf), "/mnt/web/%d/body", conn); /* Response */ if((bodyfd = open(buf, OREAD)) < 0) sysfatal("httpget: open %s: %r", buf); if(readn(bodyfd, body, TLBUFSIZE) <= 0) sysfatal("httpget: readn: %r"); close(bodyfd); close(ctlfd); return body; } char * httppost(char *token, char *url, char *text) { int n, ctlfd, bodyfd, conn; char buf[TOOTBUFSIZE]; char *bearer_token; ctlfd = webclone(&conn); snprint(buf, sizeof buf, "url %s", url); if(write(ctlfd, buf, n = strlen(buf)) != n) sysfatal("httppost: write url: %r"); /* Request */ bearer_token = esmprint("Authorization: Bearer %s", token); if(fprint(ctlfd, "headers %s", bearer_token) <= 0) sysfatal("httppost: write headers: %r"); snprint(buf, TOOTBUFSIZE, "/mnt/web/%d/postbody", conn); if((bodyfd = open(buf, OWRITE)) < 0) sysfatal("httppost: open %s: %r", buf); if(write(bodyfd, text, strlen(text)) < 0) sysfatal("httppost: write: %r"); close(bodyfd); /* Response */ snprint(buf, TOOTBUFSIZE, "/mnt/web/%d/body", conn); if((bodyfd = open(buf, OREAD)) < 0) sysfatal("httppost: open %s: %r", buf); if(readn(bodyfd, buf, TOOTBUFSIZE) <= 0) sysfatal("httppost: readn: %r"); close(bodyfd); close(ctlfd); return buf; } char * mime_type(char *filename) { char *ext = strrchr(filename, '.'); if(!ext) return "application/octet-stream"; if(strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) return "image/jpeg"; if(strcmp(ext, ".gif") == 0) return "image/gif"; if(strcmp(ext, ".png") == 0) return "image/png"; if(strcmp(ext, ".mp3") == 0) return "audio/mp3"; if(strcmp(ext, ".mp4") == 0) return "video/mp4"; if(strcmp(ext, ".webm") == 0) return "video/webm"; return "application/octet-stream"; } char * upload(char *token, char *url, char *filepath) { char buf[BUFSIZE]; int n, conn, ctlfd, bodyfd; char *bearer_token, *multipart_header; FileAttachment *fa; if((ctlfd = open("/mnt/web/clone", ORDWR)) < 0) sysfatal("upload: open: %r"); if((n = read(ctlfd, buf, sizeof(buf))) < 0) sysfatal("upload: read: %r"); buf[n] = '\0'; conn = atoi(buf); fa = readfile(filepath); snprint(buf, sizeof buf, "url %s", url); if(write(ctlfd, buf, n = strlen(buf)) != n) sysfatal("upload: write: %r"); bearer_token = esmprint("Authorization: Bearer %s", token); snprint(buf, sizeof buf, "headers %s", bearer_token); if(write(ctlfd, buf, n = strlen(buf)) != n) sysfatal("upload: write headers: %r"); snprint(buf, sizeof buf, "contenttype multipart/form-data; boundary=%s", BOUNDARY); if(write(ctlfd, buf, n = strlen(buf)) != n) sysfatal("upload: write contenttype: %r"); snprint(buf, sizeof buf, "/mnt/web/%d/postbody", conn); if((bodyfd = open(buf, OWRITE)) < 0) sysfatal("upload: open %s: %r", buf); /* Write multipart body */ write(bodyfd, "--", 2); write(bodyfd, BOUNDARY, strlen(BOUNDARY)); write(bodyfd, "\r\n", 2); multipart_header = esmprint("Content-Disposition: form-data; \ name=\"file\"; \ filename=\"blob\"\r\nContent-Type: %s\r\n\r\n", mime_type(basename(filepath))); write(bodyfd, multipart_header, strlen(multipart_header)); write(bodyfd, fa->buf, fa->size); write(bodyfd, "\r\n", 2); write(bodyfd, "--", 2); write(bodyfd, BOUNDARY, strlen(BOUNDARY)); write(bodyfd, "--\r\n", 4); close(bodyfd); /* Response */ snprint(buf, sizeof buf, "/mnt/web/%d/body", conn); if((bodyfd = open(buf, OREAD)) < 0) sysfatal("upload: open %s: %r", buf); if(readn(bodyfd, buf, BUFSIZE) <= 0) sysfatal("upload: readn: %r"); close(bodyfd); close(ctlfd); return buf; }