1 /*
2  *  This file is part of nzbget. See <http://nzbget.net>.
3  *
4  *  Copyright (C) 2012-2016 Andrey Prygunkov <hugbug@users.sourceforge.net>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #ifndef WEBDOWNLOADER_H
22 #define WEBDOWNLOADER_H
23 
24 #include "NString.h"
25 #include "Observer.h"
26 #include "Thread.h"
27 #include "Connection.h"
28 #include "FileSystem.h"
29 #include "Util.h"
30 
31 class WebDownloader : public Thread, public Subject
32 {
33 public:
34 	enum EStatus
35 	{
36 		adUndefined,
37 		adRunning,
38 		adFinished,
39 		adFailed,
40 		adRetry,
41 		adNotFound,
42 		adRedirect,
43 		adConnectError,
44 		adFatalError
45 	};
46 
47 	WebDownloader();
GetStatus()48 	EStatus GetStatus() { return m_status; }
49 	virtual void Run();
50 	virtual void Stop();
51 	EStatus Download();
52 	EStatus DownloadWithRedirects(int maxRedirects);
SetInfoName(const char * infoName)53 	void SetInfoName(const char* infoName) { m_infoName = infoName; }
GetInfoName()54 	const char* GetInfoName() { return m_infoName; }
55 	void SetUrl(const char* url);
GetOutputFilename()56 	const char* GetOutputFilename() { return m_outputFilename; }
SetOutputFilename(const char * outputFilename)57 	void SetOutputFilename(const char* outputFilename) { m_outputFilename = outputFilename; }
GetLastUpdateTime()58 	time_t GetLastUpdateTime() { return m_lastUpdateTime; }
59 	void SetLastUpdateTimeNow();
GetConfirmedLength()60 	bool GetConfirmedLength() { return m_confirmedLength; }
GetOriginalFilename()61 	const char* GetOriginalFilename() { return m_originalFilename; }
SetForce(bool force)62 	void SetForce(bool force) { m_force = force; }
SetRetry(bool retry)63 	void SetRetry(bool retry) { m_retry = retry; }
64 
65 	void LogDebugInfo();
66 
67 protected:
68 	virtual void ProcessHeader(const char* line);
69 
70 private:
71 	CString m_url;
72 	CString m_outputFilename;
73 	std::unique_ptr<Connection> m_connection;
74 	Mutex m_connectionMutex;
75 	EStatus m_status = adUndefined;
76 	time_t m_lastUpdateTime;
77 	CString m_infoName;
78 	DiskFile m_outFile;
79 	int m_contentLen;
80 	bool m_confirmedLength = false;
81 	CString m_originalFilename;
82 	bool m_force = false;
83 	bool m_redirecting;
84 	bool m_redirected;
85 	bool m_gzip;
86 	bool m_retry = true;
87 #ifndef DISABLE_GZIP
88 	std::unique_ptr<GUnzipStream> m_gUnzipStream;
89 #endif
90 
91 	void SetStatus(EStatus status);
92 	bool Write(void* buffer, int len);
93 	bool PrepareFile();
94 	void FreeConnection();
95 	EStatus CheckResponse(const char* response);
96 	EStatus CreateConnection(URL *url);
97 	void ParseFilename(const char* contentDisposition);
98 	void SendHeaders(URL *url);
99 	EStatus DownloadHeaders();
100 	EStatus DownloadBody();
101 	void ParseRedirect(const char* location);
102 };
103 
104 #endif
105