1 2 #ifndef _DLCON_H 3 #define _DLCON_H 4 5 #include <string> 6 #include <list> 7 #include <map> 8 #include <set> 9 10 //#include <netinet/in.h> 11 //#include <netdb.h> 12 13 #include "tcpconnect.h" 14 #include "lockable.h" 15 #include "fileitem.h" 16 #include "acfg.h" 17 #include "acbuf.h" 18 19 namespace acng 20 { 21 22 struct tDlJob; 23 typedef std::shared_ptr<tDlJob> tDlJobPtr; 24 typedef std::list<tDlJobPtr> tDljQueue; 25 26 /** 27 * dlcon is a basic connection broker for download processes. 28 * It's defacto a slave of the conn class, the active thread is spawned by conn when needed 29 * and it's finished by its destructor. However, the life time is prolonged if the usage count 30 * is not down to zero, i.e. when there are more users registered as reader for the file 31 * downloaded by the agent here then it will continue downloading and block the conn dtor 32 * until that download is finished or the other client detaches. If a download is active and parent 33 * conn object calls Stop... then the download will be aborted ASAP. 34 * 35 * Internally, a queue of download job items is maintained. Each contains a reference either to 36 * a full target URL or to a tupple of a list of mirror descriptions (url prefix) and additional 37 * path suffix for the required file. 38 * 39 * In addition, there is a local blacklist which is applied to all download jobs in the queue, 40 * i.e. remotes marked as faulty there are no longer considered by the subsequent download jobs. 41 */ 42 class dlcon : public base_with_mutex 43 { 44 public: 45 dlcon(bool bManualExecution, mstring *xff=nullptr, 46 IDlConFactory *pConFactory = &g_tcp_con_factory); 47 ~dlcon(); 48 49 void WorkLoop(); 50 51 void SignalStop(); 52 53 bool AddJob(tFileItemPtr m_pItem, const tHttpUrl *pForcedUrl, 54 const cfg::tRepoData *pRepoDesc, 55 cmstring *sPatSuffix, LPCSTR reqHead, 56 int nMaxRedirection); 57 58 mstring m_sXForwardedFor; 59 60 private: 61 62 //not to be copied 63 dlcon & operator=(const dlcon&); 64 dlcon(const dlcon&); 65 66 friend struct tDlJob; 67 68 tDljQueue m_qNewjobs; 69 IDlConFactory* m_pConFactory; 70 71 #ifdef HAVE_LINUX_EVENTFD 72 int m_wakeventfd = -1; 73 #define fdWakeRead m_wakeventfd 74 #define fdWakeWrite m_wakeventfd 75 #else 76 int m_wakepipe[2] = {-1, -1}; 77 #define fdWakeRead m_wakepipe[0] 78 #define fdWakeWrite m_wakepipe[1] 79 #endif 80 // flags and local copies for input parsing 81 /// remember being attached to an fitem 82 83 bool m_bStopASAP; 84 85 unsigned m_bManualMode; 86 87 /// blacklist for permanently failing hosts, with error message 88 std::map<std::pair<cmstring,cmstring>, mstring> m_blacklist; 89 tSS m_sendBuf, m_inBuf; 90 91 unsigned ExchangeData(mstring &sErrorMsg, tDlStreamHandle &con, tDljQueue &qActive); 92 93 // Disable pipelining for the next # requests. Actually used as crude workaround for the 94 // concept limitation (because of automata over a couple of function) and its 95 // impact on download performance. 96 // The use case: stupid web servers that redirect all requests do that step-by-step, i.e. 97 // they get a bunch of requests but return only the first response and then flush the buffer 98 // so we process this response and wish to switch to the new target location (dropping 99 // the current connection because we don't keep it somehow to background, this is the only 100 // download agent we have). This manner perverts the whole principle and causes permanent 101 // disconnects/reconnects. In this case, it's beneficial to disable pipelining and send 102 // our requests one-by-one. This is done for a while (i.e. the valueof(m_nDisablePling)/2 ) 103 // times before the operation mode returns to normal. 104 int m_nTempPipelineDisable; 105 106 107 // the default behavior or using or not using the proxy. Will be set 108 // if access proxies shall no longer be used. 109 bool m_bProxyTot; 110 111 // this is a binary factor, meaning how many reads from buffer are OK when 112 // speed limiting is enabled 113 unsigned m_nSpeedLimiterRoundUp = (unsigned(1)<<16)-1; 114 unsigned m_nSpeedLimitMaxPerTake = MAX_VAL(unsigned); 115 unsigned m_nLastDlCount=0; 116 117 void wake(); 118 }; 119 120 #define IS_REDIRECT(st) (st == 301 || st == 302 || st == 307) 121 122 } 123 124 #endif 125