/*
 *	An demo illustrating how to retrieve a URI from a secure HTTP server.
 *
 *	Author: 	Roy Wood
 *	Date:		September 7, 1999
 *	Comments:	This relies heavily on my MacSockets library.
 *				This project is also set up so that it expects the OpenSSL source folder (0.9.4 as I write this)
 *				to live in a folder called "OpenSSL-0.9.4" in this project's parent folder.  For example:
 *
 *					Macintosh HD:
 *						Development:
 *							OpenSSL-0.9.4:
 *								(OpenSSL sources here)
 *							OpenSSL Example:
 *								(OpenSSL example junk here)
 *
 *
 *				Also-- before attempting to compile this, make sure the aliases in "OpenSSL-0.9.4:include:openssl" 
 *				are installed!  Use the AppleScript applet in the "openssl-0.9.4" folder to do this!
 */


//	Include some funky libs I've developed over time

#include "CPStringUtils.hpp"
#include "ErrorHandling.hpp"
#include "MacSocket.h"


//	We use the OpenSSL implementation of SSL....
//	This was a lot of work to finally get going, though you wouldn't know it by the results!

#include <openssl/ssl.h>
#include <openssl/err.h>



//	Let's try grabbing some data from here:

#define kHTTPS_DNS		"www.apache-ssl.org"
#define kHTTPS_Port		443
#define kHTTPS_URI		"/"


//	Forward-declare this

OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr);





//	My idle-wait callback.  Doesn't do much, does it?  Silly cooperative multitasking.

OSErr MyMacSocket_IdleWaitCallback(void *inUserRefPtr)
{
#pragma unused(inUserRefPtr)

EventRecord		theEvent;

	::EventAvail(everyEvent,&theEvent);

	return(noErr);
}



//	Finally!

void main(void)
{
OSErr				errCode;
int					theSocket = -1;
int					theTimeout = 30;

SSL_CTX				*ssl_ctx = nil;
SSL					*ssl = nil;

char				tempString[256];

	
	printf("OpenSSL Demo by Roy Wood, roy@centricsystems.ca\n\n");
	
	BailIfError(errCode = MacSocket_Startup());



	//	Create a socket-like object
	
	BailIfError(errCode = MacSocket_socket(&theSocket,false,theTimeout * 60,MyMacSocket_IdleWaitCallback,nil));

	
	//	Set up the connect string and try to connect
	
	CopyCStrAndInsertCStrLongIntIntoCStr("%s:%ld",kHTTPS_DNS,kHTTPS_Port,tempString,sizeof(tempString));
	
	printf("Connecting to %s....\n",tempString);

	BailIfError(errCode = MacSocket_connect(theSocket,tempString));
	
	
	//	Init SSL stuff
	
	SSL_load_error_strings();
	
	SSLeay_add_ssl_algorithms();
	
	
	//	Pick the SSL method
	
//	ssl_ctx = SSL_CTX_new(SSLv2_client_method());
	ssl_ctx = SSL_CTX_new(SSLv23_client_method());
//	ssl_ctx = SSL_CTX_new(SSLv3_client_method());
			

	//	Create an SSL thingey and try to negotiate the connection
	
	ssl = SSL_new(ssl_ctx);
	
	SSL_set_fd(ssl,theSocket);
	
	errCode = SSL_connect(ssl);
	
	if (errCode < 0)
	{
		SetErrorMessageAndLongIntAndBail("OpenSSL: Can't initiate SSL connection, SSL_connect() = ",errCode);
	}
	
	//	Request the URI from the host
	
	CopyCStrToCStr("GET ",tempString,sizeof(tempString));
	ConcatCStrToCStr(kHTTPS_URI,tempString,sizeof(tempString));
	ConcatCStrToCStr(" HTTP/1.0\r\n\r\n",tempString,sizeof(tempString));

	
	errCode = SSL_write(ssl,tempString,CStrLength(tempString));
	
	if (errCode < 0)
	{
		SetErrorMessageAndLongIntAndBail("OpenSSL: Error writing data via ssl, SSL_write() = ",errCode);
	}
	

	for (;;)
	{
	char	tempString[256];
	int		bytesRead;
		

		//	Read some bytes and dump them to the console
		
		bytesRead = SSL_read(ssl,tempString,sizeof(tempString) - 1);
		
		if (bytesRead == 0 && MacSocket_RemoteEndIsClosing(theSocket))
		{
			break;
		}
		
		else if (bytesRead < 0)
		{
			SetErrorMessageAndLongIntAndBail("OpenSSL: Error reading data via ssl, SSL_read() = ",bytesRead);
		}
		
		
		tempString[bytesRead] = '\0';
		
		printf(tempString);
	}
	
	printf("\n\n\n");
	
	//	All done!
	
	errCode = noErr;
	
	
EXITPOINT:

	//	Clean up and go home
	
	if (theSocket >= 0)
	{
		MacSocket_close(theSocket);
	}
	
	if (ssl != nil)
	{
		SSL_free(ssl);
	}
	
	if (ssl_ctx != nil)
	{
		SSL_CTX_free(ssl_ctx);
	}
	
	
	if (errCode != noErr)
	{
		printf("An error occurred:\n");
		
		printf(GetErrorMessage());
	}
	
	
	MacSocket_Shutdown();
}
