[PHP] Webseite auslesen, trotz allow_url_fopen=false

theHacker

sieht vor lauter Ads den Content nicht mehr
Teammitglied
ID: 69505
L
20 April 2006
22.680
1.315
Wenn allow_url_fopen auf false gesetzt ist, schlagen die Funktionen fopen(), file(), ... fehl:
Warning: file() [function.file]: URL file-access is disabled in the server configuration in /www/script.php on line 123
Wenn Sockets verfügbar sind, kann man das mit dieser Funktion umgehen:
PHP:
/** myfile(URL) ** Aequivalent zu file() 
    ***************************************** (w) tleilax, 2004 *** 
    * Funktioniert auch bei allow_url_fopen=false, solange Sockets 
    * geöffnet werden können 
    * 
    * Übergabe: 
    *  Die auszulesende URL. 
    * Rückgabe: 
    *  Array, das alle Zeilen der auszulesenden URL enthält. 
    ***************************************************************/ 
  function myfile($url) { 
    // URL zerlegen 
    $parsedurl = @parse_url($url); 
    // Host ermitteln, ungültigen Aufruf abfangen 
    if (empty($parsedurl['host'])) 
      return null; 
    $host = $parsedurl['host']; 
    // Pfadangabe ermitteln 
    if (empty($parsedurl['path'])) 
      $documentpath = '/'; 
    else 
      $documentpath = $parsedurl['path']; 
    // Parameter ermitteln 
    if (!empty($parsedurl['query'])) 
      $documentpath .= $parsedurl['query']; 
    // Port ermitteln 
    if (!empty($parsedurl['port'])) 
      $port = $parsedurl['port']; 
    else 
      $port = 80; 
    // Socket öffnen 
    $fp = fsockopen ($host, $port, $errno, $errstr, 30); 
    if (!$fp) 
      return null; 
    // Request senden 
    fputs ($fp, "GET {$documentpath} HTTP/1.0\r\nHost: {$host}\r\n\r\n"); 
    // Header auslesen 
    do { 
      $line = chop(fgets($fp)); 
    } while (!empty($line) and !feof($fp)); 
    // Daten auslesen 
    $result = Array(); 
    while (!feof($fp)) { 
      $result[] = fgets($fp); 
    } 
    // Socket schliessen 
    fclose($fp); 
    // Ergebnis-Array zurückgeben 
    return $result; 
  }
Danke @tleilax für den Code :D

Quelle im Crashforum:
https://www.klamm.de/crashforum/showpost.php?p=1041750&postcount=5
 
Und wer sonst mit file_get_contents() arbeitet, kann diese (nur leicht abgewandelten) Code nutzen:
PHP:
/** file_getContents(URL) ** Aequivalent zu file_get_contents()
 ***************************************** (w) tleilax, 2004 ***
 * Funktioniert auch bei allow_url_fopen=false, solange Sockets
 * geöffnet werden können
 *
 * Übergabe:
 *  Die auszulesende URL.
 * Rückgabe:
 *  String, der die komplette Rückgabe der auszulesenden URL enthält
 ***************************************************************/
function file_getContents($url) {
  // URL zerlegen
  $parsedurl = @parse_url($url);
  // Host ermitteln, ungültigen Aufruf abfangen
  if (empty($parsedurl['host']))
    return null;
  $host = $parsedurl['host'];
  // Pfadangabe ermitteln
  if (empty($parsedurl['path']))
    $documentpath = '/';
  else
    $documentpath = $parsedurl['path'];
  // Parameter ermitteln
  if (!empty($parsedurl['query']))
    $documentpath .= $parsedurl['query'];
  // Port ermitteln
  if (!empty($parsedurl['port']))
    $port = $parsedurl['port'];
  else
    $port = 80;
  // Socket öffnen
  $fp = fsockopen ($host, $port, $errno, $errstr, 30);
  if (!$fp)
    return null;
  // Request senden
  fputs ($fp, "GET {$documentpath} HTTP/1.0\r\nHost: {$host}\r\n\r\n");
  // Header auslesen
  do {
    $line = chop(fgets($fp));
  } while (!empty($line) and !feof($fp));
  // Daten auslesen
  $result = '';
  while (!feof($fp)) {
    $result .= fgets($fp);
  }
  // Socket schliessen
  fclose($fp);
  // Ergebnis zurückgeben
  return $result;
}
 
