Bug 1729952 [wpt PR 30477] - Fix timeout in grid-positioned-item-dynamic-change-006...
[gecko.git] / netwerk / base / nsDownloader.cpp
blob670459e710ccf0b92a759b545d157e72d4433437
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsDownloader.h"
6 #include "nsIInputStream.h"
7 #include "nsDirectoryServiceUtils.h"
8 #include "nsDirectoryServiceDefs.h"
9 #include "nsNetUtil.h"
10 #include "nsCRTGlue.h"
12 nsDownloader::~nsDownloader() {
13 if (mLocation && mLocationIsTemp) {
14 // release the sink first since it may still hold an open file
15 // descriptor to mLocation. this needs to happen before the
16 // file can be removed otherwise the Remove call will fail.
17 if (mSink) {
18 mSink->Close();
19 mSink = nullptr;
22 nsresult rv = mLocation->Remove(false);
23 if (NS_FAILED(rv)) NS_ERROR("unable to remove temp file");
27 NS_IMPL_ISUPPORTS(nsDownloader, nsIDownloader, nsIStreamListener,
28 nsIRequestObserver)
30 NS_IMETHODIMP
31 nsDownloader::Init(nsIDownloadObserver* observer, nsIFile* location) {
32 mObserver = observer;
33 mLocation = location;
34 return NS_OK;
37 NS_IMETHODIMP
38 nsDownloader::OnStartRequest(nsIRequest* request) {
39 nsresult rv;
40 if (!mLocation) {
41 nsCOMPtr<nsIFile> location;
42 rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(location));
43 if (NS_FAILED(rv)) return rv;
45 char buf[13];
46 NS_MakeRandomString(buf, 8);
47 memcpy(buf + 8, ".tmp", 5);
48 rv = location->AppendNative(nsDependentCString(buf, 12));
49 if (NS_FAILED(rv)) return rv;
51 rv = location->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
52 if (NS_FAILED(rv)) return rv;
54 location.swap(mLocation);
55 mLocationIsTemp = true;
58 rv = NS_NewLocalFileOutputStream(getter_AddRefs(mSink), mLocation);
59 if (NS_FAILED(rv)) return rv;
61 // we could wrap this output stream with a buffered output stream,
62 // but it shouldn't be necessary since we will be writing large
63 // chunks given to us via OnDataAvailable.
65 return NS_OK;
68 NS_IMETHODIMP
69 nsDownloader::OnStopRequest(nsIRequest* request, nsresult status) {
70 if (mSink) {
71 mSink->Close();
72 mSink = nullptr;
75 mObserver->OnDownloadComplete(this, request, nullptr, status, mLocation);
76 mObserver = nullptr;
78 return NS_OK;
81 nsresult nsDownloader::ConsumeData(nsIInputStream* in, void* closure,
82 const char* fromRawSegment,
83 uint32_t toOffset, uint32_t count,
84 uint32_t* writeCount) {
85 nsDownloader* self = (nsDownloader*)closure;
86 if (self->mSink) return self->mSink->Write(fromRawSegment, count, writeCount);
88 *writeCount = count;
89 return NS_OK;
92 NS_IMETHODIMP
93 nsDownloader::OnDataAvailable(nsIRequest* request, nsIInputStream* inStr,
94 uint64_t sourceOffset, uint32_t count) {
95 uint32_t n;
96 return inStr->ReadSegments(ConsumeData, this, count, &n);