Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HBResponse.redirect #174

Merged
merged 2 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions Sources/Hummingbird/Server/Response.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,47 @@ public struct HBResponse: HBSendableExtensible {
}
}

extension HBResponse {
/// Specifies the type of redirect that the client should receive.
public enum RedirectType {
/// `301 moved permanently`: The URL of the requested resource has been changed permanently.
/// The new URL is iven in the response.
case permanent
/// `302 found`: This response code means that the URI of requested resource has been changed
/// temporarily. Further changes in the URI might be made in the future. Therefore,
/// this same URI should be used by the client in future requests.
case found
/// `303 see other`: The server sent this response to direct the client to get the requested
/// resource at another URI with a GET request.
case normal
/// `307 Temporary`: The server sends this response to direct the client to get the requested
/// resource at another URI with the same method that was used in the prior request. This has
/// the same semantics as the 302 Found HTTP response code, with the exception that the user
/// agent must not change the HTTP method used: if a POST was used in the first request, a POST
/// must be used in the second request.
case temporary

/// Associated `HTTPResponseStatus` for this redirect type.
public var status: HTTPResponseStatus {
switch self {
case .permanent: return .movedPermanently
case .found: return .found
case .normal: return .seeOther
case .temporary: return .temporaryRedirect
}
}
}

/// Create a redirect response
/// - Parameters:
/// - location: Location to redirect to
/// - type: Redirection type
/// - Returns: HBResponse with redirection
public static func redirect(to location: String, type: RedirectType = .normal) -> HBResponse {
return .init(status: type.status, headers: ["location": location])
}
}

extension HBResponse: CustomStringConvertible {
public var description: String {
"status: \(self.status), headers: \(self.headers), body: \(self.body)"
Expand Down
15 changes: 15 additions & 0 deletions Tests/HummingbirdTests/RouterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,21 @@ final class RouterTests: XCTestCase {
XCTAssertEqual(id2, id + 1)
}
}

// Test redirect response
func testRedirect() throws {
let app = HBApplication(testing: .embedded)
app.router.get("redirect") { _ in
return HBResponse.redirect(to: "/other")
}
try app.XCTStart()
defer { app.XCTStop() }

try app.XCTExecute(uri: "/redirect", method: .GET) { response in
XCTAssertEqual(response.headers["location"].first, "/other")
XCTAssertEqual(response.status, .seeOther)
}
}
}

extension HBRequest {
Expand Down