Bonjour,
J'essaie de définir un travailleur personnalisé pour récupérer les informations de certificat client à partir du serveur, puis de les importer dans mon application Flask comme suit :
gunicorn_options.py :
import multiprocessing
import os
from mypackage.client_auth_worker import CustomSyncWorker
def config_dir():
return os.path.dirname(os.path.realpath(__file__))
bind = "0.0.0.0:8000"
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = CustomSyncWorker
timeout = 30
ca_certs = os.path.join(config_dir(), 'ca.cert.pem')
certfile = os.path.join(config_dir(), 'server.cert.pem')
keyfile = os.path.join(config_dir(), 'server.key.pem')
cert_reqs = 2
do_handshake_on_connect = True
custom_auth_worker.py :
from gunicorn.workers.sync import SyncWorker
class CustomSyncWorker(SyncWorker):
def handle_request(self, listener, req, client, addr):
subject = dict(client.getpeercert().get('subject')[0])
headers = dict(req.headers)
headers['X-USER'] = subject.get('commonName')
print(headers)
req.headers = list(headers.items())
super(CustomSyncWorker, self).handle_request(listener, req, client, addr)
Je reçois toujours l'exception suivante :
File "/Users/me/.virtualenvs/mypackage/lib/python3.5/site-packages/gunicorn/arbiter.py", line 162, in start
self.log.info("Using worker: %s", self.cfg.worker_class_str)
File "/Users/me/.virtualenvs/mypackage/lib/python3.5/site-packages/gunicorn/config.py", line 68, in __getattr__
raise AttributeError("No configuration setting for: %s" % name)
AttributeError: No configuration setting for: worker_class_str
J'ai essayé plusieurs choses pour résoudre ce problème, par exemple, j'ai essayé de définir un worker_class_str
dans le fichier gunicorn_options.py
, cela n'a pas résolu le problème. J'ai ensuite commencé à creuser dans le code du package réel et j'ai découvert que lorsque j'ai modifié le fichier gunicorn/arbiter.py
pour commenter la ligne : self.log.info("Using worker: %s", self.cfg.worker_class_str)
tout fonctionne parfaitement bien, le CustomSyncWorker est bien chargé et fait son travail car il est censé définir l'en-tête X-USER et tout.
Est-ce un bug ? Ou est-ce que je fais juste quelque chose de gravement mal ? Je pense que je ne devrais pas prendre sur moi de modifier le code localement juste pour forcer les choses à fonctionner...
Je pense que vous devez passer une chaîne à worker_class
. Donc changeant
worker_class = CustomSyncWorker
à
worker_class = 'mypackage.client_auth_worker.CustomSyncWorker'
résoudrait votre problème.
Et notez que cela est déjà documenté sur http://docs.gunicorn.org/en/stable/settings.html#worker -class
En option, vous pouvez fournir votre propre worker en donnant à Gunicorn un chemin Python vers une sous-classe de gunicorn.workers.base.Worker. Cette syntaxe alternative chargera la classe gevent : gunicorn.workers.ggevent.GeventWorker.
Bien sûr, nous pourrions toujours améliorer la documentation si vous avez une meilleure suggestion.
Merci pour le rapport!
Je pense avoir essayé cela et cela n'a pas fonctionné, cependant, je n'en suis pas certain et j'ai peut-être écrit la chaîne différemment (comme dans un format "mypackage.client_auth_worker:CustomSyncWorker"
). Je devrai vérifier quand je rentrerai à la maison plus tard dans la journée.
En dehors de cela, je recommanderais de mettre un exemple direct dans la documentation ou au moins ailleurs (là où vous pensez que c'est approprié) simplement parce que j'avais vu cette documentation et qu'il n'était pas clair que c'est ce que j'aurais dû faire dans le cas de un fichier de configuration python. J'ai fini par faire un tas d'essais et d'erreurs qui m'ont permis d'obtenir une version de travail que j'ai publiée après avoir commenté l'impression.
Merci d'être revenu vers moi si rapidement !
OK, confirmé, cela a fonctionné. Merci pour l'aide!
Commentaire le plus utile
Je pense que vous devez passer une chaîne à
worker_class
. Donc changeantà
résoudrait votre problème.