29 #include <sys/types.h>
34 #include <netinet/in.h>
35 #include <sys/socket.h>
39 #define close closesocket
40 #define write(s, buf, len) send(s, buf, (int)(len), 0)
41 #define read(s, buf, len) recv(s, buf, (int)(len), 0)
70 "Internal Error. What the hell?!",
72 "Timed out, no metadata for %d seconds",
73 "Timed out, no data for %d seconds",
74 "Couldn't find return code in HTTP response",
75 "Couldn't convert return code in HTTP response",
76 "Request returned a status code of %d",
77 "Couldn't convert Content-Length to integer",
78 "Network error (description unavailable)",
79 "Status code of %d but no Location: field",
80 "Followed the maximum number of redirects (%d)"
100 char *tmp, *url, *pageBuf, *requestBuf = NULL, *host, *charIndex;
102 int i, ret = -1, tempSize, selectRet, found = 0,
103 redirectsFollowed = 0;
106 if (url_tmp == NULL) {
115 url = (
char *)malloc(strlen(url_tmp) + 1);
120 strncpy(url, url_tmp, strlen(url_tmp) + 1);
133 charIndex = strstr(url,
"://");
134 if (charIndex != NULL) {
136 charIndex += strlen(
"://");
138 charIndex = strchr(charIndex,
'/');
141 charIndex = strchr(url,
'/');
145 requestBuf = (
char *)malloc(bufsize);
146 if (requestBuf == NULL) {
153 if (charIndex == NULL) {
158 tempSize = (int)strlen(
"GET /") + (int)strlen(
HTTP_VERSION) + 2;
160 snprintf(requestBuf, bufsize,
"GET / %s\r\n",
HTTP_VERSION) < 0) {
167 tempSize = (int)strlen(
"GET ") + (int)strlen(charIndex) +
172 snprintf(requestBuf, bufsize,
"GET %s %s\r\n",
182 if (charIndex != NULL)
190 ret = (int)bufsize - (
int)strlen(requestBuf);
191 tempSize = (int)strlen(
"Host: ") + (int)strlen(host) + 3;
199 strcat(requestBuf,
"Host: ");
200 strcat(requestBuf, host);
201 strcat(requestBuf,
"\r\n");
204 tempSize = (int)strlen(
"Referer: ") + (int)strlen(
referer) + 3;
212 strcat(requestBuf,
"Referer: ");
214 strcat(requestBuf,
"\r\n");
217 tempSize = (int)strlen(
"User-Agent: ") +
226 strcat(requestBuf,
"User-Agent: ");
228 strcat(requestBuf,
"/");
230 strcat(requestBuf,
"\r\n");
232 tempSize = (int)strlen(
"User-Agent: ") + (int)strlen(
userAgent) + 3;
240 strcat(requestBuf,
"User-Agent: ");
242 strcat(requestBuf,
"\r\n");
244 tempSize = (int)strlen(
"Connection: Close\r\n\r\n");
251 strcat(requestBuf,
"Connection: Close\r\n\r\n");
254 tmp = (
char *)realloc(requestBuf, strlen(requestBuf) + 1);
273 if (write(sock, requestBuf, strlen(requestBuf)) == -1) {
290 charIndex = strstr(headerBuf,
"HTTP/");
291 if (charIndex == NULL) {
297 while (*charIndex !=
' ')
301 ret = sscanf(charIndex,
"%d", &i);
308 if (i < 200 || i > 307) {
331 charIndex = strstr(headerBuf,
"Location:");
340 charIndex += strlen(
"Location:");
342 while (*charIndex !=
'\0' && isspace(*charIndex))
344 if (*charIndex ==
'\0') {
352 i = (int)strcspn(charIndex,
" \r\n");
354 url = (
char *)malloc(i + 1);
355 strncpy(url, charIndex, i);
391 charIndex = strstr(headerBuf,
"Content-Length:");
392 if (charIndex == NULL)
393 charIndex = strstr(headerBuf,
"Content-length:");
395 if (charIndex != NULL) {
396 ret = sscanf(charIndex + strlen(
"content-length: "),
"%d",
406 if (contentLength == -1)
409 pageBuf = (
char *)malloc(contentLength);
410 if (pageBuf == NULL) {
423 selectRet = select(sock + 1, &rfds, NULL, NULL, &tv);
425 selectRet = select(sock + 1, &rfds, NULL, NULL, NULL);
427 if (selectRet == 0) {
434 }
else if (selectRet == -1) {
440 ret = read(sock, pageBuf + bytesRead, contentLength);
455 tmp = (
char *)realloc(pageBuf, bytesRead + contentLength);
472 tmp = (
char *)realloc(pageBuf, bytesRead + 1);
486 pageBuf[bytesRead] =
'\0';
504 static int freeOldAgent = 0;
508 if (newAgent == NULL) {
514 tmp = (
char *)malloc(strlen(newAgent));
537 static int freeOldReferer = 0;
541 if (newReferer == NULL) {
547 tmp = (
char *)malloc(strlen(newReferer));
607 ptr = (
char *)rindex(url,
'/');
616 *filename = (
char *)malloc(strlen(ptr));
617 if (*filename == NULL) {
621 strcpy(*filename, ptr);
639 const char *stringIndex;
642 fputs(
string, stderr);
652 while (*stringIndex !=
'%') {
653 fputc(*stringIndex, stderr);
658 while (*stringIndex != 0) {
660 fputc(*stringIndex, stderr);
680 return strerror(errno);
682 #ifdef HAVE_HSTRERROR
683 return hstrerror(h_errno);
696 char *stringIndex, *originalError;
700 stringIndex = strstr(originalError,
"%d");
702 abs(stringIndex - originalError));
724 int bytesRead = 0, newlines = 0, ret, selectRet;
733 selectRet = select(sock + 1, &rfds, NULL, NULL, &tv);
735 selectRet = select(sock + 1, &rfds, NULL, NULL, NULL);
737 if (selectRet == 0) {
742 }
else if (selectRet == -1) {
746 ret = read(sock, headerPtr, 1);
753 if (*headerPtr ==
'\r') {
760 }
else if (*headerPtr ==
'\n')
782 struct sockaddr_in sa;
789 p = strchr(host,
':');
796 hp = gethostbyname(host);
802 memcpy((
char *)&sa.sin_addr, (
char *)hp->h_addr, hp->h_length);
803 sa.sin_family = hp->h_addrtype;
804 sa.sin_port = htons(port);
806 sock = (int)socket(hp->h_addrtype, SOCK_STREAM, 0);
811 ret = connect(sock, (
struct sockaddr *)&sa,
sizeof(sa));
830 int roomLeft = (int)*bufsize - (
int)(strlen(*buf) + 1);
833 tmp = (
char *)realloc(*buf, *bufsize + more + 1);
837 *bufsize += more + 1;
void http_setRedirects(int redirects)
void http_perror(const char *string)
#define DEFAULT_PAGE_BUF_SIZE
interval abs(const interval &x)
const char * http_strerror()
const char * http_errlist[]
int _http_read_header(int sock, char *headerPtr)
int http_setUserAgent(const char *newAgent)
void http_setTimeout(int seconds)
int makeSocket(char *host)
#define DEFAULT_REDIRECTS
static int followRedirects
int http_parseFilename(const char *url, char **filename)
#define DEFAULT_READ_TIMEOUT
int http_fetch(const char *url_tmp, char **fileBuf)
int http_setReferer(const char *newReferer)
#define DEFAULT_USER_AGENT
int _checkBufSize(char **buf, int *bufsize, int more)