SocketReader.cpp 3.61 KiB
//
// Created by Ben Bergkamp on 2/14/18.
//
#include "SocketReader.h"
char * GetArbitrarySizeBuffer(SSL* ssl)
{
int buf_size = 10240;
int current_size = buf_size;
char* ssl_buffer = new char[buf_size];
char* front = ssl_buffer;
int bytes;
while ( ( bytes = SSL_read( ssl, front, buf_size ) ) > 0 )
{
current_size += buf_size;
char *temp = new char[current_size];
strcpy(temp, ssl_buffer);
front = temp + strlen(ssl_buffer);
delete[] ssl_buffer;
ssl_buffer = temp;
}
return ssl_buffer;
}
char * GetArbitrarySizeBuffer(int s )
{
int buf_size = 10240;
int current_size = buf_size;
char* http_buff = new char[buf_size];
char* front = http_buff;
int bytes;
while ( ( bytes = recv( s, front, buf_size, 0 ) ) > 0 )
{
current_size += buf_size;
char *temp = new char[current_size];
strcpy(temp, http_buff);
front = temp + strlen(http_buff);
delete[] http_buff;
http_buff = temp;
}
return http_buff;
}
void SocketReader::httpRequest()
{
int s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
assert( s != -1 );
// Get the host address.
struct hostent *host = gethostbyname( url.Host );
assert( host );
struct sockaddr_in address;
memset( &address, 0, sizeof( address ) );
address.sin_family = AF_INET;
address.sin_port = htons( 80 );
memcpy( &address.sin_addr, host->h_addr, host->h_length );
// Connect to the host.
int connectResult = connect( s, ( struct sockaddr * )&address,
sizeof( address ) );
assert( connectResult == 0 );
// Send a GET message for the desired page.
cout << "Socket Reader is pulling from the web" << endl;
string getMessage = "GET ";
getMessage += url.CompleteUrl;
getMessage += " HTTP/1.1\r\nHost: ";
getMessage += url.Host;
getMessage += "\r\nConnection: close\r\n\r\n";
cout << getMessage << endl;
send( s, getMessage.c_str( ), getMessage.length( ), 0 );
// Read from the socket until there's no more data.
char HTTPbuffer[ 10240 ];
int bytes;
while ( ( bytes = recv( s, buffer, sizeof( buffer ), 0 ) ) > 0 )
write( 1, buffer, bytes );
buffer = GetArbitrarySizeBuffer(s);
close( s );
return;
}
void SocketReader::httpsRequest(){
struct hostent *host = gethostbyname( url.Host );
assert( host );
struct sockaddr_in address;
memset( &address, 0, sizeof( address ) );
address.sin_family = AF_INET;
address.sin_port = htons( 443 );
memcpy( &address.sin_addr, host->h_addr, host->h_length );
// Create a TCP/IP socket.
int s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
assert( s != -1 );
// Connect the socket to the host address.
int connectResult = connect( s, ( struct sockaddr * )&address,
sizeof( address ) );
assert( connectResult == 0 );
// Build an SSL layer and set it to read/write
// to the socket we've connected.
SSL_library_init( );
SSL_CTX *ctx = SSL_CTX_new( SSLv23_method( ) );
assert( ctx );
SSL *ssl = SSL_new( ctx );
assert( ssl );
SSL_set_fd( ssl, s );
// Establish an SSL connection.
int sslConnectResult = SSL_connect( ssl );
assert( sslConnectResult == 1 );
// Send a GET message for the desired page through the SSL.
string getMessage = "GET ";
getMessage += url.CompleteUrl;
getMessage += " HTTP/1.1\r\nHost: ";
getMessage += url.Host;
getMessage += "\r\nConnection: close\r\n\r\n";
cout << getMessage << endl;
SSL_write( ssl, getMessage.c_str( ), getMessage.length( ) );
// Read from the SSL until there's no more data.
buffer = GetArbitrarySizeBuffer(ssl);
SSL_shutdown( ssl );
SSL_free( ssl );
SSL_CTX_free( ctx );
close( s );
}
void SocketReader::fillBuffer( )
{
if ( !strcmp(url.Service , "http" ) )
httpRequest();
else
httpsRequest();
}