~ft/gemnine

578fad97c2a3599aec2ac4085fed2430e3c2bbc8 — Sigrid Haflínudóttir 2 months ago d15bc69
status codes etc
3 files changed, 81 insertions(+), 53 deletions(-)

M gemnine.h
M main.c
M req.c
M gemnine.h => gemnine.h +24 -1
@@ 1,3 1,24 @@
enum {
	Cinput = 10,
	Cinputnoecho = 11,
	Csuccess = 20,
	Credirtmp = 30,
	Credirperm = 31,
	Cfailtmp = 40,
	Cunavail = 41,
	Ccgierr = 42,
	Cproxyerr = 43,
	Cslowdown = 44,
	Cfailperm = 50,
	Cnotfound = 51,
	Cgone = 52,
	Cnoproxy = 53,
	Cbadrequest = 59,
	Ccertrequired = 60,
	Ccertnotauth = 61,
	Ccertinvalid = 62,
};

typedef struct Response Response;
typedef struct Url Url;



@@ 5,7 26,9 @@ struct Response {
	Url *url;
	char *mime;
	char *prompt;
	int status;
	char *meta;
	char *status;
	int code;
	int fd;
};


M main.c => main.c +15 -30
@@ 5,29 5,6 @@
#include <ctype.h>
#include "gemnine.h"

char *
readall(int fd)
{
	char *s;
	int n, sz, bufsz;

	bufsz = 1023;
	s = nil;
	for(sz = 0;; sz += n){
		if(bufsz-sz < 1024){
			bufsz *= 2;
			s = realloc(s, bufsz);
		}
		if((n = read(fd, s+sz, bufsz-sz-1)) < 1)
			break;
	}
	s[sz] = 0;
	if(sz > 1 && s[sz-1] == '\n')
		s[sz-1] = 0;

	return s;
}

void
page(Response *r)
{


@@ 125,13 102,20 @@ nextreq:
			if((fd = open("/dev/consctl", OWRITE)) >= 0){
				write(fd, "holdon", 6);
				print("%s\n", r->prompt);
				s = readall(0);
				free(url);
				t = smprint("%s?%E", r->url->full, (Str2){s, "/:@ \n"});
				Binit(&body, 0, OREAD);
				t = nil;
				if((s = Brdstr(&body, 0, 1)) != nil)
					t = smprint("%s?%E", r->url->full, (Str2){s, "/:@ \n"});
				Bterm(&body);
				free(s);
				url = urlparse(nil, t);
				free(t);
				freeresponse(r);
				if(t != nil){
					freeurl(url);
					url = urlparse(nil, t);
					free(t);
					freeresponse(r);
				}else{
					fprint(2, "%r\n");
				}
				close(fd);
				goto nextreq;
			}else{


@@ 162,10 146,11 @@ nextreq:
				}
				free(s);
			}
			Bterm(&body);
		}
		freeresponse(r);
	}else{
		fprint(2, "%r\n");
		fprint(2, "%U: %r\n", url);
		if(!wait)
			exits("failed");
	}

M req.c => req.c +42 -22
@@ 4,6 4,27 @@
#include <ctype.h>
#include "gemnine.h"

static char *statuses[] = {
	[Cinput] = "input",
	[Cinputnoecho] = "sensitive input",
	[Csuccess] = "success",
	[Credirtmp] = "redirect - temporary",
	[Credirperm] = "redirect - permanent",
	[Cfailtmp] = "temporary failure",
	[Cunavail] = "server unavailable",
	[Ccgierr] = "cgi error",
	[Cproxyerr] = "proxy error",
	[Cslowdown] = "slow down",
	[Cfailperm] = "permanent failure",
	[Cnotfound] = "not found",
	[Cgone] = "gone",
	[Cnoproxy] = "proxy request refused",
	[Cbadrequest] = "bad request",
	[Ccertrequired] = "client certificate required",
	[Ccertnotauth] = "certificate not authorized",
	[Ccertinvalid] = "certificate not valid",
};

Response *
request(Url *url)
{


@@ 65,39 86,37 @@ request(Url *url)
		werrstr("invalid status");
		goto err;
	}
	r->status = 10*(int)(s[0]-'0') + s[1] - '0';
	r->code = 10*(int)(s[0]-'0') + s[1] - '0';
	s += 2;
	while(isspace(*s))
		s++;

	if(r->status >= 10 && r->status < 20){ /* input */
	if(r->code < nelem(statuses))
		r->status = statuses[r->code];
	if(r->status == nil)
		r->status = "???";

	if(r->code >= 10 && r->code < 20){ /* input */
		r->prompt = estrdup(s);
	}else if(r->status >= 20 && r->status < 30){ /* success */
	}else if(r->code >= 20 && r->code < 30){ /* success */
		r->mime = estrdup(s[0] ? s : "text/gemini");
	}else if(r->status >= 30 && r->status < 40){ /* redirect */
	}else if(r->code >= 30 && r->code < 40){ /* redirect */
		if((u = urlparse(r->url, s)) == nil){
			werrstr("invalid redirect url");
			werrstr("invalid redirect");
			goto err;
		}
		freeresponse(r);
		if((r = request(u)) == nil)
			freeurl(u);
	}else if(r->status >= 40 && r->status < 50){
		werrstr("temporary failure: %s", s);
		goto err;
	}else if(r->status >= 50 && r->status < 60){
		werrstr("permanent failure: %s", s);
		goto err;
	}else if(r->status >= 60 && r->status < 70){
		werrstr("client cert required: %s", s);
	}else{
		r->meta = estrdup(s);
		werrstr(r->status);
		goto err;
	}

	return r;

err:
	if(r != nil && r->url != nil)
		werrstr("%U: %r", r->url);
	freeresponse(r);
	return nil;
}


@@ 105,11 124,12 @@ err:
void
freeresponse(Response *r)
{
	if(r != nil){
		close(r->fd);
		freeurl(r->url);
		free(r->mime);
		free(r->prompt);
		free(r);
	}
	if(r == nil)
		return;
	close(r->fd);
	freeurl(r->url);
	free(r->mime);
	free(r->prompt);
	free(r->meta);
	free(r);
}