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); } }
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; }