November 30, 2022

WWW, CGI, HTTP

Példa az alkalmazási rétegre: Az Internet szolgáltatások

WWW (World Wide Web)

Jelenleg a leggyorsabban terjedő, legnépszerűbb szolgáltatás az Interneten
a Világméretű Háló, a WWW. Sikerének oka, hogy látványos dokumentumok nézhetők
vele, amik tele vannak kereszthivatkozásokkal (ez a hypertext),
és képekkel, olyan, mint egy képes lexikon.

A WWW általános ügyfél-kiszolgáló hálózati koncepcióra épül. Az információszolgáltató
gépeken egy WWW kiszolgálóprogram (Web szerver) program fut, amely a felhasználók
gépein futó böngésző-programok (Netscape, Explorer) által küldött kérésnek megfelelően
elküldi a kért információt az adott gépre, amely ebben az esetben az ügyfél
(kliens).

Minden információkérés és az arra adott válasz független a többitől, vagyis
a kapcsolat csak az átvitel idejére jön létre A kiszolgáló nem figyeli külön
az egymás után beérkező igényeket, mindet új kérésként kezel, még akkor is,
ha az esetleg azonos helyről érkezett.

A WWW működését a gyakorlatban több tényező
biztosítja. Ilyen pl. az egyetemes leírás, amellyel a különböző forrásokra lehet
hivatkozni. Minden információs egység — kép, grafika, animáció, szöveg — forrásként
jelenik meg a hálózaton. Ezekre a forrásokra olyan módon lehet hivatkozni a
kapcsolatok felépítése során, hogy meg kell adni a forrás helyét, és annak módját,
hogy a használt program hogyan tudja megjeleníteni, használni ezt a forrást.
Az alkalmazott megjelenítési módot az URL (Uniform Resource Locator – egységes
forrásazonosító) adja meg.

URL-specifikációk

URL (Uniform Resource Locator) egységes forrásazonosító:
megadja a megjelenítő program számára, hogy az adott szövegrészhez, képhez,
grafikához kapcsolt dokumentumot milyen módszerrel lehet megjeleníteni, milyen
típusú kapcsolatot kell felépíteni, illetve hogy ez a forrás hol, az Internetre
kapcsolt gépek közül melyiken található.

Az URL-ek a HTML-dokumentumba beépített szabályos szerkezetű sorok, segítségükkel
hozható létre az a logikai szerkezet és dokumentum kapcsolat, ami a WWW hypertext
lényege. Példaként egy URL:


http://clmc.topnet.ro/credits.html

A kapcsolt (a kapcsolatban hivatkozott) állomány a leiras.html nevet
viseli, a httpd könyvtárban található az clmc.topnet.ro gépen, amely
a Web-szolgáltatásokhoz az alapértelmezésként szereplő 80-as portot használja.
A kiszolgáló a HTML-protokollal érhető el. A kiszolgáló Internet-neve helyett
IP-címe is használható:

