418: Eu sou um bule de chá


68

Como todos sabemos, existe um código de status HTTP 418: sou um bule de chá .

Sua missão, se você optar por aceitá-la, é usar sua capacidade criativa e escrever o menor servidor possível que responda com o código de status acima a toda e qualquer solicitação HTTP feita a ele.

Aplicam-se brechas padrão , incluindo

Buscando a saída desejada de uma fonte externa

Isso inclui fazer uma solicitação HTTP para buscar a página com a pergunta e extrair uma solução dessa página. Isso foi levemente divertido em 2011, mas agora é derivado e desinteressante.

Significando que você não pode simplesmente redirecionar a solicitação para outro servidor para que ela retorne a resposta.


Resolvendo alguma confusão sobre a funcionalidade do servidor:
Seu servidor pode fazer qualquer coisa (ou nada) enquanto nenhuma solicitação HTTP for feita, desde que responda com a resposta correta assim que uma solicitação HTTP for feita.


15
para cada solicitação http? Certamente apenas alguns para um café: URI?
dave

3
Podemos assumir que já temos privilégios de root? (por exemplo, bind () na porta 80 está ok)
Digital Trauma

2
@DigitalTrauma Sim, você pode assumir privilégios escalados para o seu servidor.
Nit

4
@ Knerd Estou apoiado no lado não, você não está escrevendo um programa, está simplesmente configurando um.
Nit

2
AMD. Com a IOT chegando, esse código de status pode ter um motivo real para existir!
Luminous

Respostas:


39

GNU Awk: 69 caracteres

Um servidor em si (serve infinitamente uma solicitação por vez), nenhuma biblioteca usada.

Envie 418 para todos que se conectarem ( 82 69 caracteres):

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

Envie 418 para todos que enviarem algo ( 93 80 caracteres):

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

Envie 418 para todos que enviarem uma solicitação 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)}}

Mas .. como se conectar? ;)
Optimizer

5
Da mesma maneira que você se conecta a qualquer servidor web. Navegador, netcat, telnet, wget, curl, outro GNU awkroteiro, ... Teoricamente ele escuta em localhost: 80, mas para que 1) nenhum servidor web, Skype ou outro programa deve utilizar a porta 80; 2) você precisa ser superusuário para abrir portas abaixo de 1024. Portanto, para testar é mais fácil editar o número da porta no script para algo como 8080 ( s="/inet/tcp/8080/0/0") e conectar-se a isso. pastebin.com/zauP7LMA
manatwork

2
Eu vejo. Legal. Awk noob aqui :)
Otimizador

11
Você pode salvar um byte usando uma porta menor como 8, que não é atribuída.
Hannes Karppila 20/03

@HannesKarppila, está correto. Mas, como todas as outras soluções que especificam explicitamente uma porta (exceto a porta 8888 da resposta de Haskell) usam a porta 80, é melhor mantê-la assim para fins de comparabilidade.
manatwork 21/03/16

32

Bash (33)

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

