comparison OrthancFramework/Sources/HttpServer/HttpServer.cpp @ 4232:688435755466

added DELETE in WebDAV, first working virtual filesystem
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 07 Oct 2020 13:00:57 +0200
parents 013d6c6b2387
children ca2a55a62c81
comparison
equal deleted inserted replaced
4231:290ffcb0a147 4232:688435755466
753 else 753 else
754 { 754 {
755 output.AddHeader("DAV", "1,2"); // Necessary for Windows XP 755 output.AddHeader("DAV", "1,2"); // Necessary for Windows XP
756 756
757 #if CIVETWEB_HAS_WEBDAV_WRITING == 1 757 #if CIVETWEB_HAS_WEBDAV_WRITING == 1
758 output.AddHeader("Allow", "GET, PUT, OPTIONS, PROPFIND, HEAD, LOCK, UNLOCK, PROPPATCH, MKCOL"); 758 output.AddHeader("Allow", "GET, PUT, DELETE, OPTIONS, PROPFIND, HEAD, LOCK, UNLOCK, PROPPATCH, MKCOL");
759 #else 759 #else
760 output.AddHeader("Allow", "GET, PUT, OPTIONS, PROPFIND, HEAD"); 760 output.AddHeader("Allow", "GET, PUT, DELETE, OPTIONS, PROPFIND, HEAD");
761 #endif 761 #endif
762 762
763 output.SendStatus(HttpStatus_200_Ok); 763 output.SendStatus(HttpStatus_200_Ok);
764 return true; 764 return true;
765 } 765 }
766 } 766 }
767 else if (method == "GET" || 767 else if (method == "GET" ||
768 method == "PROPFIND" || 768 method == "PROPFIND" ||
769 method == "PROPPATCH" || 769 method == "PROPPATCH" ||
770 method == "PUT" || 770 method == "PUT" ||
771 method == "DELETE" ||
771 method == "HEAD" || 772 method == "HEAD" ||
772 method == "LOCK" || 773 method == "LOCK" ||
773 method == "UNLOCK" || 774 method == "UNLOCK" ||
774 method == "MKCOL") 775 method == "MKCOL")
775 { 776 {
815 "WebDAV PROPFIND at unsupported depth (can only be 0 or 1): " + i->second); 816 "WebDAV PROPFIND at unsupported depth (can only be 0 or 1): " + i->second);
816 } 817 }
817 818
818 std::string answer; 819 std::string answer;
819 820
820 if (depth == 0) 821 MimeType mime;
822 std::string content;
823 boost::posix_time::ptime modificationTime = boost::posix_time::second_clock::universal_time();
824
825 if (bucket->second->IsExistingFolder(path))
821 { 826 {
822 MimeType mime; 827 if (depth == 0)
823 std::string content;
824 boost::posix_time::ptime modificationTime;
825
826 if (bucket->second->IsExistingFolder(path))
827 { 828 {
828 IWebDavBucket::Collection c; 829 IWebDavBucket::Collection c;
829 c.AddResource(new IWebDavBucket::Folder("")); 830 c.AddResource(new IWebDavBucket::Folder(""));
830 c.Format(answer, uri); 831 c.Format(answer, uri, true /* include display name */);
831 } 832 }
832 else if (!path.empty() && 833 else if (depth == 1)
833 bucket->second->GetFileContent(mime, content, modificationTime, path)) 834 {
835 IWebDavBucket::Collection c;
836 c.AddResource(new IWebDavBucket::Folder("")); // Necessary for empty folders
837
838 if (!bucket->second->ListCollection(c, path))
839 {
840 output.SendStatus(HttpStatus_404_NotFound);
841 return true;
842 }
843
844 c.Format(answer, uri, true /* include display name */);
845 }
846 else
847 {
848 throw OrthancException(ErrorCode_InternalError);
849 }
850 }
851 else if (!path.empty() &&
852 bucket->second->GetFileContent(mime, content, modificationTime, path))
853 {
854 if (depth == 0 ||
855 depth == 1)
834 { 856 {
835 std::unique_ptr<IWebDavBucket::File> f(new IWebDavBucket::File(path.back())); 857 std::unique_ptr<IWebDavBucket::File> f(new IWebDavBucket::File(path.back()));
836 f->SetContentLength(content.size()); 858 f->SetContentLength(content.size());
837 f->SetModificationTime(modificationTime); 859 f->SetModificationTime(modificationTime);
838 f->SetMimeType(mime); 860 f->SetMimeType(mime);
844 Toolbox::SplitUriComponents(p, uri); 866 Toolbox::SplitUriComponents(p, uri);
845 if (p.empty()) 867 if (p.empty())
846 { 868 {
847 throw OrthancException(ErrorCode_InternalError); 869 throw OrthancException(ErrorCode_InternalError);
848 } 870 }
871
872 // Nautilus doesn't work on DELETE, if "D:displayname"
873 // is included in the multi-status answer of PROPFIND at depth 1
874 const bool includeDisplayName = (depth == 0);
849 875
850 p.resize(p.size() - 1); 876 p.resize(p.size() - 1);
851 c.Format(answer, Toolbox::FlattenUri(p)); 877 c.Format(answer, Toolbox::FlattenUri(p), includeDisplayName);
852 } 878 }
853 else 879 else
854 { 880 {
855 output.SendStatus(HttpStatus_404_NotFound); 881 throw OrthancException(ErrorCode_InternalError);
856 return true;
857 } 882 }
858 }
859 else if (depth == 1)
860 {
861 IWebDavBucket::Collection c;
862 c.AddResource(new IWebDavBucket::Folder("")); // Necessary for empty folders
863
864 if (!bucket->second->ListCollection(c, path))
865 {
866 output.SendStatus(HttpStatus_404_NotFound);
867 return true;
868 }
869
870 c.Format(answer, uri);
871 } 883 }
872 else 884 else
873 { 885 {
874 throw OrthancException(ErrorCode_InternalError); 886 output.SendStatus(HttpStatus_404_NotFound);
887 return true;
875 } 888 }
876 889
877 output.AddHeader("Content-Type", "application/xml; charset=UTF-8"); 890 output.AddHeader("Content-Type", "application/xml; charset=UTF-8");
878 output.SendStatus(HttpStatus_207_MultiStatus, answer); 891 output.SendStatus(HttpStatus_207_MultiStatus, answer);
879 return true; 892 return true;
949 return true; 962 return true;
950 } 963 }
951 964
952 965
953 /** 966 /**
967 * WebDAV - DELETE
968 **/
969
970 else if (method == "DELETE")
971 {
972 if (bucket->second->DeleteItem(path))
973 {
974 output.SendStatus(HttpStatus_204_NoContent);
975 }
976 else
977 {
978 output.SendStatus(HttpStatus_403_Forbidden);
979 }
980 return true;
981 }
982
983
984 /**
954 * WebDAV - MKCOL 985 * WebDAV - MKCOL
955 **/ 986 **/
956 987
957 else if (method == "MKCOL") 988 else if (method == "MKCOL")
958 { 989 {