418: я чайник

68

Как мы все должны знать, есть HTTP-код состояния 418: я чайник .

Ваша миссия, если вы решите принять ее, - это использовать ваш creativitea и написать наименьший возможный сервер, который отвечает приведенным выше кодом состояния, на любой и любой HTTP-запрос, сделанный к нему.

Применяются стандартные лазейки , в том числе

Извлечение желаемого выхода из внешнего источника

Это включает в себя выполнение HTTP-запроса для извлечения страницы с вопросом и извлечения решения с этой страницы. Это было слегка забавно еще в 2011 году, но сейчас оно производное и неинтересное.

Это означает, что вы не можете просто перенаправить запрос на другой сервер, чтобы он возвратил ответ.


Устранение путаницы в функциональности сервера:
ваш сервер может делать все (или ничего), пока к нему не поступает HTTP-запрос, если он отвечает правильным ответом после выполнения HTTP-запроса.

гнида
источник
15
к каждому HTTP-запросу? Наверняка только для кофе: URI?
Дэйв
3
Можем ли мы предположить, что у нас уже есть привилегии root? (например, bind () с портом 80 в порядке)
Digital Trauma
2
@DigitalTrauma Да, вы можете принять расширенные привилегии для вашего сервера.
Нить
4
@ Knerd Я не склоняюсь ни к чему, вы не пишете программу, вы просто ее настраиваете.
Нить
2
О, мой бог. С появлением IOT у этого кода состояния может быть реальная причина существования!
Светящийся

Ответы:

39

GNU Awk: 69 символов

Сам сервер (бесконечно обслуживает один запрос за раз), библиотека не используется.

Отправьте 418 всем, кто подключается ( 82 69 символов):

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

Отправьте 418 всем, кто что-то отправляет ( 93 80 символов):

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

Отправьте 418 всем, кто отправляет действительный HTTP-запрос GET ( 122 109 символов):

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)}}
manatwork
источник
Но .. как подключить? ;)
Оптимизатор
5
Так же, как вы подключаетесь к любому веб-серверу. Браузер, netcat, telnet, wget, curl, другой GNU awkсценарий, ... Теоретически он прослушивает локального хоста: 80, но для того, что 1) нет веб - сервера, Skype или другой программы , следует использовать порт 80; 2) Вы должны быть суперпользователем, чтобы открыть порты ниже 1024. Поэтому для тестирования проще отредактировать номер порта в скрипте на что-то вроде 8080 ( s="/inet/tcp/8080/0/0"), а затем подключиться к нему. pastebin.com/zauP7LMA
manatwork
2
Понимаю. Здорово. Ауку нуб тут :)
Оптимизатор
1
Вы можете сохранить байт, используя меньший порт, например 8, который не назначен.
Ханнес Карппила
@ HannesKarppila, это правильно. Но, учитывая, что все другие решения, которые явно указывают порт (за исключением порта 8888 ответа на Haskell), используют порт 80, я лучше оставлю это для сравнения.
Манатворк
32

Баш (33)

nc -lp80 -q1<<<"HTTP/1.1 418
";$0
Мэринус
источник
3
Нужны ли две новые строки? Кажется, работает хорошо только с одним для меня. Также, по моим подсчетам, вышеприведенное составляет 34 байта - я предполагаю, что ваш редактор добавляет ненужный символ новой строки или \0в конец вашего файла - вы можете truncateэто сделать, и он все еще работает. s='echo HTTP/1.1 418|nc -lp80 -q1;$0' ; echo ${#s}дает 33 для меня
Цифровая травма
@DigitalTrauma: Вы правы - заключительный символ новой строки автоматически добавляется в строки здесь: Почему строка здесь bash добавляет завершающий символ новой строки? ------ Но я вижу две возможные проблемы: 1. Скрипт ожидает, что он хранится в одном из $PATHкаталогов или что он вызывается с путем (рекурсия по $0). ----- 2. HTTP требует, чтобы строки заканчивались \r\nне только \n. Здесь строка должна быть $"HTTP/1.1 418\r\n\r"(более читабельная форма). ------ И наконец: скрипт может быть короче: -q1параметр не обязателен.
Пабук
2
@DigitalTrauma, @pabouk: вывод должен заканчиваться двумя символами новой строки. Таким образом, одна из новых строк была ненужной (из-за строки здесь), но echoвариант не работает (по крайней мере, Firefox не распознает его как 418). Тем не менее, \rс не нужны. Спецификация говорит, что так и должно быть \r\n\r\n, но, по крайней мере, Firefox и Chrome примут \n\n, так что, похоже, в духе игры в гольф их не включать. -q1Параметр необходим в моей системе, потому что браузер не закроет соединение самого по себе. $0работает нормально, если скрипт сделан исполняемым и вызывается таким образом.
Маринус
@marinus Интересно - я проводил тестирование, и мне wgetкажется, что все в порядке с одной новой строкой
Digital Trauma
1
@pabouk - Интересный фрагмент здесь w3.org/Protocols/HTTP/OldServers.html : «Строки должны рассматриваться как прерванные переводом строки, а предыдущий символ возврата каретки игнорируется»
Digital Trauma
30

PHP - 85 байт

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

Сохраняется с окончаниями строк в стиле Windows (CR-LF), требуется php_socketsвключить.

Я фактически использовал это в качестве кода ошибки для Hard Code Golf: создайте вызов в чате , но никто не заметил.


Версия для браузера

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

Запустите сценарий в интерфейсе командной строки и укажите свой браузер на http://localhost.

Примо
источник
1
+1 для пользователя firendlyness / I'm a teapot:-)
Левит
20

Node.js (LiveScript)

http модуль - 66

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

Вдохновленный ответом Qwertiy .

net модуль - 76

require(\net)createServer (->it.write 'HTTP/1.1 418\r\n';it.end!) .listen 80
nyuszika7h
источник
2
Может ли человек, который проголосовал против, объяснить, почему?
nyuszika7h
20

Ruby + Rack, 19 байтов

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

Должен быть сохранен как config.ruи запущен с rackupкомандой.

Или, если вы предпочитаете "чистый" Ruby:

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

42 байта + -rrackфлаг = 48 байтов

августейший
источник
12

Общие команды Bash + BSD, 29

Займем немного назад от других ответов:

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

У меня работает с wget.

Первый ответ использовать nc, 38

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

Я предполагаю права суперпользователя - запустите следующее:

sudo bash ./418.sh
Цифровая травма
источник
3
@ ub3rst4r Правильно - именно поэтому я сказал «общие команды BSD», которые можно рассматривать как «библиотеку» с точки зрения сценариев оболочки. Из ОП: «Все библиотеки приветствуются»
Digital Trauma
2
Ответ должен заканчиваться новой строкой, см. W3.org/Protocols/HTTP/Response.html
Nit
2
@Nit - Да - bash "here strings" будет автоматически добавлен с новой строкой
Digital Trauma
1
Как насчетnc -l 80 <<<HTTP/1.1\ 418;$0
core1024
1
Извините за путаницу с двумя пробелами. Я не заметил, что вы не использовали -pпереключатель :) Я тестировал код с Firefox и без двух новых строк код состояния не распознается.
Пабук
9

Ruby (системная команда nc) - 35

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

DigitalTrauma должна получить признание за идею использования nc, однако Ruby может сделать бесконечный цикл с меньшим количеством символов, чем Bash :)

Рубин (TCPServer) - 75

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

Эта новая строка является преднамеренной - фактический символ новой строки на один символ короче, чем "\ n".

Рубин (WEBrick HTTPServer) - 87

require'webrick'
(s=WEBrick::HTTPServer.new).mount_proc(?/){|_,r|r.status=418}
s.start
Трей Томас
источник
Ответ должен заканчиваться новой строкой
Nit
1
@DigitalTrauma, я собирался использовать это, но потом понял, что обратную косую черту нужно экранировать другой обратной косой чертой, так что в любом случае это было бы то же количество символов :)
Трей Томас
@TreyThomas О, я понимаю, - так Руби нуждается в дополнительном уровне спасения здесь
Цифровая Травма
8

Node.js, 80

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

Ответ

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

