#include "httpwrapper.h" namespace MOOLA_MH { HTTPWrapper::HTTPWrapper() : m_hostname(""), m_port(80), m_referer("") { initWSA(); } HTTPWrapper::HTTPWrapper(string host, int port = 80) : m_port(port), m_referer("") { // Use setHost so that error checking is done setHost(host); } HTTPWrapper::~HTTPWrapper() { WSACleanup(); } void HTTPWrapper::initWSA() { int iResult = WSAStartup(MAKEWORD(2,2), &m_wsaData); if (iResult != 0) { cout << "WSAStartup failed: " << iResult << endl; throw WSAStartupFailed(); } } void HTTPWrapper::setHost(string host) { if (!validHost(host, m_hostEntry)) { cout << "Invalid host: " << WSAGetLastError() << endl; throw InvalidHost(); } m_hostname = host; } void HTTPWrapper::setPort(int port) { m_port = port; } void HTTPWrapper::setReferer(string referer) { m_referer = referer; } void HTTPWrapper::setData(string name, string value = "") { if (value == "") m_data.erase(name); else m_data[name] = value; } void HTTPWrapper::clearData() { m_data.clear(); } void HTTPWrapper::get(string file) { connect(); string data = ""; string request = ""; int nResult = 0; dataString(data); if (data != "") file += "?" + data; prepareRequest("GET", file, request); nResult = send(m_socket, request.c_str(), request.length(), 0); if (nResult == SOCKET_ERROR) { cout << "Send Error: " << WSAGetLastError() << endl; throw SendError(); } string realdata = ""; cout << "Receving..." << endl; // First get the damn headers char cur, prev[3]; string headers = ""; while (true) { recv(m_socket, &cur, 1, 0); headers += cur; if (cur == '\n' && prev[2] == '\r' && prev[1] == '\n' && prev[0] == '\r') break; else { prev[0] = prev[1]; prev[1] = prev[2]; prev[2] = cur; } } // Second, parse headers, store int a1 = 0, a2 = 0, a3 = 0; m_headers.clear(); a1 = headers.find("\r\n"); while (a1 != string::npos) { a1 += strlen("\r\n"); a2 = headers.find(": ", a1); string key = headers.substr(a1, a2 - a1); a2 += 2; a3 = headers.find("\r\n", a2); string value = headers.substr(a2, a3 - a2); m_headers[key] = value; a1 = headers.find("\r\n", a1); } // Third, GET THE DAMN DATA FOOL! int clength, blength = 256, bytes = 0; char *buffer = new char[blength]; clength = atoi(m_headers["Content-Length"].c_str()); while (bytes < clength) { bytes += recv(m_socket, buffer, blength - 1, 0); buffer[blength - 1] = '\0'; realdata += buffer; ZeroMemory(buffer, blength); } delete[] buffer; } void HTTPWrapper::prepareRequest(string method, string file, string& request) { request = ""; request = method + " " + file + " HTTP/1.0\r\n" + "Host: " + m_hostname + "\r\n" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4\r\n" + "Accept: application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n" + "Accept-Language: en-us,en;q=0.5\r\n" + "Accept-Encoding: none\r\n" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" + "Keep-Alive: 300\r\n" + "Connection: keep-alive\r\n" + "\r\n"; } void HTTPWrapper::dataString(string& data) { if (m_data.size() > 0) { for(map::iterator piece = m_data.begin(); piece != m_data.end(); piece++) { data += piece->first + "=" + piece->second + "&"; } data.erase(data.length() - 1, 1); } } void HTTPWrapper::connect() { m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_socket == INVALID_SOCKET) { cout << "Invalid socket: " << WSAGetLastError() << endl; throw InvalidSocket(); } SOCKADDR_IN serverInfo; serverInfo.sin_family = AF_INET; serverInfo.sin_addr = *((LPIN_ADDR)*m_hostEntry->h_addr_list); serverInfo.sin_port = htons(m_port); int nResult = 0; nResult = ::connect(m_socket, (LPSOCKADDR)&serverInfo, sizeof(SOCKADDR_IN)); if (nResult == SOCKET_ERROR) { cout << "Connect error: " << WSAGetLastError() << endl; throw NoConnect(); } } bool HTTPWrapper::validHost(string host, LPHOSTENT& entry) { entry = gethostbyname(host.c_str()); if (!entry) return false; else return true; } }