void getClient(char * serverAddress) { int sockFd = makeSocketOrDie(); struct addrinfo * serverInfo = getServerInfo(serverAddress); printf("Connecting to server\n"); connectOrDie(sockFd, serverInfo); printf("Connected to server. Making LIBSSH2 session\n"); LIBSSH2_SESSION * session = makeSession(); libssh2_session_set_blocking(session, 1); libssh2_session_set_timeout(session, 5000); printf("Made session, handshaking\n"); int result = libssh2_session_handshake(session, sockFd); //const char * fingerprint = libssh2_hostkey_hash(session, LIBSSH_HOSTKEY_HASH_SHA1); //TODO: Match the fingerprint against something. if (result) { char * errorMessage; libssh2_session_last_error(session, &errorMessage, NULL, 0); fprintf(stderr, "Error %s handshaking\n", errorMessage); exit(EXIT_FAILURE); } printf("Handshake completed, making SFTP Session\n"); libssh2_userauth_password(session, NETID, PWD); LIBSSH2_SFTP * sftpSession = makeSFTPSession(session); printf("Started SFTP - Downloading file\n"); LIBSSH2_SFTP_HANDLE * fileHandle = libssh2_sftp_open(sftpSession, serverFilePath, LIBSSH2_FXF_READ, 0); readFile(session, sftpSession, fileHandle); libssh2_sftp_shutdown(sftpSession); libssh2_session_disconnect(session, "Done.\n"); libssh2_session_free(session); freeaddrinfo(serverInfo); close(sockFd); }
bool HttpProtocolData::splitMaxSession(HttpTask *task) { LOG(0, "enter splitMaxSession, task = %p\n", task); if (task->sessions.size() == 0) { LOG(0, "no session find in task\n"); return false; } HttpSession *maxLengthSes = task->sessions.front(); for (Sessions::iterator it = task->sessions.begin() + 1; it != task->sessions.end(); ++it) { if ((*it)->length > maxLengthSes->length) { maxLengthSes = *it; } } if ( maxLengthSes->length < (task->conf.minSessionBlocks * task->conf.bytesPerBlock * 2) ) { LOG(0, "don't have enough length to split\n"); return false; } size_t begin0 = maxLengthSes->pos / task->conf.bytesPerBlock; size_t length0 = maxLengthSes->length / task->conf.bytesPerBlock; size_t length = length0 / 2; size_t begin = (begin0 + length) * task->conf.bytesPerBlock; length0 = begin - maxLengthSes->pos; length = maxLengthSes->length - length0; maxLengthSes->length = length0; char logBuffer[64]; snprintf(logBuffer, 63, "split session at %lu, length %d", maxLengthSes->pos, maxLengthSes->length); task->info->taskLog(task->info, logBuffer); makeSession(task, begin, length); return true; }
void HttpProtocolData::checkSession(HttpSession *ses) { LOG(0, "enter checkSession, ses = %p in task = %p\n", ses, ses->t); HttpTask *task = ses->t; LOG(0, "check task %p session from %lu, len %d, sessions size = %lu\n", task->info, ses->pos, ses->length, task->sessions.size()); if (ses->length > 0) { LOG(0, "session length is not 0.\n"); } removeSession(ses); size_t begin; size_t len; if (findNonDownload(task, &begin, &len)) { makeSession(task, begin, len); } else if (task->sessions.size() == 0) { TaskInfo *info = task->info; LOG(0, "task %p finish\n", info); task->info->downloadFinish(info); p->removeTask(info); } else { splitMaxSession(task); } }
void HttpProtocolData::initTask(HttpTask *task) { LOG(0, "enter initTask, task = %p\n", task); HttpSession *ses = task->sessions[0]; TaskInfo *info = task->info; CURL *ehandle = ses->handle; char logBuffer[64] = {0}; info->mimeType = getMimeType(ehandle, info->uri); snprintf(logBuffer, 63, "mime type: %s", info->mimeType.c_str()); info->taskLog(info, logBuffer); // get file information. double length; if (info->outputName.length() == 0) info->outputName = getFileName(ehandle, info->uri); std::string output = info->outputPath; output.append(info->outputName); if (info->totalSize == 0) { File::remove(output.c_str()); } task->file.open(output.c_str(), OF_Create | OF_Write); if (!task->file.isOpen()) throw DOWNLOADEXCEPTION(FAIL_OPEN_FILE, "HTTP", strerror(FAIL_OPEN_FILE)); snprintf(logBuffer, 63, "File path: %s", output.c_str()); info->taskLog(info, logBuffer); if (info->totalSize == 0) { CURLcode rete = curl_easy_getinfo(ehandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length); CHECK_CURLE(rete); if (length > 0) { info->totalSize = static_cast<size_t>(length); info->downloadMap = BitMap(size_t(length), task->conf.bytesPerBlock); info->downloadMap.setAll(false); info->validMap = BitMap(size_t(length), task->conf.bytesPerBlock); info->validMap.setAll(true); snprintf(logBuffer, 63, "File length: %lu", info->totalSize); info->taskLog(info, logBuffer); task->file.resize(info->totalSize); } else if (length < 0) info->totalSize = 0; else // length == 0, zero length file return; } info->totalSource = info->validSource = 1; if (info->totalSize > 0) // may equal 0 mean unknow length. { LOG(0, "make download sessions\n"); // seperate download part in 2 steps: // 1 give each non-download part a session; // 2 find a biggest part and divide, repeat till enough session. unsigned int begin = ses->pos / info->downloadMap.bytesPerBit(); unsigned int end = info->downloadMap.find(true, begin); unsigned int nextBegin = info->downloadMap.find(false, end); ses->length = (end - begin) * info->downloadMap.bytesPerBit(); int i = 1; begin = nextBegin; while ( (i < task->conf.sessionNumber) && (begin < info->downloadMap.size()) ) { end = info->downloadMap.find(true, begin); nextBegin = info->downloadMap.find(false, end); // make [begin, end) a seesion. makeSession(task, begin * info->downloadMap.bytesPerBit(), (end - begin) * info->downloadMap.bytesPerBit()); ++i; begin = nextBegin; } while (i < task->conf.sessionNumber) { if (!splitMaxSession(task)) { break; } ++i; } } task->state = HT_DOWNLOAD; }