Hmm, imho sollte die Funktion noch so ergänzt werden, dass bei einem 404er (etc.) FALSE zurückgegeben wird, aber sonst schauts (natürlich) gut aus :)
 
As you wish. Sogar noch ein bisschen aufwendiger. ;)

:arrow: file_getContents()
PHP:
/** file_getContents(URL) ** Aequivalent zu file_get_contents()
***************************************** (w) tleilax, 2006 ***
* Funktioniert auch bei allow_url_fopen=false, solange Sockets
* geöffnet werden können
*
* Übergabe:
*  $url     - Die auszulesende URL.
*  $timeout - Zeit in Sekunden für den Verbindungsaufbau
* Rückgabe:
*  String, der die komplette Rückgabe der auszulesenden URL enthält
***************************************************************/
function file_getContents($url, $timeout=30) {
  // URL zerlegen
  $parsedurl = @parse_url($url);
  // Host ermitteln, ungültigen Aufruf abfangen
  if (empty($parsedurl['host']))
    return null;
  $host = $parsedurl['host'];
  // Pfadangabe ermitteln
  $documentpath = empty($parsedurl['path']) ? '/' : $documentpath = $parsedurl['path'];
  // Parameter ermitteln
  if (!empty($parsedurl['query']))
    $documentpath .= '?'.$parsedurl['query'];
  // Port ermitteln
  $port = empty($parsedurl['port']) ? 80 : $port = $parsedurl['port'];

  // Socket öffnen
  $fp = fsockopen ($host, $port, $errno, $errstr, $timeout);
  if (!$fp)
    return null;
  
  // Request senden
  fputs ($fp, "GET {$documentpath} HTTP/1.0\r\nHost: {$host}\r\n\r\n");
  
  // Header auslesen
  $header = '';
  do {
    $line = chop(fgets($fp));
    $header .= $line."\n";
  } while (!empty($line) and !feof($fp));
  // Daten auslesen
  $result = '';
  while (!feof($fp)) {
    $result .= fgets($fp);
  }
  // Socket schliessen
  fclose($fp);
  
  // Header auswerten
  preg_match('~^HTTP/1\.\d (?P<status>\d+)~', $header, $matches);
  $status = $matches['status'];
  if ($status == 200) { // OK
    return $result;
  } elseif ($status == 204 or $status == 304) { // No Content | Not modified
    return '';
  } elseif (in_array($status, Array(300, 301,302,303,307))) {
    preg_match('~Location: (?P<location>\S+)~', $header, $match);
    $result = file_getContents($match['location'], $timeout);
  } elseif ($status >= 400) { // Any error
    return false;
  } 
  
  // Ergebnis zurückgeben
  return $result;
}

:arrow: my_file()
PHP:
/** my_file(URL) ** Aequivalent zu file()
***************************************** (w) tleilax, 2006 ***
* Funktioniert auch bei allow_url_fopen=false, solange Sockets
* geöffnet werden können
*
* Übergabe:
*  $url     - Die auszulesende URL.
*  $timeout - Zeit in Sekunden für den Verbindungsaufbau
* Rückgabe:
*  Array, das alle Zeilen der auszulesenden URL enthält.
***************************************************************/
function my_file($url, $timeout=30) {
  // URL zerlegen
  $parsedurl = @parse_url($url);
  // Host ermitteln, ungültigen Aufruf abfangen
  if (empty($parsedurl['host']))
    return null;
  $host = $parsedurl['host'];
  // Pfadangabe ermitteln
  $documentpath = empty($parsedurl['path']) ? '/' : $documentpath = $parsedurl['path'];
  // Parameter ermitteln
  if (!empty($parsedurl['query']))
    $documentpath .= '?'.$parsedurl['query'];
  // Port ermitteln
  $port = empty($parsedurl['port']) ? 80 : $port = $parsedurl['port'];

  // Socket öffnen
  $fp = fsockopen ($host, $port, $errno, $errstr, $timeout);
  if (!$fp)
    return null;
  
  // Request senden
  fputs ($fp, "GET {$documentpath} HTTP/1.0\r\nHost: {$host}\r\n\r\n");
  
  // Header auslesen
  $header = '';
  do {
    $line = chop(fgets($fp));
    $header .= $line."\n";
  } while (!empty($line) and !feof($fp));
  // Daten auslesen
  $result = Array();
  while (!feof($fp)) {
    $result[] = fgets($fp);
  }
  // Socket schliessen
  fclose($fp);
  
  // Header auswerten
  preg_match('~^HTTP/1\.\d (?P<status>\d+)~', $header, $matches);
  $status = $matches['status'];
  if ($status == 200) { // OK
    return $result;
  } elseif ($status == 204 or $status == 304) { // No Content | Not modified
    return Array('');
  } elseif (in_array($status, Array(300, 301,302,303,307))) {
    preg_match('~Location: (?P<location>\S+)~', $header, $match);
    $result = my_file($match['location'], $timeout);
  } elseif ($status >= 400) { // Any error
    return false;
  } 
  
  // Ergebnis zurückgeben
  return $result;
}
 
Zuletzt bearbeitet:
Sehr schön :)
Und ich hab mal wieder was gelernt, den P-"Modifier" kannte ich noch gar nicht, sieht aber sehr nützlich aus :)
 
Xgame schrieb:
Und ich hab mal wieder was gelernt, den P-"Modifier" kannte ich noch gar nicht, sieht aber sehr nützlich aus :)
Geht mir auch so. Den werd ich sicherlich in Zukunft immer verwenden, dann hab ich alles übersichtlicher :)
 
erstmal, ihr habt nen klasse script geschrieben, hätte ich selbst nicht besser machen können, aber ich habe noch einen fehler für euch beim rüberschauen gefunden und eine anmerkung/Vorschlag :

Mein Vorschlag :

PHP:
  fputs ($fp, "GET {$documentpath} HTTP/1.0\r\nHost: {$host}\r\n\r\n");
mit einem Useragent verzieren
PHP:
  $request = "GET {$documentpath} HTTP/1.0\r\n";
  $request .= "Host: {$host}\r\n"
  $request .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511  Firefox/1.0.4\r\n\r\n";
  fputs ($fp, $request);

und der Fehler :

PHP:
 if (!empty($parsedurl['query'])) 
   $documentpath .= $parsedurl['query'];

muss natürlich wie folgt lauten

PHP:
 if (!empty($parsedurl['query'])) 
   $documentpath .= '?'.$parsedurl['query'];

MfG

Blacky

Danke für eure FunktionsInspiration
 
Hallo,
Black-Horse schrieb:
mit einem Useragent verzieren
PHP:
$request .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511  Firefox/1.0.4\r\n\r\n";
Das ist so IMHO ziemlich unschön, denn was bringt der User-Agent-Header, wenn man ihm eh nicht glauben kann?
Wenn schon, dann so:
PHP:
$request .= 'User-Agent: '.ini_get('user_agent')."\r\n\r\n";
// Alternative
$request .= 'User-Agent: PHP '.phpversion()."\r\n\r\n";

Gruß,
Xgame
 
Den Fehler beim Query habe ich oben behoben. Danke fürs Melden.

Das mit dem User Agent habe ich bewusst weggelassen, da die Funktion dann noch überladener wäre. Wer's haben will, kann's sich selbst implementieren. Sonst müsste ich auch noch den Referer und andere Dinge mit aufnehmen.
 
Xgame schrieb:
Hallo,

Das ist so IMHO ziemlich unschön, denn was bringt der User-Agent-Header, wenn man ihm eh nicht glauben kann?
Wenn schon, dann so:
PHP:
$request .= 'User-Agent: '.ini_get('user_agent')."\r\n\r\n";
// Alternative
$request .= 'User-Agent: PHP '.phpversion()."\r\n\r\n";

Gruß,
Xgame
naja sorry für ot, aber es macht sinn für boards, die zum beispiel dem user agent googlebot ohne login freigegeben sind um deren content zu lesen ohne sich anzumelden (gerade bei einigen foren, die google indiziert) aber das hat ja auch mit dem eigentlich sinn der funktion nichts mehr zu tun, darum am besten vergessen :)
 
Eben das ist ja der Sinn! Die Boards erkennen den Google-Bot daran, dass er "GoogleBot" als User-Agent sendet. Stell dir vor er würde sich als IE oder Firefox identifizieren, dann ginge das nicht mehr...
 
Es gibt auch Webserver die auf die Übergabe eines User Agent bestehen, wäre also sinnvoll!
 
:(

Ich habe da ein kleines Problem.

Vielleicht stell ich mir einfach nur blöd an, aber bitte helft mir :(

Ich habe jetzt den Script (vom ersten Post) eingebunden, und die variable $url den Link gegeben.

Jetzt bekomm ich den fehler:

Code:
Parse error: syntax error, unexpected T_FUNCTION in /var/www/web******/html/*noch_geheim*/fiftygame/check.php on line 14

Hier nochmal die ersten paar zeilen code:

Code:
<?
/** my_file(URL) ** Aequivalent zu file()
***************************************** (w) tleilax, 2006 ***
* Funktioniert auch bei allow_url_fopen=false, solange Sockets
* geöffnet werden können
*
* Übergabe:
*  $url     - Die auszulesende URL.
*  $timeout - Zeit in Sekunden für den Verbindungsaufbau
* Rückgabe:
*  Array, das alle Zeilen der auszulesenden URL enthält.
***************************************************************/
include('data.php');
$url='https://www.klamm.de/engine/klamm/validate.php?ef_id=12345&ef_pw=test&k_id=20876'
function my_file($url, $timeout=30) {
  // URL zerlegen
  $parsedurl = @parse_url($url);
  // Host ermitteln, ungültigen Aufruf abfangen
  if (empty($parsedurl['host']))
    return null;
(Ich weiß, der Link selbst muss noch abgeändert werden, ist nur zum testen drin... irgendein wert muss ja zurückgegeben werden....)

In der data.php werden die Variablen für den EF-Login definiert ;)
 
In Zeile 14 (aus deinem Code Abschnitt, müsste also im original Script 13 sein, weil da der Fehler ja in 14 ist) fehlt das Semikolon.
 
Hmm.. alles klar, jetzt gibt er... etwas zurück, mit dem ich allerdings nichts anfangen kann... und zwar:

Code:


Soll das so sein?
 
Zuletzt bearbeitet:
Ich bin ganze einfach der Meinung, dass man solche Dinge besser über nen Chat klären kann.

Aber ich schau nochmal (vll. findet ja noch jemand den fehler, der code wurde ja weier nicht verändert)
 
Hmm.. alles klar, jetzt gibt er... etwas zurück, mit dem ich allerdings nichts anfangen kann... und zwar:

Code:


Soll das so sein?

Wenns nicht so sein soll machs weg :LOL: Das ist der BOM einer UTF8 Datei... wahrscheinlich der Datei die du da einleist. Also prüf einfach ob die ersten drei Zeichen "\xEF\xBB\xBF" sind und wenn ja weg damit.
 
bei mir funktioniert das nicht

Hi!

Ich weis, dass Theam ist schon etwas älter, aber da mein Provider vor kurzem allow_url_fopen auf false gesetzt hat, ist es für mich im Moment erst akut geworden.

1. phpinfo() sagt: allow_url_fopen=false UND "Sockets Support" = enabled
somit müsste das Skript ja eigentlich funktionieren, tut es aber nicht!

2. Ich habe zum Testen einmal folgendes Skript geschrieben
[...] hat sich erledigt

Der Request braucht den User-Agent, sonst läuft das Skript vor die Wand und rödelt sich tot.

Als Rückgabe bekomme ich immer:
Bad request!

Your browser (or proxy) sent a request that this server could not understand.
If you think this is a server error, please contact the webmaster.

[...]



Was mache ich falsch, wo liegt das Problem, ich weis nicht weiter!



Vielen Dank schon mal im vorraus!
 
Zuletzt bearbeitet: