entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Accediendo a un disco de red con PHP 5.5.11

Hola buenos días a todos, o tardes depende del lugar del mundo donde te encuentres.

Tengo el siguiente problema, tengo un equipo que tiene un sistema de gestión documental que se surte de archivos generados en pdf a través de la web. La web la queremos migrar a PHP 5.5.11 que ya está funcionando perfectamente pero a la hora de recobrar un archivo de la carpeta de red o subir un archivo a la carpeta de la app de gestión documental no nos deja. No accede a dispositivos de red. Hemos probado dando permisos a la carpeta a "Everyone", dando permisos exclusivamente a IUSR (el usuario que gestiona el IIS en Windows Server) y nada. Sabéis algo?

Os comento un poco los sistemas que usamos.

Lenguaje de programación: PHP
Base de datos: SQL Server (que no incluye porque la base de datos no falla en abosluto)
Servidor de servicios de internet: IIS Windows Server 2013
Servidor con archivos: Windows Server 2013
Infraestructura de red: Dominio

Creo que no me falta ningún dato. Si se os ocurre algo por favor contribuid a la pregunta porque no encuentro mucha documentación.

0voto

carlossevi comentado

¿Puedes ponernos la parte del código que falla?

Por otro lado supongo que has probado a hacer login en el servidor de servicios de internet con el usuario que ejecuta el servicio de IIS y puedes acceder sin problemas a la ruta de red ¿correcto?

0voto

ankeorum comentado

Exactamente, he entrado en la carpeta de red sin problemas desde cualquier máquina (después de dar acceso a everyone obviamente) y no hay problema, es más, en el servidor que ejecuta IIS tengo mapeada la carpeta de red como F:/ y entro sin problema pero luego defino en el código PHP que la ruta de recuperación de archivos es F:/uploads/ y no vale, me baja un archivo con 0 kb de contenido y vacío obviamente.

El código PHP creo que en este caso no es el problema pero aquí lo pongo también, ya que me ayudáis lo que sea ;-)

view_uploads.php

<?php
  define('CHUNK_SIZE', 1024*1024); // Size (in bytes) of tiles chunk
  //
  $upload_loc = "F:\\\\uploads\\\\";

    //include_once ($_SERVER['DOCUMENT_ROOT'].'/php_functions.php');

    if ($userdetails[0] == "demo")
    {
          $upload_loc = "F:\\\\uploads_demo\\\\";
    }

    function mimetype($filename) 
    {
            $mime_types = array(

                'txt' => 'text/plain',
                'htm' => 'text/html',
                'html' => 'text/html',
                'php' => 'text/html',
                'css' => 'text/css',
                'js' => 'application/javascript',
                'json' => 'application/json',
                'xml' => 'application/xml',
                'swf' => 'application/x-shockwave-flash',
                'flv' => 'video/x-flv',

                // images
                'png' => 'image/png',
                'jpe' => 'image/jpeg',
                'jpeg' => 'image/jpeg',
                'jpg' => 'image/jpeg',
                'gif' => 'image/gif',
                'bmp' => 'image/bmp',
                'ico' => 'image/vnd.microsoft.icon',
                'tiff' => 'image/tiff',
                'tif' => 'image/tiff',
                'svg' => 'image/svg+xml',
                'svgz' => 'image/svg+xml',

                // archives
                'zip' => 'application/zip',
                'rar' => 'application/x-rar-compressed',
                'exe' => 'application/x-msdownload',
                'msi' => 'application/x-msdownload',
                'cab' => 'application/vnd.ms-cab-compressed',

                // audio/video
                'mp3' => 'audio/mpeg',
                'qt' => 'video/quicktime',
                'mov' => 'video/quicktime',

                // adobe
                'pdf' => 'application/pdf',
                'psd' => 'image/vnd.adobe.photoshop',
                'ai' => 'application/postscript',
                'eps' => 'application/postscript',
                'ps' => 'application/postscript',

                // ms office
                'doc' => 'application/msword',
                //'docx' =>'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                'rtf' => 'application/rtf',
                'xls' => 'application/vnd.ms-excel',
                'ppt' => 'application/vnd.ms-powerpoint',

                // open office
                'odt' => 'application/vnd.oasis.opendocument.text',
                'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
            );

            $ext = strtolower(array_pop(explode('.',$filename)));

            if (array_key_exists($ext, $mime_types)) 
            {
                return $mime_types[$ext];
            }
            else 
            {
                return 'application/octet-stream';
            }
    }
  //
  // Read a file and display its content chunk by chunk
  function readfile_chunked($filename, $retbytes = TRUE) {
    $buffer = '';
    $cnt =0;
    // $handle = fopen($filename, 'rb');
    $handle = fopen($filename, 'rb');
    if ($handle === false) {
      return false;
    }
    while (!feof($handle)) {
      $buffer = fread($handle, CHUNK_SIZE);
      echo $buffer;
      ob_flush();
      flush();
      if ($retbytes) {
        $cnt += strlen($buffer);
      }
    }
    $status = fclose($handle);
    if ($retbytes && $status) {
      return $cnt; // return num. bytes delivered like readfile() does.
    }
    return $status;
  }

  // Here goes your code for checking that the user is logged in
  // ...
  // ...
  $logged_in = true;

  if ($logged_in) 
  {
    $filename = $upload_loc.$_REQUEST['filetoview'];

    $mimetype = mimetype($_REQUEST['filetoview']);
    header('Content-Type: application/force-download'); 
    //header('Content-Type: '.$mimetype );
    header('Content-Disposition: attachment; filename='.$_REQUEST['filetoview']); 
    ob_clean();
    ob_flush();
    readfile_chunked($filename);

  }
  else 
  {
    //echo 'Tabatha says you haven\'t paid.';
  }

