/** * Serve a Google Cloud Storage file as the response. * * @param string $gs_filename The name of the Google Cloud Storage object to * serve. * @param mixed[] $options Array of additional options for serving the object. * <ul> * <li>'content_type': string Content-Type to override when known. * <li>'save_as': boolean If True then send the file as an attachment. * <li>'start': int Start index of content-range to send. * <li>'end': int End index of content-range to send. End index is * inclusive. * <li>'use_range': boolean Use provided content range from the request's * Range header. Mutually exclusive with start and end. * </ul> * * @throws \InvalidArgumentException If invalid options are supplied. */ 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)); } }
/** * Construct an object of CloudStorageClient. * * @param string $bucket The name of the bucket. * @param string $object The name of the object, or null if there is no * object. * @param resource $context The stream context to use. */ public function __construct($bucket, $object = null, $context = null) { $this->bucket_name = $bucket; $this->object_name = $object; if (!isset($context)) { $context = stream_context_get_default(); } $context_array = stream_context_get_options($context); if (array_key_exists("gs", $context_array)) { $this->context_options = array_merge(self::$default_gs_context_options, $context_array["gs"]); } else { $this->context_options = self::$default_gs_context_options; } $this->anonymous = ArrayUtil::findByKeyOrNull($this->context_options, "anonymous"); $this->url = $this->createObjectUrl($bucket, $object); }
/** * Parse a MIME part and set the Message object accordingly. * * @param resource $part A MIME part, returned from mailparse_msg_get_part, * to be parse. * @param string $raw_mail The string holding the raw content of the email * $part is extracted from. * @param Message& $email The Message object to be set. */ private static function parseMimePart($part, $raw_mail, &$email) { $data = mailparse_msg_get_part_data($part); $type = ArrayUtil::findByKeyOrDefault($data, 'content-type', 'text/plain'); $start = $data['starting-pos-body']; $end = $data['ending-pos-body']; $encoding = ArrayUtil::findByKeyOrDefault($data, 'transfer-encoding', ''); $content = self::decodeContent(substr($raw_mail, $start, $end - $start), $encoding); if (isset($data['content-disposition'])) { $filename = ArrayUtil::findByKeyOrDefault($data, 'disposition-filename', uniqid()); $content_id = ArrayUtil::findByKeyOrNull($data, 'content-id'); if ($content_id != null) { $content_id = "<{$content_id}>"; } $email->addAttachment($filename, $content, $content_id); } else { if ($type == 'text/html') { $email->setHtmlBody($content); } else { if ($type == 'text/plain') { $email->setTextBody($content); } else { if (!StringUtil::startsWith($type, 'multipart/')) { trigger_error("Ignore MIME part with unknown Content-Type {$type}. " . "Did you forget to specifcy Content-Disposition header?", E_USER_WARNING); } } } } }