commit - 0d7a38c4ce99cf5367a242d0a1d41b51d4a742e8
commit + 9862b637c2aa97e7e8d148ae9c3f92d0ca758fa7
blob - ab19646ef28f0d0c0d7c5a4ab18e94d2353629cc
blob + 13d49e238fe9957f5d2580fda736d3f50e949676
--- gmid.c
+++ gmid.c
}
void
-handle(struct pollfd *fds, struct client *client)
+handle_handshake(struct pollfd *fds, struct client *c)
{
+ switch (tls_handshake(c->ctx)) {
+ case 0: /* success */
+ case -1: /* already handshaked */
+ break;
+ case TLS_WANT_POLLIN:
+ fds->events = POLLIN;
+ return;
+ case TLS_WANT_POLLOUT:
+ fds->events = POLLOUT;
+ return;
+ default:
+ /* unreachable */
+ abort();
+ }
+
+ /* TODO: check SNI here */
+ logs(LOG_DEBUG, c, "client wanted to talk to: %s", tls_conn_servername(c->ctx));
+
+ c->state = S_OPEN;
+ handle_open_conn(fds, c);
+}
+
+void
+handle_open_conn(struct pollfd *fds, struct client *c)
+{
char buf[GEMINI_URL_LEN];
- const char *parse_err;
+ const char *parse_err = "invalid request";
struct iri iri;
- switch (client->state) {
- case S_OPEN:
- bzero(buf, GEMINI_URL_LEN);
- switch (tls_read(client->ctx, buf, sizeof(buf)-1)) {
- case -1:
- LOGE(client, "tls_read: %s", tls_error(client->ctx));
- goodbye(fds, client);
+ bzero(buf, sizeof(buf));
+
+ switch (tls_read(c->ctx, buf, sizeof(buf)-1)) {
+ case -1:
+ LOGE(c, "tls_read: %s", tls_error(c->ctx));
+ goodbye(fds, c);
+ return;
+
+ case TLS_WANT_POLLIN:
+ fds->events = POLLIN;
+ return;
+
+ case TLS_WANT_POLLOUT:
+ fds->events = POLLOUT;
+ return;
+ }
+
+ if (!trim_req_iri(buf) || !parse_iri(buf, &iri, &parse_err)) {
+ if (!start_reply(fds, c, BAD_REQUEST, parse_err))
return;
+ goodbye(fds, c);
+ return;
+ }
- case TLS_WANT_POLLIN:
- fds->events = POLLIN;
+ if (strcmp(iri.schema, "gemini")) {
+ if (!start_reply(fds, c, PROXY_REFUSED, "won't proxy request"))
return;
+ goodbye(fds, c);
+ return;
+ }
- case TLS_WANT_POLLOUT:
- fds->events = POLLOUT;
- return;
- }
+ LOGI(c, "GET %s%s%s",
+ *iri.path ? iri.path : "/",
+ *iri.query ? "?" : "",
+ *iri.query ? iri.query : "");
- parse_err = "invalid request";
- if (!trim_req_iri(buf) || !parse_iri(buf, &iri, &parse_err)) {
- if (!start_reply(fds, client, BAD_REQUEST, parse_err))
- return;
- goodbye(fds, client);
- return;
- }
+ send_file(iri.path, iri.query, fds, c);
+}
- if (strcmp(iri.schema, "gemini")) {
- if (!start_reply(fds, client, PROXY_REFUSED, "won't proxy request"))
- return;
- goodbye(fds, client);
- return;
- }
-
- LOGI(client, "GET %s%s%s",
- *iri.path ? iri.path : "/",
- *iri.query ? "?" : "",
- *iri.query ? iri.query : "");
+void
+handle(struct pollfd *fds, struct client *client)
+{
+ switch (client->state) {
+ case S_HANDSHAKE:
+ handle_handshake(fds, client);
+ break;
- send_file(iri.path, iri.query, fds, client);
+ case S_OPEN:
+ handle_open_conn(fds, client);
break;
case S_INITIALIZING:
fds[i].fd = fd;
fds[i].events = POLLIN;
- clients[i].state = S_OPEN;
+ clients[i].state = S_HANDSHAKE;
clients[i].fd = -1;
clients[i].child = -1;
clients[i].buf = MAP_FAILED;
blob - e145d1a626088989b5738e140f7480da9c5fac93
blob + 570d38cc4b4fc4d38bcdf32cd7af64ceed755f42
--- gmid.h
+++ gmid.h
#define MAX_USERS 64
enum {
+ S_HANDSHAKE,
S_OPEN,
S_INITIALIZING,
S_SENDING,
void handle_cgi(struct pollfd*, struct client*);
void send_file(char*, char*, struct pollfd*, struct client*);
void send_dir(char*, struct pollfd*, struct client*);
+void handle_handshake(struct pollfd*, struct client*);
+void handle_open_conn(struct pollfd*, struct client*);
void handle(struct pollfd*, struct client*);
void mark_nonblock(int);