Bug 282432 - Calling asyncOpen on a file channel should notify about file not found errors asynchronously instead of throwing from asyncOpen. r=bz
--- a/netwerk/protocol/file/nsFileChannel.cpp
+++ b/netwerk/protocol/file/nsFileChannel.cpp
@@ -268,34 +268,43 @@ nsFileChannel::nsFileChannel(nsIURI *uri
} else {
SetURI(uri);
}
}
nsresult
nsFileChannel::MakeFileInputStream(nsIFile *file,
nsCOMPtr<nsIInputStream> &stream,
- nsCString &contentType)
+ nsCString &contentType,
+ bool async)
{
// we accept that this might result in a disk hit to stat the file
bool isDir;
nsresult rv = file->IsDirectory(&isDir);
if (NS_FAILED(rv)) {
// canonicalize error message
if (rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
rv = NS_ERROR_FILE_NOT_FOUND;
- return rv;
+
+ if (async && (NS_ERROR_FILE_NOT_FOUND == rv)) {
+ // We don't return "Not Found" errors here. Since we could not find
+ // the file, it's not a directory anyway.
+ isDir = false;
+ } else {
+ return rv;
+ }
}
if (isDir) {
rv = nsDirectoryIndexStream::Create(file, getter_AddRefs(stream));
if (NS_SUCCEEDED(rv) && !HasContentTypeHint())
contentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
} else {
- rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file, -1, -1,
+ async? nsIFileInputStream::DEFER_OPEN : 0);
if (NS_SUCCEEDED(rv) && !HasContentTypeHint()) {
// Use file extension to infer content type
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
if (NS_SUCCEEDED(rv)) {
mime->GetTypeFromFile(file, contentType);
}
}
}
@@ -359,28 +368,35 @@ nsFileChannel::OpenContentStream(bool as
// Since there isn't any content to speak of we just set the content-type
// to something other than "unknown" to avoid triggering the content-type
// sniffer code in nsBaseChannel.
// However, don't override explicitly set types.
if (!HasContentTypeHint())
SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
} else {
nsAutoCString contentType;
- rv = MakeFileInputStream(file, stream, contentType);
+ rv = MakeFileInputStream(file, stream, contentType, async);
if (NS_FAILED(rv))
return rv;
EnableSynthesizedProgressEvents(true);
// fixup content length and type
if (mContentLength < 0) {
int64_t size;
rv = file->GetFileSize(&size);
- if (NS_FAILED(rv))
- return rv;
+ if (NS_FAILED(rv)) {
+ if (async &&
+ (NS_ERROR_FILE_NOT_FOUND == rv ||
+ NS_ERROR_FILE_TARGET_DOES_NOT_EXIST == rv)) {
+ size = 0;
+ } else {
+ return rv;
+ }
+ }
mContentLength = size;
}
if (!contentType.IsEmpty())
SetContentType(contentType);
}
*result = nullptr;
stream.swap(*result);
--- a/netwerk/protocol/file/nsFileChannel.h
+++ b/netwerk/protocol/file/nsFileChannel.h
@@ -23,17 +23,17 @@ public:
nsFileChannel(nsIURI *uri);
protected:
// Called to construct a blocking file input stream for the given file. This
// method also returns a best guess at the content-type for the data stream.
// NOTE: If the channel has a type hint set, contentType will be left
// untouched. The caller should not use it in that case.
nsresult MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
- nsCString &contentType);
+ nsCString &contentType, bool async);
virtual nsresult OpenContentStream(bool async, nsIInputStream **result,
nsIChannel** channel);
private:
nsCOMPtr<nsIInputStream> mUploadStream;
int64_t mUploadLength;
};