using System; using System.Collections.Generic; using System.Net; using System.Threading; using Ooui; namespace Samples { public class FilesSample : ISample { public string Title => "Upload files"; public string Path => "/files"; public void Publish () { var app = CreateElement (); UI.Publish (Path, app); UI.PublishCustomResponse ("/files/upload", HandleUpload); } void HandleUpload (HttpListenerContext listenerContext, CancellationToken token) { var req = listenerContext.Request; var ct = req.ContentType; var bi = ct.IndexOf ("boundary=", StringComparison.InvariantCulture); var boundaryString = ct.Substring (bi + 9); var boundaryBytes = System.Text.Encoding.UTF8.GetBytes ("--" + boundaryString + "\r\n"); var boundaryEndBytes = System.Text.Encoding.UTF8.GetBytes (boundaryString + "--"); var headerEndBytes = System.Text.Encoding.UTF8.GetBytes ("\r\n\r\n"); Console.WriteLine ("OMGGGGGG " + boundaryString); var state = 0; var buffer = new byte[1024]; var bufferLen = 0; var needsRead = true; using (var s = req.InputStream) { while (state < 1000) { if (needsRead) { var r = buffer.Length - bufferLen; if (r <= 0) { Array.Resize (ref buffer, buffer.Length * 2); r = buffer.Length - bufferLen; } var n = s.Read (buffer, bufferLen, r); if (n > 0) { bufferLen += n; } else if (n == 0) { // End! state = 1000; } else { state = 1001; } } switch (state) { case 0: var i = FindIndex (buffer, 0, bufferLen, boundaryBytes); if (i >= 0) { var e = i + boundaryBytes.Length; var r = bufferLen - e; Buffer.BlockCopy (buffer, e, buffer, 0, r); bufferLen = r; state = 1; } else { needsRead = true; } break; case 1: i = FindIndex (buffer, 0, bufferLen, headerEndBytes); if (i >= 0) { var h = System.Text.Encoding.ASCII.GetString (buffer, 0, i); Console.WriteLine ("HEADERS {0}", h); var e = i + headerEndBytes.Length; var r = bufferLen - e; Buffer.BlockCopy (buffer, e, buffer, 0, r); bufferLen = r; state = 2; } else { needsRead = true; } break; case 2: i = FindIndex (buffer, 0, bufferLen, boundaryEndBytes); if (i >= 0) { Console.WriteLine ("DATA {0}", bufferLen); var data = new byte[bufferLen]; var e = i + boundaryBytes.Length; var r = bufferLen - e; Buffer.BlockCopy (buffer, e, buffer, 0, r); bufferLen = r; state = 0; } else { needsRead = true; } break; } } } Console.WriteLine ("STATE " + state); listenerContext.Response.StatusCode = 200; listenerContext.Response.Close (); } static int FindIndex (byte[] buffer, int bufferStart, int bufferLen, byte[] pattern) { var n = pattern.Length; for (var i = bufferLen - n; i >= bufferStart; i--) { var all = true; for (var j = 0; all && j < n; j++) { all = buffer[i + j] == pattern[j]; } if (all) return i; } return -1; } public Element CreateElement () { var heading = new Heading ("Upload Files"); var subtitle = new Paragraph ("Upload files to the app"); var uploadForm = new Form (); uploadForm.Action = "/files/upload"; uploadForm.Method = "POST"; uploadForm.EncodingType = "multipart/form-data"; uploadForm.AppendChild (new Input (InputType.File) { Name = "file" }); uploadForm.AppendChild (new Input (InputType.Submit) { Value = "Upload" }); var app = new Div (); app.AppendChild (heading); app.AppendChild (subtitle); app.AppendChild (uploadForm); return app; } } }