418: je suis une théière


68

Comme nous devrions tous le savoir, il existe un code de statut HTTP 418: je suis une théière .

Votre mission, si vous l'acceptez, consiste à utiliser votre création et à écrire le plus petit serveur possible qui répond avec le code d'état ci-dessus à toute requête HTTP qui lui est adressée.

Des failles standard s'appliquent, notamment

Récupérer la sortie désirée d'une source externe

Cela inclut une requête HTTP pour extraire la page avec la question et extraire une solution de cette page. C'était assez amusant en 2011, mais maintenant c'est dérivé et sans intérêt.

Cela signifie que vous ne pouvez pas simplement rediriger la demande vers un autre serveur pour qu'il renvoie la réponse.


Remédier à une certaine confusion au sujet des fonctionnalités du serveur:
votre serveur peut faire n'importe quoi (ou rien) sans qu'aucune requête HTTP ne lui soit adressée tant qu'il répond avec la réponse correcte une fois qu'une requête HTTP est effectuée.


15
à chaque demande http? Sûrement juste pour un café: URI?
dave

3
Pouvons-nous supposer que nous avons déjà des privilèges root? (par exemple, bind () sur le port 80 est ok)
Digital Trauma,

2
@ DigitalTrauma Oui, vous pouvez assumer des privilèges plus élevés pour votre serveur.
Nit

4
@Knerd Je m'appuie sur le non, vous n'écrivez pas un programme, vous ne faites que le configurer.
Nit

2
OMG. Avec l'IOT, ce code de statut peut avoir une raison réelle d'exister!
Lumineux

Réponses:


39

GNU Awk: 69 caractères

Un serveur lui-même (sert indéfiniment une requête à la fois), aucune bibliothèque utilisée.

Envoyez 418 à toutes les personnes qui se connectent ( 82 69 caractères):

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

Envoyez 418 à tous ceux qui envoient quelque chose ( 93 80 caractères):

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

Envoyez 418 à tous ceux qui envoient une requête HTTP GET valide ( 122 109 caractères):

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

Mais .. comment se connecter? ;)
Optimiseur

5
De la même manière, vous vous connectez à n’importe quel serveur Web. Navigateur, netcat, telnet, wget, curl, un autre GNU awkscript ... En théorie , il écoute sur localhost: 80, mais pour que 1) aucun serveur web, Skype ou tout autre programme devrait utiliser le port 80; 2) vous devez être super utilisateur pour ouvrir les ports inférieurs à 1024. Ainsi, pour les tests, il est plus facile de modifier le numéro de port dans le script à quelque chose comme 8080 ( s="/inet/tcp/8080/0/0"), puis de vous y connecter. pastebin.com/zauP7LMA
manatwork

2
Je vois. Cool. Awk noob here :)
Optimiseur,

1
Vous pouvez éventuellement enregistrer un octet en utilisant un port plus petit, tel que 8, non attribué.
Hannes Karppila

@HannesKarppila, c'est bien ça. Mais étant donné que toutes les autres solutions spécifiant explicitement un port (à l'exception du port 8888 de la réponse Haskell) utilisent le port 80, il vaut mieux le conserver comme ceci pour des raisons de comparabilité.
Manatwork

32

Bash (33)

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

