Комментарии 46
Ждем вебсервер на bash'е
А это идея, bash вроде умеет работать с сокетами :)
while :;do nc -p8080 -vnlc'r=read;e=«echo -e»;$r a b c;while [ -n "`$e $a|tr -d "\r\n"`" ];do $r a;done;f=`$e $b|sed s/.//`;h=«HTTP/1.0»;z=«404 Not Found\n»;[ -z $f ]&&(ls|while $r n;do [ -f $n ]&&$e "$n";done)||([ -f $f ]&&($e "$h 200 OK\r\nContent-Type: `file -ib $f`\n";cat $f)||$e "$h $z\n$z")';done
Источник, если хабрапарсер закушает кавычки: alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/
Источник, если хабрапарсер закушает кавычки: alexey.sveshnikov.ru/blog/2007/08/30/bash-httpd-2/
на JS
я не понял, а почему код не картинкой? если программа на перл, то или фигурка сисястой девушки, или пивные бутылки, или еще что-нибудь, у кого на что фантазии хватит. думал в перле такая индентация…
:)
В текущем виде проще объяснить что к чему и проще понять что да как ;)
> думал в перле такая индентация…
Кроме отступов для «картинки» нужны и символы подходящие
В текущем виде проще объяснить что к чему и проще понять что да как ;)
> думал в перле такая индентация…
Кроме отступов для «картинки» нужны и символы подходящие
pastebin.com/m79a90bbf
программа из топика)
программа из топика)
НЛО прилетело и опубликовало эту надпись здесь
Вместо
use LWP::Socket;
use FCGI::ProcManager
лучше использовать Net::Server
use LWP::Socket;
use FCGI::ProcManager
лучше использовать Net::Server
хех…
Аккуратно, не проверяется запрашиваемое имя файла… дырищааа, запроси /etc/passwd и получишь :)
P.S. но вообще то уже давно есть (gentoo dev-perl/HTTP-Server-Simple под лицензией Artistic GPL-2)
Аккуратно, не проверяется запрашиваемое имя файла… дырищааа, запроси /etc/passwd и получишь :)
P.S. но вообще то уже давно есть (gentoo dev-perl/HTTP-Server-Simple под лицензией Artistic GPL-2)
НЛО прилетело и опубликовало эту надпись здесь
А это и не web-сервер, а просто пример скрипта ;) Он не предназначен для использования на продакшен-серверах. Это скорее серверная часть, которая по запросу может делать что ей скажут, в данном случае отдавать любой запрошенный файл. Я сперва сделал, чтобы файл брался только из папки со скриптом, но решил не удлинять код и оставил то, что сейчас в посте :)
У вас HTTP протокол нарушается.
Я бы кстати не стал использовать вот такое «на коленке», когда есть полнеценный и навороченный Perlbal. Это не считая фреймворков для написания своих серверов (HTTP::Daemon, HTTP::Server, AnyEvent::HTTPD, ...).
Ну и к тому же здесь уже была серия статей «пишем fcgi приложение».
Я бы кстати не стал использовать вот такое «на коленке», когда есть полнеценный и навороченный Perlbal. Это не считая фреймворков для написания своих серверов (HTTP::Daemon, HTTP::Server, AnyEvent::HTTPD, ...).
Ну и к тому же здесь уже была серия статей «пишем fcgi приложение».
А такой вопрос. Мне нужно чтоб по любому запросу отсылался файл нулевого содержания.
Правильно ли я сделал, т.е. вместо этой части
Использую эту?
Правильно ли я сделал, т.е. вместо этой части
if ( $file_name ) { if ( -f $file_name and open FILE, '<', $file_name ) { # Read from file $content = join "", <FILE>; close FILE; } else { $content = "File not found"; $stat = 404; }
Использую эту?
if ( open FILE, '<', "/tmp/null" ) { $content = join "", <FILE>; close FILE;
> $content = join "",;
не оптимально, лутше файл читать по частям и писать сразу, а не копить в переменной.
не оптимально, лутше файл читать по частям и писать сразу, а не копить в переменной.
#!/usr/bin/perl use strict; use warnings; $|++; use IO::Socket::INET; use EV; my $sock = IO::Socket::INET->new(Listen => 10000, LocalPort => 8882, Blocking => 0, Proto => 'tcp') or die "Can't bind : $@\n"; my @evs; push(@evs,EV::io $sock,EV::READ,\&accept); sub accept { my $newsock = $sock->accept; $newsock->blocking(0); push(@evs,EV::io $newsock,EV::READ,\&request); $evs[-1]->data(scalar(@evs)-1); }; sub request { my $data; $_[0]->fh->sysread($data,128); my $content = "HTTP/1.1 200 OK\r\n" . "Server: EV/2009-09-12\r\n" . "Content-Type: text/html\r\n" . "Connection: close\r\n\r\n" . "<html><body><h1>Hello from Habr</h1></body></html>"; $_[0]->fh->syswrite($content); $_[0]->fh->close; undef $evs[$_[0]->data()]; undef $_[0]; }; EV::loop();
1 поток:
#ab -n 10000 -c 30 http://localhost:8882/
Requests per second: 7099.00 [#/sec] (mean)
пример очень упрощен, отсутсвуют какие либо проверки, но скорость говорит за себя
если ещё добавить prefork…
Не там скорость меряете ;)
Уберите из «поста» чтение из сокета и обращение к диску, подозреваю, что скорость заметно увеличится…
> пример очень упрощен
от того и скорость :)
Уберите из «поста» чтение из сокета и обращение к диску, подозреваю, что скорость заметно увеличится…
> пример очень упрощен
от того и скорость :)
Не понимаю чего Вы хотите этим сказать, но Вы продолжаете не там мерять скорость… У Вашего скрипта немного другой функционал, да и про «железо» Вы забыли, вряд ли оно у нас савпадает.
Код из поста, но 10 child'ов
$ siege -c 30 -b -f _urls
$ siege -c 30 -b -i -f _urls
$ ab2 -n 10000 -c 30 httр://127.0.0.1:8080/
Перебираемые урлы — «главная страница», несуществующая страница, существующая страница
Как видите, скорость не сильно различается.
«Облегчённый сервер»
(просто выдача «приветствия»)
$ siege -c 30 -b 127.0.0.1:8080
$ ab2 -n 10000 -c 30 httр://127.0.0.1:8080/
Ваш код
(копипаст и изменение порта)
$ siege -c 30 -b 127.0.0.1:8080
$ ab2 -n 10000 -c 30 httр://127.0.0.1:8080/
Код из поста, но 10 child'ов
$ siege -c 30 -b -f _urls
Transaction rate: 3847.76 trans/sec
Successful transactions: 25193
Failed transactions: 0
$ siege -c 30 -b -i -f _urls
Transaction rate: 3783.66 trans/sec
Successful transactions: 119578
Failed transactions: 0
$ ab2 -n 10000 -c 30 httр://127.0.0.1:8080/
Requests per second: 3900.84 [#/sec] (mean)
Перебираемые урлы — «главная страница», несуществующая страница, существующая страница
Как видите, скорость не сильно различается.
«Облегчённый сервер»
(просто выдача «приветствия»)
$ siege -c 30 -b 127.0.0.1:8080
Transaction rate: 4867.47 trans/sec
Successful transactions: 36506
Failed transactions: 0
$ ab2 -n 10000 -c 30 httр://127.0.0.1:8080/
Requests per second: 5647.83 [#/sec] (mean)
Ваш код
(копипаст и изменение порта)
$ siege -c 30 -b 127.0.0.1:8080
Transaction rate: 3111.36 trans/sec
Successful transactions: 15059
Failed transactions: 0
$ ab2 -n 10000 -c 30 httр://127.0.0.1:8080/
Requests per second: 3201.50 [#/sec] (mean)
А если в вашем коде исправить:
EV: error in callback (ignoring): Modification of a read-only value attempted at tmp.pl line 51.
т.е. убрать строку
undef $_[0];
то результат увеличится примерно на тысячу ;)
Попробуйте на своём компьютере, результаты должны быть ещё выше.
EV: error in callback (ignoring): Modification of a read-only value attempted at tmp.pl line 51.
т.е. убрать строку
undef $_[0];
то результат увеличится примерно на тысячу ;)
Попробуйте на своём компьютере, результаты должны быть ещё выше.
* «облегчённый сервер» работает в один поток, забыл это сразу указать
Код из топика не претендует на идеальный, самый быстрый и самый правильный. Я старался продемонстрировать простоту и лаконичность perl'а. И если уж сокращать функционал и код, то на мой взгляд приведённый ниже код будет более предпочтителен для новичка.
P.S. Я не имею ничего против Вашего кода, не поймите меня неправильно, я просто поясняю идею поста. Если Вы с таким написанием несложного кода несогласны, напишите пост на эту тему, с удовольствием почитаю (думаю, что не только я один).
- #!/usr/bin/perl
- use strict;
- use warnings;
- use LWP::Socket;
- my $sock = new LWP::Socket();
- die "Can't bind a socket" unless $sock->bind('127.0.0.1', '8080');
- $sock->listen(10);
- while ( my $socket = $sock->accept(3) ) {
- $socket->write( "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"
- . "<html><body><h1>Hello from Habr</h1></body></html>" );
- $socket->shutdown();
- }
- $sock->shutdown();
P.S. Я не имею ничего против Вашего кода, не поймите меня неправильно, я просто поясняю идею поста. Если Вы с таким написанием несложного кода несогласны, напишите пост на эту тему, с удовольствием почитаю (думаю, что не только я один).
как это можно понять?
Хорошую скорость при очень малых ресурсах, можно получить используя неблокирующие сокеты.
На счёт чтения файла по кускам; к этому следует также запрещать буферизацию вывода.
На счёт чтения файла по кускам; к этому следует также запрещать буферизацию вывода.
Ну к коду всё-таки надо относиться не как к образцовому написанию сетевого приложения :) Здесь я пытался показать, что не такой уж и страшный perl, его не надо бояться, написать код на перле можно различными способами, в том числе и так, чтобы всё нормально читалось… А "$|++;" пришлось бы поподробнее описывать и чтобы всё было совсем хорошо не помешало описать и прочие предопределённый переменные, типа $/, $_, $!, $', а это уже в этой статье будет лишним.
пардон за оффтопик, но моя душа радуется: торнадо, торнадо…
www.tornadoweb.org/
www.tornadoweb.org/
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Почти-web-сервер своими руками