nsresult nsUnknownDecoder::ConvertEncodedData(nsIRequest* request, const char* data, uint32_t length) { nsresult rv = NS_OK; mDecodedData = ""; nsCOMPtr<nsIEncodedChannel> encodedChannel(do_QueryInterface(request)); if (encodedChannel) { RefPtr<ConvertedStreamListener> strListener = new ConvertedStreamListener(this); nsCOMPtr<nsIStreamListener> listener; rv = encodedChannel->DoApplyContentConversions(strListener, getter_AddRefs(listener), nullptr); if (NS_FAILED(rv)) { return rv; } if (listener) { listener->OnStartRequest(request, nullptr); nsCOMPtr<nsIStringInputStream> rawStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID); if (!rawStream) return NS_ERROR_FAILURE; rv = rawStream->SetData((const char*)data, length); NS_ENSURE_SUCCESS(rv, rv); rv = listener->OnDataAvailable(request, nullptr, rawStream, 0, length); NS_ENSURE_SUCCESS(rv, rv); listener->OnStopRequest(request, nullptr, NS_OK); } } return rv; }
NS_IMETHODIMP HeaderSniffer::OnStopRequest (nsIRequest *aRequest, nsISupports *aContext, nsresult aStatusCode) { nsresult rv; LOG ("HeaderSniffer::OnStopRequest"); if (aStatusCode != NS_BINDING_SUCCEEDED) { GtkWidget *parent, *dialog; parent = galeon_embed_persist_get_fc_parent (mEmbedPersist); dialog = hig_alert_new (parent ? GTK_WINDOW (parent) : NULL, GTK_DIALOG_DESTROY_WITH_PARENT, HIG_ALERT_ERROR, _("Unable to save link."), _("The web page might have been removed " "or had its name changed."), GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); g_signal_connect (dialog, "response", (GCallback)gtk_widget_destroy, NULL); gtk_widget_show (dialog); return NS_OK; } nsCOMPtr<nsIURIChecker> checker = do_QueryInterface (aRequest); NS_ENSURE_TRUE (checker, NS_ERROR_FAILURE); nsCOMPtr<nsIChannel> channel; checker->GetBaseChannel (getter_AddRefs(channel)); NS_ENSURE_TRUE (channel, NS_ERROR_FAILURE); /* Get the final URL of the request */ channel->GetURI (getter_AddRefs(mFinalURL)); /* Get the Content-Disposition header, it might give us a * hint on the filename */ nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); GulCString contentDisposition; if (httpChannel) { httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-disposition"), contentDisposition); } /* Get the document encoding */ nsCOMPtr<nsIEncodedChannel> encodedChannel(do_QueryInterface(channel)); GulCString contentEncoding; if (encodedChannel) { nsCOMPtr<nsIUTF8StringEnumerator> enumerator; encodedChannel->GetContentEncodings (getter_AddRefs (enumerator)); if (enumerator) { PRBool more = PR_FALSE; enumerator->HasMore (&more); if (more) { enumerator->GetNext (contentEncoding); } } } /* Get the Content-Type header */ GulCString contentType; channel->GetContentType(contentType); if (contentType.Equals ("application/x-unknown-content-type")) { contentType = ""; } /* If no Content-Type, try and get it from the document */ if (contentType.IsEmpty() && mDocument) { nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(mDocument); if (doc) { GulString type; doc->GetContentType (type); contentType = type; } } /* Failing that, guess from the url */ if (contentType.IsEmpty()) { nsCOMPtr<nsIMIMEService> mimeService (do_GetService(NS_MIMESERVICE_CONTRACTID)); mimeService->GetTypeFromURI (mFinalURL, contentType); } /* Calculate whether we whould decode */ mShouldDecode = PR_FALSE; if (contentEncoding.Length ()) { nsCOMPtr<nsIExternalHelperAppService> helperService = do_GetService (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID); nsCOMPtr<nsIURL> resultURL = do_QueryInterface (mFinalURL); if (resultURL) { GulCString extension; resultURL->GetFileExtension (extension); rv = helperService->ApplyDecodingForExtension (extension, contentEncoding, &mShouldDecode); if (NS_FAILED (rv)) { mShouldDecode = PR_FALSE; } } } if (!mDocument && !mShouldDecode && contentEncoding.Length()) { // The data is encoded, we are not going to decode it, // and this is not a document save so just set our // content type to correspond to the outermost // encoding so we get extensions and the like right. contentType = contentEncoding; } GulCString filename; rv = GetFilename (contentDisposition, contentType, filename); NS_ENSURE_TRUE (NS_SUCCEEDED (rv), NS_ERROR_FAILURE); PerformSave (filename); return NS_OK; }