function GetURL($s_url, &$s_error, $b_ret_lines = false, $n_depth = 0)
{
    global $php_errormsg, $aServerVars, $sUserAgent;
    global $AUTHENTICATE, $AUTH_USER, $AUTH_PW;
    //
    // open the URL with the same session as we have
    //
    if (session_id() !== "") {
        $s_url = AddURLParams($s_url, session_name() . "=" . urlencode(session_id()));
    }
    if (defined("SID")) {
        $s_url = AddURLParams($s_url, SID);
    }
    $http_get = new HTTPGet($s_url);
    //
    // Determine authentication requirements
    //
    if ($AUTHENTICATE !== "" || $AUTH_USER !== "" || $AUTH_PW !== "") {
        if ($AUTHENTICATE === "") {
            $http_get->SetAuthentication("Basic", $AUTH_USER, $AUTH_PW);
        } else {
            $http_get->SetAuthenticationLine($AUTHENTICATE);
        }
    } else {
        $a_parts = $http_get->GetURLSplit();
        if (isset($a_parts["user"]) || isset($a_parts["pass"])) {
            $s_auth_user = isset($a_parts["user"]) ? $a_parts["user"] : "";
            $s_auth_pass = isset($a_parts["pass"]) ? $a_parts["pass"] : "";
        } else {
            $s_auth_type = isset($aServerVars["PHP_AUTH_TYPE"]) ? $aServerVars["PHP_AUTH_TYPE"] : "";
            $s_auth_user = isset($aServerVars["PHP_AUTH_USER"]) ? $aServerVars["PHP_AUTH_USER"] : "";
            $s_auth_pass = isset($aServerVars["PHP_AUTH_PW"]) ? $aServerVars["PHP_AUTH_PW"] : "";
        }
        if (!isset($s_auth_type) || $s_auth_type === "") {
            $s_auth_type = "Basic";
        }
        if ($s_auth_user !== "" || $s_auth_pass !== "") {
            $http_get->SetAuthentication($s_auth_type, $s_auth_user, $s_auth_pass);
        }
    }
    //
    // set the user agent
    //
    $http_get->SetAgent($sUserAgent);
    //
    // resolve the name now so the DNS cache can be written to the session
    //
    $http_get->Resolve();
    //
    // Since we might be opening a URL within the same session, we can
    // get locks.  So, close the session for writing to prevent this.
    //
    $b_closed = false;
    if (function_exists('session_write_close')) {
        session_write_close();
        $b_closed = true;
        //ob_flush();             // this prevents automatic redirects if $TEMPLATEURL
        // is in use and JavaScript is switched off
    }
    $m_buf = FALSE;
    //FMDebug("Begin read");
    if (($a_lines = $http_get->Read()) === FALSE) {
        $http_get->Close();
        //
        // get the error code and send the appropriate alert
        //
        list($i_error, $i_sys_err, $s_sys_msg) = $http_get->GetError();
        switch ($i_error) {
            case $http_get->nErrParse:
                $s_error = GetMessage(MSG_URL_PARSE);
                break;
            case $http_get->nErrScheme:
                $a_parts = $http_get->GetURLSplit();
                $s_error = GetMessage(MSG_URL_SCHEME, array("SCHEME" => $a_parts["scheme"]));
                break;
            default:
                $s_error = GetMessage(MSG_SOCKET, array("ERRNO" => $i_sys_err, "ERRSTR" => $s_sys_msg, "PHPERR" => isset($php_errormsg) ? $php_errormsg : ""));
                break;
        }
    } else {
        $http_get->Close();
        //
        // check the HTTP response for actual status.  Anything outside
        // 200-299 is a failure, but we also handle redirects.
        //
        list($i_http_code, $s_http_status) = $http_get->GetHTTPStatus();
        if ($i_http_code < 200 || $i_http_code > 299) {
            switch ($i_http_code) {
                case 300:
                    // multiple choices (we'll take the first)
                // multiple choices (we'll take the first)
                case 301:
                    // moved permanently
                // moved permanently
                case 302:
                    // found
                // found
                case 303:
                    // see other
                // see other
                case 307:
                    // temporary redirect
                    //
                    // a "location" header must be present for us to continue
                    // In the case of infinite redirects, we need to stop.
                    // So, we limit to a maximum of 10 redirects.
                    //
                    if ($n_depth < 10) {
                        if (($s_location = $http_get->FindHeader("location")) !== false) {
                            FMDebug("Redirect from '{$s_url}' to '{$s_location}'");
                            $m_buf = GetURL($s_location, $s_error, $b_ret_lines, $n_depth + 1);
                            $b_closed = false;
                            break;
                        }
                        FMDebug("Redirect FAILED - no location header");
                    } else {
                        FMDebug("Redirect FAILED depth={$n_depth}");
                    }
                    // FALL THRU
                // FALL THRU
                default:
                    $s_error = GetMessage(MSG_GETURL_OPEN, array("STATUS" => $s_http_status));
                    break;
            }
        } elseif ($b_ret_lines) {
            $m_buf = $a_lines;
        } else {
            //
            // return lines as one big string buffer
            //
            $m_buf = implode("", $a_lines);
        }
    }
    //
    // re-open our session
    //
    if ($b_closed) {
        session_start();
    }
    return $m_buf;
}
function GetURL($s_url, &$s_error)
{
    global $php_errormsg, $aServerVars, $sUserAgent;
    global $AUTHENTICATE, $AUTH_USER, $AUTH_PW;
    //
    // open the URL with the same session as we have
    //
    if (session_id() !== "") {
        $s_url = AddURLParams($s_url, session_name() . "=" . urlencode(session_id()));
    }
    if (defined("SID")) {
        $s_url = AddURLParams($s_url, SID);
    }
    $http_get = new HTTPGet($s_url);
    //
    // Determine authentication requirements
    //
    if ($AUTHENTICATE !== "" || $AUTH_USER !== "" || $AUTH_PW !== "") {
        if ($AUTHENTICATE === "") {
            $http_get->SetAuthentication("Basic", $AUTH_USER, $AUTH_PW);
        } else {
            $http_get->SetAuthenticationLine($AUTHENTICATE);
        }
    } else {
        $a_parts = $http_get->GetURLSplit();
        if (isset($a_parts["user"]) || isset($a_parts["pass"])) {
            $s_auth_user = isset($a_parts["user"]) ? $a_parts["user"] : "";
            $s_auth_pass = isset($a_parts["pass"]) ? $a_parts["pass"] : "";
        } else {
            $s_auth_type = isset($aServerVars["PHP_AUTH_TYPE"]) ? $aServerVars["PHP_AUTH_TYPE"] : "";
            $s_auth_user = isset($aServerVars["PHP_AUTH_USER"]) ? $aServerVars["PHP_AUTH_USER"] : "";
            $s_auth_pass = isset($aServerVars["PHP_AUTH_PW"]) ? $aServerVars["PHP_AUTH_PW"] : "";
        }
        if (!isset($s_auth_type) || $s_auth_type === "") {
            $s_auth_type = "Basic";
        }
        if ($s_auth_user !== "" || $s_auth_pass !== "") {
            $http_get->SetAuthentication($s_auth_type, $s_auth_user, $s_auth_pass);
        }
    }
    //
    // set the user agent
    //
    $http_get->SetAgent($sUserAgent);
    //
    // resolve the name now so the DNS cache can be written to the session
    //
    $http_get->Resolve();
    //
    // Since we might be opening a URL within the same session, we can
    // get locks.  So, close the session for writing to prevent this.
    //
    if (function_exists('session_write_close')) {
        session_write_close();
        ob_flush();
        // probably a good idea
    }
    $m_buf = FALSE;
    //FMDebug("Begin read");
    if (($a_lines = $http_get->Read()) === FALSE) {
        //
        // get the error code and send the appropriate alert
        //
        list($i_error, $i_sys_err, $s_sys_msg) = $http_get->GetError();
        switch ($i_error) {
            case $http_get->nErrParse:
                $s_error = GetMessage(MSG_URL_PARSE);
                break;
            case $http_get->nErrScheme:
                $a_parts = $http_get->GetURLSplit();
                $s_error = GetMessage(MSG_URL_SCHEME, array("SCHEME" => $a_parts["scheme"]));
                break;
            default:
                $s_error = GetMessage(MSG_SOCKET, array("ERRNO" => $i_sys_err, "ERRSTR" => $s_sys_msg, "PHPERR" => isset($php_errormsg) ? $php_errormsg : ""));
                break;
        }
    } else {
        //
        // check the HTTP response for actual status.  Anything outside
        // 200-299 is a failure
        //
        list($i_http_code, $s_http_status) = $http_get->GetHTTPStatus();
        if ($i_http_code < 200 || $i_http_code > 299) {
            $s_error = GetMessage(MSG_GETURL_OPEN, array("STATUS" => $s_http_status));
        } else {
            //
            // return lines as one big string buffer
            //
            $m_buf = implode("", $a_lines);
        }
    }
    $http_get->Close();
    //
    // re-open our session
    //
    session_start();
    return $m_buf;
}