No issue - Make content-type on JAR channels behave the same as HTTP channels

This ensures that the content type is also determined when opening JAR channels both synchronously and asynchronously. Current m-c modifies only the async portion, while the mentioned commit below modifies only the sync portion. This commit does it for both.

Partially based on 425677ada7380f7c592dd01ddfbc9631ab2038a0 and bug 1757604.
This commit is contained in:
FranklinDM 2022-05-04 14:55:57 +08:00 committed by roytam1
commit 091a2aab80
2 changed files with 48 additions and 36 deletions

View file

@ -577,48 +577,47 @@ nsJARChannel::GetSecurityInfo(nsISupports **aSecurityInfo)
return NS_OK;
}
bool nsJARChannel::GetContentTypeGuess(nsACString& aResult) const {
const char *ext = nullptr, *fileName = mJarEntry.get();
int32_t len = mJarEntry.Length();
// check if we're displaying a directory
// mJarEntry will be empty if we're trying to display
// the topmost directory in a zip, e.g. jar:foo.zip!/
if (ENTRY_IS_DIRECTORY(mJarEntry)) {
aResult.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
return true;
}
// Not a directory, take a guess by its extension
for (int32_t i = len - 1; i >= 0; i--) {
if (fileName[i] == '.') {
ext = &fileName[i + 1];
break;
}
}
if (!ext) {
return false;
}
nsIMIMEService* mimeServ = gJarHandler->MimeService();
if (!mimeServ) {
return false;
}
mimeServ->GetTypeFromExtension(nsDependentCString(ext), aResult);
return !aResult.IsEmpty();
}
NS_IMETHODIMP
nsJARChannel::GetContentType(nsACString &result)
nsJARChannel::GetContentType(nsACString &aResult)
{
// If the Jar file has not been open yet,
// We return application/x-unknown-content-type
if (!mOpened) {
result.Assign(UNKNOWN_CONTENT_TYPE);
aResult.Assign(UNKNOWN_CONTENT_TYPE);
return NS_OK;
}
if (mContentType.IsEmpty()) {
//
// generate content type and set it
//
const char *ext = nullptr, *fileName = mJarEntry.get();
int32_t len = mJarEntry.Length();
// check if we're displaying a directory
// mJarEntry will be empty if we're trying to display
// the topmost directory in a zip, e.g. jar:foo.zip!/
if (ENTRY_IS_DIRECTORY(mJarEntry)) {
mContentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
}
else {
// not a directory, take a guess by its extension
for (int32_t i = len-1; i >= 0; i--) {
if (fileName[i] == '.') {
ext = &fileName[i + 1];
break;
}
}
if (ext) {
nsIMIMEService *mimeServ = gJarHandler->MimeService();
if (mimeServ)
mimeServ->GetTypeFromExtension(nsDependentCString(ext), mContentType);
}
if (mContentType.IsEmpty())
mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
}
}
result = mContentType;
aResult = mContentType;
return NS_OK;
}
@ -636,8 +635,8 @@ nsJARChannel::SetContentType(const nsACString &aContentType)
NS_IMETHODIMP
nsJARChannel::GetContentCharset(nsACString &aContentCharset)
{
// If someone gives us a charset hint we should just use that charset.
// So we don't care when this is being called.
// We behave like HTTP channels (treat this as a hint if called before open,
// and override the charset if called after open).
aContentCharset = mContentCharset;
return NS_OK;
}
@ -730,6 +729,10 @@ nsJARChannel::Open(nsIInputStream **stream)
input.forget(stream);
mOpened = true;
// Compute the content type now.
if (!GetContentTypeGuess(mContentType)) {
mContentType.Assign(UNKNOWN_CONTENT_TYPE);
}
// local files are always considered safe
mIsUnsafe = false;
return NS_OK;
@ -827,6 +830,10 @@ nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
mLoadGroup->AddRequest(this, nullptr);
mOpened = true;
// Compute the content type now.
if (!GetContentTypeGuess(mContentType)) {
mContentType.Assign(UNKNOWN_CONTENT_TYPE);
}
return NS_OK;
}

View file

@ -59,6 +59,11 @@ private:
nsresult OpenLocalFile();
void NotifyError(nsresult aError);
void FireOnProgress(uint64_t aProgress);
// Returns false if we don't know the content type of this channel, in which
// case we should use the content-type hint.
bool GetContentTypeGuess(nsACString&) const;
virtual void OnDownloadComplete(mozilla::net::MemoryDownloader* aDownloader,
nsIRequest* aRequest,
nsISupports* aCtxt,