418: Sono una teiera


68

Come tutti sappiamo, esiste un codice di stato HTTP 418: sono una teiera .

La tua missione, se scegli di accettarlo, è quella di utilizzare la tua creatività e scrivere il server più piccolo possibile che risponda con il codice di stato sopra riportato a qualsiasi richiesta HTTP che gli viene fatta.

Si applicano scappatoie standard , tra cui

Recupero dell'output desiderato da una fonte esterna

Ciò include l'esecuzione di una richiesta HTTP per recuperare la pagina con la domanda e l'estrazione di una soluzione da quella pagina. Questo è stato leggermente divertente nel 2011, ma ora è derivato e poco interessante.

Ciò significa che non è possibile reindirizzare semplicemente la richiesta a un altro server per restituire la risposta.


Affrontare un po 'di confusione sulla funzionalità del server: il
tuo server può fare qualsiasi cosa (o nulla) senza che sia stata fatta una richiesta HTTP purché risponda con la risposta corretta una volta effettuata una richiesta HTTP.


15
per ogni richiesta http? Sicuramente solo quelli per un caffè: URI?
Dave,

3
Possiamo presumere che abbiamo già i privilegi di root? (es. bind () alla porta 80 è ok)
Digital Trauma

2
@DigitalTrauma Sì, puoi assumere privilegi di escalation per il tuo server.
Nit

4
@Knerd Non mi sto appoggiando, non stai scrivendo un programma, ne stai semplicemente configurando uno.
Nit

2
Oh mio Dio. Con l'IOT in arrivo, questo codice di stato potrebbe avere un vero motivo per esistere!
Luminoso

Risposte:


39

GNU Awk: 69 caratteri

Un server stesso (serve all'infinito una richiesta alla volta), nessuna libreria utilizzata.

Invia 418 a tutti coloro che si connettono ( 82 69 caratteri):

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

Invia 418 a tutti coloro che inviano qualcosa ( 93 80 caratteri):

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

Invia 418 a tutti coloro che inviano una richiesta HTTP GET valida ( 122 109 caratteri):

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)}}

Ma .. come connettersi? ;)
Ottimizzatore

5
Allo stesso modo in cui ti connetti a qualsiasi server web. Browser, netcat, telnet, wget, curl, un altro GNU awksceneggiatura, ... Teoricamente in ascolto su localhost: 80, ma per quel 1) nessun server web, Skype o altri programmi dovrebbero utilizzare la porta 80; 2) devi essere un super utente per aprire le porte inferiori a 1024. Quindi per i test è più semplice modificare il numero di porta nello script in qualcosa di simile a 8080 ( s="/inet/tcp/8080/0/0"), quindi connettersi a quello. pastebin.com/zauP7LMA
arte

2
Vedo. Freddo. Awk noob qui :)
Ottimizzatore

1
È possibile salvare un byte utilizzando una porta più piccola come 8, che non è assegnata.
Hannes Karppila,

@HannesKarppila, è corretto. Ma dato che tutte le altre soluzioni che specificano esplicitamente una porta (eccetto la porta 8888 della risposta di Haskell) usano la porta 80, è meglio che la mantenga così per comparabilità.
arte

32

Bash (33)

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