3
Les deux nouvelles lignes sont-elles nécessaires? Semble fonctionner correctement avec un seul pour moi. En outre, 34 octets sont mentionnés ci-dessus - je suppose que votre éditeur ajoute un saut de ligne inutile ou \0à la fin de votre fichier - vous pouvez le faire truncateet cela fonctionne toujours. s='echo HTTP/1.1 418|nc -lp80 -q1;$0' ; echo ${#s}donne 33 pour moi
Digital Trauma

@DigitalTrauma: Vous avez raison - la nouvelle ligne finale est ajoutée automatiquement dans ces chaînes: pourquoi une chaîne bash ajoute-t-elle un caractère de fin de ligne? ------ Mais je vois deux problèmes possibles: 1. Le script s'attend à ce qu'il soit stocké dans l'un des $PATHrépertoires ou appelé avec un chemin (récursion par $0). ----- 2. HTTP exige que les lignes soient terminées par \r\nnon seulement \n. Ici, la chaîne devrait être $"HTTP/1.1 418\r\n\r"(forme plus lisible). ------ Et enfin: le script pourrait être plus court: le -q1paramètre n'est pas nécessaire.
Pabouk

2
@ DigitalTrauma, @pabouk: La sortie doit se terminer par deux nouvelles lignes. Une des nouvelles lignes était donc inutile (à cause de la chaîne here), mais la echovariante ne fonctionne pas (au moins, Firefox ne le reconnaîtra pas comme un 418). Cependant, les \rs ne sont pas nécessaires. La spécification dit que cela devrait être le cas \r\n\r\n, mais au moins Firefox et Chrome l'accepteront \n\n. Il semble donc que le golfeur n'a pas à les inclure. Le -q1paramètre était nécessaire sur mon système, car le navigateur ne fermera pas la connexion par lui-même. $0fonctionne bien si le script est rendu exécutable et appelé de cette manière.
marinus

@marinus Intéressant - J'essayais avec wgetce qui semble aller avec juste une nouvelle ligne
Digital Trauma

1
@pabouk - Extrait intéressant ici w3.org/Protocols/HTTP/OldServers.html : "Les lignes doivent être considérées comme terminées par un saut de ligne et le caractère précédent de Carriage Return est ignoré"
Digital Trauma,

30

PHP - 85 octets

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

Enregistré avec des fins de ligne de style Windows (CR-LF), requiert php_socketsactivé.

En fait, je l'ai utilisé comme code d'erreur pour Hard Code Golf: créer un défi Chatroom , mais personne ne s'en est aperçu.


Version conviviale pour le navigateur

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

Lancez le script dans la CLI et pointez votre navigateur sur http://localhost.


1
+1 pour l'utilisateur firendlyness / I'm a teapot:-)
Levit

20

Node.js (LiveScript)

http module - 66

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

Inspiré par la réponse de Qwertiy .

net module - 76

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

2
La personne qui a voté vers le bas pourrait-elle expliquer pourquoi?
Nyuszika7h

20

Ruby + Rack, 19 octets

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

Doit être enregistré en tant que config.ruet exécuté avec la rackupcommande.

Ou si vous préférez "pur" Ruby:

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

42 octets + -rrackdrapeau = 48 octets


12

Commandes générales Bash + BSD, 29

Revenons un peu aux autres réponses:

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

Travaille pour moi avec wget.

Première réponse à utiliser nc, 38

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

J'assume les privilèges root - fonctionne comme suit:

sudo bash ./418.sh

3
@ ub3rst4r Correct - C’est la raison pour laquelle j’ai déclaré "commandes générales BSD", ce qui peut être considéré comme une "bibliothèque" du point de vue des scripts shell. De l'OP: "Toutes les bibliothèques sont les bienvenues"
Digital Trauma

2
Une réponse doit se terminer par un saut à la ligne, voir w3.org/Protocols/HTTP/Response.html
Nit

2
@Nit - Yes - bash "here strings" sera automatiquement ajouté à la nouvelle ligne
Digital Trauma

1
Que diriez-vousnc -l 80 <<<HTTP/1.1\ 418;$0
core1024

1
Désolé pour la confusion avec les deux espaces. Je n'ai pas remarqué que vous n'utilisiez pas le -pcommutateur :) J'ai testé le code avec Firefox et sans deux nouvelles lignes, le code d'état n'est pas reconnu.
Pabouk

9

Ruby (commande système nc) - 35

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

DigitalTrauma devrait avoir le mérite d'utiliser l'idée nc, mais Ruby peut créer une boucle infinie avec moins de caractères que Bash :)

Ruby (Serveur TCPS) - 75

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

Cette nouvelle ligne est intentionnelle - le caractère de nouvelle ligne actuel est inférieur à "\ n" d'un caractère.

Ruby (WEBrick HTTPServer) - 87

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

Une réponse doit se terminer par un saut à la
Nit

1
@ DigitalTrauma, j'allais l'utiliser, mais je me suis rendu compte que la barre oblique inverse devait être évitée avec une autre barre oblique inversée. Le nombre de caractères aurait donc été identique :)
Trey Thomas

@TreyThomas Oh, je vois. Ruby a donc besoin d'un peu plus d'échappatoire ici
Digital Trauma

8

Node.js, 80

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

La réponse est

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
Je trouve ça génial que ce noeud supporte ce code d'erreur de manière native ^^
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
Basé sur le commentaire de hallvabo dans Tips for golfing in Python , il est plus court. from socket import*;s=socket(AF_INET,SOCK_STREAM)
manatwork

@manatwork Merci, existe-t-il un moyen plus court de boucle infinie? Je n'en ai trouvé aucun dans les conseils ...
Tuomas Laakkonen

3
while 1:s.accept()[0].sendall(bytes('HTTP/1.1 418\n','UTF8'))- sauf si j'ai raté quelque chose. (Au fait, sentez-vous libre de compter les sauts de ligne d'un seul caractère, comme le permet la langue. Ainsi, vous ne perdez rien en séparant les commandes par des sauts de ligne au lieu de ;.)
manatwork

Vous pouvez supprimer 2 caractères en supposant que le port 80 est accessible, en fonction du commentaire du propriétaire de la question . Une chose laide qui peut casser la portabilité, mais peut être acceptable ici: utilisez directement les valeurs des constantes s=socket(2,1)(au moins, ce sont leurs valeurs sur mon Linux).
Manatwork

La documentation indique pour listen()le paramètre de s que «la valeur maximale dépend du système (généralement 5)». Donc au lieu de 10, 9 est plus que suffisant et 1 caractère plus court. Et au lieu d' bytes('HTTP/1.1 418\n','UTF8')un littéral b'HTTP/1.1 418\n'suffit. Ou si vous créez le code Python 2, le bpréfixe d'octet n'est plus nécessaire. Et le plus court send()semble aussi suffire.
manatwork

7

Haskell - 142 octets

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 octets

Edit - ajouté dans une nouvelle ligne (total de 2 nouvelles lignes) pour des raisons de conformité.

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

Une réponse doit se terminer par une nouvelle ligne, voir w3.org/Protocols/HTTP/Response.html
Nit

3
@Nit - Oui, les options Tcl ajoutent automatiquement une nouvelle ligne, sauf si l'option -nonewline est donnée. tcl.tk/man/tcl/TclCmd/puts.htm
Digital Trauma

5

Julia: 86 73 caractères

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

")
close(c)
end

Je ne pense pas que vous ayez besoin de la partie "Je suis une théière" - le code de réponse devrait suffire.
Desty

Oui je l'ai remarqué. Mais comme cela n'aidera pas beaucoup Julia, je l'ai gardé complet. Mais il serait probablement préférable de le supprimer pour faciliter la comparaison des langues.
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 caractères

Jamais la programmation de socket avec R n'avait été faite auparavant, mais je vais essayer:

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

Ici socketConnections'ouvre un socket: le premier argument devrait être l'hôte, le défaut étant de le localhostsauter ici; le deuxième argument est le port qui n'a pas de valeur par défaut, puis l'argument, serverlorsqu'il est spécifié, TRUEcrée le socket, s'il FALSEne se connecte qu'à un existant. Test, par défaut, égal à TRUE, dans R.

Édition: comme suggéré dans une modification suggérée par @AlexBrown, cela pourrait être raccourci en 69 caractères :

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

4

Node.js koa , 61 octets

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

Réponse:

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

Requiert le noeud v0.11.12 +

Courir comme:

node --harmony app.js

C'est quoi function*?
Nyuszika7h

2
Il s’agit d’une fonction de générateur, intégrée à la proposition Harmony dans ECMAScript 6.
cPu1

4

Shell + socat, 60 ans

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\rest plus courte.
Jimmy23013

Le \\ Tn'est même pas nécessaire.
nyuszika7h

3

