websocket-server – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5 using System.Net.Sockets;
6 using System.Text;
7 using System.IO;
8 using System.Reflection;
9 using System.Configuration;
10 using System.Xml;
11 using WebSockets.Common;
12  
13 namespace WebSockets.Server.Http
14 {
15 public class HttpService : IService
16 {
17 private readonly Stream _stream;
18 private readonly string _path;
19 private readonly string _webRoot;
20 private readonly IWebSocketLogger _logger;
21 private readonly MimeTypes _mimeTypes;
22  
23 public HttpService(Stream stream, string path, string webRoot, IWebSocketLogger logger)
24 {
25 _stream = stream;
26 _path = path;
27 _webRoot = webRoot;
28 _logger = logger;
29 _mimeTypes = MimeTypesFactory.GetMimeTypes(webRoot);
30 }
31  
32 private static bool IsDirectory(string file)
33 {
34 if (Directory.Exists(file))
35 {
36 //detect whether its a directory or file
37 FileAttributes attr = File.GetAttributes(file);
38 return ((attr & FileAttributes.Directory) == FileAttributes.Directory);
39 }
40  
41 return false;
42 }
43  
44 public void Respond()
45 {
46 _logger.Information(this.GetType(), "Request: {0}", _path);
47 string file = GetSafePath(_path);
48  
49 // default to index.html is path is supplied
50 if (IsDirectory(file))
51 {
52 file += "index.html";
53 }
54  
55 FileInfo fi = new FileInfo(file);
56  
57 if (fi.Exists)
58 {
59 string ext = fi.Extension.ToLower();
60  
61 string contentType;
62 if (_mimeTypes.TryGetValue(ext, out contentType))
63 {
64 Byte[] bytes = File.ReadAllBytes(fi.FullName);
65 RespondSuccess(contentType, bytes.Length);
66 _stream.Write(bytes, 0, bytes.Length);
67 _logger.Information(this.GetType(), "Served file: {0}", file);
68 }
69 else
70 {
71 RespondMimeTypeFailure(file);
72 }
73 }
74 else
75 {
76 RespondNotFoundFailure(file);
77 }
78 }
79  
80 /// <summary>
81 /// I am not convinced that this function is indeed safe from hacking file path tricks
82 /// </summary>
83 /// <param name="path">The relative path</param>
84 /// <returns>The file system path</returns>
85 private string GetSafePath(string path)
86 {
87 path = path.Trim().Replace("/", "\\");
88 if (path.Contains("..") || !path.StartsWith("\\") || path.Contains(":"))
89 {
90 return string.Empty;
91 }
92  
93 string file = _webRoot + path;
94 return file;
95 }
96  
97 public void RespondMimeTypeFailure(string file)
98 {
99 HttpHelper.WriteHttpHeader("415 Unsupported Media Type", _stream);
100 _logger.Warning(this.GetType(), "File extension not found MimeTypes.config: {0}", file);
101 }
102  
103 public void RespondNotFoundFailure(string file)
104 {
105 HttpHelper.WriteHttpHeader("HTTP/1.1 404 Not Found", _stream);
106 _logger.Information(this.GetType(), "File not found: {0}", file);
107 }
108  
109 public void RespondSuccess(string contentType, int contentLength)
110 {
111 string response = "HTTP/1.1 200 OK" + Environment.NewLine +
112 "Content-Type: " + contentType + Environment.NewLine +
113 "Content-Length: " + contentLength + Environment.NewLine +
114 "Connection: close";
115 HttpHelper.WriteHttpHeader(response, _stream);
116 }
117  
118 public void Dispose()
119 {
120 // do nothing. The network stream will be closed by the WebServer
121 }
122 }
123 }