#include "StdAfx.h"
#include "sock_http.h"
#include "_error.h"
#include "utiles_dll.h"

#define INCREMENTO_MINIMO_SOC_HTTP	1024


//********************************************************************
Csock_http::Csock_http( C_error* e/*=NULL*/ )
{
	buf=NULL;
	n=m=0;
	if (e)
	{
		er=e;
		er_ex=TRUE;
	}
	else
	{
		er=new C_error();
		er_ex=FALSE;
	}
	pirate=FALSE;
}

//********************************************************************
Csock_http::~Csock_http(void)
{
	if (buf)
		free(buf);
	if (!er_ex && er)
		delete er;
}
//********************************************************************
BOOL Csock_http::cuida_mem( int i )
{
	int incre=n+i-m;
	if (incre>0)
	{
		if (incre<INCREMENTO_MINIMO_SOC_HTTP)
			incre=INCREMENTO_MINIMO_SOC_HTTP;
		m+=incre;
		buf=(char*)realloc(buf,m);
		if (!buf)
		{
			if (er)
				er->pon("Csock_http","Sin memoria");
			return FALSE;
		}
		memset(&buf[m-incre],0,incre);
	}
	return TRUE;
}
//********************************************************************
BOOL Csock_http::carga( char *url, int puerto )
{
	Cutiles_dll dll;
	int i, nb;//,vec;
	char *st;
	char srv[256];
	Close();
	Create();
	n=0;
	if (!cuida_mem(32+(int)strlen(url)+1))
		return FALSE;
	st=strstr(url,"/");
	if (!st)
	{
		if(er)
			er->pon("Csock_http", "Argumento url incorrecto");
		return FALSE;
	}
	
	n=(int)strlen(buf);
	//strcpy(srv,"http://");
	//nb=strlen(srv);
	for (i=0; i<254 && st!=&url[i]; i++)
		srv[i/*+nb*/]=url[i];
	
	srv[i]=0;
	nb=0;
	sprintf(buf,"GET %s HTTP/1.1\r\nHOST: http://%s\r\n\r\n", st, srv);
	//sprintf(buf, "GET /index.html HTTP/1.1\nHOST: %s\n\n",st,srv);
	
	if(!Connect(srv,puerto))
	{
		i = GetLastError();
		if(i != WSAEWOULDBLOCK)
		{
			if (er)
			{
				er->pon_win("Csock_http");
			}
			return FALSE;
		}
	}

	Sleep(1000);
	//envia----------------------------------------------
	nb=n;
	if(pirate)
	{
		if(er)
			er->pon("Csock_http", "Salida forzosa");
		Close();
		return FALSE;
	}
	while(nb>0 && !pirate)
	{
		i=Send(&buf[n-nb],nb);
		if (i<0)
		{
			i = GetLastError();
			if(i != WSAEWOULDBLOCK)
			{
				Close();
				if(er)
					er->pon_win("Csock_http");
				return FALSE;
			}
			Sleep(100);
		}
		else
			nb-=i;
	}
	if (pirate)
	{
		if(er)
			er->pon("Csock_http", "Salida forzosa");
		Close();
		return FALSE;
	}
	//recibe-----------------------------------------------------
	nb=n=0;
	i=1;
	while(nb<10000)
	{
		//revisa memoria--------------------------
		if (m-n<64 && !cuida_mem(128))
		{
			if (er)
			{
				er->pon("Csock_http", "Sin memoria suficiente");
			}
			Close();
			return FALSE;
		}
		i=Receive(&buf[n],m+1-n);
		if (i<0)
		{
			i = GetLastError();
			if(i != WSAEWOULDBLOCK)
			{
				if (er)
				{
					er->pon_win("Csock_http");
				}
				Close();
				return FALSE;
			}
			Sleep(10);
			nb++;
		}
		else if(i==0)
			nb++;
		else
		{
			nb=0;
			n+=i;
		}
		//fuerza salida----------------------------------
		if (pirate)
		{
			if(er)
				er->pon("Csock_http", "Salida forzosa");
			Close();
			return FALSE;
		}
	}
	Close();
	//asegura null----------------------------------------
	if (m-n<1)
	{
		if(!cuida_mem(1))
		{
			if (er)
			{
				er->pon("Csock_http", "Sin memoria suficiente");
			}
			return FALSE;
		}
		buf[n]=0;
		n++;
	}
	return TRUE;
}
//********************************************************************
char * Csock_http::get( int *nb )
{
	if (n==0 && !buf)
		return NULL;
	return buf;
}
//********************************************************************