xref: /haiku/src/kits/package/FetchFileJob.cpp (revision 1a3518cf757c2da8006753f83962da5935bbc82b)
1 /*
2  * Copyright 2011-2015, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler <axeld@pinc-software.de>
7  *		Rene Gollent <rene@gollent.com>
8  *		Oliver Tappe <zooey@hirschkaefer.de>
9  */
10 
11 
12 #include "FetchFileJob.h"
13 
14 #include <stdio.h>
15 #include <sys/wait.h>
16 
17 #include <Path.h>
18 
19 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
20 #	include <HttpRequest.h>
21 #	include <UrlRequest.h>
22 #	include <UrlProtocolRoster.h>
23 #endif
24 
25 
26 namespace BPackageKit {
27 
28 namespace BPrivate {
29 
30 
31 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
32 
33 FetchFileJob::FetchFileJob(const BContext& context, const BString& title,
34 	const BString& fileURL, const BEntry& targetEntry)
35 	:
36 	inherited(context, title),
37 	fFileURL(fileURL),
38 	fTargetEntry(targetEntry),
39 	fTargetFile(&targetEntry, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY),
40 	fError(B_ERROR),
41 	fDownloadProgress(0.0)
42 {
43 }
44 
45 
46 FetchFileJob::~FetchFileJob()
47 {
48 }
49 
50 
51 float
52 FetchFileJob::DownloadProgress() const
53 {
54 	return fDownloadProgress;
55 }
56 
57 
58 const char*
59 FetchFileJob::DownloadURL() const
60 {
61 	return fFileURL.String();
62 }
63 
64 
65 const char*
66 FetchFileJob::DownloadFileName() const
67 {
68 	return fTargetEntry.Name();
69 }
70 
71 
72 off_t
73 FetchFileJob::DownloadBytes() const
74 {
75 	return fBytes;
76 }
77 
78 
79 off_t
80 FetchFileJob::DownloadTotalBytes() const
81 {
82 	return fTotalBytes;
83 }
84 
85 
86 status_t
87 FetchFileJob::Execute()
88 {
89 	status_t result = fTargetFile.InitCheck();
90 	if (result != B_OK)
91 		return result;
92 
93 	BUrlRequest* request = BUrlProtocolRoster::MakeRequest(fFileURL.String(),
94 		this);
95 	if (request == NULL)
96 		return B_BAD_VALUE;
97 
98 	thread_id thread = request->Run();
99 	wait_for_thread(thread, NULL);
100 
101 	return fError;
102 }
103 
104 
105 void
106 FetchFileJob::DataReceived(BUrlRequest*, const char* data, off_t position,
107 	ssize_t size)
108 {
109 	fTargetFile.WriteAt(position, data, size);
110 }
111 
112 
113 void
114 FetchFileJob::DownloadProgress(BUrlRequest*, ssize_t bytesReceived,
115 	ssize_t bytesTotal)
116 {
117 	if (bytesTotal != 0) {
118 		fBytes = bytesReceived;
119 		fTotalBytes = bytesTotal;
120 		fDownloadProgress = (float)bytesReceived/bytesTotal;
121 		NotifyStateListeners();
122 	}
123 }
124 
125 
126 void
127 FetchFileJob::RequestCompleted(BUrlRequest* request, bool success)
128 {
129 	fError = request->Status();
130 
131 	if (success) {
132 		const BHttpResult* httpResult = dynamic_cast<const BHttpResult*>
133 			(&request->Result());
134 		if (httpResult != NULL) {
135 			uint16 code = httpResult->StatusCode();
136 			uint16 codeClass = BHttpRequest::StatusCodeClass(code);
137 
138 			switch (codeClass) {
139 				case B_HTTP_STATUS_CLASS_CLIENT_ERROR:
140 				case B_HTTP_STATUS_CLASS_SERVER_ERROR:
141 					fError = B_IO_ERROR;
142 					break;
143 				default:
144 					fError = B_OK;
145 					break;
146 			}
147 			switch (code) {
148 				case B_HTTP_STATUS_OK:
149 					fError = B_OK;
150 					break;
151 				case B_HTTP_STATUS_PARTIAL_CONTENT:
152 					fError = B_PARTIAL_READ;
153 					break;
154 				case B_HTTP_STATUS_REQUEST_TIMEOUT:
155 				case B_HTTP_STATUS_GATEWAY_TIMEOUT:
156 					fError = B_DEV_TIMEOUT;
157 					break;
158 				case B_HTTP_STATUS_NOT_IMPLEMENTED:
159 				case B_HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE:
160 					fError = B_NOT_SUPPORTED;
161 					break;
162 				case B_HTTP_STATUS_UNAUTHORIZED:
163 					fError = B_PERMISSION_DENIED;
164 					break;
165 				case B_HTTP_STATUS_FORBIDDEN:
166 				case B_HTTP_STATUS_METHOD_NOT_ALLOWED:
167 				case B_HTTP_STATUS_NOT_ACCEPTABLE:
168 					fError = B_NOT_ALLOWED;
169 					break;
170 				case B_HTTP_STATUS_NOT_FOUND:
171 					fError = B_NAME_NOT_FOUND;
172 					break;
173 				case B_HTTP_STATUS_BAD_GATEWAY:
174 					fError = B_BAD_DATA;
175 					break;
176 				default:
177 					break;
178 			}
179 		}
180 	}
181 }
182 
183 
184 void
185 FetchFileJob::Cleanup(status_t jobResult)
186 {
187 	if (jobResult != B_OK)
188 		fTargetEntry.Remove();
189 }
190 
191 
192 #else // HAIKU_TARGET_PLATFORM_HAIKU
193 
194 
195 FetchFileJob::FetchFileJob(const BContext& context, const BString& title,
196 	const BString& fileURL, const BEntry& targetEntry)
197 	:
198 	inherited(context, title),
199 	fFileURL(fileURL),
200 	fTargetEntry(targetEntry),
201 	fTargetFile(&targetEntry, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY),
202 	fDownloadProgress(0.0)
203 {
204 }
205 
206 
207 FetchFileJob::~FetchFileJob()
208 {
209 }
210 
211 
212 float
213 FetchFileJob::DownloadProgress() const
214 {
215 	return fDownloadProgress;
216 }
217 
218 
219 const char*
220 FetchFileJob::DownloadURL() const
221 {
222 	return fFileURL.String();
223 }
224 
225 
226 const char*
227 FetchFileJob::DownloadFileName() const
228 {
229 	return fTargetEntry.Name();
230 }
231 
232 
233 off_t
234 FetchFileJob::DownloadBytes() const
235 {
236 	return fBytes;
237 }
238 
239 
240 off_t
241 FetchFileJob::DownloadTotalBytes() const
242 {
243 	return fTotalBytes;
244 }
245 
246 
247 status_t
248 FetchFileJob::Execute()
249 {
250 	return B_UNSUPPORTED;
251 }
252 
253 
254 void
255 FetchFileJob::Cleanup(status_t jobResult)
256 {
257 	if (jobResult != B_OK)
258 		fTargetEntry.Remove();
259 }
260 
261 
262 #endif // HAIKU_TARGET_PLATFORM_HAIKU
263 
264 }	// namespace BPrivate
265 
266 }	// namespace BPackageKit
267