Skip to content

Instantly share code, notes, and snippets.

@maquejp
Last active August 29, 2015 14:27
Show Gist options
  • Save maquejp/15f8bcb534fc9ea7d1ec to your computer and use it in GitHub Desktop.
Save maquejp/15f8bcb534fc9ea7d1ec to your computer and use it in GitHub Desktop.
CS50x lookup function adapted for behind reverse proxies with authentication
<?php
/**
* functions.php
*
* Computer Science 50
* Problem Set 7
*
* Helper functions.
*/
require_once("constants.php");
/**
* Apologizes to user with message.
*/
function apologize($message)
{
render("apology.php", ["message" => $message]);
exit;
}
/**
* Facilitates debugging by dumping contents of variable
* to browser.
*/
function dump($variable)
{
require("../templates/dump.php");
exit;
}
/**
* Logs out current user, if any. Based on Example #1 at
* http://us.php.net/manual/en/function.session-destroy.php.
*/
function logout()
{
// unset any session variables
$_SESSION = [];
// expire cookie
if (!empty($_COOKIE[session_name()]))
{
setcookie(session_name(), "", time() - 42000);
}
// destroy session
session_destroy();
}
/**
* Returns a stock by symbol (case-insensitively) else false if not found.
*/
function lookup($symbol)
{
// reject symbols that start with ^
if (preg_match("/^\^/", $symbol))
{
return false;
}
// reject symbols that contain commas
if (preg_match("/,/", $symbol))
{
return false;
}
// headers for proxy servers
$headers = [
"Accept" => "*/*",
"Connection" => "Keep-Alive",
"User-Agent" => sprintf("curl/%s", curl_version()["version"])
];
// open connection to Yahoo
$context = stream_context_create([
"http" => [
"header" => implode(array_map(function($value, $key) {return sprintf("%s: %s\r\n", $key, $value);}, $headers, array_keys($headers))),
"method" => "GET"
]
]);
$fopenmethod = 0;
$handle = @fopen("http://download.finance.yahoo.com/d/quotes.csv?f=snl1&s={$symbol}", "r", false, $context);
if ($handle === false)
{
$handle = curlFile("http://download.finance.yahoo.com/d/quotes.csv?f=snl1&s={$symbol}","http://proxy","proxyport","uuid:puid");
$fopenmethod = 1;
if ($handle === false)
{
// trigger (big, orange) error
trigger_error("Could not connect to Yahoo!", E_USER_ERROR);
exit;
}
}
// download first line of CSV file
if ($fopenmethod === 0)
{
$data = fgetcsv($handle);
if ($data === false || count($data) == 1)
{
return false;
}
// close connection to Yahoo
fclose($handle);
}
else if ($fopenmethod === 1)
{
// error if name of the symbol contains a ,
// $data = explode(",",$handle);
$data = str_getcsv($handle);
}
// ensure symbol was found
if ($data[2] === "N/A" || $data[2] === "0.00")
{
return false;
}
// return stock as an associative array
return [
"symbol" => $data[0],
"name" => $data[1],
"price" => floatval($data[2])
];
}
/**
* Executes SQL statement, possibly with parameters, returning
* an array of all rows in result set or false on (non-fatal) error.
*/
function query(/* $sql [, ... ] */)
{
// SQL statement
$sql = func_get_arg(0);
// parameters, if any
$parameters = array_slice(func_get_args(), 1);
// try to connect to database
static $handle;
if (!isset($handle))
{
try
{
// connect to database
$handle = new PDO("mysql:dbname=" . DATABASE . ";host=" . SERVER, USERNAME, PASSWORD);
// ensure that PDO::prepare returns false when passed invalid SQL
$handle->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch (Exception $e)
{
// trigger (big, orange) error
trigger_error($e->getMessage(), E_USER_ERROR);
exit;
}
}
// prepare SQL statement
$statement = $handle->prepare($sql);
if ($statement === false)
{
// trigger (big, orange) error
trigger_error($handle->errorInfo()[2], E_USER_ERROR);
exit;
}
// execute SQL statement
$results = $statement->execute($parameters);
// return result set's rows, if any
if ($results !== false)
{
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
else
{
return false;
}
}
/**
* Redirects user to destination, which can be
* a URL or a relative path on the local host.
*
* Because this function outputs an HTTP header, it
* must be called before caller outputs any HTML.
*/
function redirect($destination)
{
// handle URL
if (preg_match("/^https?:\/\//", $destination))
{
header("Location: " . $destination);
}
// handle absolute path
else if (preg_match("/^\//", $destination))
{
$protocol = (isset($_SERVER["HTTPS"])) ? "https" : "http";
$host = $_SERVER["HTTP_HOST"];
header("Location: $protocol://$host$destination");
}
// handle relative path
else
{
// adapted from http://www.php.net/header
$protocol = (isset($_SERVER["HTTPS"])) ? "https" : "http";
$host = $_SERVER["HTTP_HOST"];
$path = rtrim(dirname($_SERVER["PHP_SELF"]), "/\\");
header("Location: $protocol://$host$path/$destination");
}
// exit immediately since we're redirecting anyway
exit;
}
/**
* Renders template, passing in values.
*/
function render($template, $values = [])
{
// if template exists, render it
if (file_exists("../templates/$template"))
{
// extract variables into local scope
extract($values);
// render header
require("../templates/header.php");
// render template
require("../templates/$template");
// render footer
require("../templates/footer.php");
}
// else err
else
{
trigger_error("Invalid template: $template", E_USER_ERROR);
}
}
function curlFile($url,$proxy_ip,$proxy_port,$loginpassw)
{
//$loginpassw = 'username:password';
//$proxy_ip = '192.168.1.1';
//$proxy_port = '12345';
//$url = 'http://www.domain.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
curl_setopt($ch, CURLOPT_PROXYTYPE, 'HTTP');
curl_setopt($ch, CURLOPT_PROXY, $proxy_ip);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $loginpassw);
curl_setopt($ch, CURLOPT_CRLF, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment