Acceda a un file en PHP a través de un enlace simbólico de un usuario que normalmente no tiene permiso

Tengo este website, donde si el usuario envía un formulario, un script de python se ejecuta a través de una página php, y el script python crea un file zip y debe ofrecerlo al usuario para su descarga a través de un enlace. El file puede ser enorme (unos pocos GB).

Como estoy trabajando en un server de la universidad, estoy estrictamente sujeto a sus reglas y capacidades de server. Aquí está el problema:

El website se almacena en /data/mywebsite , que tiene un espacio de disco limitado. Por supuesto, esto es propiedad de www-data ya que es accesible principalmente por mi server Apache.

Me ofrecen 1 TB de almacenamiento en /experimentdata/ , que SÓLO ES ACCESIBLE por un único usuario específico, como el usuario. Esto se debe a que esta carpeta es una montura samba a la que se puede tener acceso mediante una ID de usuario única y específica.

Para crear el file en /experimentdata , utilizo un command sudo -u theuser que creará el file /experimentdata/downloadme.zip como usuario theuser . Ahora mi problema es: ¿cómo puedo ofrecer este file a través de un enlace para download a través de Apache?

Pensé en usar un enlace simbólico que puse, por ejemplo, /data/mywebsite/download/downloadme.zip . ¡El problema con eso es que el usuario www-data tiene absolutamente ningún permiso para leer el file!

¿Cómo puedo dejar que el usuario descargue el file /experimentdata/downloadme.zip con el usuario www-data través del usuario theuser ?

Me gustaría decir explícitamente que involucrar a sudo -u theuser está absolutamente bien. Pero no sé cómo hacer un enlace fuera de la carpeta de mi website.

PD: si necesita información adicional, pregunte.

Creo que lo que hay que hacer es que tu php / python devuelva los datos directamente en lugar de apache . Tu código puede hacer lo mismo que apache . En mi experiencia esto es mucho mejor que abrir otro directory y / o usar sudo , o cambiar permissions de file para apache , etc.

Si el progtwig produce el file grande más rápido que la connection a Internet, puede transmitir los datos directamente desde su progtwig, lo que elimina el file de datos adicional y el código para administrarlo y los mecanismos para recordarlo.

Esta respuesta en Stack Overflow muestra cómo funciona el código en php . https://stackoverflow.com/a/4357904/5484716 .

Para los progtwigs que se llamarán de esta manera, elimine todo el flujo de stderr y asegúrese de que el código de retorno de su process de python refleje con precisión el éxito o el fracaso del process.

Los ejemplos a continuación muestran las llamadas a popen() que usaría en el escenario de ejemplo anterior de stackoverflow. He prependido exec 2>/dev/null; al command de shell. Esto garantiza que ninguna salida vaya a un error estándar, incluso desde el propio shell, ya que tener datos en stderr y stdout puede ser una fuente de interlockings con popen() .

Si desea download el file de disco a su usuario:

 $fp = popen('exec 2>/dev/null; sudo -u theuser cat yourfile.zip', 'r'); 

Si desea download los datos del process activo:

 $fp = popen('exec 2>/dev/null; sudo yourpythonscript arg argN', 'r'); 

Estas líneas de commands son commands de shell y deben citarse apropiadamente para metacaracteres de shell.

En el segundo método, el server comenzaría a enviar los datos inmediatamente. Cuando el usuario envía el formulario con éxito, inmediatamente ve un dialog "save como" desde su browser. Tan pronto como el usuario select el file de salida, su secuencia de commands php transmite los datos directamente a través del cable y en el file remoto.

El script python debe imprimir solo los datos zip en el resultado estándar y devolver un código de salida que represente con precisión el éxito o el fracaso del process zip. En python el script debe escribir el resultado en sys.stdout , por ejemplo zf = ZipFile(sys.stdout, ...

Es fundamental llamar a pclose() y verificar el valor de retorno , porque esa será la única forma de saber si el file zip tuvo éxito o no. Si pclose() devuelve algo que no sea 0, algo está mal.

Cómo maneja el file el cliente depende de la configuration de estos response headers y otros: content-type: content-encoding: y content-disposition: Ver: http://www.w3.org/Protocols/rfc2616/ rfc2616-sec6.html , observe el response-header y la información del entity-header .