Hlavní navigace

Knihovna M2Crypto (3)

Jakub Matys

V dnešním dílu budeme "budovat" HTTPS server, využijeme k tomu modulu SSLServer. A abychom si ověřili funkčnost našeho serveru, napíšeme si také prográmek, který se k němu připojí. Ten bude využívat zase modulu httpslib.

SSLServer

#!/usr/bin/env python
'''HTTPS Echo Server'''
from M2Crypto.SSL import SSLServer
from M2Crypto.SSL import Context
from M2Crypto.SSL import timeout
import SocketServer
import string

class EchoHandler(SocketServer.BaseRequestHandler):
        def handle(self):
                f = self.request.makefile()
                self.request.send("HTTP/1.0 200 OK\r\n")
                self.request.send("Content-type: text/plain\r\n\r\n" )
                self.request.send("Received connection from %s\r\n\r\n" %
                                (self.client_address,))
                while 1:
                        line = f.readline()
                        self.request.send(line)
                        if not string.strip(line):
                                break
                f.close()


SSL_context = Context()
SSL_context.load_cert('cert.pem', 'key.pem')
timeout(120,0)
serv = SSLServer(("", 443), EchoHandler, SSL_context)
while 1:
        serv.handle_request() 

Ukázkový program představuje jednoduchý SSL server, který při HTTP dotazu odešle tento dotaz zpátky.

Handler obhospodařující příchozí požadavky musí dědit třídu SocketServer.Ba­seRequestHandler, která obsahuje potřebné metody. Třída handleru se může jmenovat libovolně, její metody však musí, co se týče názvů, dodržovat určité konvence. Metoda setup slouží k provedení inicializačních kroků, většinou však tato metoda nic neprovádí. finish se volá pro vyčištění po metodě handle, pokud ji nenadefinujete, nic se nestane, prostě se neprovede. Jestliže skončí setup nebo handle s výjimkou, nebude tato metoda zavolána.

V těle metody handle vidíme, že obsahuje nějaký objekt nazvaný request. Jedná se o soket, který je spojen s klientem, můžeme tedy používat všechny jeho metody.

Na prvním řádku otevřeme soket jako soubor a přiřadíme jeho objekt jménu. Několik dalších řádků poslouží k odeslání HTTP hlavičky klientu. V „nekonečné” smyčce čteme ze souboru soketu řádek po řádku a ta samá data zase odesíláme zpět. Pokud vstup neobsahuje žádné znaky, ukončí program smyčku a uzavře soubor soketu. Samotný soket se však tímto neuzavře, bude uzavřen implicitně po ukončení funkce handleru.

Před voláním konstruktoru třídy serveru musíme vytvořit objekt kontextu, který server vyžaduje. Musíme také do kontextu uložit potřebné certifikáty a klíče.

K nastavení odezvy slouží třída timeout, které se předává doba prodlevy v sekundách a mikrosekundách.

Objekt serveru získáme voláním třídy M2Crypto.SSL.SSLSer­ver s parametry obsahujícími lokální adresu('' můžeme použít pro jakoukoliv ze síťových karet resp. adres počítače) a port, třídu handleru a objekt kontextu. Ve smyčce poté spustíme metodu pro obsluhu požadavků.

Kromě SSLServeru můžeme také použít ForkingSSLServer a ThreadingSSLServer. První přiřadí každému novému spojení nový proces, druhý zase vlákno. Rozhraní třídy je však pořád stejné.

httpslib

#!/usr/bin/env python
'''httpslib'''
from M2Crypto.httpslib import HTTPSConnection

h = HTTPSConnection('localhost', 443)
h.putrequest('GET', '/index.html')
h.putheader('Accept', 'text/html')
h.putheader('Accept', 'text/plain')
h.endheaders()
response = h.getresponse()
print response.read()
response.close()
h.close() 

Tímto prográmkem můžeme ověřit funkčnost SSL serveru, připojí se na port 443 a odešle HTTP požadavek. Vrácená data vytiskne na standardní výstup. Pokud výstup programu obsahuje řetězce předávané funkcím putrequest a putheader, pracuje SSL server správně. Jednotlivé příkazy jsou, podle mě, dostatečně srozumitelné a nepotřebují další vysvětlení. Jelikož třída odvozuje metody od HTTPConnection (modul httplib), naleznete další informace k metodám v dokumentaci standardní knihovny jazyka. Modul obsahuje i druhou třídu nazvanou HTTPS, která je odvozena z třídy httplib.HTTP, jež implementuje HTTP/1.0. HTTPCon­nection implementuje novější HTTP/1.1.

Našli jste v článku chybu?