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