tags:

views:

179

answers:

3

Is there a web server library for F#, similar to SimpleHTTPServer in Python?

Installing a full server like IIS is overkill for what I want, which is a simple application that can be queried using a web browser, effectively using HTTP as a monitoring method. Ideally, a request to the address /engines/id/state would map to a function get_state(engine_id) which I provide.

+7  A: 

A self-hosted WCF service is not a bad start; here's a tiny one for starters:

open System
open System.IO 
// add reference to these two guys, need .NET full (not client profile)
open System.ServiceModel
open System.ServiceModel.Web

[<ServiceContract>]
type MyContract() =
    [<OperationContract>]
    [<WebGet(UriTemplate="{s}/{t}")>]
    member this.Get(s:string, t:string) : Stream =
        let html = sprintf @"
<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">
<html><head></head><body>Called with '%s' and '%s'</body></html>" s t
        upcast new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html))

let Main() =
    let address = "http://localhost:64385/"
    let host = new WebServiceHost(typeof<MyContract>, new Uri(address))
    host.AddServiceEndpoint(typeof<MyContract>, new WebHttpBinding(), "") 
        |> ignore
    host.Open()
    printfn "Server running at %s" address
    printfn "Press a key to close server"
    System.Console.ReadKey() |> ignore
    host.Close()

Main()
// now go hit 
// http://localhost:64385/foo/42
// in your browser
Brian
After executing I get `Exception DispatchOperation '*' for contract 'MyContract' requires Invoker. at System.ServiceModel.Dispatcher.OperationInvokerHandler.EnsureValid (System.ServiceModel.Dispatcher.DispatchOperation operation) [0x00000] in <filename unknown>:0` on the server and text starting with "falsetrue1310.." on the browser. I am using F# with Mono on OS X so may be there is a bug there. Any hint on what to look for?
Muhammad Alkarouri
Nope. I didn't even know WCF ran on Mono at all, wow.
Brian
you should probably add a "Mono" tag to your question
BlackTigerX
No problem. I just used mono as the test machine that I have access to at the moment. I need it in a Windows application tomorrow.
Muhammad Alkarouri
Thanks. The application works in Windows with a small snag, the text is downloaded rather than opened as a web page. My guess is that it needs a header `text/html` sent somehow.
Muhammad Alkarouri
You can change the content type by adding this to the `Get` method: ` WebOperationContext.Current.OutgoingResponse.ContentType <- "text/html"` (There might be an easier way / a global setting.)
wmeyer
+1  A: 

I have not looked into this at all, but maybe glance at

http://github.com/ademar/suave/blob/master/README.textile#readme

Suave is a simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition.

Brian
Looks very interesting. Thanks.
Muhammad Alkarouri
A: 

Take a look at frack (a Rack-like interface), and if you need a nicer syntax, frank (which builds on top of frack).

There's also Kayak, it's written on C# but you could easily use it from F#.

Mauricio Scheffer