Skip to content

Commit

Permalink
An easy way to access cookies in RestResponse (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
RudraniW authored and djones6 committed Aug 15, 2019
1 parent 5050b47 commit c41343a
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 29 deletions.
101 changes: 73 additions & 28 deletions Sources/SwiftyRequest/RestRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,26 @@ public class RestRequest: NSObject {
}
}

// Function to get cookies from HTTPURLResponse headers.
private func getCookies(from response: HTTPURLResponse?) -> [HTTPCookie]? {
guard let headers = response?.allHeaderFields else {
return nil
}
var headerFields = [String : String]()
for (key, value) in headers {
guard let key = key as? String, let value = value as? String else {
continue
}
headerFields[key] = value
}
guard headerFields["Set-Cookie"] != nil else {
return nil
}
let url = response?.url
let dummyUrl = URL(string:"http://example.com")!
return HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url ?? dummyUrl)
}

/// Request response method with the expected result of a `Data` object.
///
/// - Parameters:
Expand All @@ -340,7 +360,7 @@ public class RestRequest: NSObject {

if let error = performSubstitutions(params: templateParams) {
let result = Result<Data>.failure(error)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result, cookies: nil)
completionHandler(dataResponse)
return
}
Expand All @@ -355,19 +375,22 @@ public class RestRequest: NSObject {

if let error = error {
let result = Result<Data>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

guard let data = data else {
let result = Result<Data>.failure(RestError.noData)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}
let result = Result.success(data)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
}
}
Expand All @@ -389,7 +412,7 @@ public class RestRequest: NSObject {

if let error = performSubstitutions(params: templateParams) {
let result = Result<T>.failure(error)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result, cookies: nil)
completionHandler(dataResponse)
return
}
Expand All @@ -404,23 +427,26 @@ public class RestRequest: NSObject {

if let error = error {
let result = Result<T>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

if let responseToError = responseToError,
let error = responseToError(response, data) {
let result = Result<T>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

// ensure data is not nil
guard let data = data else {
let result = Result<T>.failure(RestError.noData)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}
Expand Down Expand Up @@ -449,7 +475,8 @@ public class RestRequest: NSObject {
}

// execute callback
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
}
}
Expand All @@ -469,7 +496,7 @@ public class RestRequest: NSObject {

if let error = performSubstitutions(params: templateParams) {
let result = Result<T>.failure(error)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result, cookies: nil)
completionHandler(dataResponse)
return
}
Expand All @@ -484,15 +511,17 @@ public class RestRequest: NSObject {

if let error = error ?? responseToError?(response, data) {
let result = Result<T>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

// ensure data is not nil
guard let data = data else {
let result = Result<T>.failure(RestError.noData)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}
Expand All @@ -507,7 +536,8 @@ public class RestRequest: NSObject {
}

// execute callback
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
}
}
Expand All @@ -529,7 +559,7 @@ public class RestRequest: NSObject {

if let error = performSubstitutions(params: templateParams) {
let result = Result<[T]>.failure(error)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result, cookies: nil)
completionHandler(dataResponse)
return
}
Expand All @@ -544,23 +574,26 @@ public class RestRequest: NSObject {

if let error = error {
let result = Result<[T]>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

if let responseToError = responseToError,
let error = responseToError(response, data) {
let result = Result<[T]>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

// ensure data is not nil
guard let data = data else {
let result = Result<[T]>.failure(RestError.noData)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}
Expand Down Expand Up @@ -590,7 +623,8 @@ public class RestRequest: NSObject {
}

// execute callback
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
}
}
Expand All @@ -610,7 +644,7 @@ public class RestRequest: NSObject {

if let error = performSubstitutions(params: templateParams) {
let result = Result<String>.failure(error)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result, cookies: nil)
completionHandler(dataResponse)
return
}
Expand All @@ -625,23 +659,26 @@ public class RestRequest: NSObject {

if let error = error {
let result = Result<String>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

if let responseToError = responseToError,
let error = responseToError(response, data) {
let result = Result<String>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

// ensure data is not nil
guard let data = data else {
let result = Result<String>.failure(RestError.noData)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}
Expand All @@ -652,14 +689,16 @@ public class RestRequest: NSObject {
// parse data as a string
guard let string = String(data: data, encoding: encoding) else {
let result = Result<String>.failure(RestError.serializationError)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: nil, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

// execute callback
let result = Result.success(string)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
}
}
Expand All @@ -679,7 +718,7 @@ public class RestRequest: NSObject {

if let error = performSubstitutions(params: templateParams) {
let result = Result<Void>.failure(error)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result)
let dataResponse = RestResponse(request: request, response: nil, data: nil, result: result, cookies: nil)
completionHandler(dataResponse)
return
}
Expand All @@ -694,21 +733,24 @@ public class RestRequest: NSObject {

if let error = error {
let result = Result<Void>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

if let responseToError = responseToError, let error = responseToError(response, data) {
let result = Result<Void>.failure(error)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
return
}

// execute callback
let result = Result<Void>.success(())
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result)
let cookies = self.getCookies(from: response)
let dataResponse = RestResponse(request: self.request, response: response, data: data, result: result, cookies: cookies)
completionHandler(dataResponse)
}
}
Expand Down Expand Up @@ -852,6 +894,9 @@ public struct RestResponse<T> {

/// The Reponse Result.
public let result: Result<T>

/// The cookies from HTTPURLResponse
public let cookies: [HTTPCookie]?
}

/// Enum to differentiate a success or failure.
Expand Down
25 changes: 25 additions & 0 deletions TestServer/Sources/TestServer/main.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
import Kitura
import HeliumLogger
import FileKit
import Foundation
#if swift(>=4.1)
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
#endif

func cookieHandler(request: RouterRequest, response: RouterResponse, next: @escaping () -> Void) throws {
let number = request.parameters["number"].map { Int($0) ?? 0 } ?? 0
for no in 0..<number {
var cookieProps: [HTTPCookiePropertyKey: Any]
cookieProps = [
HTTPCookiePropertyKey.domain: "localhost",
HTTPCookiePropertyKey.path: "/",
HTTPCookiePropertyKey.name: "name\(no)",
HTTPCookiePropertyKey.value: "value\(no)",
]
let cookie = HTTPCookie(properties: cookieProps)
response.cookies["name\(no)"] = cookie
}
try response.status(.OK).end()
}

// Enable logging
HeliumLogger.use(.info)
Expand Down Expand Up @@ -40,6 +62,7 @@ router.post("/echoJSON") {
try response.status(.badRequest).end()
}
}
router.get("/cookies/:number", handler: cookieHandler)

// Create a router that will be used for SSL requests
let sslRouter = Router()
Expand Down Expand Up @@ -82,6 +105,8 @@ sslRouter.get("/ssl/friends") {
try response.send(json: friends).end()
}

sslRouter.get("/ssl/cookies/:number", handler: cookieHandler)

// Add an HTTP server and connect it to the router
Kitura.addHTTPServer(onPort: 8080, with: router)
Kitura.addHTTPServer(onPort: 8443, with: sslRouter, withSSL: sslConfig)
Expand Down
Loading

0 comments on commit c41343a

Please sign in to comment.