Files
Mozilla/mozilla/extensions/webdav/src/nsWebDAVService.cpp
daniel.boelzle%sun.com 92c3d33432 Bug 400382 make webdav code link with xpcom_glue instead of xpcom directly, convert to frozen linkage; r=dmose
git-svn-id: svn://10.0.0.236/trunk@240299 18797224-902f-48f8-a5cc-f745e15eee43
2007-12-03 12:31:16 +00:00

797 lines
29 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// vim:expandtab:ts=4 sw=4:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Oracle Corporation.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike Shaver <shaver@off.net> (original author)
* Gary van der Merwe <garyvdm@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsWebDAVInternal.h"
#include "nsIWebDAVService.h"
#include "nsWebDAVServiceCID.h"
#include "nsServiceManagerUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsIHttpChannel.h"
#include "nsIIOService.h"
#include "nsNetUtil.h"
#include "nsIStorageStream.h"
#include "nsIUploadChannel.h"
#include "nsIURL.h"
#include "nsContentCID.h"
#include "nsIDOMXMLDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMNodeList.h"
#include "nsIDOM3Node.h"
#include "nsIPrivateDOMImplementation.h" // I don't even pretend any more
#include "nsIDOMDOMImplementation.h"
#include "nsIDocument.h"
#include "nsIDocumentEncoder.h"
#include "nsContentCID.h"
#include "nsIDOMParser.h"
#include "nsIGenericFactory.h"
class nsWebDAVService : public nsIWebDAVService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBDAVSERVICE
nsWebDAVService();
virtual ~nsWebDAVService();
protected:
nsresult EnsureIOService();
nsresult ChannelFromResource(nsIWebDAVResource *resource,
nsIInterfaceRequestor *notificationCallbacks,
nsIHttpChannel** channel,
nsIURI ** resourceURI = 0);
nsresult CreatePropfindDocument(nsIURI *resourceURI,
nsIDOMDocument **requestDoc,
nsIDOMElement **propfindElt);
nsresult PropfindInternal(nsIWebDAVResource *resource, PRUint32 propCount,
const char **properties, PRBool withDepth,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure, PRBool namesOnly);
nsresult SendDocumentToChannel(nsIDocument *doc, nsIHttpChannel *channel,
const char *const method,
nsIStreamListener *listener,
PRBool withDepth);
nsCOMPtr<nsIIOService> mIOService; // XXX weak?
nsAutoString mDAVNSString; // "DAV:"
};
NS_IMPL_ISUPPORTS1_CI(nsWebDAVService, nsIWebDAVService)
#define ENSURE_IO_SERVICE() \
{ \
nsresult rv_ = EnsureIOService(); \
NS_ENSURE_SUCCESS(rv_, rv_); \
}
nsresult
nsWebDAVService::EnsureIOService()
{
if (!mIOService) {
nsresult rv;
mIOService = do_GetIOService(&rv);
if (!mIOService)
return rv;
}
return NS_OK;
}
nsresult
nsWebDAVService::SendDocumentToChannel(nsIDocument *doc,
nsIHttpChannel *channel,
const char *const method,
nsIStreamListener *listener,
PRBool withDepth)
{
// Why do I have to pick values for these? I just want to store some data
// for stream access! (And how would script set these?)
nsresult rv;
nsCOMPtr<nsIStorageStream> const storageStream(
do_CreateInstance("@mozilla.org/storagestream;1", &rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = storageStream->Init(4096, PR_UINT32_MAX, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIOutputStream> storageOutputStream;
rv = storageStream->GetOutputStream(0,
getter_AddRefs(storageOutputStream));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocumentEncoder> encoder =
do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/xml", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
NS_ASSERTION(domDoc, "Need a document");
rv = encoder->Init(domDoc, NS_LITERAL_STRING("text/xml"),
nsIDocumentEncoder::OutputEncodeBasicEntities);
NS_ENSURE_SUCCESS(rv, rv);
encoder->SetCharset(NS_LITERAL_CSTRING("UTF-8"));
rv = encoder->EncodeToStream(storageOutputStream);
NS_ENSURE_SUCCESS(rv, rv);
storageOutputStream->Close();
// You gotta really want it.
#ifdef PR_LOGGING
if (PR_LOG_TEST(gDAVLog, 5)) {
nsCOMPtr<nsIInputStream> logInputStream;
rv = storageStream->NewInputStream(0, getter_AddRefs(logInputStream));
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 len, read;
logInputStream->Available(&len);
char *buf = new char[len+1];
memset(buf, 0, len+1);
logInputStream->Read(buf, len, &read);
NS_ASSERTION(len == read, "short read on closed storage stream?");
LOG(("XML:\n\n%*s\n\n", len, buf));
delete [] buf;
}
#endif
nsCOMPtr<nsIInputStream> inputStream;
rv = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = uploadChannel->SetUploadStream(inputStream,
NS_LITERAL_CSTRING("text/xml"), -1);
NS_ENSURE_SUCCESS(rv, rv);
channel->SetRequestMethod(nsDependentCString(method));
channel->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
NS_LITERAL_CSTRING("text/xml; charset=utf-8"),
PR_FALSE);
channel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
NS_LITERAL_CSTRING("text/xml"),
PR_FALSE);
channel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Charset"),
NS_LITERAL_CSTRING("utf-8,*;q=0.1"),
PR_FALSE);
if (withDepth) {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
NS_LITERAL_CSTRING("1"), PR_FALSE);
} else {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
NS_LITERAL_CSTRING("0"), PR_FALSE);
}
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsCAutoString spec;
uri->GetSpec(spec);
LOG(("%s starting for %s", method, spec.get()));
}
#endif
return channel->AsyncOpen(listener, channel);
}
nsresult
nsWebDAVService::CreatePropfindDocument(nsIURI *resourceURI,
nsIDOMDocument **requestDoc,
nsIDOMElement **propfindElt)
{
nsresult rv;
static NS_DEFINE_CID(kDOMDOMDOMDOMImplementationCID,
NS_DOM_IMPLEMENTATION_CID);
nsCOMPtr<nsIDOMDOMImplementation>
implementation(do_CreateInstance(kDOMDOMDOMDOMImplementationCID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrivateDOMImplementation>
privImpl(do_QueryInterface(implementation));
// XXXbz I doubt this is right, but I have no idea what this code is doing
// or why it's creating documents without a useful principal... so I'm just
// going to make the fact that those documents have no principal very
// explicit, and if this causes issues then someone familiar with this code
// should figure out what principals this _should_ be using.
privImpl->Init(resourceURI, resourceURI, nsnull);
nsCOMPtr<nsIDOMDocument> doc;
rv = implementation->CreateDocument(mDAVNSString, EmptyString(), nsnull,
getter_AddRefs(doc));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> baseDoc = do_QueryInterface(doc);
baseDoc->SetXMLDeclaration(NS_LITERAL_STRING("1.0").get(),
EmptyString().get(), -1);
baseDoc->SetDocumentURI(resourceURI);
nsCOMPtr<nsIDOMElement> elt;
rv = NS_WD_AppendElementWithNS(doc, doc, mDAVNSString,
NS_LITERAL_STRING("propfind"),
getter_AddRefs(elt));
elt->SetPrefix(NS_LITERAL_STRING("D"));
NS_ENSURE_SUCCESS(rv, rv);
*requestDoc = doc.get();
NS_ADDREF(*requestDoc);
*propfindElt = elt.get();
NS_ADDREF(*propfindElt);
return NS_OK;
}
nsresult
nsWebDAVService::ChannelFromResource(nsIWebDAVResource *aResource,
nsIInterfaceRequestor *notificationCallbacks,
nsIHttpChannel **aChannel,
nsIURI **aResourceURI)
{
ENSURE_IO_SERVICE();
nsCOMPtr<nsIURL> resourceURL;
nsresult rv = aResource->GetResourceURL(getter_AddRefs(resourceURL));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> baseChannel;
rv = mIOService->NewChannelFromURI(resourceURL, getter_AddRefs(baseChannel));
NS_ENSURE_SUCCESS(rv, rv);
rv = baseChannel->SetNotificationCallbacks(notificationCallbacks);
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags loadFlags;
rv = baseChannel->GetLoadFlags(&loadFlags);
if (NS_SUCCEEDED(rv)) {
rv = baseChannel->SetLoadFlags(loadFlags |
nsIRequest::VALIDATE_ALWAYS);
NS_ASSERTION(NS_SUCCEEDED(rv),
"nsWebDavService::ChannelFromResource(): "
"Couldn't set loadflags on channel");
}
rv = CallQueryInterface(baseChannel, aChannel);
if (NS_SUCCEEDED(rv) && aResourceURI) {
*aResourceURI = resourceURL.get();
NS_ADDREF(*aResourceURI);
}
return rv;
}
nsWebDAVService::nsWebDAVService() :
mDAVNSString(NS_LITERAL_STRING("DAV:"))
{
#ifdef PR_LOGGING
gDAVLog = PR_NewLogModule("webdav");
#endif
}
nsWebDAVService::~nsWebDAVService()
{
/* destructor code */
}
NS_IMETHODIMP
nsWebDAVService::LockResources(PRUint32 count, nsIWebDAVResource **resources,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsWebDAVService::UnlockResources(PRUint32 count, nsIWebDAVResource **resources,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsWebDAVService::GetResourcePropertyNames(nsIWebDAVResource *resource,
PRBool withDepth,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
return PropfindInternal(resource, 0, nsnull, withDepth,
listener, notificationCallbacks, closure, PR_TRUE);
}
NS_IMETHODIMP
nsWebDAVService::GetResourceProperties(nsIWebDAVResource *resource,
PRUint32 propCount,
const char **properties,
PRBool withDepth,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
return PropfindInternal(resource, propCount, properties, withDepth,
listener, notificationCallbacks, closure, PR_FALSE);
}
nsresult
nsWebDAVService::PropfindInternal(nsIWebDAVResource *resource,
PRUint32 propCount,
const char **properties,
PRBool withDepth,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure,
PRBool namesOnly)
{
nsresult rv;
NS_ENSURE_ARG(resource);
NS_ENSURE_ARG(listener);
nsCOMPtr<nsIURI> resourceURI;
nsCOMPtr<nsIHttpChannel> channel;
rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel),
getter_AddRefs(resourceURI));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIDOMDocument> requestDoc;
nsCOMPtr<nsIDOMElement> propfindElt;
rv = CreatePropfindDocument(resourceURI, getter_AddRefs(requestDoc),
getter_AddRefs(propfindElt));
NS_ENSURE_SUCCESS(rv, rv);
if (namesOnly) {
nsCOMPtr<nsIDOMElement> allpropElt;
rv = NS_WD_AppendElementWithNS(requestDoc, propfindElt,
mDAVNSString, NS_LITERAL_STRING("propname"),
getter_AddRefs(allpropElt));
NS_ENSURE_SUCCESS(rv, rv);
} else if (propCount == 0) {
nsCOMPtr<nsIDOMElement> allpropElt;
rv = NS_WD_AppendElementWithNS(requestDoc, propfindElt,
mDAVNSString, NS_LITERAL_STRING("allprop"),
getter_AddRefs(allpropElt));
NS_ENSURE_SUCCESS(rv, rv);
} else {
nsCOMPtr<nsIDOMElement> propElt;
rv = NS_WD_AppendElementWithNS(requestDoc, propfindElt,
mDAVNSString, NS_LITERAL_STRING("prop"),
getter_AddRefs(propElt));
NS_ENSURE_SUCCESS(rv, rv);
for (PRUint32 i = 0; i < propCount; i++) {
nsDependentCString fullpropName(properties[i]);
PRInt32 const index = fullpropName.RFindChar(' ');
if (index < 0) {
nsCAutoString msg(NS_LITERAL_CSTRING("Illegal property name "));
msg += fullpropName;
msg.Append('\n');
NS_WARNING(msg.get());
return NS_ERROR_INVALID_ARG;
}
nsDependentCSubstring const propNamespace_(fullpropName, 0, index);
nsDependentCSubstring const propName_(fullpropName, index + 1);
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCString const ns(propNamespace_);
nsCString const name(propName_);
LOG(("prop ns: '%s', name: '%s'", ns.get(), name.get()));
}
#endif
NS_ConvertASCIItoUTF16 const propNamespace(propNamespace_);
NS_ConvertASCIItoUTF16 const propName(propName_);
nsCOMPtr<nsIDOMElement> junk;
rv = NS_WD_AppendElementWithNS(requestDoc, propElt, propNamespace,
propName, getter_AddRefs(junk));
NS_ENSURE_SUCCESS(rv, rv);
}
}
nsCOMPtr<nsIStreamListener> streamListener =
NS_WD_NewPropfindStreamListener(resource, listener, closure,
namesOnly);
if (!streamListener)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIDocument> requestBaseDoc = do_QueryInterface(requestDoc);
return SendDocumentToChannel(requestBaseDoc, channel, "PROPFIND",
streamListener, withDepth);
}
NS_IMETHODIMP
nsWebDAVService::GetResourceOptions(nsIWebDAVResource *resource,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsWebDAVService::Get(nsIWebDAVResource *resource, nsIStreamListener *listener,
nsIInterfaceRequestor *notificationCallbacks)
{
nsresult rv;
nsCOMPtr<nsIHttpChannel> channel;
rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
if (NS_FAILED(rv))
return rv;
return channel->AsyncOpen(listener, channel);
}
NS_IMETHODIMP
nsWebDAVService::GetToOutputStream(nsIWebDAVResource *resource,
nsIOutputStream *stream,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIRequestObserver> getObserver;
nsresult rv;
rv = NS_WD_NewGetOperationRequestObserver(resource, listener, closure,
stream,
getter_AddRefs(getObserver));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> streamListener;
rv = NS_NewSimpleStreamListener(getter_AddRefs(streamListener),
stream, getObserver);
NS_ENSURE_SUCCESS(rv, rv);
return Get(resource, streamListener, notificationCallbacks);
}
NS_IMETHODIMP
nsWebDAVService::GetToString(nsIWebDAVResource *resource,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIStreamListener> getListener;
nsresult rv;
rv = NS_WD_NewGetToStringOperationRequestObserver(resource, listener,
closure,
getter_AddRefs(getListener));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHttpChannel> channel;
rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
return channel->AsyncOpen(getListener, channel);
}
NS_IMETHODIMP
nsWebDAVService::Put(nsIWebDAVResource *resource,
const nsACString& contentType, nsIInputStream *data,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIHttpChannel> channel;
nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = uploadChannel->SetUploadStream(data, contentType, -1);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> streamListener;
rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
nsIWebDAVOperationListener::PUT,
getter_AddRefs(streamListener));
NS_ENSURE_SUCCESS(rv, rv);
channel->SetRequestMethod(NS_LITERAL_CSTRING("PUT"));
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsCAutoString spec;
uri->GetSpec(spec);
LOG(("PUT starting for %s", spec.get()));
}
#endif
return channel->AsyncOpen(streamListener, channel);
}
NS_IMETHODIMP
nsWebDAVService::PutFromString(nsIWebDAVResource *resource,
const nsACString& contentType,
const nsACString& data,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsresult rv;
nsCOMPtr<nsIStringInputStream> dataStream =
do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
dataStream->SetData(PromiseFlatCString(data).get(),
data.Length());
return Put(resource, contentType, dataStream, listener,
notificationCallbacks, closure);
}
NS_IMETHODIMP
nsWebDAVService::Remove(nsIWebDAVResource *resource,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIHttpChannel> channel;
nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> streamListener;
rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
nsIWebDAVOperationListener::REMOVE,
getter_AddRefs(streamListener));
NS_ENSURE_SUCCESS(rv, rv);
channel->SetRequestMethod(NS_LITERAL_CSTRING("DELETE"));
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsCAutoString spec;
uri->GetSpec(spec);
LOG(("DELETE starting for %s", spec.get()));
}
#endif
return channel->AsyncOpen(streamListener, channel);
}
NS_IMETHODIMP
nsWebDAVService::MakeCollection(nsIWebDAVResource *resource,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIHttpChannel> channel;
nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> streamListener;
rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
nsIWebDAVOperationListener::MAKE_COLLECTION,
getter_AddRefs(streamListener));
NS_ENSURE_SUCCESS(rv, rv);
channel->SetRequestMethod(NS_LITERAL_CSTRING("MKCOL"));
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsCAutoString spec;
uri->GetSpec(spec);
LOG(("MKCOL starting for %s", spec.get()));
}
#endif
return channel->AsyncOpen(streamListener, channel);
}
NS_IMETHODIMP
nsWebDAVService::MoveTo(nsIWebDAVResource *resource,
const nsACString &destination,
PRBool overwrite,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIHttpChannel> channel;
nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> streamListener;
rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
nsIWebDAVOperationListener::COPY,
getter_AddRefs(streamListener));
NS_ENSURE_SUCCESS(rv, rv);
channel->SetRequestMethod(NS_LITERAL_CSTRING("MOVE"));
if (!overwrite) {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
NS_LITERAL_CSTRING("F"),
PR_FALSE);
} else {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
NS_LITERAL_CSTRING("F"),
PR_FALSE);
}
channel->SetRequestHeader(NS_LITERAL_CSTRING("Destination"),
destination, PR_FALSE);
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsCAutoString spec;
uri->GetSpec(spec);
LOG(("MOVE starting for %s -> %s", spec.get(),
nsCAutoString(destination).get()));
}
#endif
return channel->AsyncOpen(streamListener, channel);
}
NS_IMETHODIMP
nsWebDAVService::CopyTo(nsIWebDAVResource *resource,
const nsACString &destination,
PRBool recursive, PRBool overwrite,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsCOMPtr<nsIHttpChannel> channel;
nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStreamListener> streamListener;
rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
nsIWebDAVOperationListener::COPY,
getter_AddRefs(streamListener));
NS_ENSURE_SUCCESS(rv, rv);
channel->SetRequestMethod(NS_LITERAL_CSTRING("COPY"));
if (!overwrite) {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
NS_LITERAL_CSTRING("F"),
PR_FALSE);
} else {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
NS_LITERAL_CSTRING("F"),
PR_FALSE);
}
if (recursive) {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
NS_LITERAL_CSTRING("infinity"), PR_FALSE);
} else {
channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
NS_LITERAL_CSTRING("0"), PR_FALSE);
}
channel->SetRequestHeader(NS_LITERAL_CSTRING("Destination"),
destination, PR_FALSE);
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsCAutoString spec;
uri->GetSpec(spec);
LOG(("COPY starting for %s -> %s", spec.get(),
nsCAutoString(destination).get()));
}
#endif
return channel->AsyncOpen(streamListener, channel);
}
NS_IMETHODIMP
nsWebDAVService::Report(nsIWebDAVResource *resource, nsIDOMDocument *query,
PRBool withDepth,
nsIWebDAVOperationListener *listener,
nsIInterfaceRequestor *notificationCallbacks,
nsISupports *closure)
{
nsresult rv;
NS_ENSURE_ARG(resource);
NS_ENSURE_ARG(query);
NS_ENSURE_ARG(listener);
nsCOMPtr<nsIDocument> queryDoc = do_QueryInterface(query, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> resourceURI;
nsCOMPtr<nsIHttpChannel> channel;
rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel),
getter_AddRefs(resourceURI));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIStreamListener> streamListener =
NS_WD_NewReportStreamListener(resource, listener, closure);
if (!streamListener)
return NS_ERROR_OUT_OF_MEMORY;
return SendDocumentToChannel(queryDoc, channel, "REPORT", streamListener,
withDepth);
}
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebDAVService)
NS_DECL_CLASSINFO(nsWebDAVService)
static const nsModuleComponentInfo components[] =
{
{ "WebDAV Service", NS_WEBDAVSERVICE_CID, NS_WEBDAVSERVICE_CONTRACTID,
nsWebDAVServiceConstructor,
NULL, NULL, NULL,
NS_CI_INTERFACE_GETTER_NAME(nsWebDAVService),
NULL,
&NS_CLASSINFO_NAME(nsWebDAVService)
}
};
NS_IMPL_NSGETMODULE(nsWebDAVService, components)