12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /*
- A directory viewer object. Parses "application/http-index-format"
- per Lou Montulli's original spec:
- http://www.mozilla.org/projects/netlib/dirindexformat.html
- One added change is for a description entry, for when the
- target does not match the filename
- */
- #include "nsDirectoryViewer.h"
- #include "nsArray.h"
- #include "nsArrayUtils.h"
- #include "nsIDirIndex.h"
- #include "nsIDocShell.h"
- #include "jsapi.h"
- #include "nsCOMPtr.h"
- #include "nsEnumeratorUtils.h"
- #include "nsEscape.h"
- #include "nsIRDFService.h"
- #include "nsRDFCID.h"
- #include "rdf.h"
- #include "nsIServiceManager.h"
- #include "nsIXPConnect.h"
- #include "nsEnumeratorUtils.h"
- #include "nsString.h"
- #include "nsXPIDLString.h"
- #include "nsReadableUtils.h"
- #include "nsITextToSubURI.h"
- #include "nsIInterfaceRequestor.h"
- #include "nsIInterfaceRequestorUtils.h"
- #include "nsIFTPChannel.h"
- #include "nsIWindowWatcher.h"
- #include "nsIPrompt.h"
- #include "nsIAuthPrompt.h"
- #include "nsIProgressEventSink.h"
- #include "nsIDOMWindow.h"
- #include "nsIDOMElement.h"
- #include "nsIStreamConverterService.h"
- #include "nsICategoryManager.h"
- #include "nsXPCOMCID.h"
- #include "nsIDocument.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/dom/ScriptSettings.h"
- #include "nsContentUtils.h"
- #include "nsIURI.h"
- #include "nsNetUtil.h"
- using namespace mozilla;
- static const int FORMAT_XUL = 3;
- //----------------------------------------------------------------------
- //
- // Common CIDs
- //
- static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
- // Various protocols we have to special case
- static const char kFTPProtocol[] = "ftp://";
- //----------------------------------------------------------------------
- //
- // nsHTTPIndex
- //
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTTPIndex)
- NS_INTERFACE_MAP_ENTRY(nsIHTTPIndex)
- NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
- NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
- NS_INTERFACE_MAP_ENTRY(nsIDirIndexListener)
- NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
- NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
- NS_INTERFACE_MAP_ENTRY(nsIFTPEventSink)
- NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTTPIndex)
- NS_INTERFACE_MAP_END
- NS_IMPL_CYCLE_COLLECTION(nsHTTPIndex, mInner)
- NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTTPIndex)
- NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTTPIndex)
- NS_IMETHODIMP
- nsHTTPIndex::GetInterface(const nsIID &anIID, void **aResult )
- {
- if (anIID.Equals(NS_GET_IID(nsIFTPEventSink))) {
- // If we don't have a container to store the logged data
- // then don't report ourselves back to the caller
- if (!mRequestor)
- return NS_ERROR_NO_INTERFACE;
- *aResult = static_cast<nsIFTPEventSink*>(this);
- NS_ADDREF(this);
- return NS_OK;
- }
- if (anIID.Equals(NS_GET_IID(nsIPrompt))) {
-
- if (!mRequestor)
- return NS_ERROR_NO_INTERFACE;
- nsCOMPtr<nsPIDOMWindowOuter> aDOMWindow = do_GetInterface(mRequestor);
- if (!aDOMWindow)
- return NS_ERROR_NO_INTERFACE;
- nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
-
- return wwatch->GetNewPrompter(aDOMWindow, (nsIPrompt**)aResult);
- }
- if (anIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
-
- if (!mRequestor)
- return NS_ERROR_NO_INTERFACE;
- nsCOMPtr<nsPIDOMWindowOuter> aDOMWindow = do_GetInterface(mRequestor);
- if (!aDOMWindow)
- return NS_ERROR_NO_INTERFACE;
- nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
-
- return wwatch->GetNewAuthPrompter(aDOMWindow, (nsIAuthPrompt**)aResult);
- }
- if (anIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
- if (!mRequestor)
- return NS_ERROR_NO_INTERFACE;
- nsCOMPtr<nsIProgressEventSink> sink = do_GetInterface(mRequestor);
- if (!sink)
- return NS_ERROR_NO_INTERFACE;
-
- *aResult = sink;
- NS_ADDREF((nsISupports*)*aResult);
- return NS_OK;
- }
- return NS_ERROR_NO_INTERFACE;
- }
- NS_IMETHODIMP
- nsHTTPIndex::OnFTPControlLog(bool server, const char *msg)
- {
- NS_ENSURE_TRUE(mRequestor, NS_OK);
- nsCOMPtr<nsIGlobalObject> globalObject = do_GetInterface(mRequestor);
- NS_ENSURE_TRUE(globalObject, NS_OK);
- // We're going to run script via JS_CallFunctionName, so we need an
- // AutoEntryScript. This is Gecko specific and not in any spec.
- dom::AutoEntryScript aes(globalObject,
- "nsHTTPIndex OnFTPControlLog");
- JSContext* cx = aes.cx();
- JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
- NS_ENSURE_TRUE(global, NS_OK);
- nsString unicodeMsg;
- unicodeMsg.AssignWithConversion(msg);
- JSString* jsMsgStr = JS_NewUCStringCopyZ(cx, unicodeMsg.get());
- NS_ENSURE_TRUE(jsMsgStr, NS_ERROR_OUT_OF_MEMORY);
- JS::AutoValueArray<2> params(cx);
- params[0].setBoolean(server);
- params[1].setString(jsMsgStr);
- JS::Rooted<JS::Value> val(cx);
- JS_CallFunctionName(cx,
- global,
- "OnFTPControlLog",
- params,
- &val);
- return NS_OK;
- }
- NS_IMETHODIMP
- nsHTTPIndex::SetEncoding(const char *encoding)
- {
- mEncoding = encoding;
- return(NS_OK);
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetEncoding(char **encoding)
- {
- NS_PRECONDITION(encoding, "null ptr");
- if (! encoding)
- return(NS_ERROR_NULL_POINTER);
-
- *encoding = ToNewCString(mEncoding);
- if (!*encoding)
- return(NS_ERROR_OUT_OF_MEMORY);
-
- return(NS_OK);
- }
- NS_IMETHODIMP
- nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext)
- {
- nsresult rv;
- mParser = do_CreateInstance(NS_DIRINDEXPARSER_CONTRACTID, &rv);
- if (NS_FAILED(rv)) return rv;
-
- rv = mParser->SetEncoding(mEncoding.get());
- if (NS_FAILED(rv)) return rv;
- rv = mParser->SetListener(this);
- if (NS_FAILED(rv)) return rv;
- rv = mParser->OnStartRequest(request,aContext);
- if (NS_FAILED(rv)) return rv;
- // This should only run once...
- // Unless we don't have a container to start with
- // (ie called from bookmarks as an rdf datasource)
- if (mBindToGlobalObject && mRequestor) {
- mBindToGlobalObject = false;
- nsCOMPtr<nsIGlobalObject> globalObject = do_GetInterface(mRequestor);
- NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE);
- // We might run script via JS_SetProperty, so we need an AutoEntryScript.
- // This is Gecko specific and not in any spec.
- dom::AutoEntryScript aes(globalObject,
- "nsHTTPIndex set HTTPIndex property");
- JSContext* cx = aes.cx();
- JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
- // Using XPConnect, wrap the HTTP index object...
- static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID);
- nsCOMPtr<nsIXPConnect> xpc(do_GetService(kXPConnectCID, &rv));
- if (NS_FAILED(rv)) return rv;
- JS::Rooted<JSObject*> jsobj(cx);
- rv = xpc->WrapNative(cx,
- global,
- static_cast<nsIHTTPIndex*>(this),
- NS_GET_IID(nsIHTTPIndex),
- jsobj.address());
- NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index");
- if (NS_FAILED(rv)) return rv;
- NS_ASSERTION(jsobj,
- "unable to get jsobj from xpconnect wrapper");
- if (!jsobj) return NS_ERROR_UNEXPECTED;
- JS::Rooted<JS::Value> jslistener(cx, JS::ObjectValue(*jsobj));
- // ...and stuff it into the global context
- bool ok = JS_SetProperty(cx, global, "HTTPIndex", jslistener);
- NS_ASSERTION(ok, "unable to set Listener property");
- if (!ok)
- return NS_ERROR_FAILURE;
- }
- if (!aContext) {
- nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
- NS_ASSERTION(channel, "request should be a channel");
- // lets hijack the notifications:
- channel->SetNotificationCallbacks(this);
- // now create the top most resource
- nsCOMPtr<nsIURI> uri;
- channel->GetURI(getter_AddRefs(uri));
- nsAutoCString entryuriC;
- rv = uri->GetSpec(entryuriC);
- if (NS_FAILED(rv)) return rv;
- nsCOMPtr<nsIRDFResource> entry;
- rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry));
- NS_ConvertUTF8toUTF16 uriUnicode(entryuriC);
- nsCOMPtr<nsIRDFLiteral> URLVal;
- rv = mDirRDF->GetLiteral(uriUnicode.get(), getter_AddRefs(URLVal));
- Assert(entry, kNC_URL, URLVal, true);
- mDirectory = do_QueryInterface(entry);
- }
- else
- {
- // Get the directory from the context
- mDirectory = do_QueryInterface(aContext);
- }
- if (!mDirectory) {
- request->Cancel(NS_BINDING_ABORTED);
- return NS_BINDING_ABORTED;
- }
- // Mark the directory as "loading"
- rv = Assert(mDirectory, kNC_Loading,
- kTrueLiteral, true);
- if (NS_FAILED(rv)) return rv;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsHTTPIndex::OnStopRequest(nsIRequest *request,
- nsISupports* aContext,
- nsresult aStatus)
- {
- // If mDirectory isn't set, then we should just bail. Either an
- // error occurred and OnStartRequest() never got called, or
- // something exploded in OnStartRequest().
- if (! mDirectory)
- return NS_BINDING_ABORTED;
- mParser->OnStopRequest(request,aContext,aStatus);
- nsresult rv;
- nsXPIDLCString commentStr;
- mParser->GetComment(getter_Copies(commentStr));
- nsCOMPtr<nsIRDFLiteral> comment;
- rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUTF16(commentStr).get(), getter_AddRefs(comment));
- if (NS_FAILED(rv)) return rv;
- rv = Assert(mDirectory, kNC_Comment, comment, true);
- if (NS_FAILED(rv)) return rv;
- // hack: Remove the 'loading' annotation (ignore errors)
- AddElement(mDirectory, kNC_Loading, kTrueLiteral);
- return NS_OK;
- }
- NS_IMETHODIMP
- nsHTTPIndex::OnDataAvailable(nsIRequest *request,
- nsISupports* aContext,
- nsIInputStream* aStream,
- uint64_t aSourceOffset,
- uint32_t aCount)
- {
- // If mDirectory isn't set, then we should just bail. Either an
- // error occurred and OnStartRequest() never got called, or
- // something exploded in OnStartRequest().
- if (! mDirectory)
- return NS_BINDING_ABORTED;
- return mParser->OnDataAvailable(request, mDirectory, aStream, aSourceOffset, aCount);
- }
- nsresult
- nsHTTPIndex::OnIndexAvailable(nsIRequest* aRequest, nsISupports *aContext,
- nsIDirIndex* aIndex)
- {
- nsCOMPtr<nsIRDFResource> parentRes = do_QueryInterface(aContext);
- if (!parentRes) {
- NS_ERROR("Could not obtain parent resource");
- return(NS_ERROR_UNEXPECTED);
- }
-
- const char* baseStr;
- parentRes->GetValueConst(&baseStr);
- if (! baseStr) {
- NS_ERROR("Could not reconstruct base uri");
- return NS_ERROR_UNEXPECTED;
- }
- // we found the filename; construct a resource for its entry
- nsAutoCString entryuriC(baseStr);
- nsXPIDLCString filename;
- nsresult rv = aIndex->GetLocation(getter_Copies(filename));
- if (NS_FAILED(rv)) return rv;
- entryuriC.Append(filename);
- // if its a directory, make sure it ends with a trailing slash.
- uint32_t type;
- rv = aIndex->GetType(&type);
- if (NS_FAILED(rv))
- return rv;
- bool isDirType = (type == nsIDirIndex::TYPE_DIRECTORY);
- if (isDirType && entryuriC.Last() != '/') {
- entryuriC.Append('/');
- }
- nsCOMPtr<nsIRDFResource> entry;
- rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry));
- // At this point, we'll (hopefully) have found the filename and
- // constructed a resource for it, stored in entry. So now take a
- // second pass through the values and add as statements to the RDF
- // datasource.
- if (entry && NS_SUCCEEDED(rv)) {
- nsCOMPtr<nsIRDFLiteral> lit;
- nsString str;
- str.AssignWithConversion(entryuriC.get());
- rv = mDirRDF->GetLiteral(str.get(), getter_AddRefs(lit));
- if (NS_SUCCEEDED(rv)) {
- rv = Assert(entry, kNC_URL, lit, true);
- if (NS_FAILED(rv)) return rv;
-
- nsXPIDLString xpstr;
- // description
- rv = aIndex->GetDescription(getter_Copies(xpstr));
- if (NS_FAILED(rv)) return rv;
- if (xpstr.Last() == '/')
- xpstr.Truncate(xpstr.Length() - 1);
- rv = mDirRDF->GetLiteral(xpstr.get(), getter_AddRefs(lit));
- if (NS_FAILED(rv)) return rv;
- rv = Assert(entry, kNC_Description, lit, true);
- if (NS_FAILED(rv)) return rv;
-
- // contentlength
- int64_t size;
- rv = aIndex->GetSize(&size);
- if (NS_FAILED(rv)) return rv;
- int64_t minus1 = UINT64_MAX;
- if (size != minus1) {
- int32_t intSize = int32_t(size);
- // XXX RDF should support 64 bit integers (bug 240160)
- nsCOMPtr<nsIRDFInt> val;
- rv = mDirRDF->GetIntLiteral(intSize, getter_AddRefs(val));
- if (NS_FAILED(rv)) return rv;
- rv = Assert(entry, kNC_ContentLength, val, true);
- if (NS_FAILED(rv)) return rv;
- }
- // lastmodified
- PRTime tm;
- rv = aIndex->GetLastModified(&tm);
- if (NS_FAILED(rv)) return rv;
- if (tm != -1) {
- nsCOMPtr<nsIRDFDate> val;
- rv = mDirRDF->GetDateLiteral(tm, getter_AddRefs(val));
- if (NS_FAILED(rv)) return rv;
- rv = Assert(entry, kNC_LastModified, val, true);
- }
- // filetype
- uint32_t type;
- rv = aIndex->GetType(&type);
- switch (type) {
- case nsIDirIndex::TYPE_UNKNOWN:
- rv = mDirRDF->GetLiteral(u"UNKNOWN", getter_AddRefs(lit));
- break;
- case nsIDirIndex::TYPE_DIRECTORY:
- rv = mDirRDF->GetLiteral(u"DIRECTORY", getter_AddRefs(lit));
- break;
- case nsIDirIndex::TYPE_FILE:
- rv = mDirRDF->GetLiteral(u"FILE", getter_AddRefs(lit));
- break;
- case nsIDirIndex::TYPE_SYMLINK:
- rv = mDirRDF->GetLiteral(u"SYMLINK", getter_AddRefs(lit));
- break;
- }
-
- if (NS_FAILED(rv)) return rv;
- rv = Assert(entry, kNC_FileType, lit, true);
- if (NS_FAILED(rv)) return rv;
- }
- // Since the definition of a directory depends on the protocol, we would have
- // to do string comparisons all the time.
- // But we're told if we're a container right here - so save that fact
- if (isDirType)
- Assert(entry, kNC_IsContainer, kTrueLiteral, true);
- else
- Assert(entry, kNC_IsContainer, kFalseLiteral, true);
-
- // instead of
- // rv = Assert(parentRes, kNC_Child, entry, true);
- // if (NS_FAILED(rv)) return rv;
- // defer insertion onto a timer so that the UI isn't starved
- AddElement(parentRes, kNC_Child, entry);
- }
- return rv;
- }
- nsresult
- nsHTTPIndex::OnInformationAvailable(nsIRequest *aRequest,
- nsISupports *aCtxt,
- const nsAString& aInfo) {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- //----------------------------------------------------------------------
- //
- // nsHTTPIndex implementation
- //
- nsHTTPIndex::nsHTTPIndex()
- : mBindToGlobalObject(true),
- mRequestor(nullptr)
- {
- }
- nsHTTPIndex::nsHTTPIndex(nsIInterfaceRequestor* aRequestor)
- : mBindToGlobalObject(true),
- mRequestor(aRequestor)
- {
- }
- nsHTTPIndex::~nsHTTPIndex()
- {
- // note: these are NOT statics due to the native of nsHTTPIndex
- // where it may or may not be treated as a singleton
- if (mTimer)
- {
- // be sure to cancel the timer, as it holds a
- // weak reference back to nsHTTPIndex
- mTimer->Cancel();
- mTimer = nullptr;
- }
- mConnectionList = nullptr;
- mNodeList = nullptr;
-
- if (mDirRDF)
- {
- // UnregisterDataSource() may fail; just ignore errors
- mDirRDF->UnregisterDataSource(this);
- }
- }
- nsresult
- nsHTTPIndex::CommonInit()
- {
- nsresult rv = NS_OK;
- // set initial/default encoding to ISO-8859-1 (not UTF-8)
- mEncoding = "ISO-8859-1";
- mDirRDF = do_GetService(kRDFServiceCID, &rv);
- NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
- if (NS_FAILED(rv)) {
- return(rv);
- }
- mInner = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=in-memory-datasource", &rv);
- if (NS_FAILED(rv))
- return rv;
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"),
- getter_AddRefs(kNC_Child));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "loading"),
- getter_AddRefs(kNC_Loading));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Comment"),
- getter_AddRefs(kNC_Comment));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "URL"),
- getter_AddRefs(kNC_URL));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"),
- getter_AddRefs(kNC_Description));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Length"),
- getter_AddRefs(kNC_ContentLength));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"),
- getter_AddRefs(kNC_LastModified));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Type"),
- getter_AddRefs(kNC_ContentType));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "File-Type"),
- getter_AddRefs(kNC_FileType));
- mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IsContainer"),
- getter_AddRefs(kNC_IsContainer));
- rv = mDirRDF->GetLiteral(u"true", getter_AddRefs(kTrueLiteral));
- if (NS_FAILED(rv)) return(rv);
- rv = mDirRDF->GetLiteral(u"false", getter_AddRefs(kFalseLiteral));
- if (NS_FAILED(rv)) return(rv);
- mConnectionList = nsArray::Create();
- // note: don't register DS here
- return rv;
- }
- nsresult
- nsHTTPIndex::Init()
- {
- nsresult rv;
- // set initial/default encoding to ISO-8859-1 (not UTF-8)
- mEncoding = "ISO-8859-1";
- rv = CommonInit();
- if (NS_FAILED(rv)) return(rv);
- // (do this last) register this as a named data source with the RDF service
- rv = mDirRDF->RegisterDataSource(this, false);
- if (NS_FAILED(rv)) return(rv);
- return(NS_OK);
- }
- nsresult
- nsHTTPIndex::Init(nsIURI* aBaseURL)
- {
- NS_PRECONDITION(aBaseURL != nullptr, "null ptr");
- if (! aBaseURL)
- return NS_ERROR_NULL_POINTER;
- nsresult rv;
- rv = CommonInit();
- if (NS_FAILED(rv)) return(rv);
- // note: don't register DS here (singleton case)
- rv = aBaseURL->GetSpec(mBaseURL);
- if (NS_FAILED(rv)) return rv;
-
- // Mark the base url as a container
- nsCOMPtr<nsIRDFResource> baseRes;
- mDirRDF->GetResource(mBaseURL, getter_AddRefs(baseRes));
- Assert(baseRes, kNC_IsContainer, kTrueLiteral, true);
- return NS_OK;
- }
- nsresult
- nsHTTPIndex::Create(nsIURI* aBaseURL, nsIInterfaceRequestor* aRequestor,
- nsIHTTPIndex** aResult)
- {
- *aResult = nullptr;
- nsHTTPIndex* result = new nsHTTPIndex(aRequestor);
- nsresult rv = result->Init(aBaseURL);
- if (NS_SUCCEEDED(rv))
- {
- NS_ADDREF(result);
- *aResult = result;
- }
- else
- {
- delete result;
- }
- return rv;
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetBaseURL(char** _result)
- {
- *_result = ToNewCString(mBaseURL);
- if (! *_result)
- return NS_ERROR_OUT_OF_MEMORY;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetDataSource(nsIRDFDataSource** _result)
- {
- NS_ADDREF(*_result = this);
- return NS_OK;
- }
- // This function finds the destination when following a given nsIRDFResource
- // If the resource has a URL attribute, we use that. If not, just use
- // the uri.
- //
- // Do NOT try to get the destination of a uri in any other way
- void nsHTTPIndex::GetDestination(nsIRDFResource* r, nsXPIDLCString& dest) {
- // First try the URL attribute
- nsCOMPtr<nsIRDFNode> node;
-
- GetTarget(r, kNC_URL, true, getter_AddRefs(node));
- nsCOMPtr<nsIRDFLiteral> url;
-
- if (node)
- url = do_QueryInterface(node);
- if (!url) {
- const char* temp;
- r->GetValueConst(&temp);
- dest.Adopt(temp ? strdup(temp) : 0);
- } else {
- const char16_t* uri;
- url->GetValueConst(&uri);
- dest.Adopt(ToNewUTF8String(nsDependentString(uri)));
- }
- }
- // rjc: isWellknownContainerURI() decides whether a URI is a container for which,
- // when asked (say, by the template builder), we'll make a network connection
- // to get its contents. For the moment, all we speak is ftp:// URLs, even though
- // a) we can get "http-index" mimetypes for really anything
- // b) we could easily handle file:// URLs here
- // Q: Why don't we?
- // A: The file system datasource ("rdf:file"); at some point, the two
- // should be perhaps united. Until then, we can't aggregate both
- // "rdf:file" and "http-index" (such as with bookmarks) because we'd
- // get double the # of answers we really want... also, "rdf:file" is
- // less expensive in terms of both memory usage as well as speed
- // We use an rdf attribute to mark if this is a container or not.
- // Note that we still have to do string comparisons as a fallback
- // because stuff like the personal toolbar and bookmarks check whether
- // a URL is a container, and we have no attribute in that case.
- bool
- nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r)
- {
- nsCOMPtr<nsIRDFNode> node;
- GetTarget(r, kNC_IsContainer, true, getter_AddRefs(node));
- if (node) {
- bool isContainerFlag;
- if (NS_SUCCEEDED(node->EqualsNode(kTrueLiteral, &isContainerFlag)))
- return isContainerFlag;
- }
- nsXPIDLCString uri;
- GetDestination(r, uri);
- return uri.get() && !strncmp(uri, kFTPProtocol, sizeof(kFTPProtocol) - 1) &&
- (uri.Last() == '/');
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetURI(char * *uri)
- {
- NS_PRECONDITION(uri != nullptr, "null ptr");
- if (! uri)
- return(NS_ERROR_NULL_POINTER);
- if ((*uri = strdup("rdf:httpindex")) == nullptr)
- return(NS_ERROR_OUT_OF_MEMORY);
- return(NS_OK);
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue,
- nsIRDFResource **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- *_retval = nullptr;
- if (mInner)
- {
- rv = mInner->GetSource(aProperty, aTarget, aTruthValue, _retval);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue,
- nsISimpleEnumerator **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->GetSources(aProperty, aTarget, aTruthValue, _retval);
- }
- else
- {
- rv = NS_NewEmptyEnumerator(_retval);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue,
- nsIRDFNode **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- *_retval = nullptr;
- if ((aTruthValue) && (aProperty == kNC_Child) && isWellknownContainerURI(aSource))
- {
- // fake out the generic builder (i.e. return anything in this case)
- // so that search containers never appear to be empty
- NS_IF_ADDREF(aSource);
- *_retval = aSource;
- return(NS_OK);
- }
- if (mInner)
- {
- rv = mInner->GetTarget(aSource, aProperty, aTruthValue, _retval);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue,
- nsISimpleEnumerator **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval);
- }
- else
- {
- rv = NS_NewEmptyEnumerator(_retval);
- }
- if ((aProperty == kNC_Child) && isWellknownContainerURI(aSource))
- {
- bool doNetworkRequest = true;
- if (NS_SUCCEEDED(rv) && (_retval))
- {
- // check and see if we already have data for the search in question;
- // if we do, don't bother doing the search again
- bool hasResults;
- if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) &&
- hasResults)
- doNetworkRequest = false;
- }
- // Note: if we need to do a network request, do it out-of-band
- // (because the XUL template builder isn't re-entrant)
- // by using a global connection list and an immediately-firing timer
- if (doNetworkRequest && mConnectionList)
- {
- uint32_t connectionIndex;
- nsresult idx_rv = mConnectionList->IndexOf(0, aSource, &connectionIndex);
- if (NS_FAILED(idx_rv))
- {
- // add aSource into list of connections to make
- mConnectionList->AppendElement(aSource, /*weak =*/ false);
- // if we don't have a timer about to fire, create one
- // which should fire as soon as possible (out-of-band)
- if (!mTimer)
- {
- mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
- NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
- if (NS_SUCCEEDED(rv))
- {
- mTimer->InitWithFuncCallback(nsHTTPIndex::FireTimer, this, 1,
- nsITimer::TYPE_ONE_SHOT);
- // Note: don't addref "this" as we'll cancel the
- // timer in the httpIndex destructor
- }
- }
- }
- }
- }
- return(rv);
- }
- nsresult
- nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode *child)
- {
- nsresult rv;
- if (!mNodeList)
- {
- mNodeList = nsArray::Create();
- }
- // order required: parent, prop, then child
- mNodeList->AppendElement(parent, /*weak =*/ false);
- mNodeList->AppendElement(prop, /*weak =*/ false);
- mNodeList->AppendElement(child, /*weak = */ false);
- if (!mTimer)
- {
- mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
- NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
- if (NS_FAILED(rv)) return(rv);
- mTimer->InitWithFuncCallback(nsHTTPIndex::FireTimer, this, 1,
- nsITimer::TYPE_ONE_SHOT);
- // Note: don't addref "this" as we'll cancel the
- // timer in the httpIndex destructor
- }
- return(NS_OK);
- }
- void
- nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure)
- {
- nsHTTPIndex *httpIndex = static_cast<nsHTTPIndex *>(aClosure);
- if (!httpIndex)
- return;
- // don't return out of this loop as mTimer may need to be cancelled afterwards
- uint32_t numItems = 0;
- if (httpIndex->mConnectionList)
- {
- httpIndex->mConnectionList->GetLength(&numItems);
- if (numItems > 0)
- {
- nsCOMPtr<nsIRDFResource> source =
- do_QueryElementAt(httpIndex->mConnectionList, 0);
- httpIndex->mConnectionList->RemoveElementAt(0);
- nsXPIDLCString uri;
- if (source) {
- httpIndex->GetDestination(source, uri);
- }
- if (!uri) {
- NS_ERROR("Could not reconstruct uri");
- return;
- }
- nsresult rv = NS_OK;
- nsCOMPtr<nsIURI> url;
- rv = NS_NewURI(getter_AddRefs(url), uri.get());
- nsCOMPtr<nsIChannel> channel;
- if (NS_SUCCEEDED(rv) && (url)) {
- rv = NS_NewChannel(getter_AddRefs(channel),
- url,
- nsContentUtils::GetSystemPrincipal(),
- nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
- nsIContentPolicy::TYPE_OTHER);
- }
- if (NS_SUCCEEDED(rv) && (channel)) {
- channel->SetNotificationCallbacks(httpIndex);
- rv = channel->AsyncOpen2(httpIndex);
- }
- }
- }
- if (httpIndex->mNodeList)
- {
- httpIndex->mNodeList->GetLength(&numItems);
- if (numItems > 0)
- {
- // account for order required: src, prop, then target
- numItems /=3;
- if (numItems > 10)
- numItems = 10;
- int32_t loop;
- for (loop=0; loop<(int32_t)numItems; loop++)
- {
- nsCOMPtr<nsIRDFResource> src = do_QueryElementAt(httpIndex->mNodeList, 0);
- httpIndex->mNodeList->RemoveElementAt(0);
- nsCOMPtr<nsIRDFResource> prop = do_QueryElementAt(httpIndex->mNodeList, 0);
- httpIndex->mNodeList->RemoveElementAt(0);
- nsCOMPtr<nsIRDFNode> target = do_QueryElementAt(httpIndex->mNodeList, 0);
- httpIndex->mNodeList->RemoveElementAt(0);
- if (src && prop && target)
- {
- if (prop.get() == httpIndex->kNC_Loading)
- {
- httpIndex->Unassert(src, prop, target);
- }
- else
- {
- httpIndex->Assert(src, prop, target, true);
- }
- }
- }
- }
- }
- bool refireTimer = false;
- // check both lists to see if the timer needs to continue firing
- if (httpIndex->mConnectionList)
- {
- httpIndex->mConnectionList->GetLength(&numItems);
- if (numItems > 0)
- {
- refireTimer = true;
- }
- else
- {
- httpIndex->mConnectionList->Clear();
- }
- }
- if (httpIndex->mNodeList)
- {
- httpIndex->mNodeList->GetLength(&numItems);
- if (numItems > 0)
- {
- refireTimer = true;
- }
- else
- {
- httpIndex->mNodeList->Clear();
- }
- }
- // be sure to cancel the timer, as it holds a
- // weak reference back to nsHTTPIndex
- httpIndex->mTimer->Cancel();
- httpIndex->mTimer = nullptr;
- // after firing off any/all of the connections be sure
- // to cancel the timer if we don't need to refire it
- if (refireTimer)
- {
- httpIndex->mTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (httpIndex->mTimer)
- {
- httpIndex->mTimer->InitWithFuncCallback(nsHTTPIndex::FireTimer, aClosure, 10,
- nsITimer::TYPE_ONE_SHOT);
- // Note: don't addref "this" as we'll cancel the
- // timer in the httpIndex destructor
- }
- }
- }
- NS_IMETHODIMP
- nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget,
- bool aTruthValue)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->Unassert(aSource, aProperty, aTarget);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty,
- nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource,
- nsIRDFResource *aProperty, nsIRDFNode *aTarget)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty,
- nsIRDFNode *aTarget, bool aTruthValue, bool *_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::AddObserver(nsIRDFObserver *aObserver)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->AddObserver(aObserver);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::RemoveObserver(nsIRDFObserver *aObserver)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->RemoveObserver(aObserver);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
- {
- if (!mInner) {
- *result = false;
- return NS_OK;
- }
- return mInner->HasArcIn(aNode, aArc, result);
- }
- NS_IMETHODIMP
- nsHTTPIndex::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result)
- {
- if (aArc == kNC_Child && isWellknownContainerURI(aSource)) {
- *result = true;
- return NS_OK;
- }
- if (mInner) {
- return mInner->HasArcOut(aSource, aArc, result);
- }
- *result = false;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->ArcLabelsIn(aNode, _retval);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
- {
- *_retval = nullptr;
- nsCOMPtr<nsISimpleEnumerator> child, anonArcs;
- if (isWellknownContainerURI(aSource))
- {
- NS_NewSingletonEnumerator(getter_AddRefs(child), kNC_Child);
- }
- if (mInner)
- {
- mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs));
- }
- return NS_NewUnionEnumerator(_retval, child, anonArcs);
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->GetAllResources(_retval);
- }
- return(rv);
- }
- NS_IMETHODIMP
- nsHTTPIndex::IsCommandEnabled(nsISupports *aSources, nsIRDFResource *aCommand,
- nsISupports *aArguments, bool *_retval)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- nsHTTPIndex::DoCommand(nsISupports *aSources, nsIRDFResource *aCommand,
- nsISupports *aArguments)
- {
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- nsHTTPIndex::BeginUpdateBatch()
- {
- return mInner->BeginUpdateBatch();
- }
- NS_IMETHODIMP
- nsHTTPIndex::EndUpdateBatch()
- {
- return mInner->EndUpdateBatch();
- }
- NS_IMETHODIMP
- nsHTTPIndex::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
- {
- nsresult rv = NS_ERROR_UNEXPECTED;
- if (mInner)
- {
- rv = mInner->GetAllCmds(aSource, _retval);
- }
- return(rv);
- }
- //----------------------------------------------------------------------
- //
- // nsDirectoryViewerFactory
- //
- nsDirectoryViewerFactory::nsDirectoryViewerFactory()
- {
- }
- nsDirectoryViewerFactory::~nsDirectoryViewerFactory()
- {
- }
- NS_IMPL_ISUPPORTS(nsDirectoryViewerFactory, nsIDocumentLoaderFactory)
- NS_IMETHODIMP
- nsDirectoryViewerFactory::CreateInstance(const char *aCommand,
- nsIChannel* aChannel,
- nsILoadGroup* aLoadGroup,
- const nsACString& aContentType,
- nsIDocShell* aContainer,
- nsISupports* aExtraInfo,
- nsIStreamListener** aDocListenerResult,
- nsIContentViewer** aDocViewerResult)
- {
- nsresult rv;
- bool viewSource = FindInReadable(NS_LITERAL_CSTRING("view-source"),
- aContentType);
- if (!viewSource &&
- Preferences::GetInt("network.dir.format", FORMAT_XUL) == FORMAT_XUL) {
- // ... and setup the original channel's content type
- (void)aChannel->SetContentType(NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"));
- // This is where we shunt the HTTP/Index stream into our datasource,
- // and open the directory viewer XUL file as the content stream to
- // load in its place.
-
- // Create a dummy loader that will load a stub XUL document.
- nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
- if (NS_FAILED(rv))
- return rv;
- nsXPIDLCString contractID;
- rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "application/vnd.mozilla.xul+xml",
- getter_Copies(contractID));
- if (NS_FAILED(rv))
- return rv;
- nsCOMPtr<nsIDocumentLoaderFactory> factory(do_GetService(contractID, &rv));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIURI> uri;
- rv = NS_NewURI(getter_AddRefs(uri), "chrome://communicator/content/directory/directory.xul");
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIChannel> channel;
- rv = NS_NewChannel(getter_AddRefs(channel),
- uri,
- nsContentUtils::GetSystemPrincipal(),
- nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
- nsIContentPolicy::TYPE_OTHER,
- aLoadGroup);
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIStreamListener> listener;
- rv = factory->CreateInstance(aCommand, channel, aLoadGroup,
- NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"),
- aContainer, aExtraInfo, getter_AddRefs(listener),
- aDocViewerResult);
- if (NS_FAILED(rv)) return rv;
- rv = channel->AsyncOpen2(listener);
- if (NS_FAILED(rv)) return rv;
-
- // Create an HTTPIndex object so that we can stuff it into the script context
- nsCOMPtr<nsIURI> baseuri;
- rv = aChannel->GetURI(getter_AddRefs(baseuri));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIInterfaceRequestor> requestor = do_QueryInterface(aContainer,&rv);
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIHTTPIndex> httpindex;
- rv = nsHTTPIndex::Create(baseuri, requestor, getter_AddRefs(httpindex));
- if (NS_FAILED(rv)) return rv;
-
- // Now shanghai the stream into our http-index parsing datasource
- // wrapper beastie.
- listener = do_QueryInterface(httpindex,&rv);
- *aDocListenerResult = listener.get();
- NS_ADDREF(*aDocListenerResult);
-
- return NS_OK;
- }
- // setup the original channel's content type
- (void)aChannel->SetContentType(NS_LITERAL_CSTRING("text/html"));
- // Otherwise, lets use the html listing
- nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
- if (NS_FAILED(rv))
- return rv;
- nsXPIDLCString contractID;
- rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html",
- getter_Copies(contractID));
- if (NS_FAILED(rv))
- return rv;
- nsCOMPtr<nsIDocumentLoaderFactory> factory(do_GetService(contractID, &rv));
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIStreamListener> listener;
- if (viewSource) {
- rv = factory->CreateInstance("view-source", aChannel, aLoadGroup,
- NS_LITERAL_CSTRING("text/html; x-view-type=view-source"),
- aContainer, aExtraInfo, getter_AddRefs(listener),
- aDocViewerResult);
- } else {
- rv = factory->CreateInstance("view", aChannel, aLoadGroup,
- NS_LITERAL_CSTRING("text/html"),
- aContainer, aExtraInfo, getter_AddRefs(listener),
- aDocViewerResult);
- }
- if (NS_FAILED(rv)) return rv;
- nsCOMPtr<nsIStreamConverterService> scs = do_GetService("@mozilla.org/streamConverters;1", &rv);
- if (NS_FAILED(rv)) return rv;
- rv = scs->AsyncConvertData("application/http-index-format",
- "text/html",
- listener,
- nullptr,
- aDocListenerResult);
- if (NS_FAILED(rv)) return rv;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsDirectoryViewerFactory::CreateInstanceForDocument(nsISupports* aContainer,
- nsIDocument* aDocument,
- const char *aCommand,
- nsIContentViewer** aDocViewerResult)
- {
- NS_NOTYETIMPLEMENTED("didn't expect to get here");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- NS_IMETHODIMP
- nsDirectoryViewerFactory::CreateBlankDocument(nsILoadGroup *aLoadGroup,
- nsIPrincipal *aPrincipal,
- nsIDocument **_retval) {
- NS_NOTYETIMPLEMENTED("didn't expect to get here");
- return NS_ERROR_NOT_IMPLEMENTED;
- }
|