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