Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.
/lib/ -> wasmlib.php (source)
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * This file contains various Web Assembly related functions,
  19   * all functions here are self-contained and can be used in ABORT_AFTER_CONFIG scripts.
  20   *
  21   * @package core_lib
  22   * @copyright 2021 Huong Nguyen <huongnv13@gmail.com>
  23   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /**
  29   * Send Web Assembly file content with as much caching as possible
  30   *
  31   * @param string $wasmpath Path to Web Assembly file
  32   * @param string $etag Etag
  33   * @param string $filename File name to be served
  34   */
  35  function wasm_send_cached(string $wasmpath, string $etag, string $filename = 'wasm.php'): void {
  36      require (__DIR__ . '/xsendfilelib.php');
  37  
  38      // 90 days only - based on Moodle point release cadence being every 3 months.
  39      $lifetime = 60 * 60 * 24 * 90;
  40  
  41      header('Etag: "' . $etag . '"');
  42      header('Content-Disposition: inline; filename="' . $filename . '"');
  43      header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($wasmpath)) . ' GMT');
  44      header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT');
  45      header('Pragma: ');
  46      header('Cache-Control: public, max-age=' . $lifetime . ', immutable');
  47      header('Accept-Ranges: none');
  48      header('Content-Type: application/wasm');
  49  
  50      if (xsendfile($wasmpath)) {
  51          die;
  52      }
  53  
  54      if (!min_enable_zlib_compression()) {
  55          header('Content-Length: ' . filesize($wasmpath));
  56      }
  57  
  58      readfile($wasmpath);
  59      die;
  60  }
  61  
  62  /**
  63   * Send Web Assembly file without any caching
  64   *
  65   * @param string $wasm Web Assembly file content
  66   * @param string $filename File name to be served
  67   */
  68  function wasm_send_uncached(string $wasm, string $filename = 'wasm.php'): void {
  69      header('Content-Disposition: inline; filename="' . $filename . '"');
  70      header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
  71      header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2) . ' GMT');
  72      header('Pragma: ');
  73      header('Accept-Ranges: none');
  74      header('Content-Type: application/wasm');
  75      header('Content-Length: ' . strlen($wasm));
  76  
  77      echo $wasm;
  78      die;
  79  }
  80  
  81  /**
  82   * Send Web Assembly file not modified headers
  83   *
  84   * @param int $lastmodified Last modified timestamp
  85   * @param string $etag Etag
  86   */
  87  function wasm_send_unmodified(int $lastmodified, string $etag): void {
  88      // 90 days only - based on Moodle point release cadence being every 3 months.
  89      $lifetime = 60 * 60 * 24 * 90;
  90      header('HTTP/1.1 304 Not Modified');
  91      header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT');
  92      header('Cache-Control: public, max-age=' . $lifetime);
  93      header('Content-Type: application/wasm');
  94      header('Etag: "' . $etag . '"');
  95      if ($lastmodified) {
  96          header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastmodified) . ' GMT');
  97      }
  98      die;
  99  }
 100  
 101  /**
 102   * Create cache file for Web Assembly content
 103   *
 104   * @param string $file full file path to cache file
 105   * @param string $content Web Assembly content
 106   */
 107  function wasm_write_cache_file_content(string $file, string $content): void {
 108      global $CFG;
 109  
 110      clearstatcache();
 111      if (!file_exists(dirname($file))) {
 112          @mkdir(dirname($file), $CFG->directorypermissions, true);
 113      }
 114  
 115      // Prevent serving of incomplete file from concurrent request,
 116      // the rename() should be more atomic than fwrite().
 117      ignore_user_abort(true);
 118      if ($fp = fopen($file . '.tmp', 'xb')) {
 119          fwrite($fp, $content);
 120          fclose($fp);
 121          rename($file . '.tmp', $file);
 122          @chmod($file, $CFG->filepermissions);
 123          @unlink($file . '.tmp'); // Just in case anything fails.
 124      }
 125      ignore_user_abort(false);
 126      if (connection_aborted()) {
 127          die;
 128      }
 129  }