Foros del Web » Programando para Internet » Python »

upload con python a apache

Estas en el tema de upload con python a apache en el foro de Python en Foros del Web. Hola a todosç: Tengo un problema que me esta llevando unos días. Lo que quiero es subir ("enviar") un archivo local a un servidor apache ...
  #1 (permalink)  
Antiguo 27/09/2011, 05:55
 
Fecha de Ingreso: enero-2011
Mensajes: 88
Antigüedad: 13 años, 10 meses
Puntos: 1
Exclamación upload con python a apache

Hola a todosç:

Tengo un problema que me esta llevando unos días.

Lo que quiero es subir ("enviar") un archivo local a un servidor apache (remoto o local).

El apache me responde que ha realizado la operación pero el archivo no esta.

El código python 2.5 es el siguiente:
headers = {'Content-type': 'application/octet-stream','Accept':'text/plain'}
conn = httplib.HTTPConnection("localhost")
conn.request("POST","/upload", open("C:\\archivo.png", "rb").read(),headers)

r1 = conn.getresponse()
print r1.status , r1.reason
print r1.read()
conn.close()

Como se puede apreciar se escrivo la respuesta de apache en la pantalla y es esta:
301 Moved Permanently
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://localhost/upload/">here</a>.</p>
</body></html>


¿alguien sabe lo que falla?
El moved permanently borra al cerrar la connexion?

Gracias, atentamente Eñaut.
  #2 (permalink)  
Antiguo 27/09/2011, 08:00
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: upload con python a apache

El 301 es una respuesta de redirección, deberías seguir la cabecera Location que te devuelve el servidor. Es probable que httplib la esté siguiendo automáticamente, pero el POST no se re-envía cuando suceden redirecciones.

Si la redirección la está haciendo directamente el servidor, es probable que el contenido de tu petición POST ni siquiera llegue al programa que debe procesarlo.

A propósito, ¿hay algún motivo en especial para que estés usando httplib en vez de urllib2?


Saludos.
  #3 (permalink)  
Antiguo 28/09/2011, 01:04
 
Fecha de Ingreso: enero-2011
Mensajes: 88
Antigüedad: 13 años, 10 meses
Puntos: 1
Respuesta: upload con python a apache

Hola, gracias por la respuesta.

Utilizo el httplib porque es parte de código de un plugin para qgis (www.qgis.org), que utiliza python 2.5.

No se porque intenta redireccionar, el tema es que en la parte del servidor no hay ningun php que lo procese.

Con un código cliente parecido a este pero diciendo que ejecute un php he conseguido subir un archivo. El php sólo hace esto:
<?php
move_uploaded_file($_FILES["file"]["tmp_name"],
upload\ . $_FILES["file"]["name"]);
?>

Como este código solo mueve el archivo, hemos pensado que quizá el cliente (código python) pueda decirle que deje el archivo directamente en upload\ y así el código php no será necesario.

¿Se puede hacer esto, o el archivo siempre queda en una carpeta temporal?
¿Quizá se tiene que configurar apache para poder hacer esto?

Gracias, atentamente Eñaut.
  #4 (permalink)  
Antiguo 28/09/2011, 13:21
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: upload con python a apache

El programa que envía el archivo vía POST no tiene ninguna forma de decirle al servidor dónde dejarlo, sencillamente porque sería un problema de seguridad muy grande.

Siempre debes trabajar con dos componentes, uno del lado del servidor y otro del lado del cliente. Si no hay código del lado del servidor para recibir y colocar el archivo donde debe, no hay nada que puedas hacer desde el cliente. Tu única opción en ese caso es jugar con el método PUT de HTTP (en vez de POST).

Creo que la redirección sucede porque le estás indicando que envíe hacia una carpeta, mientras que es convención que siempre que se solicita una carpeta, se redirige hacia la misma URL con una barra al final (/)


Saludos.
  #5 (permalink)  
Antiguo 28/09/2011, 14:27
 
Fecha de Ingreso: enero-2011
Mensajes: 88
Antigüedad: 13 años, 10 meses
Puntos: 1
Respuesta: upload con python a apache

Hola, estoy de acuerdo contigo, suponía que no podía ser.

Aun así no controlo muy bien este tema y voy a estudiar mas los métodos por que no se en lo que afecta cada uno y como utilizar el protocolo http, me parece interesante.

El segundo parámetro de la función request debe ser un archivo html, php etc algo que se ejecute en el servidor, ¿podría ser un archivo python, java etc?

He visto esto en la documentación de python: conn.request("GET", "/parrot.spam")

Y esto también:

