Hello world/Web server task on RosettaCode fails

jfondren julian.fondren at gmail.com
Fri Jul 16 20:04:21 UTC 2021


On Friday, 16 July 2021 at 19:25:32 UTC, btiffin wrote:
> Using gdc-11 and Seamonkey.  
> https://rosettacode.org/wiki/Hello_world/Web_server#D does not 
> compile.

The `while` as you noted is wrong. The server also doesn't turn 
REUSEADDR on for the server socket, so this will be very annoying 
to test as you'll frequently get "address already in use" errors 
when you restart the server. The delimited string leads to your 
last problem: a blank space between the headers and the body of 
the response results in "\r\n \r\n" being sent rather than 
"\r\n\r\n", so the browser gives up on the invalid HTTP.

This works if you're careful to not re-add any stray whitespace 
in the response:

```d
import std.socket, std.array;

ushort port = 8080;

void main() {
     Socket listener = new TcpSocket;
     listener.bind(new InternetAddress(port));
     listener.setOption(SocketOptionLevel.SOCKET, 
SocketOption.REUSEADDR, 1);
     listener.listen(10);

     Socket currSock;

     while (null !is (currSock = listener.accept())) {
         currSock.sendTo(replace(q"EOF
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<html>
   <head><title>Hello, world!</title></head>
   <body>Hello, world!</body>
</html>
EOF", "\n", "\r\n"));
         currSock.close();
     }
}
```

Personally I'd prefer something more like:

```d
import std.socket : Socket, TcpSocket, SocketOption, 
SocketOptionLevel, InternetAddress;
import std.array : replace, array;
import std.algorithm : map, joiner;
import std.string : splitLines, strip;
import std.conv : to;

ushort port = 8080;

// dfmt off
static const greeting = q"EOF
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8

<html>
   <head><title>Hello, world!</title></head>
   <body>Hello, world!</body>
</html>
EOF"
     .splitLines
     .map!strip
     .joiner("\r\n")
     .to!string;
// dfmt on

void main() {
     import std.stdio : writefln;

     Socket listener = new TcpSocket;
     listener.bind(new InternetAddress(port));
     listener.setOption(SocketOptionLevel.SOCKET, 
SocketOption.REUSEADDR, 1);
     listener.listen(10);
     writefln!"Listening on port %d."(port);

     while (true) {
         scope client = listener.accept;
         writefln!"Received connection from 
%s."(client.remoteAddress.toString);
         client.send(greeting);
         client.close;
     }
}
```

But this *still violates HTTP* by not receiving the client's 
request, so it's still not a good answer for the task. A vibe 
hello world would make a lot more sense:
https://github.com/vibe-d/vibe.d/blob/master/examples/http_server/source/app.d

> If this is the wrong place for this kind of info note, I'll 
> gladly move to or redo the post in a more appropriate spot.

You're in the right place.


More information about the Digitalmars-d-learn mailing list