3131#include " CommonLib/UrlCode.h"
3232#include " SpawnProcess.h"
3333#include " FastCgi/FastCgi.h"
34+ #include " MappedFile.h"
3435
3536using namespace std ;
3637using namespace std ::placeholders;
@@ -2489,33 +2490,57 @@ void CHttpServ::DoAction(const MetaSocketData soMetaDa, const uint8_t httpVers,
24892490 }
24902491
24912492 // Load file
2492- fstream fin ( FN_CA (strItemPath), ios_base::in | ios_base::binary) ;
2493- if (fin. is_open ( ) == true )
2493+ MappedFile map ;
2494+ if (map. open (strItemPath ) == true )
24942495 {
2495- uint64_t nFSize = stFileInfo.st_size ;
2496+ // std::deque<std::tuple<uint8_t, uint8_t*, uint64_t>> queMem2Send;
2497+ // queMem2Send.emplace_back(0, map.data(), map.size()); // Dummy packet to indicate the start of the data stream
2498+
2499+ uint64_t nFSize = map.size ();
24962500 if (vecRanges.size () == 1 ) // Momentan nur 1 Range
24972501 {
2498- nFSize = vecRanges[0 ].second - vecRanges[0 ].first ;
2499- fin.seekg (vecRanges[0 ].first , ios_base::beg);
2500- umPhpHeaders.emplace_back (make_pair (" Content-Range" , " bytes " + to_string (vecRanges[0 ].first ) + " -" + to_string (vecRanges[0 ].second ) + " /" + to_string (stFileInfo.st_size )));
2501- iStatus = 206 ;
2502+ // OutputDebugStringA(std::string("Range requested, nFSize=" + std::to_string(nFSize) + ", Range from: " + std::to_string(vecRanges[0].first) + " bis " + std::to_string(vecRanges[0].second) + "\r\n").c_str());
2503+ if (vecRanges[0 ].first < nFSize && vecRanges[0 ].second <= nFSize && vecRanges[0 ].second >= vecRanges[0 ].first )
2504+ {
2505+ nFSize = vecRanges[0 ].second - vecRanges[0 ].first ;
2506+ map.setOffset (vecRanges[0 ].first );
2507+ umPhpHeaders.emplace_back (make_pair (" Content-Range" , " bytes " + to_string (vecRanges[0 ].first ) + " -" + to_string (vecRanges[0 ].second ) + " /" + to_string (stFileInfo.st_size )));
2508+ iStatus = 206 ;
2509+ }
2510+ else
2511+ OutputDebugStringA (std::string (" Invalid Range requested, nFSize=" + std::to_string (nFSize) + " , Range from: " + std::to_string (vecRanges[0 ].first ) + " bis " + std::to_string (vecRanges[0 ].second ) + " \r\n " ).c_str ());
25022512 }
25032513 else
25042514 umPhpHeaders.emplace_back (make_pair (" Accept-Ranges" , " bytes" ));
25052515
25062516 const auto acceptencoding = lstHeaderFields.find (" accept-encoding" );
25072517 if (acceptencoding != end (lstHeaderFields))
25082518 {
2519+ // OutputDebugStringA(string("accept-encoding: " + lstHeaderFields.find("accept-encoding")->second + "\r\n").c_str());
25092520 // http://www.filesignatures.net/index.php?page=all
25102521 if (find_if (begin (m_vHostParam[szHost].m_vDeflateTyps ), end (m_vHostParam[szHost].m_vDeflateTyps ), [&](const string& strType) noexcept { return strType == strMineType ? true : false ; }) != end (m_vHostParam[szHost].m_vDeflateTyps ))
25112522 {
25122523 if (acceptencoding->second .find (" br" ) != string::npos) iHeaderFlag |= BROTLICODING;
25132524 else if (acceptencoding->second .find (" gzip" ) != string::npos) iHeaderFlag |= GZIPENCODING;
25142525 else if (acceptencoding->second .find (" deflate" ) != string::npos) iHeaderFlag |= DEFLATEENCODING;
2526+
2527+ const auto xPrefCompAlgo = lstHeaderFields.find (" x-prefcompalgo" );
2528+ if (xPrefCompAlgo != end (lstHeaderFields))
2529+ {
2530+ // OutputDebugStringA(string("x-prefcompalgo: " + xPrefCompAlgo->second + "\r\n").c_str());
2531+ iHeaderFlag &= ~BROTLICODING;
2532+ iHeaderFlag &= ~DEFLATEENCODING;
2533+ iHeaderFlag &= ~GZIPENCODING;
2534+ if (xPrefCompAlgo->second == " gzip" )
2535+ iHeaderFlag |= GZIPENCODING;
2536+ else if (xPrefCompAlgo->second == " deflate" )
2537+ iHeaderFlag |= DEFLATEENCODING;
2538+ else if (xPrefCompAlgo->second == " br" )
2539+ iHeaderFlag |= BROTLICODING;
2540+ }
25152541 }
25162542 }
25172543
2518- // iHeaderFlag &= ~(GZIPENCODING | DEFLATEENCODING);
25192544 if (iHeaderFlag & GZIPENCODING || iHeaderFlag & DEFLATEENCODING)
25202545 {
25212546 if (httpVers < 2 )
@@ -2534,68 +2559,55 @@ void CHttpServ::DoAction(const MetaSocketData soMetaDa, const uint8_t httpVers,
25342559 GZipPack gzipEncoder;
25352560 if (gzipEncoder.Init ((iHeaderFlag & DEFLATEENCODING) ? true : false ) == Z_OK)
25362561 {
2537- unique_ptr<unsigned char []> srcBuf (new unsigned char [nSizeSendBuf]);
2538- unique_ptr<unsigned char []> dstBuf (new unsigned char [nSizeSendBuf]);
2539-
2540- uint64_t nBytesTransferred = 0 ;
25412562 int iResult = 0 ;
2542- do
2543- {
2544- const streamsize nBytesRead = fin.read (reinterpret_cast <char *>(srcBuf.get ()), nSizeSendBuf).gcount ();
2545- if (nBytesRead == 0 )
2546- break ;
2547- nBytesTransferred += nBytesRead;
2563+ gzipEncoder.InitBuffer (map.data (), static_cast <uint32_t >(nFSize));
25482564
2549- gzipEncoder.InitBuffer (srcBuf.get (), static_cast <uint32_t >(nBytesRead));
2550- const int nFlush = nBytesTransferred == nFSize ? Z_FINISH : Z_NO_FLUSH;
2565+ unique_ptr<unsigned char []> dstBuf (new unsigned char [nSizeSendBuf]);
2566+ size_t nBytesConverted;
2567+ do
2568+ { // Get next compressed chunk
2569+ nBytesConverted = nSizeSendBuf - nHttp2Offset;
2570+ iResult = gzipEncoder.Inflate (dstBuf.get () + nHttp2Offset, &nBytesConverted, Z_FINISH);
25512571
2552- size_t nBytesConverted;
2553- do
2572+ // Send compressed chunk
2573+ size_t nOffset = 0 ;
2574+ while ((iResult == Z_OK || iResult == Z_STREAM_END) && ((nSizeSendBuf - nHttp2Offset) - nBytesConverted - nOffset) != 0 && patStop.load () == false && fnIsStreamReset (nStreamId) == false )
25542575 {
2555- nBytesConverted = nSizeSendBuf - nHttp2Offset;
2556- iResult = gzipEncoder.Inflate (dstBuf.get () + nHttp2Offset, &nBytesConverted, nFlush);
2557-
2558- size_t nOffset = 0 ;
2559- while ((iResult == Z_OK || iResult == Z_STREAM_END) && ((nSizeSendBuf - nHttp2Offset) - nBytesConverted - nOffset) != 0 && patStop.load () == false && fnIsStreamReset (nStreamId) == false )
2560- {
2561- int64_t nStreamWndSize = INT32_MAX;
2562- if (fnGetStreamWindowSize (nStreamWndSize) == false )
2563- break ; // Stream Item was removed, probably the stream was reset
2564-
2565- size_t nSendBufLen;
2566- if (fnSendQueueReady (nStreamWndSize, nSendBufLen, static_cast <uint64_t >(nSizeSendBuf - nHttp2Offset), ((nSizeSendBuf - nHttp2Offset) - nBytesConverted - nOffset)) == false )
2567- continue ;
2568-
2569- if (httpVers == 2 )
2570- {
2571- bool bLastPaket = false ;
2572- if (iResult == Z_STREAM_END && ((nSizeSendBuf - nHttp2Offset) - nBytesConverted - nOffset) == nSendBufLen) // Letztes Paket
2573- bLastPaket = true ;
2574- BuildHttp2Frame (dstBuf.get () + nOffset, nSendBufLen, 0x0 , bLastPaket == true ? 0x1 : 0x0 , nStreamId);
2575- }
2576- else
2577- {
2578- stringstream ss;
2579- ss << hex << ::uppercase << nSendBufLen << " \r\n " ;
2580- soMetaDa.fSocketWrite (ss.str ().c_str (), ss.str ().size ());
2581- }
2582- soMetaDa.fSocketWrite (dstBuf.get () + nOffset, nSendBufLen + nHttp2Offset);
2583- if (httpVers < 2 )
2584- soMetaDa.fSocketWrite (" \r\n " , 2 );
2585- soMetaDa.fResetTimer ();
2576+ int64_t nStreamWndSize = INT32_MAX;
2577+ if (fnGetStreamWindowSize (nStreamWndSize) == false )
2578+ break ; // Stream Item was removed, probably the stream was reset
25862579
2587- if (fnUpdateStreamParam (nSendBufLen) == -1 )
2588- break ; // Stream Item was removed, probably the stream was reset
2580+ size_t nSendBufLen;
2581+ if (fnSendQueueReady (nStreamWndSize, nSendBufLen, static_cast <uint64_t >(nSizeSendBuf - nHttp2Offset), ((nSizeSendBuf - nHttp2Offset) - nBytesConverted - nOffset)) == false )
2582+ continue ;
25892583
2590- // nBytesConverted += nSendBufLen;
2591- nOffset += nSendBufLen;
2584+ if (httpVers == 2 )
2585+ {
2586+ bool bLastPaket = false ;
2587+ if (iResult == Z_STREAM_END && ((nSizeSendBuf - nHttp2Offset) - nBytesConverted - nOffset) == nSendBufLen) // Letztes Paket
2588+ bLastPaket = true ;
2589+ BuildHttp2Frame (dstBuf.get () + nOffset, nSendBufLen, 0x0 , bLastPaket == true ? 0x1 : 0x0 , nStreamId);
2590+ }
2591+ else
2592+ {
2593+ stringstream ss;
2594+ ss << hex << ::uppercase << nSendBufLen << " \r\n " ;
2595+ soMetaDa.fSocketWrite (ss.str ().c_str (), ss.str ().size ());
25922596 }
2597+ soMetaDa.fSocketWrite (dstBuf.get () + nOffset, nSendBufLen + nHttp2Offset);
2598+ if (httpVers < 2 )
2599+ soMetaDa.fSocketWrite (" \r\n " , 2 );
2600+ soMetaDa.fResetTimer ();
2601+
2602+ if (fnUpdateStreamParam (nSendBufLen) == -1 )
2603+ break ; // Stream Item was removed, probably the stream was reset
25932604
2594- fnResetReservierteWindowSize ();
2605+ nOffset += nSendBufLen;
2606+ }
25952607
2596- } while (iResult == Z_OK && nBytesConverted == 0 && patStop. load () == false && fnIsStreamReset (nStreamId) == false );
2608+ fnResetReservierteWindowSize ( );
25972609
2598- } while (iResult == Z_OK && patStop.load () == false && fnIsStreamReset (nStreamId) == false );
2610+ } while (iResult == Z_OK && nBytesConverted == 0 && patStop.load () == false && fnIsStreamReset (nStreamId) == false );
25992611
26002612 if (httpVers < 2 && patStop.load () == false )
26012613 soMetaDa.fSocketWrite (" 0\r\n\r\n " , 5 );
@@ -2619,35 +2631,21 @@ void CHttpServ::DoAction(const MetaSocketData soMetaDa, const uint8_t httpVers,
26192631 BrotliEncoderState* s = BrotliEncoderCreateInstance (nullptr , nullptr , nullptr );
26202632 BrotliEncoderSetParameter (s, BROTLI_PARAM_QUALITY, (uint32_t )9 );
26212633 BrotliEncoderSetParameter (s, BROTLI_PARAM_LGWIN, (uint32_t )0 );
2622- /* if (dictionary_path != NULL) {
2623- size_t dictionary_size = 0;
2624- uint8_t* dictionary = ReadDictionary(dictionary_path, &dictionary_size);
2625- BrotliEncoderSetCustomDictionary(s, dictionary_size, dictionary);
2626- free(dictionary);
2627- }
2628- */
2629- unique_ptr<unsigned char []> srcBuf (new unsigned char [nSizeSendBuf]);
2634+
26302635 unique_ptr<unsigned char []> dstBuf (new unsigned char [nSizeSendBuf]);
26312636
2632- size_t nBytIn = 0 ;
2633- const uint8_t * input = nullptr ;
2637+ size_t nBytIn = nFSize ;
2638+ const uint8_t * input = map. data () ;
26342639 size_t nBytOut = nSizeSendBuf - nHttp2Offset;
26352640 uint8_t * output = dstBuf.get () + nHttp2Offset;
26362641
2637- uint64_t nBytesTransferred = 0 ;
26382642 while (patStop.load () == false && fnIsStreamReset (nStreamId) == false )
26392643 {
2640- if (nBytIn == 0 )
2641- {
2642- const streamsize nBytesRead = fin.read (reinterpret_cast <char *>(srcBuf.get ()), nSizeSendBuf).gcount ();
2643- nBytIn = static_cast <size_t >(nBytesRead);
2644- input = srcBuf.get ();
2645- nBytesTransferred += nBytIn;
2646- }
2647-
2644+ // Nächsten Chunk komprimieren
26482645 if (!BrotliEncoderCompressStream (s, nBytIn == 0 ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS, &nBytIn, &input, &nBytOut, &output, nullptr ))
26492646 break ;
26502647
2648+ // Senden des komprimierten Chunks
26512649 size_t nOffset = 0 ;
26522650 while (nBytOut != nSizeSendBuf - nHttp2Offset && patStop.load () == false && fnIsStreamReset (nStreamId) == false )
26532651 {
@@ -2704,9 +2702,6 @@ void CHttpServ::DoAction(const MetaSocketData soMetaDa, const uint8_t httpVers,
27042702 soMetaDa.fSocketWrite (caBuffer, nHeaderLen + nHttp2Offset);
27052703 }
27062704 soMetaDa.fResetTimer ();
2707-
2708- auto apBuf = make_unique<uint8_t []>(nSizeSendBuf + nHttp2Offset + 2 );
2709-
27102705 uint64_t nBytesTransferred = 0 ;
27112706 while (nBytesTransferred < nFSize && patStop.load () == false && fnIsStreamReset (nStreamId) == false )
27122707 {
@@ -2718,20 +2713,22 @@ void CHttpServ::DoAction(const MetaSocketData soMetaDa, const uint8_t httpVers,
27182713 if (fnSendQueueReady (nStreamWndSize, nSendBufLen, static_cast <uint64_t >(nSizeSendBuf - nHttp2Offset), nFSize - nBytesTransferred) == false )
27192714 continue ;
27202715
2721- nBytesTransferred += nSendBufLen;
2722- fin.read (reinterpret_cast <char *>(apBuf.get ()) + nHttp2Offset, nSendBufLen);
2723-
27242716 if (httpVers == 2 )
2725- BuildHttp2Frame (apBuf.get (), nSendBufLen, 0x0 , (nFSize - nBytesTransferred == 0 ? 0x1 : 0x0 ), nStreamId);
2726- soMetaDa.fSocketWrite (apBuf.get (), nSendBufLen + nHttp2Offset);
2717+ {
2718+ BuildHttp2Frame (caBuffer, nSendBufLen, 0x0 , (nFSize - (nBytesTransferred + nSendBufLen) == 0 ? 0x1 : 0x0 ), nStreamId);
2719+ soMetaDa.fSocketWrite (caBuffer, nHttp2Offset);
2720+ }
2721+ soMetaDa.fSocketWrite (map.data (), nSendBufLen);
27272722 soMetaDa.fResetTimer ();
27282723
27292724 if (fnUpdateStreamParam (nSendBufLen) == -1 )
27302725 break ; // Stream Item was removed, probably the stream was reset
2726+
2727+ nBytesTransferred += nSendBufLen;
2728+ map.addOffset (nSendBufLen);
27312729 }
27322730 fnResetReservierteWindowSize ();
27332731 }
2734- fin.close ();
27352732
27362733 CLogFile::GetInstance (m_vHostParam[szHost].m_strLogFile ) << soMetaDa.strIpClient << " - - [" << CLogFile::LOGTYPES::PUTTIME << " ] \" "
27372734 << itMethode->second << " " << lstHeaderFields.find (" :path" )->second
0 commit comments