the whole game
This commit is contained in:
313
project/lib_projects/raknet/jni/RaknetSources/HTTPConnection.cpp
Executable file
313
project/lib_projects/raknet/jni/RaknetSources/HTTPConnection.cpp
Executable file
@@ -0,0 +1,313 @@
|
||||
/// \file
|
||||
/// \brief Contains HTTPConnection, used to communicate with web servers
|
||||
///
|
||||
/// This file is part of RakNet Copyright 2008 Kevin Jenkins.
|
||||
///
|
||||
/// Usage of RakNet is subject to the appropriate license agreement.
|
||||
/// Creative Commons Licensees are subject to the
|
||||
/// license found at
|
||||
/// http://creativecommons.org/licenses/by-nc/2.5/
|
||||
/// Single application licensees are subject to the license found at
|
||||
/// http://www.jenkinssoftware.com/SingleApplicationLicense.html
|
||||
/// Custom license users are subject to the terms therein.
|
||||
/// GPL license users are subject to the GNU General Public
|
||||
/// License as published by the Free
|
||||
/// Software Foundation; either version 2 of the License, or (at your
|
||||
/// option) any later version.
|
||||
|
||||
#include "NativeFeatureIncludes.h"
|
||||
#if _RAKNET_SUPPORT_HTTPConnection==1 && _RAKNET_SUPPORT_TCPInterface==1
|
||||
|
||||
#include "TCPInterface.h"
|
||||
#include "HTTPConnection.h"
|
||||
#include "RakSleep.h"
|
||||
#include "RakString.h"
|
||||
#include "RakAssert.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace RakNet;
|
||||
|
||||
STATIC_FACTORY_DEFINITIONS(HTTPConnection,HTTPConnection);
|
||||
|
||||
HTTPConnection::HTTPConnection() : connectionState(CS_NONE)
|
||||
{
|
||||
tcp=0;
|
||||
}
|
||||
|
||||
void HTTPConnection::Init(TCPInterface* _tcp, const char *_host, unsigned short _port)
|
||||
{
|
||||
tcp=_tcp;
|
||||
host=_host;
|
||||
port=_port;
|
||||
}
|
||||
|
||||
void HTTPConnection::Post(const char *remote_path, const char *data, const char *_contentType)
|
||||
{
|
||||
OutgoingCommand op;
|
||||
op.contentType=_contentType;
|
||||
op.data=data;
|
||||
op.remotePath=remote_path;
|
||||
op.isPost=true;
|
||||
outgoingCommand.Push(op, _FILE_AND_LINE_ );
|
||||
//printf("Adding outgoing post\n");
|
||||
}
|
||||
|
||||
void HTTPConnection::Get(const char *path)
|
||||
{
|
||||
OutgoingCommand op;
|
||||
op.remotePath=path;
|
||||
op.isPost=false;
|
||||
outgoingCommand.Push(op, _FILE_AND_LINE_ );
|
||||
}
|
||||
|
||||
bool HTTPConnection::HasBadResponse(int *code, RakNet::RakString *data)
|
||||
{
|
||||
if(badResponses.IsEmpty())
|
||||
return false;
|
||||
|
||||
if (code)
|
||||
*code = badResponses.Peek().code;
|
||||
if (data)
|
||||
*data = badResponses.Pop().data;
|
||||
return true;
|
||||
}
|
||||
void HTTPConnection::CloseConnection()
|
||||
{
|
||||
connectionState=CS_DISCONNECTING;
|
||||
}
|
||||
void HTTPConnection::Update(void)
|
||||
{
|
||||
SystemAddress sa;
|
||||
sa = tcp->HasCompletedConnectionAttempt();
|
||||
while (sa!=UNASSIGNED_SYSTEM_ADDRESS)
|
||||
{
|
||||
// printf("Connected\n");
|
||||
connectionState=CS_CONNECTED;
|
||||
server=sa;
|
||||
sa = tcp->HasCompletedConnectionAttempt();
|
||||
}
|
||||
|
||||
sa = tcp->HasFailedConnectionAttempt();
|
||||
while (sa!=UNASSIGNED_SYSTEM_ADDRESS)
|
||||
{
|
||||
//printf("Failed connected\n");
|
||||
CloseConnection();
|
||||
sa = tcp->HasFailedConnectionAttempt();
|
||||
}
|
||||
|
||||
sa = tcp->HasLostConnection();
|
||||
while (sa!=UNASSIGNED_SYSTEM_ADDRESS)
|
||||
{
|
||||
//printf("Lost connection\n");
|
||||
CloseConnection();
|
||||
sa = tcp->HasLostConnection();
|
||||
}
|
||||
|
||||
|
||||
switch (connectionState)
|
||||
{
|
||||
case CS_NONE:
|
||||
{
|
||||
if (outgoingCommand.IsEmpty())
|
||||
return;
|
||||
|
||||
//printf("Connecting\n");
|
||||
server = tcp->Connect(host, port, false);
|
||||
connectionState = CS_CONNECTING;
|
||||
}
|
||||
break;
|
||||
case CS_DISCONNECTING:
|
||||
{
|
||||
if (tcp->ReceiveHasPackets()==false)
|
||||
{
|
||||
if (incomingData.IsEmpty()==false)
|
||||
{
|
||||
results.Push(incomingData, _FILE_AND_LINE_ );
|
||||
}
|
||||
incomingData.Clear();
|
||||
tcp->CloseConnection(server);
|
||||
connectionState=CS_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CS_CONNECTING:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case CS_CONNECTED:
|
||||
{
|
||||
//printf("Connected\n");
|
||||
if (outgoingCommand.IsEmpty())
|
||||
{
|
||||
//printf("Closed connection (nothing to do)\n");
|
||||
CloseConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
#if OPEN_SSL_CLIENT_SUPPORT==1
|
||||
tcp->StartSSLClient(server);
|
||||
#endif
|
||||
|
||||
//printf("Sending request\n");
|
||||
currentProcessingCommand = outgoingCommand.Pop();
|
||||
RakString request;
|
||||
if (currentProcessingCommand.isPost)
|
||||
{
|
||||
request.Set("POST %s HTTP/1.0\r\n"
|
||||
"Host: %s:%i\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Content-Length: %u\r\n"
|
||||
"\r\n"
|
||||
"%s",
|
||||
currentProcessingCommand.remotePath.C_String(),
|
||||
host.C_String(),
|
||||
port,
|
||||
currentProcessingCommand.contentType.C_String(),
|
||||
(unsigned) currentProcessingCommand.data.GetLength(),
|
||||
currentProcessingCommand.data.C_String());
|
||||
}
|
||||
else
|
||||
{
|
||||
// request.Set("GET %s\r\n", host.C_String());
|
||||
// http://www.jenkinssoftware.com/forum/index.php?topic=4601.0;topicseen
|
||||
request.Set("GET %s HTTP/1.0\r\n"
|
||||
"Host: %s:%i\r\n"
|
||||
"\r\n",
|
||||
currentProcessingCommand.remotePath.C_String(),
|
||||
host.C_String(),
|
||||
port);
|
||||
}
|
||||
|
||||
// printf(request.C_String());
|
||||
// request.URLEncode();
|
||||
tcp->Send(request.C_String(), (unsigned int) request.GetLength(), server,false);
|
||||
connectionState=CS_PROCESSING;
|
||||
}
|
||||
break;
|
||||
case CS_PROCESSING:
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// if (connectionState==CS_PROCESSING && currentProcessingCommand.data.IsEmpty()==false)
|
||||
// outgoingCommand.PushAtHead(currentProcessingCommand);
|
||||
}
|
||||
bool HTTPConnection::HasRead(void) const
|
||||
{
|
||||
return results.IsEmpty()==false;
|
||||
}
|
||||
RakString HTTPConnection::Read(void)
|
||||
{
|
||||
if (results.IsEmpty())
|
||||
return RakString();
|
||||
|
||||
RakNet::RakString resultStr = results.Pop();
|
||||
// const char *start_of_body = strstr(resultStr.C_String(), "\r\n\r\n");
|
||||
const char *start_of_body = strpbrk(resultStr.C_String(), "\001\002\003%");
|
||||
|
||||
if(start_of_body)
|
||||
return RakNet::RakString::NonVariadic(start_of_body);
|
||||
else
|
||||
return resultStr;
|
||||
}
|
||||
SystemAddress HTTPConnection::GetServerAddress(void) const
|
||||
{
|
||||
return server;
|
||||
}
|
||||
void HTTPConnection::ProcessTCPPacket(Packet *packet)
|
||||
{
|
||||
RakAssert(packet);
|
||||
|
||||
// read all the packets possible
|
||||
if(packet->systemAddress == server)
|
||||
{
|
||||
if(incomingData.GetLength() == 0)
|
||||
{
|
||||
int response_code = atoi((char *)packet->data + strlen("HTTP/1.0 "));
|
||||
|
||||
if(response_code > 299)
|
||||
{
|
||||
badResponses.Push(BadResponse(packet->data, response_code), _FILE_AND_LINE_ );
|
||||
//printf("Closed connection (Bad response 2)\n");
|
||||
CloseConnection();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RakNet::RakString incomingTemp = RakNet::RakString::NonVariadic((const char*) packet->data);
|
||||
incomingTemp.URLDecode();
|
||||
incomingData += incomingTemp;
|
||||
|
||||
// printf((const char*) packet->data);
|
||||
// printf("\n");
|
||||
|
||||
RakAssert(strlen((char *)packet->data) == packet->length); // otherwise it contains Null bytes
|
||||
|
||||
const char *start_of_body = strstr(incomingData, "\r\n\r\n");
|
||||
|
||||
// besides having the server close the connection, they may
|
||||
// provide a length header and supply that many bytes
|
||||
if(
|
||||
// Why was start_of_body here? Makes the GET command fail
|
||||
// start_of_body &&
|
||||
connectionState == CS_PROCESSING)
|
||||
{
|
||||
/*
|
||||
// The stupid programmer that wrote this originally didn't think that just because the header contains this value doesn't mean you got the whole message
|
||||
if (strstr((const char*) packet->data, "\r\nConnection: close\r\n"))
|
||||
{
|
||||
CloseConnection();
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
long length_of_headers;
|
||||
if (start_of_body)
|
||||
{
|
||||
length_of_headers = (long)(start_of_body + 4 - incomingData.C_String());
|
||||
const char *length_header = strstr(incomingData, "\r\nLength: ");
|
||||
|
||||
if(length_header)
|
||||
{
|
||||
long length = atol(length_header + 10) + length_of_headers;
|
||||
|
||||
if((long) incomingData.GetLength() >= length)
|
||||
{
|
||||
//printf("Closed connection (Got all data due to length header)\n");
|
||||
CloseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No processing needed
|
||||
}
|
||||
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HTTPConnection::IsBusy(void) const
|
||||
{
|
||||
return connectionState != CS_NONE;
|
||||
}
|
||||
|
||||
int HTTPConnection::GetState(void) const
|
||||
{
|
||||
return connectionState;
|
||||
}
|
||||
|
||||
|
||||
HTTPConnection::~HTTPConnection(void)
|
||||
{
|
||||
if (tcp)
|
||||
tcp->CloseConnection(server);
|
||||
}
|
||||
|
||||
|
||||
#endif // _RAKNET_SUPPORT_*
|
||||
Reference in New Issue
Block a user