Skip to content

Commit

Permalink
Fix baseUri should provide correct value for ANY_ADDRESS. (#563)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheatfate authored Jan 13, 2025
1 parent 70cbe34 commit 7c5cbf0
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 81 deletions.
73 changes: 34 additions & 39 deletions chronos/apps/http/httpserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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*(
Expand Down
79 changes: 37 additions & 42 deletions chronos/apps/http/shttpserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
37 changes: 37 additions & 0 deletions tests/testhttpserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()
46 changes: 46 additions & 0 deletions tests/testshttpserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 7c5cbf0

Please sign in to comment.