commit cc2b348eaea87e36e2b205b338c1ab70d8fda2ef from: xavier date: Mon Jul 27 04:43:45 2026 UTC First commit 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 + +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 +#include +#include +#include + +#include +#include +#include + +#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 +#include +#include + +#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); +}