0
Qwertiy
источник
2
Я нахожу просто удивительным, что узел поддерживает этот код ошибки изначально ^^
Левит
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
На основе hallvabo «s комментарий в Советы для игры в гольф в Python , from socket import*;s=socket(AF_INET,SOCK_STREAM)короче.
Манатворк
@manatwork Спасибо, есть более короткий путь к бесконечному циклу? Я не нашел ни одного в подсказках ...
Туомас Лаакконен,
3
while 1:s.accept()[0].sendall(bytes('HTTP/1.1 418\n','UTF8'))- если я что-то пропустил. (Между прочим, не стесняйтесь считать новые строки отдельными символами, поскольку язык позволяет им. Таким образом, вы ничего не теряете, разделяя команды вместо ;
новых
Вы можете отрезать 2 символа, предполагая, что порт 80 доступен, согласно комментарию владельца вопроса . Одна уродливая вещь, которая может нарушить переносимость, но может быть приемлемой здесь: использовать значения констант напрямую s=socket(2,1)(по крайней мере, это их значения в моем Linux).
Манатворк
В документации для listen()параметра «указано, что« максимальное значение зависит от системы (обычно 5) ». Таким образом, вместо 10, 9 более чем достаточно и 1 символ короче. И вместо bytes('HTTP/1.1 418\n','UTF8')буквального b'HTTP/1.1 418\n'вполне достаточно. Или, если вы делаете код Python 2, тогда bпрефикс байта больше не нужен. И короче send()тоже кажется достаточно.
manatwork
7

Haskell - 142 байта

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 байт

Редактировать - добавлен дополнительный перевод строки (всего 2 перехода) для соответствия.

socket -server {apply {{c - -} {puts $c "HTTP/1.1 418
";close $c}}} 80
vwait f
Цифровая травма
источник
Ответ должен заканчиваться новой строкой, см. W3.org/Protocols/HTTP/Response.html
Nit
3
@Nit - Да, команды Tcl автоматически добавят новую строку, если не указана опция -nonewline. tcl.tk/man/tcl/TclCmd/puts.htm
Цифровая травма
5

Юлия: 86 73 персонажа

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

")
close(c)
end
manatwork
источник
Я не думаю, что вам нужна настоящая часть "Я чайник" - достаточно кода ответа.
Дести
Да, я это заметил. Но так как это не сильно поможет счету Джулии, я сохранил его завершенным. Но, вероятно, было бы лучше удалить его, чтобы облегчить сравнение языков.
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()}
user2320464
источник
5

R, 80 символов

Никогда раньше не программировал сокеты с помощью R, но я попробую:

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

Здесь socketConnectionоткрывается сокет: первый аргумент должен быть хостом, по умолчанию localhostмы можем пропустить его здесь; второй аргумент - это порт, который не имеет значения по умолчанию, а затем аргумент, serverесли он указан, TRUEсоздает сокет, если FALSEон просто подключается к существующему. Tпо умолчанию равно TRUER.

Редактировать: как предложено в предлагаемом редакторе @AlexBrown, это можно сократить до 69 символов :

repeat cat("HTTP/1.1 418\n",file=s<-socketConnection(,80,T))+close(s)
plannapus
источник
4

Node.js koa , 61 байт

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

Отклик:

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

Требуется узел v0.11.12 +

Беги как:

node --harmony app.js
CPU1
источник
Что function*?
nyuszika7h
2
Это функция генератора , часть предложения ECMAScript 6, Harmony.
cPu1
4

Shell + socat, 60

socat tcp-l:80,fork exec:'printf HTTP/1.1\\ 418\\ T\r\n\r\n'
Vi.
источник
echo -e HTTP/1.1 418 T\r\n\rкороче
jimmy23013
Это \\ Tдаже не нужно.
nyuszika7h
3

MATLAB, 97 86 байт

Не очень серьезный претендент с точки зрения абсолютного количества байтов, но я хотел бы опубликовать его, потому что я не думал, что можно было бы написать полнофункциональный веб-сервер с использованием математического инструмента. Обратите внимание на использование сокращения свойства : 'Ne','s'внутренне расширяется до 'NetworkRole', 'server'.

t=tcpip('0.0.0.0','Ne','s');while 1
fopen(t)
fprintf(t,'HTTP/1.1 418\n')
fclose(t)
end
Sanchises
источник
3

Вы можете сделать это с минимальными усилиями, используя .htaccessфайл и PHP.

Все обращения к вашему серверу вернут статус 418.

Ниже приведен код:

.htaccess (28 байт)

RewriteRule .* index.php [L]

PHP ( 38 19 байт)

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

Спасибо @primo за то, что спасли мне кучу байтов!


Я проверил это и подтверждаю, что он возвращает желаемый результат!

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

Кстати, «Pedido» означает «Запрос», а «Resposta» означает «Ответ».

Исмаэль Мигель
источник
-1, это не полная программа. Он опирается на внешний веб-сервер.
nyuszika7h
@ nyuszika7h На самом деле, он опирается на Apache с PHP, установленным в качестве модуля. Ваш аргумент является действительным и недействительным. Apache только перенаправляет доступ к файлу PHP, файл PHP заботится о коде.
Исмаэль Мигель
@ nyuszika7h Если мы перейдем на этот уровень, вы даже не сможете использовать консоль для запуска своего PHP-кода. Апач это стартер. Триггер, который стреляет из пули. Запуск PHP-файла из консоли сделает консоль триггером.
Исмаэль Мигель
Вы полагаетесь на то, что Apache уже запущен, и я не думаю, что он будет работать без изменения конфигурации по умолчанию. Мне все равно, что вы говорите, я никак не могу понять, что это действительно. Но вы должны спросить @Nit, так как это их вопрос.
nyuszika7h
@ nyuszika7h Если бы он был недействительным, ОП уже сказал бы.
Исмаэль Мигель
2

node.js с CoffeeScript (76)

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

Просто скомпилируйте его в JavaScript, тогда вам нужно запустить npm install connect. После этого начните сnode server.js

Knerd
источник
2

nginx - 35

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

Добавьте это в nginx.conf, запустите nginx.

Не уверен, что при этом используются стандартные лазейки «Использование встроенных функций для выполнения работы» или «Слишком прямое толкование задачи». К сожалению, OP не понравится этот ответ.

zamnuts
источник
Будет ли это работать, если вы уронили ;?
Кирилл
+ 4 / -4: хорошо сделано в споре: D
кот
2

Perl, 78

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

беги как plackup whatever.pl.

Hobbs
источник
Если вы хотите приложение с бляшкой, то просто sub{[418,[],[]]}должно быть достаточно. (16 символов.)
tobyink
Конечно ты прав! Это не так, как я использую какие-либо рамки, зачем загружать его? :)
Хоббс
@tobyink, не стесняйтесь представить его как свой собственный :) :)
Хоббс
2

