зеркало из https://github.com/mozilla/gecko-dev.git
Bug 17586. Use more robust condition to determine stream length ('-1') for HTTP-index streams on directories. Add lots of logging along the way. r=syd,valeski.
This commit is contained in:
Родитель
8cc87b679d
Коммит
f8347ec3fb
|
@ -23,19 +23,35 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
The converts a filesystem directory into an "HTTP index" stream.
|
The converts a filesystem directory into an "HTTP index" stream per
|
||||||
|
Lou Montulli's original spec:
|
||||||
|
|
||||||
|
http://www.area.com/~roeber/file_format.html
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nsEscape.h"
|
#include "nsEscape.h"
|
||||||
#include "nsDirectoryIndexStream.h"
|
#include "nsDirectoryIndexStream.h"
|
||||||
|
#include "nsXPIDLString.h"
|
||||||
#include "prio.h"
|
#include "prio.h"
|
||||||
|
#include "prlog.h"
|
||||||
|
|
||||||
|
#ifdef PR_LOGGING
|
||||||
|
static PRLogModuleInfo* gLog;
|
||||||
|
#endif
|
||||||
|
|
||||||
nsDirectoryIndexStream::nsDirectoryIndexStream()
|
nsDirectoryIndexStream::nsDirectoryIndexStream()
|
||||||
: mOffset(0)
|
: mOffset(0)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
|
||||||
|
#ifdef PR_LOGGING
|
||||||
|
if (! gLog)
|
||||||
|
gLog = PR_NewLogModule("nsDirectoryIndexStream");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
||||||
|
("nsDirectoryIndexStream[%p]: created", this));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -49,6 +65,16 @@ nsDirectoryIndexStream::Init(nsIFile* aDir)
|
||||||
if (!isDir)
|
if (!isDir)
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
|
||||||
|
#ifdef PR_LOGGING
|
||||||
|
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
|
||||||
|
nsXPIDLCString path;
|
||||||
|
aDir->GetPath(getter_Copies(path));
|
||||||
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
||||||
|
("nsDirectoryIndexStream[%p]: initialized on %s",
|
||||||
|
this, (const char*) path));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mDir = aDir;
|
mDir = aDir;
|
||||||
|
|
||||||
// Sigh. We have to allocate on the heap because there are no
|
// Sigh. We have to allocate on the heap because there are no
|
||||||
|
@ -62,6 +88,8 @@ nsDirectoryIndexStream::Init(nsIFile* aDir)
|
||||||
|
|
||||||
nsDirectoryIndexStream::~nsDirectoryIndexStream()
|
nsDirectoryIndexStream::~nsDirectoryIndexStream()
|
||||||
{
|
{
|
||||||
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
||||||
|
("nsDirectoryIndexStream[%p]: destroyed", this));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -141,11 +169,26 @@ nsDirectoryIndexStream::Read(char* aBuf, PRUint32 aCount, PRUint32* aReadCount)
|
||||||
nsCOMPtr<nsIFile> current = do_QueryInterface(cur, &rv);
|
nsCOMPtr<nsIFile> current = do_QueryInterface(cur, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
#ifdef PR_LOGGING
|
||||||
|
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
|
||||||
|
nsXPIDLCString path;
|
||||||
|
current->GetPath(getter_Copies(path));
|
||||||
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
||||||
|
("nsDirectoryIndexStream[%p]: iterated %s",
|
||||||
|
this, (const char*) path));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// rjc: don't return hidden files/directories!
|
// rjc: don't return hidden files/directories!
|
||||||
PRBool hidden;
|
PRBool hidden;
|
||||||
rv = current->IsHidden(&hidden);
|
rv = current->IsHidden(&hidden);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
if (hidden) continue;
|
if (hidden) {
|
||||||
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
||||||
|
("nsDirectoryIndexStream[%p]: skipping hidden file/directory",
|
||||||
|
this));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
char* path;
|
char* path;
|
||||||
rv = current->GetPath(&path);
|
rv = current->GetPath(&path);
|
||||||
|
|
|
@ -88,10 +88,7 @@ public:
|
||||||
|
|
||||||
// We'll try to use the file's length, if it has one. If not,
|
// We'll try to use the file's length, if it has one. If not,
|
||||||
// assume the file to be special, and set the content length
|
// assume the file to be special, and set the content length
|
||||||
// to -1, which means "read the stream until
|
// to -1, which means "read the stream until exhausted".
|
||||||
// exhausted". (Conveniently, a filespec will return "0" for a
|
|
||||||
// directory's length, so our directory HTTP index stream will
|
|
||||||
// just do the right thing.)
|
|
||||||
PRInt64 size;
|
PRInt64 size;
|
||||||
rv = mFile->GetFileSize(&size);
|
rv = mFile->GetFileSize(&size);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
@ -105,7 +102,11 @@ public:
|
||||||
PRBool isDir;
|
PRBool isDir;
|
||||||
rv = mFile->IsDirectory(&isDir);
|
rv = mFile->IsDirectory(&isDir);
|
||||||
if (NS_SUCCEEDED(rv) && isDir) {
|
if (NS_SUCCEEDED(rv) && isDir) {
|
||||||
|
// Directories turn into an HTTP-index stream, with
|
||||||
|
// unbounded (i.e., read 'til the stream says it's done)
|
||||||
|
// length.
|
||||||
*contentType = nsCRT::strdup("application/http-index-format");
|
*contentType = nsCRT::strdup("application/http-index-format");
|
||||||
|
*contentLength = -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char* fileName;
|
char* fileName;
|
||||||
|
@ -336,9 +337,6 @@ nsFileTransport::nsFileTransport()
|
||||||
mOffset(0),
|
mOffset(0),
|
||||||
mTotalAmount(-1),
|
mTotalAmount(-1),
|
||||||
mTransferAmount(0),
|
mTransferAmount(0),
|
||||||
#ifdef PR_LOGGING
|
|
||||||
mSpec(nsnull),
|
|
||||||
#endif
|
|
||||||
mBuffer(nsnull)
|
mBuffer(nsnull)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
|
@ -351,6 +349,8 @@ nsFileTransport::nsFileTransport()
|
||||||
if (nsnull == gFileTransportLog) {
|
if (nsnull == gFileTransportLog) {
|
||||||
gFileTransportLog = PR_NewLogModule("nsFileTransport");
|
gFileTransportLog = PR_NewLogModule("nsFileTransport");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSpec = nsnull;
|
||||||
#endif /* PR_LOGGING */
|
#endif /* PR_LOGGING */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,8 +591,8 @@ nsFileTransport::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
|
||||||
*result = mBufferInputStream.get();
|
*result = mBufferInputStream.get();
|
||||||
NS_ADDREF(*result);
|
NS_ADDREF(*result);
|
||||||
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
||||||
("nsFileTransport: OpenInputStream [this=%x %s]",
|
("nsFileTransport: OpenInputStream [this=%x %s] startPosition=%d readCount=%d",
|
||||||
this, (const char*)mSpec));
|
this, (const char*)mSpec, startPosition, readCount));
|
||||||
|
|
||||||
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
@ -722,8 +722,8 @@ nsFileTransport::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
|
||||||
mTransferAmount = readCount;
|
mTransferAmount = readCount;
|
||||||
|
|
||||||
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
||||||
("nsFileTransport: AsyncRead [this=%x %s]",
|
("nsFileTransport: AsyncRead [this=%x %s] startPosition=%d readCount=%d",
|
||||||
this, (const char*)mSpec));
|
this, (const char*)mSpec, startPosition, readCount));
|
||||||
|
|
||||||
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
@ -890,11 +890,17 @@ nsFileTransport::Process(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (NS_FAILED(mStatus) || writeAmt == 0) {
|
if (NS_FAILED(mStatus) || writeAmt == 0) {
|
||||||
|
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
||||||
|
("nsFileTransport: READING [this=%x %s] %s writing to buffered output stream",
|
||||||
|
this, (const char*)mSpec, NS_SUCCEEDED(mStatus) ? "done" : "error"));
|
||||||
mState = END_READ;
|
mState = END_READ;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mTransferAmount > 0) {
|
if (mTransferAmount > 0) {
|
||||||
mTransferAmount -= writeAmt;
|
mTransferAmount -= writeAmt;
|
||||||
|
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
||||||
|
("nsFileTransport: READING [this=%x %s] %d bytes left to transfer",
|
||||||
|
this, (const char*)mSpec, mTransferAmount));
|
||||||
}
|
}
|
||||||
PRUint32 offset = mOffset;
|
PRUint32 offset = mOffset;
|
||||||
mOffset += writeAmt;
|
mOffset += writeAmt;
|
||||||
|
@ -903,6 +909,10 @@ nsFileTransport::Process(void)
|
||||||
mBufferInputStream,
|
mBufferInputStream,
|
||||||
offset, writeAmt);
|
offset, writeAmt);
|
||||||
if (NS_FAILED(mStatus)) {
|
if (NS_FAILED(mStatus)) {
|
||||||
|
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
|
||||||
|
("nsFileTransport: READING [this=%x %s] error notifying stream listener",
|
||||||
|
this, (const char*)mSpec));
|
||||||
|
|
||||||
mState = END_READ;
|
mState = END_READ;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче