[PHP] Remote bestanden inlezen etc

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wij draaien backups voor onze klanten via een backup server. Deze backups willen wij graag toegankelijk maken voor de klant, zodat zij zelfstandig files kunnen terughalen etc. In principe krijgen de klanten alleen leesrechten, dus men hoeft zich niet zorgen te maken om het feit dat je klanten nooit in backups moet laten rommelen ;)

Ok.

Onze applicatie draait op server1, de backups staan opgeslagen op server2. Wat ik gemaakt heb is een kopje 'back up' binnen ons CRM, waar de klant een bestandslijst van zijn/haar files ziet.

Binnen deze applicatie leg ik verbinding met server2, door middel van de SSH2 module. Het verbinden lukt, ik voer vervolgens het commando 'ls -p -l' uit en parse dit, waarna ik netjes een bestandlijst kan weergeven (met onderscheid tussen folders en files, bestandsgrootte, etc).

Per file voer ik ook een SSH2 commando uit om de bestandsgrootte op te vragen. In mappen met veel bestanden kan het aantal uitgevoerde commando's al snel oplopen tot 30+.

Het (welbekende) probleem met SSH2 is, dat je soms geen output terug krijgt. Ik heb al een aantal dingen geprobeerd, zoals bijvoorbeeld het keyword '__FINISHED__' laten echo'en aan het einde van de ssh2_exec(), en pas een result returnen als het resultaat dus dat keyword bevat. Werkt niet lekker, ik krijg nog steeds veel ongewenste resultaten terug.

Is hier misschien een betere methode voor? De bedoeling is dat de bestanden dus weergegeven worden en dat de files beschikbaar worden voor download. Via ftp is geen optie, de lijn moet namelijk gecodeerd zijn omdat het om soms gevoelige informatie gaat.

Ik vraag me af hoe ik dit het beste kan realiseren. Op zich werkt het inlezen van de bestandstructuur nu, maar als het om grote mappen gaat, krijg ik de ene keer wel data terug, de andere keer niet. Het is op het moment dus vrij onbetrouwbaar.

Zelf heb ik al vele wrappers geprobeerd voor m'n ssh2_exec() functie. Ook heb ik alle suggesties uit de comments http://nl2.php.net/ssh2_exec geprobeerd.

Mijn huidige wrapper ziet er overigens zo uit:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    /**
     * Executes shell commands
     *
     * @param   string      Command to execute
     * @return  string      Returned data or status message
     */ 
    public function execute($command) {
        if(!is_resource($this->connection)) return 'noConnection';
        
        $dataResource = ssh2_exec($this->connection, $command .'; echo "__FINISHED__"', false);
        
        stream_set_blocking($dataResource, true);
        
        $timeStart = time();
        $data = '';

        while((time() - $timeStart) < 10) {
            $data .= fread($dataResource, 4096);

            if(strpos($data, 'FINISHED__')){
                $data = str_replace('__FINISHED__', '', $data);
                fclose($dataResource);
                return $data;
            }
        }   
                    
        return 'dataError';
    }


Ik heb uiteraard geprobeerd om de tijd in de while() loop hoger te zetten.

Suggesties zijn welkom :)

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
FTP is geen optie omdat t beveiligd moet zijn zeg je, maar FTP kan ook encrypted zijn (SSL/TLS), wellicht toch een optie dat eens te checken?

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Het ophalen kan ook prima over ssh2, er is zelf een ssh2-wrapper voor SFTP, genaamd ssh2_sftp. Voorbeeldcode van php.net:
PHP:
1
2
3
4
5
6
7
8
<?php
$connection = ssh2_connect('shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');

$sftp = ssh2_sftp($connection);

$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r');
?>
Zo simpel is het. Maar je kunt ook gewoon ssh2_scp_recv gebruiken, dat is nog simpeler:
PHP:
1
2
3
4
5
6
<?php
$connection = ssh2_connect('shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');

ssh2_scp_recv($connection, '/remote/filename', '/local/filename');
?>
Met deze commando's heb je ook geen last van het probleem dat je soms geen antwoord krijgt, omdat je niets via ssh2_exec verstuurt.

Wat dat probleem betreft, dat is altijd een beetje jammer inderdaad, maar een simpele sleep(1) nadat je een commando hebt verstuurd doet wonderen.
Per file voer ik ook een SSH2 commando uit om de bestandsgrootte op te vragen.
Dat snap ik even niet, waarom gebruik je de output van ls -l niet gewoon?

[ Voor 25% gewijzigd door Bergen op 03-06-2009 01:51 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
De output van ls -l gebruiken is nu een optie idd, ik ging er van uit dat m'n baas ook de bestandsgrootte van de mappen wilde zien in het overzicht. Aangezien een map gewoon als file wordt gezien (geloof ik?) binnen Linux, heeft dit altijd dezelfde grootte (4096).... vandaar dat ik nogmaals door de array moest lopen en per map nog een andere commando uitvoeren.

Waar moet ik die sleep(1) precies zetten?

Acties:
  • 0 Henk 'm!

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 07-09 11:44

Bergen

Spellingscontroleur

Na ssh2_exec.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hmm dan krijg ik helemaal geen results meer terug en is de hele boel vrij traag :)
Pagina: 1