Archive de l'auteur

Le problème de publier des images intéressantes, c’est que vous risquez d’avoir d’autres personnes qui les affichent sur leur site, mais en laissant l’image sur votre serveur.

Le problème est qu’ayant l’image hébergée sur votre machine, c’est votre débit qui sera utilisé. Si l’autre site possède un important trafic, il peux tuer votre disponibilité ou en tout cas la ralentir.

Afin d’éviter que les images ne soient affichées depuis un autre site, voici un petit bout de code à mettre dans un fichier .htacess :

RewriteEngine On
#Replace ?yoursite.com/ with your blog url
RewriteCond %{HTTP_REFERER} !^http://(.+.)?yoursite.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Replace /images/stealing-is-bad.jpg with your "don't hotlink" image url
RewriteRule .*.(jpe?g|gif|bmp|png)$ /images/stealing-is-bad.jpg [L]

Remplacez bien les valeurs indiquées par celle correspondant à votre configuration, et vous serez tranquilles :)

Source: http://www.pcland.info/archives/156/more-htaccess-tricks-for-you-wordpress-blog.html

Comments 4 commentaires »

Voici quelques commandes bash qui permettre de trouver une chaine contenue dans les fichiers d’un répertoire (utile par exemple pour trouver quels fichiers ont été infectés par le virus Gumblar :D )

La solution la plus simple est rgrep, mais qui n’est pas installé par défaut.

rgrep 'chaine' /arborescence

Sinon, vous avez la solution avec grep.
Cette méthode n’affiche que le fichier concerné

grep -lir "chaine" /arborescence

Cette méthode affiche le fichier concerné, la ligne ou la chaine à été trouvée, et la chaine trouvée :

grep -oHnr "chaine" /arborescence

Ou la solution avec find :

find /arborescence -name "*extension_du_fichier" -exec grep -l "chaine" {} \;

Enfin, limiter la recherche à certaines extensions :

for i in `find /arborescence -type d`; do grep "chaine" $i/*.{txt,log}; done 2>/dev/null

Parfois très utile ! :)

Comments Pas de commentaire »

Voici le sommaire de ma série “faire mumuse avec python sur son serveur” :

Hope this helps :)

Comments Pas de commentaire »

(Voici la suite de ma petite série “faire mumuse avec python sur son serveur”.)

Nous avons vu précédemment comment configurer notre projet Django pour qu’il fonctionne sur un serveur Apache, en utilisant soit mod_python, soit mod_wsgi. Comme j’ai réalisé ce projet pour un client, je lui ai pris avec un forfait Start1G chez OVH.

Ce serait bête de ne pas l’utiliser ! :)

J’ai donc fait quelques recherches sur le web sur comment faire fonctionner un projet python sur un hébergeur qui, à la base, n’accepte que du Php. Heureusement pour moi, j’ai trouvé deux articles complémentaires qui m’ont permis de faire fonctionner mon site :

Le premier article est très complet et c’est parce que j’ai eu quelques difficultés à y arriver que je poste ma solution, sinon j’aurais juste mis le liens vers ce site. Le second peux donner quelques idées pour résoudre vos soucis, mais les liens vers les documents (.htaccess, django.cgi) retournent des erreurs 404.

Alors voilà, comme toujours, il faut respecter une certaine arborescence, qui dépends de vos goûts je doit dire.

Pour ma part, voici l’arborescence finale :

  • cgi-bin/ : dossier par défaut fournis par OVH, non modifié
  • projet/
    • [project_name]/ : le nom du projet, contient le code python, dont le settings.py
    • static/ : les fichiers statiques (css, js, images, etc)
    • templates/ : les templates nécessaires à l’affichage du site.
  • python-local/ : contient tout ce qui est nécessaire au fonctionnement du site, dans mon cas, juste Django
    • django/ : le framework Django
  • requetes/ : dossier par défaut fournis par OVH, non modifié
  • www/
    • media/ : copie du repertoire django/django/contrib/admin/media/ (medias utilisés par l’admin)
    • .htaccess
    • django.cgi

Voici le contenu des fichiers .htaccess et django.cgi

.htaccess : très simple, mais efficace ;)

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ django.cgi/$1 [L]<strong>
</strong>

django.cgi. Vous pourrez trouver une version originale de ce fichier ici.

#!/usr/bin/env python
# encoding: utf-8
"""
django.cgi
 
A simple cgi script which uses the django WSGI to serve requests.
 
Code copy/pasted from PEP-0333 and then tweaked to serve django.
http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
 
This script assumes django is on your sys.path, and that your site code is at
/home/mycode/mysite. Copy this script into your cgi-bin directory (or do
whatever you need to to make a cgi script executable on your system), and then
update the paths at the bottom of this file to suit your site.
 
This is probably the slowest way to serve django pages, as the python
interpreter, the django code-base and your site code has to be loaded every
time a request is served. FCGI and mod_python solve this problem, use them if
you can.
 
In order to speed things up it may be worth experimenting with running
uncompressed zips on the sys.path for django and the site code, as this can be
(theorectically) faster. See PEP-0273 (specifically Benchmarks).
http://www.python.org/dev/peps/pep-0273/
 
Make sure all python files are compiled in your code base. See
http://docs.python.org/lib/module-compileall.html
 
"""
 
import os, sys
 
sys.path.append("/[racine]/python-local/django")
sys.path.append("/[racine]/[projet]")
 
import django.core.handlers.wsgi
 
def run_with_cgi(application):
 
    environ                      = dict(os.environ.items())
    environ['wsgi.input']        = sys.stdin
    environ['wsgi.errors']       = sys.stderr
    environ['wsgi.version']      = (1,0)
    environ['wsgi.multithread']  = False
    environ['wsgi.multiprocess'] = True
    environ['wsgi.run_once']     = True
 
    if environ.get('HTTPS','off') in ('on','1'):
        environ['wsgi.url_scheme'] = 'https'
    else:
        environ['wsgi.url_scheme'] = 'http'
 
    headers_set  = []
    headers_sent = []
 
    def write(data):
        if not headers_set:
             raise AssertionError("write() before start_response()")
 
        elif not headers_sent:
             # Before the first output, send the stored headers
             status, response_headers = headers_sent[:] = headers_set
             sys.stdout.write('Status: %s\r\n' % status)
             for header in response_headers:
                 sys.stdout.write('%s: %s\r\n' % header)
             sys.stdout.write('\r\n')
 
        sys.stdout.write(data)
        sys.stdout.flush()
 
    def start_response(status,response_headers,exc_info=None):
        if exc_info:
            try:
                if headers_sent:
                    # Re-raise original exception if headers sent
                    raise exc_info[0], exc_info[1], exc_info[2]
            finally:
                exc_info = None     # avoid dangling circular ref
        elif headers_set:
            raise AssertionError("Headers already set!")
 
        headers_set[:] = [status,response_headers]
        return write
 
    result = application(environ, start_response)
    try:
        for data in result:
            if data:    # don't send headers until body appears
                write(data)
        if not headers_sent:
            write('')   # send headers now if body was empty
    finally:
        if hasattr(result,'close'):
            result.close()
 
# Change mysite to the name of your site package
os.environ['DJANGO_SETTINGS_MODULE'] = '[projet].settings'
 
run_with_cgi(django.core.handlers.wsgi.WSGIHandler())

Bien évidement, vous modifierez les valeurs de [racine] et de [projet] par celle correspondantes.
Pour évaluer [racine], j’ai fait un simple script php qui me faisait un echo de $_SERVER[“DOCUMENT_ROOT”] :

<?php
echo $_SERVER["DOCUMENT_ROOT"];
?>

Pour [projet], c’est le nom que vous avez donné à votre projet python.

Enfin, n’oubliez pas d’adapter les chemins dans votre fichier settings.py à votre structure.

Normalement, si vous tentez d’accéder à votre site maintenant, vous aurez une erreur 500. Si vous regardez les logs d’erreurs, voici le type d’erreur que vous aurez :

Premature end of script headers: django.cgi
suexec policy violation: see suexec log for more details

En fait, l’erreur est très conne ici. Tout ce que vous avez à faire, c’est donner les bons droits à votre fichier django.cgi, notamment le fait qu’il soit exécutable.
Pour ma part, seul le droit -rwx —  —  — (tous les droits pour l’utilisateur, et rien pour le groupe et les autres) fonctionne. A vous de voir.

Maintenant, un petit F5 sur votre site et il devrait-être opérationnel !

Voilà ! C’est la fin de ma petite série sur Django, j’espère que vous avez apprécié :)
Si vous avez des questions n’hésitez pas, les commentaires sont fait pour ça !

Pour ma part, j’aurai préféré avoir un raccourcis de media dans www qui pointe sur le dossier django/contrib/admin/media, mais je n’ai pas trouvé comment faire cela dans FileZilla. Si c’est possible et que vous savez comment faire, je suis impatient d’avoir votre explication :)

Comments Pas de commentaire »

(Voici la suite de ma petite série “faire mumuse avec python sur son serveur”.)

Nous venons de voir la mise en ligne de notre projet développé en python en utilisant mod_python. Mais aujourd’hui, nous pouvons utiliser un nouveau module, plus performant que ce dernier, alors pourquoi s’en priver ?

Tout d’abord, installons le. Sous Debian, voici la commande :

apt-get install libapache2-mod-wsgi

Puis activons le :

a2enmod wsgi

ou à la mano :

ln -s /etc/apache2/mods-available/wsgi.load /etc/apache2/mods-enabled/
ln -s /etc/apache2/mods-available/wsgi.conf /etc/apache2/mods-enabled/

Remarquez qu’il y a aussi un fichier de configuration !
(par défaut, ce fichier de configuration est entièrement commenté. Vous pouvez donc l’ignorer.)

Maintenant, passons aux choses sérieuses, voici à quoi ressemblera votre VirtualHost :

<VirtualHost *:80>
        ServerAdmin postmaster@[domain].tld
        ServerName www.[domain].tld
        ServerAlias [domain].tld
        DocumentRoot /var/www/[domain]/www/[domain]
 
        ErrorLog /var/log/apache2/[domain]_error.log
        LogLevel warn
        CustomLog /var/log/apache2/[domain]_access.log combined
        ServerSignature Off
 
        WSGIScriptAlias / /var/www/[domain]/www/[project_name]/django.wsgi
 
        Alias /media "/var/www/[domain]/www/media"
        <Location "/media/">
                SetHandler None
        </Location>
 
        Alias /static "/var/www/[domain]/www/static"
        <Location "/static/">
                SetHandler None
        </Location>
 
        <LocationMatch "\.(jpg|gif|png)$">
                SetHandler None
        </LocationMatch>
</VirtualHost>

Je passerai sur l’explication des directives pour media et static, que vous trouverez sur le précédent article.

La ligne qui nous intéressent vraiment ici, c’est : WSGIScriptAlias / /var/www/[domain]/www/[domain]/django.wsgi.
Comme nous l’avions vu dans le précédent article, ma structure de dossier est faite de telle manière que j’ai un dossier correspondant au sous domaine (ici, www), et dedans, trois dossiers : domain (le même nom que le domaine (aka le nom du projet), qui contiens le code python, static et templates).

Maintenant, voici le contenu du fichier django.wsgi :

import os
import sys
 
sys.path.append('/var/www/[domain]/www/')
 
os.environ['DJANGO_SETTINGS_MODULE'] = 'domain.settings'
 
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Remarquez que j’ajoute le projet au python path (avec la ligne “sys.path.append”).
Je ne précise pas le répertoire qui contiens le code, car la ligne d’après s’en charge (de “/var/www/[domain]/www/” à “domain.settings”, j’obtiens /var/www/[domain]/www/[domain]/settings.py !

Redémarrez Apache et voilà !
Tout fonctionne !
Bon, la première fois, ça peut-être un peu long à charger, mais ensuite, le site sera fluide et agréable à naviguer !

Si vous avez des problèmes avec le thème de la partie Admin, vous avez oublié de faire un lien symbolique vers le répertoire “media” du module admin de Django. Pour avoir la démarche, c’est ici.

De plus, si vous désirez plus de détails concernant le module Wsgi, cette page vous aidera probablement.

Comments Un commentaire »