void doit(int index)//, CycList<zip*>* zipList) { char* qualifiedName = "C:/Users/Ahmad/Downloads/test"; m.lock(); CRC crclib; crclib.partialCompute((uint8_t *)qualifiedName, 0, _strlen(qualifiedName)); uint32_t crc = crclib.GetCRC32(); uint64_t zipCount = zipList.count; uint32_t i; for (i = 0; i < zipCount && zipList[i]->crc != crc; i++); zip* cur; if (i == zipCount) { cur = new zip(true); cur->crc = crc; if (zipList.count == ZIPLISTCAP) delete zipList[zipList.index + 1 % ZIPLISTCAP]; zipList.append(cur); cur->zs->addDirectory(qualifiedName); } else cur = zipList[i]; m.unlock(); std::ostringstream ss; ss << "c:/users/ahmad/desktop/custom/test" << index; std::ofstream outfile(ss.str(), std::ios::binary); cur->m.lock(); cur->zs->buildStream(); cur->m.unlock(); int64_t streamSize = cur->zs->getStreamSize(); uint64_t from = (streamSize / THREADCOUNT + 1) * index; uint64_t to = from + streamSize / THREADCOUNT; if (index == THREADCOUNT - 1) to = streamSize - 1; uint64_t targetLength; for (uint64_t i = from; i <= to; i += targetLength) { targetLength = MIN(10240, to - i + 1); cur->zs->printBytes(i, i + targetLength - 1, outfile.rdbuf()); } //cur->zs->printBytes(from, to, outfile.rdbuf()); outfile.close(); }
static void* Listen(void* arg) { sigset_t* set = (sigset_t *)arg; FCGX_Request request; FCGX_InitRequest(&request, 0, 0); static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&accept_mutex); int rc = FCGX_Accept_r(&request); //Accept new request pthread_create(&lastThread, NULL, Listen, (void*)arg); //Listen for next request pthread_mutex_unlock(&accept_mutex); if (rc < 0) return NULL; fcgi_streambuf cout_fcgi_streambuf(request.out); const char* uri = FCGX_GetParam("REQUEST_URI", request.envp); uint32_t urisize = _strlen(uri); while (urisize > 0 && uri[urisize - 1] == '/') ((char*)uri)[--urisize] = '\0'; const char* root = FCGX_GetParam("DOCUMENT_ROOT", request.envp); char* qualifiedName = new char[_strlen(root) + _strlen(uri) + 1]; memcpy(qualifiedName, root, _strlen(root)); memcpy(qualifiedName + _strlen(root), uri, _strlen(uri) + 1); DIR* dp = opendir(qualifiedName); if (dp == NULL) { FCGX_FPrintF(request.out, "Status: 404 Not Found\r\n\r\n"); FCGX_Finish_r(&request); return NULL; } (void)closedir(dp); char* rangeStr = FCGX_GetParam("HTTP_RANGE", request.envp); bool isPartial = false; List<range> rangeList; if (rangeStr) { isPartial = true; int32_t rangeLen = _strlen(rangeStr); for (; rangeStr[0] != '='; rangeStr++, rangeLen--); rangeStr++; rangeLen--; while (rangeLen > 0) { range cur; int32_t i; for (; rangeStr[0] == ' '; rangeStr++, rangeLen--); for (i = 0; i < rangeLen && rangeStr[i] != '-'; i++); rangeStr[i] = '\0'; if (_strlen(rangeStr) == 0) cur.from = -1; else cur.from = atol(rangeStr); rangeStr += ++i; rangeLen -= i; for (; rangeStr[0] == ' '; rangeStr++, rangeLen--); for (i = 0; i < rangeLen && rangeStr[i] != ','; i++); rangeStr[i] = '\0'; if (_strlen(rangeStr) == 0) cur.to = -1; else cur.to = atol(rangeStr); rangeStr += ++i; rangeLen -= i; rangeList.append(cur); } } m.lock(); CRC crclib; crclib.partialCompute((uint8_t *)qualifiedName, 0, _strlen(qualifiedName)); uint32_t crc = crclib.GetCRC32(); uint64_t zipCount = zipList.count; uint32_t i; for (i = 0; i < zipCount && zipList[i]->crc != crc; i++); zip* cur; if (i == zipCount) { cur = new zip(); cur->crc = crc; if (zipList.count == ZIPLISTCAP) delete zipList[zipList.index + 1 % ZIPLISTCAP]; zipList.append(cur); cur->zs.addDirectory(qualifiedName); } else cur = zipList[i]; m.unlock(); cur->m.lock(); cur->zs.buildStream(); cur->m.unlock(); if (isPartial) FCGX_FPrintF(request.out, "Status: 206 Partial Content\r\n"); FCGX_FPrintF(request.out, "Accept-Ranges: bytes\r\n" "Content-type: application/octet-stream\r\n" "Content-Disposition: attachment; filename=\"zs_%s.zip\"\r\n" "X-Threads: %d\r\n", qualifiedName + getFileNameOffset(qualifiedName), -1); int64_t streamSize = cur->zs.getStreamSize(); if (!isPartial) { range full; full.from = 0; full.to = streamSize - 1; rangeList.append(full); } range& first = rangeList[0]; if (first.to == -1) first.to = streamSize - 1; else if (first.from == -1) { first.from = streamSize - first.to; first.to = streamSize - 1; } if (isPartial) FCGX_FPrintF(request.out, "Content-Range: bytes %lu-%lu/%lu\r\n", first.from, first.to, streamSize); FCGX_FPrintF(request.out, "Content-Length: %lu\r\n" "\r\n", first.to - first.from + 1); uint32_t error_code; uint32_t error_code_size = sizeof(error_code); uint64_t targetLength; timespec w; memset(&w, 0, sizeof(w)); siginfo_t info; for (uint64_t c = first.from; c <= first.to && sigtimedwait(set, &info, &w) == -1; c += targetLength) { getsockopt(request.ipcFd, SOL_SOCKET, SO_ERROR, &error_code, (socklen_t *)&error_code_size); if (error_code != 0) exit(1996); targetLength = MIN(1024 * 1024, first.to - c + 1); cur->zs.printBytes(c, c + targetLength - 1, &cout_fcgi_streambuf); } //cur->zs.printBytes(first.from, first.to, &cout_fcgi_streambuf); delete[] qualifiedName; FCGX_Finish_r(&request); return NULL; }