Import from 1.9a8 tarball
[mozilla-extra.git] / extensions / webdav / src / nsWebDAVService.cpp
bloba607e77d108bd61c1790df898f0515d41fb78cc4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 // vim:expandtab:ts=4 sw=4:
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is Mozilla.
18 * The Initial Developer of the Original Code is
19 * Oracle Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Mike Shaver <shaver@off.net> (original author)
25 * Gary van der Merwe <garyvdm@gmail.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "nsWebDAVInternal.h"
43 #include "nsIWebDAVService.h"
44 #include "nsWebDAVServiceCID.h"
46 #include "nsServiceManagerUtils.h"
47 #include "nsIClassInfoImpl.h"
49 #include "nsIHttpChannel.h"
50 #include "nsIIOService.h"
51 #include "nsNetUtil.h"
52 #include "nsIStorageStream.h"
53 #include "nsIUploadChannel.h"
54 #include "nsIURL.h"
56 #include "nsContentCID.h"
58 #include "nsIDOMXMLDocument.h"
59 #include "nsIDOMElement.h"
60 #include "nsIDOMNodeList.h"
61 #include "nsIDOM3Node.h"
62 #include "nsIPrivateDOMImplementation.h" // I don't even pretend any more
63 #include "nsIDOMDOMImplementation.h"
65 #include "nsIDocument.h"
66 #include "nsIDocumentEncoder.h"
67 #include "nsContentCID.h"
69 #include "nsIDOMParser.h"
71 #include "nsIGenericFactory.h"
73 class nsWebDAVService : public nsIWebDAVService
75 public:
76 NS_DECL_ISUPPORTS
77 NS_DECL_NSIWEBDAVSERVICE
79 nsWebDAVService();
80 virtual ~nsWebDAVService();
81 protected:
82 nsresult EnsureIOService();
83 nsresult ChannelFromResource(nsIWebDAVResource *resource,
84 nsIInterfaceRequestor *notificationCallbacks,
85 nsIHttpChannel** channel,
86 nsIURI ** resourceURI = 0);
88 nsresult CreatePropfindDocument(nsIURI *resourceURI,
89 nsIDOMDocument **requestDoc,
90 nsIDOMElement **propfindElt);
92 nsresult PropfindInternal(nsIWebDAVResource *resource, PRUint32 propCount,
93 const char **properties, PRBool withDepth,
94 nsIWebDAVOperationListener *listener,
95 nsIInterfaceRequestor *notificationCallbacks,
96 nsISupports *closure, PRBool namesOnly);
98 nsresult SendDocumentToChannel(nsIDocument *doc, nsIHttpChannel *channel,
99 const char *const method,
100 nsIStreamListener *listener,
101 PRBool withDepth);
102 nsCOMPtr<nsIIOService> mIOService; // XXX weak?
103 nsAutoString mDAVNSString; // "DAV:"
106 NS_IMPL_ISUPPORTS1_CI(nsWebDAVService, nsIWebDAVService)
108 #define ENSURE_IO_SERVICE() \
110 nsresult rv_ = EnsureIOService(); \
111 NS_ENSURE_SUCCESS(rv_, rv_); \
114 nsresult
115 nsWebDAVService::EnsureIOService()
117 if (!mIOService) {
118 nsresult rv;
119 mIOService = do_GetIOService(&rv);
120 if (!mIOService)
121 return rv;
124 return NS_OK;
127 nsresult
128 nsWebDAVService::SendDocumentToChannel(nsIDocument *doc,
129 nsIHttpChannel *channel,
130 const char *const method,
131 nsIStreamListener *listener,
132 PRBool withDepth)
134 nsCOMPtr<nsIStorageStream> storageStream;
135 // Why do I have to pick values for these? I just want to store some data
136 // for stream access! (And how would script set these?)
137 nsresult rv = NS_NewStorageStream(4096, PR_UINT32_MAX,
138 getter_AddRefs(storageStream));
139 NS_ENSURE_SUCCESS(rv, rv);
141 nsCOMPtr<nsIOutputStream> storageOutputStream;
142 rv = storageStream->GetOutputStream(0,
143 getter_AddRefs(storageOutputStream));
144 NS_ENSURE_SUCCESS(rv, rv);
146 nsCOMPtr<nsIDocumentEncoder> encoder =
147 do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/xml", &rv);
148 NS_ENSURE_SUCCESS(rv, rv);
150 nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
151 NS_ASSERTION(domDoc, "Need a document");
153 rv = encoder->Init(domDoc, NS_LITERAL_STRING("text/xml"),
154 nsIDocumentEncoder::OutputEncodeBasicEntities);
155 NS_ENSURE_SUCCESS(rv, rv);
157 encoder->SetCharset(NS_LITERAL_CSTRING("UTF-8"));
158 rv = encoder->EncodeToStream(storageOutputStream);
159 NS_ENSURE_SUCCESS(rv, rv);
161 storageOutputStream->Close();
163 // You gotta really want it.
164 #ifdef PR_LOGGING
165 if (PR_LOG_TEST(gDAVLog, 5)) {
166 nsCOMPtr<nsIInputStream> logInputStream;
167 rv = storageStream->NewInputStream(0, getter_AddRefs(logInputStream));
168 NS_ENSURE_SUCCESS(rv, rv);
170 PRUint32 len, read;
171 logInputStream->Available(&len);
173 char *buf = new char[len+1];
174 memset(buf, 0, len+1);
175 logInputStream->Read(buf, len, &read);
176 NS_ASSERTION(len == read, "short read on closed storage stream?");
177 LOG(("XML:\n\n%*s\n\n", len, buf));
179 delete [] buf;
181 #endif
183 nsCOMPtr<nsIInputStream> inputStream;
184 rv = storageStream->NewInputStream(0, getter_AddRefs(inputStream));
185 NS_ENSURE_SUCCESS(rv, rv);
187 nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel, &rv);
188 NS_ENSURE_SUCCESS(rv, rv);
189 rv = uploadChannel->SetUploadStream(inputStream,
190 NS_LITERAL_CSTRING("text/xml"), -1);
191 NS_ENSURE_SUCCESS(rv, rv);
193 channel->SetRequestMethod(nsDependentCString(method));
194 channel->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
195 NS_LITERAL_CSTRING("text/xml; charset=utf-8"),
196 PR_FALSE);
197 channel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
198 NS_LITERAL_CSTRING("text/xml"),
199 PR_FALSE);
200 channel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Charset"),
201 NS_LITERAL_CSTRING("utf-8,*;q=0.1"),
202 PR_FALSE);
205 if (withDepth) {
206 channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
207 NS_LITERAL_CSTRING("1"), PR_FALSE);
208 } else {
209 channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
210 NS_LITERAL_CSTRING("0"), PR_FALSE);
213 #ifdef PR_LOGGING
214 if (LOG_ENABLED()) {
215 nsCOMPtr<nsIURI> uri;
216 channel->GetURI(getter_AddRefs(uri));
217 nsCAutoString spec;
218 uri->GetSpec(spec);
219 LOG(("%s starting for %s", method, spec.get()));
221 #endif
223 return channel->AsyncOpen(listener, channel);
226 nsresult
227 nsWebDAVService::CreatePropfindDocument(nsIURI *resourceURI,
228 nsIDOMDocument **requestDoc,
229 nsIDOMElement **propfindElt)
231 nsresult rv;
232 static NS_DEFINE_CID(kDOMDOMDOMDOMImplementationCID,
233 NS_DOM_IMPLEMENTATION_CID);
234 nsCOMPtr<nsIDOMDOMImplementation>
235 implementation(do_CreateInstance(kDOMDOMDOMDOMImplementationCID, &rv));
236 NS_ENSURE_SUCCESS(rv, rv);
238 nsCOMPtr<nsIPrivateDOMImplementation>
239 privImpl(do_QueryInterface(implementation));
240 // XXXbz I doubt this is right, but I have no idea what this code is doing
241 // or why it's creating documents without a useful principal... so I'm just
242 // going to make the fact that those documents have no principal very
243 // explicit, and if this causes issues then someone familiar with this code
244 // should figure out what principals this _should_ be using.
245 privImpl->Init(resourceURI, resourceURI, nsnull);
247 nsCOMPtr<nsIDOMDocument> doc;
248 rv = implementation->CreateDocument(mDAVNSString, EmptyString(), nsnull,
249 getter_AddRefs(doc));
250 NS_ENSURE_SUCCESS(rv, rv);
252 nsCOMPtr<nsIDocument> baseDoc = do_QueryInterface(doc);
253 baseDoc->SetXMLDeclaration(NS_LITERAL_STRING("1.0").get(),
254 EmptyString().get(), -1);
255 baseDoc->SetDocumentURI(resourceURI);
257 nsCOMPtr<nsIDOMElement> elt;
258 rv = NS_WD_AppendElementWithNS(doc, doc, mDAVNSString,
259 NS_LITERAL_STRING("propfind"),
260 getter_AddRefs(elt));
261 elt->SetPrefix(NS_LITERAL_STRING("D"));
262 NS_ENSURE_SUCCESS(rv, rv);
264 *requestDoc = doc.get();
265 NS_ADDREF(*requestDoc);
266 *propfindElt = elt.get();
267 NS_ADDREF(*propfindElt);
269 return NS_OK;
272 nsresult
273 nsWebDAVService::ChannelFromResource(nsIWebDAVResource *aResource,
274 nsIInterfaceRequestor *notificationCallbacks,
275 nsIHttpChannel **aChannel,
276 nsIURI **aResourceURI)
278 ENSURE_IO_SERVICE();
280 nsCOMPtr<nsIURL> resourceURL;
282 nsresult rv = aResource->GetResourceURL(getter_AddRefs(resourceURL));
283 NS_ENSURE_SUCCESS(rv, rv);
285 nsCOMPtr<nsIChannel> baseChannel;
286 rv = mIOService->NewChannelFromURI(resourceURL, getter_AddRefs(baseChannel));
287 NS_ENSURE_SUCCESS(rv, rv);
289 rv = baseChannel->SetNotificationCallbacks(notificationCallbacks);
290 NS_ENSURE_SUCCESS(rv, rv);
292 nsLoadFlags loadFlags;
293 rv = baseChannel->GetLoadFlags(&loadFlags);
294 if (NS_SUCCEEDED(rv)) {
295 rv = baseChannel->SetLoadFlags(loadFlags |
296 nsIRequest::VALIDATE_ALWAYS);
297 NS_ASSERTION(NS_SUCCEEDED(rv),
298 "nsWebDavService::ChannelFromResource(): "
299 "Couldn't set loadflags on channel");
302 rv = CallQueryInterface(baseChannel, aChannel);
304 if (NS_SUCCEEDED(rv) && aResourceURI) {
305 *aResourceURI = resourceURL.get();
306 NS_ADDREF(*aResourceURI);
309 return rv;
312 nsWebDAVService::nsWebDAVService() :
313 mDAVNSString(NS_LITERAL_STRING("DAV:"))
316 #ifdef PR_LOGGING
317 gDAVLog = PR_NewLogModule("webdav");
318 #endif
321 nsWebDAVService::~nsWebDAVService()
323 /* destructor code */
326 NS_IMETHODIMP
327 nsWebDAVService::LockResources(PRUint32 count, nsIWebDAVResource **resources,
328 nsIWebDAVOperationListener *listener,
329 nsIInterfaceRequestor *notificationCallbacks,
330 nsISupports *closure)
332 return NS_ERROR_NOT_IMPLEMENTED;
335 NS_IMETHODIMP
336 nsWebDAVService::UnlockResources(PRUint32 count, nsIWebDAVResource **resources,
337 nsIWebDAVOperationListener *listener,
338 nsIInterfaceRequestor *notificationCallbacks,
339 nsISupports *closure)
341 return NS_ERROR_NOT_IMPLEMENTED;
344 NS_IMETHODIMP
345 nsWebDAVService::GetResourcePropertyNames(nsIWebDAVResource *resource,
346 PRBool withDepth,
347 nsIWebDAVOperationListener *listener,
348 nsIInterfaceRequestor *notificationCallbacks,
349 nsISupports *closure)
351 return PropfindInternal(resource, 0, nsnull, withDepth,
352 listener, notificationCallbacks, closure, PR_TRUE);
355 NS_IMETHODIMP
356 nsWebDAVService::GetResourceProperties(nsIWebDAVResource *resource,
357 PRUint32 propCount,
358 const char **properties,
359 PRBool withDepth,
360 nsIWebDAVOperationListener *listener,
361 nsIInterfaceRequestor *notificationCallbacks,
362 nsISupports *closure)
364 return PropfindInternal(resource, propCount, properties, withDepth,
365 listener, notificationCallbacks, closure, PR_FALSE);
368 nsresult
369 nsWebDAVService::PropfindInternal(nsIWebDAVResource *resource,
370 PRUint32 propCount,
371 const char **properties,
372 PRBool withDepth,
373 nsIWebDAVOperationListener *listener,
374 nsIInterfaceRequestor *notificationCallbacks,
375 nsISupports *closure,
376 PRBool namesOnly)
378 nsresult rv;
380 NS_ENSURE_ARG(resource);
381 NS_ENSURE_ARG(listener);
383 nsCOMPtr<nsIURI> resourceURI;
384 nsCOMPtr<nsIHttpChannel> channel;
385 rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel),
386 getter_AddRefs(resourceURI));
387 if (NS_FAILED(rv))
388 return rv;
390 nsCOMPtr<nsIDOMDocument> requestDoc;
391 nsCOMPtr<nsIDOMElement> propfindElt;
392 rv = CreatePropfindDocument(resourceURI, getter_AddRefs(requestDoc),
393 getter_AddRefs(propfindElt));
394 NS_ENSURE_SUCCESS(rv, rv);
396 if (namesOnly) {
397 nsCOMPtr<nsIDOMElement> allpropElt;
398 rv = NS_WD_AppendElementWithNS(requestDoc, propfindElt,
399 mDAVNSString, NS_LITERAL_STRING("propname"),
400 getter_AddRefs(allpropElt));
401 NS_ENSURE_SUCCESS(rv, rv);
402 } else if (propCount == 0) {
403 nsCOMPtr<nsIDOMElement> allpropElt;
404 rv = NS_WD_AppendElementWithNS(requestDoc, propfindElt,
405 mDAVNSString, NS_LITERAL_STRING("allprop"),
406 getter_AddRefs(allpropElt));
407 NS_ENSURE_SUCCESS(rv, rv);
408 } else {
409 nsCOMPtr<nsIDOMElement> propElt;
410 rv = NS_WD_AppendElementWithNS(requestDoc, propfindElt,
411 mDAVNSString, NS_LITERAL_STRING("prop"),
412 getter_AddRefs(propElt));
413 NS_ENSURE_SUCCESS(rv, rv);
415 for (PRUint32 i = 0; i < propCount; i++) {
416 nsDependentCString fullpropName(properties[i]);
418 // This string math is _ridiculous_. It better compile to a total of
419 // 5 instructions, or I'm ripping it all out and doing my own looping.
421 nsACString::const_iterator start, saveStart, end, saveEnd;
422 fullpropName.BeginReading(start);
423 fullpropName.BeginReading(saveStart);
424 fullpropName.EndReading(end);
425 fullpropName.EndReading(saveEnd);
426 RFindInReadable(NS_LITERAL_CSTRING(" "), start, end);
428 if (start == end) {
429 nsCAutoString msg(NS_LITERAL_CSTRING("Illegal property name ")
430 + fullpropName + NS_LITERAL_CSTRING("\n"));
431 NS_WARNING(msg.get());
432 return NS_ERROR_INVALID_ARG;
435 #ifdef PR_LOGGING
436 if (LOG_ENABLED()) {
437 nsACString::const_iterator s = start;
439 nsCAutoString propNamespace(nsDependentCSubstring(saveStart, s));
440 nsCAutoString propName(nsDependentCSubstring(++s, saveEnd));
442 LOG(("prop ns: '%s', name: '%s'", propNamespace.get(), propName.get()));
444 #endif
446 NS_ConvertASCIItoUTF16 propNamespace(nsDependentCSubstring(saveStart, start)),
447 propName(nsDependentCSubstring(++start, saveEnd));
449 nsCOMPtr<nsIDOMElement> junk;
450 rv = NS_WD_AppendElementWithNS(requestDoc, propElt, propNamespace,
451 propName, getter_AddRefs(junk));
452 NS_ENSURE_SUCCESS(rv, rv);
456 nsCOMPtr<nsIStreamListener> streamListener =
457 NS_WD_NewPropfindStreamListener(resource, listener, closure,
458 namesOnly);
460 if (!streamListener)
461 return NS_ERROR_OUT_OF_MEMORY;
463 nsCOMPtr<nsIDocument> requestBaseDoc = do_QueryInterface(requestDoc);
464 return SendDocumentToChannel(requestBaseDoc, channel, "PROPFIND",
465 streamListener, withDepth);
468 NS_IMETHODIMP
469 nsWebDAVService::GetResourceOptions(nsIWebDAVResource *resource,
470 nsIWebDAVOperationListener *listener,
471 nsIInterfaceRequestor *notificationCallbacks,
472 nsISupports *closure)
474 return NS_ERROR_NOT_IMPLEMENTED;
477 NS_IMETHODIMP
478 nsWebDAVService::Get(nsIWebDAVResource *resource, nsIStreamListener *listener,
479 nsIInterfaceRequestor *notificationCallbacks)
481 nsresult rv;
482 nsCOMPtr<nsIHttpChannel> channel;
483 rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
484 if (NS_FAILED(rv))
485 return rv;
487 return channel->AsyncOpen(listener, channel);
490 NS_IMETHODIMP
491 nsWebDAVService::GetToOutputStream(nsIWebDAVResource *resource,
492 nsIOutputStream *stream,
493 nsIWebDAVOperationListener *listener,
494 nsIInterfaceRequestor *notificationCallbacks,
495 nsISupports *closure)
497 nsCOMPtr<nsIRequestObserver> getObserver;
498 nsresult rv;
500 rv = NS_WD_NewGetOperationRequestObserver(resource, listener, closure,
501 stream,
502 getter_AddRefs(getObserver));
503 NS_ENSURE_SUCCESS(rv, rv);
505 nsCOMPtr<nsIStreamListener> streamListener;
506 rv = NS_NewSimpleStreamListener(getter_AddRefs(streamListener),
507 stream, getObserver);
508 NS_ENSURE_SUCCESS(rv, rv);
510 return Get(resource, streamListener, notificationCallbacks);
513 NS_IMETHODIMP
514 nsWebDAVService::GetToString(nsIWebDAVResource *resource,
515 nsIWebDAVOperationListener *listener,
516 nsIInterfaceRequestor *notificationCallbacks,
517 nsISupports *closure)
519 nsCOMPtr<nsIStreamListener> getListener;
520 nsresult rv;
522 rv = NS_WD_NewGetToStringOperationRequestObserver(resource, listener,
523 closure,
524 getter_AddRefs(getListener));
525 NS_ENSURE_SUCCESS(rv, rv);
527 nsCOMPtr<nsIHttpChannel> channel;
528 rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
529 NS_ENSURE_SUCCESS(rv, rv);
531 return channel->AsyncOpen(getListener, channel);
534 NS_IMETHODIMP
535 nsWebDAVService::Put(nsIWebDAVResource *resource,
536 const nsACString& contentType, nsIInputStream *data,
537 nsIWebDAVOperationListener *listener,
538 nsIInterfaceRequestor *notificationCallbacks,
539 nsISupports *closure)
541 nsCOMPtr<nsIHttpChannel> channel;
543 nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
544 NS_ENSURE_SUCCESS(rv, rv);
546 nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(channel, &rv);
547 NS_ENSURE_SUCCESS(rv, rv);
549 rv = uploadChannel->SetUploadStream(data, contentType, -1);
550 NS_ENSURE_SUCCESS(rv, rv);
552 nsCOMPtr<nsIStreamListener> streamListener;
553 rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
554 nsIWebDAVOperationListener::PUT,
555 getter_AddRefs(streamListener));
556 NS_ENSURE_SUCCESS(rv, rv);
558 channel->SetRequestMethod(NS_LITERAL_CSTRING("PUT"));
560 #ifdef PR_LOGGING
561 if (LOG_ENABLED()) {
562 nsCOMPtr<nsIURI> uri;
563 channel->GetURI(getter_AddRefs(uri));
564 nsCAutoString spec;
565 uri->GetSpec(spec);
566 LOG(("PUT starting for %s", spec.get()));
568 #endif
570 return channel->AsyncOpen(streamListener, channel);
573 NS_IMETHODIMP
574 nsWebDAVService::PutFromString(nsIWebDAVResource *resource,
575 const nsACString& contentType,
576 const nsACString& data,
577 nsIWebDAVOperationListener *listener,
578 nsIInterfaceRequestor *notificationCallbacks,
579 nsISupports *closure)
581 nsresult rv;
582 nsCOMPtr<nsIStringInputStream> dataStream =
583 do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
584 NS_ENSURE_SUCCESS(rv, rv);
586 dataStream->SetData(PromiseFlatCString(data).get(),
587 data.Length());
588 return Put(resource, contentType, dataStream, listener,
589 notificationCallbacks, closure);
592 NS_IMETHODIMP
593 nsWebDAVService::Remove(nsIWebDAVResource *resource,
594 nsIWebDAVOperationListener *listener,
595 nsIInterfaceRequestor *notificationCallbacks,
596 nsISupports *closure)
598 nsCOMPtr<nsIHttpChannel> channel;
599 nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
600 NS_ENSURE_SUCCESS(rv, rv);
602 nsCOMPtr<nsIStreamListener> streamListener;
603 rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
604 nsIWebDAVOperationListener::REMOVE,
605 getter_AddRefs(streamListener));
606 NS_ENSURE_SUCCESS(rv, rv);
608 channel->SetRequestMethod(NS_LITERAL_CSTRING("DELETE"));
610 #ifdef PR_LOGGING
611 if (LOG_ENABLED()) {
612 nsCOMPtr<nsIURI> uri;
613 channel->GetURI(getter_AddRefs(uri));
614 nsCAutoString spec;
615 uri->GetSpec(spec);
616 LOG(("DELETE starting for %s", spec.get()));
618 #endif
620 return channel->AsyncOpen(streamListener, channel);
623 NS_IMETHODIMP
624 nsWebDAVService::MakeCollection(nsIWebDAVResource *resource,
625 nsIWebDAVOperationListener *listener,
626 nsIInterfaceRequestor *notificationCallbacks,
627 nsISupports *closure)
629 nsCOMPtr<nsIHttpChannel> channel;
630 nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
631 NS_ENSURE_SUCCESS(rv, rv);
633 nsCOMPtr<nsIStreamListener> streamListener;
634 rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
635 nsIWebDAVOperationListener::MAKE_COLLECTION,
636 getter_AddRefs(streamListener));
637 NS_ENSURE_SUCCESS(rv, rv);
639 channel->SetRequestMethod(NS_LITERAL_CSTRING("MKCOL"));
641 #ifdef PR_LOGGING
642 if (LOG_ENABLED()) {
643 nsCOMPtr<nsIURI> uri;
644 channel->GetURI(getter_AddRefs(uri));
645 nsCAutoString spec;
646 uri->GetSpec(spec);
647 LOG(("MKCOL starting for %s", spec.get()));
649 #endif
651 return channel->AsyncOpen(streamListener, channel);
654 NS_IMETHODIMP
655 nsWebDAVService::MoveTo(nsIWebDAVResource *resource,
656 const nsACString &destination,
657 PRBool overwrite,
658 nsIWebDAVOperationListener *listener,
659 nsIInterfaceRequestor *notificationCallbacks,
660 nsISupports *closure)
662 nsCOMPtr<nsIHttpChannel> channel;
663 nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
664 NS_ENSURE_SUCCESS(rv, rv);
666 nsCOMPtr<nsIStreamListener> streamListener;
667 rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
668 nsIWebDAVOperationListener::COPY,
669 getter_AddRefs(streamListener));
670 NS_ENSURE_SUCCESS(rv, rv);
672 channel->SetRequestMethod(NS_LITERAL_CSTRING("MOVE"));
674 if (!overwrite) {
675 channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
676 NS_LITERAL_CSTRING("F"),
677 PR_FALSE);
678 } else {
679 channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
680 NS_LITERAL_CSTRING("F"),
681 PR_FALSE);
684 channel->SetRequestHeader(NS_LITERAL_CSTRING("Destination"),
685 destination, PR_FALSE);
687 #ifdef PR_LOGGING
688 if (LOG_ENABLED()) {
689 nsCOMPtr<nsIURI> uri;
690 channel->GetURI(getter_AddRefs(uri));
691 nsCAutoString spec;
692 uri->GetSpec(spec);
693 LOG(("MOVE starting for %s -> %s", spec.get(),
694 nsCAutoString(destination).get()));
696 #endif
698 return channel->AsyncOpen(streamListener, channel);
701 NS_IMETHODIMP
702 nsWebDAVService::CopyTo(nsIWebDAVResource *resource,
703 const nsACString &destination,
704 PRBool recursive, PRBool overwrite,
705 nsIWebDAVOperationListener *listener,
706 nsIInterfaceRequestor *notificationCallbacks,
707 nsISupports *closure)
710 nsCOMPtr<nsIHttpChannel> channel;
711 nsresult rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel));
712 NS_ENSURE_SUCCESS(rv, rv);
714 nsCOMPtr<nsIStreamListener> streamListener;
715 rv = NS_WD_NewOperationStreamListener(resource, listener, closure,
716 nsIWebDAVOperationListener::COPY,
717 getter_AddRefs(streamListener));
718 NS_ENSURE_SUCCESS(rv, rv);
720 channel->SetRequestMethod(NS_LITERAL_CSTRING("COPY"));
721 if (!overwrite) {
722 channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
723 NS_LITERAL_CSTRING("F"),
724 PR_FALSE);
725 } else {
726 channel->SetRequestHeader(NS_LITERAL_CSTRING("Overwrite"),
727 NS_LITERAL_CSTRING("F"),
728 PR_FALSE);
731 if (recursive) {
732 channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
733 NS_LITERAL_CSTRING("infinity"), PR_FALSE);
734 } else {
735 channel->SetRequestHeader(NS_LITERAL_CSTRING("Depth"),
736 NS_LITERAL_CSTRING("0"), PR_FALSE);
739 channel->SetRequestHeader(NS_LITERAL_CSTRING("Destination"),
740 destination, PR_FALSE);
742 #ifdef PR_LOGGING
743 if (LOG_ENABLED()) {
744 nsCOMPtr<nsIURI> uri;
745 channel->GetURI(getter_AddRefs(uri));
746 nsCAutoString spec;
747 uri->GetSpec(spec);
748 LOG(("COPY starting for %s -> %s", spec.get(),
749 nsCAutoString(destination).get()));
751 #endif
753 return channel->AsyncOpen(streamListener, channel);
757 NS_IMETHODIMP
758 nsWebDAVService::Report(nsIWebDAVResource *resource, nsIDOMDocument *query,
759 PRBool withDepth,
760 nsIWebDAVOperationListener *listener,
761 nsIInterfaceRequestor *notificationCallbacks,
762 nsISupports *closure)
764 nsresult rv;
766 NS_ENSURE_ARG(resource);
767 NS_ENSURE_ARG(query);
768 NS_ENSURE_ARG(listener);
770 nsCOMPtr<nsIDocument> queryDoc = do_QueryInterface(query, &rv);
771 NS_ENSURE_SUCCESS(rv, rv);
773 nsCOMPtr<nsIURI> resourceURI;
774 nsCOMPtr<nsIHttpChannel> channel;
775 rv = ChannelFromResource(resource, notificationCallbacks, getter_AddRefs(channel),
776 getter_AddRefs(resourceURI));
777 if (NS_FAILED(rv))
778 return rv;
780 nsCOMPtr<nsIStreamListener> streamListener =
781 NS_WD_NewReportStreamListener(resource, listener, closure);
782 if (!streamListener)
783 return NS_ERROR_OUT_OF_MEMORY;
785 return SendDocumentToChannel(queryDoc, channel, "REPORT", streamListener,
786 withDepth);
789 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebDAVService)
791 NS_DECL_CLASSINFO(nsWebDAVService)
793 static const nsModuleComponentInfo components[] =
795 { "WebDAV Service", NS_WEBDAVSERVICE_CID, NS_WEBDAVSERVICE_CONTRACTID,
796 nsWebDAVServiceConstructor,
797 NULL, NULL, NULL,
798 NS_CI_INTERFACE_GETTER_NAME(nsWebDAVService),
799 NULL,
800 &NS_CLASSINFO_NAME(nsWebDAVService)
804 NS_IMPL_NSGETMODULE(nsWebDAVService, components)