Thread overview
tiny web server in D
Jul 14, 2011
Dr.Smith
Jul 14, 2011
Jos van Uden
Jul 14, 2011
Dr.Smith
Jul 14, 2011
Adam Ruppe
Jul 15, 2011
Dr.Smith
July 14, 2011
While the following D program runs without compiler error, it seems unable to serve a web page.  Is there a better way?

import std.socket, std.string;

void main() {
    Socket listener = new TcpSocket;
    assert(listener.isAlive);
    listener.bind(new InternetAddress(8080));
    listener.listen(10);
    string webpage = "index.html";

    Socket currSock;
    uint bytesRead;
    ubyte buff[1];

    while(1) {
        currSock = listener.accept();
        while ((bytesRead = currSock.receive(buff)) > 0) {
           currSock.sendTo(webpage);
        }
        currSock.close();
        buff.clear();
    }
}
July 14, 2011
On 14-7-2011 5:48, Dr.Smith wrote:
> import std.socket, std.string;
>
> void main() {
>      Socket listener = new TcpSocket;
>      assert(listener.isAlive);
>      listener.bind(new InternetAddress(8080));
>      listener.listen(10);
>      string webpage = "index.html";
>
>      Socket currSock;
>      uint bytesRead;
>      ubyte buff[1];
>
>      while(1) {
>          currSock = listener.accept();
>          while ((bytesRead = currSock.receive(buff))>  0) {
>             currSock.sendTo(webpage);
>          }
>          currSock.close();
>          buff.clear();
>      }
> }

I recieve

index.htmlindex.htmlindex.html etc etc

if I use this, it works

import std.socket, std.string;

void main() {
    Socket listener = new TcpSocket;
    assert(listener.isAlive);
    listener.bind(new InternetAddress(8080));
    listener.listen(10);
    string webpage = "<html><body>hi</body></html>";

    Socket currSock;
    uint bytesRead;
    ubyte buff[1];

    while(1) {
        currSock = listener.accept();
        if ((bytesRead = currSock.receive(buff)) > 0) {
           currSock.sendTo(webpage);
        }
        currSock.close();
        buff.clear();
    }
}
July 14, 2011
The program as such can regurgitate a web page provided these additional lines:

string webpage = "index.html";
string output = "HTTP/1.1 200 OK\r\n Content-Type: text/html; charset=UTF-8\r\n\r
\n" ~ to!string(read(webpage) ~ "\r\n";

This does not serve a page as localhost:port/webpage.html, but merely displays output on localhost:port

I've been exploring std.socket for an efficient solution.  It might also be desirable to get the program to open the port only on request.
July 14, 2011
std.socket is too low level for serving webpages. It just provides the means to talk on the network, but doesn't do any application protocols like http.

I've written a little http server in D, but it uses linux system calls instead of std.socket, so it only works on linux.

http://arsdnet.net/dcode

Check out httpd.d and netman.d in there. Also, my cgi.d can work together with them to serve web apps through the mini web server.


But as you can see, a lot of the code is parsing and writing http.

When you go to a web site, your browser sends something like this to the server:

GET /index.html HTTP/1.1
Host: mysite.com

Then, the server replies:

HTTP/1.1 200 OK
Content-Length: 13
Content-Type: text/plain
Connection: close

Hello, world!


Then the connection is closed and the get is complete.
July 15, 2011
Thank you Adam,
Your code is comprehensive.  I will read it closely for ideas.
I seek a minimalist approach for locally run applications.