aboutsummaryrefslogtreecommitdiff
path: root/src/molerat/url.c
diff options
context:
space:
mode:
authorShav Kinderlehrer <[email protected]>2024-07-23 17:48:28 -0400
committerShav Kinderlehrer <[email protected]>2024-07-23 17:48:28 -0400
commitdc0f2ce9ba97ebb47e05b80a511da6eb29818b63 (patch)
treedc83035069f5a015047be1ca3da6f65781eb4695 /src/molerat/url.c
parentf638f4bd1e3a03bc2bdd5f9dcd57d4830fd3c553 (diff)
downloadmolehole-dc0f2ce9ba97ebb47e05b80a511da6eb29818b63.tar.gz
molehole-dc0f2ce9ba97ebb47e05b80a511da6eb29818b63.zip
Merge old-moleholencurses
Diffstat (limited to 'src/molerat/url.c')
-rwxr-xr-xsrc/molerat/url.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/molerat/url.c b/src/molerat/url.c
new file mode 100755
index 0000000..0fd99ea
--- /dev/null
+++ b/src/molerat/url.c
@@ -0,0 +1,181 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "url.h"
+
+#define SET_STR(segment) \
+ (segment) = malloc(i - start + 1); \
+ strncpy((segment), s + start, i - start);
+
+#define MOVE(amount) \
+ i += (amount); \
+ start = i;
+
+#define SET_AT_END(segment) \
+ if (cur == '\0') { \
+ state = END; \
+ if (i - 1 > start) { \
+ SET_STR(segment); \
+ } \
+ }
+
+enum state { SCHEME, HOST, PORT, PATH, QUERY, FRAGMENT, END };
+
+int parse_url(struct url *url, char *s) {
+ int i = 0; // index into *s
+ int start = 0; // index of current mode start
+ enum state state = SCHEME;
+ char cur;
+
+ while (i < MAX_URL_LENGTH) {
+ cur = s[i];
+
+ if (cur == ' ')
+ return INVALID_CHARACTER;
+
+ switch (state) {
+ case SCHEME:
+ if (cur == ':') {
+ state = HOST;
+ SET_STR(url->scheme);
+
+ MOVE(3); // skip the '://'
+ }
+ SET_AT_END(url->scheme);
+ break;
+
+ case HOST:
+ if (cur == ':') {
+ state = PORT;
+ SET_STR(url->host);
+
+ MOVE(1);
+ }
+
+ if (cur == '/') {
+ state = PATH;
+ SET_STR(url->host);
+
+ MOVE(0);
+ }
+ SET_AT_END(url->host);
+ break;
+
+ case PORT:
+ if (cur == '/') {
+ state = PATH;
+ char *port;
+ SET_STR(port);
+
+ url->port = atoi(port);
+
+ MOVE(0);
+ }
+ if (cur == '\0') {
+ state = END;
+
+ char *port;
+ SET_STR(port);
+
+ url->port = atoi(port);
+ }
+
+ break;
+
+ case PATH:
+ if (cur == '?') {
+ state = QUERY;
+ SET_STR(url->path);
+
+ MOVE(0);
+ }
+
+ if (cur == '#') {
+ state = FRAGMENT;
+ SET_STR(url->path);
+
+ MOVE(0);
+ }
+ SET_AT_END(url->path);
+ break;
+
+ case QUERY:
+ if (cur == '#') {
+ state = FRAGMENT;
+ SET_STR(url->query);
+
+ MOVE(0);
+ }
+ SET_AT_END(url->query);
+ break;
+
+ case FRAGMENT:
+ if (cur == '\0') {
+ state = END;
+ SET_STR(url->fragment);
+
+ MOVE(0);
+ }
+ break;
+
+ case END:
+ break;
+ }
+
+ i++;
+
+ if (cur == '\0')
+ break;
+ if (state == END)
+ break;
+ }
+
+ if (url->host == NULL)
+ return MISSING_HOST;
+ if (url->port == 0)
+ return MISSING_PORT;
+
+ if (url->path == NULL) {
+ url->path = malloc(2);
+ strcpy(url->path, "/");
+ }
+
+ return 0;
+}
+
+struct url *init_url(void) {
+ struct url *url = malloc(sizeof(struct url));
+
+ url->scheme = NULL;
+ url->host = NULL;
+ url->port = 2693;
+
+ url->path = NULL;
+
+ url->query = NULL;
+ url->fragment = NULL;
+
+ return url;
+}
+
+void free_url(struct url *url) {
+ free(url->scheme);
+ free(url->host);
+ free(url->path);
+ free(url->fragment);
+ free(url->query);
+ free(url);
+}
+
+int len_url(struct url *url) {
+ int len = 0;
+
+ len += url->scheme != NULL ? strlen(url->scheme) : 0;
+ len += url->host != NULL ? strlen(url->host) : 0;
+ len += sizeof(url->port);
+ len += url->path != NULL ? strlen(url->path) : 0;
+ len += url->query != NULL ? strlen(url->query) : 0;
+ len += url->fragment != NULL ? strlen(url->fragment) : 0;
+
+ return len;
+}