ALIOSS::auth PHP Method

auth() public method

Authorization
Since: 2012-05-31
public auth ( array $options )
$options array (Required)
    public function auth($options)
    {
        //开始记录LOG
        $msg = "---LOG START---------------------------------------------------------------------------\n";
        //验证Bucket,list_bucket时不需要验证
        if (!('/' == $options[self::OSS_OBJECT] && '' == $options[self::OSS_BUCKET] && 'GET' == $options[self::OSS_METHOD]) && !$this->validate_bucket($options[self::OSS_BUCKET])) {
            throw new OSS_Exception('"' . $options[self::OSS_BUCKET] . '"' . OSS_BUCKET_NAME_INVALID);
        }
        //验证Object
        if (isset($options[self::OSS_OBJECT]) && !$this->validate_object($options[self::OSS_OBJECT])) {
            throw new OSS_Exception($options[self::OSS_OBJECT] . OSS_OBJECT_NAME_INVALID);
        }
        //Object编码为UTF-8
        if ($this->is_gb2312($options[self::OSS_OBJECT])) {
            $options[self::OSS_OBJECT] = iconv('GB2312', "UTF-8", $options[self::OSS_OBJECT]);
        } elseif ($this->check_char($options[self::OSS_OBJECT], true)) {
            $options[self::OSS_OBJECT] = iconv('GBK', "UTF-8", $options[self::OSS_OBJECT]);
        }
        //验证ACL
        if (isset($options[self::OSS_HEADERS][self::OSS_ACL]) && !empty($options[self::OSS_HEADERS][self::OSS_ACL])) {
            if (!in_array(strtolower($options[self::OSS_HEADERS][self::OSS_ACL]), self::$OSS_ACL_TYPES)) {
                throw new OSS_Exception($options[self::OSS_HEADERS][self::OSS_ACL] . ':' . OSS_ACL_INVALID);
            }
        }
        //定义scheme
        $scheme = $this->use_ssl ? 'https://' : 'http://';
        //匹配bucket
        if (strpos($options[self::OSS_BUCKET], "-") !== false) {
            //bucket 带"-"的时候
            $this->set_enable_domain_style(false);
        } else {
            $this->set_enable_domain_style(true);
        }
        if ($this->enable_domain_style) {
            $hostname = $this->vhost ? $this->vhost : ($options[self::OSS_BUCKET] == '' ? $this->hostname : $options[self::OSS_BUCKET] . '.' . $this->hostname);
        } else {
            $hostname = isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET] ? $this->hostname . '/' . $options[self::OSS_BUCKET] : $this->hostname;
        }
        //请求参数
        $resource = '';
        $sub_resource = '';
        $signable_resource = '';
        $query_string_params = array();
        $signable_query_string_params = array();
        $string_to_sign = '';
        $headers = array(self::OSS_CONTENT_MD5 => '', self::OSS_CONTENT_TYPE => isset($options[self::OSS_CONTENT_TYPE]) ? $options[self::OSS_CONTENT_TYPE] : 'application/x-www-form-urlencoded', self::OSS_DATE => isset($options[self::OSS_DATE]) ? $options[self::OSS_DATE] : gmdate('D, d M Y H:i:s \\G\\M\\T'), self::OSS_HOST => $this->enable_domain_style ? $hostname : $this->hostname);
        if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) {
            $signable_resource = '/' . str_replace('%2F', '/', rawurlencode($options[self::OSS_OBJECT]));
        }
        if (isset($options[self::OSS_QUERY_STRING])) {
            $query_string_params = array_merge($query_string_params, $options[self::OSS_QUERY_STRING]);
        }
        $query_string = $this->to_query_string($query_string_params);
        $signable_list = array('partNumber', 'uploadId');
        foreach ($signable_list as $item) {
            if (isset($options[$item])) {
                $signable_query_string_params[$item] = $options[$item];
            }
        }
        $signable_query_string = $this->to_query_string($signable_query_string_params);
        //合并 HTTP headers
        if (isset($options[self::OSS_HEADERS])) {
            $headers = array_merge($headers, $options[self::OSS_HEADERS]);
        }
        //生成请求URL
        $conjunction = '?';
        $non_signable_resource = '';
        if (isset($options[self::OSS_SUB_RESOURCE])) {
            $signable_resource .= $conjunction . $options[self::OSS_SUB_RESOURCE];
            $conjunction = '&';
        }
        if ($signable_query_string !== '') {
            $signable_query_string = $conjunction . $signable_query_string;
            $conjunction = '&';
        }
        if ($query_string !== '') {
            $non_signable_resource .= $conjunction . $query_string;
            $conjunction = '&';
        }
        $this->request_url = $scheme . $hostname . $signable_resource . $signable_query_string . $non_signable_resource;
        $msg .= "--REQUEST URL:----------------------------------------------\n" . $this->request_url . "\n";
        //创建请求
        $request = new RequestCore($this->request_url);
        // Streaming uploads
        if (isset($options[self::OSS_FILE_UPLOAD])) {
            if (is_resource($options[self::OSS_FILE_UPLOAD])) {
                $length = null;
                if (isset($options[self::OSS_CONTENT_LENGTH])) {
                    $length = $options[self::OSS_CONTENT_LENGTH];
                } elseif (isset($options[self::OSS_SEEK_TO])) {
                    $stats = fstat($options[self::OSS_FILE_UPLOAD]);
                    if ($stats && $stats[self::OSS_SIZE] >= 0) {
                        $length = $stats[self::OSS_SIZE] - (int) $options[self::OSS_SEEK_TO];
                    }
                }
                $request->set_read_stream($options[self::OSS_FILE_UPLOAD], $length);
                if ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded') {
                    $headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream';
                }
            } else {
                $request->set_read_file($options[self::OSS_FILE_UPLOAD]);
                $length = $request->read_stream_size;
                if (isset($options[self::OSS_CONTENT_LENGTH])) {
                    $length = $options[self::OSS_CONTENT_LENGTH];
                } elseif (isset($options[self::OSS_SEEK_TO]) && isset($length)) {
                    $length -= (int) $options[self::OSS_SEEK_TO];
                }
                $request->set_read_stream_size($length);
                if (isset($headers[self::OSS_CONTENT_TYPE]) && $headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded') {
                    $extension = explode('.', $options[self::OSS_FILE_UPLOAD]);
                    $ext = array_pop($extension);
                    $mime_type = MimeTypes::get_mimetype($ext);
                    $headers[self::OSS_CONTENT_TYPE] = $mime_type;
                }
            }
            $options[self::OSS_CONTENT_MD5] = '';
        }
        if (isset($options[self::OSS_SEEK_TO])) {
            $request->set_seek_position((int) $options[self::OSS_SEEK_TO]);
        }
        if (isset($options[self::OSS_FILE_DOWNLOAD])) {
            if (is_resource($options[self::OSS_FILE_DOWNLOAD])) {
                $request->set_write_stream($options[self::OSS_FILE_DOWNLOAD]);
            } else {
                $request->set_write_file($options[self::OSS_FILE_DOWNLOAD]);
            }
        }
        if (isset($options[self::OSS_METHOD])) {
            $request->set_method($options[self::OSS_METHOD]);
            $string_to_sign .= $options[self::OSS_METHOD] . "\n";
        }
        if (isset($options[self::OSS_CONTENT])) {
            $request->set_body($options[self::OSS_CONTENT]);
            if ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded') {
                $headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream';
            }
            $headers[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]);
            $headers[self::OSS_CONTENT_MD5] = $this->hex_to_base64(md5($options[self::OSS_CONTENT]));
        }
        uksort($headers, 'strnatcasecmp');
        foreach ($headers as $header_key => $header_value) {
            $header_value = str_replace(array("\r", "\n"), '', $header_value);
            if ($header_value !== '') {
                $request->add_header($header_key, $header_value);
            }
            if (strtolower($header_key) === 'content-md5' || strtolower($header_key) === 'content-type' || strtolower($header_key) === 'date' || isset($options['self::OSS_PREAUTH']) && (int) $options['self::OSS_PREAUTH'] > 0) {
                $string_to_sign .= $header_value . "\n";
            } elseif (substr(strtolower($header_key), 0, 6) === self::OSS_DEFAULT_PREFIX) {
                $string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n";
            }
        }
        $string_to_sign .= '/' . $options[self::OSS_BUCKET];
        $string_to_sign .= $this->enable_domain_style ? $options[self::OSS_BUCKET] != '' ? $options[self::OSS_OBJECT] == '/' ? '/' : '' : '' : '';
        $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string);
        $msg .= "STRING TO SIGN:----------------------------------------------\n" . $string_to_sign . "\n";
        $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->access_key, true));
        $request->add_header('Authorization', 'OSS ' . $this->access_id . ':' . $signature);
        if (isset($options[self::OSS_PREAUTH]) && (int) $options[self::OSS_PREAUTH] > 0) {
            return $this->request_url . $conjunction . self::OSS_URL_ACCESS_KEY_ID . '=' . $this->access_id . '&' . self::OSS_URL_EXPIRES . '=' . $options[self::OSS_PREAUTH] . '&' . self::OSS_URL_SIGNATURE . '=' . rawurlencode($signature);
        } elseif (isset($options[self::OSS_PREAUTH])) {
            return $this->request_url;
        }
        if ($this->debug_mode) {
            $request->debug_mode = $this->debug_mode;
        }
        $msg .= "REQUEST HEADERS:----------------------------------------------\n" . serialize($request->request_headers) . "\n";
        $request->send_request();
        $response_header = $request->get_response_header();
        $response_header['x-oss-request-url'] = $this->request_url;
        $response_header['x-oss-redirects'] = $this->redirects;
        $response_header['x-oss-stringtosign'] = $string_to_sign;
        $response_header['x-oss-requestheaders'] = $request->request_headers;
        $msg .= "RESPONSE HEADERS:----------------------------------------------\n" . serialize($response_header) . "\n";
        $data = new ResponseCore($response_header, $request->get_response_body(), $request->get_response_code());
        if ((int) $request->get_response_code() === 400 || (int) $request->get_response_code() === 500 || (int) $request->get_response_code() === 503) {
            if ($this->redirects <= $this->max_retries) {
                //设置休眠
                $delay = (int) (pow(4, $this->redirects) * 100000);
                usleep($delay);
                $this->redirects++;
                $data = $this->auth($options);
            }
        }
        $msg .= "RESPONSE DATA:----------------------------------------------\n" . serialize($data) . "\n";
        $msg .= date('Y-m-d H:i:s') . ":---LOG END---------------------------------------------------------------------------\n";
        //add log
        $this->log($msg);
        $this->redirects = 0;
        return $data;
    }