3
As duas novas linhas são necessárias? Parece funcionar bem com apenas um para mim. Também pela minha contagem, os 34 bytes acima - acho que seu editor está adicionando uma nova linha desnecessária ou \0no final do seu arquivo - você pode fazer truncateisso e ainda funciona. s='echo HTTP/1.1 418|nc -lp80 -q1;$0' ; echo ${#s}dá 33 para mim
Digital Trauma

@DigitalTrauma: Você está certo - a nova linha final é adicionada automaticamente nas strings aqui: Por que uma string aqui do bash adiciona um caractere de nova linha à direita? ------ Mas vejo dois problemas possíveis: 1. O script espera que seja armazenado em um dos $PATHdiretórios ou seja chamado com um caminho (recursão por $0). ----- 2. O HTTP exige que as linhas sejam terminadas \r\nnão apenas \n. Aqui a string deve ser $"HTTP/1.1 418\r\n\r"(formato mais legível). ------ E finalmente: o script pode ser mais curto: o -q1parâmetro não é necessário.
Pabouk

2
@DigitalTrauma, @pabouk: a saída precisa terminar com duas novas linhas. Portanto, uma das novas linhas era desnecessária (por causa da string aqui), mas a echovariante não funciona (pelo menos o Firefox não a reconhecerá como 418). No entanto, os \rs não são necessários. As especificações dizem que \r\n\r\nsim, mas pelo menos o Firefox e o Chrome aceitarão \n\n, por isso parece estar no espírito do golfe não incluí-los. O -q1parâmetro foi necessário no meu sistema, porque o navegador não fechará a conexão sozinho. $0funciona bem se o script for tornado executável e chamado dessa maneira.
Marinus

@ marinus Interessante - Eu estava testando com o wgetque parece estar bem com apenas uma nova linha
Digital Trauma

11
@pabouk - Trecho interessante aqui w3.org/Protocols/HTTP/OldServers.html : "As linhas devem ser consideradas terminadas pelo Feed de linha e o caractere precedente de retorno de carro ignorado"
Digital Trauma

30

PHP - 85 bytes

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

Salvo com terminações de linha no estilo Windows (CR-LF), é necessário php_socketsativar.

Na verdade, eu usei isso como meu código de erro para o Hard Code Golf: Criar um desafio no Chatroom , mas ninguém percebeu.


Versão amigável ao 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 o script na CLI e aponte seu navegador para http://localhost.


11
+1 para firendlyness do usuário / I'm a teapot:-)
Levit 25/02

20

Node.js (LiveScript)

http módulo - 66

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

Inspirado pela resposta de Qwertiy .

net módulo - 76

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

2
A pessoa que recusou o voto pode explicar o porquê?
nyuszika7h

20

Ruby + Rack, 19 bytes

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

Deve ser salvo como config.rue executado com o rackupcomando

Ou se você preferir Ruby "puro":

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

42 bytes + -rracksinalizador = 48 bytes


12

Comandos gerais do Bash + BSD, 29

Tomando emprestado um pouco de outras respostas:

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

Trabalha para mim com wget.

Primeira resposta a ser usada nc, 38

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

Estou assumindo privilégios de root - execute da seguinte maneira:

sudo bash ./418.sh

3
@ ub3rst4r Correto - É por isso que afirmei "comandos gerais do BSD", que podem ser considerados uma "biblioteca" do ponto de vista do script de shell. Do OP: "Todas as bibliotecas são bem-vindas"
Digital Trauma

2
Uma resposta deve terminar com uma nova linha, consulte w3.org/Protocols/HTTP/Response.html
Nit

2
@Nit - Sim - o bash "here strings" será automaticamente anexado a uma nova linha
Digital Trauma

11
Que talnc -l 80 <<<HTTP/1.1\ 418;$0
core1024

11
Desculpe a confusão com os dois espaços. Não notei que você não usou a -popção :) Testei o código com o Firefox e, sem duas novas linhas, o código de status não é reconhecido.
pabouk

9

Ruby (comando do sistema nc) - 35

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

O DigitalTrauma deve receber o crédito pela ideia de usar nc, no entanto, Ruby pode fazer um loop infinito com menos caracteres que o Bash :)

Ruby (TCPServer) - 75

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

Essa nova linha é intencional - o caractere da nova linha real é um caractere menor que "\ n".

Ruby (WEBrick HTTPServer) - 87

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

Uma resposta deve terminar com uma nova linha, consulte w3.org/Protocols/HTTP/Response.html
Nit

11
@DigitalTrauma, eu ia usar isso, mas então percebeu que a barra invertida deve ser escapada com outra barra invertida, por isso teria sido o mesmo número de caracteres de qualquer maneira :)
Trey Thomas

@TreyThomas Oh eu vejo - assim Rubi precisa de um nível extra de escapar aqui
Trauma Digital

8

Node.js, 80

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

A resposta é

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
Acho que é simplesmente fantástico esse nó suporta esse código de erro nativamente ^^
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')

11
Baseado em hallvabo 's comentário no Dicas para jogar golfe em Python , from socket import*;s=socket(AF_INET,SOCK_STREAM)é mais curto.
manatwork

@manatwork Obrigado, existe uma maneira mais curta de loop infinito? Eu não encontrar um nas pontas ...
Tuomas Laakkonen

3
while 1:s.accept()[0].sendall(bytes('HTTP/1.1 418\n','UTF8'))- a menos que eu tenha perdido alguma coisa. (By the way, fique à vontade para contar novas linhas de uma única personagens, como a língua permite-lhes Dessa forma, você nada solto, separando os comandos por novas linhas em vez de. ;.)
manatwork

Você pode cortar 2 caracteres assumindo que a porta 80 esteja acessível, de acordo com o comentário do proprietário da pergunta . Uma coisa feia que pode quebrar a portabilidade, mas pode ser aceitável aqui: use os valores das constantes diretamente s=socket(2,1)(pelo menos esses são os valores no meu Linux).
manatwork

A documentação diz para listen()o parâmetro de que "o valor máximo depende do sistema (geralmente 5)". Então, em vez de 10, 9 é mais do que suficiente e 1 caractere mais curto. E em vez de bytes('HTTP/1.1 418\n','UTF8')um literal b'HTTP/1.1 418\n'é suficiente. Ou se você criar o código Python 2, o bprefixo de bytes não será mais necessário. E o mais curto send()também 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 - adicionada em uma nova linha extra (total de 2 novas linhas) por motivos de conformidade.

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

Uma resposta deve terminar com uma nova linha, consulte w3.org/Protocols/HTTP/Response.html
Nit

3
@Nit - Sim, o Tcl puts acrescentará automaticamente uma nova linha, a menos que a opção -nonewline seja fornecida. tcl.tk/man/tcl/TclCmd/puts.htm
Trauma digital

5

