osticket-docker/osTicket-v1.18.2/include/class.http.php

206 lines
7.2 KiB
PHP

<?php
/*********************************************************************
class.http.php
Http helper.
Peter Rotich <peter@osticket.com>
Copyright (c) 2006-2013 osTicket
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
See LICENSE.TXT for details.
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
class Http {
static function header_code_verbose($code) {
switch($code):
case 200: return '200 OK';
case 201: return '201 Created';
case 204: return '204 No Content';
case 205: return '205 Reset Content';
case 400: return '400 Bad Request';
case 401: return '401 Unauthorized';
case 403: return '403 Forbidden';
case 404: return '404 Not Found';
case 405: return '405 Method Not Allowed';
case 416: return '416 Requested Range Not Satisfiable';
case 418: return "418 I'm a teapot";
case 422: return '422 Unprocessable Entity';
default: return '500 Internal Server Error';
endswitch;
}
static function response($code,$content=false,$contentType='text/html',$charset='UTF-8') {
header('HTTP/1.1 '.Http::header_code_verbose($code));
header('Status: '.Http::header_code_verbose($code)."\r\n");
header("Connection: Close\r\n");
$ct = "Content-Type: $contentType";
if ($charset)
$ct .= "; charset=$charset";
header($ct);
if (is_string($content)) {
header('Content-Length: '.strlen($content)."\r\n\r\n");
print $content;
exit;
}
}
/*
* Flush the content to requester without exiting
*
*/
static function flush($code, $content, $contentType='text/html', $charset='UTF-8') {
self::response($code, null, $contentType, $charset);
header('Cache-Control: no-cache, must-revalidate');
header('Content-Length: '.strlen($content)."\r\n\r\n");
print $content;
// Flush the request buffer
while(@ob_end_flush());
flush();
// Terminate the request
if (function_exists('fastcgi_finish_request'))
fastcgi_finish_request();
}
static function redirect($url,$delay=0,$msg='') {
$iis = strpos($_SERVER['SERVER_SOFTWARE'], 'IIS') !== false;
@list($name, $version) = explode('/', $_SERVER['SERVER_SOFTWARE']);
// Legacy code for older versions of IIS that would not emit the
// correct HTTP status and headers when using the `Location`
// header alone
if ($iis && version_compare($version, '7.0', '<')) {
header("Refresh: $delay; URL=$url");
}else{
header("Location: $url");
}
print('<html></html>');
flush();
ob_flush();
exit;
}
static function cacheable($etag, $modified=false, $ttl=3600) {
// Thanks, http://stackoverflow.com/a/1583753/1025836
// Timezone doesn't matter here — but the time needs to be
// consistent round trip to the browser and back.
if ($modified) {
$last_modified = strtotime($modified." GMT");
header("Last-Modified: ".date('D, d M Y H:i:s', $last_modified)." GMT", false);
}
header('ETag: "'.$etag.'"');
header("Cache-Control: private, max-age=$ttl");
header('Expires: ' . gmdate('D, d M Y H:i:s', Misc::gmtime() + $ttl)." GMT");
header('Pragma: private');
if (($modified && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified)
|| @trim($_SERVER['HTTP_IF_NONE_MATCH'], '" ') == $etag) {
header("HTTP/1.1 304 Not Modified");
exit();
}
}
/**
* Creates the filename=... part of the Content-Disposition header. This
* is browser dependent, so the user agent is inspected to determine the
* best encoding format for the filename
*/
static function getDispositionFilename($filename) {
$user_agent = strtolower ($_SERVER['HTTP_USER_AGENT']);
if (false !== strpos($user_agent,'msie')
&& false !== strpos($user_agent,'win'))
return 'filename='.rawurlencode($filename);
else
// Use RFC5987
return "filename*=UTF-8''".rawurlencode($filename);
}
static function download($filename, $type, $data=null, $disposition='attachment') {
if (strpos($type, 'image/') !== false && preg_match('/image\/.*\+.*/', $type))
$disposition='attachment';
header('Pragma: private');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Type: '.$type);
header(sprintf('Content-Disposition: %s; %s',
$disposition,
self::getDispositionFilename(basename($filename))));
header('Content-Transfer-Encoding: binary');
if ($data !== null) {
header('Content-Length: '.strlen($data));
print $data;
exit;
}
}
static function build_query($vars, $encode=true, $separator='&amp;') {
if (!$vars)
return '';
if ($encode)
$vars = Format::htmlchars($vars);
return http_build_query($vars, '', $separator);
}
static function domain() {
$domain = null;
if (isset($_SERVER['HTTP_HOST'])
&& strpos($_SERVER['HTTP_HOST'], '.') !== false
&& !Validator::is_ip($_SERVER['HTTP_HOST']))
// Remote port specification, as it will make an invalid domain
list($domain) = explode(':', $_SERVER['HTTP_HOST']);
return $domain;
}
// Get current url
static function url() {
// Scheme + Host.
$https = osTicket::is_https();
$url = sprintf('http%s://%s',
$https ? 's' : '',
$_SERVER['HTTP_HOST']);
// Add Port if not 80 and not https
$port = osTicket::get_client_port();
if ($port && $port != 80 && !$https && !str_contains($url, $port))
$url .= ":{$port}";
// Path + Query string
if (isset($_SERVER['REQUEST_URI']))
$url .= $_SERVER['REQUEST_URI'];
else
$url .= sprintf('%s?$s',
$_SERVER['PHP_SELF'], $_SERVER['QUERY_STRING']);
return $url;
}
// Parse path from given url or the current url
static function url_path(string $url = null, bool $htmlentities = true) {
$path = parse_url($url ?: self::url(), PHP_URL_PATH);
return ($htmlentities && $path)
? htmlentities($path) : $path;
}
// Parse query string from current url
static function query_string(string $url = null) {
return parse_url($url ?: self::url(), PHP_URL_QUERY);
}
// Refresh url
static function refresh_url(array $queryFilter = []) {
$url = self::url();
$refresh_url = self::url_path($url);
if (($qs=self::query_string($url)))
$refresh_url .= sprintf('?%s',
Format::http_query_string($qs, $queryFilter));
return $refresh_url;
}
}
?>