3
Le due nuove linee sono necessarie? Sembra funzionare bene con uno solo per me. Inoltre, secondo il mio conteggio, quanto sopra è di 34 byte - suppongo che il tuo editor stia aggiungendo una nuova riga non necessaria o \0alla fine del tuo file - puoi truncatefarlo e funziona ancora. s='echo HTTP/1.1 418|nc -lp80 -q1;$0' ; echo ${#s}dà 33 per me
Digital Trauma

@DigitalTrauma: Hai ragione: la nuova riga finale viene aggiunta automaticamente nelle stringhe qui: Perché una stringa qui bash aggiunge un carattere newline finale? ------ Ma vedo due possibili problemi: 1. Lo script si aspetta che sia archiviato in una delle $PATHdirectory o che sia chiamato con un percorso (ricorsione da $0). ----- 2. HTTP richiede che le linee siano terminate \r\nnon solo \n. Qui la stringa dovrebbe essere $"HTTP/1.1 418\r\n\r"(forma più leggibile). ------ E infine: lo script potrebbe essere più breve: il -q1parametro non è necessario.
pabouk,

2
@DigitalTrauma, @pabouk: l'output deve terminare con due nuove righe. Quindi una delle nuove righe non era necessaria (a causa della stringa qui), ma la echovariante non funziona (almeno Firefox non la riconoscerà come 418). Tuttavia, le \rs non sono necessarie. Le specifiche dicono che dovrebbe essere \r\n\r\n, ma almeno Firefox e Chrome accetteranno \n\n, quindi sembra essere nello spirito del golf non includerle. Il -q1parametro era necessario sul mio sistema, perché il browser non chiudeva la connessione da solo. $0funziona bene se lo script è reso eseguibile e chiamato in quel modo.
Marin

@marinus Interessante: stavo provando con il wgetquale sembra andare bene solo con una nuova riga
Trauma digitale

1
@pabouk: frammento interessante qui w3.org/Protocols/HTTP/OldServers.html : "Le righe devono essere considerate terminate dal feed di riga e il precedente carattere di ritorno a capo del carrello ignorato"
Digital Trauma

30

PHP - 85 byte

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

Salvato con terminazioni di linea in stile Windows (CR-LF), richiede php_socketsabilitato.

In realtà l'ho usato come codice di errore per l' Hard Code Golf: creare una sfida Chatroom , ma nessuno se ne è accorto.


Versione compatibile con il browser

<?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);

Avviare lo script nella CLI e puntare il browser verso http://localhost.


1
+1 per la gentilezza dell'utente / I'm a teapot:-)
Levit

20

Node.js (LiveScript)

http modulo - 66

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

Ispirato dalla risposta di Qwertiy .

net modulo - 76

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

2
La persona che ha effettuato il downvoting potrebbe spiegare perché?
nyuszika7h,

20

Ruby + Rack, 19 byte

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

Deve essere salvato come config.rued eseguito con il rackupcomando.

O se preferisci il rubino "puro":

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

42 byte + -rrackflag = 48 byte


12

Comandi generali Bash + BSD, 29

Prendendo in prestito un po 'indietro dalle altre risposte:

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

Funziona con me wget.

Prima risposta da usare nc, 38

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

Sto assumendo i privilegi di root - esegui come segue:

sudo bash ./418.sh

3
@ ub3rst4r Corretto - Ecco perché ho dichiarato "comandi generali BSD", che possono essere considerati una "libreria" dal punto di vista dello scripting della shell. Dall'OP: "Tutte le biblioteche sono benvenute"
Digital Trauma,

2
Una risposta deve terminare con una nuova riga, vedere w3.org/Protocols/HTTP/Response.html
Nit

2
@Nit - Sì - bash "qui stringhe" verrà automaticamente aggiunto con una nuova riga
Digital Trauma

1
Che ne dicinc -l 80 <<<HTTP/1.1\ 418;$0
core1024

1
Scusate la confusione con i due spazi. Non ho notato che non hai utilizzato lo -pswitch :) Ho testato il codice con Firefox e senza due righe il codice di stato non è riconosciuto.
pabouk,

9

Ruby (comando di sistema nc) - 35

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

DigitalTrauma dovrebbe avere il merito dell'idea di usare nc, tuttavia Ruby può fare un ciclo infinito con meno caratteri di Bash :)

Ruby (TCPServer) - 75

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

Quella nuova riga è intenzionale: il carattere della nuova riga effettiva è più corto di "\ n".

Ruby (WEBrick HTTPServer) - 87

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

Una risposta deve terminare con una nuova riga, vedere w3.org/Protocols/HTTP/Response.html
Nit

