Skip to content

Instantly share code, notes, and snippets.

@ilyapuchka
Last active February 11, 2017 12:57
Show Gist options
  • Save ilyapuchka/c9c3efb405e30207e6dd3003df3ec4c9 to your computer and use it in GitHub Desktop.
Save ilyapuchka/c9c3efb405e30207e6dd3003df3ec4c9 to your computer and use it in GitHub Desktop.
import XCTest
import Ambassador
import Embassy
class EmbassyRedirectUITests: XCTestCase {
var app: XCUIApplication!
var router: Router!
private var eventLoop: EventLoop!
private var server: HTTPServer!
private var eventLoopThreadCondition: NSCondition!
private var eventLoopThread: Thread!
func startHTTPServer() {
self.eventLoop = try! SelectorEventLoop(selector: try! KqueueSelector())
self.router = Router()
self.router.notFoundResponse = RedirectResponse(scheme: "http", host: "httpbin.org", queryOverride: [:])
let server = DefaultHTTPServer(eventLoop: self.eventLoop, port: 8080, app: self.router.app)
server.logger.add(handler: PrintLogHandler())
self.server = server
try! self.server.start()
self.eventLoopThreadCondition = NSCondition()
self.eventLoopThread = Thread(target: self, selector: #selector(self.runEventLoop), object: nil)
self.eventLoopThread.start()
}
func stopHTTPServer() {
self.server.stop()
self.eventLoopThreadCondition.lock()
self.eventLoop.stop()
while self.eventLoop.running {
if !self.eventLoopThreadCondition.wait(until: Date().addingTimeInterval(10)) {
fatalError("Join eventLoopThread timeout")
}
}
}
@objc func runEventLoop() {
self.eventLoop.runForever()
self.eventLoopThreadCondition.lock()
self.eventLoopThreadCondition.signal()
self.eventLoopThreadCondition.unlock()
}
override func setUp() {
super.setUp()
startHTTPServer()
continueAfterFailure = false
app = XCUIApplication()
app.launch()
}
override func tearDown() {
super.tearDown()
app.terminate()
stopHTTPServer()
}
func testExample() {
_ = expectation(description: "")
waitForExpectations(timeout: 5, handler: nil)
}
}
import Embassy
import Ambassador
import Foundation
struct RedirectResponse: WebApp {
let host: String
let scheme: String
let queryOverride: [String: String]
init(scheme: String, host: String, queryOverride: [String: String]) {
self.host = host
self.scheme = scheme
self.queryOverride = queryOverride
}
func urlRequest(_ environ: [String: Any]) -> URLRequest {
var environ = environ
environ["HTTP_HOST"] = nil
var components = URLComponents()
components.scheme = scheme
components.host = host
components.path = environ["PATH_INFO"] as! String
components.query = environ["QUERY_STRING"] as? String
var url = components.url!
components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
components.queryItems = components.queryItems?.map({ (item) in
var item = item
item.value = queryOverride[item.name] ?? item.value
return item
})
url = components.url!
//All http headers are fucked up at this point...
var headers: [String: String] = [:]
for (key, value) in environ {
guard key.hasPrefix("HTTP_") else { continue }
let key = String(key.characters.dropFirst("HTTP_".characters.count)).replacingOccurrences(of: "_", with: "-")
headers[key] = value as? String
}
//URLSession will automatically decompress data but Content-Encoding reponse header will be "gzip",
//so we request content as it is so that it can be correcty read by client
headers["Accept-Encoding"] = "identity"
var request = URLRequest(url: url)
request.httpMethod = environ["REQUEST_METHOD"] as? String
request.allHTTPHeaderFields = headers
return request
}
public func app(_ environ: [String : Any], startResponse: @escaping ((String, [(String, String)]) -> Swift.Void), sendBody: @escaping ((Data) -> Swift.Void)) {
var request = urlRequest(environ)
let input = environ["swsgi.input"] as! SWSGIInput
DataReader.read(input) { data in
do {
print(try JSONSerialization.jsonObject(with: data, options: []))
} catch {}
request.httpBody = data
URLSession.shared.dataTask(with: request) { (_data, _response, error) in
let response = _response as! HTTPURLResponse
let statusCode = response.statusCode
let headers = response.allHeaderFields.map({ ($0 as! String, $1 as! String) })
startResponse("\(statusCode)", headers)
if !data.isEmpty {
sendBody(data)
}
sendBody(Data())
}.resume()
}
}
}
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var request = URLRequest(url: URL(string: "http://localhost:8080/post")!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject: ["key": "value"], options: [])
let task = URLSession.shared.dataTask(with: request) { (data, url, error) in
if let data = data, !data.isEmpty {
do {
try print(JSONSerialization.jsonObject(with: data, options: []))
} catch {
print("\(error)")
}
} else {
print("empty data")
}
}
task.resume()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment