LCOV - code coverage report
Current view: top level - xpfe/components/directory - nsDirectoryViewer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 616 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 60 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /*
       7             : 
       8             :   A directory viewer object. Parses "application/http-index-format"
       9             :   per Lou Montulli's original spec:
      10             : 
      11             :   http://www.mozilla.org/projects/netlib/dirindexformat.html
      12             : 
      13             :   One added change is for a description entry, for when the
      14             :   target does not match the filename
      15             : 
      16             : */
      17             : 
      18             : #include "nsDirectoryViewer.h"
      19             : #include "nsArray.h"
      20             : #include "nsArrayUtils.h"
      21             : #include "nsIDirIndex.h"
      22             : #include "nsIDocShell.h"
      23             : #include "jsapi.h"
      24             : #include "nsCOMPtr.h"
      25             : #include "nsEnumeratorUtils.h"
      26             : #include "nsEscape.h"
      27             : #include "nsIRDFService.h"
      28             : #include "nsRDFCID.h"
      29             : #include "rdf.h"
      30             : #include "nsIServiceManager.h"
      31             : #include "nsIXPConnect.h"
      32             : #include "nsEnumeratorUtils.h"
      33             : #include "nsString.h"
      34             : #include "nsXPIDLString.h"
      35             : #include "nsReadableUtils.h"
      36             : #include "nsITextToSubURI.h"
      37             : #include "nsIInterfaceRequestor.h"
      38             : #include "nsIInterfaceRequestorUtils.h"
      39             : #include "nsIFTPChannel.h"
      40             : #include "nsIWindowWatcher.h"
      41             : #include "nsIPrompt.h"
      42             : #include "nsIAuthPrompt.h"
      43             : #include "nsIProgressEventSink.h"
      44             : #include "nsIDOMWindow.h"
      45             : #include "nsIDOMElement.h"
      46             : #include "nsIStreamConverterService.h"
      47             : #include "nsICategoryManager.h"
      48             : #include "nsXPCOMCID.h"
      49             : #include "nsIDocument.h"
      50             : #include "mozilla/Preferences.h"
      51             : #include "mozilla/dom/ScriptSettings.h"
      52             : #include "nsContentUtils.h"
      53             : #include "nsIURI.h"
      54             : #include "nsNetUtil.h"
      55             : 
      56             : using namespace mozilla;
      57             : 
      58             : static const int FORMAT_XUL = 3;
      59             : 
      60             : //----------------------------------------------------------------------
      61             : //
      62             : // Common CIDs
      63             : //
      64             : 
      65             : static NS_DEFINE_CID(kRDFServiceCID,             NS_RDFSERVICE_CID);
      66             : 
      67             : // Various protocols we have to special case
      68             : static const char               kFTPProtocol[] = "ftp://";
      69             : 
      70             : //----------------------------------------------------------------------
      71             : //
      72             : // nsHTTPIndex
      73             : //
      74             : 
      75           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTTPIndex)
      76           0 :     NS_INTERFACE_MAP_ENTRY(nsIHTTPIndex)
      77           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
      78           0 :     NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
      79           0 :     NS_INTERFACE_MAP_ENTRY(nsIDirIndexListener)
      80           0 :     NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
      81           0 :     NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
      82           0 :     NS_INTERFACE_MAP_ENTRY(nsIFTPEventSink)
      83           0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTTPIndex)
      84           0 : NS_INTERFACE_MAP_END
      85             : 
      86           0 : NS_IMPL_CYCLE_COLLECTION(nsHTTPIndex, mInner)
      87           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHTTPIndex)
      88           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHTTPIndex)
      89             : 
      90             : NS_IMETHODIMP
      91           0 : nsHTTPIndex::GetInterface(const nsIID &anIID, void **aResult )
      92             : {
      93           0 :     if (anIID.Equals(NS_GET_IID(nsIFTPEventSink))) {
      94             :         // If we don't have a container to store the logged data
      95             :         // then don't report ourselves back to the caller
      96             : 
      97           0 :         if (!mRequestor)
      98           0 :           return NS_ERROR_NO_INTERFACE;
      99           0 :         *aResult = static_cast<nsIFTPEventSink*>(this);
     100           0 :         NS_ADDREF(this);
     101           0 :         return NS_OK;
     102             :     }
     103             : 
     104           0 :     if (anIID.Equals(NS_GET_IID(nsIPrompt))) {
     105             : 
     106           0 :         if (!mRequestor)
     107           0 :             return NS_ERROR_NO_INTERFACE;
     108             : 
     109           0 :         nsCOMPtr<nsPIDOMWindowOuter> aDOMWindow = do_GetInterface(mRequestor);
     110           0 :         if (!aDOMWindow)
     111           0 :             return NS_ERROR_NO_INTERFACE;
     112             : 
     113           0 :         nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     114             : 
     115           0 :         return wwatch->GetNewPrompter(aDOMWindow, (nsIPrompt**)aResult);
     116             :     }
     117             : 
     118           0 :     if (anIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
     119             : 
     120           0 :         if (!mRequestor)
     121           0 :             return NS_ERROR_NO_INTERFACE;
     122             : 
     123           0 :         nsCOMPtr<nsPIDOMWindowOuter> aDOMWindow = do_GetInterface(mRequestor);
     124           0 :         if (!aDOMWindow)
     125           0 :             return NS_ERROR_NO_INTERFACE;
     126             : 
     127           0 :         nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     128             : 
     129           0 :         return wwatch->GetNewAuthPrompter(aDOMWindow, (nsIAuthPrompt**)aResult);
     130             :     }
     131             : 
     132           0 :     if (anIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
     133             : 
     134           0 :         if (!mRequestor)
     135           0 :             return NS_ERROR_NO_INTERFACE;
     136             : 
     137           0 :         nsCOMPtr<nsIProgressEventSink> sink = do_GetInterface(mRequestor);
     138           0 :         if (!sink)
     139           0 :             return NS_ERROR_NO_INTERFACE;
     140             : 
     141           0 :         *aResult = sink;
     142           0 :         NS_ADDREF((nsISupports*)*aResult);
     143           0 :         return NS_OK;
     144             :     }
     145             : 
     146           0 :     return NS_ERROR_NO_INTERFACE;
     147             : }
     148             : 
     149             : NS_IMETHODIMP
     150           0 : nsHTTPIndex::OnFTPControlLog(bool server, const char *msg)
     151             : {
     152           0 :     NS_ENSURE_TRUE(mRequestor, NS_OK);
     153             : 
     154           0 :     nsCOMPtr<nsIGlobalObject> globalObject = do_GetInterface(mRequestor);
     155           0 :     NS_ENSURE_TRUE(globalObject, NS_OK);
     156             : 
     157             :     // We're going to run script via JS_CallFunctionName, so we need an
     158             :     // AutoEntryScript. This is Gecko specific and not in any spec.
     159             :     dom::AutoEntryScript aes(globalObject,
     160           0 :                              "nsHTTPIndex OnFTPControlLog");
     161           0 :     JSContext* cx = aes.cx();
     162             : 
     163           0 :     JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
     164           0 :     NS_ENSURE_TRUE(global, NS_OK);
     165             : 
     166           0 :     nsString unicodeMsg;
     167           0 :     unicodeMsg.AssignWithConversion(msg);
     168           0 :     JSString* jsMsgStr = JS_NewUCStringCopyZ(cx, unicodeMsg.get());
     169           0 :     NS_ENSURE_TRUE(jsMsgStr, NS_ERROR_OUT_OF_MEMORY);
     170             : 
     171           0 :     JS::AutoValueArray<2> params(cx);
     172           0 :     params[0].setBoolean(server);
     173           0 :     params[1].setString(jsMsgStr);
     174             : 
     175           0 :     JS::Rooted<JS::Value> val(cx);
     176           0 :     JS_CallFunctionName(cx,
     177             :                         global,
     178             :                         "OnFTPControlLog",
     179             :                         params,
     180           0 :                         &val);
     181           0 :     return NS_OK;
     182             : }
     183             : 
     184             : NS_IMETHODIMP
     185           0 : nsHTTPIndex::SetEncoding(const char *encoding)
     186             : {
     187           0 :     mEncoding = encoding;
     188           0 :     return(NS_OK);
     189             : }
     190             : 
     191             : NS_IMETHODIMP
     192           0 : nsHTTPIndex::GetEncoding(char **encoding)
     193             : {
     194           0 :   NS_PRECONDITION(encoding, "null ptr");
     195           0 :   if (! encoding)
     196           0 :     return(NS_ERROR_NULL_POINTER);
     197             : 
     198           0 :   *encoding = ToNewCString(mEncoding);
     199           0 :   if (!*encoding)
     200           0 :     return(NS_ERROR_OUT_OF_MEMORY);
     201             : 
     202           0 :   return(NS_OK);
     203             : }
     204             : 
     205             : NS_IMETHODIMP
     206           0 : nsHTTPIndex::OnStartRequest(nsIRequest *request, nsISupports* aContext)
     207             : {
     208             :   nsresult rv;
     209             : 
     210           0 :   mParser = do_CreateInstance(NS_DIRINDEXPARSER_CONTRACTID, &rv);
     211           0 :   if (NS_FAILED(rv)) return rv;
     212             : 
     213           0 :   rv = mParser->SetEncoding(mEncoding.get());
     214           0 :   if (NS_FAILED(rv)) return rv;
     215             : 
     216           0 :   rv = mParser->SetListener(this);
     217           0 :   if (NS_FAILED(rv)) return rv;
     218             : 
     219           0 :   rv = mParser->OnStartRequest(request,aContext);
     220           0 :   if (NS_FAILED(rv)) return rv;
     221             : 
     222             :   // This should only run once...
     223             :   // Unless we don't have a container to start with
     224             :   // (ie called from bookmarks as an rdf datasource)
     225           0 :   if (mBindToGlobalObject && mRequestor) {
     226           0 :     mBindToGlobalObject = false;
     227             : 
     228           0 :     nsCOMPtr<nsIGlobalObject> globalObject = do_GetInterface(mRequestor);
     229           0 :     NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE);
     230             : 
     231             :     // We might run script via JS_SetProperty, so we need an AutoEntryScript.
     232             :     // This is Gecko specific and not in any spec.
     233             :     dom::AutoEntryScript aes(globalObject,
     234           0 :                              "nsHTTPIndex set HTTPIndex property");
     235           0 :     JSContext* cx = aes.cx();
     236             : 
     237           0 :     JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
     238             : 
     239             :     // Using XPConnect, wrap the HTTP index object...
     240             :     static NS_DEFINE_CID(kXPConnectCID, NS_XPCONNECT_CID);
     241           0 :     nsCOMPtr<nsIXPConnect> xpc(do_GetService(kXPConnectCID, &rv));
     242           0 :     if (NS_FAILED(rv)) return rv;
     243             : 
     244           0 :     JS::Rooted<JSObject*> jsobj(cx);
     245           0 :     rv = xpc->WrapNative(cx,
     246             :                          global,
     247             :                          static_cast<nsIHTTPIndex*>(this),
     248             :                          NS_GET_IID(nsIHTTPIndex),
     249           0 :                          jsobj.address());
     250             : 
     251           0 :     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to xpconnect-wrap http-index");
     252           0 :     if (NS_FAILED(rv)) return rv;
     253             : 
     254           0 :     NS_ASSERTION(jsobj,
     255             :                  "unable to get jsobj from xpconnect wrapper");
     256           0 :     if (!jsobj) return NS_ERROR_UNEXPECTED;
     257             : 
     258           0 :     JS::Rooted<JS::Value> jslistener(cx, JS::ObjectValue(*jsobj));
     259             : 
     260             :     // ...and stuff it into the global context
     261           0 :     bool ok = JS_SetProperty(cx, global, "HTTPIndex", jslistener);
     262           0 :     NS_ASSERTION(ok, "unable to set Listener property");
     263           0 :     if (!ok)
     264           0 :       return NS_ERROR_FAILURE;
     265             :   }
     266             : 
     267           0 :   if (!aContext) {
     268           0 :     nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
     269           0 :     NS_ASSERTION(channel, "request should be a channel");
     270             : 
     271             :     // lets hijack the notifications:
     272           0 :     channel->SetNotificationCallbacks(this);
     273             : 
     274             :     // now create the top most resource
     275           0 :     nsCOMPtr<nsIURI> uri;
     276           0 :     channel->GetURI(getter_AddRefs(uri));
     277             : 
     278           0 :     nsAutoCString entryuriC;
     279           0 :     rv = uri->GetSpec(entryuriC);
     280           0 :     if (NS_FAILED(rv)) return rv;
     281             : 
     282           0 :     nsCOMPtr<nsIRDFResource> entry;
     283           0 :     rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry));
     284             : 
     285           0 :     NS_ConvertUTF8toUTF16 uriUnicode(entryuriC);
     286             : 
     287           0 :     nsCOMPtr<nsIRDFLiteral> URLVal;
     288           0 :     rv = mDirRDF->GetLiteral(uriUnicode.get(), getter_AddRefs(URLVal));
     289             : 
     290           0 :     Assert(entry, kNC_URL, URLVal, true);
     291           0 :     mDirectory = do_QueryInterface(entry);
     292             :   }
     293             :   else
     294             :   {
     295             :     // Get the directory from the context
     296           0 :     mDirectory = do_QueryInterface(aContext);
     297             :   }
     298             : 
     299           0 :   if (!mDirectory) {
     300           0 :       request->Cancel(NS_BINDING_ABORTED);
     301           0 :       return NS_BINDING_ABORTED;
     302             :   }
     303             : 
     304             :   // Mark the directory as "loading"
     305           0 :   rv = Assert(mDirectory, kNC_Loading,
     306           0 :                            kTrueLiteral, true);
     307           0 :   if (NS_FAILED(rv)) return rv;
     308             : 
     309           0 :   return NS_OK;
     310             : }
     311             : 
     312             : 
     313             : NS_IMETHODIMP
     314           0 : nsHTTPIndex::OnStopRequest(nsIRequest *request,
     315             :                            nsISupports* aContext,
     316             :                            nsresult aStatus)
     317             : {
     318             :   // If mDirectory isn't set, then we should just bail. Either an
     319             :   // error occurred and OnStartRequest() never got called, or
     320             :   // something exploded in OnStartRequest().
     321           0 :   if (! mDirectory)
     322           0 :     return NS_BINDING_ABORTED;
     323             : 
     324           0 :   mParser->OnStopRequest(request,aContext,aStatus);
     325             : 
     326             :   nsresult rv;
     327             : 
     328           0 :   nsXPIDLCString commentStr;
     329           0 :   mParser->GetComment(getter_Copies(commentStr));
     330             : 
     331           0 :   nsCOMPtr<nsIRDFLiteral> comment;
     332           0 :   rv = mDirRDF->GetLiteral(NS_ConvertASCIItoUTF16(commentStr).get(), getter_AddRefs(comment));
     333           0 :   if (NS_FAILED(rv)) return rv;
     334             : 
     335           0 :   rv = Assert(mDirectory, kNC_Comment, comment, true);
     336           0 :   if (NS_FAILED(rv)) return rv;
     337             : 
     338             :   // hack: Remove the 'loading' annotation (ignore errors)
     339           0 :   AddElement(mDirectory, kNC_Loading, kTrueLiteral);
     340             : 
     341           0 :   return NS_OK;
     342             : }
     343             : 
     344             : 
     345             : NS_IMETHODIMP
     346           0 : nsHTTPIndex::OnDataAvailable(nsIRequest *request,
     347             :                              nsISupports* aContext,
     348             :                              nsIInputStream* aStream,
     349             :                              uint64_t aSourceOffset,
     350             :                              uint32_t aCount)
     351             : {
     352             :   // If mDirectory isn't set, then we should just bail. Either an
     353             :   // error occurred and OnStartRequest() never got called, or
     354             :   // something exploded in OnStartRequest().
     355           0 :   if (! mDirectory)
     356           0 :     return NS_BINDING_ABORTED;
     357             : 
     358           0 :   return mParser->OnDataAvailable(request, mDirectory, aStream, aSourceOffset, aCount);
     359             : }
     360             : 
     361             : 
     362             : nsresult
     363           0 : nsHTTPIndex::OnIndexAvailable(nsIRequest* aRequest, nsISupports *aContext,
     364             :                               nsIDirIndex* aIndex)
     365             : {
     366           0 :   nsCOMPtr<nsIRDFResource>        parentRes = do_QueryInterface(aContext);
     367           0 :   if (!parentRes) {
     368           0 :     NS_ERROR("Could not obtain parent resource");
     369           0 :     return(NS_ERROR_UNEXPECTED);
     370             :   }
     371             : 
     372             :   const char* baseStr;
     373           0 :   parentRes->GetValueConst(&baseStr);
     374           0 :   if (! baseStr) {
     375           0 :     NS_ERROR("Could not reconstruct base uri");
     376           0 :     return NS_ERROR_UNEXPECTED;
     377             :   }
     378             : 
     379             :   // we found the filename; construct a resource for its entry
     380           0 :   nsAutoCString entryuriC(baseStr);
     381             : 
     382           0 :   nsXPIDLCString filename;
     383           0 :   nsresult rv = aIndex->GetLocation(getter_Copies(filename));
     384           0 :   if (NS_FAILED(rv)) return rv;
     385           0 :   entryuriC.Append(filename);
     386             : 
     387             :   // if its a directory, make sure it ends with a trailing slash.
     388             :   uint32_t type;
     389           0 :   rv = aIndex->GetType(&type);
     390           0 :   if (NS_FAILED(rv))
     391           0 :     return rv;
     392             : 
     393           0 :   bool isDirType = (type == nsIDirIndex::TYPE_DIRECTORY);
     394           0 :   if (isDirType && entryuriC.Last() != '/') {
     395           0 :       entryuriC.Append('/');
     396             :   }
     397             : 
     398           0 :   nsCOMPtr<nsIRDFResource> entry;
     399           0 :   rv = mDirRDF->GetResource(entryuriC, getter_AddRefs(entry));
     400             : 
     401             :   // At this point, we'll (hopefully) have found the filename and
     402             :   // constructed a resource for it, stored in entry. So now take a
     403             :   // second pass through the values and add as statements to the RDF
     404             :   // datasource.
     405             : 
     406           0 :   if (entry && NS_SUCCEEDED(rv)) {
     407           0 :     nsCOMPtr<nsIRDFLiteral> lit;
     408           0 :     nsString str;
     409             : 
     410           0 :     str.AssignWithConversion(entryuriC.get());
     411             : 
     412           0 :     rv = mDirRDF->GetLiteral(str.get(), getter_AddRefs(lit));
     413             : 
     414           0 :     if (NS_SUCCEEDED(rv)) {
     415           0 :       rv = Assert(entry, kNC_URL, lit, true);
     416           0 :       if (NS_FAILED(rv)) return rv;
     417             : 
     418           0 :       nsXPIDLString xpstr;
     419             : 
     420             :       // description
     421           0 :       rv = aIndex->GetDescription(getter_Copies(xpstr));
     422           0 :       if (NS_FAILED(rv)) return rv;
     423           0 :       if (xpstr.Last() == '/')
     424           0 :         xpstr.Truncate(xpstr.Length() - 1);
     425             : 
     426           0 :       rv = mDirRDF->GetLiteral(xpstr.get(), getter_AddRefs(lit));
     427           0 :       if (NS_FAILED(rv)) return rv;
     428           0 :       rv = Assert(entry, kNC_Description, lit, true);
     429           0 :       if (NS_FAILED(rv)) return rv;
     430             : 
     431             :       // contentlength
     432             :       int64_t size;
     433           0 :       rv = aIndex->GetSize(&size);
     434           0 :       if (NS_FAILED(rv)) return rv;
     435           0 :       int64_t minus1 = UINT64_MAX;
     436           0 :       if (size != minus1) {
     437           0 :         int32_t intSize = int32_t(size);
     438             :         // XXX RDF should support 64 bit integers (bug 240160)
     439           0 :         nsCOMPtr<nsIRDFInt> val;
     440           0 :         rv = mDirRDF->GetIntLiteral(intSize, getter_AddRefs(val));
     441           0 :         if (NS_FAILED(rv)) return rv;
     442           0 :         rv = Assert(entry, kNC_ContentLength, val, true);
     443           0 :         if (NS_FAILED(rv)) return rv;
     444             :       }
     445             : 
     446             :       // lastmodified
     447             :       PRTime tm;
     448           0 :       rv = aIndex->GetLastModified(&tm);
     449           0 :       if (NS_FAILED(rv)) return rv;
     450           0 :       if (tm != -1) {
     451           0 :         nsCOMPtr<nsIRDFDate> val;
     452           0 :         rv = mDirRDF->GetDateLiteral(tm, getter_AddRefs(val));
     453           0 :         if (NS_FAILED(rv)) return rv;
     454           0 :         rv = Assert(entry, kNC_LastModified, val, true);
     455             :       }
     456             : 
     457             :       // filetype
     458             :       uint32_t type;
     459           0 :       rv = aIndex->GetType(&type);
     460           0 :       switch (type) {
     461             :       case nsIDirIndex::TYPE_UNKNOWN:
     462           0 :         rv = mDirRDF->GetLiteral(u"UNKNOWN", getter_AddRefs(lit));
     463           0 :         break;
     464             :       case nsIDirIndex::TYPE_DIRECTORY:
     465           0 :         rv = mDirRDF->GetLiteral(u"DIRECTORY", getter_AddRefs(lit));
     466           0 :         break;
     467             :       case nsIDirIndex::TYPE_FILE:
     468           0 :         rv = mDirRDF->GetLiteral(u"FILE", getter_AddRefs(lit));
     469           0 :         break;
     470             :       case nsIDirIndex::TYPE_SYMLINK:
     471           0 :         rv = mDirRDF->GetLiteral(u"SYMLINK", getter_AddRefs(lit));
     472           0 :         break;
     473             :       }
     474             : 
     475           0 :       if (NS_FAILED(rv)) return rv;
     476           0 :       rv = Assert(entry, kNC_FileType, lit, true);
     477           0 :       if (NS_FAILED(rv)) return rv;
     478             :     }
     479             : 
     480             :     // Since the definition of a directory depends on the protocol, we would have
     481             :     // to do string comparisons all the time.
     482             :     // But we're told if we're a container right here - so save that fact
     483           0 :     if (isDirType)
     484           0 :       Assert(entry, kNC_IsContainer, kTrueLiteral, true);
     485             :     else
     486           0 :       Assert(entry, kNC_IsContainer, kFalseLiteral, true);
     487             : 
     488             : //   instead of
     489             : //       rv = Assert(parentRes, kNC_Child, entry, true);
     490             : //       if (NS_FAILED(rv)) return rv;
     491             : //   defer insertion onto a timer so that the UI isn't starved
     492           0 :     AddElement(parentRes, kNC_Child, entry);
     493             :   }
     494             : 
     495           0 :   return rv;
     496             : }
     497             : 
     498             : nsresult
     499           0 : nsHTTPIndex::OnInformationAvailable(nsIRequest *aRequest,
     500             :                                   nsISupports *aCtxt,
     501             :                                   const nsAString& aInfo) {
     502           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     503             : }
     504             : 
     505             : //----------------------------------------------------------------------
     506             : //
     507             : // nsHTTPIndex implementation
     508             : //
     509             : 
     510           0 : nsHTTPIndex::nsHTTPIndex()
     511             :   : mBindToGlobalObject(true),
     512           0 :     mRequestor(nullptr)
     513             : {
     514           0 : }
     515             : 
     516             : 
     517           0 : nsHTTPIndex::nsHTTPIndex(nsIInterfaceRequestor* aRequestor)
     518             :   : mBindToGlobalObject(true),
     519           0 :     mRequestor(aRequestor)
     520             : {
     521           0 : }
     522             : 
     523             : 
     524           0 : nsHTTPIndex::~nsHTTPIndex()
     525             : {
     526             :   // note: these are NOT statics due to the native of nsHTTPIndex
     527             :   // where it may or may not be treated as a singleton
     528             : 
     529           0 :     if (mTimer)
     530             :     {
     531             :         // be sure to cancel the timer, as it holds a
     532             :         // weak reference back to nsHTTPIndex
     533           0 :         mTimer->Cancel();
     534           0 :         mTimer = nullptr;
     535             :     }
     536             : 
     537           0 :     mConnectionList = nullptr;
     538           0 :     mNodeList = nullptr;
     539             : 
     540           0 :     if (mDirRDF)
     541             :       {
     542             :         // UnregisterDataSource() may fail; just ignore errors
     543           0 :         mDirRDF->UnregisterDataSource(this);
     544             :       }
     545           0 : }
     546             : 
     547             : 
     548             : 
     549             : nsresult
     550           0 : nsHTTPIndex::CommonInit()
     551             : {
     552           0 :     nsresult    rv = NS_OK;
     553             : 
     554             :     // set initial/default encoding to windows-1252 (not UTF-8)
     555           0 :     mEncoding = "windows-1252";
     556             : 
     557           0 :     mDirRDF = do_GetService(kRDFServiceCID, &rv);
     558           0 :     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
     559           0 :     if (NS_FAILED(rv)) {
     560           0 :       return(rv);
     561             :     }
     562             : 
     563           0 :     mInner = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=in-memory-datasource", &rv);
     564             : 
     565           0 :     if (NS_FAILED(rv))
     566           0 :       return rv;
     567             : 
     568           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"),
     569           0 :                          getter_AddRefs(kNC_Child));
     570           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "loading"),
     571           0 :                          getter_AddRefs(kNC_Loading));
     572           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Comment"),
     573           0 :                          getter_AddRefs(kNC_Comment));
     574           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "URL"),
     575           0 :                          getter_AddRefs(kNC_URL));
     576           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"),
     577           0 :                          getter_AddRefs(kNC_Description));
     578           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Length"),
     579           0 :                          getter_AddRefs(kNC_ContentLength));
     580           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"),
     581           0 :                          getter_AddRefs(kNC_LastModified));
     582           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Type"),
     583           0 :                          getter_AddRefs(kNC_ContentType));
     584           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "File-Type"),
     585           0 :                          getter_AddRefs(kNC_FileType));
     586           0 :     mDirRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IsContainer"),
     587           0 :                          getter_AddRefs(kNC_IsContainer));
     588             : 
     589           0 :     rv = mDirRDF->GetLiteral(u"true", getter_AddRefs(kTrueLiteral));
     590           0 :     if (NS_FAILED(rv)) return(rv);
     591           0 :     rv = mDirRDF->GetLiteral(u"false", getter_AddRefs(kFalseLiteral));
     592           0 :     if (NS_FAILED(rv)) return(rv);
     593             : 
     594           0 :     mConnectionList = nsArray::Create();
     595             : 
     596             :     // note: don't register DS here
     597           0 :     return rv;
     598             : }
     599             : 
     600             : 
     601             : nsresult
     602           0 : nsHTTPIndex::Init()
     603             : {
     604             :         nsresult        rv;
     605             : 
     606             :         // set initial/default encoding to windows-1252 (not UTF-8)
     607           0 :         mEncoding = "windows-1252";
     608             : 
     609           0 :         rv = CommonInit();
     610           0 :         if (NS_FAILED(rv))      return(rv);
     611             : 
     612             :         // (do this last) register this as a named data source with the RDF service
     613           0 :         rv = mDirRDF->RegisterDataSource(this, false);
     614           0 :         if (NS_FAILED(rv)) return(rv);
     615             : 
     616           0 :         return(NS_OK);
     617             : }
     618             : 
     619             : 
     620             : 
     621             : nsresult
     622           0 : nsHTTPIndex::Init(nsIURI* aBaseURL)
     623             : {
     624           0 :   NS_PRECONDITION(aBaseURL != nullptr, "null ptr");
     625           0 :   if (! aBaseURL)
     626           0 :     return NS_ERROR_NULL_POINTER;
     627             : 
     628             :   nsresult rv;
     629             : 
     630           0 :   rv = CommonInit();
     631           0 :   if (NS_FAILED(rv))    return(rv);
     632             : 
     633             :   // note: don't register DS here (singleton case)
     634             : 
     635           0 :   rv = aBaseURL->GetSpec(mBaseURL);
     636           0 :   if (NS_FAILED(rv)) return rv;
     637             : 
     638             :   // Mark the base url as a container
     639           0 :   nsCOMPtr<nsIRDFResource> baseRes;
     640           0 :   mDirRDF->GetResource(mBaseURL, getter_AddRefs(baseRes));
     641           0 :   Assert(baseRes, kNC_IsContainer, kTrueLiteral, true);
     642             : 
     643           0 :   return NS_OK;
     644             : }
     645             : 
     646             : 
     647             : 
     648             : nsresult
     649           0 : nsHTTPIndex::Create(nsIURI* aBaseURL, nsIInterfaceRequestor* aRequestor,
     650             :                     nsIHTTPIndex** aResult)
     651             : {
     652           0 :   *aResult = nullptr;
     653             : 
     654           0 :   nsHTTPIndex* result = new nsHTTPIndex(aRequestor);
     655           0 :   nsresult rv = result->Init(aBaseURL);
     656           0 :   if (NS_SUCCEEDED(rv))
     657             :   {
     658           0 :     NS_ADDREF(result);
     659           0 :     *aResult = result;
     660             :   }
     661             :   else
     662             :   {
     663           0 :     delete result;
     664             :   }
     665           0 :   return rv;
     666             : }
     667             : 
     668             : NS_IMETHODIMP
     669           0 : nsHTTPIndex::GetBaseURL(char** _result)
     670             : {
     671           0 :   *_result = ToNewCString(mBaseURL);
     672           0 :   if (! *_result)
     673           0 :     return NS_ERROR_OUT_OF_MEMORY;
     674             : 
     675           0 :   return NS_OK;
     676             : }
     677             : 
     678             : NS_IMETHODIMP
     679           0 : nsHTTPIndex::GetDataSource(nsIRDFDataSource** _result)
     680             : {
     681           0 :   NS_ADDREF(*_result = this);
     682           0 :   return NS_OK;
     683             : }
     684             : 
     685             : // This function finds the destination when following a given nsIRDFResource
     686             : // If the resource has a URL attribute, we use that. If not, just use
     687             : // the uri.
     688             : //
     689             : // Do NOT try to get the destination of a uri in any other way
     690           0 : void nsHTTPIndex::GetDestination(nsIRDFResource* r, nsXPIDLCString& dest) {
     691             :   // First try the URL attribute
     692           0 :   nsCOMPtr<nsIRDFNode> node;
     693             : 
     694           0 :   GetTarget(r, kNC_URL, true, getter_AddRefs(node));
     695           0 :   nsCOMPtr<nsIRDFLiteral> url;
     696             : 
     697           0 :   if (node)
     698           0 :     url = do_QueryInterface(node);
     699             : 
     700           0 :   if (!url) {
     701             :      const char* temp;
     702           0 :      r->GetValueConst(&temp);
     703           0 :      dest.Adopt(temp ? strdup(temp) : 0);
     704             :   } else {
     705             :     const char16_t* uri;
     706           0 :     url->GetValueConst(&uri);
     707           0 :     dest.Adopt(ToNewUTF8String(nsDependentString(uri)));
     708             :   }
     709           0 : }
     710             : 
     711             : // rjc: isWellknownContainerURI() decides whether a URI is a container for which,
     712             : // when asked (say, by the template builder), we'll make a network connection
     713             : // to get its contents. For the moment, all we speak is ftp:// URLs, even though
     714             : //    a) we can get "http-index" mimetypes for really anything
     715             : //    b) we could easily handle file:// URLs here
     716             : //         Q: Why don't we?
     717             : //         A: The file system datasource ("rdf:file"); at some point, the two
     718             : //            should be perhaps united.  Until then, we can't aggregate both
     719             : //            "rdf:file" and "http-index" (such as with bookmarks) because we'd
     720             : //            get double the # of answers we really want... also, "rdf:file" is
     721             : //            less expensive in terms of both memory usage as well as speed
     722             : 
     723             : 
     724             : 
     725             : // We use an rdf attribute to mark if this is a container or not.
     726             : // Note that we still have to do string comparisons as a fallback
     727             : // because stuff like the personal toolbar and bookmarks check whether
     728             : // a URL is a container, and we have no attribute in that case.
     729             : bool
     730           0 : nsHTTPIndex::isWellknownContainerURI(nsIRDFResource *r)
     731             : {
     732           0 :   nsCOMPtr<nsIRDFNode> node;
     733           0 :   GetTarget(r, kNC_IsContainer, true, getter_AddRefs(node));
     734           0 :   if (node) {
     735             :     bool isContainerFlag;
     736           0 :     if (NS_SUCCEEDED(node->EqualsNode(kTrueLiteral, &isContainerFlag)))
     737           0 :       return isContainerFlag;
     738             :   }
     739             : 
     740           0 :   nsXPIDLCString uri;
     741           0 :   GetDestination(r, uri);
     742           0 :   return uri.get() && !strncmp(uri, kFTPProtocol, sizeof(kFTPProtocol) - 1) &&
     743           0 :          (uri.Last() == '/');
     744             : }
     745             : 
     746             : 
     747             : NS_IMETHODIMP
     748           0 : nsHTTPIndex::GetURI(char * *uri)
     749             : {
     750           0 :         NS_PRECONDITION(uri != nullptr, "null ptr");
     751           0 :         if (! uri)
     752           0 :                 return(NS_ERROR_NULL_POINTER);
     753             : 
     754           0 :         if ((*uri = strdup("rdf:httpindex")) == nullptr)
     755           0 :                 return(NS_ERROR_OUT_OF_MEMORY);
     756             : 
     757           0 :         return(NS_OK);
     758             : }
     759             : 
     760             : 
     761             : 
     762             : NS_IMETHODIMP
     763           0 : nsHTTPIndex::GetSource(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue,
     764             :                         nsIRDFResource **_retval)
     765             : {
     766           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
     767             : 
     768           0 :         *_retval = nullptr;
     769             : 
     770           0 :         if (mInner)
     771             :         {
     772           0 :                 rv = mInner->GetSource(aProperty, aTarget, aTruthValue, _retval);
     773             :         }
     774           0 :         return(rv);
     775             : }
     776             : 
     777             : NS_IMETHODIMP
     778           0 : nsHTTPIndex::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue,
     779             :                         nsISimpleEnumerator **_retval)
     780             : {
     781           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
     782             : 
     783           0 :         if (mInner)
     784             :         {
     785           0 :                 rv = mInner->GetSources(aProperty, aTarget, aTruthValue, _retval);
     786             :         }
     787             :         else
     788             :         {
     789           0 :                 rv = NS_NewEmptyEnumerator(_retval);
     790             :         }
     791           0 :         return(rv);
     792             : }
     793             : 
     794             : NS_IMETHODIMP
     795           0 : nsHTTPIndex::GetTarget(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue,
     796             :                         nsIRDFNode **_retval)
     797             : {
     798           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
     799             : 
     800           0 :         *_retval = nullptr;
     801             : 
     802           0 :         if ((aTruthValue) && (aProperty == kNC_Child) && isWellknownContainerURI(aSource))
     803             :         {
     804             :                 // fake out the generic builder (i.e. return anything in this case)
     805             :                 // so that search containers never appear to be empty
     806           0 :                 NS_IF_ADDREF(aSource);
     807           0 :                 *_retval = aSource;
     808           0 :                 return(NS_OK);
     809             :         }
     810             : 
     811           0 :         if (mInner)
     812             :         {
     813           0 :                 rv = mInner->GetTarget(aSource, aProperty, aTruthValue, _retval);
     814             :         }
     815           0 :         return(rv);
     816             : }
     817             : 
     818             : NS_IMETHODIMP
     819           0 : nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, bool aTruthValue,
     820             :                         nsISimpleEnumerator **_retval)
     821             : {
     822           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
     823             : 
     824           0 :         if (mInner)
     825             :         {
     826           0 :                 rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval);
     827             :         }
     828             :         else
     829             :         {
     830           0 :                 rv = NS_NewEmptyEnumerator(_retval);
     831             :         }
     832             : 
     833           0 :         if ((aProperty == kNC_Child) && isWellknownContainerURI(aSource))
     834             :         {
     835           0 :                 bool            doNetworkRequest = true;
     836           0 :                 if (NS_SUCCEEDED(rv) && (_retval))
     837             :                 {
     838             :                         // check and see if we already have data for the search in question;
     839             :                         // if we do, don't bother doing the search again
     840             :                         bool hasResults;
     841           0 :                         if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) &&
     842             :                             hasResults)
     843           0 :                           doNetworkRequest = false;
     844             :                 }
     845             : 
     846             :         // Note: if we need to do a network request, do it out-of-band
     847             :         // (because the XUL template builder isn't re-entrant)
     848             :         // by using a global connection list and an immediately-firing timer
     849           0 :                 if (doNetworkRequest && mConnectionList)
     850             :                 {
     851             :                     uint32_t connectionIndex;
     852           0 :                     nsresult idx_rv = mConnectionList->IndexOf(0, aSource, &connectionIndex);
     853           0 :                     if (NS_FAILED(idx_rv))
     854             :                     {
     855             :                     // add aSource into list of connections to make
     856           0 :                     mConnectionList->AppendElement(aSource, /*weak =*/ false);
     857             : 
     858             :                 // if we don't have a timer about to fire, create one
     859             :                 // which should fire as soon as possible (out-of-band)
     860           0 :                 if (!mTimer)
     861             :                 {
     862           0 :                         mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
     863           0 :                         NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
     864           0 :                         if (NS_SUCCEEDED(rv))
     865             :                         {
     866           0 :                           mTimer->InitWithNamedFuncCallback(
     867             :                             nsHTTPIndex::FireTimer,
     868             :                             this,
     869             :                             1,
     870             :                             nsITimer::TYPE_ONE_SHOT,
     871           0 :                             "nsHTTPIndex::GetTargets");
     872             :                           // Note: don't addref "this" as we'll cancel the
     873             :                           // timer in the httpIndex destructor
     874             :                         }
     875             :                 }
     876             :                 }
     877             :                 }
     878             :         }
     879             : 
     880           0 :         return(rv);
     881             : }
     882             : 
     883             : 
     884             : nsresult
     885           0 : nsHTTPIndex::AddElement(nsIRDFResource *parent, nsIRDFResource *prop, nsIRDFNode *child)
     886             : {
     887             :     nsresult    rv;
     888             : 
     889           0 :     if (!mNodeList)
     890             :     {
     891           0 :         mNodeList = nsArray::Create();
     892             :     }
     893             : 
     894             :     // order required: parent, prop, then child
     895           0 :     mNodeList->AppendElement(parent, /*weak =*/ false);
     896           0 :     mNodeList->AppendElement(prop, /*weak =*/ false);
     897           0 :     mNodeList->AppendElement(child, /*weak = */ false);
     898             : 
     899           0 :         if (!mTimer)
     900             :         {
     901           0 :                 mTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
     902           0 :                 NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
     903           0 :                 if (NS_FAILED(rv))  return(rv);
     904             : 
     905           0 :                 mTimer->InitWithNamedFuncCallback(nsHTTPIndex::FireTimer,
     906             :                                                   this,
     907             :                                                   1,
     908             :                                                   nsITimer::TYPE_ONE_SHOT,
     909           0 :                                                   "nsHTTPIndex::AddElement");
     910             :                 // Note: don't addref "this" as we'll cancel the
     911             :                 // timer in the httpIndex destructor
     912             :         }
     913             : 
     914           0 :     return(NS_OK);
     915             : }
     916             : 
     917             : void
     918           0 : nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure)
     919             : {
     920           0 :   nsHTTPIndex *httpIndex = static_cast<nsHTTPIndex *>(aClosure);
     921           0 :   if (!httpIndex)
     922           0 :     return;
     923             : 
     924             :   // don't return out of this loop as mTimer may need to be cancelled afterwards
     925           0 :   uint32_t numItems = 0;
     926           0 :   if (httpIndex->mConnectionList)
     927             :   {
     928           0 :     httpIndex->mConnectionList->GetLength(&numItems);
     929           0 :     if (numItems > 0)
     930             :     {
     931             :       nsCOMPtr<nsIRDFResource> source =
     932           0 :           do_QueryElementAt(httpIndex->mConnectionList, 0);
     933           0 :       httpIndex->mConnectionList->RemoveElementAt(0);
     934             : 
     935           0 :       nsXPIDLCString uri;
     936           0 :       if (source) {
     937           0 :         httpIndex->GetDestination(source, uri);
     938             :       }
     939             : 
     940           0 :       if (!uri) {
     941           0 :         NS_ERROR("Could not reconstruct uri");
     942           0 :         return;
     943             :       }
     944             : 
     945           0 :       nsresult rv = NS_OK;
     946           0 :       nsCOMPtr<nsIURI>    url;
     947             : 
     948           0 :       rv = NS_NewURI(getter_AddRefs(url), uri.get());
     949           0 :       nsCOMPtr<nsIChannel> channel;
     950           0 :       if (NS_SUCCEEDED(rv) && (url)) {
     951           0 :         rv = NS_NewChannel(getter_AddRefs(channel),
     952             :             url,
     953             :             nsContentUtils::GetSystemPrincipal(),
     954             :             nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
     955           0 :             nsIContentPolicy::TYPE_OTHER);
     956             :       }
     957           0 :       if (NS_SUCCEEDED(rv) && (channel)) {
     958           0 :         channel->SetNotificationCallbacks(httpIndex);
     959           0 :         rv = channel->AsyncOpen2(httpIndex);
     960             :       }
     961             :     }
     962             :   }
     963             : 
     964           0 :   if (httpIndex->mNodeList)
     965             :   {
     966           0 :     httpIndex->mNodeList->GetLength(&numItems);
     967           0 :     if (numItems > 0)
     968             :     {
     969             :       // account for order required: src, prop, then target
     970           0 :       numItems /=3;
     971           0 :       if (numItems > 10)
     972           0 :         numItems = 10;
     973             : 
     974             :       int32_t loop;
     975           0 :       for (loop=0; loop<(int32_t)numItems; loop++)
     976             :       {
     977           0 :         nsCOMPtr<nsIRDFResource> src = do_QueryElementAt(httpIndex->mNodeList, 0);
     978           0 :         httpIndex->mNodeList->RemoveElementAt(0);
     979             : 
     980           0 :         nsCOMPtr<nsIRDFResource> prop = do_QueryElementAt(httpIndex->mNodeList, 0);
     981           0 :         httpIndex->mNodeList->RemoveElementAt(0);
     982             : 
     983           0 :         nsCOMPtr<nsIRDFNode> target = do_QueryElementAt(httpIndex->mNodeList, 0);
     984           0 :         httpIndex->mNodeList->RemoveElementAt(0);
     985             : 
     986           0 :         if (src && prop && target)
     987             :         {
     988           0 :           if (prop.get() == httpIndex->kNC_Loading)
     989             :           {
     990           0 :             httpIndex->Unassert(src, prop, target);
     991             :           }
     992             :           else
     993             :           {
     994           0 :             httpIndex->Assert(src, prop, target, true);
     995             :           }
     996             :         }
     997             :       }
     998             :     }
     999             :   }
    1000             : 
    1001           0 :   bool refireTimer = false;
    1002             :   // check both lists to see if the timer needs to continue firing
    1003           0 :   if (httpIndex->mConnectionList)
    1004             :   {
    1005           0 :     httpIndex->mConnectionList->GetLength(&numItems);
    1006           0 :     if (numItems > 0)
    1007             :     {
    1008           0 :       refireTimer = true;
    1009             :     }
    1010             :     else
    1011             :     {
    1012           0 :       httpIndex->mConnectionList->Clear();
    1013             :     }
    1014             :   }
    1015             : 
    1016           0 :   if (httpIndex->mNodeList)
    1017             :   {
    1018           0 :     httpIndex->mNodeList->GetLength(&numItems);
    1019           0 :     if (numItems > 0)
    1020             :     {
    1021           0 :       refireTimer = true;
    1022             :     }
    1023             :     else
    1024             :     {
    1025           0 :       httpIndex->mNodeList->Clear();
    1026             :     }
    1027             :   }
    1028             : 
    1029             :   // be sure to cancel the timer, as it holds a
    1030             :   // weak reference back to nsHTTPIndex
    1031           0 :   httpIndex->mTimer->Cancel();
    1032           0 :   httpIndex->mTimer = nullptr;
    1033             : 
    1034             :   // after firing off any/all of the connections be sure
    1035             :   // to cancel the timer if we don't need to refire it
    1036           0 :   if (refireTimer)
    1037             :   {
    1038           0 :     httpIndex->mTimer = do_CreateInstance("@mozilla.org/timer;1");
    1039           0 :     if (httpIndex->mTimer)
    1040             :     {
    1041           0 :       httpIndex->mTimer->InitWithNamedFuncCallback(nsHTTPIndex::FireTimer,
    1042             :                                                    aClosure,
    1043             :                                                    10,
    1044             :                                                    nsITimer::TYPE_ONE_SHOT,
    1045           0 :                                                    "nsHTTPIndex::FireTimer");
    1046             :       // Note: don't addref "this" as we'll cancel the
    1047             :       // timer in the httpIndex destructor
    1048             :     }
    1049             :   }
    1050             : }
    1051             : 
    1052             : NS_IMETHODIMP
    1053           0 : nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget,
    1054             :                         bool aTruthValue)
    1055             : {
    1056           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1057           0 :         if (mInner)
    1058             :         {
    1059           0 :                 rv = mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
    1060             :         }
    1061           0 :         return(rv);
    1062             : }
    1063             : 
    1064             : NS_IMETHODIMP
    1065           0 : nsHTTPIndex::Unassert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
    1066             : {
    1067           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1068           0 :         if (mInner)
    1069             :         {
    1070           0 :                 rv = mInner->Unassert(aSource, aProperty, aTarget);
    1071             :         }
    1072           0 :         return(rv);
    1073             : }
    1074             : 
    1075             : NS_IMETHODIMP
    1076           0 : nsHTTPIndex::Change(nsIRDFResource *aSource, nsIRDFResource *aProperty,
    1077             :                         nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget)
    1078             : {
    1079           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1080           0 :         if (mInner)
    1081             :         {
    1082           0 :                 rv = mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
    1083             :         }
    1084           0 :         return(rv);
    1085             : }
    1086             : 
    1087             : NS_IMETHODIMP
    1088           0 : nsHTTPIndex::Move(nsIRDFResource *aOldSource, nsIRDFResource *aNewSource,
    1089             :                         nsIRDFResource *aProperty, nsIRDFNode *aTarget)
    1090             : {
    1091           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1092           0 :         if (mInner)
    1093             :         {
    1094           0 :                 rv = mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
    1095             :         }
    1096           0 :         return(rv);
    1097             : }
    1098             : 
    1099             : NS_IMETHODIMP
    1100           0 : nsHTTPIndex::HasAssertion(nsIRDFResource *aSource, nsIRDFResource *aProperty,
    1101             :                         nsIRDFNode *aTarget, bool aTruthValue, bool *_retval)
    1102             : {
    1103           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1104           0 :         if (mInner)
    1105             :         {
    1106           0 :                 rv = mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, _retval);
    1107             :         }
    1108           0 :         return(rv);
    1109             : }
    1110             : 
    1111             : NS_IMETHODIMP
    1112           0 : nsHTTPIndex::AddObserver(nsIRDFObserver *aObserver)
    1113             : {
    1114           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1115           0 :         if (mInner)
    1116             :         {
    1117           0 :                 rv = mInner->AddObserver(aObserver);
    1118             :         }
    1119           0 :         return(rv);
    1120             : }
    1121             : 
    1122             : NS_IMETHODIMP
    1123           0 : nsHTTPIndex::RemoveObserver(nsIRDFObserver *aObserver)
    1124             : {
    1125           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1126           0 :         if (mInner)
    1127             :         {
    1128           0 :                 rv = mInner->RemoveObserver(aObserver);
    1129             :         }
    1130           0 :         return(rv);
    1131             : }
    1132             : 
    1133             : NS_IMETHODIMP
    1134           0 : nsHTTPIndex::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
    1135             : {
    1136           0 :   if (!mInner) {
    1137           0 :     *result = false;
    1138           0 :     return NS_OK;
    1139             :   }
    1140           0 :   return mInner->HasArcIn(aNode, aArc, result);
    1141             : }
    1142             : 
    1143             : NS_IMETHODIMP
    1144           0 : nsHTTPIndex::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result)
    1145             : {
    1146           0 :     if (aArc == kNC_Child && isWellknownContainerURI(aSource)) {
    1147           0 :       *result = true;
    1148           0 :       return NS_OK;
    1149             :     }
    1150             : 
    1151           0 :     if (mInner) {
    1152           0 :       return mInner->HasArcOut(aSource, aArc, result);
    1153             :     }
    1154             : 
    1155           0 :     *result = false;
    1156           0 :     return NS_OK;
    1157             : }
    1158             : 
    1159             : NS_IMETHODIMP
    1160           0 : nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNode, nsISimpleEnumerator **_retval)
    1161             : {
    1162           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1163           0 :         if (mInner)
    1164             :         {
    1165           0 :                 rv = mInner->ArcLabelsIn(aNode, _retval);
    1166             :         }
    1167           0 :         return(rv);
    1168             : }
    1169             : 
    1170             : NS_IMETHODIMP
    1171           0 : nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
    1172             : {
    1173           0 :         *_retval = nullptr;
    1174             : 
    1175           0 :         nsCOMPtr<nsISimpleEnumerator> child, anonArcs;
    1176           0 :         if (isWellknownContainerURI(aSource))
    1177             :         {
    1178           0 :                 NS_NewSingletonEnumerator(getter_AddRefs(child), kNC_Child);
    1179             :         }
    1180             : 
    1181           0 :         if (mInner)
    1182             :         {
    1183           0 :                 mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs));
    1184             :         }
    1185             : 
    1186           0 :         return NS_NewUnionEnumerator(_retval, child, anonArcs);
    1187             : }
    1188             : 
    1189             : NS_IMETHODIMP
    1190           0 : nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval)
    1191             : {
    1192           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1193           0 :         if (mInner)
    1194             :         {
    1195           0 :                 rv = mInner->GetAllResources(_retval);
    1196             :         }
    1197           0 :         return(rv);
    1198             : }
    1199             : 
    1200             : NS_IMETHODIMP
    1201           0 : nsHTTPIndex::IsCommandEnabled(nsISupports *aSources, nsIRDFResource *aCommand,
    1202             :                                 nsISupports *aArguments, bool *_retval)
    1203             : {
    1204           0 :         return NS_ERROR_NOT_IMPLEMENTED;
    1205             : }
    1206             : 
    1207             : NS_IMETHODIMP
    1208           0 : nsHTTPIndex::DoCommand(nsISupports *aSources, nsIRDFResource *aCommand,
    1209             :                                 nsISupports *aArguments)
    1210             : {
    1211           0 :         return NS_ERROR_NOT_IMPLEMENTED;
    1212             : }
    1213             : 
    1214             : NS_IMETHODIMP
    1215           0 : nsHTTPIndex::BeginUpdateBatch()
    1216             : {
    1217           0 :         return mInner->BeginUpdateBatch();
    1218             : }
    1219             : 
    1220             : NS_IMETHODIMP
    1221           0 : nsHTTPIndex::EndUpdateBatch()
    1222             : {
    1223           0 :         return mInner->EndUpdateBatch();
    1224             : }
    1225             : 
    1226             : NS_IMETHODIMP
    1227           0 : nsHTTPIndex::GetAllCmds(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
    1228             : {
    1229           0 :         nsresult        rv = NS_ERROR_UNEXPECTED;
    1230           0 :         if (mInner)
    1231             :         {
    1232           0 :                 rv = mInner->GetAllCmds(aSource, _retval);
    1233             :         }
    1234           0 :         return(rv);
    1235             : }
    1236             : 
    1237             : 
    1238             : //----------------------------------------------------------------------
    1239             : //
    1240             : // nsDirectoryViewerFactory
    1241             : //
    1242           0 : nsDirectoryViewerFactory::nsDirectoryViewerFactory()
    1243             : {
    1244           0 : }
    1245             : 
    1246             : 
    1247             : 
    1248           0 : nsDirectoryViewerFactory::~nsDirectoryViewerFactory()
    1249             : {
    1250           0 : }
    1251             : 
    1252             : 
    1253           0 : NS_IMPL_ISUPPORTS(nsDirectoryViewerFactory, nsIDocumentLoaderFactory)
    1254             : 
    1255             : 
    1256             : 
    1257             : NS_IMETHODIMP
    1258           0 : nsDirectoryViewerFactory::CreateInstance(const char *aCommand,
    1259             :                                          nsIChannel* aChannel,
    1260             :                                          nsILoadGroup* aLoadGroup,
    1261             :                                          const nsACString& aContentType,
    1262             :                                          nsIDocShell* aContainer,
    1263             :                                          nsISupports* aExtraInfo,
    1264             :                                          nsIStreamListener** aDocListenerResult,
    1265             :                                          nsIContentViewer** aDocViewerResult)
    1266             : {
    1267             :   nsresult rv;
    1268             : 
    1269           0 :   bool viewSource = FindInReadable(NS_LITERAL_CSTRING("view-source"),
    1270           0 :                                    aContentType);
    1271             : 
    1272           0 :   if (!viewSource &&
    1273           0 :       Preferences::GetInt("network.dir.format", FORMAT_XUL) == FORMAT_XUL) {
    1274             :     // ... and setup the original channel's content type
    1275           0 :     (void)aChannel->SetContentType(NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"));
    1276             : 
    1277             :     // This is where we shunt the HTTP/Index stream into our datasource,
    1278             :     // and open the directory viewer XUL file as the content stream to
    1279             :     // load in its place.
    1280             : 
    1281             :     // Create a dummy loader that will load a stub XUL document.
    1282           0 :     nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
    1283           0 :     if (NS_FAILED(rv))
    1284           0 :       return rv;
    1285           0 :     nsXPIDLCString contractID;
    1286           0 :     rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "application/vnd.mozilla.xul+xml",
    1287           0 :                                   getter_Copies(contractID));
    1288           0 :     if (NS_FAILED(rv))
    1289           0 :       return rv;
    1290             : 
    1291           0 :     nsCOMPtr<nsIDocumentLoaderFactory> factory(do_GetService(contractID, &rv));
    1292           0 :     if (NS_FAILED(rv)) return rv;
    1293             : 
    1294           0 :     nsCOMPtr<nsIURI> uri;
    1295           0 :     rv = NS_NewURI(getter_AddRefs(uri), "chrome://communicator/content/directory/directory.xul");
    1296           0 :     if (NS_FAILED(rv)) return rv;
    1297             : 
    1298           0 :     nsCOMPtr<nsIChannel> channel;
    1299           0 :     rv = NS_NewChannel(getter_AddRefs(channel),
    1300             :                        uri,
    1301             :                        nsContentUtils::GetSystemPrincipal(),
    1302             :                        nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
    1303             :                        nsIContentPolicy::TYPE_OTHER,
    1304             :                        aLoadGroup);
    1305           0 :     if (NS_FAILED(rv)) return rv;
    1306             : 
    1307           0 :     nsCOMPtr<nsIStreamListener> listener;
    1308           0 :     rv = factory->CreateInstance(aCommand, channel, aLoadGroup,
    1309           0 :                                  NS_LITERAL_CSTRING("application/vnd.mozilla.xul+xml"),
    1310           0 :                                  aContainer, aExtraInfo, getter_AddRefs(listener),
    1311           0 :                                  aDocViewerResult);
    1312           0 :     if (NS_FAILED(rv)) return rv;
    1313             : 
    1314           0 :     rv = channel->AsyncOpen2(listener);
    1315           0 :     if (NS_FAILED(rv)) return rv;
    1316             : 
    1317             :     // Create an HTTPIndex object so that we can stuff it into the script context
    1318           0 :     nsCOMPtr<nsIURI> baseuri;
    1319           0 :     rv = aChannel->GetURI(getter_AddRefs(baseuri));
    1320           0 :     if (NS_FAILED(rv)) return rv;
    1321             : 
    1322           0 :     nsCOMPtr<nsIInterfaceRequestor> requestor = do_QueryInterface(aContainer,&rv);
    1323           0 :     if (NS_FAILED(rv)) return rv;
    1324             : 
    1325           0 :     nsCOMPtr<nsIHTTPIndex> httpindex;
    1326           0 :     rv = nsHTTPIndex::Create(baseuri, requestor, getter_AddRefs(httpindex));
    1327           0 :     if (NS_FAILED(rv)) return rv;
    1328             : 
    1329             :     // Now shanghai the stream into our http-index parsing datasource
    1330             :     // wrapper beastie.
    1331           0 :     listener = do_QueryInterface(httpindex,&rv);
    1332           0 :     *aDocListenerResult = listener.get();
    1333           0 :     NS_ADDREF(*aDocListenerResult);
    1334             : 
    1335           0 :     return NS_OK;
    1336             :   }
    1337             : 
    1338             :   // setup the original channel's content type
    1339           0 :   (void)aChannel->SetContentType(NS_LITERAL_CSTRING("text/html"));
    1340             : 
    1341             :   // Otherwise, lets use the html listing
    1342           0 :   nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
    1343           0 :   if (NS_FAILED(rv))
    1344           0 :     return rv;
    1345           0 :   nsXPIDLCString contractID;
    1346           0 :   rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html",
    1347           0 :                                 getter_Copies(contractID));
    1348           0 :   if (NS_FAILED(rv))
    1349           0 :     return rv;
    1350             : 
    1351           0 :   nsCOMPtr<nsIDocumentLoaderFactory> factory(do_GetService(contractID, &rv));
    1352           0 :   if (NS_FAILED(rv)) return rv;
    1353             : 
    1354           0 :   nsCOMPtr<nsIStreamListener> listener;
    1355             : 
    1356           0 :   if (viewSource) {
    1357           0 :     rv = factory->CreateInstance("view-source", aChannel, aLoadGroup,
    1358           0 :                                  NS_LITERAL_CSTRING("text/html; x-view-type=view-source"),
    1359           0 :                                  aContainer, aExtraInfo, getter_AddRefs(listener),
    1360           0 :                                  aDocViewerResult);
    1361             :   } else {
    1362           0 :     rv = factory->CreateInstance("view", aChannel, aLoadGroup,
    1363           0 :                                  NS_LITERAL_CSTRING("text/html"),
    1364           0 :                                  aContainer, aExtraInfo, getter_AddRefs(listener),
    1365           0 :                                  aDocViewerResult);
    1366             :   }
    1367             : 
    1368           0 :   if (NS_FAILED(rv)) return rv;
    1369             : 
    1370           0 :   nsCOMPtr<nsIStreamConverterService> scs = do_GetService("@mozilla.org/streamConverters;1", &rv);
    1371           0 :   if (NS_FAILED(rv)) return rv;
    1372             : 
    1373           0 :   rv = scs->AsyncConvertData("application/http-index-format",
    1374             :                              "text/html",
    1375             :                              listener,
    1376             :                              nullptr,
    1377           0 :                              aDocListenerResult);
    1378             : 
    1379           0 :   if (NS_FAILED(rv)) return rv;
    1380             : 
    1381           0 :   return NS_OK;
    1382             : }
    1383             : 
    1384             : 
    1385             : 
    1386             : NS_IMETHODIMP
    1387           0 : nsDirectoryViewerFactory::CreateInstanceForDocument(nsISupports* aContainer,
    1388             :                                                     nsIDocument* aDocument,
    1389             :                                                     const char *aCommand,
    1390             :                                                     nsIContentViewer** aDocViewerResult)
    1391             : {
    1392           0 :   NS_NOTYETIMPLEMENTED("didn't expect to get here");
    1393           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    1394             : }
    1395             : 
    1396             : NS_IMETHODIMP
    1397           0 : nsDirectoryViewerFactory::CreateBlankDocument(nsILoadGroup *aLoadGroup,
    1398             :                                               nsIPrincipal *aPrincipal,
    1399             :                                               nsIDocument **_retval) {
    1400             : 
    1401           0 :   NS_NOTYETIMPLEMENTED("didn't expect to get here");
    1402           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    1403             : }

Generated by: LCOV version 1.13