418: soy una tetera


68

Como todos deberíamos saber, hay un código de estado HTTP 418: soy una tetera .

Su misión, si elige aceptarla, es utilizar su creatividad y escribir el servidor más pequeño posible que responda con el código de estado anterior a todas y cada una de las solicitudes HTTP que se le hagan.

Se aplican lagunas estándar , que incluyen

Obteniendo la salida deseada de una fuente externa

Esto incluye hacer una solicitud HTTP para buscar la página con la pregunta y extraer una solución de esa página. Esto fue ligeramente divertido en 2011, pero ahora es derivado y poco interesante.

Lo que significa que no puede simplemente redirigir la solicitud a otro servidor para que devuelva la respuesta.


Abordar cierta confusión sobre la funcionalidad del servidor:
su servidor puede hacer cualquier cosa (o nada) mientras no se realiza una solicitud HTTP, siempre que responda con la respuesta correcta una vez que se realiza una solicitud HTTP.


15
a todas y cada una de las solicitudes http? Seguramente solo para un café: URI?
Dave

3
¿Podemos suponer que ya tenemos privilegios de root? (por ejemplo, bind () al puerto 80 está bien)
Digital Trauma

2
@DigitalTrauma Sí, puede asumir privilegios escalados para su servidor.
Nit

44
@Knerd Me estoy inclinando hacia el lado opuesto, no estás escribiendo un programa, simplemente estás configurando uno.
Nit

2
Dios mio. Con el IOT, este código de estado puede tener una razón real para existir.
Luminoso

Respuestas:


39

GNU Awk: 69 caracteres

Un servidor en sí mismo (atiende sin cesar una solicitud a la vez), no se utiliza biblioteca.

Enviar 418 a todos los que se conectan ( 82 69 caracteres):

BEGIN{while(s="/inet/tcp/80/0/0"){print"HTTP/1.1 418\n"|&s
close(s)}}

Enviar 418 a todos los que envían algo ( 93 80 caracteres):

BEGIN{while(s="/inet/tcp/80/0/0"){s|&getline
print"HTTP/1.1 418\n"|&s
close(s)}}

Envíe 418 a todos los que envíen una solicitud HTTP GET válida ( 122 109 caracteres):

BEGIN{while(s="/inet/tcp/80/0/0"){s|&getline
if(/^GET \S+ HTTP\/1\.[01]$/)print"HTTP/1.1 418\n"|&s
close(s)}}

Pero ... ¿cómo conectarse? ;)
Optimizador

55
De la misma manera que te conectas a cualquier servidor web. Navegador, netcat, telnet, wget, curl, otro GNU awkguión, ... En teoría se escucha en localhost: 80, pero para que 1) no hay un servidor web, Skype u otro programa debe utilizar el puerto 80; 2) tienes que ser superusuario para abrir puertos por debajo de 1024. Por lo tanto, para probar es más fácil editar el número de puerto en el script a algo como 8080 ( s="/inet/tcp/8080/0/0") y luego conectarte a eso. pastebin.com/zauP7LMA
manatwork

2
Veo. Bueno. Awk noob aquí :)
Optimizador

1
Posiblemente podría guardar un byte utilizando un puerto más pequeño como 8, que no está asignado.
Hannes Karppila

@HannesKarppila, eso es correcto. Pero dado que todas las demás soluciones que especifican explícitamente un puerto (excepto el puerto 8888 de la respuesta de Haskell) usan el puerto 80, es mejor que lo mantenga así para la comparabilidad.
manatwork

32

Golpe (33)

nc -lp80 -q1<<<"HTTP/1.1 418
";$0

