shithub: masto9

ref: 22b180670881db7c4850e7fd9786ffcb70498057
dir: /http.c/

View raw version
#include <u.h>
#include <libc.h>
#include <stdio.h>
#include <json.h>
#include <bio.h>

#include "masto9.h"

#define BOUNDARY "---------------------------328018649918767126933410246249"

int
webclone(int *c)
{
	char buf[128];
	int n, fd;

	if((fd = open("/mnt/web/clone", ORDWR)) < 0)
		sysfatal("couldn't open %s: %r", buf);
	if((n = read(fd, buf, sizeof buf-1)) < 0)
		sysfatal("reading clone: %r");
	if(n == 0)
		sysfatal("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("post: write: %r");

  /* Request */
  bearer_token = concat("Authorization: Bearer ", token);
	if (fprint(ctlfd, "headers %s", bearer_token) <= 0)
		sysfatal("write ctl failed 'headers'");

	snprint(buf, sizeof(buf), "/mnt/web/%d/body", conn);

  /* Response */
	if ((bodyfd = open(buf, OREAD)) < 0)
		sysfatal("open %s: %r", buf);
	if (readn(bodyfd, body, TLBUFSIZE) <= 0)
		sysfatal("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("post: write: %r");

  /* Request */
  bearer_token = concat("Authorization: Bearer ", token);
	if (fprint(ctlfd, "headers %s", bearer_token) <= 0)
		sysfatal("write ctl failed 'headers'");

	snprint(buf, TOOTBUFSIZE, "/mnt/web/%d/postbody", conn);
	bodyfd = open(buf, OWRITE);
	if (bodyfd < 0)
		sysfatal("open bodyfd %s: %r", buf);

  if (write(bodyfd, text, strlen(text)) < 0)
    sysfatal("write: %r");

	close(bodyfd);

  /* Response */
  snprint(buf, TOOTBUFSIZE, "/mnt/web/%d/body", conn);
	if((bodyfd = open(buf, OREAD)) < 0)
		sysfatal("post: opening body: %r");
	if (readn(bodyfd, buf, TOOTBUFSIZE) <= 0)
		sysfatal("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;

	ctlfd = open("/mnt/web/clone", ORDWR);
	if (ctlfd < 0)
		sysfatal("open: %r");
	n = read(ctlfd, buf, sizeof(buf));
	if (n < 0)
		sysfatal("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("post: 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("post: write headers: %r");
	snprint(buf, sizeof buf, "contenttype multipart/form-data; boundary=%s", BOUNDARY);
	if(write(ctlfd, buf, n = strlen(buf)) != n)
		sysfatal("post: write contenttype: %r");

  snprint(buf, sizeof buf, "/mnt/web/%d/postbody", conn);
	if ((bodyfd = open(buf, OWRITE)) < 0)
		sysfatal("open bodyfd %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("post: opening body: %r");
	if (readn(bodyfd, buf, BUFSIZE) <= 0)
		sysfatal("readn: %r");

	close(bodyfd);
	close(ctlfd);

  return buf;
}