1
@DigitalTrauma, stavo per usarlo, ma poi ho capito che la barra rovesciata doveva essere evasa con un'altra barra rovesciata, quindi sarebbe stato lo stesso numero di caratteri :)
Trey Thomas

@TreyThomas Oh, capisco, quindi Ruby ha bisogno di un ulteriore livello di fuga qui
Digital Trauma,

8

Node.js, 80

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

La risposta è

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
Trovo semplicemente fantastico che il nodo supporti nativamente quel codice di errore ^^
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
Sulla base del commento di Hallvabo in Consigli per giocare a golf in Python , è più breve. from socket import*;s=socket(AF_INET,SOCK_STREAM)
arte

@manatwork Grazie, c'è un modo più breve per eseguire un ciclo infinito? Non ne ho trovato uno nei suggerimenti ...
Tuomas Laakkonen,

3
while 1:s.accept()[0].sendall(bytes('HTTP/1.1 418\n','UTF8'))- a meno che non mi sia perso qualcosa. (A proposito, non esitate a contare a capo un singolo caratteri, come la lingua permette loro questo modo nulla sciolto separando i comandi con a capo al posto di. ;.)
manatwork

È possibile tagliare 2 caratteri supponendo che la porta 80 sia accessibile, in base al commento del proprietario della domanda . Una cosa brutta che può spezzare la portabilità, ma può essere accettabile qui: usa direttamente i valori delle costanti s=socket(2,1)(almeno quelli sono i loro valori sul mio Linux).
arte

La documentazione afferma per listen()il parametro "che il valore massimo dipende dal sistema (di solito 5)". Quindi, invece di 10, 9 è più che sufficiente e 1 carattere più corto. E invece di bytes('HTTP/1.1 418\n','UTF8')un letterale b'HTTP/1.1 418\n'è abbastanza. O se crei il codice Python 2, il bbytesprefix non è più necessario. E anche il più corto send()sembra essere abbastanza.
arte

7

Haskell - 142 byte

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 byte

Modifica: aggiunto in una nuova riga aggiuntiva (totale di 2 nuove righe) per motivi di conformità.

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

Una risposta deve terminare con una nuova riga, vedere w3.org/Protocols/HTTP/Response.html
Nit

3
@Nit - Sì, Tcl put aggiungerà automaticamente una nuova riga, a meno che non venga fornita l'opzione -nonewline. tcl.tk/man/tcl/TclCmd/puts.htm
Digital Trauma

5

Giulia: 86 73 caratteri

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

")
close(c)
end

Non penso che tu abbia bisogno dell'attuale parte "Sono una teiera" - il codice di risposta dovrebbe essere sufficiente.
Desty,

Sì, l'ho notato. Ma poiché ciò non aiuterà molto sul punteggio di Julia, l'ho tenuto completo. Ma probabilmente sarebbe meglio rimuoverlo per facilitare il confronto delle lingue.
arte

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 caratteri

Non ho mai programmato socket con R prima, ma ci proverò:

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

Qui socketConnectionapre un socket: il primo argomento dovrebbe essere l'host, il default è localhostche possiamo saltarlo qui; il secondo argomento è la porta che non ha valori predefiniti, quindi l'argomento, serverquando specificato, TRUEcrea il socket, se FALSEsi collega a uno esistente. Tè, per impostazione predefinita, uguale a TRUE, in R.

Modifica: come suggerito in una modifica suggerita da @AlexBrown, questo può essere abbreviato in 69 caratteri :

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

4

Node.js koa , 61 byte

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

Risposta:

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

Richiede il nodo v0.11.12 +

Correre come:

node --harmony app.js

Cosa function*?
nyuszika7h,

2
Questa è una funzione del generatore , parte dell'ECMAScript 6, proposta Harmony.
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\rè più corto.
jimmy23013,

Non \\ Tè nemmeno necessario.
nyuszika7h

3

MATLAB, 97 86 byte

Non è un serio contendente in termini di conteggio assoluto di byte, ma mi piacerebbe pubblicarlo perché non pensavo che sarebbe stato possibile scrivere un server web completamente funzionale usando uno strumento matematico. Si noti l'uso dell'accorciamento di proprietà : si 'Ne','s'espande 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

Puoi farlo con il minimo sforzo usando un .htaccessfile e php.

Tutti gli accessi al tuo server restituiranno lo stato 418.

Di seguito è riportato il codice:

.htaccess (28 byte)

RewriteRule .* index.php [L]

PHP ( 38 19 byte)

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

Grazie a @primo per avermi salvato un sacco di byte!


Ho provato questo e confermo che restituisce il risultato desiderato!

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

A proposito, "Pedido" significa "Richiesta" e "Resposta" significa "Risposta".


-1, questo non è un programma completo. Si basa su un server Web esterno.
nyuszika7h

@ nyuszika7h In realtà, si basa su Apache con PHP installato come modulo. Il tuo argomento è valido e non valido. Apache reindirizza solo gli accessi al file PHP, il file PHP si occupa del codice.
Ismael Miguel,

@ nyuszika7h Se passiamo a quel livello, non puoi nemmeno usare la console per eseguire il tuo codice PHP. Apache è l'antipasto. Il grilletto che spara il proiettile. L'esecuzione del file PHP dalla console renderebbe la console il trigger.
Ismael Miguel,

Stai facendo affidamento sul fatto che Apache sia già in esecuzione e non penso che funzionerà senza modificare la configurazione predefinita. Non mi importa di quello che dici, non c'è modo di vederlo valido. Ma dovresti chiedere a @Nit, poiché è la loro domanda.
nyuszika7h,

@ nyuszika7h Se non fosse valido, l'OP avrebbe già detto.
Ismael Miguel,

2

node.js con CoffeeScript (76)

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

Basta compilarlo in JavaScript, quindi è necessario eseguirlo npm install connect. Dopodiché inizia connode server.js


2

nginx - 35

events{}http{server{return 418;}}

Lancia quello in nginx.conf, avvia nginx.

Non sono sicuro se questo utilizza scappatoie standard "Utilizzo delle funzioni integrate per svolgere il lavoro" o "Interpretazione della sfida troppo alla lettera". Oops, sembra che a OP non piacerà questa risposta.


Funzionerebbe ancora se si lasciasse cadere ;?
Cirillo,

+ 4 / -4: ben fatto sulla controversia: D
cat

2

Perl, 78

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

corri come plackup whatever.pl.


Se vuoi un'applicazione di plack, allora sub{[418,[],[]]}dovrebbe essere sufficiente. (16 caratteri.)
Ricordo il

Certo che hai ragione! Non è che sto usando alcun framework, perché caricarlo? :)
hobbs

@tobyink sentiti libero di inviarlo come tuo :)
hobbs

2

Python 2.7 / Django, 94 byte

(aggiunto dalla django-admin.py startprojectpiastra di caldaia predefinita da ) In urls.py:

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

1

C # + OWIN 251 240

Speravo davvero che fosse più breve, ma i lunghi spazi dei nomi hanno rovinato quel piano. Richiede il Microsoft.Owin.SelfHostpacchetto disponibile su 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)

Devi correre npm install connectprima. Quindi inizia connode server.js


1

Vai, 162 byte

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

1

Fattore, 101 141 byte

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

Restituisci 418 a tutti coloro che si connettono.


1

Java 7, 208 byte

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();}}}

Questa domanda aveva bisogno di una risposta Java.

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

Dov'è il messaggio di stato?
Qwertiy,

@Qwertiy Penso che questa domanda richieda solo il codice di stato che interpreto come intero, quindi ne consegue che il messaggio di stato / motivo non è strettamente richiesto.
Colpisci il

Non me lo desidero, ma penso che dovrebbe essere con il testo di stato.
Qwertiy,

3
Ottieni già Java 8> _>
Pavel,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.