?>

Gracias por responder

0voto

ankeorum comentado

Para evitar también trabajos extra he probado:

  • obviar el mapeo e intentar acceder usando como $upload_loc = '\fileserver\d\uploads\"
  • hacerlo accediendo mediante el disco mapeado así: $upload_loc = 'f:\uploads\"

Pues ya no se me ocurre más cosas que haya probado, bueno sí, he probado con \, con \\ (por lo de que la primera es de escape)...

3 Respuestas

2votos

ankeorum Puntos7210

Después de varios golpes os mostraré como lo hemos solucionado. Hemos decidido mapear la unidad de red desde código mapeando de forma no persistente para que mapee cada vez que necesite el recurso. Esto lo hemos hecho con el siguiente código que hemos encontrado por internet.

La mapeamos en la connection_string.php para que así en cualquier página que intente acceder al recurso en cuestión no tenga problemas para encontrarlo.

// Define the parameters for the shell command
    $location = "\\\\ip\\drive";
    $user = "domain\\user";
    $pass = "password";
    $letter = "F";

    // Map the drive
    system("net use ".$letter.": \"".$location."\" ".$pass." /user:".$user." /persistent:no>nul 2>&1");

    $upload_loc = $letter.":/uploads/";

SaludoS!

0voto

carlossevi comentado

Con las nuevas cadenas que escribiste ya solucionaste el problema de las barras, las rutas están bien escritas. Te recomendaría editar el comentario y quitar las credenciales. Aunque en teoría no es una ruta accesible, nunca es recomendable publicar este tipo de cosas.

0voto

ankeorum comentado

Gracias por el consejo ;)

0voto

carlossevi Puntos63580

Opino que el problema puede estar en la siguiente línea:

$upload_loc = "F:\\\\uploads\\\\";

Prueba hacer lo siguiente:

$upload_loc = "F:\\\\uploads\\\\";
print($upload_loc);

y verás que el resultado es F:\\uploads\\, lo que obviamente no es una ruta accesible en entorno Windows.

Las alternativas:

// Unidad mapeada:
$upload_loc = "F:\\uploads\\";
// Unidad sin mapear:
$upload_loc = "\\\\fileserver\\uploads\\";

Pruébalo y nos lo comentas.

1voto

Leonardo-Tadei Puntos227320

Hola Ankeorum,

PHP 5 por defecto trae activadas las directivas open_basedir que restringe el acceso a un directorio y sus subdirectorios a los scrpts.

Si por ejemplo tu open_basedir está en c:\www, no podrás ver ningún directorio para atrás ni ninguna otra unidad.

También revisá la configuración de la directiva safe_mod y si tenés el módulo Suhosin, que no agregue restricciones de acceso a los directorios.

Si aportaras parte del log de error de PHP cuando se ejecuta esete código podríamos darte más pesiciones: el error de "archivo inexistente" y de "no puedo acceder al archivo" son ligeramenet diferentes, pero uno es que el archivo buscado no existe en esa ruta y el otro es que no se tiene permiso para acceder a la ruta.

Podrías además probar crear un script aparte que muestre la salida de scandir() de diferentes rutas y los errores, para ayudarte a determinar si la ruta es inválida o si es la configuración... digo, como idea de debbugueo.

Saludos!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta