From 32623e0f595150bd89a6c97a53d9ccf1f570852e Mon Sep 17 00:00:00 2001 From: Grzegorz Dziadkiewicz Date: Sat, 3 Sep 2022 08:26:40 +0200 Subject: [PATCH] Move Net.fs from FSharpx.Extras to FSharpx.Async --- src/FSharpx.Async/FSharpx.Async.fsproj | 1 + src/FSharpx.Async/Net.fs | 61 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/FSharpx.Async/Net.fs diff --git a/src/FSharpx.Async/FSharpx.Async.fsproj b/src/FSharpx.Async/FSharpx.Async.fsproj index c25a451..d0d9c2d 100644 --- a/src/FSharpx.Async/FSharpx.Async.fsproj +++ b/src/FSharpx.Async/FSharpx.Async.fsproj @@ -27,6 +27,7 @@ + diff --git a/src/FSharpx.Async/Net.fs b/src/FSharpx.Async/Net.fs new file mode 100644 index 0000000..fa74e6e --- /dev/null +++ b/src/FSharpx.Async/Net.fs @@ -0,0 +1,61 @@ +namespace FSharpx.Net + +open System.IO +open System.Net +open System.Text + +open FSharpx.IO + +// ---------------------------------------------------------------------------- +// Extensions that simplify working with HttpListener and related types + +[] +module HttpExtensions = + + type System.Net.HttpListener with + /// Asynchronously waits for an incoming request and returns it. + member x.AsyncGetContext() = + Async.FromBeginEnd(x.BeginGetContext, x.EndGetContext) + + /// Starts HttpListener on the specified URL. The 'handler' function is + /// called (in a new thread pool thread) each time an HTTP request is received. + static member Start(url, handler, ?cancellationToken) = + let server = async { + use listener = new HttpListener() + listener.Prefixes.Add(url) + listener.Start() + while true do + let! (context:HttpListenerContext) = listener.AsyncGetContext() + Async.Start + ( handler (context.Request, context.Response), + ?cancellationToken = cancellationToken) } + Async.Start(server, ?cancellationToken = cancellationToken) + + type System.Net.HttpListenerRequest with + /// Asynchronously reads the 'InputStream' of the request and converts it to a string + member request.AsyncInputString = async { + use tmp = new MemoryStream() + do! + request.InputStream.AsyncReadSeq(16 * 1024) + |> FSharp.Control.AsyncSeq.iter (fun data -> tmp.Write(data, 0, data.Length)) + + tmp.Seek(0L, SeekOrigin.Begin) |> ignore + use sr = new StreamReader(tmp) + return sr.ReadToEnd() } + + type System.Net.HttpListenerResponse with + /// Sends the specified string as a reply in UTF 8 encoding + member response.AsyncReply(s:string) = async { + let buffer = Encoding.UTF8.GetBytes(s) + response.ContentLength64 <- int64 buffer.Length + let output = response.OutputStream + do! output.AsyncWrite(buffer,0,buffer.Length) + output.Close() } + + /// Sends the specified data as a reply with the specified content type + member response.AsyncReply(typ, buffer:byte[]) = async { + response.ContentLength64 <- int64 buffer.Length + let output = response.OutputStream + response.ContentType <- typ + do! output.AsyncWrite(buffer,0,buffer.Length) + output.Close() } \ No newline at end of file