#ifdef _WIN32
#include <winsock.h>
#else
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>


#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>

u_long resolveHost(char*);

#define HDR_TEMPLATE "PUT %s HTTP/1.1\r\nHost: %s:%s\r\nPragma: no-cache\r\n\
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n\
Authorization: Basic anJzY2xpZW50Ompyc2NsaWVudA==\r\n\
Cache-control: no-cache\r\n\
Content-Type: application/octet-stream\r\n\
Content-Length: %d\r\n\r\n"

// pass file, host, port, remote file, i.e.
int main(int argc, char* argv[]) 
{
	char buf[8192];

	time_t start = 0;
	time_t end = 0;
	int total = 0;
	int i = 0;
	struct sockaddr_in sin;
	u_long host = 0;
	int ret = 0;
	FILE* fp = NULL;
	long filesize = 0;
#ifdef _WIN32
	WSADATA winsock_data;
	SOCKET sock;
#else
	int sock;
#endif

	if(argc != 5)
	{
	  printf("usage: httpput file host port dir\n");
	  exit(1);
	}

#ifdef _WIN32
	WSAStartup(0x0101, &winsock_data);
#endif

	fp = fopen(argv[1], "rb");
	fseek(fp, 0, 2);
	filesize = ftell(fp);
	rewind(fp);

	sprintf(buf, HDR_TEMPLATE, argv[4], argv[2], argv[3], filesize);

	printf("HTTP HEADER:\n%s", buf);

	if((host = resolveHost(argv[2])) == 0)
	{
	  printf("could not resolve host %s\n", argv[2]);
	  exit(1);
	}

	memset((void *)&sin, 0,  sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = host;
	sin.sin_port = htons((short)atoi(argv[3]));

	sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	printf("Connecting...\n");

	connect(sock, (struct sockaddr *) &sin, sizeof(sin));

	printf("Sending HTTP header...\n");

	send(sock, buf, strlen(buf), 0);

	time(&start);

	printf("Sending file...\n");

	while(!feof(fp))
	{
		int read = fread(buf, 1, 8192, fp);
		total += send(sock, buf, read, 0);
	}

	fclose(fp);

	send(sock, "\r\n", 2, 0);

	printf("Receiving response...\n");

	ret = recv(sock, buf, sizeof(buf), 0);

	time(&end);

	buf[ret] = 0;

	printf("%s\n", buf);

#ifdef _WIN32
	closesocket(sock);
	WSACleanup();
#else
	close(sock);
#endif

	printf("Sent: %d bytes in %d seconds\n", total, (end-start));

	return 0;
}

u_long resolveHost(char* host)
{
	u_long hostAddr;
	struct hostent* h;

	hostAddr = inet_addr(host);

	if(hostAddr != -1L)
	{
		return hostAddr;
	}

	h = gethostbyname(host);

	if(h)
	{
		hostAddr = *((u_long*)(h->h_addr));
		return hostAddr;
	}
	else
	{
		return 0L;
	}
}
