Monday, January 14, 2013

encabezamientos http

web.py


El sábado pasado, llevamos a cabo un taller PyHack. El tema era sobre cámaras web, pygame y el raspberry pi, como servidor de seguridad vídeo. Y acceso por teléfono a este servidor. Para demostrarlo, utilizamos inicialmente python -m SimpleHTTPServer, pero después, con web.py.

Para salvar tiempo en el taller, busco con google un ejemplo de servidor de imágenes con web.py, y de inmediato encontramos esta pagina:

webpy.org/images

El codigo es asi:

import os
import web 
 
urls = (
'/images/(.*)', 'images'
)  
 
class images:
    def GET(self,name):
        ext = name.split(".")[-1]  # Gather extension

        cType = {
            "png":"images/png",
            "jpg":"images/jpeg",
            "gif":"images/gif",
            "ico":"images/x-icon"            }

        if name in os.listdir('images'):  # Security
            web.header("Content-Type", cType[ext]) 
            return open('images/%s'%name,"rb").read() 
        else:
            raise web.notfound()

Y después de añadir :

app = web.application(urls, globals())

if __name__ == "__main__":
    app.run() 
 
 
no operaba como lo esperamos. Normalmente, no va a descargar las imágenes con un Content-Type (web.header) apropiado, solo mostrarlas en el navegador. Pero aquí, si!

image/jpg


Es lo correcto de poner un Content-Type: image/jpeg, image/png etc. Pero en el código, en el sitio, hay images/jpeg, images/png etc. En vez de salvar tiempo, perdimos mucho sin ver el S extra...

Mi versión es la siguiente (URLS en vez de urls y Images como clase en vez de images, y image/ sin el S extra)

import os
import web

class Images:
    def GET(self,name):
        ext = name.split(".")[-1]  # Gather extension

        cType = {
            "png":"image/png",
            "jpg":"image/jpeg",
            "gif":"image/gif",
            "ico":"image/x-icon"            }

        if name in os.listdir('images'):  # Security
            web.header("Content-Type", cType[ext]) # Set the Header
            return open('images/%s'%name,"rb").read() # Notice 'rb' for reading images
        else:
            raise web.notfound()

URLS = (
'/images/(.*)', Images
)

app = web.application(URLS, globals())

if __name__ == "__main__":
    app.run()


Este código opera correctamente. 

Descargar


Seguimos y añadimos mas hasta que completamos el proyecto (el código sera en bitbucket un poco mas tarde en el mes), y ahora todo esta bien.

Pero, cual es la manera si uno realmente desea ofrecer la descarga de un fichero? Hacer un error de tipo? No.

Hay que añadir un otro encabezamiento http (por medio de web.header) que se llama Content-disposition:

web.header("Content-disposition", "attachment; filename=%s"%name)

@f_dion

No comments: