Programowanie w Internecie: #5 Niskopoziomowy web
-
Upload
mikolaj-olszewski -
Category
Documents
-
view
90 -
download
0
description
Transcript of Programowanie w Internecie: #5 Niskopoziomowy web
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
1/11
#5: Niskopoziomowy web
Mikoaj Olszewski
Jakie pytania po lekturze?
Wicej ycia
Serwer HTTP tworzony na zajciach
Serwowanie statycznej treci (zawarto pliku lub katalogu)
Jak serwowa tre dynamiczn?
podmiana statycznej treci przez zewntrzny procesuruchomienie zewntrznego procesu / skryptu
Zewntrzny skrypt
In [1]: defrun_python_script(URI):
script =os.path.join(root_dir, URI)
result =subprocess.check_output(["python", script])
returnresult
Jak przekaza informacj?
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
2/11
Przekazwyanie informacji w konsoli
$ export VARIABLE="pewna wartosc"
$echo "wartosc zmiennej to:$VARIABLE"
wartosc zmiennej to: pewna wartosc
rodowisko
$ printenv
VARIABLE=pewna wartosc
LC_PAPER=pl_PL.UTF-8
LC_ADDRESS=pl_PL.UTF-8
SSH_AGENT_PID=3224
LC_MONETARY=pl_PL.UTF-8
GPG_AGENT_INFO=/run/user/mikus/keyring-sBl4bi/gpg:0:1
TERM=xterm
SHELL=/bin/bash
...
rodowisko w pythonie
In [2]: importos
printos.environ['VARIABLE']
In [3]: printos.environ.keys()
pewna wartosc
['UPSTART_EVENTS', 'GVM_PLATFORM', 'SHELL', 'XDG_DATA_DIRS', 'MANDATORY_PAT
H', 'COMPIZ_CONFIG_PROFILE', 'UPSTART_INSTANCE', 'JOB', 'TEXTDOMAIN', 'LAZY
BONES_HOME', 'DESKTOP_AUTOSTART_ID', 'XMODIFIERS', 'JAVA_HOME', 'MFLAGS', '
WORKON_HOME', 'XDG_RUNTIME_DIR', 'XDG_SESSION_ID', 'DBUS_SESSION_BUS_ADDRES
S', 'VIRTUALENVWRAPPER_HOOK_DIR', 'DESKTOP_SESSION', 'GTK_MODULES', 'INSTAN
CE', 'XDG_MENU_PREFIX', 'LS_COLORS', 'GAIDEN_HOME', 'GNOME_DESKTOP_SESSION_
ID', 'XDG_CURRENT_DESKTOP', 'GRIFFON_HOME', 'USER', 'XDG_VTNR', 'XAUTHORITY
', 'LANGUAGE', 'SESSION_MANAGER', 'SHLVL', 'CLUTTER_IM_MODULE', 'GPG_AGENT_
INFO', 'GVM_VERSION', 'GDMSESSION', 'UPSTART_JOB', 'XDG_SEAT_PATH', 'SPRING
BOOT_HOME', '_', 'GTK_IM_MODULE', 'GRAILS_HOME', 'XDG_CONFIG_DIRS', 'UBUNTU_MENUPROXY', 'PAGER', 'QT4_IM_MODULE', 'HOME', 'DISPLAY', 'LANG', 'SESSION'
, 'COMP_WORDBREAKS', 'GROOVY_HOME', 'GVM_SERVICE', 'GIT_PAGER', 'GNOME_KEYR
ING_PID', 'LESSOPEN', 'LESSCLOSE', 'GVM_INIT', 'VERTX_HOME', 'GVM_DIR', 'MA
KELEVEL', 'VIRTUALENVWRAPPER_LOG_DIR', 'GROOVYSERV_HOME', 'LOGNAME', 'XDG_S
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
3/11
In [4]: os.environ['VARIABLE']='nowa wartosc'
printos.environ['VARIABLE']
$echo "wartosc zmiennej to:$VARIABLE"
wartosc zmiennej to: pewna wartosc
Wnioski
Proces potomny dziedziczy rodowisko po rodzicu
Rodzice nie widz zmian w rodowiskach procesw potomnych
rodowisko mona ustawia explicite
CGI rodowisko webowe
RFC 3875 Common Gateway Interface19931997 (v. 1.0), 2004 (v. 1.1)
This memo provides information for the Internet community. It does not specify anInternet standard of any kind. Distribution of this memo is unlimited.
Zmienne
AUTH_TYPE, GATEWAY_INTERFACE,
CONTENT_LENGTH, CONTENT_TYPE,
PATH_INFO, PATH_TRANSLATED, QUERY_STRING, SCRIPT_NAME,
REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD,
SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL, SERVER_SOFTWARE
Serwer z CGI
Modu standardowej biblioteki Pythona: CGIHTTPServer
Serwery HTTP
Apache
IIS
EAT', 'GNOME_KEYRING_CONTROL', 'PATH', 'MAKEFLAGS', 'SSH_AGENT_PID', 'TERM'
, 'XDG_SESSION_PATH', 'DEFAULTS_PATH', 'SESSIONTYPE', 'IM_CONFIG_PHASE', 'G
IO_LAUNCHED_DESKTOP_FILE_PID', 'GIO_LAUNCHED_DESKTOP_FILE', 'SSH_AUTH_SOCK'
, 'TEXTDOMAINDIR', 'VARIABLE', 'VIRTUALENVWRAPPER_PROJECT_FILENAME', 'GRADL
E_HOME', 'UPSTART_SESSION', 'OLDPWD', 'GDM_LANG', 'CLICOLOR', 'PWD']
nowa wartosc
http://docs.python.org/2/library/cgihttpserver.htmlhttp://www.ietf.org/rfc/rfc3875 -
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
4/11
Lighttpd
...
Serwer laboratoryjny
$ python -m CGIHTTPServer
Przykady
OSError: [Errno 13] Permission denied
Uruchamianie CGI
Przewanie dedykowany katalog cgi-binlub rozszerzenie .cgi
Odpowiednie uprawnienia
r.xdla katalogu..xdla skryptu / programu
#!/usr/bin/env python system musi wiedzie jak uruchomi proces
Uruchomienie tak samo jak przez uytkownika: $ cgi-bin/test.py
Proces uruchamiany przez uytkownika nobody
kwestia bezpieczestwa (eby nie nada za duych uprawnie)
Program wykonawczy musi by uruchamialny przez kogokolwiek
CGI na serwerze laboratoryjnym
Nginx
/home//www
http:///~
/home//www/.cgi
http:///~/.cgi
Bdyerror.py
Informacja w konsoli, ukryta przed uytkownikiem
dostp do procesu przez Internet (rwnie dla wszystkich szumowin)
informacje o bdach mog by powan luk bezpieczestwa
error_debug.py
https://bitbucket.org/pwi/przyklady-cgi/src/main/cgi-bin/error.pyhttps://bitbucket.org/pwi/przyklady-cgi/src/main/cgi-bin/error.pyhttps://bitbucket.org/pwi/przyklady-cgi/src -
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
5/11
Ustawianie rodowiska
CGIHTTPServer.run_cgi
...
env = copy.deepcopy(os.environ)
env['SERVER_SOFTWARE'] = self.version_string()
env['SERVER_NAME'] = self.server.server_name
env['GATEWAY_INTERFACE'] = 'CGI/1.1'
env['SERVER_PROTOCOL'] = self.protocol_version
env['SERVER_PORT'] = str(self.server.server_port)
env['REQUEST_METHOD'] = self.command
uqrest = urllib.unquote(rest)
env['PATH_INFO'] = uqrest
env['PATH_TRANSLATED'] = self.translate_path(uqrest)
env['SCRIPT_NAME'] = scriptname
if query:
env['QUERY_STRING'] = query
...
ua = self.headers.getheader('user-agent')
if ua:
env['HTTP_USER_AGENT'] = ua
...
ycie CGI
Serwer Skrypt
parsowanie dania
ustawienie rodowiska
uruchomienie skryptu CGI
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
6/11
odczytanie zmiennych rodowiskowych
zbudowanie nagwkw HTTP (w tym
Content-Typei Content-Length)
wypisanie nagwkw, pustej linii i ciaa na
standardowe wyjcie
zbudowanie pierwszej linii odpowiedzi:
HTTP/1.1 200 OK
odesanie wszystkich danych ze skryptu
Serwer Skrypt
Problemy CGI
Kod jest wykonywany w osobnym procesie
Kade wywoanie skryptu startuje nowy proces
Starowanie nowych procesw jest kosztowne i zuywa zasoby serwera
szczeglnie w przypadku jzykw interpretowanych (np. Python)
Alternatywy dla CGI
Zazwyczaj jeden (lub kilka) dugoyjcy proces obsugujcy skrypty CGI
Przykady: FastCGI, SCGI, mod_python
Problemy
specyficzne API
brak kompatybilnoci
brak przenonoci kodu
trudno wspdzieli zasoby
WSGIPEP 333 Web Server Gateway Interface
Nowy standard (nie implementacja!) dla aplikacji webowych w pythonie
Zbir interakcji
Pena przenaszalno kodu
Stos
HTTPWSGIAplikacja
Wymagania WSGI
http://www.python.org/dev/peps/pep-0333 -
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
7/11
Serwer
Ustawia rodowiska (podobnie jak przy CGI)
Dostarcza metod
start_response(status, headers, exc_info=None)
Buduje odpowied przez wywoanie
application(environment, start_response)
Zwraca odpowied ze statusem, nagwkami i ciaem
Aplikacja
Musi by wywoywalna
Pobiera environmenti start_responsejako parametry wywoania
Zwraca obiekt iterowalny lub obiekty typu string (0 lub wicej) stanowice ciao odpowiedzi
Implementacje WSGI
Biblioteka standardowa Pythona
Apache + mod_wsgi
Apache (proxy) + serwer WSGI
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
8/11
Zarys serwera WSGI
from some_application import simple_app
def build_env(request):
# zbudowanie rodowiska, pobranie informacji z dania
return env
def handle_request(request, app):
environ = build_env(request)
iterable = app(environ, start_response)
for data in iterable:
# wysanie danych do klienta
def start_response(status, headers):
# rozpoczcie odpowiedzi HTTP, wysanie statusu i nagwkw
# nasuchiwanie da HTTP i przekazywanie do handle_request()
serve(simple_app)
rodowisko WSGI
REQUEST_METHOD,
SCRIPT_NAME, PATH_INFO, QUERY_STRING
CONTENT_TYPE, CONTENT_LENGTH
SERVER_NAME, SERVER_PORT
SERVER_PROTOCOL
HTTP_* (zmienne odpowiadajce nagwkom)
Wyglda znajomo?
Prosta aplikacja WSGIdef application(environ, start_response):
status = "200 OK"
body = "Hello World\n"
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
9/11
response_headers = [('Content-type', 'text/plain',
'Content-length', len(body))]
start_response(status, response_headers)
return [body]
WSGI na serwerze laboratoryjnym
uWSGI
uwsgi --http-socket : --plugin python --wsgi-file .wsgi
script.ini
[uwsgi]
plugin = python
http-socket = :
wsgi-file = .wsgi
uwsgi --ini script.ini
opcje
nginx + uWSGI
/tmp/.wsgi.sock
http:///~/wsgi
script.ini
[uwsgi]
plugin = python
socket = /tmp/.wsgi.sock
wsgi-file = .wsgi
chmod-socket = 666
master = true
daemonize = /tmp/.wsgi.log
pidfile = /tmp/.wsgi.pid
uwsgi --reload/--stop /tmp/.wsgi.pid
WSGI middleware
Implementacja obu interfejsw (serwera i aplikacji)
Dla aplikacji zachowuje si jak serwer
Dla serwera zachowuje si jak aplikacja
Wzorzec projektowy... ?
http://uwsgi-docs.readthedocs.org/en/latest/Options.html -
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
10/11
Prosta warstwa porednia WSGI
In [5]: classUpperware:def__init__(self, app):
self.wrapped_app =app
def__call__(self, environ, start_response):
fordata inself.wrapped_app(environ, start_response):
yielddata.upper()
Waciwoci warstwy poredniej WSGI
Przezroczysto, lune powizania
Moliwo dowolnego dokadania, usuwania i przekadania
Aplikacja nie powinna przesta dziaa po usuniciu warstwy poredniej (jednej z)
Esencja kodu powinna znajdowa si w aplikacji a nie w warstwach porednich
Uycie
Routing
Autentykacja
Kontrola cache'a
Debugowanie i introspekcja
Motywy tematyczne
Podsumowanie
Dynamiczne waciwoci WWW za pomoc osobnych programw
Standardy
CGI, FastCGI, SCGI, ...
WSGI
-
5/28/2018 Programowanie w Internecie: #5 Niskopoziomowy web
11/11
Osobne procesy
rodowisko wykonawcze ze zmiennymi z dania
Standardowe wyjcie przesyane jako odpowied