145 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace nur\v;
 | 
						|
 | 
						|
use nur\base;
 | 
						|
use nur\session;
 | 
						|
 | 
						|
/**
 | 
						|
 * Class http: des outils pour parler le protocole HTTP dans le cadre de la
 | 
						|
 * génération d'une page
 | 
						|
 */
 | 
						|
class http {
 | 
						|
  static final function get_url(): string {
 | 
						|
    $proto = $_SERVER["HTTP_X_FORWARDED_PROTO"];
 | 
						|
    $host = $_SERVER["HTTP_X_FORWARDED_HOST"];
 | 
						|
    $uri = $_SERVER["SCRIPT_NAME"];
 | 
						|
    return "$proto://$host$uri";
 | 
						|
  }
 | 
						|
 | 
						|
  static final function get_baseurl(): string {
 | 
						|
    $proto = $_SERVER["HTTP_X_FORWARDED_PROTO"];
 | 
						|
    $host = $_SERVER["HTTP_X_FORWARDED_HOST"];
 | 
						|
    $baseuri = dirname($_SERVER["SCRIPT_NAME"]);
 | 
						|
    return "$proto://$host$baseuri";
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * ne pas mettre en cache la réponse.
 | 
						|
   *
 | 
						|
   * appeler cette méthode est nécessaire si une page est dynamique
 | 
						|
   * et que les sessions ne sont pas utilisées.
 | 
						|
   *
 | 
						|
   * si un session est déjà démarrée, cette méthode est un NOP, sauf si
 | 
						|
   * $force==true
 | 
						|
   */
 | 
						|
  static function no_cache(bool $force=false): void {
 | 
						|
    if (session::started() && !$force) return;
 | 
						|
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
 | 
						|
    header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
 | 
						|
    header("Cache-Control: no-cache, max-age=0, must-revalidate");
 | 
						|
    header("Pragma: public");
 | 
						|
  }
 | 
						|
 | 
						|
  /** spécifier le type de contenu de la réponse */
 | 
						|
  static function content_type(string $content_type=null, string $charset=null): void {
 | 
						|
    if ($content_type === null) $content_type = "application/octet-stream";
 | 
						|
    if (substr($content_type, 0, 5) == "text/") {
 | 
						|
      if ($charset === null) $charset = "utf-8";
 | 
						|
      if ($charset) $content_type .= "; charset=$charset";
 | 
						|
    }
 | 
						|
    header("Content-Type: $content_type");
 | 
						|
  }
 | 
						|
 | 
						|
  static final function content_type_text(): void {
 | 
						|
    self::content_type("text/plain");
 | 
						|
  }
 | 
						|
 | 
						|
  /** indiquer que la réponse doit être téléchargée */
 | 
						|
  static function download_as($filename, string $disposition=null): void {
 | 
						|
    if (base::nz($filename)) {
 | 
						|
      $filename = basename($filename);
 | 
						|
      if ($disposition === null) $disposition = "attachment";
 | 
						|
      header("Content-Disposition: $disposition; filename=\"$filename\"");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /** rediriger vers l'url spécifiée et arrêter le script immédiatement */
 | 
						|
  static function redirect(string $url, bool $exit_now=true): void {
 | 
						|
    header("Location: $url");
 | 
						|
    if ($exit_now) exit();
 | 
						|
  }
 | 
						|
 | 
						|
  /** rafraichir vers l'url spécifiée et arrêter le script immédiatement */
 | 
						|
  static function refresh(string $url, int $delay=1, bool $exit_now=true): void {
 | 
						|
    header("Refresh: $delay; url=$url");
 | 
						|
    if ($exit_now) exit();
 | 
						|
  }
 | 
						|
 | 
						|
  /** envoyer le status "pas de contenu" et arrêter le script immédiatement */
 | 
						|
  static function send_no_content(bool $exit_now=true): void {
 | 
						|
    header("HTTP/1.1 204 No Content");
 | 
						|
    if ($exit_now) exit();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Envoyer le fichier spécifié pour téléchargement et arrêter le script
 | 
						|
   * immédiatement. On assume que les méthodes statiques {@link content_type()}
 | 
						|
   * et {@link download_as()} ont déjà été appelées.
 | 
						|
   *
 | 
						|
   * - si $delete==true, supprimer le fichier après téléchargement.
 | 
						|
   * - si $add_content_length==true, ajouter une en-tête qui précise la taille
 | 
						|
   *   du fichier à télécharger. attention: la taille du fichier ne devrait pas
 | 
						|
   *   changer
 | 
						|
   * - si $close_session==true, la session est fermée avant de lancer le
 | 
						|
   *   téléchargement du fichier pour éviter de garder inutilement le verrou.
 | 
						|
   *   NB: si le fichier à retourner est d'une certaine taille, il est avisé
 | 
						|
   *   de fermer la session pour ne pas bloquer la navigation.
 | 
						|
   *
 | 
						|
   * si une erreur s'est produite, retourner false, même si $exit_now==true
 | 
						|
   */
 | 
						|
  static function send_file(string $file, bool $delete=false, bool $close_session=true, bool $add_content_length=true, bool $exit_now=true): bool {
 | 
						|
    $fd = fopen($file, "r");
 | 
						|
    if ($fd === false) return false;
 | 
						|
    if ($close_session) session::close();
 | 
						|
    if ($add_content_length) {
 | 
						|
      $size = filesize($file);
 | 
						|
      if ($size !== false) header("Content-Length: $size");
 | 
						|
    }
 | 
						|
    if ($delete) unlink($file);
 | 
						|
    $written = fpassthru($fd);
 | 
						|
    # XXX si $written !== $size, il faudrait agir en conséquence...
 | 
						|
    fclose($fd);
 | 
						|
    if ($written === false) return false;
 | 
						|
    if ($exit_now) exit();
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  static final function error(string $status, bool $exit=true): void {
 | 
						|
    header("HTTP/1.1 $status");
 | 
						|
    if ($exit) exit();
 | 
						|
  }
 | 
						|
 | 
						|
  static final function error400(?string $message=null, ?string $body=null, bool $exit=true): void {
 | 
						|
    if ($message === null) $message = "Bad Request";
 | 
						|
    elseif ($body === null) $body = $message;
 | 
						|
    self::error("400 $message", false);
 | 
						|
    if ($body !== null) echo $body;
 | 
						|
    if ($exit) exit();
 | 
						|
  }
 | 
						|
 | 
						|
  static final function error404(?string $message=null, ?string $body=null, bool $exit=true): void {
 | 
						|
    if ($message === null) $message = "Not Found";
 | 
						|
    elseif ($body === null) $body = $message;
 | 
						|
    self::error("404 $message", false);
 | 
						|
    if ($body !== null) echo $body;
 | 
						|
    if ($exit) exit();
 | 
						|
  }
 | 
						|
 | 
						|
  static final function error500(?string $message=null, ?string $body=null, bool $exit=true): void {
 | 
						|
    if ($message === null) $message = "Internal Server Error";
 | 
						|
    elseif ($body === null) $body = $message;
 | 
						|
    self::error("500 $message", false);
 | 
						|
    if ($body !== null) echo $body;
 | 
						|
    if ($exit) exit();
 | 
						|
  }
 | 
						|
}
 |