Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    socket: possibile un tunnel http?

    Ciao, la mia situazione e` questa: ho due server, sul primo (PIPPO) hanno accesso gli utenti, sul secondo (PLUTO) ci sono dei file disponibili via http solo per PIPPO. Sto cercando di costruire con le funzioni socket php una specie di tunnel, in modo che un utente chiedendo un file su PIPPO ottenga un file di PLUTO.

    Funziona bene, ma quando il file e` grande vado incontro a problemi di memoria di PHP. Secondo voi c'e` il modo di passare il file pezzo pezzo all'utente?

    Codice PHP:
    <?php
    set_time_limit
    (0);
    $fp fsockopen('pluto',80,$errno$errstr30);
          if(!
    $fp){
                print 
    '**ERROR: '.$errstr.' ('.$errno.')'."\n";
                exit;
          }

    $in "GET /var/file.iso HTTP/1.1\r\n"
    $in.= "Host: pluto\r\n";    
    $in.= "Content-Type: application/octet-stream\r\n";
    $in.= "Connection: Close\r\n\r\n";

    fputs($fp,$in);
    while (!
    feof($fp)) {
           
    $str[] = fread($fp4096);
    }
    fclose($fp);
    $ISO =  implode('',$str);
    print 
    $ISO;
    ?>
    Are you alive?
    No, but I was written with LOVE. A new scripting language.
    www.frequenze.it

  2. #2
    certo

    invece di

    while (!feof($fp)) {
    $str[] = fread($fp, 4096);
    }
    fclose($fp);
    $ISO = implode('',$str);
    print $ISO;

    fai

    while (!feof($fp)) {
    // VANNO PARSATI GLI HEADERS \\
    echo fread($fp, 8192);
    }
    fclose($fp);

    ---

    Ovviamente facendo questo c'è un grosso problema, ovvero gli headers!
    Devi fare una cosa particolare ... metti i vari chunk in un'array, come facevi prima, e ogni chunk, prima di metterlo, lo parsi alla ricerca di un doppio invio (solo \n\n) e se lo trovi tagli il chunk al punto che ti serve, li analizzi e acquisisci informazioni come la dimensione del file e simili dopo di che invii le informazioni che servono. Una volta fatta questa fase puoi inviare in blocco il resto senza problemi

    Se vuoi aumentare ancora il buffer puoi farlo ma su windows non puoi ricevere più di 8192 byte per blocco

  3. #3
    Si` grazie. Avevo provato questa strada genere, ma ottenevo come risultato una serie di caratteri binari.
    Secondo te devo inviare qualcosa in header() prima di iniziare il ciclo?
    Are you alive?
    No, but I was written with LOVE. A new scripting language.
    www.frequenze.it

  4. #4
    no, non prima del ciclo, ma dopo che acquisisci gli headers dalla richiesta

    il fatto che tu riceva caratteri binari è normale, è dovuto proprio al fatto che non mandi nessun header

    cmq è una cosa che ho fatto in svariate occasioni e quella di su è sicuramente la strada migliore, perché:
    - non c'è un limite alla dimensione del file
    - occupa sempre una quantità ridottissima di memoria
    - il buffer si può regolare per ottenere performance migliori

  5. #5
    Ok, quindi:

    - inizio il ciclo
    - parso gli header di risposta
    - uso header() per inviare i miei
    - stampo il resto regolando il buffer
    Are you alive?
    No, but I was written with LOVE. A new scripting language.
    www.frequenze.it

  6. #6
    Esatto ... semplicemente fai cosi, che è di solito quello che faccio io

    codice:
    $headerRecived = false;
    $headerText = '';
    while (!feof($fp))
    {
    $buffer = fread($fp, 8192);
    
    if ($headerRecived == false)
    {
    if (($headersEnd = strpos($buffer, "\n\n")) === FALSE)
    {
    $headerText .= $buffer;
    }
    else
    {
    $headerText .= substr($buffer, 0, $headersEnd);
    
    // PARSA GLI HEADERS
    
    // INVIA GLI HEADERS NECESSARI
    
    // Invia l'output rimanente
    echo substr($buffer, $headersEnd);
    
    // Setta lo switch
    $headerRecived = true;
    }
    }
    else
    {
    echo $buffer;
    }
    }
    Per parsare gli headers semplicemente li esplodi prima sull'invio ovvero \n, dopo di che li cicli col while e rimuovi la prima riga mettendola da parte perché è lo status, dopo che li esplodi sul : e acquisisci la prima parte che ti viene restituita togliendola usando array_shift dopo di che reimplodi l'array che hai ancora senza quel primo elemento col : in modo che se c'è ne stavano altri nella stringa non si è corrotta ... un giochino stupido ma efficente

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.