5 using System.Net.Sockets;
\r
7 using System.Threading;
\r
9 using System.Windows.Forms;
\r
11 namespace KancolleSniffer
\r
13 public class LogServer
\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
20 public string OutputDir
\r
22 set { _outputDir = value; }
\r
25 public LogServer(int port)
\r
27 _listener = new TcpListener(IPAddress.Loopback, port);
\r
28 _thread = new Thread(Listen);
\r
36 private void Listen()
\r
43 var data = new byte[4096];
\r
44 var client = _listener.AcceptSocket();
\r
47 if (client.Available == 0)
\r
50 if (client.Available == 0)
\r
53 if (client.Receive(data) == 0)
\r
55 var request = Encoding.UTF8.GetString(data).Split('\r')[0].Split(' ');
\r
56 if (request.Length != 3)
\r
58 SendError(client, "400 Bad Request");
\r
61 if (!request[0].StartsWith("GET", StringComparison.OrdinalIgnoreCase))
\r
63 SendError(client, "501 Not Implemented");
\r
66 var path = HttpUtility.UrlDecode(request[1].Split('?')[0]);
\r
67 if (path == null || !path.StartsWith("/"))
\r
69 SendError(client, "400 Bad Request");
\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
78 SendFile(client, full, "text/html");
\r
81 if (path.EndsWith(".csv", StringComparison.OrdinalIgnoreCase) && File.Exists(csv))
\r
83 SendFile(client, csv, "text/csv; charset=Shift_JIS");
\r
86 if (path.EndsWith(".json", StringComparison.OrdinalIgnoreCase) &&
\r
87 File.Exists(csv.Replace(".json", ".csv")))
\r
89 SendJsonData(client, csv);
\r
92 if (path.EndsWith(".js", StringComparison.OrdinalIgnoreCase) && File.Exists(full))
\r
94 SendFile(client, full, "application/javascript");
\r
97 SendError(client, "404 Not Found");
\r
102 catch (InvalidOperationException)
\r
111 catch (SocketException)
\r
120 private void SendError(Socket client, string error)
\r
122 using (var writer = new StreamWriter(new MemoryStream(), Encoding.ASCII))
\r
124 writer.Write("HTTP/1.1 {0}\r\n", error);
\r
125 writer.Write("Server: KancolleSniffer\r\n");
\r
126 writer.Write("Date: {0:R}\r\n", DateTime.Now);
\r
127 writer.Write("Connection: close\r\n\r\n");
\r
128 writer.Write("<html><head><title>{0}</title></head>\r\n", error);
\r
129 writer.Write("<body><h4>{0}</h4></body></html>\r\n\r\n", error);
\r
131 client.Send(((MemoryStream)writer.BaseStream).ToArray());
\r
135 private void SendJsonData(Socket client, string path)
\r
137 var header = new StreamWriter(new MemoryStream(), Encoding.ASCII);
\r
138 header.Write("HTTP/1.1 200 OK\r\n");
\r
139 header.Write("Server: KancolleSniffer\r\n");
\r
140 header.Write("Date: {0:R}\r\n", DateTime.Now);
\r
141 header.Write("Content-Type: {0}\r\n", "application/json; charset=Shift_JIS");
\r
142 header.Write("Connection: close\r\n\r\n");
\r
144 client.Send(((MemoryStream)header.BaseStream).ToArray());
\r
146 var encoding = Encoding.GetEncoding("Shift_JIS");
\r
147 client.Send(encoding.GetBytes("{ \"data\": [\n"));
\r
148 var delimiter = "";
\r
149 foreach (var line in File.ReadLines(path.Replace(".json", ".csv"), encoding).Skip(1))
\r
151 client.Send(encoding.GetBytes(delimiter + "[\"" + string.Join("\",\"", line.Split(',')) + "\"]"));
\r
154 client.Send(encoding.GetBytes("]}\n"));
\r
157 private void SendFile(Socket client, string path, string mime)
\r
159 using (var writer = new StreamWriter(new MemoryStream(), Encoding.ASCII))
\r
161 writer.Write("HTTP/1.1 200 OK\r\n");
\r
162 writer.Write("Server: KancolleSniffer\r\n");
\r
163 writer.Write("Date: {0:R}\r\n", DateTime.Now);
\r
164 writer.Write("Content-Length: {0}\r\n", new FileInfo(path).Length);
\r
165 writer.Write("Content-Type: {0}\r\n", mime);
\r
166 writer.Write("Connection: close\r\n\r\n");
\r
168 client.SendFile(path, ((MemoryStream)writer.BaseStream).ToArray(), null,
\r
169 TransmitFileOptions.UseDefaultWorkerThread);
\r