зеркало из 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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsBaseChannel::HasContentTypeHint() const
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!IsPending(), "HasContentTypeHint called too late");
|
||||||
|
return !mContentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsBaseChannel::SetContentLength64(PRInt64 len)
|
nsBaseChannel::SetContentLength64(PRInt64 len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,6 +125,12 @@ public:
|
||||||
// parameter consists of the flag values defined on nsIChannelEventSink.
|
// parameter consists of the flag values defined on nsIChannelEventSink.
|
||||||
nsresult Redirect(nsIChannel *newChannel, PRUint32 redirectFlags);
|
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
|
// The URI member should be initialized before the channel is used, and then
|
||||||
// it should never be changed again until the channel is destroyed.
|
// it should never be changed again until the channel is destroyed.
|
||||||
nsIURI *URI() {
|
nsIURI *URI() {
|
||||||
|
@ -154,7 +160,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a short-cut to calling nsIRequest::IsPending()
|
// This is a short-cut to calling nsIRequest::IsPending()
|
||||||
PRBool IsPending() {
|
PRBool IsPending() const {
|
||||||
return (mPump != nsnull);
|
return (mPump != nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,11 +269,10 @@ nsFileUploadContentStream::OnOutputStreamReady(nsIAsyncOutputStream *unused)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Called to construct a blocking file input stream for the given file. This
|
nsresult
|
||||||
// method also returns a best guess at the content-type for the data stream.
|
nsFileChannel::MakeFileInputStream(nsIFile *file,
|
||||||
static nsresult
|
nsCOMPtr<nsIInputStream> &stream,
|
||||||
MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
|
nsCString &contentType)
|
||||||
nsCString &contentType)
|
|
||||||
{
|
{
|
||||||
// we accept that this might result in a disk hit to stat the file
|
// we accept that this might result in a disk hit to stat the file
|
||||||
PRBool isDir;
|
PRBool isDir;
|
||||||
|
@ -287,11 +286,11 @@ MakeFileInputStream(nsIFile *file, nsCOMPtr<nsIInputStream> &stream,
|
||||||
|
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
rv = nsDirectoryIndexStream::Create(file, getter_AddRefs(stream));
|
rv = nsDirectoryIndexStream::Create(file, getter_AddRefs(stream));
|
||||||
if (NS_SUCCEEDED(rv))
|
if (NS_SUCCEEDED(rv) && !HasContentTypeHint())
|
||||||
contentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
|
contentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT);
|
||||||
} else {
|
} else {
|
||||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv) && !HasContentTypeHint()) {
|
||||||
// Use file extension to infer content type
|
// Use file extension to infer content type
|
||||||
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
|
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
|
||||||
if (NS_SUCCEEDED(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
|
// 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
|
// to something other than "unknown" to avoid triggering the content-type
|
||||||
// sniffer code in nsBaseChannel.
|
// 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 {
|
} else {
|
||||||
nsCAutoString contentType;
|
nsCAutoString contentType;
|
||||||
nsresult rv = MakeFileInputStream(file, stream, contentType);
|
nsresult rv = MakeFileInputStream(file, stream, contentType);
|
||||||
|
|
|
@ -58,6 +58,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
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);
|
virtual nsresult OpenContentStream(PRBool async, nsIInputStream **result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -5,10 +5,13 @@ const Ci = Components.interfaces;
|
||||||
const Cr = Components.results;
|
const Cr = Components.results;
|
||||||
const PR_RDONLY = 0x1; // see prio.h
|
const PR_RDONLY = 0x1; // see prio.h
|
||||||
|
|
||||||
|
const special_type = "application/x-our-special-type";
|
||||||
|
|
||||||
var test_index = 0;
|
var test_index = 0;
|
||||||
var test_array = [
|
var test_array = [
|
||||||
test_read_file,
|
test_read_file,
|
||||||
test_read_dir,
|
test_read_dir_1,
|
||||||
|
test_read_dir_2,
|
||||||
test_upload_file,
|
test_upload_file,
|
||||||
do_test_finished
|
do_test_finished
|
||||||
];
|
];
|
||||||
|
@ -137,6 +140,11 @@ function test_read_file() {
|
||||||
function on_read_complete(data) {
|
function on_read_complete(data) {
|
||||||
dump("*** test_read_file.on_read_complete\n");
|
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,
|
/* read completed successfully. now read data directly from file,
|
||||||
and compare the result. */
|
and compare the result. */
|
||||||
var stream = new_file_input_stream(file, false);
|
var stream = new_file_input_stream(file, false);
|
||||||
|
@ -146,27 +154,40 @@ function test_read_file() {
|
||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chan.contentType = special_type;
|
||||||
chan.asyncOpen(new Listener(on_read_complete), null);
|
chan.asyncOpen(new Listener(on_read_complete), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_read_dir() {
|
function do_test_read_dir(set_type, expected_type) {
|
||||||
dump("*** test_read_dir\n");
|
dump("*** test_read_dir(" + set_type + ", " + expected_type + ")\n");
|
||||||
|
|
||||||
var file = getFile("TmpD");
|
var file = getFile("TmpD");
|
||||||
var chan = new_file_channel(file);
|
var chan = new_file_channel(file);
|
||||||
|
|
||||||
function on_read_complete(data) {
|
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();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (set_type)
|
||||||
|
chan.contentType = expected_type;
|
||||||
chan.asyncOpen(new Listener(on_read_complete), null);
|
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() {
|
function test_upload_file() {
|
||||||
dump("*** test_upload_file\n");
|
dump("*** test_upload_file\n");
|
||||||
|
|
||||||
|
@ -184,6 +205,11 @@ function test_upload_file() {
|
||||||
function on_upload_complete(data) {
|
function on_upload_complete(data) {
|
||||||
dump("*** test_upload_file.on_upload_complete\n");
|
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. */
|
/* upload of file completed successfully. */
|
||||||
if (data.length != 0)
|
if (data.length != 0)
|
||||||
do_throw("Upload resulted in data!");
|
do_throw("Upload resulted in data!");
|
||||||
|
@ -209,6 +235,7 @@ function test_upload_file() {
|
||||||
run_next_test();
|
run_next_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chan.contentType = special_type;
|
||||||
chan.asyncOpen(new Listener(on_upload_complete), null);
|
chan.asyncOpen(new Listener(on_upload_complete), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче