Live dc++ forum
Форма входа
Главная | GreyGen — создание настроенных сборок GreyLink на лету - Форум | Воскресенье, 24.11.2024, 10:16
[ Новые сообщения · Участники · Правила форума · Поиск
  • Страница 1 из 1
  • 1
GreyGen — создание настроенных сборок GreyLink на лету
OCTAGRAMДата: Вторник, 19.04.2011, 23:01 | Сообщение # 1
Подполковник
Сообщений: 115
Репутация: 12
Статус: Offline
Просьба потестить сабж: http://p2p.toom.su/greygen

Примеры использования:

http://p2p.toom.su/greygen/mydc.ru/ — самый простой URL
http://p2p.toom.su/greygen/dchub/mydc.ru/ — можно добавить dchub или adc
http://p2p.toom.su/greygen/dchub/mydc.ru/411/ — ещё можно добавить порт
http://p2p.toom.su/greygen/dchub/mydc.ru/411/greylink4mydc.exe — ещё можно дать название файлу
http://p2p.toom.su/greygen/dchub/mydc.ru/411/greylink4mydc — можно без .exe, .exe всё равно добавится
http://p2p.toom.su/greygen/411/mydc.ru/dchub/greylink4mydc.exe — порядок dchub и номера порта не важны
http://p2p.toom.su/greygen/411/dchub/mydc.ru/greylink4mydc.exe — так тоже будет работать
http://p2p.toom.su/greygen/411/mydc.ru/greylink4mydc.exe — любой компонент можно убрать, если он дефолтный
http://p2p.toom.su/greygen/mydc.ru/greylink4mydc — снова минимальный URL
http://p2p.toom.su/greygen/adc/dchub/adc/dchub/mydc.ru/greylink4mydc — победит dchub, т. к. самый последний
http://p2p.toom.su/greygen/adc/babylon.aab21pro.org/412/ — а это ADC хаб
http://p2p.toom.su/greygen....lon.exe
http://p2p.toom.su/greygen....babylon
http://p2p.toom.su/greygen....adc — адрес хаба в виде URL тоже принимается

Я реализовал продолжение прерванных закачек, но не тестил.

Самая интересная часть делается на PascalScript в Inno Setup, позже опубликую, если интересно.

Исходники собственно greygen.php

Code
<?php

$glversion = trim(file_get_contents("version.txt"));

$directory = "";
$file1 = "greylink.$glversion.metro.ttk.exe";
$file1patchoffset = (int) (file_get_contents("greylink.$glversion.metro.ttk.txt"));
$patchsize = 2048;
$patch = '';

$mime_type = "application/octet-stream";

$file = $directory.$file1;

// URL processing

$configString = $_SERVER['QUERY_STRING']; // edit this line !

// example of $configString :
// "mydc.ru/greylink.setup.exe"
// "dchub/mydc.ru/greylink.setup.exe"
// "greylink.exe" // unmodified
// "dchub/mydc.ru/411/greylink.setup.exe"
// "adc/localhost/greylink.setup.exe"
// "adc/localhost/"
// ""

$predefinedOn = FALSE;
$adc = FALSE;
$hub = '';
$port = 0;
$greyname = '';

$configSplit = explode('/', $configString);

if (FALSE !== $configSplit) {
    if (count($configSplit) >= 1) {
       if (0 < strlen(end($configSplit))) {
          $greyname = end($configSplit);
       }
       for ($i = 0; $i + 1 < count($configSplit); $i++) {
          $configChunk = $configSplit[$i];
          if ("dchub" === strtolower($configChunk)) {
             $adc = FALSE;
          } else if ("dchub:" === strtolower($configChunk)) {
             $adc = FALSE;
          } else if ("adc" === strtolower($configChunk)) {
             $adc = TRUE;
          } else if ("adc:" === strtolower($configChunk)) {
             $adc = TRUE;
          } else if (ctype_digit($configChunk)) {
             $port = (int) $configChunk;
          } else if (FALSE !== preg_match('/^[-a-zA-Z0-9._]+$/', $configChunk)) {
             $predefinedOn = TRUE;
             $hub = $configChunk;
          } else if (FALSE !== preg_match('/^[-a-zA-Z0-9._]+:[0-9]+$/', $configChunk)) {
             $predefinedOn = TRUE;
             $configChunkExploded = explode(':', $configChunk);
             $hub = $configChunkExploded[0];
             $port = (int) ($configChunkExploded[1]);
          } else {
             header("404 Not found");
             echo("<html><head><title>404 Not found</title></head><body><h1>404 Not found</h1>Invalid URL chunk: ".htmlspecialchars($configChunk)."</body></html>");
             exit;
          }
       }
    }
}

if (strlen($greyname) >= 4 && strtolower(substr($greyname, strlen($greyname) - 4, 4)) == ".exe") {
    $greyname = substr($greyname, 0, strlen($greyname) - 4);
}

if ('' === $greyname) {
    $greyname = 'greylink.setup';
    if ($predefinedOn) {
       $greyname .= '.' . $hub;
    } else {
       $greyname .= '.openmod';
    }
}

$greyname .= ".$glversion.exe";

if ($predefinedOn) {
    $hubUrl = $hub;

    if ($adc) {
       $hubUrl = 'adc://' . $hubUrl;
    }

    if (0 != $port && 411 != $port) {
       $hubUrl .= ':' . $port;
    }

    $patch = "OpenModDisable=True\r\n".
             "PredefinedHub=$hubUrl\r\n".
             "PredefinedHubEnable=True\r\n".
             "-- ";
}

if (strlen($patch) > $patchsize) {
    header("404 Not found");
    echo "<html><head><title>404 Not found</title></head><body><h1>404 Not found</h1>URL is too long, failed to generate</body></html>";
    exit;
}

if (is_file($file))
{
         header("Content-Type: $mime_type");
         header("Content-Disposition: attachment; filename=\x22$greyname\x22");
         //if (isset($_SERVER['HTTP_RANGE']))
         // {
                 rangeDownload($file);
         // }
         //else
         // {
         //        header("Content-Length: ".filesize($file));
         //        readfile($file);
         // }
}  
else
{
         // some error...
         header("500 Not found");
         echo "<html><head><title>404 Not found</title></head><body><h1>404 Not found</h1>Essential file is missing</body></html>";
         exit;
}

function rangeDownload($file)
{
         $fp = @fopen($file, 'rb');

         $size   = filesize($file); // File size
         $length = $size;           // Content length
         $start  = 0;               // Start byte
         $end    = $size - 1;       // End byte
         // Now that we've gotten so far without errors we send the accept range header
         /* At the moment we only support single ranges.
          * Multiple ranges requires some more work to ensure it works correctly
          * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
          *
          * Multirange support annouces itself with:
          * header('Accept-Ranges: bytes');
          *
          * Multirange content must be sent with multipart/byteranges mediatype,
          * (mediatype = mimetype)
          * as well as a boundry header to indicate the various chunks of data.
          */
         header("Accept-Ranges: 0-$length");
         // header('Accept-Ranges: bytes');
         // multipart/byteranges
         // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
         if (isset($_SERVER['HTTP_RANGE']))
         {
                 $c_start = $start;
                 $c_end   = $end;
                 // Extract the range string
                 list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
                 // Make sure the client hasn't sent us a multibyte range
                 if (strpos($range, ',') !== false)
                 {
                         // (?) Shoud this be issued here, or should the first
                         // range be used? Or should the header be ignored and
                         // we output the whole content?
                         header('HTTP/1.1 416 Requested Range Not Satisfiable');
                         header("Content-Range: bytes $start-$end/$size");
                         // (?) Echo some info to the client?
                         exit;
                 }
                 // If the range starts with an '-' we start from the beginning
                 // If not, we forward the file pointer
                 // And make sure to get the end byte if spesified
                 if ($range{0} == '-')
                 {
                         // The n-number of the last bytes is requested
                         $c_start = $size - substr($range, 1);
                 }
                 else
                 {
                         $range  = explode('-', $range);
                         $c_start = $range[0];
                         $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
                 }
                 /* Check the range and make sure it's treated according to the specs.
                  * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
                  */
                 // End bytes can not be larger than $end.
                 $c_end = ($c_end > $end) ? $end : $c_end;
                 // Validate the requested range and return an error if it's not correct.
                 if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size)
                 {
                         header('HTTP/1.1 416 Requested Range Not Satisfiable');
                         header("Content-Range: bytes $start-$end/$size");
                         // (?) Echo some info to the client?
                         exit;
                 }
                 $start  = $c_start;
                 $end    = $c_end;
                 $length = $end - $start + 1; // Calculate new content length
                 fseek($fp, $start);
                 header('HTTP/1.1 206 Partial Content');
         }
         // Notify the client the byte range we'll be outputting
         header("Content-Range: bytes $start-$end/$size");
         header("Content-Length: $length");

         rangeOutput ($fp, $end);

         fclose($fp);
}                   

function rangeOutput (&$fp, $end) {
         global $file1patchoffset, $patchsize, $patch;
         // Start buffered download
         $buffer = 1024 * 8;
         while(!feof($fp) && ($p = ftell($fp)) <= $end)
         {
                 if ($p + $buffer > $end)
                 {
                         // In case we're only outputting a chunk, make sure we don't
                         // read past the length
                         $buffer = $end - $p + 1;
                 }
                 set_time_limit(0); // Reset time limit for big files
                 $chunk = fread($fp, $buffer);

                 $patch_l_offset = max($p, $file1patchoffset);
                 $patch_r_offset = min($p + $buffer, $file1patchoffset + strlen($patch));

                 if ($patch_l_offset < $patch_r_offset)
                 {
                    // patched region and current chunk overlap

                    $chunk = substr_replace($chunk,  
                       substr($patch, $patch_l_offset - $file1patchoffset, $patch_r_offset - $patch_l_offset),
                    $patch_l_offset - $p,                $patch_r_offset - $patch_l_offset);

                    assert(strlen($chunk) == $buffer);
                 }

                 echo $chunk;
                 flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
         }
}

?>








Сообщение отредактировал OCTAGRAM - Среда, 20.04.2011, 05:37
 
lazybadgerДата: Четверг, 21.04.2011, 15:31 | Сообщение # 2
Подполковник
Сообщений: 141
Репутация: 11
Статус: Offline
А подробнее рассказать для ленящихся читать исходники, что именно из URL можно переопределять?
 
OCTAGRAMДата: Суббота, 23.04.2011, 10:33 | Сообщение # 3
Подполковник
Сообщений: 115
Репутация: 12
Статус: Offline
Пока только адрес хаба





 
  • Страница 1 из 1
  • 1
Поиск:


В движке поковырялся LiveDC :p © 2024
Сделать бесплатный сайт с uCoz