bool Http_Func::GetRequestString(const wchar_t* cmd,const wchar_t* url,const wchar_t* head,const wchar_t* content,wstring*res){ #define HTTP_VERSION_TEXT TEXT("HTTP/1.1") wstring host,a,path; UrlSplit(url,&a,&host,&path); bool get=false; if(wcscmp(cmd,TEXT("GET"))==0||wcscmp(cmd,TEXT("HEAD"))==0){ get=true; } res->clear(); res->append(cmd).append(TEXT(" ")); res->append(path); if(get&&lstrlen(content)!=0){ res->append(TEXT("?")).append(content); } res->append(TEXT(" ")).append(HTTP_VERSION_TEXT).append(TEXT("\r\n")); res->append(TEXT("Host:")).append(host).append(TEXT("\r\n")); res->append(head); res->append(TEXT("\r\n")); if(!get){ res->append(content); } res->append(TEXT("\r\n")); #undef HTTP_VERSION_TEXT return true; }
int btTracker::Initial() { if( UrlSplit(m_spec->url, &m_spec->host, &m_spec->port, &m_spec->request) < 0 ){ CONSOLE.Warning(1, "Error parsing tracker URL (%s): %s", m_spec->url, errno ? strerror(errno) : "invalid format"); return -1; } char chars[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for( int i=0; i<8; i++ ) m_key[i] = chars[RandBits(6) % 36]; m_key[8] = 0; if( BuildBaseRequest() < 0 ) return -1; return 0; }
dt_result_t btTracker::CheckResponse() { const char *pdata; ssize_t r; size_t q, hlen, dlen; r = m_response_buffer.FeedIn(m_sock); m_last_timestamp = now; if( r > 0 ){ // connection is still open; may have more data coming return DT_NORMAL; } q = m_response_buffer.Count(); if( !q ){ int error = 0; socklen_t n = sizeof(error); if( getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ) error = errno; if( error ){ CONSOLE.Warning(2, "warn, received nothing from tracker at %s: %s", m_spec->url, strerror(error)); }else{ CONSOLE.Warning(2, "warn, received nothing from tracker at %s", m_spec->url); } Reset(); // try again return DT_FAILURE; } hlen = HttpSplit(m_response_buffer.BasePointer(), q, &pdata, &dlen); if( !hlen ){ CONSOLE.Warning(2, "warn, no HTTP header in response from tracker at %s", m_spec->url); return DT_FAILURE; } r = HttpGetStatusCode(m_response_buffer.BasePointer(), hlen); if( r != 200 ){ if( r == 301 || r == 302 || r == 303 || r == 307 ){ char *tmpurl = (char *)0, *c; tracker_spec *tmpspec; if( HttpGetHeader(m_response_buffer.BasePointer(), hlen, "Location", &tmpurl) < 0 ){ if( errno ){ CONSOLE.Warning(2, "Error parsing redirect response from tracker at %s: %s", m_spec->url, strerror(errno)); }else{ CONSOLE.Warning(2, "warn, redirect with no location from tracker at %s", m_spec->url); } if( tmpurl ) delete []tmpurl; return DT_FAILURE; } if( !(tmpspec = new tracker_spec) ){ CONSOLE.Warning(1, "warn, could not allocate memory for tracker redirect from %s", m_spec->url); errno = ENOMEM; delete []tmpurl; return DT_FAILURE; } if( (c = strstr(tmpurl, "?info_hash=")) || (c = strstr(tmpurl, "&info_hash=")) ){ *c = '\0'; } if( UrlSplit(tmpurl, &tmpspec->host, &tmpspec->port, &tmpspec->request) < 0 ){ CONSOLE.Warning(1, "warn, error parsing redirected tracker URL from %s (%s): %s", m_spec->url, tmpurl, errno ? strerror(errno) : "invalid format"); delete tmpspec; delete []tmpurl; return DT_FAILURE; }else{ CONSOLE.Debug("tracker at %s redirected%s to %s", m_spec->url, (r == 301) ? " permanently" : "", tmpurl); if( (tmpspec->url = new char[strlen(tmpurl) + 1]) ) strcpy(tmpspec->url, tmpurl); else{ CONSOLE.Warning(1, "warn, could not allocate memory for tracker redirect from %s", m_spec->url); errno = ENOMEM; delete tmpspec; delete []tmpurl; return DT_FAILURE; } delete []tmpurl; Reset(); m_redirect = m_spec; m_spec = tmpspec; if( BuildBaseRequest() < 0 ){ delete m_spec; m_spec = m_redirect; m_redirect = (tracker_spec *)0; return DT_FAILURE; }else if( r == 301 ){ // moved permanently delete m_redirect; m_redirect = (tracker_spec *)0; } } if( Connect() < 0 ){ Reset(); delete m_spec; m_spec = m_redirect; m_redirect = (tracker_spec *)0; return DT_FAILURE; }else return DT_NORMAL; }else if( r >= 400 ){ CONSOLE.Warning(2, "Tracker response code %d from %s%s", r, m_spec->url, (r >= 500) ? "" : "; the torrent is not registered on this tracker" " or may have been removed."); if( pdata && dlen ){ // write(STDERR_FILENO, pdata, dlen); char data[dlen + 1]; memcpy(data, pdata, dlen); data[dlen] = '\0'; CONSOLE.Warning(0, "Tracker response data DUMP:"); CONSOLE.Warning(0, "%s", data); CONSOLE.Warning(0, "== DUMP OVER=="); } m_interval = (m_default_interval > 300) ? m_default_interval : 300; m_f_started = 0; return DT_FAILURE; }else{ m_f_started = 0; return DT_FAILURE; } } m_f_started = m_f_stop ? 0 : 1; m_refuse_click = 0; m_ok_click++; if( !pdata ){ CONSOLE.Warning(2, "warn, received no response data from tracker at %s", m_spec->url); return DT_FAILURE; } return ParseResponse(pdata, dlen); }