www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - tiny web server in D

reply Dr.Smith <ds nomail.com> writes:
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();
    }
}
Jul 13 2011
parent reply Jos van Uden <user domain.invalid> writes:
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(); } }
Jul 13 2011
parent reply Dr.Smith <ds nomail.com> writes:
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.
Jul 14 2011
parent reply Adam Ruppe <destructionator gmail.com> writes:
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.
Jul 14 2011
parent Dr.Smith <ds nomail.com> writes:
Thank you Adam,
Your code is comprehensive.  I will read it closely for ideas.
I seek a minimalist approach for locally run applications.
Jul 14 2011