Skip to content

Commit cef545c

Browse files
committed
re-factor RestFiles to make it look more like @AlexZeitler's WCF Web APIs port.
1 parent b7ac0b3 commit cef545c

File tree

3 files changed

+49
-60
lines changed

3 files changed

+49
-60
lines changed
Lines changed: 23 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,22 @@
11
using System;
22
using System.IO;
33
using System.Net;
4+
using RestFiles.ServiceInterface.Support;
45
using RestFiles.ServiceModel.Operations;
56
using RestFiles.ServiceModel.Types;
67
using ServiceStack.Common.Web;
78
using ServiceStack.ServiceHost;
89
using ServiceStack.ServiceInterface;
10+
using Dto = RestFiles.ServiceModel.Types;
911
using File = System.IO.File;
10-
using FileResult = RestFiles.ServiceModel.Types.FileResult;
11-
12-
/* For syntax highlighting and better readability of this file, view it on GitHub:
13-
* https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/RestFiles/RestFiles.Tests/SyncRestClientTests.cs
14-
*/
1512

1613
namespace RestFiles.ServiceInterface
1714
{
1815
/// <summary>
19-
/// Contains the entire implementation of ServiceStack's REST /files Web Service:
20-
///
21-
/// Complete file management
22-
///
16+
/// Contains the entire file manager implementation of ServiceStack's REST /files Web Service:
17+
/// Demo: http://www.servicestack.net/RestFiles/
2318
/// </summary>
24-
public class FilesService
25-
: RestServiceBase<Files>
19+
public class FilesService : RestServiceBase<Files>
2620
{
2721
public AppConfig Config { get; set; }
2822

@@ -33,7 +27,7 @@ public override object OnGet(Files request)
3327
var isDirectory = Directory.Exists(targetFile.FullName);
3428

3529
if (!isDirectory && request.ForDownload)
36-
return new HttpResult(targetFile, true);
30+
return new HttpResult(targetFile, asAttachment:true);
3731

3832
var response = isDirectory
3933
? new FilesResponse { Directory = GetFolderResult(targetFile.FullName) }
@@ -54,12 +48,9 @@ public override object OnPost(Files request)
5448
"POST only supports uploading new files. Use PUT to replace contents of an existing file");
5549

5650
if (!Directory.Exists(targetDir.FullName))
57-
{
5851
Directory.CreateDirectory(targetDir.FullName);
59-
}
6052

61-
foreach (var uploadedFile in base.RequestContext.Files)
62-
{
53+
foreach (var uploadedFile in base.RequestContext.Files) {
6354
var newFilePath = Path.Combine(targetDir.FullName, uploadedFile.FileName);
6455
uploadedFile.SaveTo(newFilePath);
6556
}
@@ -73,7 +64,7 @@ public override object OnPut(Files request)
7364

7465
if (!this.Config.TextFileExtensions.Contains(targetFile.Extension))
7566
throw new NotSupportedException("PUT Can only update text files, not: " + targetFile.Extension);
76-
67+
7768
if (request.TextContents == null)
7869
throw new ArgumentNullException("TextContents");
7970

@@ -85,36 +76,31 @@ public override object OnPut(Files request)
8576
public override object OnDelete(Files request)
8677
{
8778
var targetFile = GetAndValidateExistingPath(request);
88-
89-
File.Delete(targetFile.FullName);
9079

80+
File.Delete(targetFile.FullName);
81+
9182
return new FilesResponse();
9283
}
9384

94-
private FolderResult GetFolderResult(string targetPath)
95-
{
85+
private FolderResult GetFolderResult(string targetPath) {
9686
var result = new FolderResult();
9787

98-
foreach (var dirPath in Directory.GetDirectories(targetPath))
99-
{
88+
foreach (var dirPath in Directory.GetDirectories(targetPath)) {
10089
var dirInfo = new DirectoryInfo(dirPath);
10190

10291
if (this.Config.ExcludeDirectories.Contains(dirInfo.Name)) continue;
103-
104-
result.Folders.Add(new Folder
105-
{
92+
93+
result.Folders.Add(new Folder {
10694
Name = dirInfo.Name,
10795
ModifiedDate = dirInfo.LastWriteTimeUtc,
10896
FileCount = dirInfo.GetFiles().Length
10997
});
11098
}
11199

112-
foreach (var filePath in Directory.GetFiles(targetPath))
113-
{
100+
foreach (var filePath in Directory.GetFiles(targetPath)) {
114101
var fileInfo = new FileInfo(filePath);
115-
116-
result.Files.Add(new ServiceModel.Types.File
117-
{
102+
103+
result.Files.Add(new ServiceModel.Types.File {
118104
Name = fileInfo.Name,
119105
Extension = fileInfo.Extension,
120106
FileSizeBytes = fileInfo.Length,
@@ -126,30 +112,22 @@ private FolderResult GetFolderResult(string targetPath)
126112
return result;
127113
}
128114

129-
private FileInfo GetPath(Files request)
130-
{
131-
var targetPath = Path.Combine(this.Config.RootDirectory,
132-
GetSafePath(request.Path ?? string.Empty));
133-
134-
return new FileInfo(targetPath);
115+
private FileInfo GetPath(Files request) {
116+
return new FileInfo(Path.Combine(this.Config.RootDirectory, request.Path.GetSafePath()));
135117
}
136118

137-
private FileInfo GetAndValidateExistingPath(Files request)
138-
{
119+
private FileInfo GetAndValidateExistingPath(Files request) {
139120
var targetFile = GetPath(request);
140121
if (!targetFile.Exists && !Directory.Exists(targetFile.FullName))
141-
throw new HttpError(HttpStatusCode.NotFound,
142-
new FileNotFoundException("Could not find: " + request.Path));
122+
throw new HttpError(HttpStatusCode.NotFound, new FileNotFoundException("Could not find: " + request.Path));
143123

144124
return targetFile;
145125
}
146126

147-
private FileResult GetFileResult(FileInfo fileInfo)
148-
{
127+
private Dto.FileResult GetFileResult(FileInfo fileInfo) {
149128
var isTextFile = this.Config.TextFileExtensions.Contains(fileInfo.Extension);
150129

151-
return new FileResult
152-
{
130+
return new Dto.FileResult {
153131
Name = fileInfo.Name,
154132
Extension = fileInfo.Extension,
155133
FileSizeBytes = fileInfo.Length,
@@ -158,20 +136,5 @@ private FileResult GetFileResult(FileInfo fileInfo)
158136
ModifiedDate = fileInfo.LastWriteTimeUtc,
159137
};
160138
}
161-
162-
public static string GetSafePath(string filePath)
163-
{
164-
//Strip invalid chars
165-
foreach (var invalidChar in Path.GetInvalidPathChars())
166-
{
167-
filePath = filePath.Replace(invalidChar.ToString(), string.Empty);
168-
}
169-
170-
return filePath
171-
.TrimStart('.', '/', '\\') //Remove illegal chars at the start
172-
.Replace('\\', '/') //Switch all to use the same seperator
173-
.Replace("../", string.Empty) //Remove access to top-level directories anywhere else
174-
.Replace('/', Path.DirectorySeparatorChar); //Switch all to use the OS seperator
175-
}
176139
}
177140
}

src/RestFiles/RestFiles.ServiceInterface/RestFiles.ServiceInterface.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<Compile Include="Properties\AssemblyInfo.cs" />
8080
<Compile Include="AppConfig.cs" />
8181
<Compile Include="RevertFilesService.cs" />
82+
<Compile Include="Support\FileExtensions.cs" />
8283
</ItemGroup>
8384
<ItemGroup>
8485
<ProjectReference Include="..\RestFiles.ServiceModel\RestFiles.ServiceModel.csproj">
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.IO;
3+
4+
namespace RestFiles.ServiceInterface.Support
5+
{
6+
public static class FileExtensions
7+
{
8+
public static string GetSafePath(this string filePath)
9+
{
10+
if (string.IsNullOrEmpty(filePath)) return string.Empty;
11+
12+
//Strip invalid chars
13+
foreach (var invalidChar in Path.GetInvalidPathChars())
14+
{
15+
filePath = filePath.Replace(invalidChar.ToString(), String.Empty);
16+
}
17+
18+
return filePath
19+
.TrimStart('.', '/', '\\') //Remove illegal chars at the start
20+
.Replace('\\', '/') //Switch all to use the same seperator
21+
.Replace("../", String.Empty) //Remove access to top-level directories anywhere else
22+
.Replace('/', Path.DirectorySeparatorChar); //Switch all to use the OS seperator
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)