[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/aphront/sink/ -> AphrontHTTPSink.php (source)

   1  <?php
   2  
   3  /**
   4   * Abstract class which wraps some sort of output mechanism for HTTP responses.
   5   * Normally this is just @{class:AphrontPHPHTTPSink}, which uses "echo" and
   6   * "header()" to emit responses.
   7   *
   8   * Mostly, this class allows us to do install security or metrics hooks in the
   9   * output pipeline.
  10   *
  11   * @task write  Writing Response Components
  12   * @task emit   Emitting the Response
  13   */
  14  abstract class AphrontHTTPSink {
  15  
  16  
  17  /* -(  Writing Response Components  )---------------------------------------- */
  18  
  19  
  20    /**
  21     * Write an HTTP status code to the output.
  22     *
  23     * @param int Numeric HTTP status code.
  24     * @return void
  25     */
  26    final public function writeHTTPStatus($code, $message = '') {
  27      if (!preg_match('/^\d{3}$/', $code)) {
  28        throw new Exception("Malformed HTTP status code '{$code}'!");
  29      }
  30  
  31      $code = (int)$code;
  32      $this->emitHTTPStatus($code, $message);
  33    }
  34  
  35  
  36    /**
  37     * Write HTTP headers to the output.
  38     *
  39     * @param list<pair> List of <name, value> pairs.
  40     * @return void
  41     */
  42    final public function writeHeaders(array $headers) {
  43      foreach ($headers as $header) {
  44        if (!is_array($header) || count($header) !== 2) {
  45          throw new Exception('Malformed header.');
  46        }
  47        list($name, $value) = $header;
  48  
  49        if (strpos($name, ':') !== false) {
  50          throw new Exception(
  51            'Declining to emit response with malformed HTTP header name: '.
  52            $name);
  53        }
  54  
  55        // Attackers may perform an "HTTP response splitting" attack by making
  56        // the application emit certain types of headers containing newlines:
  57        //
  58        //   http://en.wikipedia.org/wiki/HTTP_response_splitting
  59        //
  60        // PHP has built-in protections against HTTP response-splitting, but they
  61        // are of dubious trustworthiness:
  62        //
  63        //   http://news.php.net/php.internals/57655
  64  
  65        if (preg_match('/[\r\n\0]/', $name.$value)) {
  66          throw new Exception(
  67            "Declining to emit response with unsafe HTTP header: ".
  68            "<'".$name."', '".$value."'>.");
  69        }
  70      }
  71  
  72      foreach ($headers as $header) {
  73        list($name, $value) = $header;
  74        $this->emitHeader($name, $value);
  75      }
  76    }
  77  
  78  
  79    /**
  80     * Write HTTP body data to the output.
  81     *
  82     * @param string Body data.
  83     * @return void
  84     */
  85    final public function writeData($data) {
  86      $this->emitData($data);
  87    }
  88  
  89  
  90    /**
  91     * Write an entire @{class:AphrontResponse} to the output.
  92     *
  93     * @param AphrontResponse The response object to write.
  94     * @return void
  95     */
  96    final public function writeResponse(AphrontResponse $response) {
  97      // Do this first, in case it throws.
  98      $response_string = $response->buildResponseString();
  99  
 100      $all_headers = array_merge(
 101        $response->getHeaders(),
 102        $response->getCacheHeaders());
 103  
 104      $this->writeHTTPStatus(
 105        $response->getHTTPResponseCode(),
 106        $response->getHTTPResponseMessage());
 107      $this->writeHeaders($all_headers);
 108      $this->writeData($response_string);
 109    }
 110  
 111  
 112  /* -(  Emitting the Response  )---------------------------------------------- */
 113  
 114  
 115    abstract protected function emitHTTPStatus($code, $message = '');
 116    abstract protected function emitHeader($name, $value);
 117    abstract protected function emitData($data);
 118  
 119  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1