// Get the original HTTP response header from the request. static bool GetOriginalResponseHeader(nsIRequest* aRequest, nsACString& aHeader) { nsCOMPtr<nsIMultiPartChannel> multiPartChannel(do_QueryInterface(aRequest)); if (!multiPartChannel) { return false; } multiPartChannel->GetOriginalResponseHeader(aHeader); return true; }
/* void onDataAvailable (in nsIRequest request, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */ NS_IMETHODIMP imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt, nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) { LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "count", count); NS_ASSERTION(aRequest, "imgRequest::OnDataAvailable -- no request!"); mGotData = PR_TRUE; if (!mProcessing) { LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable |First time through... finding mimetype|"); /* set our processing flag to true if this is the first OnDataAvailable() */ mProcessing = PR_TRUE; /* look at the first few bytes and see if we can tell what the data is from that * since servers tend to lie. :( */ PRUint32 out; inStr->ReadSegments(sniff_mimetype_callback, this, count, &out); #ifdef NS_DEBUG /* NS_WARNING if the content type from the channel isn't the same if the sniffing */ #endif if (mContentType.IsEmpty()) { LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable |sniffing of mimetype failed|"); nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest)); nsresult rv = NS_ERROR_FAILURE; if (chan) { rv = chan->GetContentType(mContentType); } if (NS_FAILED(rv)) { PR_LOG(gImgLog, PR_LOG_ERROR, ("[this=%p] imgRequest::OnDataAvailable -- Content type unavailable from the channel\n", this)); this->Cancel(NS_IMAGELIB_ERROR_FAILURE); return NS_BINDING_ABORTED; } LOG_MSG(gImgLog, "imgRequest::OnDataAvailable", "Got content type from the channel"); } /* set our mimetype as a property */ nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1")); if (contentType) { contentType->SetData(mContentType); mProperties->Set("type", contentType); } /* set our content disposition as a property */ nsCAutoString disposition; nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest)); if (httpChannel) { httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-disposition"), disposition); } else { nsCOMPtr<nsIMultiPartChannel> multiPartChannel(do_QueryInterface(aRequest)); if (multiPartChannel) { multiPartChannel->GetContentDisposition(disposition); } } if (!disposition.IsEmpty()) { nsCOMPtr<nsISupportsCString> contentDisposition(do_CreateInstance("@mozilla.org/supports-cstring;1")); if (contentDisposition) { contentDisposition->SetData(disposition); mProperties->Set("content-disposition", contentDisposition); } } LOG_MSG_WITH_PARAM(gImgLog, "imgRequest::OnDataAvailable", "content type", mContentType.get()); nsCAutoString conid(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;2?type=") + mContentType); mDecoder = do_CreateInstance(conid.get()); if (!mDecoder) { PR_LOG(gImgLog, PR_LOG_WARNING, ("[this=%p] imgRequest::OnDataAvailable -- Decoder not available\n", this)); // no image decoder for this mimetype :( this->Cancel(NS_IMAGELIB_ERROR_NO_DECODER); return NS_IMAGELIB_ERROR_NO_DECODER; } nsresult rv = mDecoder->Init(static_cast<imgILoad*>(this)); if (NS_FAILED(rv)) { PR_LOG(gImgLog, PR_LOG_WARNING, ("[this=%p] imgRequest::OnDataAvailable -- mDecoder->Init failed\n", this)); this->Cancel(NS_IMAGELIB_ERROR_FAILURE); return NS_BINDING_ABORTED; } } if (!mDecoder) { PR_LOG(gImgLog, PR_LOG_WARNING, ("[this=%p] imgRequest::OnDataAvailable -- no decoder\n", this)); this->Cancel(NS_IMAGELIB_ERROR_NO_DECODER); return NS_BINDING_ABORTED; } // The decoder will start decoding into the current frame (if we have one). // When it needs to add another frame, we will unlock this frame and lock the // new frame. // Our invariant is that, while in the decoder, the last frame is always // locked, and all others are unlocked. imgContainer *image = reinterpret_cast<imgContainer*>(mImage.get()); if (image->mFrames.Length() > 0) { imgFrame *curframe = image->mFrames.ElementAt(image->mFrames.Length() - 1); curframe->LockImageData(); } PRUint32 wrote; nsresult rv = mDecoder->WriteFrom(inStr, count, &wrote); // We unlock the current frame, even if that frame is different from the // frame we entered the decoder with. (See above.) if (image->mFrames.Length() > 0) { imgFrame *curframe = image->mFrames.ElementAt(image->mFrames.Length() - 1); curframe->UnlockImageData(); } if (NS_FAILED(rv)) { PR_LOG(gImgLog, PR_LOG_WARNING, ("[this=%p] imgRequest::OnDataAvailable -- mDecoder->WriteFrom failed\n", this)); this->Cancel(NS_IMAGELIB_ERROR_FAILURE); return NS_BINDING_ABORTED; } return NS_OK; }