├── .gitignore
├── CHANGELOG.md
├── Generate-ReleaseNotes.cmd
├── LICENSE
├── README.md
├── WebDAV-Client-Solution.sln
├── WebDAV-Client-Solution.sln.DotSettings
├── src
└── WebDAV-Client
│ ├── ApiParams
│ ├── CopyParameters.cs
│ ├── DeleteParameters.cs
│ ├── GetFileParameters.cs
│ ├── LockParameters.cs
│ ├── MkColParameters.cs
│ ├── MoveParameters.cs
│ ├── PropfindParameters.cs
│ ├── ProppatchParameters.cs
│ ├── PutFileParameters.cs
│ ├── RequestParameters.cs
│ ├── UnlockParameters.cs
│ └── WebDavClientParams.cs
│ ├── Domain
│ ├── ActiveLock.cs
│ ├── ApplyTo.cs
│ ├── LockOwner.cs
│ ├── LockScope.cs
│ ├── NamespaceAttr.cs
│ ├── PrincipalLockOwner.cs
│ ├── UriLockOwner.cs
│ ├── WebDavMethod.cs
│ ├── WebDavProperty.cs
│ ├── WebDavPropertyStatus.cs
│ └── WebDavResource.cs
│ ├── Extensions
│ ├── LinqToXmlExtensions.cs
│ └── XDocumentExtensions.cs
│ ├── Helpers
│ ├── DepthHeaderHelper.cs
│ └── IfHeaderHelper.cs
│ ├── Infrastructure
│ ├── HttpResponse.cs
│ ├── IWebDavDispatcher.cs
│ └── WebDavDispatcher.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Request
│ ├── LockRequestBuilder.cs
│ ├── PropfindRequestBuilder.cs
│ └── ProppatchRequestBuilder.cs
│ ├── Response
│ ├── IResponseParser.cs
│ ├── LockResponse.cs
│ ├── LockResponseParser.cs
│ ├── MultiStatusParser.cs
│ ├── PropertyValueParser.cs
│ ├── PropfindResponse.cs
│ ├── PropfindResponseParser.cs
│ ├── ProppatchResponse.cs
│ ├── ProppatchResponseParser.cs
│ ├── ResourceType.cs
│ ├── WebDavResponse.cs
│ └── WebDavStreamResponse.cs
│ ├── System.ComponentModel
│ └── InvalidEnumArgumentException.cs
│ ├── System
│ └── RuntimeUtils.cs
│ ├── Validation
│ ├── Check.cs
│ └── CoreStrings.cs
│ ├── WebDAV-Client.csproj
│ └── WebDavClient.cs
└── test
├── WebDAV-Client.Tests.Net452
├── Infrastructure
│ └── WebDavDispatcherTests.cs
├── Properties
│ └── AssemblyInfo.cs
├── Response
│ ├── LockResponseParserTests.cs
│ ├── PropfindResponseParserTests.cs
│ └── ProppatchResponseParserTests.cs
├── Responses.cs
├── TestDoubles
│ └── Dispatcher.cs
├── WebDAV-Client.Tests.Net452.csproj
├── WebDavClientTests
│ ├── CopyTests.cs
│ ├── DeleteTests.cs
│ ├── GetFileTests.cs
│ ├── LockTests.cs
│ ├── MkcolTests.cs
│ ├── MoveTests.cs
│ ├── Predicates.cs
│ ├── PropfindTests.cs
│ ├── ProppatchTests.cs
│ ├── PutFileTests.cs
│ └── UnlockTests.cs
└── packages.config
└── WebDAV-Client.Tests
└── WebDAV-Client.Tests.csproj
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 | *.VC.VC.opendb
85 |
86 | # Visual Studio profiler
87 | *.psess
88 | *.vsp
89 | *.vspx
90 | *.sap
91 |
92 | # TFS 2012 Local Workspace
93 | $tf/
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 | *.DotSettings.user
102 |
103 | # JustCode is a .NET coding add-in
104 | .JustCode
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | _NCrunch_*
114 | .*crunch*.local.xml
115 | nCrunchTemp_*
116 |
117 | # MightyMoose
118 | *.mm.*
119 | AutoTest.Net/
120 |
121 | # Web workbench (sass)
122 | .sass-cache/
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.[Pp]ublish.xml
142 | *.azurePubxml
143 | # TODO: Comment the next line if you want to checkin your web deploy settings
144 | # but database connection strings (with potential passwords) will be unencrypted
145 | *.pubxml
146 | *.publishproj
147 |
148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
149 | # checkin your Azure Web App publish settings, but sensitive information contained
150 | # in these scripts will be unencrypted
151 | PublishScripts/
152 |
153 | # NuGet Packages
154 | *.nupkg
155 | # The packages folder can be ignored because of Package Restore
156 | **/packages/*
157 | # except build/, which is used as an MSBuild target.
158 | !**/packages/build/
159 | # Uncomment if necessary however generally it will be regenerated when needed
160 | #!**/packages/repositories.config
161 | # NuGet v3's project.json files produces more ignoreable files
162 | *.nuget.props
163 | *.nuget.targets
164 |
165 | # Microsoft Azure Build Output
166 | csx/
167 | *.build.csdef
168 |
169 | # Microsoft Azure Emulator
170 | ecf/
171 | rcf/
172 |
173 | # Windows Store app package directories and files
174 | AppPackages/
175 | BundleArtifacts/
176 | Package.StoreAssociation.xml
177 | _pkginfo.txt
178 |
179 | # Visual Studio cache files
180 | # files ending in .cache can be ignored
181 | *.[Cc]ache
182 | # but keep track of directories ending in .cache
183 | !*.[Cc]ache/
184 |
185 | # Others
186 | ClientBin/
187 | ~$*
188 | *~
189 | *.dbmdl
190 | *.dbproj.schemaview
191 | *.pfx
192 | *.publishsettings
193 | node_modules/
194 | orleans.codegen.cs
195 |
196 | # Since there are multiple workflows, uncomment next line to ignore bower_components
197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198 | #bower_components/
199 |
200 | # RIA/Silverlight projects
201 | Generated_Code/
202 |
203 | # Backup & report files from converting an old project file
204 | # to a newer Visual Studio version. Backup files are not needed,
205 | # because we have git ;-)
206 | _UpgradeReport_Files/
207 | Backup*/
208 | UpgradeLog*.XML
209 | UpgradeLog*.htm
210 |
211 | # SQL Server files
212 | *.mdf
213 | *.ldf
214 |
215 | # Business Intelligence projects
216 | *.rdl.data
217 | *.bim.layout
218 | *.bim_*.settings
219 |
220 | # Microsoft Fakes
221 | FakesAssemblies/
222 |
223 | # GhostDoc plugin setting file
224 | *.GhostDoc.xml
225 |
226 | # Node.js Tools for Visual Studio
227 | .ntvs_analysis.dat
228 |
229 | # Visual Studio 6 build log
230 | *.plg
231 |
232 | # Visual Studio 6 workspace options file
233 | *.opt
234 |
235 | # Visual Studio LightSwitch build output
236 | **/*.HTMLClient/GeneratedArtifacts
237 | **/*.DesktopClient/GeneratedArtifacts
238 | **/*.DesktopClient/ModelManifest.xml
239 | **/*.Server/GeneratedArtifacts
240 | **/*.Server/ModelManifest.xml
241 | _Pvt_Extensions
242 |
243 | # Paket dependency manager
244 | .paket/paket.exe
245 | paket-files/
246 |
247 | # FAKE - F# Make
248 | .fake/
249 |
250 | # JetBrains Rider
251 | .idea/
252 | *.sln.iml
253 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.1.2 (04 February 2023)
2 | - [#8](https://github.com/StefH/WebDAV-Client/pull/8) - Bump System.Net.Http from 4.3.0 to 4.3.4 in /src/WebDAV-Client [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
3 | - [#12](https://github.com/StefH/WebDAV-Client/pull/12) - Add net6.0 and net7.0 [enhancement] contributed by [StefH](https://github.com/StefH)
4 | - [#11](https://github.com/StefH/WebDAV-Client/issues/11) - PlatformNotSupportedException on Blazor Webassembly / WASM [bug]
5 |
6 | # 1.1.0.0 (02 May 2020)
7 | - [#6](https://github.com/StefH/WebDAV-Client/pull/6) - Fixes for Blazor WASM [bug] contributed by [StefH](https://github.com/StefH)
8 | - [#4](https://github.com/StefH/WebDAV-Client/issues/4) - Upgrade project to VS2017
9 |
10 | # 1.0.3.0 (22 August 2018)
11 | - [#5](https://github.com/StefH/WebDAV-Client/pull/5) - Upgrade to VS2017 and update TargetFrameworks contributed by [StefH](https://github.com/StefH)
12 | - [#2](https://github.com/StefH/WebDAV-Client/issues/2) - Content-Type is set to text/plain when sending XML [bug, enhancement]
13 |
14 | # 1.0.2.0 (06 March 2017)
15 | - [#1](https://github.com/StefH/WebDAV-Client/issues/1) - Add support for using a custom HttpClient or HttpMessageHandler [enhancement]
16 |
17 |
--------------------------------------------------------------------------------
/Generate-ReleaseNotes.cmd:
--------------------------------------------------------------------------------
1 | rem https://github.com/StefH/GitHubReleaseNotes
2 |
3 | SET version=1.1.2
4 |
5 | GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Stef Heyenrath
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WebDAV-Client
2 | An easy-to-use async WebDAV client for .NET, .NETStandard, UAP and Portable based on https://github.com/skazantsev/WebDavClient.
3 |
4 | [](https://www.nuget.org/packages/WebDAV-Client)
5 |
6 | #### Supported Frameworks
7 | - .NET Framework 4.5 and 4.6
8 | - .NET Standard 1.1, 2.0 and 2.1
9 | - .NET 6.0 and 7.0
10 | - Blazor WASM
11 | - Portable (Profile7, Profile32, Profile44, Profile111, Profile115). See [portablelibraryprofiles](https://portablelibraryprofiles.stephencleary.com/).
12 |
13 | #### Basic usage
14 | ``` csharp
15 | using (var webDavClient = new WebDavClient())
16 | {
17 | var result = await webDavClient.Propfind("http://mywebdav/1.txt");
18 | if (result.IsSuccessful)
19 | // continue ...
20 | else
21 | // handle an error
22 | }
23 | ```
24 |
25 | #### Usage in Blazor WASM
26 | See https://github.com/StefH/WebDAV-AudioPlayer/tree/master/src/Blazor-WebDAV-AudioPlayer.v2
27 |
28 | #### Using BaseAddress
29 | ``` csharp
30 | var clientParams = new WebDavClientParams { BaseAddress = new Uri("http://mywebdav/") };
31 | using (var webDavClient = new WebDavClient(clientParams))
32 | {
33 | await webDavClient.Propfind("1.txt");
34 | }
35 | ```
36 |
37 | #### Operations with files and directories (resources & collections)
38 | ``` csharp
39 | var clientParams = new WebDavClientParams { BaseAddress = new Uri("http://mywebdav/") };
40 | using (var webDavClient = new WebDavClient(clientParams))
41 | {
42 | await webDavClient.Mkcol("mydir"); // create a directory
43 |
44 | await webDavClient.Copy("source.txt", "dest.txt"); // copy a file
45 |
46 | await webDavClient.Move("source.txt", "dest.txt"); // move a file
47 |
48 | await webDavClient.Delete("file.txt", "dest.txt"); // delete a file
49 |
50 | await webDavClient.GetRawFile("file.txt"); // get a file without processing from the server
51 |
52 | await webDavClient.GetProcessedFile("file.txt"); // get a file that can be processed by the server
53 |
54 | await webDavClient.PutFile("file.xml", File.OpenRead("file.xml"), "text/xml"); // upload a resource
55 | }
56 | ```
57 |
58 | #### PROPFIND example
59 | ``` csharp
60 | // list files & subdirectories in 'mydir'
61 | var result = await webDavClient.Propfind("http://mywebdav/mydir");
62 | if (result.IsSuccessful)
63 | {
64 | foreach (var res in result.Resources)
65 | {
66 | Trace.WriteLine("Name: " + res.DisplayName);
67 | Trace.WriteLine("Is directory: " + res.IsCollection);
68 | // other params
69 | }
70 | }
71 | ```
72 |
73 | #### Authentication example
74 | ``` csharp
75 | var clientParams = new WebDavClientParams
76 | {
77 | BaseAddress = new Uri("http://mywebdav/"),
78 | Credentials = new NetworkCredential("user", "12345")
79 | };
80 | using (var webDavClient = new WebDavClient(clientParams))
81 | {
82 | // call webdav methods...
83 | }
84 | ```
85 |
86 | #### License
87 | WebDAV-Client is licensed under the MIT License.
88 |
--------------------------------------------------------------------------------
/WebDAV-Client-Solution.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33213.308
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F3674172-2C87-4529-8B3B-D4047ED5F1C3}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{570FF30A-3A31-43E4-A8C3-56610FA26DFA}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Solution Items", "_Solution Items", "{7898F0E5-AE83-4BE9-B8D9-BBD92A4858DF}"
11 | ProjectSection(SolutionItems) = preProject
12 | appveyor.yml = appveyor.yml
13 | CHANGELOG.md = CHANGELOG.md
14 | Generate-ReleaseNotes.cmd = Generate-ReleaseNotes.cmd
15 | README.md = README.md
16 | EndProjectSection
17 | EndProject
18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{049FB370-482F-40A4-A38B-81E600E98775}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebDAV-Client", "src\WebDAV-Client\WebDAV-Client.csproj", "{7C2D4AAD-02B1-4E29-9C10-F397482DC6FC}"
21 | EndProject
22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebDAV-Client.Tests", "test\WebDAV-Client.Tests\WebDAV-Client.Tests.csproj", "{9C2BF524-C306-4C94-BAC9-2E4ED06B8943}"
23 | EndProject
24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebDAV-Client.Tests.Net452", "test\WebDAV-Client.Tests.Net452\WebDAV-Client.Tests.Net452.csproj", "{DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D}"
25 | ProjectSection(ProjectDependencies) = postProject
26 | {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC} = {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC}
27 | EndProjectSection
28 | EndProject
29 | Global
30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
31 | Debug|Any CPU = Debug|Any CPU
32 | Release|Any CPU = Release|Any CPU
33 | EndGlobalSection
34 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
35 | {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {9C2BF524-C306-4C94-BAC9-2E4ED06B8943}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {9C2BF524-C306-4C94-BAC9-2E4ED06B8943}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {9C2BF524-C306-4C94-BAC9-2E4ED06B8943}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {9C2BF524-C306-4C94-BAC9-2E4ED06B8943}.Release|Any CPU.Build.0 = Release|Any CPU
43 | {DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44 | {DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D}.Debug|Any CPU.Build.0 = Debug|Any CPU
45 | {DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 | {DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D}.Release|Any CPU.Build.0 = Release|Any CPU
47 | EndGlobalSection
48 | GlobalSection(SolutionProperties) = preSolution
49 | HideSolutionNode = FALSE
50 | EndGlobalSection
51 | GlobalSection(NestedProjects) = preSolution
52 | {7C2D4AAD-02B1-4E29-9C10-F397482DC6FC} = {F3674172-2C87-4529-8B3B-D4047ED5F1C3}
53 | {9C2BF524-C306-4C94-BAC9-2E4ED06B8943} = {570FF30A-3A31-43E4-A8C3-56610FA26DFA}
54 | {DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D} = {570FF30A-3A31-43E4-A8C3-56610FA26DFA}
55 | EndGlobalSection
56 | GlobalSection(ExtensibilityGlobals) = postSolution
57 | SolutionGuid = {A8E50C61-508C-4512-B7A6-02E1C9D34AC4}
58 | EndGlobalSection
59 | EndGlobal
60 |
--------------------------------------------------------------------------------
/WebDAV-Client-Solution.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | True
4 | True
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/CopyParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents parameters for the COPY WebDAV method.
7 | ///
8 | public class CopyParameters
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public CopyParameters()
14 | {
15 | Overwrite = true;
16 | CancellationToken = CancellationToken.None;
17 | }
18 |
19 | ///
20 | /// Gets or sets a value indicating whether the method is to be applied only to the resource or the resource and all its members.
21 | /// It corresponds to the WebDAV Depth header.
22 | ///
23 | public ApplyTo.Copy? ApplyTo { get; set; }
24 |
25 | ///
26 | /// Gets or sets the lock token for the destination resource.
27 | ///
28 | public string DestLockToken { get; set; }
29 |
30 | ///
31 | /// Gets or sets a value indicating whether the server should overwrite a non-null destination.
32 | /// For more information see https://msdn.microsoft.com/en-us/library/aa142944.
33 | ///
34 | ///
35 | /// true if the the server should overwrite a non-null destination; otherwise false. The default value is true.
36 | ///
37 | public bool Overwrite { get; set; }
38 |
39 | ///
40 | /// Gets or sets the cancellation token.
41 | ///
42 | public CancellationToken CancellationToken { get; set; }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/DeleteParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents parameters for the DELETE WebDAV method.
7 | ///
8 | public class DeleteParameters
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public DeleteParameters()
14 | {
15 | CancellationToken = CancellationToken.None;
16 | }
17 |
18 | ///
19 | /// Gets or sets the resource lock token.
20 | ///
21 | public string LockToken { get; set; }
22 |
23 | ///
24 | /// Gets or sets the cancellation token.
25 | ///
26 | public CancellationToken CancellationToken { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/GetFileParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents parameters for the GET WebDAV method.
7 | ///
8 | public class GetFileParameters
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public GetFileParameters()
14 | {
15 | CancellationToken = CancellationToken.None;
16 | }
17 |
18 | ///
19 | /// Gets or sets the cancellation token.
20 | ///
21 | public CancellationToken CancellationToken { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/LockParameters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace WebDav
5 | {
6 | ///
7 | /// Represents parameters for the LOCK WebDAV method.
8 | ///
9 | public class LockParameters
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | public LockParameters()
15 | {
16 | CancellationToken = CancellationToken.None;
17 | }
18 |
19 | ///
20 | /// Gets or sets a value indicating whether this lock is an exclusive lock or a shared lock.
21 | ///
22 | public LockScope LockScope { get; set; }
23 |
24 | ///
25 | /// Gets or sets the timeout of this lock.
26 | ///
27 | public TimeSpan? Timeout { get; set; }
28 |
29 | ///
30 | /// Gets or sets a value indicating whether the method is to be applied only to the resource or the resource and all its members.
31 | /// It corresponds to the WebDAV Depth header.
32 | ///
33 | public ApplyTo.Lock? ApplyTo { get; set; }
34 |
35 | ///
36 | /// Gets or sets the owner of this lock.
37 | ///
38 | public LockOwner Owner { get; set; }
39 |
40 | ///
41 | /// Gets or sets the cancellation token.
42 | ///
43 | public CancellationToken CancellationToken { get; set; }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/MkColParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents parameters for the MKCOL WebDAV method.
7 | ///
8 | public class MkColParameters
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public MkColParameters()
14 | {
15 | CancellationToken = CancellationToken.None;
16 | }
17 |
18 | ///
19 | /// Gets or sets the resource lock token.
20 | ///
21 | public string LockToken { get; set; }
22 |
23 | ///
24 | /// Gets or sets the cancellation token.
25 | ///
26 | public CancellationToken CancellationToken { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/MoveParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents parameters for the MOVE WebDAV method.
7 | ///
8 | public class MoveParameters
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public MoveParameters()
14 | {
15 | Overwrite = true;
16 | CancellationToken = CancellationToken.None;
17 | }
18 |
19 | ///
20 | /// Gets or sets the lock token for the moving resource.
21 | ///
22 | public string SourceLockToken { get; set; }
23 |
24 | ///
25 | /// Gets or sets the lock token for the destination resource.
26 | ///
27 | public string DestLockToken { get; set; }
28 |
29 | ///
30 | /// Gets or sets a value indicating whether the server should overwrite a non-null destination.
31 | /// For more information see https://msdn.microsoft.com/en-us/library/aa142944.
32 | ///
33 | ///
34 | /// true if the the server should overwrite a non-null destination; otherwise false. The default value is true.
35 | ///
36 | public bool Overwrite { get; set; }
37 |
38 | ///
39 | /// Gets or sets the cancellation token.
40 | ///
41 | public CancellationToken CancellationToken { get; set; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/PropfindParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Xml.Linq;
4 |
5 | namespace WebDav
6 | {
7 | ///
8 | /// Represents parameters for the PROPFIND WebDAV method.
9 | ///
10 | public class PropfindParameters
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | public PropfindParameters()
16 | {
17 | CustomProperties = new List();
18 | Namespaces = new List();
19 | CancellationToken = CancellationToken.None;
20 | }
21 |
22 | ///
23 | /// Gets or sets the collection of custom properties (or dead properties in terms of WebDav).
24 | ///
25 | public IReadOnlyCollection CustomProperties { get; set; }
26 |
27 | ///
28 | /// Gets or sets the collection of xml namespaces of properties.
29 | ///
30 | public IReadOnlyCollection Namespaces { get; set; }
31 |
32 | ///
33 | /// Gets or sets a value indicating whether the method is to be applied only to the resource, to the resource and its internal members only, or the resource and all its members.
34 | /// It corresponds to the WebDAV Depth header.
35 | ///
36 | public ApplyTo.Propfind? ApplyTo { get; set; }
37 |
38 | ///
39 | /// Gets or sets the cancellation token.
40 | ///
41 | public CancellationToken CancellationToken { get; set; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/ProppatchParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Xml.Linq;
4 |
5 | namespace WebDav
6 | {
7 | ///
8 | /// Represents parameters for the PROPPATCH WebDAV method.
9 | ///
10 | public class ProppatchParameters
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | public ProppatchParameters()
16 | {
17 | PropertiesToSet = new Dictionary();
18 | PropertiesToRemove = new List();
19 | Namespaces = new List();
20 | CancellationToken = CancellationToken.None;
21 | }
22 |
23 | ///
24 | /// Gets or sets properties to set on the resource.
25 | ///
26 | public IDictionary PropertiesToSet { get; set; }
27 |
28 | ///
29 | /// Gets or sets the collection of properties defined on the resource to remove.
30 | ///
31 | public IReadOnlyCollection PropertiesToRemove { get; set; }
32 |
33 | ///
34 | /// Gets or sets the collection of xml namespaces of properties.
35 | ///
36 | public IReadOnlyCollection Namespaces { get; set; }
37 |
38 | ///
39 | /// Gets or sets the cancellation token.
40 | ///
41 | public CancellationToken CancellationToken { get; set; }
42 |
43 | ///
44 | /// Gets or sets the resource lock token.
45 | ///
46 | public string LockToken { get; set; }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/PutFileParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents parameters for the PUT WebDAV method.
7 | ///
8 | public class PutFileParameters
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public PutFileParameters()
14 | {
15 | ContentType = "application/octet-stream";
16 | CancellationToken = CancellationToken.None;
17 | }
18 |
19 | ///
20 | /// Gets or sets the content type of the request body.
21 | /// The default value is application/octet-stream.
22 | ///
23 | public string ContentType { get; set; }
24 |
25 | ///
26 | /// Gets or sets the resource lock token.
27 | ///
28 | public string LockToken { get; set; }
29 |
30 | ///
31 | /// Gets or sets the cancellation token.
32 | ///
33 | public CancellationToken CancellationToken { get; set; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/RequestParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Net.Http;
3 |
4 | namespace WebDav
5 | {
6 | internal class RequestParameters
7 | {
8 | public RequestParameters()
9 | {
10 | Headers = new List>();
11 | }
12 |
13 | public IReadOnlyCollection> Headers { get; set; }
14 |
15 | public HttpContent Content { get; set; }
16 |
17 | public string ContentType { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/UnlockParameters.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using JetBrains.Annotations;
3 |
4 | namespace WebDav
5 | {
6 | ///
7 | /// Represents parameters for the UNLOCK WebDAV method.
8 | ///
9 | public class UnlockParameters
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | /// The resource lock token.
14 | ///
15 | public UnlockParameters([NotNull] string lockToken)
16 | {
17 | Check.NotNull(lockToken, nameof(lockToken));
18 |
19 | LockToken = lockToken;
20 | CancellationToken = CancellationToken.None;
21 | }
22 |
23 | ///
24 | /// Gets the resource lock token.
25 | ///
26 | public string LockToken { get; private set; }
27 |
28 | ///
29 | /// Gets or sets the cancellation token.
30 | ///
31 | public CancellationToken CancellationToken { get; set; }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/ApiParams/WebDavClientParams.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 | using System.Net.Http;
5 |
6 | namespace WebDav
7 | {
8 | ///
9 | /// Represents parameters for the class.
10 | ///
11 | public class WebDavClientParams
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | public WebDavClientParams()
17 | {
18 | UseDefaultCredentials = true;
19 | DefaultRequestHeaders = new Dictionary();
20 | Timeout = TimeSpan.FromMilliseconds(-1); // Infinite timespan is nothing but TimeSpan with milliseconds set to -1
21 | UseProxy = true;
22 | PreAuthenticate = true;
23 | }
24 |
25 | ///
26 | /// Gets or sets the HTTP message handler. Note that this overrides some other properties in this class like:
27 | /// - PreAuthenticate
28 | /// - UseDefaultCredentials
29 | /// - UseProxy
30 | /// - Credentials
31 | /// - Proxy
32 | ///
33 | public HttpMessageHandler HttpMessageHandler { get; set; }
34 |
35 | ///
36 | /// Gets or sets a value that controls whether default credentials are sent.
37 | ///
38 | ///
39 | /// true if the default credentials are used; otherwise false. The default value is true.
40 | ///
41 | public bool UseDefaultCredentials { get; set; }
42 |
43 | ///
44 | /// Gets or sets the base address of the resource's URI used when sending requests.
45 | ///
46 | public Uri BaseAddress { get; set; }
47 |
48 | ///
49 | /// Gets or sets authentication information used by the WebDavClient.
50 | ///
51 | public ICredentials Credentials { get; set; }
52 |
53 | ///
54 | /// Gets or sets the headers which should be sent with each request.
55 | ///
56 | public IDictionary DefaultRequestHeaders { get; set; }
57 |
58 | ///
59 | /// Gets or sets a value that indicates whether an Authorization header should be sent with the request.
60 | ///
61 | ///
62 | /// true if an HTTP Authorization header should be send with requests after authentication has taken place; otherwise, false. The default value is true.
63 | ///
64 | public bool PreAuthenticate { get; set; }
65 |
66 | ///
67 | /// Gets or sets proxy information used by the WebDavClient.
68 | ///
69 | public IWebProxy Proxy { get; set; }
70 |
71 | ///
72 | /// Gets or sets a timeout for WebDAV operations.
73 | ///
74 | public TimeSpan Timeout { get; set; }
75 |
76 | ///
77 | /// Gets or sets a value indicating whether a proxy should be used for requests.
78 | ///
79 | ///
80 | /// true if a proxy should be used for requests; otherwise, false. The default value is true.
81 | ///
82 | public bool UseProxy { get; set; }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/ActiveLock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents an active lock taken on a WebDAV resource.
7 | ///
8 | public class ActiveLock
9 | {
10 | private ActiveLock()
11 | {
12 | }
13 |
14 | ///
15 | /// Gets a value indicating whether the lock is to be applied only to the resource or the resource and all its members.
16 | /// It corresponds to the WebDAV Depth header.
17 | ///
18 | public ApplyTo.Lock? ApplyTo { get; private set; }
19 |
20 | ///
21 | /// Gets a value indicating whether this lock is an exclusive lock or a shared lock.
22 | ///
23 | public LockScope? LockScope { get; private set; }
24 |
25 | ///
26 | /// Gets the resource lock token.
27 | ///
28 | public string LockToken { get; private set; }
29 |
30 | ///
31 | /// Gets the owner of this lock.
32 | ///
33 | public LockOwner Owner { get; private set; }
34 |
35 | ///
36 | /// Gets the root URL of the lock, which is the URL through which the resource was addressed in the LOCK request.
37 | ///
38 | public string LockRoot { get; private set; }
39 |
40 | ///
41 | /// Gets the duration of this lock.
42 | ///
43 | public TimeSpan? Timeout { get; private set; }
44 |
45 | ///
46 | /// Represents a builder of the class.
47 | ///
48 | public class Builder
49 | {
50 | private ApplyTo.Lock? _applyTo;
51 | private LockScope? _lockScope;
52 | private string _lockToken;
53 | private LockOwner _owner;
54 | private string _lockRoot;
55 | private TimeSpan? _timeout;
56 |
57 | ///
58 | /// Sets the ApplyTo parameter of an instance of the class.
59 | ///
60 | public Builder WithApplyTo(ApplyTo.Lock? applyTo)
61 | {
62 | _applyTo = applyTo;
63 | return this;
64 | }
65 |
66 | ///
67 | /// Sets the LockTo parameter of an instance of the class.
68 | ///
69 | public Builder WithLockScope(LockScope? lockScope)
70 | {
71 | _lockScope = lockScope;
72 | return this;
73 | }
74 |
75 | ///
76 | /// Sets the LockToken parameter of an instance of the class.
77 | ///
78 | public Builder WithLockToken(string lockToken)
79 | {
80 | _lockToken = lockToken;
81 | return this;
82 | }
83 |
84 | ///
85 | /// Sets the Owner parameter of an instance of the class.
86 | ///
87 | public Builder WithOwner(LockOwner owner)
88 | {
89 | _owner = owner;
90 | return this;
91 | }
92 |
93 | ///
94 | /// Sets the LockRoot parameter of an instance of the class.
95 | ///
96 | public Builder WithLockRoot(string lockRoot)
97 | {
98 | _lockRoot = lockRoot;
99 | return this;
100 | }
101 |
102 | ///
103 | /// Sets the Timeout parameter of an instance of the class.
104 | ///
105 | public Builder WithTimeout(TimeSpan? timeout)
106 | {
107 | _timeout = timeout;
108 | return this;
109 | }
110 |
111 | ///
112 | /// Builds a new instance of the class.
113 | ///
114 | /// A new instance of the class.
115 | public ActiveLock Build()
116 | {
117 | return new ActiveLock
118 | {
119 | ApplyTo = _applyTo,
120 | LockScope = _lockScope,
121 | LockToken = _lockToken,
122 | Owner = _owner,
123 | LockRoot = _lockRoot,
124 | Timeout = _timeout
125 | };
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/ApplyTo.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav
2 | {
3 | ///
4 | /// Contains classes to specify AppltTo for concrete methods.
5 | ///
6 | public static class ApplyTo
7 | {
8 | ///
9 | /// Specifies whether the PROPFIND method is to be applied only to the resource, to the resource and its internal members only, or the resource and all its members.
10 | /// It corresponds to the WebDAV Depth header.
11 | ///
12 | public enum Propfind
13 | {
14 | ResourceOnly,
15 | ResourceAndChildren,
16 | ResourceAndAncestors
17 | }
18 |
19 | ///
20 | /// Specifies whether the COPY method is to be applied only to the resource or the resource and all its members.
21 | /// It corresponds to the WebDAV Depth header.
22 | ///
23 | public enum Copy
24 | {
25 | ResourceOnly,
26 | ResourceAndAncestors
27 | }
28 |
29 | ///
30 | /// Specifies whether the LOCK method is to be applied only to the resource or the resource and all its members.
31 | /// It corresponds to the WebDAV Depth header.
32 | ///
33 | public enum Lock
34 | {
35 | ResourceOnly,
36 | ResourceAndAncestors
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/LockOwner.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav
2 | {
3 | ///
4 | /// Represents a lock owner.
5 | ///
6 | public abstract class LockOwner
7 | {
8 | ///
9 | /// Gets a value representing an owner.
10 | ///
11 | public abstract string Value { get; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/LockScope.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav
2 | {
3 | ///
4 | /// Specifies a type of lock - exclusive or shared.
5 | ///
6 | public enum LockScope
7 | {
8 | Shared,
9 | Exclusive
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/NamespaceAttr.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav
2 | {
3 | ///
4 | /// Represents an xml namespace attribute.
5 | ///
6 | public class NamespaceAttr
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The default namespace.
12 | public NamespaceAttr(string defaultNamespace)
13 | {
14 | Namespace = defaultNamespace;
15 | }
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// The prefix of the namespace
21 | /// The namespace in form of URI specified at an xmlns attribute
22 | public NamespaceAttr(string prefix, string @namespace)
23 | {
24 | Prefix = prefix;
25 | Namespace = @namespace;
26 | }
27 |
28 | ///
29 | /// Gets the prefix of this namespace.
30 | ///
31 | public string Prefix { get; private set; }
32 |
33 | ///
34 | /// Gets the namespace in form of URI specified at an xmlns attribute as follows. xmlns:prefix="URI".
35 | ///
36 | public string Namespace { get; private set; }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/PrincipalLockOwner.cs:
--------------------------------------------------------------------------------
1 | using JetBrains.Annotations;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents a lock owner identified by principal name.
7 | ///
8 | public class PrincipalLockOwner : LockOwner
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// Name of the principal.
14 | public PrincipalLockOwner([NotNull] string principalName)
15 | {
16 | Check.NotNull(principalName, nameof(principalName));
17 | Value = principalName;
18 | }
19 |
20 | ///
21 | /// Gets a value representing an owner.
22 | ///
23 | public override string Value { get; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/UriLockOwner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents a lock owner identified by URI.
7 | ///
8 | public class UriLockOwner : LockOwner
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The absolute URI.
14 | /// The parameter uri should be a valid absolute uri.;absoluteUri
15 | public UriLockOwner(string absoluteUri)
16 | {
17 | if (!Uri.IsWellFormedUriString(absoluteUri, UriKind.Absolute))
18 | throw new ArgumentException("The parameter uri should be a valid absolute uri.", nameof(absoluteUri));
19 | Value = absoluteUri;
20 | }
21 |
22 | ///
23 | /// Gets a value representing an owner.
24 | ///
25 | public override string Value { get; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/WebDavMethod.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http;
2 |
3 | namespace WebDav
4 | {
5 | internal static class WebDavMethod
6 | {
7 | public static readonly HttpMethod Propfind = new HttpMethod("PROPFIND");
8 |
9 | public static readonly HttpMethod Proppatch = new HttpMethod("PROPPATCH");
10 |
11 | public static readonly HttpMethod Mkcol = new HttpMethod("MKCOL");
12 |
13 | public static readonly HttpMethod Copy = new HttpMethod("COPY");
14 |
15 | public static readonly HttpMethod Move = new HttpMethod("MOVE");
16 |
17 | public static readonly HttpMethod Lock = new HttpMethod("LOCK");
18 |
19 | public static readonly HttpMethod Unlock = new HttpMethod("UNLOCK");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/WebDavProperty.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents a WebDAV resource property.
7 | ///
8 | public class WebDavProperty
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The property name.
14 | /// The property value.
15 | public WebDavProperty(XName name, string value)
16 | {
17 | Check.NotEmpty((name ?? "").ToString(), nameof(name));
18 |
19 | Name = name;
20 | Value = value;
21 | }
22 |
23 | ///
24 | /// Gets the property name.
25 | ///
26 | public XName Name { get; private set; }
27 |
28 | ///
29 | /// Gets the property value.
30 | ///
31 | public string Value { get; private set; }
32 |
33 | public override string ToString()
34 | {
35 | return string.Format("{{ Name: {0}, Value: {1} }}", Name, Value);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/WebDavPropertyStatus.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents a status of an operation on a resource property.
7 | ///
8 | public class WebDavPropertyStatus
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The property name.
14 | /// The status code of the operation.
15 | public WebDavPropertyStatus(XName name, int statusCode)
16 | :this (name, statusCode, null)
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The property name.
24 | /// The status code of the operation.
25 | /// The description of the operation.
26 | public WebDavPropertyStatus(XName name, int statusCode, string description)
27 | {
28 | Check.NotEmpty((name ?? "").ToString(), nameof(name));
29 |
30 | Name = name;
31 | StatusCode = statusCode;
32 | Description = description;
33 | }
34 |
35 | ///
36 | /// Gets the property name.
37 | ///
38 | public XName Name { get; private set; }
39 |
40 | ///
41 | /// Gets the status code of the operation.
42 | ///
43 | public int StatusCode { get; private set; }
44 |
45 | ///
46 | /// Gets the description of the operation.
47 | ///
48 | public string Description { get; private set; }
49 |
50 | ///
51 | /// Gets a value indicating whether the operation on the property was successful.
52 | ///
53 | ///
54 | /// true if the operation was successfull; otherwise, false.
55 | ///
56 | public virtual bool IsSuccessful => StatusCode >= 200 && StatusCode <= 299;
57 |
58 | public override string ToString()
59 | {
60 | return string.Format("{{ Name: {0}, StatusCode: {1}, Description: {2} }}", Name, StatusCode, Description);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Domain/WebDavResource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using JetBrains.Annotations;
4 |
5 | namespace WebDav
6 | {
7 | ///
8 | /// Represents a WebDAV resource.
9 | ///
10 | public class WebDavResource
11 | {
12 | ///
13 | /// Prevents a default instance of the class from being created.
14 | ///
15 | private WebDavResource()
16 | {
17 | Properties = new List();
18 | PropertyStatuses = new List();
19 | }
20 |
21 | ///
22 | /// Gets a collection locks on this resource.
23 | ///
24 | public IReadOnlyCollection ActiveLocks { get; private set; }
25 |
26 | ///
27 | /// Gets the content language of this resource.
28 | ///
29 | public string ContentLanguage { get; private set; }
30 |
31 | ///
32 | /// Gets the content length of this resource.
33 | ///
34 | public int? ContentLength { get; private set; }
35 |
36 | ///
37 | /// Gets the content type of this resource.
38 | ///
39 | public string ContentType { get; private set; }
40 |
41 | ///
42 | /// Gets the creation date of this resource.
43 | ///
44 | public DateTime? CreationDate { get; private set; }
45 |
46 | ///
47 | /// Gets the display name of this resource.
48 | ///
49 | public string DisplayName { get; private set; }
50 |
51 | ///
52 | /// Gets the ETag of this resource.
53 | ///
54 | public string ETag { get; private set; }
55 |
56 | ///
57 | /// Gets the URI of this resource.
58 | ///
59 | public string Uri { get; private set; }
60 |
61 | ///
62 | /// Gets a value indicating whether this resource is a collection.
63 | ///
64 | ///
65 | /// true if this resource is a collection; otherwise, false. The default value is false.
66 | ///
67 | public bool IsCollection { get; private set; }
68 |
69 | ///
70 | /// Gets a value indicating whether this resource is hidden.
71 | ///
72 | ///
73 | /// true if this resource is hidden; otherwise, false. The default value is false.
74 | ///
75 | public bool IsHidden { get; private set; }
76 |
77 | ///
78 | /// Gets the last modified date of this resource.
79 | ///
80 | public DateTime? LastModifiedDate { get; private set; }
81 |
82 | ///
83 | /// Gets the collection of properties of this resource.
84 | ///
85 | public IReadOnlyCollection Properties { get; private set; }
86 |
87 | ///
88 | /// Gets the collection of property statuses of this resource.
89 | ///
90 | public IReadOnlyCollection PropertyStatuses { get; private set; }
91 |
92 | ///
93 | /// Represents a builder of the class.
94 | ///
95 | public class Builder
96 | {
97 | private IReadOnlyCollection _activeLocks;
98 | private string _contentLanguage;
99 | private int? _contentLength;
100 | private string _contentType;
101 | private DateTime? _creationDate;
102 | private string _displayName;
103 | private string _eTag;
104 | private string _uri;
105 | private bool _isCollection;
106 | private bool _isHidden;
107 | private DateTime? _lastModifiedDate;
108 | private IReadOnlyCollection _properties;
109 | private IReadOnlyCollection _propertyStatuses;
110 |
111 | ///
112 | /// Sets the ActiveLocks parameter of an instance of the class.
113 | ///
114 | public Builder WithActiveLocks(IReadOnlyCollection activeLocks)
115 | {
116 | _activeLocks = activeLocks;
117 | return this;
118 | }
119 |
120 | ///
121 | /// Sets the ContentLanguage parameter of an instance of the class.
122 | ///
123 | public Builder WithContentLanguage(string contentLanguage)
124 | {
125 | _contentLanguage = contentLanguage;
126 | return this;
127 | }
128 |
129 | ///
130 | /// Sets the ContentLength parameter of an instance of the class.
131 | ///
132 | public Builder WithContentLength(int? contentLength)
133 | {
134 | _contentLength = contentLength;
135 | return this;
136 | }
137 |
138 | ///
139 | /// Sets the ContentType parameter of an instance of the class.
140 | ///
141 | public Builder WithContentType(string contentType)
142 | {
143 | _contentType = contentType;
144 | return this;
145 | }
146 |
147 | ///
148 | /// Sets the CreationDate parameter of an instance of the class.
149 | ///
150 | public Builder WithCreationDate(DateTime? creationDate)
151 | {
152 | _creationDate = creationDate;
153 | return this;
154 | }
155 |
156 | ///
157 | /// Sets the DisplayName parameter of an instance of the class.
158 | ///
159 | public Builder WithDisplayName(string displayName)
160 | {
161 | _displayName = displayName;
162 | return this;
163 | }
164 |
165 | ///
166 | /// Sets the ETag parameter of an instance of the class.
167 | ///
168 | public Builder WithETag(string eTag)
169 | {
170 | _eTag = eTag;
171 | return this;
172 | }
173 |
174 | ///
175 | /// Sets the Uri parameter of an instance of the class.
176 | ///
177 | public Builder WithUri(string uri)
178 | {
179 | _uri = uri;
180 | return this;
181 | }
182 |
183 | ///
184 | /// Sets the IsCollection parameter of an instance of the class to true.
185 | ///
186 | public Builder IsCollection()
187 | {
188 | _isCollection = true;
189 | return this;
190 | }
191 |
192 | ///
193 | /// Sets the IsCollection parameter of an instance of the class to false.
194 | ///
195 | public Builder IsNotCollection()
196 | {
197 | _isCollection = false;
198 | return this;
199 | }
200 |
201 | ///
202 | /// Sets the IsHidden parameter of an instance of the class to true.
203 | ///
204 | public Builder IsHidden()
205 | {
206 | _isHidden = true;
207 | return this;
208 | }
209 |
210 | ///
211 | /// Sets the IsHidden parameter of an instance of the class to false.
212 | ///
213 | public Builder IsNotHidden()
214 | {
215 | _isHidden = false;
216 | return this;
217 | }
218 |
219 | ///
220 | /// Sets the LastModifiedDate parameter of an instance of the class.
221 | ///
222 | public Builder WithLastModifiedDate(DateTime? lastModifiedDate)
223 | {
224 | _lastModifiedDate = lastModifiedDate;
225 | return this;
226 | }
227 |
228 | ///
229 | /// Sets the Properties parameter of an instance of the class.
230 | ///
231 | public Builder WithProperties([NotNull] IReadOnlyCollection properties)
232 | {
233 | Check.NotNull(properties, nameof(properties));
234 | _properties = properties;
235 | return this;
236 | }
237 |
238 | ///
239 | /// Sets the PropertyStatuses parameter of an instance of the class.
240 | ///
241 | public Builder WithPropertyStatuses([NotNull] IReadOnlyCollection propertyStatuses)
242 | {
243 | Check.NotNull(propertyStatuses, nameof(propertyStatuses));
244 | _propertyStatuses = propertyStatuses;
245 | return this;
246 | }
247 |
248 | ///
249 | /// Builds a new instance of the class.
250 | ///
251 | /// A new instance of the class.
252 | public WebDavResource Build()
253 | {
254 | return new WebDavResource
255 | {
256 | ActiveLocks = _activeLocks,
257 | ContentLanguage = _contentLanguage,
258 | ContentLength = _contentLength,
259 | ContentType = _contentType,
260 | CreationDate = _creationDate,
261 | DisplayName = _displayName,
262 | ETag = _eTag,
263 | Uri = _uri,
264 | IsCollection = _isCollection,
265 | IsHidden = _isHidden,
266 | LastModifiedDate = _lastModifiedDate,
267 | Properties = _properties,
268 | PropertyStatuses = _propertyStatuses
269 | };
270 | }
271 | }
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Extensions/LinqToXmlExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Xml.Linq;
5 |
6 | namespace WebDav
7 | {
8 | internal static class LinqToXmlExtensions
9 | {
10 | public static string ToStringWithDeclaration(this XDocument doc)
11 | {
12 | if (doc == null)
13 | throw new ArgumentNullException(nameof(doc));
14 |
15 | return doc.Declaration + Environment.NewLine + doc;
16 | }
17 |
18 | public static string GetValueOrNull(this XElement element)
19 | {
20 | return element != null ? element.Value : null;
21 | }
22 |
23 | public static XElement LocalNameElement(this XElement parent, string localName)
24 | {
25 | return LocalNameElement(parent, localName, StringComparison.Ordinal);
26 | }
27 |
28 | public static XElement LocalNameElement(this XElement parent, string localName, StringComparison comparisonType)
29 | {
30 | return parent.Elements().FirstOrDefault(e => e.Name.LocalName.Equals(localName, comparisonType));
31 | }
32 |
33 | public static IEnumerable LocalNameElements(this XElement parent, string localName)
34 | {
35 | return LocalNameElements(parent, localName, StringComparison.Ordinal);
36 | }
37 |
38 | public static IEnumerable LocalNameElements(this XElement parent, string localName, StringComparison comparisonType)
39 | {
40 | return parent.Elements().Where(e => e.Name.LocalName.Equals(localName, comparisonType));
41 | }
42 |
43 | public static string GetInnerXml(this XElement element)
44 | {
45 | using (var reader = element.CreateReader())
46 | {
47 | reader.MoveToContent();
48 | return reader.ReadInnerXml();
49 | }
50 | }
51 |
52 | public static void SetInnerXml(this XElement element, string innerXml)
53 | {
54 | element.ReplaceNodes(XElement.Parse("" + innerXml + "").Nodes());
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Extensions/XDocumentExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 |
3 | namespace WebDav
4 | {
5 | internal static class XDocumentExtensions
6 | {
7 | public static XDocument TryParse(string text)
8 | {
9 | try
10 | {
11 | return XDocument.Parse(text);
12 | }
13 | catch
14 | {
15 | return null;
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Helpers/DepthHeaderHelper.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace WebDav
4 | {
5 | internal static class DepthHeaderHelper
6 | {
7 | public static string GetValueForPropfind(ApplyTo.Propfind applyTo)
8 | {
9 | switch (applyTo)
10 | {
11 | case ApplyTo.Propfind.ResourceOnly:
12 | return "0";
13 | case ApplyTo.Propfind.ResourceAndChildren:
14 | return "1";
15 | case ApplyTo.Propfind.ResourceAndAncestors:
16 | return "infinity";
17 | default:
18 | throw new InvalidEnumArgumentException("applyTo", (int)applyTo, typeof(ApplyTo.Propfind));
19 | }
20 | }
21 |
22 | public static string GetValueForCopy(ApplyTo.Copy applyTo)
23 | {
24 | switch (applyTo)
25 | {
26 | case ApplyTo.Copy.ResourceOnly:
27 | return "0";
28 | case ApplyTo.Copy.ResourceAndAncestors:
29 | return "infinity";
30 | default:
31 | throw new InvalidEnumArgumentException("applyTo", (int)applyTo, typeof(ApplyTo.Copy));
32 | }
33 | }
34 |
35 | public static string GetValueForLock(ApplyTo.Lock applyTo)
36 | {
37 | switch (applyTo)
38 | {
39 | case ApplyTo.Lock.ResourceOnly:
40 | return "0";
41 | case ApplyTo.Lock.ResourceAndAncestors:
42 | return "infinity";
43 | default:
44 | throw new InvalidEnumArgumentException("applyTo", (int)applyTo, typeof(ApplyTo.Lock));
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Helpers/IfHeaderHelper.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav
2 | {
3 | internal static class IfHeaderHelper
4 | {
5 | public static string GetHeaderValue(string lockToken)
6 | {
7 | return string.Format("(<{0}>)", lockToken);
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Infrastructure/HttpResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http;
2 |
3 | namespace WebDav.Infrastructure
4 | {
5 | internal class HttpResponse
6 | {
7 | public HttpResponse(HttpContent content, int statusCode)
8 | : this (content, statusCode, string.Empty)
9 | {
10 | }
11 |
12 | public HttpResponse(HttpContent content, int statusCode, string description)
13 | {
14 | Content = content;
15 | StatusCode = statusCode;
16 | Description = description;
17 | }
18 |
19 | public HttpContent Content { get; private set; }
20 |
21 | public int StatusCode { get; private set; }
22 |
23 | public string Description { get; private set; }
24 |
25 | public bool IsSuccessful => StatusCode >= 200 && StatusCode <= 299;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Infrastructure/IWebDavDispatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace WebDav.Infrastructure
7 | {
8 | internal interface IWebDavDispatcher
9 | {
10 | Uri BaseAddress { get; }
11 |
12 | Task Send(Uri requestUri, HttpMethod method, RequestParameters requestParams, CancellationToken cancellationToken);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Infrastructure/WebDavDispatcher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net.Http;
3 | using System.Net.Http.Headers;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using JetBrains.Annotations;
7 |
8 | namespace WebDav.Infrastructure
9 | {
10 | internal class WebDavDispatcher : IWebDavDispatcher, IDisposable
11 | {
12 | private readonly HttpClient _httpClient;
13 |
14 | public WebDavDispatcher([NotNull] HttpClient httpClient)
15 | {
16 | Check.NotNull(httpClient, nameof(httpClient));
17 |
18 | _httpClient = httpClient;
19 | }
20 |
21 | public Uri BaseAddress => _httpClient.BaseAddress;
22 |
23 | public async Task Send(Uri requestUri, HttpMethod method, RequestParameters requestParams, CancellationToken cancellationToken)
24 | {
25 | using (var request = new HttpRequestMessage(method, requestUri))
26 | {
27 | foreach (var header in requestParams.Headers)
28 | {
29 | request.Headers.Add(header.Key, header.Value);
30 | }
31 |
32 | if (requestParams.Content != null)
33 | {
34 | request.Content = requestParams.Content;
35 | if (!string.IsNullOrEmpty(requestParams.ContentType))
36 | request.Content.Headers.ContentType = new MediaTypeHeaderValue(requestParams.ContentType);
37 | }
38 |
39 | var response = await _httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
40 | return new HttpResponse(response.Content, (int)response.StatusCode, response.ReasonPhrase);
41 | }
42 | }
43 |
44 | #region IDisposable
45 |
46 | public void Dispose()
47 | {
48 | DisposeManagedResources();
49 | }
50 |
51 | protected virtual void DisposeManagedResources()
52 | {
53 | _httpClient?.Dispose();
54 | }
55 |
56 | #endregion
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.CompilerServices;
2 |
3 | [assembly: InternalsVisibleTo("WebDAV-Client.Tests")]
4 | [assembly: InternalsVisibleTo("WebDAV-Client.Tests.Net452")]
5 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
--------------------------------------------------------------------------------
/src/WebDAV-Client/Request/LockRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Xml.Linq;
4 |
5 | namespace WebDav.Request
6 | {
7 | internal static class LockRequestBuilder
8 | {
9 | public static string BuildRequestBody(LockParameters lockParams)
10 | {
11 | var doc = new XDocument(new XDeclaration("1.0", "utf-8", null));
12 | var lockinfo = new XElement("{DAV:}lockinfo", new XAttribute(XNamespace.Xmlns + "D", "DAV:"));
13 |
14 | lockinfo.Add(GetLockScope(lockParams.LockScope));
15 | lockinfo.Add(GetLockType());
16 |
17 | if (lockParams.Owner != null)
18 | lockinfo.Add(GetLockOwner(lockParams.Owner));
19 |
20 | doc.Add(lockinfo);
21 | return doc.ToStringWithDeclaration();
22 | }
23 |
24 | private static XElement GetLockScope(LockScope lockScope)
25 | {
26 | var lockscope = new XElement("{DAV:}lockscope");
27 | switch (lockScope)
28 | {
29 | case LockScope.Shared:
30 | lockscope.Add(new XElement("{DAV:}shared"));
31 | break;
32 | case LockScope.Exclusive:
33 | lockscope.Add(new XElement("{DAV:}exclusive"));
34 | break;
35 | default:
36 | throw new InvalidEnumArgumentException("lockScope", (int)lockScope, typeof(LockScope));
37 | }
38 | return lockscope;
39 | }
40 |
41 | private static XElement GetLockType()
42 | {
43 | var locktype = new XElement("{DAV:}locktype");
44 | locktype.Add(new XElement("{DAV:}write"));
45 | return locktype;
46 | }
47 |
48 | private static XElement GetLockOwner(LockOwner lockOwner)
49 | {
50 | var owner = new XElement("{DAV:}owner");
51 |
52 | if (lockOwner is PrincipalLockOwner)
53 | {
54 | owner.SetValue(lockOwner.Value);
55 | }
56 | else if (lockOwner is UriLockOwner)
57 | {
58 | var uri = new XElement("{DAV:}href");
59 | uri.SetValue(lockOwner.Value);
60 | owner.Add(uri);
61 | }
62 | else
63 | {
64 | throw new ArgumentException("Lock owner is invalid.", nameof(lockOwner));
65 | }
66 |
67 | return owner;
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/src/WebDAV-Client/Request/PropfindRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Xml.Linq;
4 |
5 | namespace WebDav.Request
6 | {
7 | internal static class PropfindRequestBuilder
8 | {
9 | public static string BuildRequestBody(IReadOnlyCollection customProperties, IReadOnlyCollection namespaces)
10 | {
11 | var doc = new XDocument(new XDeclaration("1.0", "utf-8", null));
12 | var propfind = new XElement("{DAV:}propfind", new XAttribute(XNamespace.Xmlns + "D", "DAV:"));
13 | propfind.Add(new XElement("{DAV:}allprop"));
14 | if (customProperties.Any())
15 | {
16 | var include = new XElement("{DAV:}include");
17 | foreach (var ns in namespaces)
18 | {
19 | var nsAttr = string.IsNullOrEmpty(ns.Prefix) ? "xmlns" : XNamespace.Xmlns + ns.Prefix;
20 | include.SetAttributeValue(nsAttr, ns.Namespace);
21 | }
22 | foreach (var prop in customProperties)
23 | {
24 | include.Add(new XElement(prop));
25 | }
26 | propfind.Add(include);
27 | }
28 | doc.Add(propfind);
29 | return doc.ToStringWithDeclaration();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Request/ProppatchRequestBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Xml.Linq;
4 |
5 | namespace WebDav.Request
6 | {
7 | internal static class ProppatchRequestBuilder
8 | {
9 | public static string BuildRequestBody(IDictionary propertiesToSet,
10 | IReadOnlyCollection propertiesToRemove,
11 | IReadOnlyCollection namespaces)
12 | {
13 | var doc = new XDocument(new XDeclaration("1.0", "utf-8", null));
14 | var propertyupdate = new XElement("{DAV:}propertyupdate", new XAttribute(XNamespace.Xmlns + "D", "DAV:"));
15 | foreach (var ns in namespaces)
16 | {
17 | var nsAttr = string.IsNullOrEmpty(ns.Prefix) ? "xmlns" : XNamespace.Xmlns + ns.Prefix;
18 | propertyupdate.SetAttributeValue(nsAttr, ns.Namespace);
19 | }
20 | if (propertiesToSet.Any())
21 | {
22 | var setEl = new XElement("{DAV:}set");
23 | foreach (var prop in propertiesToSet)
24 | {
25 | var el = new XElement(prop.Key);
26 | el.SetInnerXml(prop.Value);
27 | setEl.Add(new XElement(XName.Get("prop", "DAV:"), el));
28 | }
29 | propertyupdate.Add(setEl);
30 | }
31 |
32 | if (propertiesToRemove.Any())
33 | {
34 | var removeEl = new XElement("{DAV:}remove");
35 | foreach (var prop in propertiesToRemove)
36 | {
37 | removeEl.Add(
38 | new XElement(XName.Get("prop", "DAV:"),
39 | new XElement(prop)));
40 | }
41 | propertyupdate.Add(removeEl);
42 | }
43 |
44 | doc.Add(propertyupdate);
45 | return doc.ToStringWithDeclaration();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/IResponseParser.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav.Response
2 | {
3 | internal interface IResponseParser
4 | {
5 | TResponse Parse(string response, int statusCode, string description);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/LockResponse.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using JetBrains.Annotations;
5 |
6 | namespace WebDav
7 | {
8 | ///
9 | /// Represents a response of the LOCK operation.
10 | ///
11 | public class LockResponse : WebDavResponse
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | /// The status code of the operation.
17 | public LockResponse(int statusCode)
18 | : this(statusCode, null, new List())
19 | {
20 | }
21 |
22 | ///
23 | /// Initializes a new instance of the class.
24 | ///
25 | /// The status code of the response.
26 | /// The active locks of the resource.
27 | public LockResponse(int statusCode, IEnumerable activeLocks)
28 | : this(statusCode, null, activeLocks)
29 | {
30 | }
31 |
32 | ///
33 | /// Initializes a new instance of the class.
34 | ///
35 | /// The status code of the response.
36 | /// The description of the response.
37 | public LockResponse(int statusCode, string description)
38 | : this(statusCode, description, new List())
39 | {
40 | }
41 |
42 | ///
43 | /// Initializes a new instance of the class.
44 | ///
45 | /// The status code of the response.
46 | /// The description of the response.
47 | /// The active locks of the resource.
48 | public LockResponse(int statusCode, string description, [NotNull] IEnumerable activeLocks)
49 | : base(statusCode, description)
50 | {
51 | Check.NotNull(activeLocks, nameof(activeLocks));
52 | ActiveLocks = activeLocks.ToList();
53 | }
54 |
55 | ///
56 | /// Gets a collection locks on this resource.
57 | ///
58 | public IReadOnlyCollection ActiveLocks { get; private set; }
59 |
60 | public override string ToString()
61 | {
62 | return string.Format("LOCK response - StatusCode: {0}, Description: {1}", StatusCode, Description);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/LockResponseParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Xml.Linq;
5 |
6 | namespace WebDav.Response
7 | {
8 | internal class LockResponseParser : IResponseParser
9 | {
10 | public LockResponse Parse(string response, int statusCode, string description)
11 | {
12 | var xresponse = XDocumentExtensions.TryParse(response);
13 | if (xresponse == null || xresponse.Root == null)
14 | return new LockResponse(statusCode, description);
15 |
16 | var lockdiscovery = xresponse.Root.LocalNameElement("lockdiscovery", StringComparison.OrdinalIgnoreCase);
17 | var activeLocks = ParseLockDiscovery(lockdiscovery);
18 | return new LockResponse(statusCode, description, activeLocks);
19 | }
20 |
21 | public List ParseLockDiscovery(XElement lockdiscovery)
22 | {
23 | if (lockdiscovery == null)
24 | return new List();
25 |
26 | return lockdiscovery
27 | .LocalNameElements("activelock", StringComparison.OrdinalIgnoreCase)
28 | .Select(x => CreateActiveLock(x.Elements().ToList()))
29 | .ToList();
30 | }
31 |
32 | private ActiveLock CreateActiveLock(List properties)
33 | {
34 | var activeLock =
35 | new ActiveLock.Builder()
36 | .WithApplyTo(PropertyValueParser.ParseLockDepth(FindProp("depth", properties)))
37 | .WithLockScope(PropertyValueParser.ParseLockScope(FindProp("lockscope", properties)))
38 | .WithLockToken(PropertyValueParser.ParseString(FindProp("locktoken", properties)))
39 | .WithOwner(PropertyValueParser.ParseOwner(FindProp("owner", properties)))
40 | .WithLockRoot(PropertyValueParser.ParseString(FindProp("lockroot", properties)))
41 | .WithTimeout(PropertyValueParser.ParseLockTimeout(FindProp("timeout", properties)))
42 | .Build();
43 | return activeLock;
44 | }
45 |
46 | private static XElement FindProp(string localName, IEnumerable properties)
47 | {
48 | return properties.FirstOrDefault(x => x.Name.LocalName.Equals(localName, StringComparison.OrdinalIgnoreCase));
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/MultiStatusParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text.RegularExpressions;
5 | using System.Xml.Linq;
6 |
7 | namespace WebDav
8 | {
9 | internal static class MultiStatusParser
10 | {
11 | private static readonly Regex StatusCodeRegex = new Regex(@".*(\d{3}).*");
12 |
13 | public static List GetPropstats(XElement xresponse)
14 | {
15 | return xresponse.LocalNameElements("propstat", StringComparison.OrdinalIgnoreCase)
16 | .Select(x =>
17 | new Propstat
18 | {
19 | Element = x,
20 | StatusCode = GetStatusCodeFromPropstat(x),
21 | Description = GetDescriptionFromPropstat(x)
22 | })
23 | .ToList();
24 | }
25 |
26 | public static List GetPropertyStatuses(XElement xresponse)
27 | {
28 | var propstats = GetPropstats(xresponse);
29 | return GetPropertyStatuses(propstats);
30 | }
31 |
32 | public static List GetPropertyStatuses(List propstats)
33 | {
34 | return propstats
35 | .SelectMany(x => x.Element.LocalNameElements("prop", StringComparison.OrdinalIgnoreCase)
36 | .SelectMany(p => p.Elements())
37 | .Select(p => new { Prop = p, StatusCode = x.StatusCode, Description = x.Description }))
38 | .Select(x => new WebDavPropertyStatus(x.Prop.Name, x.StatusCode, x.Description))
39 | .ToList();
40 | }
41 |
42 | public static List GetProperties(List propstats)
43 | {
44 | return propstats
45 | .Where(x => IsSuccessStatusCode(x.StatusCode))
46 | .SelectMany(x => x.Element.LocalNameElements("prop", StringComparison.OrdinalIgnoreCase))
47 | .SelectMany(x => x.Elements())
48 | .ToList();
49 | }
50 |
51 | private static bool IsSuccessStatusCode(int statusCode)
52 | {
53 | return statusCode >= 200 && statusCode <= 299;
54 | }
55 |
56 | private static string GetDescriptionFromPropstat(XElement propstat)
57 | {
58 | return
59 | propstat.LocalNameElement("responsedescription", StringComparison.OrdinalIgnoreCase).GetValueOrNull() ??
60 | propstat.LocalNameElement("status", StringComparison.OrdinalIgnoreCase).GetValueOrNull();
61 | }
62 |
63 | private static int GetStatusCodeFromPropstat(XElement propstat)
64 | {
65 | var statusRawValue = propstat.LocalNameElement("status", StringComparison.OrdinalIgnoreCase).GetValueOrNull();
66 | if (string.IsNullOrEmpty(statusRawValue))
67 | return default(int);
68 |
69 | var statusCodeGroup = StatusCodeRegex.Match(statusRawValue).Groups[1];
70 | if (!statusCodeGroup.Success)
71 | return default(int);
72 |
73 | int statusCode;
74 | if (!int.TryParse(statusCodeGroup.Value, out statusCode))
75 | return default(int);
76 |
77 | return statusCode;
78 | }
79 |
80 | internal class Propstat
81 | {
82 | public XElement Element { get; set; }
83 |
84 | public int StatusCode { get; set; }
85 |
86 | public string Description { get; set; }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/PropertyValueParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace WebDav.Response
5 | {
6 | internal static class PropertyValueParser
7 | {
8 | public static string ParseString(XElement element)
9 | {
10 | return element != null ? element.Value : null;
11 | }
12 |
13 | public static int? ParseInteger(XElement element)
14 | {
15 | if (element == null)
16 | return null;
17 |
18 | int value;
19 | return int.TryParse(element.Value, out value) ? (int?)value : null;
20 | }
21 |
22 | public static DateTime? ParseDateTime(XElement element)
23 | {
24 | if (element == null)
25 | return null;
26 |
27 | DateTime value;
28 | return DateTime.TryParse(element.Value, out value) ? (DateTime?)value : null;
29 | }
30 |
31 | public static ResourceType ParseResourceType(XElement element)
32 | {
33 | if (element == null)
34 | return ResourceType.Other;
35 |
36 | return element.LocalNameElement("collection") != null
37 | ? ResourceType.Collection
38 | : ResourceType.Other;
39 | }
40 |
41 | public static LockScope? ParseLockScope(XElement element)
42 | {
43 | if (element == null)
44 | return null;
45 |
46 | if (element.LocalNameElement("shared", StringComparison.OrdinalIgnoreCase) != null)
47 | return LockScope.Shared;
48 | if (element.LocalNameElement("exclusive", StringComparison.OrdinalIgnoreCase) != null)
49 | return LockScope.Exclusive;
50 |
51 | return null;
52 | }
53 |
54 | public static ApplyTo.Lock? ParseLockDepth(XElement element)
55 | {
56 | if (element == null)
57 | return null;
58 | return element.Value.Equals("0") ? ApplyTo.Lock.ResourceOnly : ApplyTo.Lock.ResourceAndAncestors;
59 | }
60 |
61 | public static LockOwner ParseOwner(XElement element)
62 | {
63 | if (element == null)
64 | return null;
65 |
66 | var uri = element.LocalNameElement("href", StringComparison.OrdinalIgnoreCase);
67 | if (uri != null && Uri.IsWellFormedUriString(uri.Value, UriKind.Absolute))
68 | return new UriLockOwner(uri.Value);
69 |
70 | return !string.IsNullOrEmpty(element.Value) ? new PrincipalLockOwner(element.Value) : null;
71 | }
72 |
73 | public static TimeSpan? ParseLockTimeout(XElement element)
74 | {
75 | if (element == null)
76 | return null;
77 |
78 | var value = element.Value;
79 | if (value.Equals("infinity", StringComparison.OrdinalIgnoreCase))
80 | return null;
81 |
82 | if (value.StartsWith("Second-", StringComparison.OrdinalIgnoreCase))
83 | {
84 | int seconds;
85 | if (int.TryParse(value.Substring(value.IndexOf("-") + 1), out seconds))
86 | return TimeSpan.FromSeconds(seconds);
87 | }
88 | return null;
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/PropfindResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using JetBrains.Annotations;
4 |
5 | namespace WebDav
6 | {
7 | ///
8 | /// Represents a response of the PROPFIND operation.
9 | ///
10 | public class PropfindResponse : WebDavResponse
11 | {
12 | ///
13 | /// Initializes a new instance of the class.
14 | ///
15 | /// The status code of the operation.
16 | public PropfindResponse(int statusCode)
17 | : this(statusCode, null, new List())
18 | {
19 | }
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// The status code of the response.
25 | /// The collection of WebDAV resources.
26 | public PropfindResponse(int statusCode, IEnumerable resources)
27 | : this(statusCode, null, resources)
28 | {
29 | }
30 |
31 | ///
32 | /// Initializes a new instance of the class.
33 | ///
34 | /// The status code of the response.
35 | /// The description of the response.
36 | public PropfindResponse(int statusCode, string description)
37 | : this(statusCode, description, new List())
38 | {
39 | }
40 |
41 | ///
42 | /// Initializes a new instance of the class.
43 | ///
44 | /// The status code of the response.
45 | /// The description of the response.
46 | /// The collection of WebDAV resources.
47 | public PropfindResponse(int statusCode, string description, [NotNull] IEnumerable resources)
48 | : base(statusCode, description)
49 | {
50 | Check.NotNull(resources, nameof(resources));
51 | Resources = resources.ToList();
52 | }
53 |
54 | ///
55 | /// Gets the collection of WebDAV resources.
56 | ///
57 | public IReadOnlyCollection Resources { get; private set; }
58 |
59 | public override string ToString()
60 | {
61 | return string.Format("PROPFIND WebDAV response - StatusCode: {0}, Description: {1}", StatusCode, Description);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/PropfindResponseParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Xml.Linq;
6 | using JetBrains.Annotations;
7 |
8 | namespace WebDav.Response
9 | {
10 | internal class PropfindResponseParser : IResponseParser
11 | {
12 | private readonly LockResponseParser _lockResponseParser;
13 |
14 | public PropfindResponseParser([NotNull] LockResponseParser lockResponseParser)
15 | {
16 | Check.NotNull(lockResponseParser, nameof(lockResponseParser));
17 | _lockResponseParser = lockResponseParser;
18 | }
19 |
20 | public PropfindResponse Parse(string response, int statusCode, string description)
21 | {
22 | if (string.IsNullOrEmpty(response))
23 | return new PropfindResponse(statusCode, description);
24 |
25 | var xresponse = XDocumentExtensions.TryParse(response);
26 | if (xresponse == null || xresponse.Root == null)
27 | return new PropfindResponse(statusCode, description);
28 |
29 | var resources = xresponse.Root.LocalNameElements("response", StringComparison.OrdinalIgnoreCase)
30 | .Select(ParseResource)
31 | .ToList();
32 | return new PropfindResponse(statusCode, description, resources);
33 | }
34 |
35 | private WebDavResource ParseResource(XElement xresponse)
36 | {
37 | var uriValue = xresponse.LocalNameElement("href", StringComparison.OrdinalIgnoreCase).GetValueOrNull();
38 | var propstats = MultiStatusParser.GetPropstats(xresponse);
39 | return CreateResource(uriValue, propstats);
40 | }
41 |
42 | private WebDavResource CreateResource(string uri, List propstats)
43 | {
44 | var properties = MultiStatusParser.GetProperties(propstats);
45 | var resourceBuilder = new WebDavResource.Builder()
46 | .WithActiveLocks(_lockResponseParser.ParseLockDiscovery(FindProp("{DAV:}lockdiscovery", properties)))
47 | .WithContentLanguage(PropertyValueParser.ParseString(FindProp("{DAV:}getcontentlanguage", properties)))
48 | .WithContentLength(PropertyValueParser.ParseInteger(FindProp("{DAV:}getcontentlength", properties)))
49 | .WithContentType(PropertyValueParser.ParseString(FindProp("{DAV:}getcontenttype", properties)))
50 | .WithCreationDate(PropertyValueParser.ParseDateTime(FindProp("{DAV:}creationdate", properties)))
51 | .WithDisplayName(PropertyValueParser.ParseString(FindProp("{DAV:}displayname", properties)))
52 | .WithETag(PropertyValueParser.ParseString(FindProp("{DAV:}getetag", properties)))
53 | .WithLastModifiedDate(PropertyValueParser.ParseDateTime(FindProp("{DAV:}getlastmodified", properties)))
54 | .WithProperties(new ReadOnlyCollection(properties.Select(x => new WebDavProperty(x.Name, x.GetInnerXml())).ToList()))
55 | .WithPropertyStatuses(MultiStatusParser.GetPropertyStatuses(propstats));
56 |
57 | var isHidden = PropertyValueParser.ParseInteger(FindProp("{DAV:}ishidden", properties)) > 0;
58 | if (isHidden)
59 | resourceBuilder.IsHidden();
60 |
61 | var isCollection = PropertyValueParser.ParseInteger(FindProp("{DAV:}iscollection", properties)) > 0 ||
62 | PropertyValueParser.ParseResourceType(FindProp("{DAV:}resourcetype", properties)) == ResourceType.Collection;
63 | if (isCollection)
64 | {
65 | resourceBuilder.IsCollection();
66 | resourceBuilder.WithUri(uri.TrimEnd('/') + "/");
67 | }
68 | else
69 | {
70 | resourceBuilder.WithUri(uri);
71 | }
72 | return resourceBuilder.Build();
73 | }
74 |
75 | private static XElement FindProp(XName name, IEnumerable properties)
76 | {
77 | return properties.FirstOrDefault(x => x.Name.Equals(name));
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/ProppatchResponse.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using JetBrains.Annotations;
3 |
4 | namespace WebDav
5 | {
6 | ///
7 | /// Represents a response of the PROPPATCH operation.
8 | ///
9 | public class ProppatchResponse : WebDavResponse
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The status code of the operation.
15 | public ProppatchResponse(int statusCode)
16 | : this(statusCode, null, new List())
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The status code of the response.
24 | /// The collection of property statuses.
25 | public ProppatchResponse(int statusCode, IEnumerable propertyStatuses)
26 | : this(statusCode, null, propertyStatuses)
27 | {
28 | }
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The status code of the response.
34 | /// The description of the response.
35 | public ProppatchResponse(int statusCode, string description)
36 | : this(statusCode, description, new List())
37 | {
38 | }
39 |
40 | ///
41 | /// Initializes a new instance of the class.
42 | ///
43 | /// The status code of the response.
44 | /// The description of the response.
45 | /// The collection of property statuses.
46 | public ProppatchResponse(int statusCode, string description, [NotNull] IEnumerable propertyStatuses)
47 | : base(statusCode, description)
48 | {
49 | Check.NotNull(propertyStatuses, nameof(propertyStatuses));
50 | PropertyStatuses = new List(propertyStatuses);
51 | }
52 |
53 | ///
54 | /// Gets the collection statuses of set/delete operation on the resource's properties.
55 | ///
56 | public IReadOnlyCollection PropertyStatuses { get; private set; }
57 |
58 | public override string ToString()
59 | {
60 | return string.Format("PROPPATCH WebDAV response - StatusCode: {0}, Description: {1}", StatusCode, Description);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/ProppatchResponseParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace WebDav.Response
5 | {
6 | internal class ProppatchResponseParser : IResponseParser
7 | {
8 | public ProppatchResponse Parse(string response, int statusCode, string description)
9 | {
10 | if (string.IsNullOrEmpty(response))
11 | return new ProppatchResponse(statusCode, description);
12 |
13 | var xresponse = XDocumentExtensions.TryParse(response);
14 | if (xresponse == null || xresponse.Root == null)
15 | return new ProppatchResponse(statusCode, description);
16 |
17 | var propStatuses = xresponse.Root.LocalNameElements("response", StringComparison.OrdinalIgnoreCase)
18 | .SelectMany(MultiStatusParser.GetPropertyStatuses)
19 | .ToList();
20 | return new ProppatchResponse(statusCode, description, propStatuses);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/ResourceType.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav.Response
2 | {
3 | internal enum ResourceType
4 | {
5 | Collection,
6 | Other
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/WebDavResponse.cs:
--------------------------------------------------------------------------------
1 | namespace WebDav
2 | {
3 | ///
4 | /// Represents a response of a WebDAV operation.
5 | ///
6 | public class WebDavResponse
7 | {
8 | ///
9 | /// Initializes a new instance of the class.
10 | ///
11 | /// The status code of the operation.
12 | public WebDavResponse(int statusCode)
13 | {
14 | StatusCode = statusCode;
15 | }
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// The status code of the response.
21 | /// The description of the response.
22 | public WebDavResponse(int statusCode, string description)
23 | {
24 | StatusCode = statusCode;
25 | Description = description;
26 | }
27 |
28 | ///
29 | /// Gets the status code of the response.
30 | ///
31 | public int StatusCode { get; private set; }
32 |
33 | ///
34 | /// Gets the description of the response.
35 | ///
36 | public string Description { get; private set; }
37 |
38 | ///
39 | /// Gets a value indicating whether the operation was successful.
40 | ///
41 | ///
42 | /// true if the operation was successful; otherwise, false.
43 | ///
44 | public virtual bool IsSuccessful => StatusCode >= 200 && StatusCode <= 299;
45 |
46 | public override string ToString()
47 | {
48 | return string.Format("WebDAV response - StatusCode: {0}, Description: {1}", StatusCode, Description);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/Response/WebDavStreamResponse.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace WebDav
4 | {
5 | ///
6 | /// Represents a response of the GET operation.
7 | ///
8 | public class WebDavStreamResponse : WebDavResponse
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The status code of the operation.
14 | public WebDavStreamResponse(int statusCode)
15 | : this(statusCode, null, null)
16 | {
17 | }
18 |
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The status code of the response.
23 | /// The stream of resource's content.
24 | public WebDavStreamResponse(int statusCode, Stream stream)
25 | : this(statusCode, null, stream)
26 | {
27 | }
28 |
29 | ///
30 | /// Initializes a new instance of the class.
31 | ///
32 | /// The status code of the response.
33 | /// The description of the response.
34 | public WebDavStreamResponse(int statusCode, string description)
35 | : this(statusCode, description, null)
36 | {
37 | }
38 |
39 | ///
40 | /// Initializes a new instance of the class.
41 | ///
42 | /// The status code of the response.
43 | /// The description of the response.
44 | /// The stream of content of the resource.
45 | public WebDavStreamResponse(int statusCode, string description, Stream stream)
46 | : base(statusCode, description)
47 | {
48 | Stream = stream;
49 | }
50 |
51 | ///
52 | /// Gets the stream of content of the resource.
53 | ///
54 | public Stream Stream { get; private set; }
55 |
56 | public override string ToString()
57 | {
58 | return string.Format("WebDAV stream response - StatusCode: {0}, Description: {1}", StatusCode, Description);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/WebDAV-Client/System.ComponentModel/InvalidEnumArgumentException.cs:
--------------------------------------------------------------------------------
1 | #if NETSTANDARD1_1 || NETSTANDARD1_2 || PORTABLE
2 | // Copied from https://github.com/Microsoft/referencesource/blob/4fe4349175f4c5091d972a7e56ea12012f1e7170/System/compmod/system/componentmodel/InvalidEnumArgumentException.cs
3 |
4 | // ReSharper disable once CheckNamespace
5 | namespace System.ComponentModel
6 | {
7 | ///
8 | /// The exception that is thrown when using invalid arguments that are enumerators.
9 | ///
10 | public class InvalidEnumArgumentException : ArgumentException
11 | {
12 | ///
13 | /// Initializes a new instance of the class without a message.
14 | ///
15 | public InvalidEnumArgumentException() : this(null)
16 | {
17 | }
18 |
19 | ///
20 | /// Initializes a new instance of the class with
21 | /// the specified message.
22 | ///
23 | public InvalidEnumArgumentException(string message)
24 | : base(message)
25 | {
26 | }
27 |
28 | ///
29 | /// Initializes a new instance of the Exception class with a specified error message and a
30 | /// reference to the inner exception that is the cause of this exception.
31 | /// FxCop CA1032: Multiple constructors are required to correctly implement a custom exception.
32 | ///
33 | public InvalidEnumArgumentException(string message, Exception innerException)
34 | : base(message, innerException)
35 | {
36 | }
37 |
38 | ///
39 | /// Initializes a new instance of the class with a
40 | /// message generated from the argument, invalid value, and enumeration
41 | /// class.
42 | ///
43 | public InvalidEnumArgumentException(string argumentName, int invalidValue, Type enumClass)
44 | : base($"The value of argument '{argumentName}' ({invalidValue}) is invalid for Enum type '{enumClass.Name}'", argumentName)
45 | {
46 | }
47 | }
48 | }
49 | #endif
--------------------------------------------------------------------------------
/src/WebDAV-Client/System/RuntimeUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // ReSharper disable once CheckNamespace
4 | namespace WebDav
5 | {
6 | internal static class RuntimeUtils
7 | {
8 | public static bool IsBlazorWASM => Type.GetType("Mono.Runtime") != null;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/WebDAV-Client/Validation/Check.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.Linq;
8 | using JetBrains.Annotations;
9 |
10 | // Copied from https://github.com/aspnet/EntityFramework/blob/dev/src/Shared/Check.cs
11 | namespace WebDav
12 | {
13 | [DebuggerStepThrough]
14 | internal static class Check
15 | {
16 | [ContractAnnotation("value:null => halt")]
17 | public static T Condition([NoEnumeration] T value, [NotNull] Predicate condition, [InvokerParameterName] [NotNull] string parameterName)
18 | {
19 | NotNull(condition, nameof(condition));
20 | NotNull(value, nameof(value));
21 |
22 | if (!condition(value))
23 | {
24 | NotEmpty(parameterName, nameof(parameterName));
25 |
26 | throw new ArgumentOutOfRangeException(parameterName);
27 | }
28 |
29 | return value;
30 | }
31 |
32 | [ContractAnnotation("value:null => halt")]
33 | public static T NotNull([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)
34 | {
35 | if (ReferenceEquals(value, null))
36 | {
37 | NotEmpty(parameterName, nameof(parameterName));
38 |
39 | throw new ArgumentNullException(parameterName);
40 | }
41 |
42 | return value;
43 | }
44 |
45 | [ContractAnnotation("value:null => halt")]
46 | public static T NotNull(
47 | [NoEnumeration] T value,
48 | [InvokerParameterName] [NotNull] string parameterName,
49 | [NotNull] string propertyName)
50 | {
51 | if (ReferenceEquals(value, null))
52 | {
53 | NotEmpty(parameterName, nameof(parameterName));
54 | NotEmpty(propertyName, nameof(propertyName));
55 |
56 | throw new ArgumentException(CoreStrings.ArgumentPropertyNull(propertyName, parameterName));
57 | }
58 |
59 | return value;
60 | }
61 |
62 | [ContractAnnotation("value:null => halt")]
63 | public static IList NotEmpty(IList value, [InvokerParameterName] [NotNull] string parameterName)
64 | {
65 | NotNull(value, parameterName);
66 |
67 | if (value.Count == 0)
68 | {
69 | NotEmpty(parameterName, nameof(parameterName));
70 |
71 | throw new ArgumentException(CoreStrings.CollectionArgumentIsEmpty(parameterName));
72 | }
73 |
74 | return value;
75 | }
76 |
77 | [ContractAnnotation("value:null => halt")]
78 | public static string NotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
79 | {
80 | Exception e = null;
81 | if (ReferenceEquals(value, null))
82 | {
83 | e = new ArgumentNullException(parameterName);
84 | }
85 | else if (value.Trim().Length == 0)
86 | {
87 | e = new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
88 | }
89 |
90 | if (e != null)
91 | {
92 | NotEmpty(parameterName, nameof(parameterName));
93 |
94 | throw e;
95 | }
96 |
97 | return value;
98 | }
99 |
100 | public static string NullButNotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
101 | {
102 | if (!ReferenceEquals(value, null)
103 | && (value.Length == 0))
104 | {
105 | NotEmpty(parameterName, nameof(parameterName));
106 |
107 | throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
108 | }
109 |
110 | return value;
111 | }
112 |
113 | public static IList HasNoNulls(IList value, [InvokerParameterName] [NotNull] string parameterName)
114 | where T : class
115 | {
116 | NotNull(value, parameterName);
117 |
118 | if (value.Any(e => e == null))
119 | {
120 | NotEmpty(parameterName, nameof(parameterName));
121 |
122 | throw new ArgumentException(parameterName);
123 | }
124 |
125 | return value;
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/src/WebDAV-Client/Validation/CoreStrings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using JetBrains.Annotations;
3 |
4 | // copied from https://github.com/aspnet/EntityFramework/blob/dev/src/Microsoft.EntityFrameworkCore/Properties/CoreStrings.resx
5 | namespace WebDav
6 | {
7 | internal static class CoreStrings
8 | {
9 | ///
10 | /// The property '{property}' of the argument '{argument}' cannot be null.
11 | ///
12 | public static string ArgumentPropertyNull([CanBeNull] string property, [CanBeNull] string argument)
13 | {
14 | return string.Format($"The property '{property}' of the argument '{argument}' cannot be null.", property, argument);
15 | }
16 |
17 | ///
18 | /// The string argument '{argumentName}' cannot be empty.
19 | ///
20 | public static string ArgumentIsEmpty([CanBeNull] string argumentName)
21 | {
22 | return string.Format($"The string argument '{argumentName}' cannot be empty.", argumentName);
23 | }
24 |
25 | ///
26 | /// The entity type '{type}' provided for the argument '{argumentName}' must be a reference type.
27 | ///
28 | public static string InvalidEntityType([CanBeNull] Type type, [CanBeNull] string argumentName)
29 | {
30 | return string.Format($"The entity type '{type}' provided for the argument '{argumentName}' must be a reference type.", type, argumentName);
31 | }
32 |
33 | ///
34 | /// The collection argument '{argumentName}' must contain at least one element.
35 | ///
36 | public static string CollectionArgumentIsEmpty([CanBeNull] string argumentName)
37 | {
38 | return string.Format($"The collection argument '{argumentName}' must contain at least one element.", argumentName);
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/WebDAV-Client/WebDAV-Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | An easy-to-use async WebDAV client for .NET, .NETStandard, Blazor-WASM and Portable based on https://github.com/skazantsev/WebDavClient.
5 | WebDAV-Client
6 | WebDav
7 | 1.1.2.0
8 | Sergey Kazantsev;Stef Heyenrath
9 | net45;net46;netstandard1.1;netstandard1.2;netstandard2.0;netstandard2.1;net6.0;net7.0
10 | WebDAV-Client
11 | WebDAV-Client
12 | webdav;client;NETStandard;.NET;Portable;Blazor;WASM
13 | See CHANGELOG.md
14 | https://github.com/stefh/WebDAV-Client
15 | https://raw.githubusercontent.com/StefH/WebDAV-Client/master/LICENSE
16 | git
17 | https://github.com/stefh/WebDAV-Client
18 | true
19 |
20 |
21 |
22 | $(PackageTargetFallback);portable-net45+win8+wpa81;portable-net45+win8
23 |
24 |
25 |
26 | $(PackageTargetFallback);portable-net451+win81+wpa81;portable-win81+wpa81;portable-net451+win81
27 |
28 |
29 |
30 |
31 | All
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/Infrastructure/WebDavDispatcherTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NSubstitute;
3 | using System.Net.Http;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using WebDav.Infrastructure;
8 | using Xunit;
9 |
10 | namespace WebDav.Client.Tests.Infrastructure
11 | {
12 | public class WebDavDispatcherTests
13 | {
14 | [Fact]
15 | public async void When_RequestIsSent_Should_ReceiveResponseAndStatusCode200()
16 | {
17 | using (var dispatcher = new WebDavDispatcher(ConfigureHttpClient()))
18 | {
19 | var response = await dispatcher.Send(new Uri("http://example.com"), HttpMethod.Get, new RequestParameters(), CancellationToken.None);
20 |
21 | Assert.IsType(typeof(HttpResponse), response);
22 | Assert.Equal(200, response.StatusCode);
23 | }
24 | }
25 |
26 | [Fact]
27 | public async void When_ContentIsSent_Should_ReceiveResponseAndStatusCode200()
28 | {
29 | using (var dispatcher = new WebDavDispatcher(ConfigureHttpClient()))
30 | {
31 | var requestParams = new RequestParameters { Content = new StringContent("content", Encoding.UTF8, "application/xml") };
32 | var response = await dispatcher.Send(new Uri("http://example.com"), HttpMethod.Put, requestParams, CancellationToken.None);
33 |
34 | Assert.IsType(typeof(HttpResponse), response);
35 | Assert.Equal(200, response.StatusCode);
36 | }
37 | }
38 |
39 | [Fact]
40 | public async void When_ResponseIsReceived_Should_ReadContent()
41 | {
42 | const string responseContent = "content";
43 | using (var dispatcher = new WebDavDispatcher(ConfigureHttpClient(responseContent)))
44 | {
45 | var response = await dispatcher.Send(new Uri("http://example.com"), HttpMethod.Get, new RequestParameters(), CancellationToken.None);
46 | Assert.Equal(responseContent, await response.Content.ReadAsStringAsync());
47 | }
48 | }
49 |
50 | [Fact]
51 | public async void When_CancellationIsRequested_Should_CancelRequest()
52 | {
53 | using (var dispatcher = new WebDavDispatcher(ConfigureHttpClient()))
54 | {
55 | var cts = new CancellationTokenSource();
56 | cts.Cancel();
57 |
58 | await Assert.ThrowsAsync(
59 | () => dispatcher.Send(new Uri("http://example.com"), HttpMethod.Get, new RequestParameters(), cts.Token));
60 | }
61 | }
62 |
63 | [Fact]
64 | public async void When_DisposeIsCalled_Should_DisposeHttpClient()
65 | {
66 | var httpClient = ConfigureHttpClient();
67 | using (var dispatcher = new WebDavDispatcher(httpClient))
68 | {
69 | await dispatcher.Send(new Uri("http://example.com"), HttpMethod.Get, new RequestParameters(), CancellationToken.None);
70 | httpClient.DidNotReceive().Dispose();
71 | }
72 |
73 | httpClient.Received().Dispose();
74 | }
75 |
76 | private static HttpClient ConfigureHttpClient(string responseContent = "")
77 | {
78 | var httpClient = Substitute.For();
79 | httpClient
80 | .SendAsync(Arg.Any(), Arg.Any())
81 | .Returns(x =>
82 | {
83 | x.Arg().ThrowIfCancellationRequested();
84 | return Task.FromResult(new HttpResponseMessage { Content = new StringContent(responseContent, Encoding.UTF8, "application/xml") });
85 | });
86 | return httpClient;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("WebDAV-Client.Tests.Net452")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("WebDAV-Client.Tests.Net452")]
13 | [assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("df7de4b0-00dd-4b96-a6ef-7c7c83ce689d")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/Response/LockResponseParserTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using WebDav.Response;
3 | using Xunit;
4 |
5 | namespace WebDav.Client.Tests.Response
6 | {
7 | public class LockResponseParserTests
8 | {
9 | [Fact]
10 | public void When_ResponseIsNull_Should_ReturnEmptyLocksCollection()
11 | {
12 | var parser = new LockResponseParser();
13 | var response = parser.Parse(null, 207, "Multi-Status");
14 |
15 | Assert.Equal(207, response.StatusCode);
16 | Assert.Equal("Multi-Status", response.Description);
17 | Assert.True(response.IsSuccessful);
18 | Assert.Empty(response.ActiveLocks);
19 | }
20 |
21 | [Fact]
22 | public void When_ResponseIsEmpty_Should_ReturnEmptyLocksCollection()
23 | {
24 | const string htmlresponse = "";
25 | var parser = new LockResponseParser();
26 | var response = parser.Parse(htmlresponse, 207, "Multi-Status");
27 |
28 | Assert.Equal(207, response.StatusCode);
29 | Assert.Equal("Multi-Status", response.Description);
30 | Assert.True(response.IsSuccessful);
31 | Assert.Empty(response.ActiveLocks);
32 | }
33 |
34 | [Fact]
35 | public void When_NotValidXml_Should_ReturnEmptyLocksCollection()
36 | {
37 | const string htmlresponse = "";
38 | var parser = new LockResponseParser();
39 | var response = parser.Parse(htmlresponse, 207, "Multi-Status");
40 |
41 | Assert.Equal(207, response.StatusCode);
42 | Assert.Equal("Multi-Status", response.Description);
43 | Assert.True(response.IsSuccessful);
44 | Assert.Empty(response.ActiveLocks);
45 | }
46 |
47 | [Fact]
48 | public void When_ResponseHasEmptyActiveLock_Should_ReturnALockWithDefaultProperties()
49 | {
50 | var parser = new LockResponseParser();
51 | var response = parser.Parse(Responses.Lock.ResponseWithEmptyActiveLock, 207, "Multi-Status");
52 | var activeLock = response.ActiveLocks.ElementAt(0);
53 |
54 | Assert.Equal(207, response.StatusCode);
55 | Assert.Equal("Multi-Status", response.Description);
56 | Assert.True(response.IsSuccessful);
57 | Assert.Equal(1, response.ActiveLocks.Count);
58 |
59 | Assert.Null(activeLock.ApplyTo);
60 | Assert.Null(activeLock.LockScope);
61 | Assert.Null(activeLock.LockToken);
62 | Assert.Null(activeLock.Owner);
63 | Assert.Null(activeLock.LockRoot);
64 | Assert.Null(activeLock.Timeout);
65 | }
66 |
67 | [Fact]
68 | public void When_ResponseHasLockScopeExclusive_Should_ReturnExclusiveLock()
69 | {
70 | var parser = new LockResponseParser();
71 | var response = parser.Parse(Responses.Lock.ResponseWithExclusiveLockScope, 207, "Multi-Status");
72 | var activeLock = response.ActiveLocks.ElementAt(0);
73 |
74 | Assert.Equal(LockScope.Exclusive, activeLock.LockScope);
75 | }
76 |
77 | [Fact]
78 | public void When_ResponseHasLockScopeShared_Should_ReturnSharedLock()
79 | {
80 | var parser = new LockResponseParser();
81 | var response = parser.Parse(Responses.Lock.ResponseWithSharedLockScope, 207, "Multi-Status");
82 | var activeLock = response.ActiveLocks.ElementAt(0);
83 |
84 | Assert.NotNull(activeLock.LockScope);
85 | Assert.Equal(LockScope.Shared, activeLock.LockScope);
86 | }
87 |
88 | [Fact]
89 | public void When_ResponseHasWrongLockScopeValue_Should_ReturnNullLockScope()
90 | {
91 | var parser = new LockResponseParser();
92 | var response = parser.Parse(Responses.Lock.ResponseWithWrongLockScopeValue, 207, "Multi-Status");
93 | var activeLock = response.ActiveLocks.ElementAt(0);
94 |
95 | Assert.Null(activeLock.LockScope);
96 | }
97 |
98 | [Fact]
99 | public void When_ResponseHasDepthInfinity_Should_ReturnLockAppliedToResourceAndAncestors()
100 | {
101 | var parser = new LockResponseParser();
102 | var response = parser.Parse(Responses.Lock.ResponseWithDepthEqualsInfinity, 207, "Multi-Status");
103 | var activeLock = response.ActiveLocks.ElementAt(0);
104 |
105 | Assert.NotNull(activeLock.ApplyTo);
106 | Assert.Equal(ApplyTo.Lock.ResourceAndAncestors, activeLock.ApplyTo);
107 | }
108 |
109 | [Fact]
110 | public void When_ResponseHasDepthInfinity_Should_ReturnLockAppliedToResourceOnly()
111 | {
112 | var parser = new LockResponseParser();
113 | var response = parser.Parse(Responses.Lock.ResponseWithDepthEqualsZero, 207, "Multi-Status");
114 | var activeLock = response.ActiveLocks.ElementAt(0);
115 |
116 | Assert.NotNull(activeLock.ApplyTo);
117 | Assert.Equal(ApplyTo.Lock.ResourceOnly, activeLock.ApplyTo);
118 | }
119 |
120 | [Fact]
121 | public void When_ResponseHasWrongDepthValue_Should_ReturnLockAppliedToResourceAndAncestors()
122 | {
123 | var parser = new LockResponseParser();
124 | var response = parser.Parse(Responses.Lock.ResponseWithWrongDepthValue, 207, "Multi-Status");
125 | var activeLock = response.ActiveLocks.ElementAt(0);
126 |
127 | Assert.NotNull(activeLock.ApplyTo);
128 | Assert.Equal(ApplyTo.Lock.ResourceAndAncestors, activeLock.ApplyTo);
129 | }
130 |
131 | [Fact]
132 | public void When_ResponseHasHrefOwner_Should_ReturnLockWithUriOwner()
133 | {
134 | var parser = new LockResponseParser();
135 | var response = parser.Parse(Responses.Lock.ResponseWithHrefOwner, 207, "Multi-Status");
136 | var activeLock = response.ActiveLocks.ElementAt(0);
137 |
138 | Assert.NotNull(activeLock.Owner);
139 | Assert.IsType(typeof (UriLockOwner), activeLock.Owner);
140 | Assert.Equal("http://example.org/~ejw/contact.html", activeLock.Owner.Value);
141 | }
142 |
143 | [Fact]
144 | public void When_ResponseHasOwnerValue_Should_ReturnLockWithPrincipalOwner()
145 | {
146 | var parser = new LockResponseParser();
147 | var response = parser.Parse(Responses.Lock.ResponseWithPrincipalOwner, 207, "Multi-Status");
148 | var activeLock = response.ActiveLocks.ElementAt(0);
149 |
150 | Assert.NotNull(activeLock.Owner);
151 | Assert.IsType(typeof(PrincipalLockOwner), activeLock.Owner);
152 | Assert.Equal("Chuck Norris", activeLock.Owner.Value);
153 | }
154 |
155 | [Fact]
156 | public void When_ResponseHasTimeout_Should_ReturnTimeoutAsTimeSpan()
157 | {
158 | var parser = new LockResponseParser();
159 | var response = parser.Parse(Responses.Lock.ResponseWithTimeout, 207, "Multi-Status");
160 | var activeLock = response.ActiveLocks.ElementAt(0);
161 |
162 | Assert.NotNull(activeLock.Timeout);
163 | Assert.Equal(119, activeLock.Timeout.Value.TotalSeconds);
164 | }
165 |
166 | [Fact]
167 | public void When_ResponseHasWrongFormattedTimeout_Should_ReturnNullTimeout()
168 | {
169 | var parser = new LockResponseParser();
170 | var response = parser.Parse(Responses.Lock.ResponseWithWrongTimeoutFormat, 207, "Multi-Status");
171 | var activeLock = response.ActiveLocks.ElementAt(0);
172 |
173 | Assert.Null(activeLock.Timeout);
174 | }
175 |
176 | [Fact]
177 | public void When_ResponseHasLockToken_Should_ReturnLockWithIt()
178 | {
179 | var parser = new LockResponseParser();
180 | var response = parser.Parse(Responses.Lock.ResponseWithLockToken, 207, "Multi-Status");
181 | var activeLock = response.ActiveLocks.ElementAt(0);
182 |
183 | Assert.Equal("urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4", activeLock.LockToken);
184 | }
185 |
186 | [Fact]
187 | public void When_ResponseHasLockRoot_Should_ReturnLockWithIt()
188 | {
189 | var parser = new LockResponseParser();
190 | var response = parser.Parse(Responses.Lock.ResponseWithLockRoot, 207, "Multi-Status");
191 | var activeLock = response.ActiveLocks.ElementAt(0);
192 |
193 | Assert.Equal("http://example.com/workspace/webdav/proposal.doc", activeLock.LockRoot);
194 | }
195 |
196 | [Fact]
197 | public void When_ResponseHasStandardProperties_Should_ParseIt()
198 | {
199 | var parser = new LockResponseParser();
200 | var response = parser.Parse(Responses.Lock.ResponseWithStandardProperties, 207, "Multi-Status");
201 | var activeLock = response.ActiveLocks.ElementAt(0);
202 |
203 | Assert.Equal(ApplyTo.Lock.ResourceOnly, activeLock.ApplyTo);
204 | Assert.Equal(LockScope.Shared, activeLock.LockScope);
205 | Assert.Equal("opaquelocktoken:15f67ec5-e229-4816-8cc7-d73f88d32220.c88101d1141db2de", activeLock.LockToken);
206 | Assert.Equal("Chuck Norris", activeLock.Owner.Value);
207 | Assert.Equal("http://example.com/1.txt", activeLock.LockRoot);
208 | Assert.Equal(20, activeLock.Timeout.Value.TotalSeconds);
209 | }
210 |
211 | [Fact]
212 | public void When_ResponseHasSeveralLocks_Should_ReturnThemAll()
213 | {
214 | var parser = new LockResponseParser();
215 | var response = parser.Parse(Responses.Lock.ResponseWithTwoLocks, 207, "Multi-Status");
216 |
217 | Assert.Equal(2, response.ActiveLocks.Count);
218 | }
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/Response/ProppatchResponseParserTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using WebDav.Response;
3 | using Xunit;
4 |
5 | namespace WebDav.Client.Tests.Response
6 | {
7 | public class ProppatchResponseParserTests
8 | {
9 | [Fact]
10 | public void When_ResponseIsNull_Should_ReturnEmptyPropertyStatusesCollection()
11 | {
12 | var parser = new ProppatchResponseParser();
13 | var response = parser.Parse(null, 207, "Multi-Status");
14 |
15 | Assert.Equal(207, response.StatusCode);
16 | Assert.Equal("Multi-Status", response.Description);
17 | Assert.True(response.IsSuccessful);
18 | Assert.Empty(response.PropertyStatuses);
19 | }
20 |
21 | [Fact]
22 | public void When_ResponseIsEmpty_Should_ReturnEmptyPropertyStatusesCollection()
23 | {
24 | const string htmlresponse = "";
25 | var parser = new ProppatchResponseParser();
26 | var response = parser.Parse(htmlresponse, 207, "Multi-Status");
27 |
28 | Assert.Equal(207, response.StatusCode);
29 | Assert.Equal("Multi-Status", response.Description);
30 | Assert.True(response.IsSuccessful);
31 | Assert.Empty(response.PropertyStatuses);
32 | }
33 |
34 | [Fact]
35 | public void When_NotValidXml_Should_ReturnEmptyPropertyStatusesCollection()
36 | {
37 | const string htmlresponse = "";
38 | var parser = new ProppatchResponseParser();
39 | var response = parser.Parse(htmlresponse, 207, "Multi-Status");
40 |
41 | Assert.Equal(207, response.StatusCode);
42 | Assert.Equal("Multi-Status", response.Description);
43 | Assert.True(response.IsSuccessful);
44 | Assert.Empty(response.PropertyStatuses);
45 | }
46 |
47 | [Fact]
48 | public void When_EmptyMultiStatus_Should_ReturnEmptyResourcesCollection()
49 | {
50 | var parser = new ProppatchResponseParser();
51 | var response = parser.Parse(Responses.Common.EmptyMultiStatusResponse, 207, "Multi-Status");
52 |
53 | Assert.Equal(207, response.StatusCode);
54 | Assert.Equal("Multi-Status", response.Description);
55 | Assert.True(response.IsSuccessful);
56 | Assert.Empty(response.PropertyStatuses);
57 | }
58 |
59 | [Fact]
60 | public void When_ResponseHasProperties_Should_ReturnTheirStatus()
61 | {
62 | var parser = new ProppatchResponseParser();
63 | var response = parser.Parse(Responses.Proppatch.ResponseWithDifferentStatuses, 207, "Multi-Status");
64 | var status1 = response.PropertyStatuses.ElementAt(0);
65 | var status2 = response.PropertyStatuses.ElementAt(1);
66 |
67 | Assert.Equal(2, response.PropertyStatuses.Count);
68 |
69 | Assert.Equal(200, status1.StatusCode);
70 | Assert.True(status1.IsSuccessful);
71 | Assert.Equal("{DAV:}getcontenttype", status1.Name);
72 | Assert.Equal("HTTP/1.1 200 OK", status1.Description);
73 |
74 | Assert.Equal(424, status2.StatusCode);
75 | Assert.False(status2.IsSuccessful);
76 | Assert.Equal("{http://ns.example.com/}myprop", status2.Name);
77 | Assert.Equal("HTTP/1.1 424 Failed Dependency", status2.Description);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/TestDoubles/Dispatcher.cs:
--------------------------------------------------------------------------------
1 | using NSubstitute;
2 | using System;
3 | using System.Net.Http;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using WebDav.Infrastructure;
8 |
9 | namespace WebDav.Client.Tests.TestDoubles
10 | {
11 | public static class Dispatcher
12 | {
13 | internal static IWebDavDispatcher Mock(string content = "", int statusCode = 200, string description = "OK")
14 | {
15 | var dispatcher = Substitute.For();
16 | dispatcher
17 | .Send(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any())
18 | .Returns(x => Task.FromResult(new HttpResponse(new StringContent(content, Encoding.UTF8, "application/xml"), statusCode, description)));
19 | return dispatcher;
20 | }
21 |
22 | internal static IWebDavDispatcher MockFaulted()
23 | {
24 | var dispatcher = Substitute.For();
25 | dispatcher
26 | .Send(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any())
27 | .Returns(x => Task.FromResult(new HttpResponse(new StringContent(string.Empty), 500, "Internal Server Error")));
28 | return dispatcher;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDAV-Client.Tests.Net452.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Debug
8 | AnyCPU
9 | {DF7DE4B0-00DD-4B96-A6EF-7C7C83CE689D}
10 | Library
11 | Properties
12 | WebDAV_Client.Tests.Net452
13 | WebDAV-Client.Tests.Net452
14 | v4.5.2
15 | 512
16 |
17 |
18 |
19 |
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 | ..\..\packages\NSubstitute.1.10.0.0\lib\net45\NSubstitute.dll
39 | True
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | ..\..\src\WebDAV-Client\bin\$(Configuration)\net45\WebDAV-Client.dll
49 |
50 |
51 | ..\..\packages\xunit.abstractions.2.0.2\lib\net35\xunit.abstractions.dll
52 | True
53 |
54 |
55 | ..\..\packages\xunit.assert.2.4.0\lib\netstandard1.1\xunit.assert.dll
56 |
57 |
58 | ..\..\packages\xunit.extensibility.core.2.4.0\lib\net452\xunit.core.dll
59 |
60 |
61 | ..\..\packages\xunit.extensibility.execution.2.4.0\lib\net452\xunit.execution.desktop.dll
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
97 |
98 |
99 |
100 |
101 |
102 |
103 |
110 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/CopyTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Net.Http;
5 | using System.Threading;
6 | using NSubstitute;
7 | using WebDav.Client.Tests.TestDoubles;
8 | using Xunit;
9 |
10 | namespace WebDav.Client.Tests.WebDavClientTests
11 | {
12 | public class CopyTests
13 | {
14 | [Fact]
15 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
16 | {
17 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
18 | var response1 = await client.Copy("http://example.com/old", "http://example.com/new");
19 | var response2 = await client.Copy(new Uri("http://example.com/old"), new Uri("http://example.com/new"));
20 | var response3 = await client.Copy("http://example.com/old", "http://example.com/new", new CopyParameters());
21 | var response4 = await client.Copy(new Uri("http://example.com/old"), new Uri("http://example.com/new"), new CopyParameters());
22 |
23 | Assert.Equal(200, response1.StatusCode);
24 | Assert.Equal(200, response2.StatusCode);
25 | Assert.Equal(200, response3.StatusCode);
26 | Assert.Equal(200, response4.StatusCode);
27 | }
28 |
29 | [Fact]
30 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
31 | {
32 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
33 | var response = await client.Copy("http://example.com/old", "http://example.com/new");
34 | Assert.Equal(500, response.StatusCode);
35 | }
36 |
37 | [Fact]
38 | public async void When_IsCalled_Should_SendCopyRequest()
39 | {
40 | var sourceUri = new Uri("http://example.com/old");
41 | var dispatcher = Dispatcher.Mock();
42 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
43 |
44 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
45 | await client.Copy(sourceUri, new Uri("http://example.com/new"));
46 | await dispatcher.Received(1)
47 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(CheckCopyRequestParameters()), CancellationToken.None);
48 | }
49 |
50 | [Fact]
51 | public async void When_IsCalled_Should_SendDestinationHeader()
52 | {
53 | var sourceUri = new Uri("http://example.com/old");
54 | var dispatcher = Dispatcher.Mock();
55 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
56 |
57 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
58 | await client.Copy(sourceUri, new Uri("http://example.com/new"));
59 | await dispatcher.Received(1)
60 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Destination", "http://example.com/new")), CancellationToken.None);
61 | }
62 |
63 | [Fact]
64 | public async void When_IsCalledWithDefaultParameters_Should_SendOverwriteHeaderEqualsT()
65 | {
66 | var sourceUri = new Uri("http://example.com/old");
67 | var dispatcher = Dispatcher.Mock();
68 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
69 |
70 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
71 | await client.Copy(sourceUri, new Uri("http://example.com/new"));
72 | await dispatcher.Received(1)
73 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Overwrite", "T")), CancellationToken.None);
74 | }
75 |
76 | [Fact]
77 | public async void When_IsCalledWithDefaultParameters_Should_SendDepthHeaderEqualsInfinity()
78 | {
79 | var sourceUri = new Uri("http://example.com/old");
80 | var dispatcher = Dispatcher.Mock();
81 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
82 |
83 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
84 | await client.Copy(sourceUri, new Uri("http://example.com/new"));
85 | await dispatcher.Received(1)
86 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Depth", "infinity")), CancellationToken.None);
87 | }
88 |
89 | [Fact]
90 | public async void When_IsCalledWithOverwriteOff_Should_SendOverwriteHeaderEqualsF()
91 | {
92 | var sourceUri = new Uri("http://example.com/old");
93 | var dispatcher = Dispatcher.Mock();
94 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
95 |
96 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
97 | await client.Copy(sourceUri, new Uri("http://example.com/new"), new CopyParameters { Overwrite = false });
98 | await dispatcher.Received(1)
99 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Overwrite", "F")), CancellationToken.None);
100 | }
101 |
102 | [Fact]
103 | public async void When_IsCalledWithOverwriteOn_Should_SendOverwriteHeaderEqualsT()
104 | {
105 | var sourceUri = new Uri("http://example.com/old");
106 | var dispatcher = Dispatcher.Mock();
107 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
108 |
109 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
110 | await client.Copy(sourceUri, new Uri("http://example.com/new"), new CopyParameters { Overwrite = true });
111 | await dispatcher.Received(1)
112 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Overwrite", "T")), CancellationToken.None);
113 | }
114 |
115 | [Fact]
116 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
117 | {
118 | var cts = new CancellationTokenSource();
119 | var dispatcher = Dispatcher.Mock();
120 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
121 |
122 | await client.Copy("http://example.com/old", "http://example.com/new", new CopyParameters { CancellationToken = cts.Token });
123 | await dispatcher.Received(1)
124 | .Send(Arg.Any(), WebDavMethod.Copy, Arg.Is(CheckCopyRequestParameters()), cts.Token);
125 | }
126 |
127 | [Fact]
128 | public async void When_IsAppliedToResourceAndAncestors_Should_SendDepthHeaderEqualsInfinity()
129 | {
130 | var sourceUri = new Uri("http://example.com/old");
131 | var dispatcher = Dispatcher.Mock();
132 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
133 |
134 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
135 | await client.Copy(sourceUri, new Uri("http://example.com/new"), new CopyParameters { ApplyTo = ApplyTo.Copy.ResourceAndAncestors});
136 | await dispatcher.Received(1)
137 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Depth", "infinity")), CancellationToken.None);
138 | }
139 |
140 | [Fact]
141 | public async void When_IsAppliedToResourceOnly_Should_SendDepthHeaderEqualsZero()
142 | {
143 | var sourceUri = new Uri("http://example.com/old");
144 | var dispatcher = Dispatcher.Mock();
145 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
146 |
147 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
148 | await client.Copy(sourceUri, new Uri("http://example.com/new"), new CopyParameters { ApplyTo = ApplyTo.Copy.ResourceOnly });
149 | await dispatcher.Received(1)
150 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("Depth", "0")), CancellationToken.None);
151 | }
152 |
153 | [Fact]
154 | public async void When_IsCalledWithLockToken_Should_SetIfHeader()
155 | {
156 | var sourceUri = new Uri("http://example.com/old");
157 | var dispatcher = Dispatcher.Mock();
158 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
159 |
160 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
161 | await client.Copy(sourceUri, new Uri("http://example.com/new"), new CopyParameters { DestLockToken = "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4" });
162 | await dispatcher.Received(1)
163 | .Send(sourceUri, WebDavMethod.Copy, Arg.Is(Predicates.CompareHeader("If", "()")), CancellationToken.None);
164 | }
165 |
166 | internal Expression> CheckCopyRequestParameters()
167 | {
168 | return x =>
169 | x.Headers.Any(h => h.Key == "Destination") &&
170 | x.Headers.Any(h => h.Key == "Depth") &&
171 | x.Headers.Any(h => h.Key == "Overwrite") &&
172 | x.Content == null;
173 | }
174 | }
175 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/DeleteTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using NSubstitute;
6 | using WebDav.Client.Tests.TestDoubles;
7 | using Xunit;
8 |
9 | namespace WebDav.Client.Tests.WebDavClientTests
10 | {
11 | public class DeleteTests
12 | {
13 | [Fact]
14 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
15 | {
16 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
17 | var response1 = await client.Delete("http://example.com/file");
18 | var response2 = await client.Delete(new Uri("http://example.com/file"));
19 | var response3 = await client.Delete("http://example.com/file", new DeleteParameters());
20 | var response4 = await client.Delete(new Uri("http://example.com/file"), new DeleteParameters());
21 |
22 | Assert.Equal(200, response1.StatusCode);
23 | Assert.Equal(200, response2.StatusCode);
24 | Assert.Equal(200, response3.StatusCode);
25 | Assert.Equal(200, response4.StatusCode);
26 | }
27 |
28 | [Fact]
29 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
30 | {
31 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
32 | var response = await client.Delete("http://example.com/file");
33 | Assert.Equal(500, response.StatusCode);
34 | }
35 |
36 | [Fact]
37 | public async void When_IsCalledWithDefaultArguments_Should_SendDeleteRequest()
38 | {
39 | var requestUri = new Uri("http://example.com/file");
40 | var dispatcher = Dispatcher.Mock();
41 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
42 |
43 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
44 | await client.Delete(requestUri);
45 | await dispatcher.Received(1)
46 | .Send(requestUri, HttpMethod.Delete, Arg.Is(x => !x.Headers.Any() && x.Content == null), CancellationToken.None);
47 | }
48 |
49 | [Fact]
50 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
51 | {
52 | var cts = new CancellationTokenSource();
53 | var dispatcher = Dispatcher.Mock();
54 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
55 |
56 | await client.Delete("http://example.com/file", new DeleteParameters { CancellationToken = cts.Token });
57 | await dispatcher.Received(1)
58 | .Send(Arg.Any(), HttpMethod.Delete, Arg.Is(x => !x.Headers.Any() && x.Content == null), cts.Token);
59 | }
60 |
61 | [Fact]
62 | public async void When_IsCalledWithLockToken_Should_SetIfHeader()
63 | {
64 | var requestUri = new Uri("http://example.com/file");
65 | var dispatcher = Dispatcher.Mock();
66 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
67 |
68 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
69 | await client.Delete(requestUri, new DeleteParameters { LockToken = "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4" });
70 | await dispatcher.Received(1)
71 | .Send(requestUri, HttpMethod.Delete, Arg.Is(Predicates.CompareHeader("If", "()")), CancellationToken.None);
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/GetFileTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using NSubstitute;
6 | using WebDav.Client.Tests.TestDoubles;
7 | using Xunit;
8 |
9 | namespace WebDav.Client.Tests.WebDavClientTests
10 | {
11 | public class GetFileTests
12 | {
13 | [Fact]
14 | public async void When_GetRawFileIsCalled_Should_ProxyCallToGetFile()
15 | {
16 | var client = Substitute.ForPartsOf().SetWebDavDispatcher(Dispatcher.Mock());
17 | client.GetFile(Arg.Any(), Arg.Any(), Arg.Any()).Returns(new WebDavStreamResponse(200));
18 |
19 | await client.GetRawFile(new Uri("http://example.com/file"));
20 | await client.GetRawFile("http://example.com/file");
21 | await client.GetRawFile(new Uri("http://example.com/file"), new GetFileParameters());
22 | await client.GetRawFile("http://example.com/file", new GetFileParameters());
23 |
24 | await client.Received(4).GetFile(Arg.Is(x => x.ToString() == "http://example.com/file"), false, CancellationToken.None);
25 | }
26 |
27 | [Fact]
28 | public async void When_GetProcessedFileIsCalled_Should_ProxyCallToGetFile()
29 | {
30 | var client = Substitute.ForPartsOf().SetWebDavDispatcher(Dispatcher.Mock());
31 | client.GetFile(Arg.Any(), Arg.Any(), Arg.Any()).Returns(new WebDavStreamResponse(200));
32 |
33 | await client.GetProcessedFile(new Uri("http://example.com/file"));
34 | await client.GetProcessedFile("http://example.com/file");
35 | await client.GetProcessedFile(new Uri("http://example.com/file"), new GetFileParameters());
36 | await client.GetProcessedFile("http://example.com/file", new GetFileParameters());
37 |
38 | await client.Received(4).GetFile(Arg.Is(x => x.ToString() == "http://example.com/file"), true, CancellationToken.None);
39 | }
40 |
41 | [Fact]
42 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
43 | {
44 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
45 | var response1 = await client.GetFile(new Uri("http://example.com/file"), false, CancellationToken.None);
46 | var response2 = await client.GetFile(new Uri("http://example.com/file"), true, CancellationToken.None);
47 |
48 | Assert.Equal(200, response1.StatusCode);
49 | Assert.Equal(200, response2.StatusCode);
50 | }
51 |
52 | [Fact]
53 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
54 | {
55 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
56 | var response1 = await client.GetFile(new Uri("http://example.com/file"), false, CancellationToken.None);
57 | var response2 = await client.GetFile(new Uri("http://example.com/file"), true, CancellationToken.None);
58 |
59 | Assert.Equal(500, response1.StatusCode);
60 | Assert.Equal(500, response2.StatusCode);
61 | }
62 |
63 | [Fact]
64 | public async void When_GetFile_Should_SendGetRequest()
65 | {
66 | var requestUri = new Uri("http://example.com/file");
67 | var dispatcher = Dispatcher.Mock();
68 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
69 |
70 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
71 | await client.GetFile(requestUri, false, CancellationToken.None);
72 | await client.GetFile(requestUri, true, CancellationToken.None);
73 | await dispatcher.Received(2)
74 | .Send(requestUri, HttpMethod.Get, Arg.Is(x => x.Content == null), CancellationToken.None);
75 | }
76 |
77 | [Fact]
78 | public async void When_IsCalledWithTranslateOff_Should_SendTranslateHeaderEqualsF()
79 | {
80 | var requestUri = new Uri("http://example.com/file");
81 | var dispatcher = Dispatcher.Mock();
82 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
83 |
84 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
85 | await client.GetFile(requestUri, false, CancellationToken.None);
86 | await dispatcher.Received(1)
87 | .Send(requestUri, HttpMethod.Get, Arg.Is(Predicates.CompareHeader("Translate", "f")), CancellationToken.None);
88 | }
89 |
90 | [Fact]
91 | public async void When_IsCalledWithTranslateOn_Should_SendTranslateHeaderEqualsT()
92 | {
93 | var requestUri = new Uri("http://example.com/file");
94 | var dispatcher = Dispatcher.Mock();
95 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
96 |
97 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
98 | await client.GetFile(requestUri, true, CancellationToken.None);
99 | await dispatcher.Received(1)
100 | .Send(requestUri, HttpMethod.Get, Arg.Is(Predicates.CompareHeader("Translate", "t")), CancellationToken.None);
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/LockTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using NSubstitute;
7 | using WebDav.Client.Tests.TestDoubles;
8 | using Xunit;
9 |
10 | namespace WebDav.Client.Tests.WebDavClientTests
11 | {
12 | public class LockTests
13 | {
14 | [Fact]
15 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
16 | {
17 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
18 | var response1 = await client.Lock("http://example.com/new");
19 | var response2 = await client.Lock(new Uri("http://example.com/new"));
20 | var response3 = await client.Lock("http://example.com/new", new LockParameters());
21 | var response4 = await client.Lock(new Uri("http://example.com/new"), new LockParameters());
22 |
23 | Assert.Equal(200, response1.StatusCode);
24 | Assert.Equal(200, response2.StatusCode);
25 | Assert.Equal(200, response3.StatusCode);
26 | Assert.Equal(200, response4.StatusCode);
27 | }
28 |
29 | [Fact]
30 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
31 | {
32 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
33 | var response = await client.Lock("http://example.com/new");
34 | Assert.Equal(500, response.StatusCode);
35 | }
36 |
37 | [Fact]
38 | public async void When_IsCalled_Should_SendLockRequest()
39 | {
40 | var requestUri = new Uri("http://example.com/new");
41 | var dispatcher = Dispatcher.Mock();
42 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
43 |
44 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
45 | await client.Lock(requestUri);
46 | await dispatcher.Received(1)
47 | .Send(requestUri, WebDavMethod.Lock, Arg.Any(), CancellationToken.None);
48 | }
49 |
50 | [Fact]
51 | public async void When_IsCalledWithDefaultArguments_Should_SendNoHeaders()
52 | {
53 | var requestUri = new Uri("http://example.com/new");
54 | var dispatcher = Dispatcher.Mock();
55 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
56 |
57 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
58 | await client.Lock(requestUri);
59 | await dispatcher.Received(1)
60 | .Send(requestUri, WebDavMethod.Lock, Arg.Is(x => !x.Headers.Any()), CancellationToken.None);
61 | }
62 |
63 | [Fact]
64 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
65 | {
66 | var cts = new CancellationTokenSource();
67 | var dispatcher = Dispatcher.Mock();
68 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
69 |
70 | await client.Lock("http://example.com/new", new LockParameters { CancellationToken = cts.Token });
71 | await dispatcher.Received(1)
72 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Any(), cts.Token);
73 | }
74 |
75 | [Fact]
76 | public async void When_IsAppliedToResourceAndAncestors_Should_SendDepthHeaderEqualsInfinity()
77 | {
78 | var dispatcher = Dispatcher.Mock();
79 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
80 |
81 | await client.Lock("http://example.com", new LockParameters { ApplyTo = ApplyTo.Lock.ResourceAndAncestors });
82 | await dispatcher.Received(1)
83 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareHeader("Depth", "infinity")), CancellationToken.None);
84 | }
85 |
86 | [Fact]
87 | public async void When_IsAppliedToResourceOnly_Should_SendDepthHeaderEqualsZero()
88 | {
89 | var dispatcher = Dispatcher.Mock();
90 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
91 |
92 | await client.Lock("http://example.com", new LockParameters { ApplyTo = ApplyTo.Lock.ResourceOnly });
93 | await dispatcher.Received(1)
94 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareHeader("Depth", "0")), CancellationToken.None);
95 | }
96 |
97 | [Fact]
98 | public async void When_IsCalledWithTimeout_Should_SendTimeoutHeaderInSeconds()
99 | {
100 | var dispatcher = Dispatcher.Mock();
101 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
102 |
103 | await client.Lock("http://example.com", new LockParameters { Timeout = TimeSpan.FromMinutes(2) });
104 | await dispatcher.Received(1)
105 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareHeader("Timeout", "Second-120")), CancellationToken.None);
106 | }
107 |
108 | [Fact]
109 | public async void When_IsCalledWithDefaultArguments_Should_SendLockInfo()
110 | {
111 | const string expectedContent =
112 | @"
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | ";
121 | var dispatcher = Dispatcher.Mock();
122 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
123 |
124 | await client.Lock("http://example.com");
125 | await dispatcher.Received(1)
126 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
127 | }
128 |
129 | [Fact]
130 | public async void When_IsCalledWithLockScopeShared_Should_AddSharedLockScopeToContent()
131 | {
132 | const string expectedContent =
133 | @"
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | ";
142 | var dispatcher = Dispatcher.Mock();
143 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
144 |
145 | await client.Lock("http://example.com", new LockParameters { LockScope = LockScope.Shared});
146 | await dispatcher.Received(1)
147 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
148 | }
149 |
150 | [Fact]
151 | public async Task When_IsCalledWithLockScopeExclusive_Should_AddExclusiveLockScopeToContent()
152 | {
153 | const string expectedContent =
154 | @"
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | ";
163 | var dispatcher = Dispatcher.Mock();
164 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
165 |
166 | await client.Lock("http://example.com", new LockParameters { LockScope = LockScope.Exclusive });
167 | await dispatcher.Received(1)
168 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(x => x.Content.ReadAsStringAsync().Result == expectedContent), CancellationToken.None);
169 | }
170 |
171 | [Fact]
172 | public async void When_IsCalledWithPrincipalLockOwner_Should_AddOwnerToContent()
173 | {
174 | const string expectedContent =
175 | @"
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 | James Bond
184 | ";
185 | var dispatcher = Dispatcher.Mock();
186 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
187 |
188 | await client.Lock("http://example.com", new LockParameters { Owner = new PrincipalLockOwner("James Bond") });
189 | await dispatcher.Received(1)
190 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
191 | }
192 |
193 | [Fact]
194 | public async void When_IsCalledWithUriLockOwner_Should_AddOwnerToContent()
195 | {
196 | const string expectedContent =
197 | @"
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 | http://example.com/owner
207 |
208 | ";
209 | var dispatcher = Dispatcher.Mock();
210 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
211 |
212 | await client.Lock("http://example.com", new LockParameters { Owner = new UriLockOwner("http://example.com/owner") });
213 | await dispatcher.Received(1)
214 | .Send(Arg.Any(), WebDavMethod.Lock, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
215 | }
216 | }
217 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/MkcolTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using NSubstitute;
6 | using WebDav.Client.Tests.TestDoubles;
7 | using Xunit;
8 |
9 | namespace WebDav.Client.Tests.WebDavClientTests
10 | {
11 | public class MkcolTests
12 | {
13 | [Fact]
14 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
15 | {
16 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
17 | var response1 = await client.Mkcol("http://example.com/new");
18 | var response2 = await client.Mkcol(new Uri("http://example.com/new"));
19 | var response3 = await client.Mkcol("http://example.com/new", new MkColParameters());
20 | var response4 = await client.Mkcol(new Uri("http://example.com/new"), new MkColParameters());
21 |
22 | Assert.Equal(200, response1.StatusCode);
23 | Assert.Equal(200, response2.StatusCode);
24 | Assert.Equal(200, response3.StatusCode);
25 | Assert.Equal(200, response4.StatusCode);
26 | }
27 |
28 | [Fact]
29 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
30 | {
31 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
32 | var response = await client.Mkcol("http://example.com/new");
33 | Assert.Equal(500, response.StatusCode);
34 | }
35 |
36 | [Fact]
37 | public async void When_IsCalledWithDefaultArguments_Should_SendMkcolRequest()
38 | {
39 | var requestUri = new Uri("http://example.com/new");
40 | var dispatcher = Dispatcher.Mock();
41 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
42 |
43 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
44 | await client.Mkcol(requestUri);
45 | await dispatcher.Received(1)
46 | .Send(requestUri, WebDavMethod.Mkcol, Arg.Is(x => !x.Headers.Any() && x.Content == null), CancellationToken.None);
47 | }
48 |
49 | [Fact]
50 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
51 | {
52 | var cts = new CancellationTokenSource();
53 | var dispatcher = Dispatcher.Mock();
54 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
55 |
56 | await client.Mkcol("http://example.com/new", new MkColParameters { CancellationToken = cts.Token });
57 | await dispatcher.Received(1)
58 | .Send(Arg.Any(), WebDavMethod.Mkcol, Arg.Is(x => !x.Headers.Any() && x.Content == null), cts.Token);
59 | }
60 |
61 | [Fact]
62 | public async void When_IsCalledWithLockToken_Should_SetIfHeader()
63 | {
64 | var requestUri = new Uri("http://example.com/new");
65 | var dispatcher = Dispatcher.Mock();
66 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
67 |
68 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
69 | await client.Mkcol(requestUri, new MkColParameters { LockToken = "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4" });
70 | await dispatcher.Received(1)
71 | .Send(requestUri, WebDavMethod.Mkcol, Arg.Is(Predicates.CompareHeader("If", "()")), CancellationToken.None);
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/MoveTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 | using System.Net.Http;
5 | using System.Threading;
6 | using NSubstitute;
7 | using WebDav.Client.Tests.TestDoubles;
8 | using Xunit;
9 |
10 | namespace WebDav.Client.Tests.WebDavClientTests
11 | {
12 | public class MoveTests
13 | {
14 | [Fact]
15 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
16 | {
17 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
18 | var response1 = await client.Move("http://example.com/old", "http://example.com/new");
19 | var response2 = await client.Move(new Uri("http://example.com/old"), new Uri("http://example.com/new"));
20 | var response3 = await client.Move("http://example.com/old", "http://example.com/new", new MoveParameters());
21 | var response4 = await client.Move(new Uri("http://example.com/old"), new Uri("http://example.com/new"), new MoveParameters());
22 |
23 | Assert.Equal(200, response1.StatusCode);
24 | Assert.Equal(200, response2.StatusCode);
25 | Assert.Equal(200, response3.StatusCode);
26 | Assert.Equal(200, response4.StatusCode);
27 | }
28 |
29 | [Fact]
30 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
31 | {
32 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
33 | var response = await client.Move("http://example.com/old", "http://example.com/new");
34 | Assert.Equal(500, response.StatusCode);
35 | }
36 |
37 | [Fact]
38 | public async void When_IsCalled_Should_SendMoveRequest()
39 | {
40 | var sourceUri = new Uri("http://example.com/old");
41 | var dispatcher = Dispatcher.Mock();
42 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
43 |
44 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
45 | await client.Move(sourceUri, new Uri("http://example.com/new"));
46 | await dispatcher.Received(1)
47 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(CheckMoveRequestParameters()), CancellationToken.None);
48 | }
49 |
50 | [Fact]
51 | public async void When_IsCalled_Should_SendDestinationHeader()
52 | {
53 | var sourceUri = new Uri("http://example.com/old");
54 | var dispatcher = Dispatcher.Mock();
55 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
56 |
57 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
58 | await client.Move(sourceUri, new Uri("http://example.com/new"));
59 | await dispatcher.Received(1)
60 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(Predicates.CompareHeader("Destination", "http://example.com/new")), CancellationToken.None);
61 | }
62 |
63 | [Fact]
64 | public async void When_IsCalledWithDefaultParameters_Should_SendOverwriteHeaderEqualsT()
65 | {
66 | var sourceUri = new Uri("http://example.com/old");
67 | var dispatcher = Dispatcher.Mock();
68 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
69 |
70 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
71 | await client.Move(sourceUri, new Uri("http://example.com/new"));
72 | await dispatcher.Received(1)
73 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(Predicates.CompareHeader("Overwrite", "T")), CancellationToken.None);
74 | }
75 |
76 | [Fact]
77 | public async void When_IsCalledWithOverwriteOff_Should_SendOverwriteHeaderEqualsF()
78 | {
79 | var sourceUri = new Uri("http://example.com/old");
80 | var dispatcher = Dispatcher.Mock();
81 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
82 |
83 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
84 | await client.Move(sourceUri, new Uri("http://example.com/new"), new MoveParameters { Overwrite = false });
85 | await dispatcher.Received(1)
86 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(Predicates.CompareHeader("Overwrite", "F")), CancellationToken.None);
87 | }
88 |
89 | [Fact]
90 | public async void When_IsCalledWithOverwriteOn_Should_SendOverwriteHeaderEqualsT()
91 | {
92 | var sourceUri = new Uri("http://example.com/old");
93 | var dispatcher = Dispatcher.Mock();
94 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
95 |
96 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
97 | await client.Move(sourceUri, new Uri("http://example.com/new"), new MoveParameters { Overwrite = true });
98 | await dispatcher.Received(1)
99 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(Predicates.CompareHeader("Overwrite", "T")), CancellationToken.None);
100 | }
101 |
102 | [Fact]
103 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
104 | {
105 | var cts = new CancellationTokenSource();
106 | var dispatcher = Dispatcher.Mock();
107 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
108 |
109 | await client.Move("http://example.com/old", "http://example.com/new", new MoveParameters { CancellationToken = cts.Token });
110 | await dispatcher.Received(1)
111 | .Send(Arg.Any(), WebDavMethod.Move, Arg.Is(CheckMoveRequestParameters()), cts.Token);
112 | }
113 |
114 | [Fact]
115 | public async void When_IsCalledWithDestLockToken_Should_SetIfHeader()
116 | {
117 | var sourceUri = new Uri("http://example.com/old");
118 | var dispatcher = Dispatcher.Mock();
119 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
120 |
121 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
122 | await client.Move(sourceUri, new Uri("http://example.com/new"), new MoveParameters { DestLockToken = "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4" });
123 | await dispatcher.Received(1)
124 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(Predicates.CompareHeader("If", "()")), CancellationToken.None);
125 | }
126 |
127 | [Fact]
128 | public async void When_IsCalledWithSourceLockToken_Should_SetIfHeader()
129 | {
130 | var sourceUri = new Uri("http://example.com/old");
131 | var dispatcher = Dispatcher.Mock();
132 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
133 |
134 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
135 | await client.Move(sourceUri, new Uri("http://example.com/new"), new MoveParameters { SourceLockToken = "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6" });
136 | await dispatcher.Received(1)
137 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(Predicates.CompareHeader("If", "()")), CancellationToken.None);
138 | }
139 |
140 | [Fact]
141 | public async void When_IsCalledWithBothLockTokens_Should_SetIfHeaderWithBothTokens()
142 | {
143 | var sourceUri = new Uri("http://example.com/old");
144 | var dispatcher = Dispatcher.Mock();
145 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
146 |
147 | await dispatcher.DidNotReceiveWithAnyArgs().Send(sourceUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
148 | await client.Move(sourceUri, new Uri("http://example.com/new"),
149 | new MoveParameters
150 | {
151 | SourceLockToken = "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
152 | DestLockToken = "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4"
153 | });
154 | await dispatcher.Received(1)
155 | .Send(sourceUri, WebDavMethod.Move, Arg.Is(CheckIfHeader()), CancellationToken.None);
156 | }
157 |
158 | internal Expression> CheckIfHeader()
159 | {
160 | return x => x.Headers.Any(h => h.Key == "If" && h.Value == "()") &&
161 | x.Headers.Any(h => h.Key == "If" && h.Value == "()");
162 | }
163 |
164 | internal Expression> CheckMoveRequestParameters()
165 | {
166 | return x =>
167 | x.Headers.Any(h => h.Key == "Destination") &&
168 | x.Headers.Any(h => h.Key == "Overwrite") &&
169 | x.Content == null;
170 | }
171 | }
172 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/Predicates.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Linq.Expressions;
4 |
5 | namespace WebDav.Client.Tests.WebDavClientTests
6 | {
7 | internal static class Predicates
8 | {
9 | public static Expression> CompareHeader(string headerName, string headerValue)
10 | {
11 | return x => x.Headers.Any(h => h.Key == headerName && h.Value == headerValue);
12 | }
13 |
14 | public static Expression> CompareRequestContent(string expectedContent)
15 | {
16 | return x => expectedContent == x.Content.ReadAsStringAsync().Result;
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/PropfindTests.cs:
--------------------------------------------------------------------------------
1 | using NSubstitute;
2 | using System;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using System.Xml.Linq;
7 | using WebDav.Client.Tests.TestDoubles;
8 | using WebDav.Response;
9 | using Xunit;
10 |
11 | namespace WebDav.Client.Tests.WebDavClientTests
12 | {
13 | public class PropfindTests
14 | {
15 | [Fact]
16 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
17 | {
18 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
19 | var response1 = await client.Propfind("http://example.com");
20 | var response2 = await client.Propfind(new Uri("http://example.com"));
21 | var response3 = await client.Propfind("http://example.com", new PropfindParameters());
22 | var response4 = await client.Propfind(new Uri("http://example.com"), new PropfindParameters());
23 |
24 | Assert.Equal(200, response1.StatusCode);
25 | Assert.Equal(200, response2.StatusCode);
26 | Assert.Equal(200, response3.StatusCode);
27 | Assert.Equal(200, response4.StatusCode);
28 | }
29 |
30 | [Fact]
31 | public async void When_RequestIsSuccessfull_Should_ParseResponse()
32 | {
33 | var dispatcher = Dispatcher.Mock("response", 207, "Multi-Status");
34 | var propfindResponseParser = Substitute.For>();
35 | var client = new WebDavClient()
36 | .SetWebDavDispatcher(dispatcher)
37 | .SetPropfindResponseParser(propfindResponseParser);
38 |
39 | propfindResponseParser.DidNotReceiveWithAnyArgs().Parse("", 0, "");
40 | await client.Propfind("http://example");
41 | propfindResponseParser.Received(1).Parse("response", 207, "Multi-Status");
42 | }
43 |
44 | [Fact]
45 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
46 | {
47 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
48 | var response = await client.Propfind("http://example.com");
49 | Assert.Equal(500, response.StatusCode);
50 | }
51 |
52 | [Fact]
53 | public async void When_IsCalledWithDefaultArguments_Should_SendPropfindRequest()
54 | {
55 | var requestUri = new Uri("http://example.com");
56 | var dispatcher = Dispatcher.Mock();
57 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
58 |
59 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
60 | await client.Propfind(requestUri);
61 | await dispatcher.Received(1)
62 | .Send(requestUri, WebDavMethod.Propfind, Arg.Is(Predicates.CompareHeader("Depth", "1")), CancellationToken.None);
63 | }
64 |
65 | [Fact]
66 | public async void When_IsAppliedToResourceAndAncestors_Should_SendDepthHeaderEqualsInfinity()
67 | {
68 | var dispatcher = Dispatcher.Mock();
69 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
70 |
71 | await client.Propfind("http://example.com", new PropfindParameters { ApplyTo = ApplyTo.Propfind.ResourceAndAncestors });
72 | await dispatcher.Received(1)
73 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareHeader("Depth", "infinity")), CancellationToken.None);
74 | }
75 |
76 | [Fact]
77 | public async void When_IsAppliedToResourceAndChildren_Should_SendDepthHeaderEqualsOne()
78 | {
79 | var dispatcher = Dispatcher.Mock();
80 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
81 |
82 | await client.Propfind("http://example.com", new PropfindParameters { ApplyTo = ApplyTo.Propfind.ResourceAndChildren });
83 | await dispatcher.Received(1)
84 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareHeader("Depth", "1")), CancellationToken.None);
85 | }
86 |
87 | [Fact]
88 | public async void When_IsAppliedToResourceOnly_Should_SendDepthHeaderEqualsZero()
89 | {
90 | var dispatcher = Dispatcher.Mock();
91 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
92 |
93 | await client.Propfind("http://example.com", new PropfindParameters { ApplyTo = ApplyTo.Propfind.ResourceOnly });
94 | await dispatcher.Received(1)
95 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareHeader("Depth", "0")), CancellationToken.None);
96 | }
97 |
98 | [Fact]
99 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
100 | {
101 | var cts = new CancellationTokenSource();
102 | var dispatcher = Dispatcher.Mock();
103 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
104 |
105 | await client.Propfind("http://example.com", new PropfindParameters { CancellationToken = cts.Token });
106 | await dispatcher.Received(1)
107 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareHeader("Depth", "1")), cts.Token);
108 | }
109 |
110 | [Fact]
111 | public async void When_IsCalledWithDefaultArguments_Should_SendAllPropRequest()
112 | {
113 | const string expectedContent =
114 | @"
115 |
116 |
117 | ";
118 | var dispatcher = Dispatcher.Mock();
119 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
120 |
121 | await client.Propfind("http://example.com");
122 | await dispatcher.Received(1)
123 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
124 | }
125 |
126 | [Fact]
127 | public async void When_IsCalledWithCustomProperties_Should_IncludeThemInRequest()
128 | {
129 | const string expectedContent =
130 | @"
131 |
132 |
133 |
134 |
135 |
136 |
137 | ";
138 | var dispatcher = Dispatcher.Mock();
139 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
140 |
141 | await client.Propfind("http://example.com",
142 | new PropfindParameters
143 | {
144 | CustomProperties = new XName[] { "myprop1", "myprop2" }
145 | });
146 | await dispatcher.Received(1)
147 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
148 | }
149 |
150 | [Fact]
151 | public async void When_CustomPropertiesHaveNamespaces_Should_IncludeThemInRequest()
152 | {
153 | const string expectedContent =
154 | @"
155 |
156 |
157 |
158 |
159 |
160 |
161 | ";
162 | var dispatcher = Dispatcher.Mock();
163 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
164 |
165 | await client.Propfind("http://example.com",
166 | new PropfindParameters
167 | {
168 | CustomProperties = new XName[] { "{http://ns1.example.com}myprop1", "{http://ns2.example.com}myprop2" }
169 | });
170 | await dispatcher.Received(1)
171 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
172 | }
173 |
174 | [Fact]
175 | public async void When_IsCalledWithDefaultNamespace_Should_IncludeItInRequest()
176 | {
177 | const string expectedContent =
178 | @"
179 |
180 |
181 |
182 |
183 |
184 |
185 | ";
186 | var dispatcher = Dispatcher.Mock();
187 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
188 |
189 | await client.Propfind("http://example.com",
190 | new PropfindParameters
191 | {
192 | CustomProperties = new XName[] { "{http://ns.example.com}myprop1", "{http://ns.example.com}myprop2" },
193 | Namespaces = new[] { new NamespaceAttr("http://ns.example.com") }
194 | });
195 | await dispatcher.Received(1)
196 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
197 | }
198 |
199 | [Fact]
200 | public async void When_IsCalledWithMoreThanOneDefaultNamespace_Should_UseTheLastOne()
201 | {
202 | const string expectedContent =
203 | @"
204 |
205 |
206 |
207 |
208 |
209 | ";
210 | var dispatcher = Dispatcher.Mock();
211 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
212 |
213 | await client.Propfind("http://example.com",
214 | new PropfindParameters
215 | {
216 | CustomProperties = new XName[] { "{http://ns2.example.com}myprop" },
217 | Namespaces = new[] { new NamespaceAttr("http://ns1.example.com"), new NamespaceAttr("http://ns2.example.com") }
218 | });
219 | await dispatcher.Received(1)
220 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
221 | }
222 |
223 | [Fact]
224 | public async Task When_IsCalledWithPrefixedNamespaces_Should_IncludeThemInRequest()
225 | {
226 | const string expectedContent =
227 | @"
228 |
229 |
230 |
231 |
232 |
233 |
234 | ";
235 | var dispatcher = Dispatcher.Mock();
236 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
237 |
238 | await client.Propfind("http://example.com",
239 | new PropfindParameters
240 | {
241 | CustomProperties = new XName[] { "{http://p1.example.com}myprop1", "{http://p2.example.com}myprop2" },
242 | Namespaces = new[] { new NamespaceAttr("P1", "http://p1.example.com"), new NamespaceAttr("P2", "http://p2.example.com") }
243 | });
244 | await dispatcher.Received(1)
245 | .Send(Arg.Any(), WebDavMethod.Propfind, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
246 | }
247 | }
248 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/ProppatchTests.cs:
--------------------------------------------------------------------------------
1 | using NSubstitute;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Threading;
7 | using System.Xml.Linq;
8 | using WebDav.Client.Tests.TestDoubles;
9 | using WebDav.Response;
10 | using Xunit;
11 |
12 | namespace WebDav.Client.Tests.WebDavClientTests
13 | {
14 | public class ProppatchTests
15 | {
16 | [Fact]
17 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
18 | {
19 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
20 | var response1 = await client.Proppatch("http://example.com", new ProppatchParameters());
21 | var response2 = await client.Proppatch(new Uri("http://example.com"), new ProppatchParameters());
22 |
23 | Assert.Equal(200, response1.StatusCode);
24 | Assert.Equal(200, response2.StatusCode);
25 | }
26 |
27 | [Fact]
28 | public async void When_RequestIsSuccessfull_Should_ParseResponse()
29 | {
30 | var dispatcher = Dispatcher.Mock("response", 207, "Multi-Status");
31 | var proppatchResponseParser = Substitute.For>();
32 | var client = new WebDavClient()
33 | .SetWebDavDispatcher(dispatcher)
34 | .SetProppatchResponseParser(proppatchResponseParser);
35 |
36 | proppatchResponseParser.DidNotReceiveWithAnyArgs().Parse("", 0, "");
37 | await client.Proppatch("http://example", new ProppatchParameters());
38 | proppatchResponseParser.Received(1).Parse("response", 207, "Multi-Status");
39 | }
40 |
41 | [Fact]
42 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
43 | {
44 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
45 | var response = await client.Proppatch("http://example", new ProppatchParameters());
46 | Assert.Equal(500, response.StatusCode);
47 | }
48 |
49 | [Fact]
50 | public async void When_IsCalledWithDefaultArguments_Should_SendProppatchRequest()
51 | {
52 | var requestUri = new Uri("http://example.com");
53 | var dispatcher = Dispatcher.Mock();
54 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
55 |
56 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
57 | await client.Proppatch(requestUri, new ProppatchParameters());
58 | await dispatcher.Received(1)
59 | .Send(requestUri, WebDavMethod.Proppatch, Arg.Is(x => !x.Headers.Any()), CancellationToken.None);
60 | }
61 |
62 | [Fact]
63 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
64 | {
65 | var cts = new CancellationTokenSource();
66 | var dispatcher = Dispatcher.Mock();
67 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
68 |
69 | await client.Proppatch("http://example.com", new ProppatchParameters { CancellationToken = cts.Token });
70 | await dispatcher.Received(1)
71 | .Send(Arg.Any(), WebDavMethod.Proppatch, Arg.Is(x => !x.Headers.Any()), cts.Token);
72 | }
73 |
74 | [Fact]
75 | public async void When_IsCalledWithDefaultArguments_Should_SendPropertyUpdateRequest()
76 | {
77 | const string expectedContent =
78 | @"
79 | ";
80 | var dispatcher = Dispatcher.Mock();
81 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
82 |
83 | await client.Proppatch("http://example.com", new ProppatchParameters());
84 | await dispatcher.Received(1)
85 | .Send(Arg.Any(), WebDavMethod.Proppatch, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
86 | }
87 |
88 | [Fact]
89 | public async void When_SetProperties_Should_IncludeThemInSetTag()
90 | {
91 | const string expectedContent =
92 | @"
93 |
94 |
95 |
96 | value1
97 |
98 |
99 | value2
100 |
101 |
102 | ";
103 | var dispatcher = Dispatcher.Mock();
104 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
105 |
106 | var propertiesToSet = new Dictionary
107 | {
108 | {"prop1", "value1"},
109 | {"prop2", "value2"}
110 | };
111 | await client.Proppatch("http://example.com", new ProppatchParameters { PropertiesToSet = propertiesToSet });
112 | await dispatcher.Received(1)
113 | .Send(Arg.Any(), WebDavMethod.Proppatch, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
114 | }
115 |
116 | [Fact]
117 | public async void When_SetPropertiesWithNamespaces_Should_IncludeXmlnsTagAndUsePrefixes()
118 | {
119 | const string expectedContent =
120 | @"
121 |
122 |
123 |
124 | value1
125 |
126 |
127 | value2
128 |
129 |
130 | ";
131 | var dispatcher = Dispatcher.Mock();
132 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
133 |
134 | var propertiesToSet = new Dictionary
135 | {
136 | {"{http://x.example.com/}prop1", "value1"},
137 | {"{http://y.example.com/}prop2", "value2"}
138 | };
139 | var ns = new[]
140 | {
141 | new NamespaceAttr("X", "http://x.example.com/"),
142 | new NamespaceAttr("http://y.example.com/")
143 | };
144 | await client.Proppatch("http://example.com", new ProppatchParameters { PropertiesToSet = propertiesToSet, Namespaces = ns});
145 | await dispatcher.Received(1)
146 | .Send(Arg.Any(), WebDavMethod.Proppatch, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
147 | }
148 |
149 | [Fact]
150 | public async void When_RemoveProperties_Should_IncludeThemInRemoveTag()
151 | {
152 | const string expectedContent =
153 | @"
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | ";
164 | var dispatcher = Dispatcher.Mock();
165 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
166 |
167 | await client.Proppatch("http://example.com", new ProppatchParameters { PropertiesToRemove = new XName[] { "prop1", "prop2" } });
168 | await dispatcher.Received(1)
169 | .Send(Arg.Any(), WebDavMethod.Proppatch, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
170 | }
171 |
172 | [Fact]
173 | public async void When_RemovePropertiesWithNamespaces_Should_IncludeXmlnsTagAndUsePrefixes()
174 | {
175 | const string expectedContent =
176 | @"
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | ";
187 | var dispatcher = Dispatcher.Mock();
188 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
189 |
190 | var propertiesToRemove = new XName[]
191 | {
192 | "{http://x.example.com/}prop1",
193 | "{http://y.example.com/}prop2"
194 | };
195 | var ns = new[]
196 | {
197 | new NamespaceAttr("X", "http://x.example.com/"),
198 | new NamespaceAttr("http://y.example.com/")
199 | };
200 | await client.Proppatch("http://example.com", new ProppatchParameters { PropertiesToRemove = propertiesToRemove, Namespaces = ns});
201 | await dispatcher.Received(1)
202 | .Send(Arg.Any(), WebDavMethod.Proppatch, Arg.Is(Predicates.CompareRequestContent(expectedContent)), CancellationToken.None);
203 | }
204 | }
205 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/PutFileTests.cs:
--------------------------------------------------------------------------------
1 | using NSubstitute;
2 | using System;
3 | using System.IO;
4 | using System.Net.Http;
5 | using System.Text;
6 | using System.Threading;
7 | using WebDav.Client.Tests.TestDoubles;
8 | using Xunit;
9 |
10 | namespace WebDav.Client.Tests.WebDavClientTests
11 | {
12 | public class PutFileTests
13 | {
14 | [Fact]
15 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
16 | {
17 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(""));
18 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
19 |
20 | var response1 = await client.PutFile("http://example.com/file", stream);
21 | var response2 = await client.PutFile(new Uri("http://example.com/file"), stream);
22 | var response3 = await client.PutFile("http://example.com/file", stream, "text/xml");
23 | var response4 = await client.PutFile(new Uri("http://example.com/file"), stream, "text/xml");
24 | var response5 = await client.PutFile(new Uri("http://example.com/file"), stream, new PutFileParameters());
25 | var response6 = await client.PutFile(new Uri("http://example.com/file"), stream, new PutFileParameters());
26 |
27 | Assert.Equal(200, response1.StatusCode);
28 | Assert.Equal(200, response2.StatusCode);
29 | Assert.Equal(200, response3.StatusCode);
30 | Assert.Equal(200, response4.StatusCode);
31 | Assert.Equal(200, response5.StatusCode);
32 | Assert.Equal(200, response6.StatusCode);
33 | }
34 |
35 | [Fact]
36 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
37 | {
38 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(""));
39 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
40 | var response = await client.PutFile("http://example.com/file", stream);
41 | Assert.Equal(500, response.StatusCode);
42 | }
43 |
44 | [Fact]
45 | public async void When_IsCalled_Should_SendPutRequestWithContent()
46 | {
47 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(""));
48 | var requestUri = new Uri("http://example.com/file");
49 | var dispatcher = Dispatcher.Mock();
50 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
51 |
52 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
53 | await client.PutFile(requestUri, stream);
54 | await dispatcher.Received(1)
55 | .Send(requestUri, HttpMethod.Put, Arg.Is(Predicates.CompareRequestContent("")), CancellationToken.None);
56 | }
57 |
58 | [Fact]
59 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
60 | {
61 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(""));
62 | var cts = new CancellationTokenSource();
63 | var dispatcher = Dispatcher.Mock();
64 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
65 |
66 | await client.PutFile("http://example.com/file", stream, new PutFileParameters { CancellationToken = cts.Token });
67 | await dispatcher.Received(1)
68 | .Send(Arg.Any(), HttpMethod.Put, Arg.Is(Predicates.CompareRequestContent("")), cts.Token);
69 | }
70 |
71 | [Fact]
72 | public async void When_IsCalledWithLockToken_Should_SetIfHeader()
73 | {
74 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(""));
75 | var requestUri = new Uri("http://example.com/file");
76 | var dispatcher = Dispatcher.Mock();
77 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
78 |
79 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
80 | await client.PutFile(requestUri, stream, new PutFileParameters { LockToken = "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4" });
81 | await dispatcher.Received(1)
82 | .Send(requestUri, HttpMethod.Put, Arg.Is(Predicates.CompareHeader("If", "()")), CancellationToken.None);
83 | }
84 |
85 | [Fact]
86 | public async void When_IsCalledWithContentType_Should_SetPassItToDispatcher()
87 | {
88 | var stream = new MemoryStream(Encoding.UTF8.GetBytes(""));
89 | var requestUri = new Uri("http://example.com/file");
90 | var dispatcher = Dispatcher.Mock();
91 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
92 |
93 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
94 | await client.PutFile(requestUri, stream, new PutFileParameters { ContentType = "text/xml" });
95 | await dispatcher.Received(1)
96 | .Send(requestUri, HttpMethod.Put, Arg.Is(x => x.ContentType == "text/xml"), CancellationToken.None);
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/WebDavClientTests/UnlockTests.cs:
--------------------------------------------------------------------------------
1 | using NSubstitute;
2 | using System;
3 | using System.Net.Http;
4 | using System.Threading;
5 | using WebDav.Client.Tests.TestDoubles;
6 | using Xunit;
7 |
8 | namespace WebDav.Client.Tests.WebDavClientTests
9 | {
10 | public class UnlockTests
11 | {
12 | [Fact]
13 | public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
14 | {
15 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
16 | var response1 = await client.Unlock("http://example.com/file", "lock-token");
17 | var response2 = await client.Unlock(new Uri("http://example.com/file"), "lock-token");
18 | var response3 = await client.Unlock("http://example.com/file", new UnlockParameters("lock-token"));
19 | var response4 = await client.Unlock(new Uri("http://example.com/file"), new UnlockParameters("lock-token"));
20 |
21 | Assert.Equal(200, response1.StatusCode);
22 | Assert.Equal(200, response2.StatusCode);
23 | Assert.Equal(200, response3.StatusCode);
24 | Assert.Equal(200, response4.StatusCode);
25 | }
26 |
27 | [Fact]
28 | public async void When_RequestIsFailed_Should_ReturnStatusCode500()
29 | {
30 | var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.MockFaulted());
31 | var response = await client.Unlock("http://example.com/file", "lock-token");
32 | Assert.Equal(500, response.StatusCode);
33 | }
34 |
35 | [Fact]
36 | public async void When_IsCalledWithDefaultArguments_Should_SendUnlockRequest()
37 | {
38 | var requestUri = new Uri("http://example.com/file");
39 | var dispatcher = Dispatcher.Mock();
40 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
41 |
42 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
43 | await client.Unlock(requestUri, "lock-token");
44 | await dispatcher.Received(1)
45 | .Send(requestUri, WebDavMethod.Unlock, Arg.Is(x => x.Content == null), CancellationToken.None);
46 | }
47 |
48 | [Fact]
49 | public async void When_IsCalledWithCancellationToken_Should_SendRequestWithIt()
50 | {
51 | var cts = new CancellationTokenSource();
52 | var dispatcher = Dispatcher.Mock();
53 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
54 |
55 | await client.Unlock("http://example.com/file", new UnlockParameters("lock-token") { CancellationToken = cts.Token });
56 | await dispatcher.Received(1)
57 | .Send(Arg.Any(), WebDavMethod.Unlock, Arg.Is(x => x.Content == null), cts.Token);
58 | }
59 |
60 | [Fact]
61 | public async void When_IsCalledWithLockToken_Should_SendLockTokenHeader()
62 | {
63 | var requestUri = new Uri("http://example.com/file");
64 | var dispatcher = Dispatcher.Mock();
65 | var client = new WebDavClient().SetWebDavDispatcher(dispatcher);
66 |
67 | await dispatcher.DidNotReceiveWithAnyArgs().Send(requestUri, Arg.Any(), new RequestParameters(), CancellationToken.None);
68 |
69 | await client.Unlock(requestUri, "urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4");
70 | await client.Unlock(requestUri, new UnlockParameters("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"));
71 |
72 | await dispatcher.Received(1)
73 | .Send(requestUri, WebDavMethod.Unlock, Arg.Is(Predicates.CompareHeader("Lock-Token", "")), CancellationToken.None);
74 |
75 | await dispatcher.Received(1)
76 | .Send(requestUri, WebDavMethod.Unlock, Arg.Is(Predicates.CompareHeader("Lock-Token", "")), CancellationToken.None);
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests.Net452/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/WebDAV-Client.Tests/WebDAV-Client.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Stef Heyenrath
5 | net452;netcoreapp1.1;netcoreapp2.1;net6.0;net7.0
6 | WebDAV-Client.Tests
7 | WebDAV-Client.Tests
8 | true
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | all
27 | runtime; build; native; contentfiles; analyzers
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------