From 7c5cbf04a6bb2258654f16cb1d51b4304986cfd1 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Mon, 13 Jan 2025 18:31:36 +0200 Subject: [PATCH] Fix baseUri should provide correct value for ANY_ADDRESS. (#563) --- chronos/apps/http/httpserver.nim | 73 +++++++++++++--------------- chronos/apps/http/shttpserver.nim | 79 +++++++++++++++---------------- tests/testhttpserver.nim | 37 +++++++++++++++ tests/testshttpserver.nim | 46 ++++++++++++++++++ 4 files changed, 154 insertions(+), 81 deletions(-) diff --git a/chronos/apps/http/httpserver.nim b/chronos/apps/http/httpserver.nim index 1adb8fc..aa295d4 100644 --- a/chronos/apps/http/httpserver.nim +++ b/chronos/apps/http/httpserver.nim @@ -252,47 +252,42 @@ proc new*( dualstack = DualStackType.Auto, middlewares: openArray[HttpServerMiddlewareRef] = [] ): HttpResult[HttpServerRef] = - - let serverUri = - if len(serverUri.hostname) > 0: - serverUri - else: + let + serverInstance = try: - parseUri("http://" & $address & "/") - except TransportAddressError as exc: + createStreamServer(address, flags = socketFlags, bufferSize = bufferSize, + backlog = backlogSize, dualstack = dualstack) + except TransportOsError as exc: return err(exc.msg) - - let serverInstance = - try: - createStreamServer(address, flags = socketFlags, bufferSize = bufferSize, - backlog = backlogSize, dualstack = dualstack) - except TransportOsError as exc: - return err(exc.msg) - - var res = HttpServerRef( - address: serverInstance.localAddress(), - instance: serverInstance, - processCallback: processCallback, - createConnCallback: createConnection, - baseUri: serverUri, - serverIdent: serverIdent, - flags: serverFlags, - socketFlags: socketFlags, - maxConnections: maxConnections, - bufferSize: bufferSize, - backlogSize: backlogSize, - headersTimeout: httpHeadersTimeout, - maxHeadersSize: maxHeadersSize, - maxRequestBodySize: maxRequestBodySize, - # semaphore: - # if maxConnections > 0: - # newAsyncSemaphore(maxConnections) - # else: - # nil - lifetime: newFuture[void]("http.server.lifetime"), - connections: initOrderedTable[string, HttpConnectionHolderRef](), - middlewares: prepareMiddlewares(processCallback, middlewares) - ) + serverUri = + if len(serverUri.hostname) > 0: + serverUri + else: + parseUri("http://" & $serverInstance.localAddress() & "/") + res = HttpServerRef( + address: serverInstance.localAddress(), + instance: serverInstance, + processCallback: processCallback, + createConnCallback: createConnection, + baseUri: serverUri, + serverIdent: serverIdent, + flags: serverFlags, + socketFlags: socketFlags, + maxConnections: maxConnections, + bufferSize: bufferSize, + backlogSize: backlogSize, + headersTimeout: httpHeadersTimeout, + maxHeadersSize: maxHeadersSize, + maxRequestBodySize: maxRequestBodySize, + # semaphore: + # if maxConnections > 0: + # newAsyncSemaphore(maxConnections) + # else: + # nil + lifetime: newFuture[void]("http.server.lifetime"), + connections: initOrderedTable[string, HttpConnectionHolderRef](), + middlewares: prepareMiddlewares(processCallback, middlewares) + ) ok(res) proc new*( diff --git a/chronos/apps/http/shttpserver.nim b/chronos/apps/http/shttpserver.nim index 532839d..917bae4 100644 --- a/chronos/apps/http/shttpserver.nim +++ b/chronos/apps/http/shttpserver.nim @@ -98,52 +98,47 @@ proc new*(htype: typedesc[SecureHttpServerRef], maxRequestBodySize: int = 1_048_576, dualstack = DualStackType.Auto ): HttpResult[SecureHttpServerRef] = - doAssert(not(isNil(tlsPrivateKey)), "TLS private key must not be nil!") doAssert(not(isNil(tlsCertificate)), "TLS certificate must not be nil!") - - let serverUri = - if len(serverUri.hostname) > 0: - serverUri - else: + let + serverInstance = try: - parseUri("https://" & $address & "/") - except TransportAddressError as exc: + createStreamServer(address, flags = socketFlags, + bufferSize = bufferSize, + backlog = backlogSize, dualstack = dualstack) + except TransportOsError as exc: return err(exc.msg) - - let serverInstance = - try: - createStreamServer(address, flags = socketFlags, bufferSize = bufferSize, - backlog = backlogSize, dualstack = dualstack) - except TransportOsError as exc: - return err(exc.msg) - - let res = SecureHttpServerRef( - address: address, - instance: serverInstance, - processCallback: processCallback, - createConnCallback: createSecConnection, - baseUri: serverUri, - serverIdent: serverIdent, - flags: serverFlags + {HttpServerFlags.Secure}, - socketFlags: socketFlags, - maxConnections: maxConnections, - bufferSize: bufferSize, - backlogSize: backlogSize, - headersTimeout: httpHeadersTimeout, - maxHeadersSize: maxHeadersSize, - maxRequestBodySize: maxRequestBodySize, - # semaphore: - # if maxConnections > 0: - # newAsyncSemaphore(maxConnections) - # else: - # nil - lifetime: newFuture[void]("http.server.lifetime"), - connections: initOrderedTable[string, HttpConnectionHolderRef](), - tlsCertificate: tlsCertificate, - tlsPrivateKey: tlsPrivateKey, - secureFlags: secureFlags - ) + serverUri = + if len(serverUri.hostname) > 0: + serverUri + else: + parseUri("https://" & $serverInstance.localAddress() & "/") + res = SecureHttpServerRef( + address: serverInstance.localAddress(), + instance: serverInstance, + processCallback: processCallback, + createConnCallback: createSecConnection, + baseUri: serverUri, + serverIdent: serverIdent, + flags: serverFlags + {HttpServerFlags.Secure}, + socketFlags: socketFlags, + maxConnections: maxConnections, + bufferSize: bufferSize, + backlogSize: backlogSize, + headersTimeout: httpHeadersTimeout, + maxHeadersSize: maxHeadersSize, + maxRequestBodySize: maxRequestBodySize, + # semaphore: + # if maxConnections > 0: + # newAsyncSemaphore(maxConnections) + # else: + # nil + lifetime: newFuture[void]("http.server.lifetime"), + connections: initOrderedTable[string, HttpConnectionHolderRef](), + tlsCertificate: tlsCertificate, + tlsPrivateKey: tlsPrivateKey, + secureFlags: secureFlags + ) ok(res) proc new*(htype: typedesc[SecureHttpServerRef], diff --git a/tests/testhttpserver.nim b/tests/testhttpserver.nim index 4cc61a0..e472c65 100644 --- a/tests/testhttpserver.nim +++ b/tests/testhttpserver.nim @@ -1790,3 +1790,40 @@ suite "HTTP server testing suite": await server.stop() await server.closeWait() + + asyncTest "HTTP server - baseUri value test": + proc process(r: RequestFence): Future[HttpResponseRef] {. + async: (raises: [CancelledError]).} = + defaultResponse() + + let + expectUri2 = "http://www.chronos-test.com/" + address = initTAddress("127.0.0.1:0") + socketFlags = {ServerFlags.TcpNoDelay, ServerFlags.ReuseAddr} + res1 = HttpServerRef.new(address, process, + socketFlags = socketFlags) + res2 = HttpServerRef.new(address, process, + socketFlags = socketFlags, + serverUri = parseUri(expectUri2)) + check: + res1.isOk == true + res2.isOk == true + + let + server1 = res1.get() + server2 = res2.get() + + try: + server1.start() + server2.start() + let + localAddress = server1.instance.localAddress() + expectUri1 = "http://127.0.0.1:" & $localAddress.port & "/" + check: + server1.baseUri == parseUri(expectUri1) + server2.baseUri == parseUri(expectUri2) + finally: + await server1.stop() + await server1.closeWait() + await server2.stop() + await server2.closeWait() diff --git a/tests/testshttpserver.nim b/tests/testshttpserver.nim index f846d8d..8e82c42 100644 --- a/tests/testshttpserver.nim +++ b/tests/testshttpserver.nim @@ -186,3 +186,49 @@ suite "Secure HTTP server testing suite": return serverRes and data == "EXCEPTION" check waitFor(testHTTPS2(initTAddress("127.0.0.1:30080"))) == true + + asyncTest "HTTPS server - baseUri value test": + proc process(r: RequestFence): Future[HttpResponseRef] {. + async: (raises: [CancelledError]).} = + defaultResponse() + + let + expectUri2 = "https://www.chronos-test.com/" + address = initTAddress("127.0.0.1:0") + socketFlags = {ServerFlags.TcpNoDelay, ServerFlags.ReuseAddr} + serverFlags = {Secure} + secureKey = TLSPrivateKey.init(HttpsSelfSignedRsaKey) + secureCert = TLSCertificate.init(HttpsSelfSignedRsaCert) + res1 = SecureHttpServerRef.new(address, process, + socketFlags = socketFlags, + serverFlags = serverFlags, + tlsPrivateKey = secureKey, + tlsCertificate = secureCert) + res2 = SecureHttpServerRef.new(address, process, + socketFlags = socketFlags, + serverFlags = serverFlags, + serverUri = parseUri(expectUri2), + tlsPrivateKey = secureKey, + tlsCertificate = secureCert) + check: + res1.isOk == true + res2.isOk == true + + let + server1 = res1.get() + server2 = res2.get() + + try: + server1.start() + server2.start() + let + localAddress = server1.instance.localAddress() + expectUri1 = "https://127.0.0.1:" & $localAddress.port & "/" + check: + server1.baseUri == parseUri(expectUri1) + server2.baseUri == parseUri(expectUri2) + finally: + await server1.stop() + await server1.closeWait() + await server2.stop() + await server2.closeWait()