summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/lib/load_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/lib/load_http.c')
-rw-r--r--contrib/ipfilter/lib/load_http.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/contrib/ipfilter/lib/load_http.c b/contrib/ipfilter/lib/load_http.c
new file mode 100644
index 0000000..164b8b4
--- /dev/null
+++ b/contrib/ipfilter/lib/load_http.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2006 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ *
+ * $Id: load_http.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $
+ */
+
+#include "ipf.h"
+
+/*
+ * Format expected is one addres per line, at the start of each line.
+ */
+alist_t *
+load_http(char *url)
+{
+ int fd, len, left, port, endhdr, removed;
+ char *s, *t, *u, buffer[1024], *myurl;
+ alist_t *a, *rtop, *rbot;
+ struct sockaddr_in sin;
+ struct hostent *host;
+
+ /*
+ * More than this would just be absurd.
+ */
+ if (strlen(url) > 512) {
+ fprintf(stderr, "load_http has a URL > 512 bytes?!\n");
+ return NULL;
+ }
+
+ fd = -1;
+ rtop = NULL;
+ rbot = NULL;
+
+ sprintf(buffer, "GET %s HTTP/1.0\r\n", url);
+
+ myurl = strdup(url);
+ if (myurl == NULL)
+ goto done;
+
+ s = myurl + 7; /* http:// */
+ t = strchr(s, '/');
+ if (t == NULL) {
+ fprintf(stderr, "load_http has a malformed URL '%s'\n", url);
+ free(myurl);
+ return NULL;
+ }
+ *t++ = '\0';
+
+ u = strchr(s, '@');
+ if (u != NULL)
+ s = u + 1; /* AUTH */
+
+ sprintf(buffer + strlen(buffer), "Host: %s\r\n\r\n", s);
+
+ u = strchr(s, ':');
+ if (u != NULL) {
+ *u++ = '\0';
+ port = atoi(u);
+ if (port < 0 || port > 65535)
+ goto done;
+ } else {
+ port = 80;
+ }
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+
+ if (isdigit(*s)) {
+ if (inet_aton(s, &sin.sin_addr) == -1) {
+ goto done;
+ }
+ } else {
+ host = gethostbyname(s);
+ if (host == NULL)
+ goto done;
+ memcpy(&sin.sin_addr, host->h_addr_list[0],
+ sizeof(sin.sin_addr));
+ }
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1)
+ goto done;
+
+ if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ close(fd);
+ goto done;
+ }
+
+ len = strlen(buffer);
+ if (write(fd, buffer, len) != len) {
+ close(fd);
+ goto done;
+ }
+
+ s = buffer;
+ endhdr = 0;
+ left = sizeof(buffer) - 1;
+
+ while ((len = read(fd, s, left)) > 0) {
+ s[len] = '\0';
+ left -= len;
+ s += len;
+
+ if (endhdr >= 0) {
+ if (endhdr == 0) {
+ t = strchr(buffer, ' ');
+ if (t == NULL)
+ continue;
+ t++;
+ if (*t != '2')
+ break;
+ }
+
+ u = buffer;
+ while ((t = strchr(u, '\r')) != NULL) {
+ if (t == u) {
+ if (*(t + 1) == '\n') {
+ u = t + 2;
+ endhdr = -1;
+ break;
+ } else
+ t++;
+ } else if (*(t + 1) == '\n') {
+ endhdr++;
+ u = t + 2;
+ } else
+ u = t + 1;
+ }
+ if (endhdr >= 0)
+ continue;
+ removed = (u - buffer) + 1;
+ memmove(buffer, u, (sizeof(buffer) - left) - removed);
+ s -= removed;
+ left += removed;
+ }
+
+ do {
+ t = strchr(buffer, '\n');
+ if (t == NULL)
+ break;
+
+ *t++ = '\0';
+ for (u = buffer; isdigit(*u) || (*u == '.'); u++)
+ ;
+ if (*u == '/') {
+ char *slash;
+
+ slash = u;
+ u++;
+ while (isdigit(*u))
+ u++;
+ if (!isspace(*u) && *u)
+ u = slash;
+ }
+ *u = '\0';
+
+ a = alist_new(4, buffer);
+ if (a != NULL) {
+ if (rbot != NULL)
+ rbot->al_next = a;
+ else
+ rtop = a;
+ rbot = a;
+ }
+
+ removed = t - buffer;
+ memmove(buffer, t, sizeof(buffer) - left - removed);
+ s -= removed;
+ left += removed;
+
+ } while (1);
+ }
+
+done:
+ if (myurl != NULL)
+ free(myurl);
+ if (fd != -1)
+ close(fd);
+ return rtop;
+}
OpenPOWER on IntegriCloud