Programowanie w Internecie: #5 Niskopoziomowy web

download Programowanie w Internecie: #5 Niskopoziomowy web

of 11

description

Niskopoziomwe zapewnienie dynamiczności treści w aplikacjach webowych

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