You are on page 1of 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 proces uruchomienie zewntrznego procesu / skryptu

Zewntrzny skrypt

In [1]: def run_python_script(URI): script = os.path.join(root_dir, URI) result = subprocess.check_output(["python", script]) return result

Jak przekaza informacj?

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]: import os print os.environ['VARIABLE'] pewna wartosc

In [3]: print os.environ.keys() ['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

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']

In [4]: os.environ['VARIABLE']='nowa wartosc' print os.environ['VARIABLE'] nowa wartosc

$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 Interface 1993 1997 (v. 1.0), 2004 (v. 1.1)

This memo provides information for the Internet community. It does not specify an Internet 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

Lighttpd ...

Serwer laboratoryjny
$ python -m CGIHTTPServer <port> Przykady OSError: [Errno 13] Permission denied

Uruchamianie CGI
Przewanie dedykowany katalog cgi-bin lub rozszerzenie .cgi Odpowiednie uprawnienia r.x dla katalogu ..x dla 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/<user>/www http://<host>/~<user> /home/<user>/www/<script>.cgi http://<host>/~<user>/<script>.cgi

Bdy
error.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

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 parsowanie dania ustawienie rodowiska uruchomienie skryptu CGI Skrypt

Serwer

Skrypt odczytanie zmiennych rodowiskowych zbudowanie nagwkw HTTP (w tym Content-Type i 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

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

WSGI
PEP 333 Web Server Gateway Interface Nowy standard (nie implementacja!) dla aplikacji webowych w pythonie Zbir interakcji Pena przenaszalno kodu

Stos
HTTP WSGI Aplikacja

Wymagania WSGI

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 environment i start_response jako 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

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 WSGI


def application(environ, start_response): status = "200 OK" body = "Hello World\n"

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 :<port> --plugin python --wsgi-file <script>.wsgi script.ini [uwsgi] plugin = python http-socket = :<port> wsgi-file = <script>.wsgi uwsgi --ini script.ini opcje

nginx + uWSGI
/tmp/<user>.wsgi.sock http://<host>/~<user>/wsgi

script.ini [uwsgi] plugin = python socket = /tmp/<user>.wsgi.sock wsgi-file = <script>.wsgi chmod-socket = 666 master = true daemonize = /tmp/<user>.wsgi.log pidfile = /tmp/<user>.wsgi.pid uwsgi --reload/--stop /tmp/<user>.wsgi.pid

WSGI middleware
Implementacja obu interfejsw (serwera i aplikacji) Dla aplikacji zachowuje si jak serwer Dla serwera zachowuje si jak aplikacja Wzorzec projektowy... ?

Prosta warstwa porednia WSGI

In [5]: class Upperware: def __init__(self, app): self.wrapped_app = app def __call__(self, environ, start_response): for data in self.wrapped_app(environ, start_response): yield data.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

Osobne procesy rodowisko wykonawcze ze zmiennymi z dania Standardowe wyjcie przesyane jako odpowied

You might also like