Actualmente no hay un servidor HTTP en la biblioteca estándar. Adam Ruppe tiene para trabajar en la web, pero actualmente no incluye un servidor web independiente.
El siguiente programa es un servidor HTTP básico simple de una sola hebra, para fines educativos . Generar una respuesta HTTP válida depende de usted; pero al menos analiza el encabezado y le da la oportunidad de responder en función de los detalles de de la solicitud.
import std.algorithm;
import std.conv;
import std.stdio;
import std.socket;
import std.string;
// usage: ./server port
void main(string[] args)
{
enum BACKLOG = 8;
ushort PORT = to!ushort(args[1]);
Socket s = new TcpSocket(AddressFamily.INET);
s.bind(new InternetAddress("0.0.0.0", PORT));
s.listen(BACKLOG);
scope (exit)
{
s.shutdown(SocketShutdown.BOTH);
s.close();
}
while (true)
{
debug writeln("waiting...");
Socket conn = s.accept();
scope (exit)
{
conn.shutdown(SocketShutdown.BOTH);
conn.close();
}
try
{
handleHttp(conn);
}
catch (Throwable e)
{
stderr.writeln("thrown: ", e);
}
}
}
void handleHttp(Socket conn)
{
// Make a buffer big enough to read a full HTTP header. My approach here is to
// read the header in its entirety before proceeding. This isn't production
// quality, but good enough for some applications.
ubyte[8192] buf; // big enough for some purposes...
size_t position, headerEnd, len, newpos;
// Receive the whole header before parsing it.
while (true)
{
len = conn.receive(buf[position..$]);
if (len == 0) // empty request
return;
newpos = position + len;
headerEnd = countUntil(buf[position..newpos], "\r\n\r\n");
position = newpos;
if (headerEnd >= 0)
break;
}
// Anything beyond headerEnd+4 is part of the request body. For now, bail:
// no POSTs or PUTs allowed. Feel free to remove the assert & implement them!
assert (position-(headerEnd+4) == 0,
"Sorry, only content-free requests are supported.");
// Now parse the header.
auto lines = splitter(buf[0..headerEnd], "\r\n");
string request_line = cast(string) lines.front;
lines.popFront;
debug writeln(request_line);
// a very simple Header structure.
struct Pair
{
string key, value;
this(ubyte[] line)
{
auto tmp = countUntil(line, ": ");
key = cast(string) line[0..tmp]; // maybe down-case these?
value = cast(string) line[tmp+2..$];
}
}
Pair[] headers;
foreach(line; lines)
headers ~= Pair(line);
auto tmp = splitter(request_line, ' ');
string method = tmp.front; tmp.popFront;
string url = tmp.front; tmp.popFront;
string protocol = tmp.front; tmp.popFront;
debug writefln("%s, %s, %s", method, url, protocol);
// Prepare a response, and send it
string resp = join(["HTTP/1.1 200 OK",
"Content-Length: 2",
"Content-Type: text/plain",
"Connection: close",
"",
"OK"],
"\r\n");
conn.send(cast(ubyte[]) resp);
}
¿Tiene permiso para escuchar en el puerto 80 o en cualquier otro puerto de bajo nivel? Pruebe con el puerto 8080 o alguna otra cosa que no esté en el rango restringido. – gmfawcett
Lo estaba intentando con el puerto 3000. También lo probé con 8080 y algunos otros. –