public static function serve($gs_filename, $options = []) {
    $extra_options = array_diff(array_keys($options), self::$serve_options);

    if (!empty($extra_options)) {
      throw new \InvalidArgumentException('Invalid options supplied: ' .
          htmlspecialchars(implode(',', $extra_options)));
    }

    // Determine the range to send
    $start = ArrayUtil::findByKeyOrNull($options, "start");
    $end = ArrayUtil::findByKeyOrNull($options, "end");
    $use_range = ArrayUtil::findByKeyOrNull($options, "use_range");
    $request_range_header = ArrayUtil::findByKeyOrNull($_SERVER, "HTTP_RANGE");

    $range_header = self::checkRanges($start,
                                      $end,
                                      $use_range,
                                      $request_range_header);

    $save_as = ArrayUtil::findByKeyOrNull($options, "save_as");
    if (isset($save_as) && !is_string($save_as)) {
      throw new \InvalidArgumentException("Unexpected value for save_as.");
    }

    $blob_key = self::createGsKey($gs_filename);
    self::sendHeader(self::BLOB_KEY_HEADER, $blob_key);

    if (isset($range_header)) {
      self::sendHeader(self::BLOB_RANGE_HEADER, $range_header);
    }

    $content_type = ArrayUtil::findByKeyOrNull($options, "content_type");
    if (isset($content_type)) {
      self::sendHeader("Content-Type", $content_type);
    }

    if (isset($save_as)) {
      self::sendHeader("Content-Disposition", sprintf(
          "attachment; filename=%s", $save_as));
    }
  }