Python 2.7 / Django, 94 байта

(добавлено из стандартного шаблона из django-admin.py startproject) В urls.py:

import django.http.HttpResponse as r;urlpatterns=patterns(url(r'^*$',lambda q:r(status=418)))
TheInitializer
источник
1

C # + OWIN 251 240

Я действительно надеялся, что это будет короче, но длинные пространства имен разрушили этот план. Требуется Microsoft.Owin.SelfHostпакет, доступный на 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 с connect (78)

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

Вам нужно бежать npm install connectпервым. Тогда начни сnode server.js

Knerd
источник
1

Go, 162 байта

package main
import "net/http"
func main(){http.HandleFunc("/",func(w http.ResponseWriter,r *http.Request){w.WriteHeader(418)})
http.ListenAndServe(":80", nil)
}
ashooby
источник
1

Фактор 101 141 байт

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

Верните 418 каждому, кто подключается.

кошка
источник
1

Java 7, 208 байт

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

Этот вопрос нуждался в ответе Java.

poke@server ~
$ curl -i localhost:80
HTTP/1.0 418
совать
источник
Где находится статусное сообщение?
Qwertiy
@Qwertiy Я думаю, что этот вопрос требует только кода состояния, который я интерпретирую как целое число, поэтому из этого следует, что сообщение о состоянии / причина строго не требуются.
Ткните
Не я, чтобы решить, но я думаю, что это должно быть с текстом статуса.
Qwertiy
3
Получить Java 8 уже> _>
Павел
Вот она как лямбда на 148 байт
Бенджамин Уркхарт