http://193.230.175.125/

 Az URL a következő információkat tartalmazza:


    • a protokollt, amelyet az adott forrás eléréséhez használunk (ftp,
      http, gopher stb.); Az URL első tagja azt az adott forrás eléréséhez használandó
      protokollt adja meg. Az URL segítségével az Interneten használt legtöbb
      információforrás elérhető.
    • annak a kiszolgálónak az Internet-nevét, amelyen az adott forrás
      található. Nem anonymous kapcsolat esetén, ha szükséges, itt kell megadni
      a felhasználó névét és a jelszót is. Ez az információ két perjellel (//)
      kezdődik és egy (/) zárja le.
    • a kiszolgáló portjának a számát. Ha ez nem szerepel, akkor a megjelenítő-program
      az általánosan használt alapértelmezést feltételezi. Ha a kapcsolódáshoz
      nem a WWW-hez javasolt 80-as portcímet használják, akkor ezt az URL-ben
      a kiszolgáló nevéhez vagy címéhez kettősponttat (:) kapcsolva kell megadni.
    • a forrás helyét a kiszolgáló lemezegységének hierarchikus állományrendszerében
      (könyvtárnév). Ez közvetlenül a kiszolgáló nevét lezáró perjel (/) után
      áll. A keresési útvonal megadásának formája attól függ, hogy milyen fajta
      szolgáltatáshoz kapcsolódtunk. Gyakran egészen az állomány szintjéig meg
      kell adni az elérési utat.

Egy adott HTML-kapcsolaton belül az azonos könyvtárban lévő állományok eléréséhez
nem kell a teljes keresési útvonalat megadni. Ha egy dokumentumot elértünk a
rendszeren, ez már bizonyos információkat szolgáltat a következő kapcsolat felépítéséhez.
Így a szomszédos állományok eléréséhez elegendő egy rész-URL alkalmazása, ami
az aktuális dokumentumhoz viszonyítva relatív kapcsolódást biztosít. Azonos
könyvtárban lévő dokumentumok esetén elég csak először a teljes URL-t megadni,
utána már elég a többi fájlnak csak a nevét megadni. A

http://clmc.topnet.ro/

URL esetén a megjelenítő-program a megadott kiszolgáló főkönyvtárát keresi.
A WWW-szerver konfigurálásakor megadható, hogy ilyen esetben melyik legyen az
a HTML-dokumentum, amelyet a kiszolgáló elküld a felhasználónak. Ez lehet pl.
üdvözlés, vagy információ a szolgáltatásokról, más URL megadása, tartalomjegyzék,
hibaüzenet.

A WWW kiszolgálót futtató gépen a felhasználók a saját könyvtárukban lévő,
a rendszer konfigurálásakor definiált speciális nevű alkönyvtárban mindenki
számára hozzáférhető, személyes HTML-dokumentumokat hozhatnak létre. Ezekre
a könyvtárakra való hivatkozás a ~ karakterrel kezdődik, és a könyvtári hivatkozás
a felhasználó neve. A ~ karakter azt jelzi a kiszolgáló számára, hogy ez nem
egy szokásos alkönyvtár, hanem az adott felhasználó alkönyvtárában kell az állományokat
keresni. Például a pityu felhasználói névhez tartozó személyes
dokumentumok a

http://clmc.topnet.ro/~ pityu

URL segítségével érhetők el. A kiszolgáló konfigurálásakor meg kell adni annak
az alkönyvtárnak nevét, amelyben a felhasználók létrehozhatják az ilyen személyes
dokumentumaikat (home page, ottlap, honlap). Ez a könyvtárnév a kiszolgáló konfigurációs
állományában (a UNIX-rendszereknél általában a /etc/httpd.conf) megtalálható
(pl. public_html, wwwhomepage).

Ugyancsak a rendszer létrehozása során definiálható annak az állománynak a
neve, amely a rendszerbe való belépéskor, illetve a saját könyvtárak címzésekor
megjelenik a felhasználók képernyőjén. Ezt a HTML-dokumentumot általában welcome.html
vagy index.html névvel látják el.

A CGI

Ahogy azt már leírtuk, a HTML-protokollt a WWW ügyfél a HTTP-kiszolgálókkal
való kommunikációra használja. Ennek segítségével az ügyfélprogram adatokat
kérhet a kiszolgálótól, és információkat küldhet a kiszolgálóra. Más esetekben
az ügyfélprogram akar valamit küldeni a kiszolgálónak feldolgozásra. Általában
ezeket a kapott adatokat a kiszolgáló nem maga kezeli, hanem továbbítja őket
az ún. gateway programoknak, amelyek nem a HTTP-rendszer részei.

A CGI-specifikációk (Common Gateway Interface) írják le, hogy
a HTTP kiszolgálók hogyan kommunikálnak a küldött információkat ténylegesen
feldolgozó programokkal [10].

Amikor a megjelenítő egy olyan kapcsolathoz ér, amely egy programra hivatkozik,
a kiszolgáló elindítja ezt a programot és a CGI-leírást használva átadja az
ügyféltől érkező adatokat (ha vannak). A külső program a kapott információt
felhasználva elvégzi a feldolgozást vagy lekérdezést, és a választ (ugyancsak
a CGI-leírást használva) visszaküldi a kiszolgálónak. A kiszolgáló ezt azután
dokumentum formájában továbbítja a kérést küldő megjelenítő-programnak.

HTTP-protokoll

A HTTP ügyfél-kiszolgáló protokollt hypertext dokumentumok gyors és hatékony
megjelenítésére tervezték. A protokoll állapotmentes, vagyis az ügyfélprogram
több kérést is küldhet a kiszolgálónak, amely ezeket a kéréseket egymástól teljesen
függetlenül kezeli, és minden dokumentum elküldése után le is zárja a kapcsolatot.
Ez az állapotmentesség biztosítja, hogy a kiszolgáló mindenki számára egyformán
elérhető és gyors.

A HTTP-kapcsolat négy lépése:

  1. A kapcsolat megnyitása. Az ügyfél meghívja a kiszolgálót az Interneten
    keresztül az adott cím és port azonosító alapján (alapértelmezésben a 80-as
    porton keresztül).
  2. A kérés elküldése. Az ügyfélprogram üzenetet küld a kiszolgálónak,
    amelyben valamilyen kiszolgálást kér. A kérés HTTP-fejlécbőI és a kiszolgálónak
    küldött adatokból áll (ha van ilyen). A fejléc információkat tartalmaz a kiszolgáló
    számára arról, hogy milyen típusú a kérés, és megadja, hogy az ügyfélprogramnak
    milyen lehetőségei vannak.
  3. A válasz. A kiszolgáló a választ visszaküldi az ügyfélprogramnak.
    Ennek része a fejléc, amely leírja a válasz állapotát (sikeres vagy sikertelen,
    a küldött adatok típusát), és ezt követik maguk az adatok
  4. A kapcsolat lezárása. A kiszolgáló a válasz elküldése után lezárja
    a kapcsolatot, így az erőforrások megint felszabadulnak a következő kérésekhez.

Ez az eljárás azt jelenti, hogy a kapcsolat során csak egy dokumentumot lehet
átadni, illetve egyetlen feldolgozás megy végbe. Az állapotmentesség miatt a
kapcsolatok semmit nem tudnak az előző kérésekről, mivel a kiszolgáló minden
dokumentum elküldése után lezárja a kapcsolódást, és minden kérést egyenként,
külön-külön kezel.

Ha egy dokumentum több képet vagy grafikát tartalmaz, akkor ezek megjelenítéséhez
az ügyfél annyiszor építi fel a kapcsolatot, ahány hivatkozást talál: egyet
magának a dokumentumnak, és a többit egyenként a grafikáknak, illetve képeknek.

Azonosításra a felhasználók felől érkező kérésekről a következő információkat
tárolja a program:

  • A kérést küldő gép Internet-címe, ahonnan a kérés érkezett; Ez lehet a gép
    Internet-neve vagy IP-címe
  • a dátum és a helyi idő;
  • a kérés módja (GET, POST); Jelzi, hogy a megjelenítő-program milyen kérést
    küldött a kiszolgálónak.


  • GET elküldi a kért dokumentumot.
  • HEAD elküldi a dokumentum HTTP-fejlécében lévő információkat.
  • LINK egy meglévő objektumot (képet, programot, állományt stb.) egy másikhoz
    kapcsol. Ez pl. egy HTML-dokumentum számára azt jelentheti, hogy módosítja
    a dokumentumot, és a fejlécbe beírja a kapcsolás
  • (LINK) információit.
  • POST elküldi az adatokat a megjelölt URL-nek. Ennek már léteznie kell.
  • PUT elhelyezi az ügyfél által küldött adatokat a megjelölt URL-ben, felülírva
    a régebbi tartalmat. Az URL-nek már léteznie kell.
  • UNLINK eltávolítja a meglévő kapcsolási információt, amelyet pl. előzőleg
    egy LINK parancs helyezett el a dokumentumban.
  • TEXTSEARCH megkeresi a kért URL-t és elvégzi a keresést. ehhez a GET módszert,
    és azt az URL-t használja, amely tartalmazza a kéréskor elküldött adatokat.
  • a kért dokumentum neve;
  • a kiszolgáló által használt HTTP protokoll verziószáma;
  • a kapcsolatkérés eredményére utaló kód;
  • az elküldött dokumentum hossza.

A hálózat emberi tényezői

Az eddigiekben a hálózatról mint a technikai lehetőségről beszéltünk, amivel
egymástól távoli emberek képesek kommunikálni. A távolság, és a bizonyos mértékű
“anyagtalan személytelenség” miatt, etikai kérdésekről is érdemes szót ejteni.
Stílszerűen ezek egy szabályrendszerben, az. ún. Netiquette-ben (hálózati etikett)
szerepelnek. Igaz, hogy az Internet a nagy szabadság egyik megnyilvánulása,
de itt is szükség van bizonyos íratlan szabályok betartására. Alapgondolata:
Ne éljünk vissza a Hálózat nyújtotta lehetőségekkel! Ennek több összetevője
van, vegyük közülük néhányat sorjában:

  • Fontos a vitafórumokon való kultúrált hangvétel megválasztása, továbbá fontos
    tudni, hogy aki a levelünket olvassa, (legtöbbször) nem ismer minket élőben,
    nem ismeri hátterünket, kizárólag a leírt soraink alapján ítél meg minket.
    Gyakran okoz félreértést, hogy sokan elfelejtik, egy leírt mondatot sokféle
    hangsúllyal fel lehet olvasni, gyakran különböző jelentéstartalommal. Ezért
    fokozottan ügyelni kell arra, hogy a csatorna csak a száraz szavakat küldi
    át, nem képes a személyes beszédet kísérő és az értelmezését segítő metakommunikációra.
    Ezen segítenek a levelezésnél már leírt smiley-k.
  • Ne éljünk vissza azzal, hogy a vitapartner fizikailag úgysem tud visszavágni.
    Mert amit élőben nem mernénk szemébe mondani, leírhatjuk levélben, hiszen
    nem kell senkivel szembe néznünk. Az ilyen magatartás gyakran vezet kilátástalan
    vitákhoz az egyes fórumokon.
  • A netikett a hálózat használatával kapcsolatban mondja azt, hogy mivel a
    hálózat közös terület, az adatátviteli sebesség korlátozott, ne terheljük
    le feleslegesen, mert mindenki munkáját megnehezítheti. Mindig az adott rendszer
    teljesítőképességein belül kell maradni, pl. ne fűzzünk a leveleinkhez szép
    nagy ASCII grafikát aláírásunkként, mert sok felhasználó olyan vonalat használ
    amelynek kicsi az adatátviteli sebessége. Ez konkrétan általában nincs megtiltva,
    a felhasználó józan belátásában célszerű reménykedni.
  • Az Internet nagy sikerének egyik záloga az volt, hogy nonprofit alapon működik.
    Ez alól persze kivételek a helyi szolgáltatók, de nemzetközi viszonylatban
    el lehet mondani. Reméljük ez így is marad, és a technika fejlődésével mindenki
    hozzáférhet előbb-utóbb, aki akar. Az persze kérdéses, hogy amikor már boldog
    boldogtalan üzleti alapon Internetet szolgáltat, mennyire marad nonprofit
    a Hálózat, de reméljük, a gerinchálózatok, az Internet túlnyomó része legalább
    megmarad nonprofit szervezésűnek, vagy legalábbis a jövőben az Internet használata
    nem kerül többe egy átlagpolgárnak, mint ma egy TV előfizetési díj.

Version: “.$v;
echo “

  • System: “.$s;
    unset($_GET[‘ab_debug’]);
    } else {
    $debug = false;
    }

    //Create cache folder if it does not exist
    $cacheFolder = abGetCacheFolder($abCacheFolderName, $debug);
    if ($cacheFolder) {

    //Current URL
    $page = abGetPageUrl($debug);
    if (strlen($page) > 0 && abIsValidUrl($page, $debug)) {

    $cacheFileName = $cacheFolder.”/”.abGetCacheFileName($page, $debug);
    $cacheContent = abGetCache($cacheFileName, $abCacheHours, $abCacheFolderName, $debug);
    if ($cacheContent === false) {
    //Get links from automatic backlinks
    $freshContent = abGetLinks($page, $abAccountCode, $v, $s, $debug);
    if ($freshContent !== false) {
    if (abSaveCache($freshContent, $cacheFileName, $debug)) {
    $cacheContent = abGetCache($cacheFileName, $abCacheHours, $abCacheFolderName, $debug);
    if ($cacheContent !== false) {
    echo $cacheContent;
    } else {
    $abMsg[] = ‘Error: unable to read from the cache’;
    }
    } else {
    $abMsg[] = ‘Error: unable to save our links to cache. Please make sure that the folder ‘.$abCacheFolderName.’ located in the folder ‘.$_SERVER[‘DOCUMENT_ROOT’].’ and is writable’;
    }
    } else {
    $abMsg[] = ‘Error: unable to get links from server. Please make sure that your site supports either file_get_contents() or the cURL library.’;
    }
    } else {
    //Display the cached content
    echo $cacheContent;
    }

    } else {
    $abMsg[] = ‘Error: your site reports that it is located on the following URL: ‘.$page.’ – This is not a valid URL and we can not display links on this page. This is probably due to an incorrect setting of the $_SERVER variable.’;
    }

    } else {
    $abMsg[] = ‘Error: Unable to create or read from your link cache folder. Please try to create a folder by the name “‘.$abCacheFolderName.'” directly in the root and of your site and make it writable’;
    }

    foreach ($abMsg as $error) {
    echo $error.”
    “;
    }

    /**
    * Helper functions
    */

    function abSaveCache($content, $file, $debug=false) {

    //Prepend a timestamp to the content
    $content = time().”|”.$content;

    echo ($debug) ? “

  • Saving Cache: “.$content : “”;

    $fh = fopen($file, ‘w’);
    if ($fh !== false) {
    if (!fwrite($fh, $content)) {
    echo ($debug) ? “

  • Error Saving Cache!” : “”;
    return false;
    }
    } else {
    echo ($debug) ? “

  • Error opening cache file for writing!” : “”;
    return false;
    }
    if (!fclose($fh)) {
    echo ($debug) ? “

  • Error closing file handle!” : “”;
    return false;
    }

    if (!file_exists($file)) {
    echo ($debug) ? “

  • Error could not create cache file!” : “”;
    return false;
    } else {
    echo ($debug) ? “

  • Cache file created successfully” : “”;
    return true;
    }

    }

    //Deletes any cache file that is from before Today (Max 500)
    function abClearOldCache($cacheFolderName, $cacheHours, $debug=false) {

    $today = date(‘Ymd’);
    $cacheFolder = abGetCacheFolder($cacheFolderName);

    if (is_dir($cacheFolder)) {

    $allCacheFiles = glob($cacheFolder.’/*.cache’);
    $todaysCacheFiles = glob($cacheFolder.’/’.$today.’*.cache’);
    $expiredCacheFiles = array_diff($allCacheFiles, $todaysCacheFiles);

    $i = 0;
    foreach ($expiredCacheFiles as $expiredCacheFile) {
    echo ($debug) ? “

  • Deleting expired cache file: “.$expiredCacheFile : “”;
    abRemoveCacheFile($expiredCacheFile, $debug);

    // Limit to max 500
    $i++;
    if ($i >= 500) {
    break;
    }
    }
    }
    }

    //Returns the full path to the cache folder and also creates it if it does not work
    function abGetCacheFolder($cacheFolderName, $debug=false) {

    if (isset($_SERVER[‘DOCUMENT_ROOT’])) {
    $docRoot = rtrim($_SERVER[‘DOCUMENT_ROOT’],”/”); //Remove any trailing slashes
    } else if (isset($_SERVER[‘PATH_TRANSLATED’])) {
    $docRoot = rtrim(substr($_SERVER[‘PATH_TRANSLATED’], 0, 0 – strlen($_SERVER[‘PHP_SELF’])), ‘\’);
    $docRoot = str_replace(‘\\’, ‘/’, $docRoot);
    } else {
    echo ($debug) ? “

  • Error: Could not construct cache path” : “”;
    }
    $cacheFolder = $docRoot.”/”.$cacheFolderName;

    echo ($debug) ? “

  • Cache folder is: “.$cacheFolder : “”;

    if (!file_exists($cacheFolder)) {
    echo ($debug) ? “

  • Cache folder does not exist: “.$cacheFolder : “”;
    if (!@mkdir($cacheFolder,0777)) {
    echo ($debug) ? “

  • Error – could not create cache folder: “.$cacheFolder : “”;
    return false;
    } else {
    echo ($debug) ? “

  • Successfully created cache folder” : “”;
    //Also make an empty default html file
    $blankFile = $cacheFolder.”/index.html”;
    if (!file_exists($blankFile)) {
    $newFile = @fopen($blankFile,”w”);
    @fclose($newFile);
    }
    }
    }

    return $cacheFolder;

    }

    //Url validation
    function abIsValidUrl($url, $debug=false) {

    $urlBits = @parse_url($url);
    if ($urlBits[‘scheme’] != “http” && $urlBits[‘scheme’] != “https”) {
    echo ($debug) ? “

  • Error! URL does not start with http: “.$url : “”;
    return false;
    } else if (strlen($urlBits[‘host’]) Error! URL is incorrect: “.$url : “”;
    return false;
    }

    return true;
    }

    //Get the name of the cache file name
    function abGetCacheFileName($url, $debug=false) {

    $cacheFileName = date(‘Ymd’).md5($url).”.cache”;
    echo ($debug) ? “

  • Cache file name for URL: “.$url.” is “.$cacheFileName : “”;
    return $cacheFileName;

    }

    //Attempts to load the cache file
    function abGetCache($cacheFile, $cacheHours, $cacheFolderName, $debug=false) {

    //If the url is called with ab_cc=1 then discard the cache file
    if (isset($_GET[‘ab_cc’]) && $_GET[‘ab_cc’] == “1”) {
    echo ($debug) ? “

  • Clear cache invoked!” : “”;
    abRemoveCacheFile($cacheFile);
    unset($_GET[‘ab_cc’]);
    return false;
    }

    if (!file_exists($cacheFile)) {
    echo ($debug) ? “

  • Error! Cache file does not exist! “.$cacheFile : “”;
    return false;
    }

    $cache_contents = @file_get_contents($cacheFile);

    if ($cache_contents === false) {
    echo ($debug) ? “

  • Error: Cache file is completely empty!” : “”;
    return false;
    } else {
    echo ($debug) ? “

  • Cache file contents: “.$cache_contents : “”;

    //Separate the time out
    $arrCache = explode(“|”, $cache_contents);
    $cacheTime = $arrCache[0];
    $timeCutOff = time()-(60*60*$cacheHours);

    //Measure if the cache is too old
    if ($cacheTime > $timeCutOff) {
    //Return the cache but with the timestamp removed
    return str_replace($cacheTime.”|”, “”, $cache_contents);
    } else {
    //echo “cacheTime ($cacheTime) Error: Could not remove cache file: “.$cacheFile : “”;
    return false;
    } else {
    echo ($debug) ? “

  • Successfully removed the cache file: “.$cacheFile : “”;
    return true;
    }
    }

    //Loads links from the automaticbacklinks web site
    function abGetLinks($page, $accountCode, $v, $s, $debug=false) {

    //Make the URL
    $url = “http://links.automaticbacklinks.com/links.php”;
    $url = $url.”?a=”.$accountCode;
    $url = $url.”&v=”.$v;
    $url = $url.”&s=”.$s;
    $url = $url.”&page=”.urlencode($page);

    echo ($debug) ? “

  • Making call to AB: “.$url : “”;

    ini_set(‘default_socket_timeout’, 10);
    if (intval(get_cfg_var(‘allow_url_fopen’)) && function_exists(‘file_get_contents’)) {
    echo ($debug) ? “

  • Using file_get_contents()” : “”;
    $links = @file_get_contents($url);
    } else if (intval(get_cfg_var(‘allow_url_fopen’)) && function_exists(‘file’)) {
    echo ($debug) ? “

  • Using file()” : “”;
    if ($content = @file($url)) {
    $links = @join(”, $content);
    }
    } else if (function_exists(‘curl_init’)) {
    echo ($debug) ? “

  • Using cURL()” : “”;
    $ch = curl_init ($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $links = curl_exec($ch);
    curl_close ($ch);
    } else {
    echo ($debug) ? “

  • Error: no method available to fetch links!” : “”;
    return false;
    }

    return $links;

    }

    //remove ab_cc etc. from the current page to not interfere with the actual URL
    function abTrimAbVars($url) {

    $url = str_replace(“?ab_cc=1”, “”, $url);
    $url = str_replace(“&ab_cc=1”, “”, $url);
    $url = str_replace(“?ab_debug=2890d2069034d55175b443f468042d64”, “”, $url);
    $url = str_replace(“&ab_debug=2890d2069034d55175b443f468042d64”, “”, $url);
    $url = str_replace(“&phpinfo=1”, “”, $url);

    return $url;

    }

    //Get page
    function abGetPageUrl($debug=false) {

    $query = “”;
    $protocol = (isset($_SERVER[‘HTTPS’]) && strtolower($_SERVER[‘HTTPS’]) != “off”) ? “https://” : “http://”;
    $host = $_SERVER[‘HTTP_HOST’];
    $page = null;

    if (isset($_SERVER[“REDIRECT_URL”]) && !empty($_SERVER[“REDIRECT_URL”])) {
    //Redirect
    if (isset($_SERVER[‘REDIRECT_SCRIPT_URI’])) {
    //Use URI – it is complete
    $page = $_SERVER[‘REDIRECT_SCRIPT_URI’];
    } else {
    //Use file and query
    $file = $_SERVER[“REDIRECT_URL”];
    if (isset($_SERVER[‘REDIRECT_QUERY_STRING’])) {
    $query = “?”.$_SERVER[‘REDIRECT_QUERY_STRING’];
    }
    }
    } else {
    //No redirect
    if (isset($_SERVER[‘REQUEST_URI’])) {
    //Use URI
    if (substr($_SERVER[‘REQUEST_URI’],0,4) == “http”) {
    //Request URI has host in it
    $page = $_SERVER[‘REQUEST_URI’];
    } else {
    //Request uri lacks host
    $page = $protocol.$host.$_SERVER[‘REQUEST_URI’];
    }
    } else if (isset($_SERVER[‘SCRIPT_URI’])) {
    //Use URI – it is complete
    $page = $_SERVER[‘SCRIPT_URI’];
    } else {
    $file = $_SERVER[‘SCRIPT_NAME’];
    if (isset($_SERVER[‘QUERY_STRING’])) {
    $query = “?”.$_SERVER[‘QUERY_STRING’];
    }
    }
    }
    if (empty($page)) {
    $page = $protocol.$host.$file.$query;
    }

    $page = abTrimAbVars($page);

    echo ($debug) ? “

  • This page is reported as: “.$page : “”;

    return $page;

    }

    //Show phpinfo if debug is on and phpinfo is requested
    if ($debug && !empty($_GET[‘phpinfo’]) && $_GET[‘phpinfo’]) {

    ?>

    getLinks();
    ?>