mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1170837 - Make nsMultiMixedConv not return an error when served only a package's metadata from the cache r=honzab
Make the stream converter aware of the "application/package" mimetype.
This commit is contained in:
parent
9cef740107
commit
922ebfe6d5
@ -433,6 +433,7 @@ nsresult NS_NewStreamConv(nsStreamConverterService **aStreamConv);
|
||||
#define INDEX_TO_HTML "?from=application/http-index-format&to=text/html"
|
||||
#define MULTI_MIXED_X "?from=multipart/x-mixed-replace&to=*/*"
|
||||
#define MULTI_MIXED "?from=multipart/mixed&to=*/*"
|
||||
#define APPLICATION_PACKAGE_CONV "?from=" APPLICATION_PACKAGE "&to=*/*"
|
||||
#define MULTI_BYTERANGES "?from=multipart/byteranges&to=*/*"
|
||||
#define UNKNOWN_CONTENT "?from=" UNKNOWN_CONTENT_TYPE "&to=*/*"
|
||||
#define GZIP_TO_UNCOMPRESSED "?from=gzip&to=uncompressed"
|
||||
@ -451,6 +452,7 @@ static const mozilla::Module::CategoryEntry kNeckoCategories[] = {
|
||||
{ NS_ISTREAMCONVERTER_KEY, INDEX_TO_HTML, "" },
|
||||
{ NS_ISTREAMCONVERTER_KEY, MULTI_MIXED_X, "" },
|
||||
{ NS_ISTREAMCONVERTER_KEY, MULTI_MIXED, "" },
|
||||
{ NS_ISTREAMCONVERTER_KEY, APPLICATION_PACKAGE_CONV, "" },
|
||||
{ NS_ISTREAMCONVERTER_KEY, MULTI_BYTERANGES, "" },
|
||||
{ NS_ISTREAMCONVERTER_KEY, UNKNOWN_CONTENT, "" },
|
||||
{ NS_ISTREAMCONVERTER_KEY, GZIP_TO_UNCOMPRESSED, "" },
|
||||
@ -1032,6 +1034,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
||||
{ NS_ISTREAMCONVERTER_KEY MULTI_MIXED_X, &kNS_MULTIMIXEDCONVERTER_CID },
|
||||
{ NS_ISTREAMCONVERTER_KEY MULTI_BYTERANGES, &kNS_MULTIMIXEDCONVERTER_CID },
|
||||
{ NS_ISTREAMCONVERTER_KEY MULTI_MIXED, &kNS_MULTIMIXEDCONVERTER_CID },
|
||||
{ NS_ISTREAMCONVERTER_KEY APPLICATION_PACKAGE_CONV, &kNS_MULTIMIXEDCONVERTER_CID },
|
||||
{ NS_ISTREAMCONVERTER_KEY UNKNOWN_CONTENT, &kNS_UNKNOWNDECODER_CID },
|
||||
{ NS_GENERIC_CONTENT_SNIFFER, &kNS_UNKNOWNDECODER_CID },
|
||||
{ NS_BINARYDETECTOR_CONTRACTID, &kNS_BINARYDETECTOR_CID },
|
||||
|
@ -72,6 +72,7 @@
|
||||
#define APPLICATION_XSLT_XML "application/xslt+xml"
|
||||
#define APPLICATION_MATHML_XML "application/mathml+xml"
|
||||
#define APPLICATION_RDF_XML "application/rdf+xml"
|
||||
#define APPLICATION_PACKAGE "application/package"
|
||||
|
||||
#define AUDIO_BASIC "audio/basic"
|
||||
#define AUDIO_OGG "audio/ogg"
|
||||
|
@ -342,7 +342,9 @@ PackagedAppService::PackagedAppDownloader::OnStopRequest(nsIRequest *aRequest,
|
||||
CallCallbacks(uri, entry, aStatusCode);
|
||||
}
|
||||
|
||||
bool lastPart = false;
|
||||
// lastPart will be true if this is the last part in the package,
|
||||
// or if aRequest isn't a multipart channel
|
||||
bool lastPart = true;
|
||||
if (multiChannel) {
|
||||
rv = multiChannel->GetIsLastPart(&lastPart);
|
||||
if (NS_SUCCEEDED(rv) && !lastPart) {
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsIPackagedAppService.h"
|
||||
#include "nsICacheInfoChannel.h"
|
||||
#include <algorithm>
|
||||
#include "nsContentSecurityManager.h"
|
||||
#include "nsHttp.h"
|
||||
@ -492,8 +492,7 @@ nsMultiMixedConv::AsyncConvertData(const char *aFromType, const char *aToType,
|
||||
// in the raw stream.
|
||||
mFinalListener = aListener;
|
||||
|
||||
nsCOMPtr<nsIPackagedAppService> pas(do_QueryInterface(aCtxt));
|
||||
if (pas) {
|
||||
if (NS_LITERAL_CSTRING(APPLICATION_PACKAGE).Equals(aFromType)) {
|
||||
mPackagedApp = true;
|
||||
}
|
||||
return NS_OK;
|
||||
@ -753,7 +752,12 @@ nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
nsCOMPtr<nsICacheInfoChannel> cacheChan = do_QueryInterface(request);
|
||||
if (cacheChan) {
|
||||
cacheChan->IsFromCache(&mIsFromCache);
|
||||
}
|
||||
|
||||
// ask the HTTP channel for the content-type and extract the boundary from it.
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -773,7 +777,7 @@ nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) {
|
||||
// Although it is compatible with multipart/* this format does not require
|
||||
// the boundary to be included in the header, as it can be ascertained from
|
||||
// the content of the file.
|
||||
if (delimiter.Find("application/package") != kNotFound) {
|
||||
if (delimiter.Find(NS_LITERAL_CSTRING(APPLICATION_PACKAGE)) != kNotFound) {
|
||||
mPackagedApp = true;
|
||||
mHasAppContentType = true;
|
||||
mToken.Truncate();
|
||||
@ -829,7 +833,14 @@ nsMultiMixedConv::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
|
||||
// We should definitely have found a token at this point. Not having one
|
||||
// is clearly an error, so we need to pass it to the listener.
|
||||
if (mToken.IsEmpty()) {
|
||||
// However, since packaged apps usually have the boundary token at the
|
||||
// begining of the content, if the package is served from the cache, and
|
||||
// only metadata was saved for said package (meaning no content is available
|
||||
// and `mFirstOnData` is true) then we wouldn't have a boundary even though
|
||||
// no error has occured.
|
||||
if (mToken.IsEmpty() &&
|
||||
NS_SUCCEEDED(rv) && // don't hide channel error results
|
||||
!(mPackagedApp && mIsFromCache && mFirstOnData)) {
|
||||
aStatus = NS_ERROR_FAILURE;
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
@ -858,6 +869,12 @@ nsMultiMixedConv::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
// OnStartRequest! - This breaks necko's semantecs.
|
||||
//(void) mFinalListener->OnStartRequest(request, ctxt);
|
||||
|
||||
(void) mFinalListener->OnStopRequest(request, ctxt, aStatus);
|
||||
} else if (mIsFromCache && mFirstOnData) {
|
||||
// `mFirstOnData` is true if the package's cache entry only holds
|
||||
// metadata and no calls to OnDataAvailable are made.
|
||||
// In this case we would not call OnStopRequest for any of the parts,
|
||||
// so we need to call it here.
|
||||
(void) mFinalListener->OnStopRequest(request, ctxt, aStatus);
|
||||
}
|
||||
|
||||
@ -881,6 +898,7 @@ nsMultiMixedConv::nsMultiMixedConv() :
|
||||
mIsByteRangeRequest = false;
|
||||
mPackagedApp = false;
|
||||
mHasAppContentType = false;
|
||||
mIsFromCache = false;
|
||||
}
|
||||
|
||||
nsMultiMixedConv::~nsMultiMixedConv() {
|
||||
@ -1061,7 +1079,7 @@ nsMultiMixedConv::ParseHeaders(nsIChannel *aChannel, char *&aPtr,
|
||||
// It may already be initialized, from a previous call of ParseHeaders
|
||||
// since the headers for a single part may come in more then one chunk
|
||||
if (mPackagedApp && !mResponseHead) {
|
||||
mResponseHead = new nsHttpResponseHead();
|
||||
mResponseHead = new mozilla::net::nsHttpResponseHead();
|
||||
}
|
||||
|
||||
mContentLength = UINT64_MAX; // XXX what if we were already called?
|
||||
|
@ -17,8 +17,6 @@
|
||||
#include "nsIResponseHeadProvider.h"
|
||||
#include "nsHttpResponseHead.h"
|
||||
|
||||
using mozilla::net::nsHttpResponseHead;
|
||||
|
||||
#define NS_MULTIMIXEDCONVERTER_CID \
|
||||
{ /* 7584CE90-5B25-11d3-A175-0050041CAF44 */ \
|
||||
0x7584ce90, \
|
||||
@ -52,7 +50,7 @@ public:
|
||||
/* SetContentDisposition expects the full value of the Content-Disposition
|
||||
* header */
|
||||
void SetContentDisposition(const nsACString& aContentDispositionHeader);
|
||||
void SetResponseHead(nsHttpResponseHead * head) { mResponseHead = head; }
|
||||
void SetResponseHead(mozilla::net::nsHttpResponseHead * head) { mResponseHead = head; }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
@ -67,7 +65,7 @@ protected:
|
||||
protected:
|
||||
nsCOMPtr<nsIChannel> mMultipartChannel;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
nsAutoPtr<nsHttpResponseHead> mResponseHead;
|
||||
nsAutoPtr<mozilla::net::nsHttpResponseHead> mResponseHead;
|
||||
|
||||
nsresult mStatus;
|
||||
nsLoadFlags mLoadFlags;
|
||||
@ -184,7 +182,11 @@ protected:
|
||||
// Streamable packages don't require the boundary in the header
|
||||
// as it can be ascertained from the package file.
|
||||
bool mPackagedApp;
|
||||
nsAutoPtr<nsHttpResponseHead> mResponseHead;
|
||||
nsAutoPtr<mozilla::net::nsHttpResponseHead> mResponseHead;
|
||||
// It is necessary to know if the content is coming from the cache
|
||||
// for packaged apps, in the case that only metadata is saved in the cache
|
||||
// entry and OnDataAvailable never gets called.
|
||||
bool mIsFromCache;
|
||||
};
|
||||
|
||||
#endif /* __nsmultimixedconv__h__ */
|
||||
|
@ -24,8 +24,6 @@ Cu.import("resource://testing-common/httpd.js");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var httpserver = null;
|
||||
var gPAS = Cc["@mozilla.org/network/packaged-app-service;1"]
|
||||
.getService(Ci.nsIPackagedAppService);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "uri", function() {
|
||||
return "http://localhost:" + httpserver.identity.primaryPort;
|
||||
@ -178,10 +176,10 @@ headerListener.prototype.visitHeader = function(header, value) {
|
||||
function test_multipart() {
|
||||
var streamConv = Cc["@mozilla.org/streamConverters;1"]
|
||||
.getService(Ci.nsIStreamConverterService);
|
||||
var conv = streamConv.asyncConvertData("multipart/mixed",
|
||||
var conv = streamConv.asyncConvertData("application/package",
|
||||
"*/*",
|
||||
new multipartListener(testData),
|
||||
gPAS);
|
||||
null);
|
||||
|
||||
var chan = make_channel(uri + "/multipart");
|
||||
chan.asyncOpen(conv, null);
|
||||
@ -190,10 +188,10 @@ function test_multipart() {
|
||||
function test_multipart_with_boundary() {
|
||||
var streamConv = Cc["@mozilla.org/streamConverters;1"]
|
||||
.getService(Ci.nsIStreamConverterService);
|
||||
var conv = streamConv.asyncConvertData("multipart/mixed",
|
||||
var conv = streamConv.asyncConvertData("application/package",
|
||||
"*/*",
|
||||
new multipartListener(testData),
|
||||
gPAS);
|
||||
null);
|
||||
|
||||
var chan = make_channel(uri + "/multipart2");
|
||||
chan.asyncOpen(conv, null);
|
||||
@ -202,10 +200,10 @@ function test_multipart_with_boundary() {
|
||||
function test_multipart_chunked_headers() {
|
||||
var streamConv = Cc["@mozilla.org/streamConverters;1"]
|
||||
.getService(Ci.nsIStreamConverterService);
|
||||
var conv = streamConv.asyncConvertData("multipart/mixed",
|
||||
var conv = streamConv.asyncConvertData("application/package",
|
||||
"*/*",
|
||||
new multipartListener(testData),
|
||||
gPAS);
|
||||
null);
|
||||
|
||||
var chan = make_channel(uri + "/multipart3");
|
||||
chan.asyncOpen(conv, null);
|
||||
@ -215,12 +213,10 @@ function test_multipart_content_type_other() {
|
||||
var streamConv = Cc["@mozilla.org/streamConverters;1"]
|
||||
.getService(Ci.nsIStreamConverterService);
|
||||
|
||||
// mime types other that multipart/mixed and application/package are only
|
||||
// allowed if an nsIPackagedAppService is passed as context
|
||||
var conv = streamConv.asyncConvertData("multipart/mixed",
|
||||
var conv = streamConv.asyncConvertData("application/package",
|
||||
"*/*",
|
||||
new multipartListener(testData, true),
|
||||
gPAS);
|
||||
null);
|
||||
|
||||
var chan = make_channel(uri + "/multipart4");
|
||||
chan.asyncOpen(conv, null);
|
||||
|
Loading…
Reference in New Issue
Block a user