]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/ipfilter/lib/load_http.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / ipfilter / lib / load_http.c
1 /*
2  * Copyright (C) 2006 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  *
6  * $Id: load_http.c,v 1.1.2.1 2006/08/25 21:13:04 darrenr Exp $
7  */
8
9 #include "ipf.h"
10
11 /*
12  * Format expected is one addres per line, at the start of each line.
13  */
14 alist_t *
15 load_http(char *url)
16 {
17         int fd, len, left, port, endhdr, removed;
18         char *s, *t, *u, buffer[1024], *myurl;
19         alist_t *a, *rtop, *rbot;
20         struct sockaddr_in sin;
21         struct hostent *host;
22
23         /*
24          * More than this would just be absurd.
25          */
26         if (strlen(url) > 512) {
27                 fprintf(stderr, "load_http has a URL > 512 bytes?!\n");
28                 return NULL;
29         }
30
31         fd = -1;
32         rtop = NULL;
33         rbot = NULL;
34
35         sprintf(buffer, "GET %s HTTP/1.0\r\n", url);
36
37         myurl = strdup(url);
38         if (myurl == NULL)
39                 goto done;
40
41         s = myurl + 7;                  /* http:// */
42         t = strchr(s, '/');
43         if (t == NULL) {
44                 fprintf(stderr, "load_http has a malformed URL '%s'\n", url);
45                 free(myurl);
46                 return NULL;
47         }
48         *t++ = '\0';
49
50         u = strchr(s, '@');
51         if (u != NULL)
52                 s = u + 1;              /* AUTH */
53
54         sprintf(buffer + strlen(buffer), "Host: %s\r\n\r\n", s);
55
56         u = strchr(s, ':');
57         if (u != NULL) {
58                 *u++ = '\0';
59                 port = atoi(u);
60                 if (port < 0 || port > 65535)
61                         goto done;
62         } else {
63                 port = 80;
64         }
65
66         memset(&sin, 0, sizeof(sin));
67         sin.sin_family = AF_INET;
68         sin.sin_port = htons(port);
69
70         if (isdigit(*s)) {
71                 if (inet_aton(s, &sin.sin_addr) == -1) {
72                         goto done;
73                 }
74         } else {
75                 host = gethostbyname(s);
76                 if (host == NULL)
77                         goto done;
78                 memcpy(&sin.sin_addr, host->h_addr_list[0],
79                        sizeof(sin.sin_addr));
80         }
81
82         fd = socket(AF_INET, SOCK_STREAM, 0);
83         if (fd == -1)
84                 goto done;
85
86         if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
87                 close(fd);
88                 goto done;
89         }
90
91         len = strlen(buffer);
92         if (write(fd, buffer, len) != len) {
93                 close(fd);
94                 goto done;
95         }
96
97         s = buffer;
98         endhdr = 0;
99         left = sizeof(buffer) - 1;
100
101         while ((len = read(fd, s, left)) > 0) {
102                 s[len] = '\0';
103                 left -= len;
104                 s += len;
105
106                 if (endhdr >= 0) {
107                         if (endhdr == 0) {
108                                 t = strchr(buffer, ' ');
109                                 if (t == NULL)
110                                         continue;
111                                 t++;
112                                 if (*t != '2')
113                                         break;
114                         }
115
116                         u = buffer;
117                         while ((t = strchr(u, '\r')) != NULL) {
118                                 if (t == u) {
119                                         if (*(t + 1) == '\n') {
120                                                 u = t + 2;
121                                                 endhdr = -1;
122                                                 break;
123                                         } else
124                                                 t++;
125                                 } else if (*(t + 1) == '\n') {
126                                         endhdr++;
127                                         u = t + 2;
128                                 } else
129                                         u = t + 1;
130                         }
131                         if (endhdr >= 0)
132                                 continue;
133                         removed = (u - buffer) + 1;
134                         memmove(buffer, u, (sizeof(buffer) - left) - removed);
135                         s -= removed;
136                         left += removed;
137                 }
138
139                 do {
140                         t = strchr(buffer, '\n');
141                         if (t == NULL)
142                                 break;
143
144                         *t++ = '\0';
145                         for (u = buffer; isdigit(*u) || (*u == '.'); u++)
146                                 ;
147                         if (*u == '/') {
148                                 char *slash;
149
150                                 slash = u;
151                                 u++;
152                                 while (isdigit(*u))
153                                         u++;
154                                 if (!isspace(*u) && *u)
155                                         u = slash;
156                         }
157                         *u = '\0';
158
159                         a = alist_new(4, buffer);
160                         if (a != NULL) {
161                                 if (rbot != NULL)
162                                         rbot->al_next = a;
163                                 else
164                                         rtop = a;
165                                 rbot = a;
166                         }
167
168                         removed = t - buffer;
169                         memmove(buffer, t, sizeof(buffer) - left - removed);
170                         s -= removed;
171                         left += removed;
172
173                 } while (1);
174         }
175
176 done:
177         if (myurl != NULL)
178                 free(myurl);
179         if (fd != -1)
180                 close(fd);
181         return rtop;
182 }