11// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0.
33
4+ import _Concurrency
45import AwsCommonRuntimeKit
56import Foundation
6- import _Concurrency
77
88// swiftlint:disable cyclomatic_complexity function_body_length
99struct Context {
@@ -15,16 +15,15 @@ struct Context {
1515 public var certificate : String ?
1616 public var privateKey : String ?
1717 public var connectTimeout : Int = 3000
18- public var headers : [ String : String ] = [ String : String ] ( )
18+ public var headers : [ String : String ] = . init ( )
1919 public var includeHeaders : Bool = false
2020 public var outputFileName : String ?
2121 public var traceFile : String ?
2222 public var insecure : Bool = false
23- public var url : URL = URL ( fileURLWithPath: " " )
23+ public var url : URL = . init ( fileURLWithPath: " " )
2424 public var data : Data ?
2525 public var alpnList : [ String ] = [ ]
2626 public var outputStream = FileHandle . standardOutput
27-
2827}
2928
3029@main
@@ -33,7 +32,6 @@ struct Elasticurl {
3332 private static var context = Context ( )
3433
3534 static func parseArguments( ) {
36-
3735 let optionString = " a:b:c:e:f:H:d:g:j:l:m:M:GPHiko:t:v:VwWh "
3836 let options = [ ElasticurlOptions . caCert. rawValue,
3937 ElasticurlOptions . caPath. rawValue,
@@ -100,7 +98,6 @@ struct Elasticurl {
10098 }
10199
102100 if let dataFilePath = argumentsDict [ " g " ] as? String {
103-
104101 guard let url = URL ( string: dataFilePath) else {
105102 print ( " path to data file is incorrect or does not exist " )
106103 exit ( - 1 )
@@ -161,7 +158,7 @@ struct Elasticurl {
161158 context. alpnList. append ( " h2 " )
162159 }
163160
164- if argumentsDict [ " w " ] == nil && argumentsDict [ " W " ] == nil {
161+ if argumentsDict [ " w " ] == nil , argumentsDict [ " W " ] == nil {
165162 context. alpnList. append ( " h2 " )
166163 context. alpnList. append ( " http/1.1 " )
167164 }
@@ -173,7 +170,8 @@ struct Elasticurl {
173170
174171 // make sure a url was given before we do anything else
175172 guard let urlString = CommandLine . arguments. last,
176- let url = URL ( string: urlString) else {
173+ let url = URL ( string: urlString)
174+ else {
177175 print ( " Invalid URL: \( CommandLine . arguments. last!) " )
178176 exit ( - 1 )
179177 }
@@ -258,8 +256,6 @@ struct Elasticurl {
258256
259257 let socketOptions = SocketOptions ( socketType: . stream)
260258
261- let semaphore = DispatchSemaphore ( value: 0 )
262-
263259 var stream : HTTPStream ?
264260 let path = context. url. path == " " ? " / " : context. url. path
265261 let httpRequest : HTTPRequest = try HTTPRequest ( method: context. verb, path: path)
@@ -276,22 +272,6 @@ struct Elasticurl {
276272 }
277273 httpRequest. addHeaders ( headers: headers)
278274
279- let onResponse : HTTPRequestOptions . OnResponse = { _, headers in
280- for header in headers {
281- print ( header. name + " : " + header. value)
282- }
283- }
284-
285- let onBody : HTTPRequestOptions . OnIncomingBody = { bodyChunk in
286- writeData ( data: bodyChunk)
287- }
288-
289- let onComplete : HTTPRequestOptions . OnStreamComplete = { result in
290- print ( result)
291-
292- semaphore. signal ( )
293- }
294-
295275 let httpClientOptions = HTTPClientConnectionOptions ( clientBootstrap: bootstrap,
296276 hostName: context. url. host!,
297277 initialWindowSize: Int . max,
@@ -302,21 +282,40 @@ struct Elasticurl {
302282 monitoringOptions: nil )
303283
304284 let connectionManager = try HTTPClientConnectionManager ( options: httpClientOptions)
305- do {
306- let connection = try await connectionManager. acquireConnection ( )
307- let requestOptions = HTTPRequestOptions ( request: httpRequest,
308- onResponse: onResponse,
309- onIncomingBody: onBody,
310- onStreamComplete: onComplete)
311- stream = try connection. makeRequest ( requestOptions: requestOptions)
312- try stream!. activate ( )
285+ let connection = try await connectionManager. acquireConnection ( )
286+ try await withCheckedThrowingContinuation { continuation in
287+ let onResponse : HTTPRequestOptions . OnResponse = { _, headers in
288+ for header in headers {
289+ print ( header. name + " : " + header. value)
290+ }
291+ }
313292
314- } catch {
315- print ( " connection has shut down with error: \( error. localizedDescription) " )
316- semaphore. signal ( )
293+ let onBody : HTTPRequestOptions . OnIncomingBody = { bodyChunk in
294+ writeData ( data: bodyChunk)
295+ }
296+
297+ let onComplete : HTTPRequestOptions . OnStreamComplete = { result in
298+ switch result {
299+ case let . success( status) :
300+ print ( " response status: \( status) " )
301+ continuation. resume ( returning: ( ) )
302+ case let . failure( error) :
303+ continuation. resume ( throwing: error)
304+ }
305+ }
306+
307+ do {
308+ let requestOptions = HTTPRequestOptions ( request: httpRequest,
309+ onResponse: onResponse,
310+ onIncomingBody: onBody,
311+ onStreamComplete: onComplete)
312+ stream = try connection. makeRequest ( requestOptions: requestOptions)
313+ try stream!. activate ( )
314+ } catch {
315+ continuation. resume ( throwing: error)
316+ }
317317 }
318318
319- semaphore. wait ( )
320319 exit ( EXIT_SUCCESS)
321320 } catch let err {
322321 showHelp ( )
0 commit comments