Commit Diff


commit - /dev/null
commit + cc2b348eaea87e36e2b205b338c1ab70d8fda2ef
blob - /dev/null
blob + 20d4bcef726a4cbf96ffbb605738e9ba4a899377 (mode 644)
--- /dev/null
+++ LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2026 Onana Onana Xavier Manuel <xavier@onana.net>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
blob - /dev/null
blob + 040e018e2da9ed09bfbc0c8342a9dd1dd53f5a9b (mode 644)
--- /dev/null
+++ Makefile
@@ -0,0 +1,17 @@
+BIN=		o3w
+SRCS=		o3w.c \
+			http.c
+OBJS=		${SRCS:.c=.o}
+CFLAGS=		-O0 -Werror
+LIBS=		-lpthread
+
+all: ${BIN}
+
+${BIN}: ${OBJS}
+	${CC} ${OBJS} -o ${BIN} ${LIBS}
+
+.c.o:
+	${CC} -c $< -o $@ ${CFLAGS}
+
+clean:
+	rm -rf ${BIN} ${BIN}.core ${OBJS}
blob - /dev/null
blob + 4f34edf0dbff6607f1c1f40f37ac63e9a81d5241 (mode 644)
--- /dev/null
+++ README
@@ -0,0 +1,6 @@
+o3w - Open Word Wide Web
+
+The goal is to create an HTTP/1.1 web browser with very
+little dependencies on OpenBSD.
+
+Lets see how this goes :^)
blob - /dev/null
blob + 2271d674510b37ef603c108814ef67514f620dc0 (mode 644)
--- /dev/null
+++ http.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include "http.h"
+
+struct http_hdl {
+	char *host;
+	int sockfd;
+	int secure;
+};
+
+struct http_hdl*
+http_connect(const char *host, const char *http_port)
+{
+	int error;
+	struct http_hdl *hdl;
+	struct addrinfo *res, *res0;
+	struct addrinfo hints;
+	const char *port = http_port;
+
+
+	hdl = calloc(1, sizeof(*hdl));
+	if (hdl == NULL) {
+		freeaddrinfo(res0);
+		return NULL;
+	}
+
+	if (strcmp(port, HTTP_UNSAFE) == 0) {
+		hdl->secure = 0;
+	} else if (strcmp(port, HTTP_SECURE) == 0) {
+		hdl->secure = 1;
+	} else {
+		free(hdl);
+		return NULL;
+	}
+
+	hdl->host = malloc(strlen(host) + 1);
+	if (hdl->host == NULL) {
+		free(hdl);
+		return NULL;
+	}
+
+	strlcpy(hdl->host, host, 1024);
+	hdl->host[strlen(host)] = '\0';
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_PASSIVE;
+	error = getaddrinfo(host, port, &hints, &res0);
+	if (error)
+		return NULL;
+
+
+	for (res = res0; res; res = res->ai_next) {
+		hdl->sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (hdl->sockfd == -1)
+			continue;
+
+		if (connect(hdl->sockfd, res->ai_addr, res->ai_addrlen) == -1) {
+			close(hdl->sockfd);
+			continue;
+		}
+		break;
+	}
+
+	if (hdl->sockfd == -1)
+		return NULL;
+
+	freeaddrinfo(res0);
+
+	return hdl;
+}
+
+void
+http_disconnect(struct http_hdl *hdl)
+{
+	close(hdl->sockfd);
+	free(hdl);
+}
+
+/*
+ * This send the HTTP request to the Host. You gotta make sure 
+ * there's a Host header before sending.
+ */
+void
+http_send(struct http_hdl *hdl)
+{
+
+}
+
+void
+http_recv(struct http_hdl *hdl)
+{
+
+}
+
+void
+http_add_header(struct http_hdl *hdl, const char *key, const char *value)
+{
+
+}
+
+/*
+ * HTTP client should send a host header field
+ * i.e:
+ * 	Host: www.example.com
+ */
+
+int
+http_GET(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_HEAD(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_POST(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_PUT(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_DELETE(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_CONNECT(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_OPTIONS(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
+
+int
+http_TRACE(struct http_hdl *hdl, const char *target)
+{
+	return 0;
+}
blob - /dev/null
blob + f64c03f39e3c41f6f39c9e141121ac5ba4bd74b0 (mode 644)
--- /dev/null
+++ http.h
@@ -0,0 +1,12 @@
+#ifndef HTTP_H
+#define HTTP_H
+
+#define HTTP_UNSAFE		"80"
+#define HTTP_SECURE		"443"
+
+struct http_hdl;
+
+struct http_hdl *http_connect(const char *, const char *);
+void http_disconnect(struct http_hdl *);
+
+#endif
blob - /dev/null
blob + f91e7e0e8e0f7e1cac579e6f9928ada8962f2e8b (mode 644)
--- /dev/null
+++ o3w.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "http.h"
+
+void usage(void);
+
+int
+main(int argc, char **argv)
+{
+	struct http_hdl *hdl;
+	const char *hostname;
+
+	if (argc < 2)
+		usage();
+
+	argc -= optind;
+	argv += optind;
+
+	hostname = *argv;
+	hdl = http_connect(hostname, HTTP_UNSAFE);
+	if (hdl == NULL) {
+		fprintf(stderr, "o3w: failed to connect to host `%s`\n", hostname);
+		return -1;
+	}
+
+	http_disconnect(hdl);
+	return 0;
+}
+
+void
+usage()
+{
+	fprintf(stderr, "o3w: usage hostname\n");
+	exit(1);
+}