зеркало из https://github.com/mozilla/pjs.git
bug 326693 filechannel ignores content-type hints
r+sr=darin
This commit is contained in:
Родитель
41d0754579
Коммит
0233b3a085
|
@ -167,6 +167,13 @@ nsBaseChannel::Redirect(nsIChannel *newChannel, PRUint32 redirectFlags)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsBaseChannel::HasContentTypeHint() const
|
||||
{
|
||||
NS_ASSERTION(!IsPending(), "HasContentTypeHint called too late");
|
||||
return !mContentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE);
|
||||
}
|
||||
|
||||
void
|
||||
nsBaseChannel::SetContentLength64(PRInt64 len)
|
||||
{
|
||||
|
|
|
@ -125,6 +125,12 @@ public:
|
|||
// parameter consists of the flag values defined on nsIChannelEventSink.
|
||||
nsresult Redirect(nsIChannel *newChannel, PRUint32 redirectFlags);
|
||||
|
||||
// Tests whether a type hint was set. Subclasses can use this to decide
|
||||
// whether to call SetContentType.
|
||||
// NOTE: This is only reliable if the subclass didn't itself call
|
||||
// SetContentType, and should also not be called after OpenContentStream.
|
||||
PRBool HasContentTypeHint() const;
|
||||
|
||||
// The URI member should be initialized before the channel is used, and then
|
||||
// it should never be changed again until the channel is destroyed.
|
||||
nsIURI *URI() {
|
||||
|
@ -154,7 +160,7 @@ public:
|
|||
}
|
||||
|
||||
// This is a short-cut to calling nsIRequest::IsPending()
|
||||
PRBool IsPending() {
|
||||
PRBool IsPending() const {
|
||||
return (mPump != nsnull);
|
||||
}
|
||||
|
||||
|
|
|
@ -269,11 +269,10 @@ nsFileUploadContentStream::OnOutputStreamReady(nsIAsyncOutputStream *unused)
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Called to construct a blocking file input stream for the given file. This
|
||||
// method also returns a best guess at the content-type for the data stream.
|
||||
static nsresult
|
||||
MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
|
||||
nsCString &contentType)
|
||||
nsresult
|
||||
nsFileChannel::MakeFileInputStream(nsIFile *file,
|
||||
nsCOMPtr<nsIInputStream> &stream,
|
||||
nsCString &contentType)
|
||||
{
|
||||
// we accept that this might result in a disk hit to stat the file
|
||||
PRBool isDir;
|
||||
|
@ -287,11 +286,11 @@ MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
|
|||
|
||||
if (isDir) {
|
||||
rv = nsDirectoryIndexStream::Create(file, getter_AddRefs(stream));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (NS_SUCCEEDED(rv) && !HasContentTypeHint())
|
||||
contentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
|
||||
} else {
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (NS_SUCCEEDED(rv) && !HasContentTypeHint()) {
|
||||
// Use file extension to infer content type
|
||||
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -336,7 +335,9 @@ nsFileChannel::OpenContentStream(PRBool async, nsIInputStream **result)
|
|||
// Since there isn't any content to speak of we just set the content-type
|
||||
// to something other than "unknown" to avoid triggering the content-type
|
||||
// sniffer code in nsBaseChannel.
|
||||
SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
|
||||
// However, don't override explicitly set types.
|
||||
if (!HasContentTypeHint())
|
||||
SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
|
||||
} else {
|
||||
nsCAutoString contentType;
|
||||
nsresult rv = MakeFileInputStream(file, stream, contentType);
|
||||
|
|
|
@ -58,6 +58,13 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
// Called to construct a blocking file input stream for the given file. This
|
||||
// method also returns a best guess at the content-type for the data stream.
|
||||
// NOTE: If the channel has a type hint set, contentType will be left
|
||||
// untouched. The caller should not use it in that case.
|
||||
nsresult MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
|
||||
nsCString &contentType);
|
||||
|
||||
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,10 +5,13 @@ const Ci = Components.interfaces;
|
|||
const Cr = Components.results;
|
||||
const PR_RDONLY = 0x1; // see prio.h
|
||||
|
||||
const special_type = "application/x-our-special-type";
|
||||
|
||||
var test_index = 0;
|
||||
var test_array = [
|
||||
test_read_file,
|
||||
test_read_dir,
|
||||
test_read_dir_1,
|
||||
test_read_dir_2,
|
||||
test_upload_file,
|
||||
do_test_finished
|
||||
];
|
||||
|
@ -137,6 +140,11 @@ function test_read_file() {
|
|||
function on_read_complete(data) {
|
||||
dump("*** test_read_file.on_read_complete\n");
|
||||
|
||||
// bug 326693
|
||||
if (chan.contentType != special_type)
|
||||
do_throw("Type mismatch! Is <" + chan.contentType + ">, should be <" +
|
||||
special_type + ">")
|
||||
|
||||
/* read completed successfully. now read data directly from file,
|
||||
and compare the result. */
|
||||
var stream = new_file_input_stream(file, false);
|
||||
|
@ -146,27 +154,40 @@ function test_read_file() {
|
|||
run_next_test();
|
||||
}
|
||||
|
||||
chan.contentType = special_type;
|
||||
chan.asyncOpen(new Listener(on_read_complete), null);
|
||||
}
|
||||
|
||||
function test_read_dir() {
|
||||
dump("*** test_read_dir\n");
|
||||
function do_test_read_dir(set_type, expected_type) {
|
||||
dump("*** test_read_dir(" + set_type + ", " + expected_type + ")\n");
|
||||
|
||||
var file = getFile("TmpD");
|
||||
var chan = new_file_channel(file);
|
||||
|
||||
function on_read_complete(data) {
|
||||
dump("*** test_read_dir.on_read_complete\n");
|
||||
dump("*** test_read_dir.on_read_complete(" + set_type + ", " + expected_type + ")\n");
|
||||
|
||||
// bug 326693
|
||||
if (chan.contentType != expected_type)
|
||||
do_throw("Type mismatch! Is <" + chan.contentType + ">, should be <" +
|
||||
expected_type + ">")
|
||||
|
||||
/* read of directory completed successfully. */
|
||||
if (chan.contentType != "application/http-index-format")
|
||||
do_throw("Unexpected content type!");
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
if (set_type)
|
||||
chan.contentType = expected_type;
|
||||
chan.asyncOpen(new Listener(on_read_complete), null);
|
||||
}
|
||||
|
||||
function test_read_dir_1() {
|
||||
return do_test_read_dir(false, "application/http-index-format");
|
||||
}
|
||||
|
||||
function test_read_dir_2() {
|
||||
return do_test_read_dir(true, special_type);
|
||||
}
|
||||
|
||||
function test_upload_file() {
|
||||
dump("*** test_upload_file\n");
|
||||
|
||||
|
@ -184,6 +205,11 @@ function test_upload_file() {
|
|||
function on_upload_complete(data) {
|
||||
dump("*** test_upload_file.on_upload_complete\n");
|
||||
|
||||
// bug 326693
|
||||
if (chan.contentType != special_type)
|
||||
do_throw("Type mismatch! Is <" + chan.contentType + ">, should be <" +
|
||||
special_type + ">")
|
||||
|
||||
/* upload of file completed successfully. */
|
||||
if (data.length != 0)
|
||||
do_throw("Upload resulted in data!");
|
||||
|
@ -209,6 +235,7 @@ function test_upload_file() {
|
|||
run_next_test();
|
||||
}
|
||||
|
||||
chan.contentType = special_type;
|
||||
chan.asyncOpen(new Listener(on_upload_complete), null);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче