Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/FSharpx.Async/FSharpx.Async.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<Compile Include="AsyncStreamReader.fs" />
<Compile Include="AsyncStream.fs" />
<Compile Include="Async.IO.fs" />
<Compile Include="Net.fs" />
<None Include="paket.references" />
</ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" />
Expand Down
61 changes: 61 additions & 0 deletions src/FSharpx.Async/Net.fs
Original file line number Diff line number Diff line change
@@ -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

[<AutoOpen>]
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() }