Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   1  <?php
   2  
   3  namespace IMSGlobal\LTI;
   4  
   5  /**
   6   * Class to represent an HTTP message
   7   *
   8   * @author  Stephen P Vickers <svickers@imsglobal.org>
   9   * @copyright  IMS Global Learning Consortium Inc
  10   * @date  2016
  11   * @version 3.0.0
  12   * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  13   */
  14  class HTTPMessage
  15  {
  16  
  17  /**
  18   * True if message was sent successfully.
  19   *
  20   * @var boolean $ok
  21   */
  22      public $ok = false;
  23  
  24  /**
  25   * Request body.
  26   *
  27   * @var request $request
  28   */
  29      public $request = null;
  30  
  31  /**
  32   * Request headers.
  33   *
  34   * @var request_headers $requestHeaders
  35   */
  36      public $requestHeaders = '';
  37  
  38  /**
  39   * Response body.
  40   *
  41   * @var response $response
  42   */
  43      public $response = null;
  44  
  45  /**
  46   * Response headers.
  47   *
  48   * @var response_headers $responseHeaders
  49   */
  50      public $responseHeaders = '';
  51  
  52  /**
  53   * Status of response (0 if undetermined).
  54   *
  55   * @var status $status
  56   */
  57      public $status = 0;
  58  
  59  /**
  60   * Error message
  61   *
  62   * @var error $error
  63   */
  64      public $error = '';
  65  
  66  /**
  67   * Request URL.
  68   *
  69   * @var url $url
  70   */
  71      private $url = null;
  72  
  73  /**
  74   * Request method.
  75   *
  76   * @var method $method
  77   */
  78      private $method = null;
  79  
  80  /**
  81   * Class constructor.
  82   *
  83   * @param string $url     URL to send request to
  84   * @param string $method  Request method to use (optional, default is GET)
  85   * @param mixed  $params  Associative array of parameter values to be passed or message body (optional, default is none)
  86   * @param string $header  Values to include in the request header (optional, default is none)
  87   */
  88      function __construct($url, $method = 'GET', $params = null, $header = null)
  89      {
  90  
  91          $this->url = $url;
  92          $this->method = strtoupper($method);
  93          if (is_array($params)) {
  94              $this->request = http_build_query($params);
  95          } else {
  96              $this->request = $params;
  97          }
  98          if (!empty($header)) {
  99              $this->requestHeaders = explode("\n", $header);
 100          }
 101  
 102      }
 103  
 104  /**
 105   * Send the request to the target URL.
 106   *
 107   * @return boolean True if the request was successful
 108   */
 109      public function send()
 110      {
 111  
 112          $this->ok = false;
 113  // Try using curl if available
 114          if (function_exists('curl_init')) {
 115              $resp = '';
 116              $ch = curl_init();
 117              curl_setopt($ch, CURLOPT_URL, $this->url);
 118              if (!empty($this->requestHeaders)) {
 119                  curl_setopt($ch, CURLOPT_HTTPHEADER, $this->requestHeaders);
 120              } else {
 121                  curl_setopt($ch, CURLOPT_HEADER, 0);
 122              }
 123              if ($this->method === 'POST') {
 124                  curl_setopt($ch, CURLOPT_POST, true);
 125                  curl_setopt($ch, CURLOPT_POSTFIELDS, $this->request);
 126              } else if ($this->method !== 'GET') {
 127                  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->method);
 128                  if (!is_null($this->request)) {
 129                      curl_setopt($ch, CURLOPT_POSTFIELDS, $this->request);
 130                  }
 131              }
 132              curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 133              curl_setopt($ch, CURLINFO_HEADER_OUT, true);
 134              curl_setopt($ch, CURLOPT_HEADER, true);
 135              $chResp = curl_exec($ch);
 136              $this->ok = $chResp !== false;
 137              if ($this->ok) {
 138                  $chResp = str_replace("\r\n", "\n", $chResp);
 139                  $chRespSplit = explode("\n\n", $chResp, 2);
 140                  if ((count($chRespSplit) > 1) && (substr($chRespSplit[1], 0, 5) === 'HTTP/')) {
 141                      $chRespSplit = explode("\n\n", $chRespSplit[1], 2);
 142                  }
 143                  $this->responseHeaders = $chRespSplit[0];
 144                  $resp = $chRespSplit[1];
 145                  $this->status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 146                  $this->ok = $this->status < 400;
 147                  if (!$this->ok) {
 148                      $this->error = curl_error($ch);
 149                  }
 150              }
 151              $this->requestHeaders = str_replace("\r\n", "\n", curl_getinfo($ch, CURLINFO_HEADER_OUT));
 152              curl_close($ch);
 153              $this->response = $resp;
 154          } else {
 155  // Try using fopen if curl was not available
 156              $opts = array('method' => $this->method,
 157                            'content' => $this->request
 158                           );
 159              if (!empty($this->requestHeaders)) {
 160                  $opts['header'] = $this->requestHeaders;
 161              }
 162              try {
 163                  $ctx = stream_context_create(array('http' => $opts));
 164                  $fp = @fopen($this->url, 'rb', false, $ctx);
 165                  if ($fp) {
 166                      $resp = @stream_get_contents($fp);
 167                      $this->ok = $resp !== false;
 168                  }
 169              } catch (\Exception $e) {
 170                  $this->ok = false;
 171              }
 172          }
 173  
 174          return $this->ok;
 175  
 176      }
 177  
 178  }