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