char * createTrackerMessage( struct torrentInfo * torrent, int msgType ) { char * request = Malloc( 1024 * sizeof(char)) ; request[1023] = '\0'; char * infoHash = percentEncode( torrent->infoHash, 20 ); char * peerID = percentEncode( torrent->peerID, 20 ); int uploaded = torrent->numBytesUploaded; int downloaded = torrent->numBytesDownloaded; int left = torrent->totalSize - torrent->numBytesDownloaded; char event[32]; if ( msgType == TRACKER_STARTED ) { strncpy( event, "event=started&", 31 ); } else if ( msgType == TRACKER_STOPPED ) { strncpy( event, "event=stopped&", 31 ); } else if ( msgType == TRACKER_COMPLETED ) { strncpy( event, "event=completed&", 31 ); } else { event[0] = '\0'; } char ip[25]; ip[0] = '\0'; if ( torrent->bindAddress != INADDR_ANY ) { struct in_addr in; in.s_addr = torrent->bindAddress; snprintf( ip, 24, "ip=%s&", inet_ntoa( in ) ); } snprintf(request, 1023, "GET /announce?" "info_hash=%s&" "peer_id=%s&" "port=%d&" "uploaded=%d&" "downloaded=%d&" "left=%d&" "compact=1&" "no_peer_id=1&" "%s" // Event string, if present "%s" // IP string, if present "numwant=50 " "HTTP/1.1\r\nHost: %s:%d\r\n\r\n", infoHash, peerID, torrent->bindPort, uploaded, downloaded, left, event, ip, torrent-> trackerDomain, torrent->trackerPort); free( infoHash ); free( peerID ); return request; }
static STSStatus compose_canonicalized_query_string(char* buffer, uint32_t bufferSize, uint32_t* len, char* paramsArray[], uint32_t paramsCount) { int i = 0; *len = 0; char* pBuffer = &(buffer[0]); for (i = 0; i < paramsCount; ++i) { char* begin = paramsArray[i]; char* middle = strchr(begin, '='); char* end = strchr(begin, '&'); size_t size = 0; if (NULL != end) { size = end - begin + 1; } else { size = strlen(begin) + 1; } size_t keyLen = middle - begin; char* key = begin; size_t valueLen = size - keyLen - 2; char* value = middle + 1; char* encodedKey = calloc(keyLen*3, 1); char* encodedValue = calloc(valueLen*3, 1); percentEncode(encodedKey, key, keyLen); percentEncode(encodedValue, value, valueLen); snprintf(pBuffer, strlen(encodedKey)+2, "%s=", encodedKey); *len += strlen(encodedKey) + 1; pBuffer = buffer + *len; snprintf(pBuffer, strlen(encodedValue)+2, "%s&", encodedValue); *len += strlen(encodedValue) + 1; pBuffer = buffer + *len; free(encodedKey); free(encodedValue); } *(--pBuffer) = '\0'; *len -= 1; return STSStatusOK; }
std::string URI::toString() const { std::string Result; llvm::raw_string_ostream OS(Result); OS << percentEncode(Scheme) << ":"; if (Authority.empty() && Body.empty()) return OS.str(); // If authority if empty, we only print body if it starts with "/"; otherwise, // the URI is invalid. if (!Authority.empty() || llvm::StringRef(Body).startswith("/")) OS << "//" << percentEncode(Authority); OS << percentEncode(Body); OS.flush(); return Result; }
static STSStatus compute_signature(char* buffer, uint32_t bufferSize, char* paramsArray[], const uint32_t paramsCount, const char* accessKeySecret) { ////////////////////////////////////////////////////////////////////////// // sign uint32_t canonLen = 0; char canonicalizedQueryString[2048 * 3]; compose_canonicalized_query_string(canonicalizedQueryString, 2048 * 3, &canonLen, paramsArray, paramsCount); string_buffer(strToSign, 2048 * 3); string_buffer_initialize(strToSign); int fit; string_buffer_append(strToSign, "POST&%2F&", 9, fit); if (!fit) { return STSStatusUriTooLong; } string_buffer(percentTwice, 2048 * 3); string_buffer_initialize(percentTwice); percentEncode(percentTwice, canonicalizedQueryString, canonLen); string_buffer_append(strToSign, percentTwice, strlen(percentTwice), fit); //fprintf(stdout, "strToSign(%lu): %s\n", strlen(strToSign), strToSign); // Generate an HMAC-SHA-1 of the strToSign size_t akSecretLen = strlen(accessKeySecret); char newAccessKeySecret[akSecretLen + 1]; snprintf(newAccessKeySecret, akSecretLen+2, "%s&", accessKeySecret); unsigned char hmac[20]; STS_HMAC_SHA1(hmac, (unsigned char *) newAccessKeySecret, strlen(newAccessKeySecret), (unsigned char *) strToSign, strlen(strToSign)); // Now base-64 encode the results char b64[((20 + 1) * 4) / 3]; int b64Len = base64Encode(hmac, 20, b64); char b64Encoded[256]; if (!urlEncode(b64Encoded, b64, b64Len)) { return STSStatusUriTooLong; } snprintf(buffer, strlen(b64Encoded)+1, "%s", b64Encoded); return STSStatusOK; }
String::CPtr percentEncode(String::CPtr str, String::Encoding enc) { static const Boolean isBigEndian = endian() == BIG; if (!str || str->length() == 0) return String::create(); Buffer::Ptr buf; switch (enc) { case String::UTF8: buf = Buffer::create(str, Buffer::UTF8); break; case String::UTF16: if (isBigEndian) { buf = Buffer::create(str, Buffer::UTF16BE); } else { buf = Buffer::create(str, Buffer::UTF16LE); } break; case String::UTF16BE: buf = Buffer::create(str, Buffer::UTF16BE); break; case String::UTF16LE: buf = Buffer::create(str, Buffer::UTF16LE); break; case String::UTF32: if (isBigEndian) { buf = Buffer::create(str, Buffer::UTF32BE); } else { buf = Buffer::create(str, Buffer::UTF32LE); } break; case String::UTF32BE: buf = Buffer::create(str, Buffer::UTF32BE); break; case String::UTF32LE: buf = Buffer::create(str, Buffer::UTF32LE); break; default: assert(false); buf = Buffer::null(); } Size sourceLen = buf->length(); const char* source = static_cast<const char*>(buf->data()); Size encodedLen = sourceLen * 3 + 1; char* encoded = new char[encodedLen]; percentEncode(encoded, encodedLen, source, sourceLen); String::CPtr res = String::create(encoded); delete[] encoded; return res; }