зеркало из https://github.com/mozilla/gecko-dev.git
Bug 129607, avoid trying to parse the response if we cannot be sure it is XML. This fixes hang in HTML parser, and is a big performance improvement if you are loading non-XML data. r=harishd, sr=vidur.
This commit is contained in:
Родитель
44b4fc0a4f
Коммит
7801aa57ee
|
@ -181,8 +181,6 @@ nsXMLHttpRequest::AddEventListener(const nsAString& type,
|
||||||
NS_ENSURE_ARG(listener);
|
NS_ENSURE_ARG(listener);
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
// I know, I know - strcmp's. But it's only for a couple of
|
|
||||||
// cases...and they are short strings. :-)
|
|
||||||
if (type.Equals(LOADSTR)) {
|
if (type.Equals(LOADSTR)) {
|
||||||
if (!mLoadEventListeners) {
|
if (!mLoadEventListeners) {
|
||||||
rv = NS_NewISupportsArray(getter_AddRefs(mLoadEventListeners));
|
rv = NS_NewISupportsArray(getter_AddRefs(mLoadEventListeners));
|
||||||
|
@ -784,23 +782,25 @@ nsXMLHttpRequest::StreamReaderFunc(nsIInputStream* in,
|
||||||
// Copy for our own use
|
// Copy for our own use
|
||||||
xmlHttpRequest->mResponseBody.Append(fromRawSegment,count);
|
xmlHttpRequest->mResponseBody.Append(fromRawSegment,count);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
// Give the same data to the parser.
|
if (xmlHttpRequest->mParseResponseBody) {
|
||||||
|
// Give the same data to the parser.
|
||||||
|
|
||||||
// We need to wrap the data in a new lightweight stream and pass that
|
// We need to wrap the data in a new lightweight stream and pass that
|
||||||
// to the parser, because calling ReadSegments() recursively on the same
|
// to the parser, because calling ReadSegments() recursively on the same
|
||||||
// stream is not supported.
|
// stream is not supported.
|
||||||
nsCOMPtr<nsISupports> supportsStream;
|
nsCOMPtr<nsISupports> supportsStream;
|
||||||
rv = NS_NewByteInputStream(getter_AddRefs(supportsStream),fromRawSegment,count);
|
rv = NS_NewByteInputStream(getter_AddRefs(supportsStream),fromRawSegment,count);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
nsCOMPtr<nsIInputStream> copyStream(do_QueryInterface(supportsStream));
|
nsCOMPtr<nsIInputStream> copyStream(do_QueryInterface(supportsStream));
|
||||||
if (copyStream) {
|
if (copyStream) {
|
||||||
rv = xmlHttpRequest->mXMLParserStreamListener->OnDataAvailable(xmlHttpRequest->mReadRequest,xmlHttpRequest->mContext,copyStream,toOffset,count);
|
rv = xmlHttpRequest->mXMLParserStreamListener->OnDataAvailable(xmlHttpRequest->mReadRequest,xmlHttpRequest->mContext,copyStream,toOffset,count);
|
||||||
} else {
|
} else {
|
||||||
NS_ERROR("NS_NewByteInputStream did not give out nsIInputStream!");
|
NS_ERROR("NS_NewByteInputStream did not give out nsIInputStream!");
|
||||||
rv = NS_ERROR_UNEXPECTED;
|
rv = NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,8 +833,22 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||||
{
|
{
|
||||||
mReadRequest = request;
|
mReadRequest = request;
|
||||||
mContext = ctxt;
|
mContext = ctxt;
|
||||||
|
mParseResponseBody = PR_TRUE;
|
||||||
ChangeState(XML_HTTP_REQUEST_LOADED);
|
ChangeState(XML_HTTP_REQUEST_LOADED);
|
||||||
if (!mOverrideMimeType.IsEmpty()) {
|
if (mOverrideMimeType.IsEmpty()) {
|
||||||
|
// If we are not overriding the mime type, we can gain a huge performance
|
||||||
|
// win by not even trying to parse non-XML data. This also protects us
|
||||||
|
// from the situation where we have an XML document and sink, but HTML (or other)
|
||||||
|
// parser, which can produce unreliable results.
|
||||||
|
nsCAutoString type;
|
||||||
|
mChannel->GetContentType(type);
|
||||||
|
nsACString::const_iterator start, end;
|
||||||
|
type.BeginReading(start);
|
||||||
|
type.EndReading(end);
|
||||||
|
if (!FindInReadable(NS_LITERAL_CSTRING("xml"), start, end)) {
|
||||||
|
mParseResponseBody = PR_FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
nsresult status;
|
nsresult status;
|
||||||
request->GetStatus(&status);
|
request->GetStatus(&status);
|
||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||||
|
@ -842,7 +856,8 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||||
channel->SetContentType(mOverrideMimeType);
|
channel->SetContentType(mOverrideMimeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mXMLParserStreamListener->OnStartRequest(request,ctxt);
|
|
||||||
|
return mParseResponseBody ? mXMLParserStreamListener->OnStartRequest(request,ctxt) : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status, in wstring statusArg); */
|
/* void onStopRequest (in nsIRequest request, in nsISupports ctxt, in nsresult status, in wstring statusArg); */
|
||||||
|
@ -852,7 +867,7 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult
|
||||||
nsCOMPtr<nsIParser> parser(do_QueryInterface(mXMLParserStreamListener));
|
nsCOMPtr<nsIParser> parser(do_QueryInterface(mXMLParserStreamListener));
|
||||||
NS_ABORT_IF_FALSE(parser, "stream listener was expected to be a parser");
|
NS_ABORT_IF_FALSE(parser, "stream listener was expected to be a parser");
|
||||||
|
|
||||||
nsresult rv = mXMLParserStreamListener->OnStopRequest(request,ctxt,status);
|
nsresult rv = mParseResponseBody ? mXMLParserStreamListener->OnStopRequest(request,ctxt,status) : NS_OK;
|
||||||
mXMLParserStreamListener = nsnull;
|
mXMLParserStreamListener = nsnull;
|
||||||
mReadRequest = nsnull;
|
mReadRequest = nsnull;
|
||||||
mContext = nsnull;
|
mContext = nsnull;
|
||||||
|
@ -1043,6 +1058,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case nsIDataType::VTYPE_VOID:
|
case nsIDataType::VTYPE_VOID:
|
||||||
case nsIDataType::VTYPE_EMPTY:
|
case nsIDataType::VTYPE_EMPTY:
|
||||||
// Makes us act as if !aBody, don't upload anything
|
// Makes us act as if !aBody, don't upload anything
|
||||||
|
|
|
@ -160,7 +160,8 @@ protected:
|
||||||
nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
|
nsCOMPtr<nsIStreamListener> mXMLParserStreamListener;
|
||||||
|
|
||||||
PRInt32 mStatus;
|
PRInt32 mStatus;
|
||||||
PRBool mAsync;
|
PRPackedBool mAsync;
|
||||||
|
PRPackedBool mParseResponseBody;
|
||||||
nsCString mOverrideMimeType;
|
nsCString mOverrideMimeType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче