ref: 578fad97c2a3599aec2ac4085fed2430e3c2bbc8
parent: d15bc694dff1248ac67740c75c299c80e0779e8a
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Mon Aug 24 09:23:26 EDT 2020
status codes etc
--- a/gemnine.h
+++ b/gemnine.h
@@ -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 @@
Url *url;
char *mime;
char *prompt;
- int status;
+ char *meta;
+ char *status;
+ int code;
int fd;
};
--- a/main.c
+++ b/main.c
@@ -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 @@
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 @@
}
free(s);
}
+ Bterm(&body);
}
freeresponse(r);
}else{
- fprint(2, "%r\n");
+ fprint(2, "%U: %r\n", url);
if(!wait)
exits("failed");
}
--- a/req.c
+++ b/req.c
@@ -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 @@
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);
+ }else{
+ r->meta = estrdup(s);
+ werrstr(r->status);
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);
- goto err;
}
return r;
err:
- if(r != nil && r->url != nil)
- werrstr("%U: %r", r->url);
freeresponse(r);
return nil;
}
@@ -105,11 +124,12 @@
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);
}