|
|
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.