Julia: 86 73 caracteres

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

")
close(c)
end

Eu não acho que você precise da parte real "Eu sou um bule de chá" - o código de resposta deve ser suficiente.
Desty

Sim, eu notei isso. Mas como isso não ajudará muito na pontuação de Julia, eu a mantive completa. Mas provavelmente seria melhor removê-lo para facilitar a comparação 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 fiz soquete de programação com R antes, mas vou tentar:

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

Aqui socketConnectionabre um soquete: o primeiro argumento deve ser o host, o padrão é localhostque podemos ignorá-lo aqui; o segundo argumento é a porta que não possui padrão; o argumento, serverquando especificado, TRUEcria o soquete, se FALSEele se conectar apenas a um existente. Té, por padrão, igual a TRUE, em R.

Editar: conforme sugerido em uma edição sugerida por @AlexBrown, isso pode ser reduzido para 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)

Resposta:

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

Requer nó v0.11.12 +

Correr como:

node --harmony app.js

O que é function*?
nyuszika7h

2
Essa é uma função geradora , parte da proposta Harmony do ECMAScript 6.
CPU1

4

Shell + sociedade, 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é mais curto.
jimmy23013

A \\ Tnão é sequer necessário.
nyuszika7h

3

MATLAB, 97 86 bytes

Não é realmente um candidato sério em termos de contagem absoluta de bytes, mas gostaria de publicá-lo porque não achei que seria possível escrever um servidor da Web totalmente funcional usando uma ferramenta matemática. Observe o uso de encurtamento de propriedade : 'Ne','s'expande internamente para '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

Você pode fazer isso com o mínimo de esforço usando um .htaccessarquivo e php.

Todos os acessos ao seu servidor retornarão o status 418.

Abaixo está o código:

.htaccess (28 bytes)

RewriteRule .* index.php [L]

PHP ( 38 19 bytes)

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

Agradeço ao @primo por me salvar um monte de bytes!


Eu testei isso e confirmo que ele retorna o resultado desejado!

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

A propósito, "Pedido" significa "Solicitação" e "Resposta" significa "Resposta".


-1, este não é um programa completo. Ele se baseia em um servidor web externo.
nyuszika7h

@ nyuszika7h Na verdade, ele depende do Apache com o PHP instalado como um módulo. Seu argumento é válido e inválido. O Apache redireciona apenas os acessos ao arquivo PHP, o arquivo PHP cuida do código.
Ismael Miguel

@ nyuszika7h Se descermos nessa camada, você não pode nem usar o console para executar seu código PHP. Apache é o iniciante. O gatilho que dispara a bala. A execução do arquivo PHP no console tornaria o console o gatilho.
Ismael Miguel

Você está contando com o Apache já em execução, e não acho que funcione sem alterar a configuração padrão. Não me importo com o que você diz, não há como ver isso como válido. Mas você deve perguntar ao @Nit, pois é a pergunta deles.
nyuszika7h

@ nyuszika7h Se fosse inválido, o OP já teria dito.
Ismael Miguel

2

node.js com CoffeeScript (76)

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

Basta compilá-lo em JavaScript, para executar npm install connect. Depois disso, inicie-o comnode server.js


2

nginx - 35

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

Jogue isso no nginx.conf, inicie o nginx.

Não tenho certeza se isso usa brechas padrão "Usando funções internas para fazer o trabalho" ou "Interpretando o desafio muito literalmente". Ops, parece que o OP não vai gostar desta resposta.


Ainda funcionaria se você deixasse cair o ;?
Cyril

+ 4 / -4: bem feito sobre controvérsia: D
cat

2

Perl, 78

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

correr como plackup whatever.pl.


Se você deseja um aplicativo plack, basta sub{[418,[],[]]}ser suficiente. (16 caracteres.)
tobyink

Claro que você está certo! Não é como se eu estivesse usando alguma estrutura, por que carregá-la? :)
hobbs

@tobyink vontade submeter-lo como seu próprio embora :)
hobbs

2

Python 2.7 / Django, 94 bytes

(adicionado a partir do padrão do site django-admin.py startproject) Em urls.py:

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

1

C # + OWIN 251 240

Eu realmente esperava que fosse mais curto, mas os longos espaços para nome arruinaram esse plano. Requer o Microsoft.Owin.SelfHostpacote disponível no 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 com o connect (78)

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

Você precisa correr npm install connectprimeiro. Então comece comnode 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

Fator, 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 ]

Retorne 418 a todos que se conectarem.


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 pergunta precisava de uma resposta java.

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

Onde está a mensagem de status?
Qwertiy

@ Qwertiy Acho que esta pergunta apenas solicita o código de status que interpreto como o número inteiro, de modo que a mensagem / razão do status não é estritamente necessária.
pique

Não sou eu quem quisesse, mas acho que deveria ser com texto de status.
28417 Qwertiy

3
Obtenha o Java 8 já> _>
Pavel

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.