>>> import httplib, urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
... "Accept": "text/plain"}
>>> conn = httplib.HTTPConnection("musi-cal.mojam.com:80")
>>> conn.request("POST", "/cgi-bin/query", params, headers)

Aquí no se envía un archivo, o es un archivo de alguna consulta sql?Como no tiene extensión.

Estoy un poco perdido, ¿me puede recomendar alguna lectura interesante para poder aprender sobre esto?

Muchisimas gracias por su atención, atentamente Eñaut.
  #6 (permalink)  
Antiguo 28/09/2011, 16:24
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: upload con python a apache

El segundo parámetro es simplemente la URL que se debe obtener.
Para hacer lo mismo que hace un navegador cuando le das la URL www.dominio.com/index.html, debes escribir:

httplib.HTTPConnection('www.dominio.com')
...
conn.request("GET", "/index.html")

¿se entiende? el segundo parámetro es simplemente la URL a obtener.

Para enviar archivos, debes ir un poco más allá de esto y buscar información sobre urllib2 y multipart/form-data (la codificación necesaria para enviar archivos).

Lamentablemente la biblioteca estándar de python no provee un método para enviar archivos por POST, deberás usar alguno de los paquetes externos que se mencionan en http://bugs.python.org/issue3244


saludos.
  #7 (permalink)  
Antiguo 29/09/2011, 02:08
 
Fecha de Ingreso: enero-2011
Mensajes: 88
Antigüedad: 13 años, 10 meses
Puntos: 1
Respuesta: upload con python a apache

ok, gracias. Al final el método que voy a utilizar para enviar el archivo es este:

Cliente (python 2.5):

Código Python:
Ver original
  1. def post_multipart(host, selector, fields, files):
  2.     """
  3.    Post fields and files to an http host as multipart/form-data.
  4.    fields is a sequence of (name, value) elements for regular form fields.
  5.    files is a sequence of (name, filename, value) elements for data to be uploaded as files
  6.    Return the server's response page.
  7.    """
  8.     content_type, body = encode_multipart_formdata(fields, files)
  9.     h = httplib.HTTP(host)
  10.     h.putrequest('POST', selector)
  11.     h.putheader('content-type', content_type)
  12.     h.putheader('content-length', str(len(body)))
  13.     h.endheaders()
  14.     h.send(body)
  15.     h.getfile()
  16.     errcode, errmsg, headers = h.getreply()
  17.     return h.file.read()
  18.  
  19. def encode_multipart_formdata(fields, files):
  20.     """
  21.    fields is a sequence of (name, value) elements for regular form fields.
  22.    files is a sequence of (name, filename, value) elements for data to be uploaded as files
  23.    Return (content_type, body) ready for httplib.HTTP instance
  24.    """
  25.     BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
  26.     CRLF = '\r\n'
  27.     L = []
  28.     for (key, value) in fields:
  29.         L.append('--' + BOUNDARY)
  30.         L.append('Content-Disposition: form-data; name="%s"' % key)
  31.         L.append('')
  32.         L.append(value)
  33.     for (key, filename, value) in files:
  34.         L.append('--' + BOUNDARY)
  35.         L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
  36.         L.append('Content-Type: %s' % get_content_type(filename))
  37.         L.append('')
  38.         L.append(value)
  39.     L.append('--' + BOUNDARY + '--')
  40.     L.append('')
  41.     body = CRLF.join(L)
  42.     content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
  43.     return content_type, body
  44.  
  45. def get_content_type(filename):
  46.     return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
  47.  
  48. def main(self):
  49.     params= [('file', 'file')]
  50.     files = [('file', 'C:\\archivo.png', open('C:\\archivo.png', 'rb').read())]
  51.     post_multipart("www.miservidor.com", "/uploader.php", params, files)
Servidor(el archivo www.miservidor.com/uploader.php)

Código PHP:
Ver original
  1. <?php
  2. move_uploaded_file($_FILES["file"]["tmp_name"],
  3. upload\ . $_FILES["file"]["name"]);
  4. ?>

Así es como envio un archivo local a la carpeta www.miservidor.com/upload/

Espero que a alguien le sirva de ayuda. en el codigo del php falta añadirle seguiridad para que cualquiera no pueda copiar archivos.

Se agradece cualquier comentario, mejora o crítica al método.

atentamente Eñaut.

Última edición por AlvaroG; 29/09/2011 a las 07:37
  #8 (permalink)  
Antiguo 29/09/2011, 07:37
AlvaroG
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: upload con python a apache

Una buena solución. Simplemente modifico para agregar las etiquetas HIGHLIGHT :)

Etiquetas: httplib, httplib2, request, response, upload, https
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:18.