You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.0 KiB

  1. /*
  2. * Minio Cloud Storage, (C) 2016 Minio, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package cmd
  17. import (
  18. "encoding/xml"
  19. "fmt"
  20. "io/ioutil"
  21. "net"
  22. "net/http"
  23. . "gopkg.in/check.v1"
  24. )
  25. // concurreny level for certain parallel tests.
  26. const (
  27. testConcurrencyLevel = 10
  28. )
  29. ///
  30. /// Excerpts from @lsegal - https://github.com/aws/aws-sdk-js/issues/659#issuecomment-120477258
  31. ///
  32. /// User-Agent:
  33. ///
  34. /// This is ignored from signing because signing this causes problems with generating pre-signed URLs
  35. /// (that are executed by other agents) or when customers pass requests through proxies, which may
  36. /// modify the user-agent.
  37. ///
  38. /// Content-Length:
  39. ///
  40. /// This is ignored from signing because generating a pre-signed URL should not provide a content-length
  41. /// constraint, specifically when vending a S3 pre-signed PUT URL. The corollary to this is that when
  42. /// sending regular requests (non-pre-signed), the signature contains a checksum of the body, which
  43. /// implicitly validates the payload length (since changing the number of bytes would change the checksum)
  44. /// and therefore this header is not valuable in the signature.
  45. ///
  46. /// Content-Type:
  47. ///
  48. /// Signing this header causes quite a number of problems in browser environments, where browsers
  49. /// like to modify and normalize the content-type header in different ways. There is more information
  50. /// on this in https://github.com/aws/aws-sdk-js/issues/244. Avoiding this field simplifies logic
  51. /// and reduces the possibility of future bugs
  52. ///
  53. /// Authorization:
  54. ///
  55. /// Is skipped for obvious reasons
  56. ///
  57. var ignoredHeaders = map[string]bool{
  58. "Authorization": true,
  59. "Content-Type": true,
  60. "Content-Length": true,
  61. "User-Agent": true,
  62. }
  63. // Headers to ignore in streaming v4
  64. var ignoredStreamingHeaders = map[string]bool{
  65. "Authorization": true,
  66. "Content-Type": true,
  67. "Content-Md5": true,
  68. "User-Agent": true,
  69. }
  70. // calculateSignedChunkLength - calculates the length of chunk metadata
  71. func calculateSignedChunkLength(chunkDataSize int64) int64 {
  72. return int64(len(fmt.Sprintf("%x", chunkDataSize))) +
  73. 17 + // ";chunk-signature="
  74. 64 + // e.g. "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2"
  75. 2 + // CRLF
  76. chunkDataSize +
  77. 2 // CRLF
  78. }
  79. // calculateSignedChunkLength - calculates the length of the overall stream (data + metadata)
  80. func calculateStreamContentLength(dataLen, chunkSize int64) int64 {
  81. if dataLen <= 0 {
  82. return 0
  83. }
  84. chunksCount := int64(dataLen / chunkSize)
  85. remainingBytes := int64(dataLen % chunkSize)
  86. var streamLen int64
  87. streamLen += chunksCount * calculateSignedChunkLength(chunkSize)
  88. if remainingBytes > 0 {
  89. streamLen += calculateSignedChunkLength(remainingBytes)
  90. }
  91. streamLen += calculateSignedChunkLength(0)
  92. return streamLen
  93. }
  94. // Ask the kernel for a free open port.
  95. func getFreePort() string {
  96. addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
  97. if err != nil {
  98. panic(err)
  99. }
  100. l, err := net.ListenTCP("tcp", addr)
  101. if err != nil {
  102. panic(err)
  103. }
  104. defer l.Close()
  105. return fmt.Sprintf("%d", l.Addr().(*net.TCPAddr).Port)
  106. }
  107. func verifyError(c *C, response *http.Response, code, description string, statusCode int) {
  108. data, err := ioutil.ReadAll(response.Body)
  109. c.Assert(err, IsNil)
  110. errorResponse := APIErrorResponse{}
  111. err = xml.Unmarshal(data, &errorResponse)
  112. c.Assert(err, IsNil)
  113. c.Assert(errorResponse.Code, Equals, code)
  114. c.Assert(errorResponse.Message, Equals, description)
  115. c.Assert(response.StatusCode, Equals, statusCode)
  116. }