Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

This is probably the simplest Web-server in the world. It is not the most efficient because it runs only single-threaded and does not keep track of clients and closes the connection after every thread. Public domain by TomD.

/*
 * Minimal webserver (listening on port 8080)
 */
module mwebserver;
private import  tango.io.device.File;
private import  tango.io.Path;
private import  tango.io.model.IConduit;

private import  tango.net.device.Socket,
                tango.net.InternetAddress;
   
private import tango.text.Util;
private import tango.text.convert.Layout;

version(Windows){
  const char[] DOCROOT="c:/DATA/tdemmer/";
}
version(linux){
  const char[] DOCROOT="/home/rp/";
}
const int SRVPORT = 8080;

bool 
sendFile(in char[] name, OutputStream dst){
  const(char)[] fullName = DOCROOT ~ name;
  string mtype;
  // Check if file exists
  auto p = tango.io.Path.parse(fullName);
  if ( !exists( fullName )){
    return false;
  }
  // Shorter as an AA?
  switch(p.suffix){
  case ".htm":
  case ".html": 
    mtype = "text/html;charset=utf-8";
    //mtype = "application/xhtml+xml;charset=utf-8";
    break;
  case ".xhtml": 
    mtype = "application/xhtml+xml;charset=utf-8";
    break;
  case ".jpg":
    mtype = "image/jpeg";
    break;
  case ".gif":
    mtype = "image/gif";
    break;
  case ".svg":
    mtype = "image/svg+xml";
    break;
  case ".png":
    mtype = "image/png";
    break;
  case ".css":
    mtype = "text/css";
    break;
  case ".js":
    mtype = "application/x-javascript";
    break;
  default: 
    mtype = "application/octet-stream";
    return false;
  }
  
  ulong fsize = fileSize(fullName);
  auto layout = new Layout!(char);
  
  // print header
  dst.write( layout("HTTP/1.1 200 OK\r\nServer: miniserver/0.1\r\n"
                   "Connection: close\r\nContent-Length: {}\r\n"
                   "Content-Type: {}\r\n\r\n", fsize, mtype));
  // write file
  auto fc = new File(fullName);
  dst.copy(fc);
  fc.close();
  return true;
}

void 
main(){
  auto server = new ServerSocket (new InternetAddress(SRVPORT));
  // wait for requests
  while(1){
    auto request = server.accept;
    char[1024] req;
    auto len = request.input.read(req);
    if (req[0..3] == "GET"){
      auto blnk = locate(req[4..len], ' ', 0);
      auto rf = req[4..blnk+4];
      if(!sendFile(rf,request.output)){
        request.output.write("404: File not found\n");
      }
    }else{
      // write a response 
      request.output.write ("server replies:"~req[0..len]);
    }
    request.close;
  }
}