Сегодня я не в первый раз задался вопросами: какие языки программирования пригодны для веба? имеет ли смысл решать какую-то узкую задачу способом, который на первый взгляд для этого не подходит? Мне захотелось попрактиковаться, сделав что-нибудь обычное необычным способом.
Для чего?
Я задался целью написать вебприложение целиком на языке матлаба без использования каких либо обёрток. Зачем я стал это делать? Здесь есть несколько причин. Мне показалось это просто забавным. Помимо этого, я наблюдал как многие вебпрограммисты склоняются в своей работе к каким-то стереотипным решениям, что можно было бы назвать «PHP головного мозга». Это сказано ни в коем случае не в укор php-программистам, просто такое явление есть и я думаю, что моя заметка будет кому-то примером.
Как?
В качестве интерпретатора этого языка я выбрал GNU Octave по причине его бесплатности и лёгкодоступности на линуксе. В качестве вебсервера я выбрал nginx по той причине, что много работаю с ним и мне он просто очень удобен. Мне нужно было заставить работать скрипт на матлабе как CGI-приложение. В юниксах есть для этого простая возможность — вначале текстового файла можно указать путь и параметры интерпретатора и если у файла стоит аттрибут выполнимости, он может быть запущен и будет выполнен посредством этого интерпретатора. Сам по себе nginx не умеет выполнять простые CGI и примеры врапперов отсюда мне НЕ помогли. В другом источнике, не столь приближённом к создателям вебсервера, было предложено использовать для nginx fcgiwrapper, который даже входит в состав моего дистрибутива debian.
Что получилось?
Фрагмент итоговой конфигурации nginx:
location ~ .m$ { gzip off; #gzip makes scripts feel slower since they have to complete before getting gzipped fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_index index.m; fastcgi_param SCRIPT_FILENAME /var/www/m.leprodc$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; }
Код скрипта plot1.m:
#!/usr/bin/octave -q domain="m.leprodc.ru"; ARG=sscanf(getenv("QUERY_STRING"),"a=%g&b=%g&c=%g"); if (length(ARG)==3) a=ARG(1); b=ARG(2); c=ARG(3); handle=figure; X=-10:0.1:10; Y=a.*X.^2+b.*X+c; printf("Content-type: text/plainnn"); plot(X,Y); print(handle, sprintf('/tmp/plot-%s:%s.png',getenv("REMOTE_ADDR"),getenv("REMOTE_PORT")),'-dpng'); printf("Full image: http://%s/plot-%s:%s.pngnn",domain,getenv("REMOTE_ADDR"),getenv("REMOTE_PORT")); else printf("Location: http://%s/nn",domain); endif
Что получилось?
Например, вот: http://m.leprodc.ru/
Почитать:
Автор: YourChief