shithub: masto9

ref: 494b0cda3dad99e3e1076acea474cf5b19b0c1d8
dir: masto9/http.c

View raw version
#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;
}