GRPCMessageLengthLimitTests.swift 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright 2021, gRPC Authors All rights reserved.
  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. import EchoImplementation
  17. import EchoModel
  18. import GRPC
  19. import NIOCore
  20. import NIOPosix
  21. import XCTest
  22. final class GRPCMessageLengthLimitTests: GRPCTestCase {
  23. private var group: EventLoopGroup!
  24. private var server: Server!
  25. private var connection: ClientConnection!
  26. private var echo: Echo_EchoNIOClient {
  27. return Echo_EchoNIOClient(channel: self.connection)
  28. }
  29. override func setUp() {
  30. super.setUp()
  31. self.group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
  32. }
  33. override func tearDown() {
  34. XCTAssertNoThrow(try self.connection?.close().wait())
  35. XCTAssertNoThrow(try self.server?.close().wait())
  36. XCTAssertNoThrow(try self.group.syncShutdownGracefully())
  37. super.tearDown()
  38. }
  39. private func startEchoServer(receiveLimit: Int) throws {
  40. self.server = try Server.insecure(group: self.group)
  41. .withServiceProviders([EchoProvider()])
  42. .withMaximumReceiveMessageLength(receiveLimit)
  43. .withLogger(self.serverLogger)
  44. .bind(host: "127.0.0.1", port: 0)
  45. .wait()
  46. }
  47. private func startConnection(receiveLimit: Int) {
  48. self.connection = ClientConnection.insecure(group: self.group)
  49. .withMaximumReceiveMessageLength(receiveLimit)
  50. .withBackgroundActivityLogger(self.clientLogger)
  51. .connect(host: "127.0.0.1", port: self.server.channel.localAddress!.port!)
  52. }
  53. private func makeRequest(minimumLength: Int) -> Echo_EchoRequest {
  54. return .with {
  55. $0.text = String(repeating: "x", count: minimumLength)
  56. }
  57. }
  58. func testServerRejectsLongUnaryRequest() throws {
  59. // Server limits request size to 1024, no client limits.
  60. try self.startEchoServer(receiveLimit: 1024)
  61. self.startConnection(receiveLimit: .max)
  62. let get = self.echo.get(self.makeRequest(minimumLength: 1024))
  63. XCTAssertThrowsError(try get.response.wait())
  64. XCTAssertEqual(try get.status.map { $0.code }.wait(), .resourceExhausted)
  65. }
  66. func testServerRejectsLongClientStreamingRequest() throws {
  67. try self.startEchoServer(receiveLimit: 1024)
  68. self.startConnection(receiveLimit: .max)
  69. let collect = self.echo.collect()
  70. XCTAssertNoThrow(try collect.sendMessage(self.makeRequest(minimumLength: 1)).wait())
  71. XCTAssertNoThrow(try collect.sendMessage(self.makeRequest(minimumLength: 1024)).wait())
  72. // (No need to send end, the server is going to close the RPC because the message was too long.)
  73. XCTAssertThrowsError(try collect.response.wait())
  74. XCTAssertEqual(try collect.status.map { $0.code }.wait(), .resourceExhausted)
  75. }
  76. func testServerRejectsLongServerStreamingRequest() throws {
  77. try self.startEchoServer(receiveLimit: 1024)
  78. self.startConnection(receiveLimit: .max)
  79. let expand = self.echo.expand(self.makeRequest(minimumLength: 1024)) { _ in
  80. XCTFail("Unexpected response")
  81. }
  82. XCTAssertEqual(try expand.status.map { $0.code }.wait(), .resourceExhausted)
  83. }
  84. func testServerRejectsLongBidirectionalStreamingRequest() throws {
  85. try self.startEchoServer(receiveLimit: 1024)
  86. self.startConnection(receiveLimit: .max)
  87. let update = self.echo.update { _ in }
  88. XCTAssertNoThrow(try update.sendMessage(self.makeRequest(minimumLength: 1)).wait())
  89. XCTAssertNoThrow(try update.sendMessage(self.makeRequest(minimumLength: 1024)).wait())
  90. // (No need to send end, the server is going to close the RPC because the message was too long.)
  91. XCTAssertEqual(try update.status.map { $0.code }.wait(), .resourceExhausted)
  92. }
  93. func testClientRejectsLongUnaryResponse() throws {
  94. // No server limits, client limits response size to 1024.
  95. try self.startEchoServer(receiveLimit: .max)
  96. self.startConnection(receiveLimit: 1024)
  97. let get = self.echo.get(.with { $0.text = String(repeating: "x", count: 1024) })
  98. XCTAssertThrowsError(try get.response.wait())
  99. XCTAssertEqual(try get.status.map { $0.code }.wait(), .resourceExhausted)
  100. }
  101. func testClientRejectsLongClientStreamingResponse() throws {
  102. try self.startEchoServer(receiveLimit: .max)
  103. self.startConnection(receiveLimit: 1024)
  104. let collect = self.echo.collect()
  105. XCTAssertNoThrow(try collect.sendMessage(self.makeRequest(minimumLength: 1)).wait())
  106. XCTAssertNoThrow(try collect.sendMessage(self.makeRequest(minimumLength: 1024)).wait())
  107. XCTAssertNoThrow(try collect.sendEnd().wait())
  108. XCTAssertThrowsError(try collect.response.wait())
  109. XCTAssertEqual(try collect.status.map { $0.code }.wait(), .resourceExhausted)
  110. }
  111. func testClientRejectsLongServerStreamingRequest() throws {
  112. try self.startEchoServer(receiveLimit: .max)
  113. self.startConnection(receiveLimit: 1024)
  114. let expand = self.echo.expand(self.makeRequest(minimumLength: 1024)) { _ in
  115. // Expand splits on spaces, there are no spaces in the request and it should be too long for
  116. // the client to expect it.
  117. XCTFail("Unexpected response")
  118. }
  119. XCTAssertEqual(try expand.status.map { $0.code }.wait(), .resourceExhausted)
  120. }
  121. func testClientRejectsLongServerBidirectionalStreamingResponse() throws {
  122. try self.startEchoServer(receiveLimit: .max)
  123. self.startConnection(receiveLimit: 1024)
  124. let update = self.echo.update { _ in }
  125. XCTAssertNoThrow(try update.sendMessage(self.makeRequest(minimumLength: 1)).wait())
  126. XCTAssertNoThrow(try update.sendMessage(self.makeRequest(minimumLength: 1024)).wait())
  127. // (No need to send end, the client will close the RPC when it receives a response which is too
  128. // long.
  129. XCTAssertEqual(try update.status.map { $0.code }.wait(), .resourceExhausted)
  130. }
  131. }