Python CherryPy Notları ----------------------- . Yüklenecek paketler python-cherrypy3 python-openssl (SSL desteği olacaksa) . SSL için anahtar ver sertifikasının oluşturulması. . Gizli anahtarın oluşturulması (parola girilecek) openssl genrsa -des3 -out cherrypy.key 1024 . Sertifika imza talebinin oluşturulması. openssl req -new -key cherrypy.key -out cherrypy.csr Country Name : TR State or Province Name : Türkiye Locality Name : İstanbul Organization Name : Firma Ltd. Organizational Unit Name: Yazılım Common Name : www.emrah.com Email Address : fakemail@www.emrah.com . Gizli anahtardan parolanın kaldırılması. Web sunucu her başladığında gizli anahtarın parolasını sormasını istemiyoruz. cp cherrypy.key cherrypy.key.org openssl rsa -in cherrypy.key.org -out cherrypy.key chmod 600 cherrypy.key* . Sertifikanın oluşturulması. openssl x509 -req -days 18250 -in cherrypy.csr -signkey cherrypy.key \ -out cherrypy.crt . SSL destekli basit bir CherryPy sunucu #!/usr/bin/python #-*- coding:utf-8 -*- import os import sys import time import signal import cherrypy from cherrypy.process.plugins import Daemonizer from cherrypy.process.plugins import PIDFile # Sunucunun dinleyecegi/cevap verecegi IP adresleri. Butun IP adresleri icin # erisebilir olacaksa '0.0.0.0' olacak. SERVER_LISTEN = '0.0.0.0' # Sunucunun dinleyecegi port. SERVER_PORT = 10443 # SSL icin sertifika dosyasi SSL_CERTIFICATE = "/home/emrah/keys/cherrypy.crt" # SSL icin anahtar dosyasi SSL_PRIVATE_KEY = "/home/emrah/keys/cherrypy.key" # Daemon mesajlarinda kullanilacak olan daemon adi. DAEMON_NAME = 'CherryServer' # Daemon'in Pid numarasini tutan dosya. PIDFILE = '/tmp/cherrypy_server.pid' # Web statik dosyalarin bulundugu klasor. WEB_STATIC = '/home/emrah/web/static' # Debug yapilacak mi? Test ortami icin 1, gercek calisma ortami icin 0. DEBUG = 1 # ----------------------------------------------------------------------------- # Default sayfayi olusturan bolum. def index(self, *args, **kwargs): try: # Host adini al. host = cherrypy.request.headers['host'].split(':')[0] # Formdan 'passwd' diye bir deger gelmisse al. passwd = None if 'passwd' in kwargs.keys() and len(kwargs['passwd']) != 0: passwd = kwargs['passwd'] result = 'index' except Exception, err: if DEBUG: raise else: print(str(err)) result = 'ERROR\n%s' % str(err) return result index.exposed = True # ----------------------------------------------------------------------------- # Temel sinif. Butun web sayfalari, bu temel sinifin methodlari olarak # tanimlanir. Ama kodun okunabilirligini korumak icin methodlar sinif # altinda tanimlanmadi. Run bolumunde metodlar, fonksiyonlara baglanarak # olusturuluyor. class Root(): exposed = True # ----------------------------------------------------------------------------- # Web sunucu hizzmetini veren asil bolum burasidir. Deamon'a start komutu # verildiginde program buradan calismaya baslar. Asil __main__ burasi... def run(): # Test ortaminda ciktilari konsola yonlendir. if DEBUG: out = '/dev/stdout' err = '/dev/stderr' # Gercek calisma ortami icin cikti olmayacak. else: out = '/dev/null' err = '/dev/null' # Web servislerini root nesnesinin methodlari olarak set et. root = Root root.index = index # Web servisini verecek olan sunucuyu baslat. # Sunucu HTTPS protokoluyle calisir. cherrypy.server.socket_host = SERVER_LISTEN cherrypy.server.socket_port = SERVER_PORT cherrypy.server.ssl_certificate = SSL_CERTIFICATE cherrypy.server.ssl_private_key = SSL_PRIVATE_KEY cherrypy.server.thread_pool = 100 cherrypy.server.socket_queue_size = 30 cherrypy.config.update({ 'tools.sessions.on': True, 'tools.sessions.timeout': 60, 'tools.sessions.storage_type': 'ram', 'tools.staticdir.on': True, 'tools.staticdir.dir': WEB_STATIC}) PIDFile(cherrypy.engine, PIDFILE).subscribe() Daemonizer(cherrypy.engine, stdout=out, stderr=err).subscribe() cherrypy.quickstart(root()) # ----------------------------------------------------------------------------- # Pid'i soyleyen bolum. Daemon baslatilirken ve durdurulurken Pid gerekiyor. def getpid(): # pidfile dosyasina kayitli bir pid var mi? try: pf = file(PIDFILE, 'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None return pid # ----------------------------------------------------------------------------- # Daemon'i baslatan bolum. def start(): # Daemon zaten calisiyor mu diye kontrol et. # Eger kayitli bir pid varsa calisiyordur. pid = getpid() if pid: sys.stderr.write("%s zaten calisiyor\n" % DAEMON_NAME) sys.exit(1) # Daemon calismaya baslasin run() # ----------------------------------------------------------------------------- # Daemon'i durduran bolum. def stop(): # Oncelikle calisan bir daemon var mi diye kontrol et. # Eger kayitli bir pid yoksa zaten calismiyor demektir. pid = getpid() if not pid: sys.stderr.write("%s zaten calismiyor\n" % DAEMON_NAME) sys.exit(1) # Daemon'i durdurma islemlerine basla. sys.stdout.write("%s durduruluyor\n" % DAEMON_NAME) # Daeman kill olana kadar belli araliklarla SIGTERM gonder. # Daemon kill olduktan sonraki kill denemesinde OSError olusacak. try: while True: os.kill(pid, signal.SIGTERM) time.sleep(1) except OSError, err: err = str(err) if err.find("No such process") > 0: if os.path.exists(PIDFILE): os.remove(PIDFILE) else: print(str(err)) sys.exit(1) # ----------------------------------------------------------------------------- # Daemoni yeniden baslatan bolum. def restart(): stop() start() # ----------------------------------------------------------------------------- # Program ana bolumu. Gelen parametreye gore daemoni baslatir veya durdurur. if __name__ == '__main__': if len(sys.argv) == 2: if 'start' == sys.argv[1]: start() elif 'stop' == sys.argv[1]: stop() elif 'restart' == sys.argv[1]: restart() else: print("Bilinmeyen komut") sys.exit(2) sys.exit(0) else: print("Kullanimi: %s start|stop|restart" % sys.argv[0]) sys.exit(2)