void do_stuff()
{
	char command[256];
	printf("Enter a message and press Return to send. Enter \"exit\" to exit.\n");
	while (1)
	{
		int ret = scanf("%s",command);
		if (strcmp(command,"exit") == 0)
			return;
		else
			spNetSendHTTP(client_connection,command);
	}
}
示例#2
0
文件: client.c 项目: theZiz/hase
pMessage sendMessage(pMessage message,char* binary_name,void* binary,int count,char* dest,char* server)
{
	char boundary[17] = "A9B8C7D6E5F4G3H2"; //This should maybe random...
	int boundary_len = 16;
	int direction = 1;
	if (count < 0)
	{
		count *= -1;
		direction = -1;
	}
	int length = 0;
	pMessage mom = message;
	while (mom)
	{
		mom->l =
			2+boundary_len+2 + //boundary start + return
			39+strlen(mom->name)+2 + //Content-Disposition: form-data; name="<name>" + return
			strlen(mom->content)+4; // content + 2 returns
		length += mom->l;
		mom = mom->next;
	}
	length += boundary_len+2+4; //--boundary-- + 2 returns;
	spNetTCPConnection server_connection = spNetOpenClientTCP(ip);
	if (server_connection == NULL)
		return NULL;
	//int buffer_size = 2048+count;//spMax(length+1,512);
	int buffer_size = 65536;
	char in_buffer[buffer_size];
	char* buffer = in_buffer;
	#ifndef WIN32
		char out_buffer[buffer_size];
	#endif
	char header[4096]; //magic number ftw!
	char host[512];
	int pos = 0;
	mom = message;
	char temp[512];
	while (mom)
	{
		sprintf(temp,
			"\r\n--%s\r\n"
			"Content-Disposition: form-data; name=\"%s\"\r\n"
			"\r\n"
			"%s",boundary,mom->name,mom->content);
		memcpy(&(buffer[pos]),temp,mom->l);
		pos += mom->l;
		mom = mom->next;
	}
	if (binary && direction == 1)
	{
		#ifdef INPUT_COMPRESSION
		if (hase_gzip)
		{
			//compress data
			z_stream strm;
			strm.zalloc = Z_NULL;
			strm.zfree = Z_NULL;
			strm.opaque = Z_NULL;
			strm.avail_in = count;
			strm.next_in = binary;
			if (deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31,8,Z_DEFAULT_STRATEGY) != Z_OK)
			{
				printf("Error: ZStream Init error\n");
				return NULL;
			}
			strm.avail_out = buffer_size;
			strm.next_out = out_buffer;
			switch (deflate(&strm, Z_FINISH))
			{
				case Z_STREAM_ERROR:
					printf("Error: ZStream error\n");
					deflateEnd(&strm);
					return NULL;
				case Z_DATA_ERROR:
					printf("Error: ZStream data error\n");
					return NULL;
				case Z_MEM_ERROR:
					deflateEnd(&strm);
					printf("Error: ZStream mem error\n");
					return NULL;
				case Z_NEED_DICT:
					printf("Error: ZStream need dict error\n");
					return NULL;
			}
			//printf("Compression saved %i%% (%i vs. %i)\n",100-(int)strm.total_out*100/count,(int)strm.total_out,count);
			count = (int)strm.total_out;
			deflateEnd(&strm);
			binary = out_buffer;
		}
		#endif
		length +=
			2+boundary_len+2 + //boundary start + return
			39+strlen(binary_name)+2 + //Content-Disposition: form-data; name="<name>" + return
			count + 4; // content + 2 returns
		int l =
			2+boundary_len+2 + //boundary start + return
			39+strlen(binary_name)+2 + //Content-Disposition: form-data; name="<name>" + return
			4; // content + 2 returns
		sprintf(temp,
			"\r\n--%s\r\n"
			"Content-Disposition: form-data; name=\"%s\"\r\n"
			"\r\n",boundary,binary_name);
		memcpy(&(buffer[pos]),temp,l);
		pos += l;
		memcpy(&(buffer[pos]),binary,count);
		pos += count;
	}
	sprintf(temp,
		"\r\n--%s--",boundary);
	memcpy(&(buffer[pos]),temp,2+4+boundary_len+1);

	sprintf(host,"%s",server);
	char* server_directory = strchr(host,'/');
	if (server_directory)
	{
		server_directory[0] = 0;
		server_directory++;
		sprintf(header,
			"POST /%s/%s HTTP/1.1\r\n"
			"Origin: http://%s\r\n"
			"User-Agent: Hase\r\n"
			"Connection: Close\r\n"
			"Content-Type: multipart/form-data; boundary=%s\r\n"
			"Content-Length: %i\r\n"
			#ifndef WIN32
			"Accept-Encoding: gzip\r\n"
			#endif
			"Host: %s\r\n"
			"\r\n",server_directory,dest,host,boundary,length,host);
	}
	else
	{
		sprintf(header,
			"POST /%s HTTP/1.1\r\n"
			"Origin: http://%s\r\n"
			"User-Agent: Hase\r\n"
			"Connection: Close\r\n"
			"Content-Type: multipart/form-data; boundary=%s\r\n"
			"Content-Length: %i\r\n"
			#ifndef WIN32
			"Accept-Encoding: gzip\r\n"
			#endif
			"Host: %s\r\n"
			"\r\n",dest,host,boundary,length,host);
	}
	//printf("Header:\n%s",header);
	spNetSendHTTP(server_connection,header);
	//printf("\nMessage\n%sEND\n",buffer);
	spNetSendTCP(server_connection,buffer,length);
	int res = spNetReceiveHTTP(server_connection,buffer,buffer_size-1);
	buffer[res] = 0;
	spNetCloseTCP(server_connection);
	//HTTP error check + jumping to begin
	if (
		buffer[ 0] != 'H' ||
		buffer[ 1] != 'T' ||
		buffer[ 2] != 'T' ||
		buffer[ 3] != 'P' ||
		buffer[ 4] != '/' ||
		buffer[ 5] != '1' ||
		buffer[ 6] != '.' ||
		buffer[ 7] != '1' ||
		buffer[ 8] != ' ' ||
		buffer[ 9] != '2' ||
		buffer[10] != '0' ||
		buffer[11] != '0' ||
		buffer[12] != ' ' ||
		buffer[13] != 'O' ||
		buffer[14] != 'K')
		return NULL;
	pos = 15;
	#ifndef WIN32
		int encoded = 0;
	#endif
	int content_length = 0;
	int chunked = 0;
	while (
		buffer[pos  ] != '\r' ||
		buffer[pos+1] != '\n' ||
		buffer[pos+2] != '\r' ||
		buffer[pos+3] != '\n')
	{
		if (buffer[pos] == 0)
			return NULL;
		#ifndef WIN32
		if (
			buffer[pos+ 0] == 'C' &&
			buffer[pos+ 1] == 'o' &&
			buffer[pos+ 2] == 'n' &&
			buffer[pos+ 3] == 't' &&
			buffer[pos+ 4] == 'e' &&
			buffer[pos+ 5] == 'n' &&
			buffer[pos+ 6] == 't' &&
			buffer[pos+ 7] == '-')
		{
			if (
				buffer[pos+ 8] == 'E' &&
				buffer[pos+ 9] == 'n' &&
				buffer[pos+10] == 'c' &&
				buffer[pos+11] == 'o' &&
				buffer[pos+12] == 'd' &&
				buffer[pos+13] == 'i' &&
				buffer[pos+14] == 'n' &&
				buffer[pos+15] == 'g' &&
				buffer[pos+16] == ':' &&
				buffer[pos+17] == ' ' &&
				buffer[pos+18] == 'g' &&
				buffer[pos+19] == 'z' &&
				buffer[pos+20] == 'i' &&
				buffer[pos+21] == 'p')
					encoded = 1;
			else
			if (
				buffer[pos+ 8] == 'L' &&
				buffer[pos+ 9] == 'e' &&
				buffer[pos+10] == 'n' &&
				buffer[pos+11] == 'g' &&
				buffer[pos+12] == 't' &&
				buffer[pos+13] == 'h' &&
				buffer[pos+14] == ':' &&
				buffer[pos+15] == ' ')
					content_length = atoi(&buffer[pos+16]);
		}
		#endif
		if (
			buffer[pos+ 0] == 'T' &&
			buffer[pos+ 1] == 'r' &&
			buffer[pos+ 2] == 'a' &&
			buffer[pos+ 3] == 'n' &&
			buffer[pos+ 4] == 's' &&
			buffer[pos+ 5] == 'f' &&
			buffer[pos+ 6] == 'e' &&
			buffer[pos+ 7] == 'r' &&
			buffer[pos+ 8] == '-' &&
			buffer[pos+ 9] == 'E' &&
			buffer[pos+10] == 'n' &&
			buffer[pos+11] == 'c' &&
			buffer[pos+12] == 'o' &&
			buffer[pos+13] == 'd' &&
			buffer[pos+14] == 'i' &&
			buffer[pos+15] == 'n' &&
			buffer[pos+16] == 'g' &&
			buffer[pos+17] == ':' &&
			buffer[pos+18] == ' ' &&
			buffer[pos+19] == 'c' &&
			buffer[pos+20] == 'h' &&
			buffer[pos+21] == 'u' &&
			buffer[pos+22] == 'n' &&
			buffer[pos+23] == 'k' &&
			buffer[pos+24] == 'e' &&
			buffer[pos+25] == 'd')
			chunked = 1;
		pos++;
	}
	pos+=4;
	if (chunked) //Remove chunk informations
	{
		int difference = 0;
		while (
			buffer[pos + difference + 0] != '\r' ||
			buffer[pos + difference + 1] != '\n')
			difference++;
		int next_chunk = strtol(&(buffer[pos]),NULL,16);
		difference += 2; // \r\n
		int work_pos = pos;
		while (next_chunk)
		{
			int i;
			for (i = work_pos; i < work_pos + next_chunk; i++)
				buffer[i] = buffer[i+difference];
			difference += 2; // \r\n
			work_pos += next_chunk;
			next_chunk = strtol(&(buffer[work_pos+difference]),NULL,16);
			while (
				buffer[work_pos + difference + 0] != '\r' ||
				buffer[work_pos + difference + 1] != '\n')
				difference++;
			difference += 2; // \r\n
		}
		buffer[work_pos] = 0;
		content_length -= difference;
	}
	#ifndef WIN32
	if (encoded)
	{
		z_stream strm;
		strm.zalloc = Z_NULL;
		strm.zfree = Z_NULL;
		strm.opaque = Z_NULL;
		strm.avail_in = content_length;
		strm.next_in = &in_buffer[pos];
		if (inflateInit2 (&strm, 31) != Z_OK)
		{
			printf("Error: ZStream Init error\n");
			return NULL;
		}
		strm.avail_out = buffer_size-pos;
		strm.next_out = &out_buffer[pos];
		switch (inflate(&strm, Z_NO_FLUSH))
		{
			case Z_STREAM_ERROR:
				printf("Error: ZStream error\n");
				inflateEnd(&strm);
				return NULL;
            case Z_DATA_ERROR:
				printf("Error: ZStream data error\n");
				return NULL;
            case Z_MEM_ERROR:
				inflateEnd(&strm);
				printf("Error: ZStream mem error\n");
				return NULL;
            case Z_NEED_DICT:
				printf("Error: ZStream need dict error\n");
				return NULL;

		}
		//printf("Compression saved %i%% (%i vs. %i)\n",100-content_length*100/(int)strm.total_out,content_length,(int)strm.total_out);
		inflateEnd(&strm);
		out_buffer[pos+(int)strm.total_out] = 0;
		buffer = out_buffer;
	}
	else
	#endif
		buffer = in_buffer;
	//printf("%s\n",&buffer[pos]);

	if (direction == -1) //incoming file
	{
		if (buffer[pos+1] == 'A' &&
			buffer[pos+2] == 'C' &&
			buffer[pos+3] == 'K')
		{
			memcpy(binary,&buffer[pos+4],count);
			last_heartbeat_diff = *((int*)(&buffer[pos+4+count]));
			pMessage result = NULL;
			numToMessage(&result,"Okay",1);
			return result;
		}
		if (buffer[pos+1] == 'N' &&
			buffer[pos+2] == 'U' &&
			buffer[pos+3] == 'L')
		{
			memset(binary,1+2+16+32,count);
			last_heartbeat_diff = (int)(buffer[pos+4]);
			pMessage result = NULL;
			numToMessage(&result,"Kicked",1);
			return result;
		}
		if (buffer[pos+1] == 'E' &&
			buffer[pos+2] == 'R' &&
			buffer[pos+3] == 'R')
		{
			last_heartbeat_diff = (int)(buffer[pos+4]);
			return NULL;
		}
		return NULL;
	}
	//Parsing in init style
	pMessage result = NULL;
	char* found;
	char* rest = &buffer[pos];
	//printf("_____\n%s\n^^^^^\n",rest);
	while ((found = strchr(rest,'\n')) || (found = strchr(rest,0)))
	{
		char exit_afterwards = 0;
		if (found[0] == 0)
			exit_afterwards = 1;
		found[0] = 0;
		char* line = rest;
		char* middle = strchr(line,':');
		if (middle && line[0] != '<') //some free hosting website add statistic bullshit
		{
			middle[0] = 0;
			middle++;
			middle++;
			addToMessage(&result,line,middle);
			//printf("Add %s -> %s\n",line,middle);
		}
		if (exit_afterwards)
			break;
		rest = ++found;
	}
	return result;
}