rendered paste body#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<string, string>::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;
}
}