11using System ;
22using System . IO ;
33using System . Net ;
4+ using RestFiles . ServiceInterface . Support ;
45using RestFiles . ServiceModel . Operations ;
56using RestFiles . ServiceModel . Types ;
67using ServiceStack . Common . Web ;
78using ServiceStack . ServiceHost ;
89using ServiceStack . ServiceInterface ;
10+ using Dto = RestFiles . ServiceModel . Types ;
911using 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
1613namespace 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}
0 commit comments