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