MATLAB, 97 86 octets

Pas vraiment sérieux en termes de nombre absolu d'octets, mais j'aimerais le poster car je ne pensais pas qu'il serait possible d'écrire un serveur Web entièrement fonctionnel à l'aide d'un outil mathématique. Notez l'utilisation de raccourcissement de propriété : 'Ne','s'étend en interne à '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

Vous pouvez le faire avec un effort minimal en utilisant un .htaccessfichier et php.

Tous les accès à votre serveur renverront le statut 418.

Ci-dessous le code:

.htaccess (28 bytes)

RewriteRule .* index.php [L]

PHP ( 38 19 octets)

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

Merci à @primo de m'avoir économisé de nombreux octets!


J'ai testé cela et confirme qu'il renvoie le résultat souhaité!

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

À propos, "Pedido" signifie "Demande" et "Resposta" signifie "Réponse".


-1, ce n'est pas un programme complet. Il s'appuie sur un serveur Web externe.
Nyuszika7h

@ nyuszika7h En fait, il repose sur Apache avec PHP installé en tant que module. Votre argument est à la fois valide et invalide. Apache ne redirige que les accès au fichier PHP, le fichier PHP s'occupe du code.
Ismael Miguel

@ nyuszika7h Si nous descendons sur cette couche, vous ne pouvez même pas utiliser la console pour exécuter votre code PHP. Apache est le démarreur. La gâchette qui tire la balle. L'exécution du fichier PHP à partir de la console ferait de la console le déclencheur.
Ismael Miguel

Vous comptez déjà utiliser Apache, et je ne pense pas que cela fonctionnera sans changer la configuration par défaut. Je me fiche de ce que vous dites, je ne peux absolument pas voir cela comme valable. Mais vous devriez demander @Nit, car c'est leur question.
nyuszika7h

@ nyuszika7h S'il était invalide, le PO l'aurait déjà dit.
Ismael Miguel

2

node.js avec CoffeeScript (76)

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

Il suffit de le compiler en JavaScript, vous devez alors exécuter npm install connect. Après cela, commencez avecnode server.js


2

nginx - 35

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

Jetez cela dans nginx.conf, lancez nginx.

Vous ne savez pas si cela utilise les échappatoires standard «Utilisation de fonctions intégrées pour effectuer le travail» ou «Interprétation trop littérale du défi». Oups, on dirait que OP ne va pas aimer cette réponse.


Cela fonctionnerait-il encore si vous laissiez tomber le ;?
Cyril

+ 4 / -4: bravo pour la controverse: D
cat

2

Perl, 78

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

courir comme plackup whatever.pl.


Si vous voulez une application plack, alors cela sub{[418,[],[]]}devrait suffire. (16 caractères.)
tobyink

Bien sûr que tu as raison! Il est pas comme je suis en utilisant tout le cadre, pourquoi le charger? :)
Hobbs

@tobyink n'hésitez pas à le soumettre comme étant le vôtre :)
hobbs

2

Python 2.7 / Django, 94 octets

(ajouté à partir de boilerplate par défaut de django-admin.py startproject) Dans urls.py:

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

1

C # + OWIN 251 240

J'espérais vraiment qu'il serait plus court, mais les longs espaces de noms ont ruiné ce plan. Requiert le Microsoft.Owin.SelfHostpaquet disponible sur 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 avec connect (78)

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

Vous devez courir en npm install connectpremier. Puis commencez avecnode server.js


1

Go, 162 octets

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

1

Facteur, 101 141 octets

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

Retournez 418 à tous ceux qui se connectent.


1

Java 7, 208 octets

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

Cette question avait besoin d'une réponse java.

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

Où est le message d'état?
Qwertiy

@Qwertiy Je pense que cette question ne demande que le code de statut que j'interprète comme un entier. Il s'ensuit que le message de statut / raison n'est pas strictement requis.
Poke

Ce n'est pas moi qui le souhaite, mais je pense que cela devrait être avec un texte d'état.
Qwertiy

3
Obtenez déjà Java 8> _>
Pavel

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.