3
¿Son necesarias las dos nuevas líneas? Parece funcionar bien con solo uno para mí. Además, según mi recuento, lo anterior es de 34 bytes; supongo que su editor está agregando una nueva línea innecesaria o \0al final de su archivo, puede truncatehacerlo y aún funciona. s='echo HTTP/1.1 418|nc -lp80 -q1;$0' ; echo ${#s}da 33 para mí
Digital Trauma

@DigitalTrauma: Tienes razón: la nueva línea final se agrega automáticamente en las cadenas aquí: ¿Por qué un bash here-string agrega un carácter de línea nueva final? ------ Pero veo dos posibles problemas: 1. El script espera que esté almacenado en uno de los $PATHdirectorios o que se llame con una ruta (recursividad por $0). ----- 2. HTTP requiere que las líneas terminen \r\nno solo \n. Aquí la cadena debe ser $"HTTP/1.1 418\r\n\r"(forma legible más larga). ------ Y finalmente: el script podría ser más corto: el -q1parámetro no es necesario.
Pabouk

2
@DigitalTrauma, @pabouk: La salida debe terminar con dos líneas nuevas. Entonces, una de las nuevas líneas era innecesaria (debido a la cadena aquí), pero la echovariante no funciona (al menos Firefox no la reconocerá como un 418). Sin embargo, los \rs no son necesarios. La especificación dice que debería ser \r\n\r\n, pero al menos Firefox y Chrome aceptarán \n\n, por lo que parece estar en el espíritu del golf no incluirlos. El -q1parámetro era necesario en mi sistema, porque el navegador no cerrará la conexión por sí mismo. $0funciona bien si el script se hace ejecutable y se llama de esa manera.
Marinus

@marinus Interesante - Estaba probando con lo wgetque parece estar bien con solo una nueva línea
Digital Trauma

1
@pabouk - Fragmento interesante aquí w3.org/Protocols/HTTP/OldServers.html : "Las líneas deben considerarse como terminadas por el avance de línea, y el carácter anterior de retorno de carro ignorado"
Trauma digital

30

PHP - 85 bytes

<?for($s=socket_create_listen(80);socket_write(socket_accept($s),"HTTP/1.1 418
"););

Guardado con terminaciones de línea estilo Windows (CR-LF), requiere php_socketshabilitado.

De hecho, usé esto como mi código de error para Hard Code Golf: crear un desafío de sala de chat , pero nadie se dio cuenta.


Versión amigable para el navegador

<?for(socket_getsockname($s=socket_create_listen(80),$n);$t="I'm a teapot";socket_write($c=socket_accept($s),"HTTP/1.0 418 $t
Content-Length: $l

<title>418 $t</title><h1>$t</h1>The requested resource is not suitable for brewing coffee.<hr><i>$n:80</i>"))$l=124+strlen($n);

Inicie el script en la CLI y apunte su navegador a http://localhost.


1
+1 para la simplicidad del usuario / I'm a teapot:-)
Levit

20

Node.js (LiveScript)

http módulo - 66

require(\http)createServer (->&1.writeHead 418;&1.end!) .listen 80

Inspirado por la respuesta de Qwertiy .

net módulo - 76

require(\net)createServer (->it.write 'HTTP/1.1 418\r\n';it.end!) .listen 80

2
¿Podría la persona que rechazó el voto explicar por qué?
nyuszika7h

20

Ruby + Rack, 19 bytes

run->e{[418,{},[]]}

Debe guardarse como config.ruy ejecutarse con el rackupcomando.

O si prefieres Ruby "puro":

Rack::Handler::WEBrick.run->e{[418,{},[]]}

42 bytes + -rrackbandera = 48 bytes


12

Comandos generales de Bash + BSD, 29

Recurriendo un poco a otras respuestas:

nc -lp80<<<"HTTP/1.1 418
";$0

Funciona para mí con wget.

Primera respuesta al uso nc, 38

for((;;)){
nc -l 80 <<<HTTP/1.1\ 418
}

Asumo privilegios de root: ejecute lo siguiente:

sudo bash ./418.sh

3
@ ub3rst4r Correcto - Es por eso que dije "comandos generales BSD", que pueden considerarse como una "biblioteca" desde el punto de vista de las secuencias de comandos de shell. Desde el OP: "Todas las bibliotecas son bienvenidas"
Digital Trauma

2
Una respuesta debe terminar con una nueva línea, ver w3.org/Protocols/HTTP/Response.html
Nit

2
@Nit - Sí, se agregará automáticamente una nueva línea a bash "here strings"
Digital Trauma

1
¿Qué talnc -l 80 <<<HTTP/1.1\ 418;$0
core1024

1
Perdón por la confusión con los dos espacios. No me di cuenta de que no -pusaste el interruptor :) Probé el código con Firefox y sin dos líneas nuevas no se reconoce el código de estado.
Pabouk

9

Ruby (comando del sistema nc) - 35

loop{`nc -l 80 <<<"HTTP/1.1 418"`}

DigitalTrauma debería obtener el crédito por la idea de usar nc, sin embargo, Ruby puede hacer un ciclo infinito con menos caracteres que Bash :)

Rubí (TCPServer) - 75

require'socket'
s=TCPServer.new 80
loop{(s.accept<<'HTTP/1.1 418
').close}

Esa nueva línea es intencional: el carácter de nueva línea real es un carácter más corto que "\ n".

Rubí (WEBrick HTTPServer) - 87

require'webrick'
(s=WEBrick::HTTPServer.new).mount_proc(?/){|_,r|r.status=418}
s.start

Una respuesta debe terminar con una nueva línea, consulte w3.org/Protocols/HTTP/Response.html
Nit

1
@DigitalTrauma, iba a usar eso, pero luego me di cuenta de que la barra invertida debe escaparse con otra barra invertida, por lo que habría sido la misma cantidad de caracteres de todos modos :)
Trey Thomas

@TreyThomas Oh, ya veo, por lo que Ruby necesita un nivel adicional de escape aquí
Digital Trauma

8

Node.js, 80

require('http').createServer(function(q,s){s.writeHead(418);s.end()}).listen(80)

La respuesta es

HTTP/1.1 418 I'm a teapot
Date: Wed, 19 Nov 2014 21:08:27 GMT
Connection: keep-alive
Transfer-Encoding: chunked

0

2
Me parece increíble que ese nodo admita ese código de error de forma nativa ^^
Levit

8

Python 3 106

s=__import__('socket').socket(2,1) 
s.bind(('',80))
s.listen(9)
while 1:s.accept()[0].send('HTTP/1.1 418\n')

1
Basado en el comentario de hallvabo en Consejos para jugar golf en Python , es más corto. from socket import*;s=socket(AF_INET,SOCK_STREAM)
trabajo de

@manatwork Gracias, ¿hay una forma más corta de bucle infinito? No encontré ninguno en los consejos ...
Tuomas Laakkonen

3
while 1:s.accept()[0].sendall(bytes('HTTP/1.1 418\n','UTF8'))- A menos que me haya perdido algo. (Por cierto, no dude en contar con nuevas líneas de una sola personajes, como el lenguaje les permite esa manera usted no pierde nada con la separación de los comandos por saltos de línea en lugar de. ;.)
manatwork

Puede cortar 2 caracteres asumiendo que el puerto 80 es accesible, de acuerdo con el comentario del propietario de la pregunta . Una cosa fea que puede romper la portabilidad, pero puede ser aceptable aquí: usar los valores de las constantes directamente s=socket(2,1)(al menos esos son sus valores en mi Linux).
manatwork

La documentación dice para listen()el parámetro de que "el valor máximo depende del sistema (generalmente 5)". Entonces, en lugar de 10, 9 es más que suficiente y 1 personaje más corto. Y en lugar de bytes('HTTP/1.1 418\n','UTF8')un literal b'HTTP/1.1 418\n'es suficiente. O si bcrea el código Python 2, entonces el prefijo de bytes ya no es necesario. Y el más corto send()también parece ser suficiente.
manatwork

7

Haskell - 142 bytes

import Network
import System.IO
main=listenOn(PortNumber 8888)>>=f
f s=do{(h,_,_)<-accept s;hPutStr h"HTTP/1.1 418\r\n";hFlush h;hClose h;f s}

5

Tcl (> = 8.5), 78 bytes

Editar: agregado en una nueva línea adicional (un total de 2 nuevas líneas) en aras del cumplimiento.

socket -server {apply {{c - -} {puts $c "HTTP/1.1 418
";close $c}}} 80
vwait f

Una respuesta debe terminar con una nueva línea, consulte w3.org/Protocols/HTTP/Response.html
Nit

3
@Nit: Sí, Tcl put agregará automáticamente una nueva línea, a menos que se proporcione la opción -nonewline. tcl.tk/man/tcl/TclCmd/puts.htm
Digital Trauma

5

Julia: 86 73 caracteres

s=listen(80)
while 1<2
c=accept(s)
write(c,"HTTP/1.1 418

")
close(c)
end

No creo que necesite la parte real "Soy una tetera": el código de respuesta debería ser suficiente.
Desty

Sí, lo noté Pero como eso no ayudará mucho en el puntaje de Julia, lo mantuve completo. Pero probablemente sería mejor eliminarlo para facilitar la comparación de idiomas.
manatwork

5

Powershell, 398

$Listener = New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Parse("10.10.10.10"), 80)
$Listener.Start()
while($true)
{
    $RemoteClient = $Listener.AcceptTcpClient()
    $Stream = $RemoteClient.GetStream()
    $Writer = New-Object System.IO.StreamWriter $Stream
    $Writer.Write("HTTP/1.1 418 I'm a Teapot`nConnection: Close`n`n")
    $Writer.Flush()
    $RemoteClient.Close()
}

258

$l=New-Object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Parse("10.10.10.10"),80);$l.Start();while($true){$r = $l.AcceptTcpClient();$s = $r.GetStream();$w = New-Object System.IO.StreamWriter $s;$w.Write("HTTP/1.1 418`n`n");$w.Flush();$r.Close()}

5

R, 80 caracteres

Nunca hice programación de sockets con R antes, pero lo intentaré:

repeat{s=socketConnection(,80,T,open="r+");cat("HTTP/1.1 418\n",file=s);close(s)}

Aquí se socketConnectionabre un socket: el primer argumento debe ser el host, el valor predeterminado es localhostque podemos omitirlo aquí; el segundo argumento es el puerto que no tiene valor predeterminado, luego el argumento servercuando se especifica TRUEcrea el socket, si FALSEsolo se conecta a uno existente. Tes, por defecto, igual a TRUE, en R.

Editar: como se sugiere en una edición sugerida por @AlexBrown, esto podría acortarse en 69 caracteres :

repeat cat("HTTP/1.1 418\n",file=s<-socketConnection(,80,T))+close(s)

4

Node.js koa , 61 Bytes

require('koa')().use(function*(){this.status=418}).listen(80)

Respuesta:

HTTP/1.1 418 I'm a teapot
X-Powered-By: koa
Content-Type: text/plain; charset=utf-8
Content-Length: 12
Date: Thu, 20 Nov 2014 07:20:36 GMT
Connection: close

I'm a teapot

Requiere el nodo v0.11.12 +

Correr como:

node --harmony app.js

¿Qué es function*?
nyuszika7h

2
Esa es una función generadora , parte de la propuesta de armonía ECMAScript 6.
cPu1

4

Shell + socat, 60

socat tcp-l:80,fork exec:'printf HTTP/1.1\\ 418\\ T\r\n\r\n'

echo -e HTTP/1.1 418 T\r\n\rEs más corto.
jimmy23013

El \\ Tni siquiera es necesario.
nyuszika7h

3

MATLAB, 97 86 bytes

No es realmente un contendiente serio en términos de conteo absoluto de bytes, pero me gustaría publicarlo porque no pensé que fuera posible escribir un servidor web completamente funcional usando una herramienta matemática. Tenga en cuenta el uso del acortamiento de propiedades : se 'Ne','s'expande internamente a 'NetworkRole', 'server'.

t=tcpip('0.0.0.0','Ne','s');while 1
fopen(t)
fprintf(t,'HTTP/1.1 418\n')
fclose(t)
end

3

Puede hacer esto con un mínimo esfuerzo utilizando un .htaccessarchivo y php.

Todos los accesos a su servidor devolverán el estado 418.

Debajo está el código:

.htaccess (28 bytes)

RewriteRule .* index.php [L]

PHP ( 38 19 bytes)

<<?header(TE,1,418);

¡Gracias a @primo por salvarme un montón de bytes!


¡He probado esto y confirmo que devuelve el resultado deseado!

http://i.stack.imgur.com/wLb9p.png

Por cierto, "Pedido" significa "Solicitud" y "Resposta" significa "Respuesta".


-1, este no es un programa completo. Se basa en un servidor web externo.
nyuszika7h

@ nyuszika7h En realidad, se basa en Apache con PHP instalado como módulo. Su argumento es válido e inválido. Apache solo redirige los accesos al archivo PHP, el archivo PHP se encarga del código.
Ismael Miguel

@ nyuszika7h Si bajamos a esa capa, entonces ni siquiera puedes usar la consola para ejecutar tu código PHP. Apache es el iniciador. El gatillo que dispara la bala. Ejecutar el archivo PHP desde la consola, haría que la consola sea el disparador.
Ismael Miguel

Estás confiando en que Apache ya se esté ejecutando, y no creo que funcione sin cambiar la configuración predeterminada tampoco. No me importa lo que digas, no hay forma de que pueda ver esto como válido. Pero deberías preguntar a @Nit, ya que es su pregunta.
nyuszika7h

@ nyuszika7h Si no fuera válido, el OP ya lo habría dicho.
Ismael Miguel

2

node.js con CoffeeScript (76)

require("connect")().use((q,s,n)->s.writeHead 418;s.end();return;).listen 80

Simplemente compílelo en JavaScript, luego debe ejecutarlo npm install connect. Después de eso comienza connode server.js



2

Perl, 78

use Web::Simple;sub dispatch_request{sub{[418,[],[]]}}__PACKAGE__->to_psgi_app

correr como plackup whatever.pl.


Si desea una aplicación de plack, entonces sub{[418,[],[]]}debería ser suficiente. (16 caracteres.)
tobyink

¡Por supuesto que tienes razón! No es que esté usando ninguno de los marcos, ¿por qué cargarlo? :)
hobbs

@tobyink dude en aportar como propio aunque :)
hobbs

2

Python 2.7 / Django, 94 bytes

(agregado de la plantilla predeterminada de django-admin.py startproject) En urls.py:

import django.http.HttpResponse as r;urlpatterns=patterns(url(r'^*$',lambda q:r(status=418)))

1

C # + OWIN 251 240

Realmente esperaba que fuera más corto, pero los largos espacios de nombres arruinaron ese plan. Requiere el Microsoft.Owin.SelfHostpaquete disponible en NuGet.

using Owin;class P{static void Main(){Microsoft.Owin.Hosting.WebApp.Start<P>("http://localhost");while(0<1);}public void Configuration(IAppBuilder a){a.Run(c=>{c.Response.StatusCode=418;return System.Threading.Tasks.Task.FromResult(0);});}}

1

node.js con connect (78)

require('connect')().use(function(q,s,n){s.writeHead(418);s.end()}).listen(80)

Necesitas correr npm install connectprimero. Entonces comience connode server.js


1

Go, 162 bytes

package main
import "net/http"
func main(){http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request){w.WriteHeader(418)})
http.ListenAndServe(":80", nil)
}

1

Factor, 101 141 bytes

[ utf8 <threaded-server> readln 10 base> >>insecure [ "HTTP/1.1 418\r" print flush ] >>handler [ start-server ] in-thread start-server drop ]

Regrese 418 a todos los que se conectan.


1

Java 7, 208 bytes

import java.net.*;class R{public static void main(String[]a)throws Exception{for(ServerSocket s=new ServerSocket(80);;){Socket p=s.accept();p.getOutputStream().write("HTTP/1.0 418\n".getBytes());p.close();}}}

Esta pregunta necesitaba una respuesta de Java.

poke@server ~
$ curl -i localhost:80
HTTP/1.0 418

¿Dónde está el mensaje de estado?
Qwertiy

@Qwertiy Creo que esta pregunta solo pide un código de estado que interpreto como el entero, por lo que se deduce que el mensaje de estado / razón no es estrictamente necesario.
Poke

No es mi decisión, pero creo que debería ser con texto de estado.
Qwertiy

3
Obtenga Java 8 ya> _>
Pavel

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.