OSDN Git Service

ログが存在しないときにブラウザでJavaScriptのAlertが出るのを直す
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / LogServer.cs
1 using System;\r
2 using System.IO;\r
3 using System.Linq;\r
4 using System.Net;\r
5 using System.Net.Sockets;\r
6 using System.Text;\r
7 using System.Threading;\r
8 using System.Web;\r
9 using System.Windows.Forms;\r
10 \r
11 namespace KancolleSniffer\r
12 {\r
13     public class LogServer\r
14     {\r
15         private readonly TcpListener _listener;\r
16         private readonly Thread _thread;\r
17         private readonly string _indexDir = Path.GetDirectoryName(Application.ExecutablePath);\r
18         private string _outputDir = Path.GetDirectoryName(Application.ExecutablePath);\r
19 \r
20         public string OutputDir\r
21         {\r
22             set { _outputDir = value; }\r
23         }\r
24 \r
25         public LogServer(int port)\r
26         {\r
27             _listener = new TcpListener(IPAddress.Loopback, port);\r
28             _thread = new Thread(Listen);\r
29         }\r
30 \r
31         public void Start()\r
32         {\r
33             _thread.Start();\r
34         }\r
35 \r
36         private void Listen()\r
37         {\r
38             try\r
39             {\r
40                 _listener.Start();\r
41                 while (true)\r
42                 {\r
43                     var data = new byte[4096];\r
44                     var client = _listener.AcceptSocket();\r
45                     try\r
46                     {\r
47                         if (client.Available == 0)\r
48                         {\r
49                             Thread.Sleep(500);\r
50                             if (client.Available == 0)\r
51                                 continue;\r
52                         }\r
53                         if (client.Receive(data) == 0)\r
54                             continue;\r
55                         var request = Encoding.UTF8.GetString(data).Split('\r')[0].Split(' ');\r
56                         if (request.Length != 3)\r
57                         {\r
58                             SendError(client, "400 Bad Request");\r
59                             continue;\r
60                         }\r
61                         if (!request[0].StartsWith("GET", StringComparison.OrdinalIgnoreCase))\r
62                         {\r
63                             SendError(client, "501 Not Implemented");\r
64                             continue;\r
65                         }\r
66                         var path = HttpUtility.UrlDecode(request[1].Split('?')[0]);\r
67                         if (path == null || !path.StartsWith("/"))\r
68                         {\r
69                             SendError(client, "400 Bad Request");\r
70                             continue;\r
71                         }\r
72 \r
73                         path = path == "/" ? "index.html" : path.Substring(1);\r
74                         var full = Path.Combine(_indexDir, path);\r
75                         var csv = Path.Combine(_outputDir, path);\r
76                         if (path.EndsWith(".html", StringComparison.OrdinalIgnoreCase) && File.Exists(full))\r
77                         {\r
78                             SendFile(client, full, "text/html");\r
79                             continue;\r
80                         }\r
81                         if (path.EndsWith(".csv", StringComparison.OrdinalIgnoreCase) && File.Exists(csv))\r
82                         {\r
83                             SendFile(client, csv, "text/csv; charset=Shift_JIS");\r
84                             continue;\r
85                         }\r
86                         if (path.EndsWith(".json", StringComparison.OrdinalIgnoreCase))\r
87                         {\r
88                             SendJsonData(client, csv);\r
89                             continue;\r
90                         }\r
91                         if (path.EndsWith(".js", StringComparison.OrdinalIgnoreCase) && File.Exists(full))\r
92                         {\r
93                             SendFile(client, full, "application/javascript");\r
94                             continue;\r
95                         }\r
96                         SendError(client, "404 Not Found");\r
97                     }\r
98                     catch (IOException)\r
99                     {\r
100                     }\r
101                     catch (InvalidOperationException)\r
102                     {\r
103                     }\r
104                     finally\r
105                     {\r
106                         client.Close();\r
107                     }\r
108                 }\r
109             }\r
110             catch (SocketException)\r
111             {\r
112             }\r
113             finally\r
114             {\r
115                 _listener.Stop();\r
116             }\r
117         }\r
118 \r
119         private void SendError(Socket client, string error)\r
120         {\r
121             using (var writer = new StreamWriter(new MemoryStream(), Encoding.ASCII))\r
122             {\r
123                 writer.Write("HTTP/1.1 {0}\r\n", error);\r
124                 writer.Write("Server: KancolleSniffer\r\n");\r
125                 writer.Write("Date: {0:R}\r\n", DateTime.Now);\r
126                 writer.Write("Connection: close\r\n\r\n");\r
127                 writer.Write("<html><head><title>{0}</title></head>\r\n", error);\r
128                 writer.Write("<body><h4>{0}</h4></body></html>\r\n\r\n", error);\r
129                 writer.Flush();\r
130                 client.Send(((MemoryStream)writer.BaseStream).ToArray());\r
131             }\r
132         }\r
133 \r
134         private void SendJsonData(Socket client, string path)\r
135         {\r
136             var header = new StreamWriter(new MemoryStream(), Encoding.ASCII);\r
137             header.Write("HTTP/1.1 200 OK\r\n");\r
138             header.Write("Server: KancolleSniffer\r\n");\r
139             header.Write("Date: {0:R}\r\n", DateTime.Now);\r
140             header.Write("Content-Type: {0}\r\n", "application/json; charset=Shift_JIS");\r
141             header.Write("Connection: close\r\n\r\n");\r
142             header.Flush();\r
143             client.Send(((MemoryStream)header.BaseStream).ToArray());\r
144 \r
145             var csv = path.Replace(".json", ".csv");\r
146             var encoding = Encoding.GetEncoding("Shift_JIS");\r
147             client.Send(encoding.GetBytes("{ \"data\": [\n"));\r
148             if (File.Exists(csv))\r
149             {\r
150                 var delimiter = "";\r
151                 foreach (var line in File.ReadLines(csv, encoding).Skip(1))\r
152                 {\r
153                     client.Send(encoding.GetBytes(delimiter + "[\"" + string.Join("\",\"", line.Split(',')) + "\"]"));\r
154                     delimiter = ",\n";\r
155                 }\r
156             }\r
157             client.Send(encoding.GetBytes("]}\n"));\r
158         }\r
159 \r
160         private void SendFile(Socket client, string path, string mime)\r
161         {\r
162             using (var writer = new StreamWriter(new MemoryStream(), Encoding.ASCII))\r
163             {\r
164                 writer.Write("HTTP/1.1 200 OK\r\n");\r
165                 writer.Write("Server: KancolleSniffer\r\n");\r
166                 writer.Write("Date: {0:R}\r\n", DateTime.Now);\r
167                 writer.Write("Content-Length: {0}\r\n", new FileInfo(path).Length);\r
168                 writer.Write("Content-Type: {0}\r\n", mime);\r
169                 writer.Write("Connection: close\r\n\r\n");\r
170                 writer.Flush();\r
171                 client.SendFile(path, ((MemoryStream)writer.BaseStream).ToArray(), null,\r
172                     TransmitFileOptions.UseDefaultWorkerThread);\r
173             }\r
174         }\r
175 \r
176         public void Stop()\r
177         {\r
178             _listener.Stop();\r
179             _thread.Join();\r
180         }\r
181     }\r
182 }