C (gcc -lws2_32
+ winsock2.h
), 408 bytes
Z;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S="HTTP/1.1 200 OK%c%cContent-Length: 408%c%c%c%cZ;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S=%c%s%c,13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}",13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}
This uses the Windows Socket 2 API. I have made many questionable choices for the sake of the golf, so there is likely some instability. Listens to an arbitrary number of HTTP requests on port 1025
. Compiled with gcc server.c -o server -lws2_32
(e.g.).
Verification
In Firefox:
[![A picture of the Quine in action on Firefox, showing the full code from earlier.][2]][2]
Here is the Ruby test harness I used to verify integrity:
require "net/http"
puts "Waiting for server to start..."
server_process = IO.popen("server.exe") { |server|
3.times { |i|
response = Net::HTTP.get_response(URI("http://localhost:1025")).body
puts "Response ##{i} obtained:"
puts response
puts "Same as server.c?"
puts File.read("server.c") == response
}
puts "Killing server..."
Process.kill("KILL", server.pid)
}
Which, when run:
λ ruby test-server.rb
Waiting for server to start...
Response #0 obtained:
Z;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S="HTTP/1.1 200 OK%c%cContent-Length: 408%c%c%c%cZ;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S=%c%s%c,13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}",13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}
Same as server.c?
true
Response #1 obtained:
Z;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S="HTTP/1.1 200 OK%c%cContent-Length: 408%c%c%c%cZ;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S=%c%s%c,13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}",13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}
Same as server.c?
true
Response #2 obtained:
Z;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S="HTTP/1.1 200 OK%c%cContent-Length: 408%c%c%c%cZ;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(9,M);sprintf(M,S=%c%s%c,13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}",13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,448,0);}
Same as server.c?
true
Killing server...
Explanation
Using fairly standard quining techniques, although my gcc on Windows does not support the POSIX extension for referencing existing *printf
arguments (as in this quine, so we must duplicate quite a few constants. At one point, I tried using unprintable characters in multiple places (`Q="\x02\x00''"), but that seemed to not work well with browsers interfacing with the server.
Here is an expanded version, producing the same output as above (so no longer a quine itself), but commented:
// our socket description integer
Z;
// the server code contained here
main() {
char
// our format string to be passed into sprintf
*S,
// shorthand for our struct sockaddr_in, which is passed to bind and accept
// struct sockaddr_in address = { .sin_family = AF_INET /*=2*/, .sin_port = htons(1025) /*=0x0401*/ };
// [NOTE 1]
Q[16] = { 2, 0, 4, 1 },
// M serves two purposes: 1. to be a sprintf buffer and 2. to be allocated memory to allow WSAStartup to run without crashing
*M = malloc(999);
// usually, wVersionRequired is version of windows sockets required (e.g. 2.1 would be 0x0201 = 513), and would be expressed like MAKEWORD(2,3)
// while wVersionRequired can't be 0, from testing, 9 seems to work.
WSAStartup(9, M);
// the main quine section
sprintf(
// the message buffer
M,
// the format string
S = "HTTP/1.1 200 OK%c%cContent-Length: 412%c%c%c%cZ;main(){char*S,Q[16]={2,0,4,1},*M=malloc(999);WSAStartup(514,M);sprintf(M,S=%c%s%c,13,10,13,10,13,10,34,S,34);bind(Z=socket(2,1,0),Q,16);for(listen(Z,3);;)send(accept(Z,Q,0),M,452,0);}",
// \r\n after 200 OK
13, 10,
// \r\n\r\n after headers
13, 10, 13, 10
// " followed by our string followed by ",
34, S, 34,
);
// binds our socket to our target address
bind(
// creates a socket with a particular configuration.
// socket(
// address family specification; AF_INET == 2, and represents IPv4
// the socket type specification; SOCK_STREAM == 1, and represents two-way connections
// the protocol subtype; 0, since we don't need to specify anything further
// )
// returns a socket description integer
Z = socket(2,1,0),
// the string from earlier, reinterpreted as an address struct
Q,
// the size of the address struct; expected to be 16
16
);
// infinite loop
for(
// but first, to save a semicolon, start listening on our socket
// we arbitrarily choose 3 as a backlog queue size
listen(Z, 3);
;
) {
// reply to the request with the message
send(
// accept a request on the address for our socket
accept(Z, Q, 0),
// the message to report
M,
// its length
452,
// flags; none chosen
0
);
}
}
Note 1: We can omit the more precise property specification .sin_addr = { .s_addr = INADDR_ANY }
as INADDR_ANY == 0
. If we did need it, we do have the golfy option Q={2,1025,{0}}
.