Skip to content

Instantly share code, notes, and snippets.

@spacelatte
Created July 18, 2017 21:44
Show Gist options
  • Save spacelatte/9d8c810a8ed1475d88a1f4258ad4e754 to your computer and use it in GitHub Desktop.
Save spacelatte/9d8c810a8ed1475d88a1f4258ad4e754 to your computer and use it in GitHub Desktop.
hn login test using plain swift 3
//: Playground - noun: a place where people can play
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
var cookie: String? = nil
let info: [String : Any] = [
"timeout": 30.0,
"auth": "https://news.ycombinator.com/login",
"post": "https://news.ycombinator.com/r",
"user": "{theusername}",
"pass": "{thepassword}",
]
func isSuccessful(status: Int) -> Bool{
return (status == 302)
}
func getCookie(_ cookie: String, param: String) -> String? {
let param = param.appending("=")
let parts = cookie.components(separatedBy: " ")
for part in parts {
if part.characters.count < param.characters.count {
continue
}
let index = part.index(part.startIndex, offsetBy: param.characters.count)
let search = part.substring(to: index)
if search.contains(param) {
return part.substring(
with: part.index(part.startIndex, offsetBy: param.characters.count)..<part.index(part.endIndex, offsetBy: -1)
)
}
}
return nil
}
func createLoginRequestBody(user: String, pass: String) -> Data {
let charset = CharacterSet.urlHostAllowed
let base = "goto=news"
let user = user.addingPercentEncoding(withAllowedCharacters: charset)
let pass = pass.addingPercentEncoding(withAllowedCharacters: charset)
let param = "\(base)&acct=\(user!)&pw=\(pass!)"
return param.data(using: .utf8)!
}
func createPostRequestBody(title: String, url: String?, text: String?) -> Data {
let charset = CharacterSet.urlHostAllowed
let base = "fnop=submit-page"
let title = title.addingPercentEncoding(withAllowedCharacters: charset)
let text = text?.addingPercentEncoding(withAllowedCharacters: charset)
let url = url?.addingPercentEncoding(withAllowedCharacters: charset)
let param = "\(base)&title=\(title!)&url=\(url!)&text=\(text!)"
return param.data(using: .utf8)!
}
func createRequest(type: String, url: String, body: Data?) -> URLRequest {
var request = URLRequest(
url: URL(string: url)!,
cachePolicy: .reloadRevalidatingCacheData,
timeoutInterval: info["timeout"] as! Double
)
request.addValue("identity", forHTTPHeaderField: "Accept-Encoding")
request.httpShouldUsePipelining = false
request.httpShouldHandleCookies = true
request.httpMethod = type
request.httpBody = body
return request
}
let credentials = createLoginRequestBody(
user: info["user"] as! String,
pass: info["pass"] as! String
)
let loginRequest = createRequest(
type: "POST",
url: info["auth"] as! String,
body: credentials
)
let postBody = createPostRequestBody(
title: "test post here",
url: "http://google.com",
text: "test google test"
)
var postRequest = createRequest(
type: "POST",
url: info["post"] as! String,
body: postBody
)
class Delegate: NSObject, URLSessionDelegate, URLSessionTaskDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
print("delegate:", 1, "redirect")
// print(session.debugDescription)
// print(response)
// print(request)
// print(task.response)
completionHandler(request)
return
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("delegate:", 2, "???")
print(session.sessionDescription)
print(challenge.debugDescription)
completionHandler(.performDefaultHandling, nil)
return
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print("delegate:", 3, "error")
// print(session.debugDescription)
// print(task.debugDescription)
// print(error.debugDescription)
print(task.response, error?.localizedDescription)
return
}
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print("delegate:", 4, "???")
// print(session.debugDescription)
print(challenge.debugDescription)
print(task.response!)
completionHandler(.performDefaultHandling, nil)
return
}
}
class PostDelegate: Delegate {
var token: String? = nil
override func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
completionHandler(request)
return
}
override func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
URLSession(
configuration: .ephemeral,
delegate: self,
delegateQueue: OperationQueue()
).dataTask(with: createRequest(
type: "GET",
url: "https://news.ycombinator.com/submit",
body: nil
)).resume()
return
}
}
class LoginDelegate: Delegate {
override func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
completionHandler(request)
print("status:", isSuccessful(status: response.statusCode))
cookie = getCookie(response.allHeaderFields["Set-Cookie"] as! String, param: "user")
postRequest.setValue("user=\(cookie!);", forHTTPHeaderField: "Cookie")
URLSession(
configuration: .ephemeral,
delegate: PostDelegate(),
delegateQueue: OperationQueue()
).dataTask(with: postRequest).resume()
print(cookie!, String(data: postBody, encoding: .utf8)!)
return
}
}
URLSession(
configuration: .ephemeral,
delegate: LoginDelegate(),
delegateQueue: OperationQueue()
).dataTask(with: loginRequest).resume()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment