AipHttpUtil.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. namespace addons\blog\library\aip\lib;
  3. /*
  4. * Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. * use this file except in compliance with the License. You may obtain a copy of
  8. * the License at
  9. *
  10. * Http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. * License for the specific language governing permissions and limitations under
  16. * the License.
  17. */
  18. /**
  19. * BCE Util
  20. */
  21. class AipHttpUtil
  22. {
  23. // 根据RFC 3986,除了:
  24. // 1.大小写英文字符
  25. // 2.阿拉伯数字
  26. // 3.点'.'、波浪线'~'、减号'-'以及下划线'_'
  27. // 以外都要编码
  28. public static $PERCENT_ENCODED_STRINGS;
  29. //填充编码数组
  30. public static function __init()
  31. {
  32. AipHttpUtil::$PERCENT_ENCODED_STRINGS = array();
  33. for ($i = 0; $i < 256; ++$i) {
  34. AipHttpUtil::$PERCENT_ENCODED_STRINGS[$i] = sprintf("%%%02X", $i);
  35. }
  36. //a-z不编码
  37. foreach (range('a', 'z') as $ch) {
  38. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord($ch)] = $ch;
  39. }
  40. //A-Z不编码
  41. foreach (range('A', 'Z') as $ch) {
  42. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord($ch)] = $ch;
  43. }
  44. //0-9不编码
  45. foreach (range('0', '9') as $ch) {
  46. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord($ch)] = $ch;
  47. }
  48. //以下4个字符不编码
  49. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord('-')] = '-';
  50. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord('.')] = '.';
  51. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord('_')] = '_';
  52. AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord('~')] = '~';
  53. }
  54. /**
  55. * 在uri编码中不能对'/'编码
  56. * @param string $path
  57. * @return string
  58. */
  59. public static function urlEncodeExceptSlash($path)
  60. {
  61. return str_replace("%2F", "/", AipHttpUtil::urlEncode($path));
  62. }
  63. /**
  64. * 使用编码数组编码
  65. * @param string $path
  66. * @return string
  67. */
  68. public static function urlEncode($value)
  69. {
  70. $result = '';
  71. for ($i = 0; $i < strlen($value); ++$i) {
  72. $result .= AipHttpUtil::$PERCENT_ENCODED_STRINGS[ord($value[$i])];
  73. }
  74. return $result;
  75. }
  76. /**
  77. * 生成标准化QueryString
  78. * @param array $parameters
  79. * @return array
  80. */
  81. public static function getCanonicalQueryString(array $parameters)
  82. {
  83. //没有参数,直接返回空串
  84. if (count($parameters) == 0) {
  85. return '';
  86. }
  87. $parameterStrings = array();
  88. foreach ($parameters as $k => $v) {
  89. //跳过Authorization字段
  90. if (strcasecmp('Authorization', $k) == 0) {
  91. continue;
  92. }
  93. if (!isset($k)) {
  94. throw new \InvalidArgumentException(
  95. "parameter key should not be null"
  96. );
  97. }
  98. if (isset($v)) {
  99. //对于有值的,编码后放在=号两边
  100. $parameterStrings[] = AipHttpUtil::urlEncode($k)
  101. . '=' . AipHttpUtil::urlEncode((string)$v);
  102. } else {
  103. //对于没有值的,只将key编码后放在=号的左边,右边留空
  104. $parameterStrings[] = AipHttpUtil::urlEncode($k) . '=';
  105. }
  106. }
  107. //按照字典序排序
  108. sort($parameterStrings);
  109. //使用'&'符号连接它们
  110. return implode('&', $parameterStrings);
  111. }
  112. /**
  113. * 生成标准化uri
  114. * @param string $path
  115. * @return string
  116. */
  117. public static function getCanonicalURIPath($path)
  118. {
  119. //空路径设置为'/'
  120. if (empty($path)) {
  121. return '/';
  122. } else {
  123. //所有的uri必须以'/'开头
  124. if ($path[0] == '/') {
  125. return AipHttpUtil::urlEncodeExceptSlash($path);
  126. } else {
  127. return '/' . AipHttpUtil::urlEncodeExceptSlash($path);
  128. }
  129. }
  130. }
  131. /**
  132. * 生成标准化http请求头串
  133. * @param array $headers
  134. * @return array
  135. */
  136. public static function getCanonicalHeaders($headers)
  137. {
  138. //如果没有headers,则返回空串
  139. if (count($headers) == 0) {
  140. return '';
  141. }
  142. $headerStrings = array();
  143. foreach ($headers as $k => $v) {
  144. //跳过key为null的
  145. if ($k === null) {
  146. continue;
  147. }
  148. //如果value为null,则赋值为空串
  149. if ($v === null) {
  150. $v = '';
  151. }
  152. //trim后再encode,之后使用':'号连接起来
  153. $headerStrings[] = AipHttpUtil::urlEncode(strtolower(trim($k))) . ':' . AipHttpUtil::urlEncode(trim($v));
  154. }
  155. //字典序排序
  156. sort($headerStrings);
  157. //用'\n'把它们连接起来
  158. return implode("\n", $headerStrings);
  159. }
  160. }
  161. AipHttpUtil::__init();