#include "CWinsock.h" CWinsock::CWinsock() { WSADATA wsaData; wsInit = FALSE; if(WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) { return; } wsInit = TRUE; } CWinsock::~CWinsock() { if(wsInit) { WSACleanup(); } } int CWinsock::GetLastError() { return WSAGetLastError(); } LPWSTR CWinsock::GetLastErrorStr() { return gai_strerror(WSAGetLastError()); } int CWinsock::URLDownload(LPSTR lpURL) { URLINFO url; char hostname[NI_MAXHOST]; if(!wsInit) return 0; if(!URLParse(lpURL, url)) return 0; printf_s("service: %s\n", url.service); printf_s("host: %s\n", url.hostname); printf_s("path: %s\n", url.path); if(!URLResolve(url.service, url.hostname)) { freeaddrinfo(ai); return 0; } printf_s("URL resolved successfully\n"); if(getnameinfo(ai->ai_addr, sizeof(sockaddr), hostname, sizeof(hostname), NULL, 0, 0)) return 0; if((url.resolved = URLHeader(ai, TRUE, url, "404 Not Found", NULL, 0)) == 0) { freeaddrinfo(ai); return 0; } if(!URLHeader(ai, FALSE, url, "Accept-Ranges", url.ranges, sizeof(url.ranges))) { freeaddrinfo(ai); return 0; } if(!URLHeader(ai, FALSE, url, "Content-Length", url.filesize, sizeof(url.filesize))) { freeaddrinfo(ai); return 0; } printf_s("Filezise: %s, ranges: %s, resolved: %d\n", url.filesize, url.ranges, url.resolved); if(!URLGet(ai, url)) { freeaddrinfo(ai); return 0; } freeaddrinfo(ai); return 0; } int CWinsock::URLParse(LPSTR lpURL, URLINFO& url) { enum { PARSE_NONE, PARSE_HTTP, PARSE_WWW, PARSE_HTTPWWW, PARSE_FTP }; int parseType = PARSE_NONE; int i = 0; if(lpURL == NULL) return 0; memset(&url, 0, sizeof(url)); // Determine the URL format if(strncmp(lpURL, "http://www.", 11) == 0 || strncmp(lpURL, "http:\\\\www.", 11) == 0) parseType = PARSE_HTTPWWW; else if(strncmp(lpURL, "http://", 7) == 0 || strncmp(lpURL, "http:\\\\", 4) == 0) parseType = PARSE_HTTP; else if(strncmp(lpURL, "www.", 4) == 0) parseType = PARSE_WWW; else if(strncmp(lpURL, "ftp://", 6) == 0 || strncmp(lpURL, "ftp:\\\\", 6) == 0) parseType = PARSE_FTP; // Parse the URL string switch(parseType) { case PARSE_HTTPWWW: { strcpy_s(url.service, "http"); URLParseURL(lpURL, url, 11); break; } case PARSE_WWW: strcpy_s(url.service, "http"); URLParseURL(lpURL, url, 4); break; case PARSE_HTTP: strcpy_s(url.service, "http"); URLParseURL(lpURL, url, 7); break; case PARSE_NONE: strcpy_s(url.service, "http"); URLParseURL(lpURL, url, 0); break; case PARSE_FTP: strcpy_s(url.service, "ftp"); URLParseURL(lpURL, url, 6); break; } // Get file name int len = (int)strlen(lpURL); if(len) { while(len && url.filename[len] != '\\') len--; if(len) url.filename[len + 1] = 0; } else { srand(GetTickCount()); sprintf_s(url.filename, "Unknown_%d.dat\0", rand()); } return 1; } int CWinsock::URLParseURL(LPSTR lpURL, URLINFO& url, int startPos) { int i = 0; // Host strcpy_s(url.hostname, lpURL+startPos); for(i=0; i<(int)strlen(url.hostname); i++) { if(url.hostname[i] == '/' || url.hostname[i] == '\\') { url.hostname[i]=0; break; } } // Path strcpy_s(url.path, lpURL+i+startPos); return 1; } int CWinsock::URLResolve(LPSTR lpService, LPSTR lpURL) { ADDRINFO aiHints; if(lpURL == NULL) return 0; // Setup addrinfo hints memset(&aiHints, 0, sizeof(aiHints)); aiHints.ai_family = AF_INET; aiHints.ai_socktype = SOCK_STREAM; aiHints.ai_protocol = IPPROTO_TCP; // Resolve the hostname if((getaddrinfo(lpURL, lpService, &aiHints, &ai) != NO_ERROR) || !ai) return 0; return 1; } int CWinsock::URLHeader(ADDRINFO *ai, int useAIForURL, URLINFO& url, LPSTR lpSearchStr, LPSTR lpOutValue, size_t valueSize) { fd_set ReadSet; struct timeval Time; int len=0, totalLen=0, timeout=0; char response[4096]; char sendBuf[2046]; SOCKET connSock = 0; char hostname[NI_MAXHOST]; if(ai == NULL || url.path == NULL) return 0; // Determine hostname & build send query if(useAIForURL == TRUE) { if(getnameinfo(ai->ai_addr, sizeof(sockaddr), hostname, sizeof(hostname), NULL, 0, 0) == NO_ERROR) sprintf_s(sendBuf, "HEAD %s HTTP/1.1\r\nHost: %s\r\n\r\n\0", url.path, hostname); else return 0; } else sprintf_s(sendBuf, "HEAD %s HTTP/1.1\r\nHost: %s\r\n\r\n\0", url.path, url.hostname); // Create socket if((connSock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == INVALID_SOCKET) return 0; // Connect to host if(connect(connSock, ai->ai_addr, (int)ai->ai_addrlen) != NO_ERROR) { closesocket(connSock); return 0; } // Send request for file header if(send(connSock, sendBuf, (int)strlen(sendBuf), 0) == SOCKET_ERROR) { closesocket(connSock); return 0; } // Read response memset(&ReadSet, 0, sizeof(ReadSet)); FD_SET(connSock, &ReadSet); Time.tv_sec = TIMEOUT; Time.tv_usec = 0; len = 1; while(len > 0 && (timeout = select(0, &ReadSet, 0, 0, &Time)) > 0) { len = recv(connSock, response + totalLen, sizeof(response) - totalLen - 1, 0); totalLen += len; Time.tv_sec = TIMEOUT; Time.tv_usec = 0; } response[totalLen]=0; if(!timeout) return 0; char *s = strstr(response, lpSearchStr); int ret = 0; // String search w/o returned value if(lpOutValue == NULL) { if(s) ret = 1; // Found str else ret = 2; // Didn't find str } // Search for a key & return value else if(s) { while(*s && *s != ':') *s++; *s++; if(*s == ' ') *s++; for(int i=0; i<(int)valueSize; i++) { if(!*s || *s == '\r' || *s == '\n') { lpOutValue[i]=0; break; } lpOutValue[i] = *s; *s++; } ret = 1; } printf("response: %s\n\n\n", response); closesocket(connSock); return ret; } int CWinsock::URLGet(ADDRINFO *ai, URLINFO& url) { fd_set ReadSet; struct timeval Time; int len=0, totalLen=0, timeout=0; char response[512]; char sendBuf[2046]; SOCKET connSock = 0; if(ai == NULL || url.hostname == NULL || url.path == NULL || url.resolved == 0) return 0; if(url.resolved == TH_SINGLE) { sprintf_s(sendBuf, "GET %s HTTP/1.1\r\n\ Host: %s\r\n\r\n\ Accept: */*\r\n\ User-Agent: veloxpro\r\n\ Connection: Keep-Alive\r\n\ Referer: %s\r\n\ \r\n\\0", url.path, url.hostname, url.hostname); // Create socket if((connSock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == INVALID_SOCKET) return 0; // Connect to host if(connect(connSock, ai->ai_addr, (int)ai->ai_addrlen) != NO_ERROR) { closesocket(connSock); return 0; } // Send request for file header if(send(connSock, sendBuf, (int)strlen(sendBuf), 0) == SOCKET_ERROR) { closesocket(connSock); return 0; } // Read response memset(&ReadSet, 0, sizeof(ReadSet)); FD_SET(connSock, &ReadSet); Time.tv_sec = TIMEOUT; Time.tv_usec = 0; len = 1; printf("Recieving...\n"); while(len > 0 && (timeout = select(0, &ReadSet, 0, 0, &Time)) > 0) { len = recv(connSock, response, sizeof(response), 0); totalLen += len; printf("%s", response); Time.tv_sec = TIMEOUT; Time.tv_usec = 0; } response[totalLen]=0; printf("\n"); if(!timeout) return 0; } else if(url.resolved == TH_MULTI) { } return 0; }