|
|
1.1 root 1: #include <stdio.h>
2:
3: #include <sys/param.h>
4: #include <sys/socket.h>
5: #include <sys/types.h>
6: #include <sys/uio.h>
7: #include <unistd.h>
8: #include <ctype.h>
9: #include <netdb.h>
10: #include <netinet/in.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <arpa/inet.h>
14:
15: #include "sockwrap.h"
16:
17: #define MAX_SCHEME_LEN 10
18: #define MAX_HOST_LEN 128
19: #define MAX_INACTIVITY 30 /* Seconds */
20: #define MAX_HEADER 1024
21:
22: u_long resolve_ip(char *addr)
23: {
24: struct hostent* host;
25: char* p;
26:
27: if(*addr==0)
28: return(INADDR_NONE);
29:
30: for(p=addr;*p;p++)
31: if(*p!='.' && !isdigit(*p))
32: break;
33: if(!(*p))
34: return(inet_addr(addr));
35: if((host=gethostbyname(addr))==NULL)
36: return(INADDR_NONE);
37: return(*((u_long*)host->h_addr_list[0]));
38: }
39:
40: int sockreadline(int sock, char *buf, size_t length, char *error)
41: {
42: char ch;
43: int i;
44: int rd;
45: #if 0
46: time_t start;
47:
48: start=time(NULL);
49: for(i=0;TRUE;) {
50: if(!socket_check(sock,&rd,NULL,1000)) {
51: if(error != NULL)
52: strcpy(error, "Socket error");
53: return(-1);
54: }
55:
56: if(!rd) {
57: if(time(NULL)-start>MAX_INACTIVITY) {
58: if(error != NULL)
59: strcpy(error,"Timed out");
60: return(-1); /* time-out */
61: }
62: continue; /* no data */
63: }
64:
65: if(recv(sock, &ch, 1, 0)!=1)
66: break;
67:
68: if(ch=='\n')
69: break;
70:
71: if(i<length)
72: buf[i++]=ch;
73: }
74: #else
75: for(i=0;1;) {
76: if(!socket_check(sock,&rd,NULL,60000) || !rd || recv(sock, &ch, 1, 0)!=1) {
77: if(error != NULL)
78: strcpy(error,"Timed out");
79: return(-1); /* time-out */
80: }
81:
82: if(ch=='\n')
83: break;
84:
85: if(i<length)
86: buf[i++]=ch;
87: }
88: #endif
89:
90: /* Terminate at length if longer */
91: if(i>length)
92: i=length;
93:
94: if(i>0 && buf[i-1]=='\r')
95: buf[--i]=0;
96: else
97: buf[i]=0;
98:
99: return(i);
100: }
101:
102: /* Error will hold the error message on a failed return... */
103: /* Must be at least 128 bytes long */
104: int http_get_fd(char *URL, size_t *len, char *error)
105: {
106: char host[MAX_HOST_LEN+1];
107: ulong ip_addr;
108: int s=-1;
109: int port=80;
110: char *p;
111: char *path;
112: struct sockaddr_in addr;
113: char header[MAX_HEADER+1];
114:
115: if(len != NULL)
116: *len=0;
117: if(error != NULL)
118: *error=0;
119: if(strncasecmp(URL, "http://", 7)) {
120: if(error!=NULL)
121: strcpy(error, "URL is not http");
122: return(-1);
123: }
124: strncpy(host, URL+7, MAX_HOST_LEN);
125: host[MAX_HOST_LEN+1]=0;
126: if((p=strchr(host,'/'))==NULL) {
127: if(error!=NULL)
128: strcpy(error, "Host too long or no path info found");
129: return(-1);
130: }
131: *p=0;
132: if((p=strchr(host,':'))!=NULL) {
133: *p=0;
134: port=atoi(p+1);
135: }
136: if((ip_addr=resolve_ip(host))==INADDR_NONE) {
137: if(error!=NULL)
138: strcpy(error, "Unable to resolve host");
139: return(-1);
140: }
141: if((path=strchr(URL+7, '/'))==NULL) {
142: if(error!=NULL)
143: strcpy(error, "Path info not found");
144: return(-1);
145: }
146: if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) {
147: if(error!=NULL)
148: strcpy(error, "Unable to create socket");
149: return(-1);
150: }
151: memset(&addr,0,sizeof(addr));
152: addr.sin_addr.s_addr = ip_addr;
153: addr.sin_family = AF_INET;
154: addr.sin_port = htons(port);
155: if (connect(s, (struct sockaddr*)&addr, sizeof (addr)) < 0) {
156: close(s);
157: if(error!=NULL)
158: strcpy(error, "Unable to connect");
159: return(-1);
160: }
161: if(error!=NULL)
162: strcpy(error,"Unable to send request");
163: if(write(s, "GET ", 4)!=4) {
164: close(s);
165: return(-1);
166: }
167: if(write(s, path, strlen(path))!=strlen(path)) {
168: close(s);
169: return(-1);
170: }
171: if(write(s, " HTTP/1.0\r\nHost: ", 17)!=17) {
172: close(s);
173: return(-1);
174: }
175: if(write(s, host, strlen(host))!=strlen(host)) {
176: close(s);
177: return(-1);
178: }
179: if(write(s, "\r\nConnection: close\r\n\r\n",23)!=23) {
180: close(s);
181: return(-1);
182: }
183: if(error!=NULL)
184: *error=0;
185: if(sockreadline(s, header, sizeof(header), error) < 0) {
186: close(s);
187: return(-1);
188: }
189: if(atoi(header+9)!=200) {
190: if(error != NULL) {
191: strncpy(error, header, 128);
192: error[127]=0;
193: }
194: close(s);
195: return(-1);
196: }
197: while(header[0]) {
198: if(sockreadline(s, header, sizeof(header), error) < 0) {
199: close(s);
200: return(-1);
201: }
202: if(len != NULL && strncasecmp(header,"content-length:",15)==0) {
203: *len=atol(header+15);
204: }
205: }
206: return(s);
207: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.