Skip to content
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
30 changes: 29 additions & 1 deletion DanXi Kit/Utils/Proxy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ public class Proxy {
ProxySettings.shared.enableProxy && FudanKit.CredentialStore.shared.credentialPresent
}

private func validateResponse(_ response: URLResponse) -> Bool {
/**
WebVPN may occasionally return HTML instead of the expected payload; when this occurs, re-authenticate.
This method can be modified to handle other cases where WebVPN returns unexpected responses.
*/

if let mimeType = response.mimeType, mimeType.contains("text/html") {
return false
}
if let httpResponse = response as? HTTPURLResponse,
let contentType = httpResponse.value(forHTTPHeaderField: "Content-Type"),
contentType.contains("text/html") {
return false
}

return true
}

func upload(for request: URLRequest, from bodyData: Data) async throws -> (Data, URLResponse) {
guard shouldTryProxy, outsideCampus else {
return try await URLSession.shared.upload(for: request, from: bodyData)
Expand All @@ -20,6 +38,9 @@ public class Proxy {
let proxiedRequest = createProxiedRequest(request: request)
// we do not try to relogin here, because it's highly unlikely to fail
return try await URLSession.shared.upload(for: proxiedRequest, from: bodyData)

// this method is not used yet so no validateResponse check for now
// todo: add validateResponse to this method when being used
}

func data(for request: URLRequest) async throws -> (Data, URLResponse) {
Expand Down Expand Up @@ -59,7 +80,14 @@ public class Proxy {
// use proxy

let proxiedRequest = createProxiedRequest(request: request)
return try await FudanKit.Authenticator.neo.authenticateRequest(request: proxiedRequest, loginURL: URL(string: "https://webvpn.fudan.edu.cn/login?cas_login=true")!)
let (data, response) = try await FudanKit.Authenticator.neo.authenticateRequest(request: proxiedRequest, loginURL: URL(string: "https://webvpn.fudan.edu.cn/login?cas_login=true")!)

// check if webvpn returns the correct data format
if validateResponse(response) {
return (data, response)
} else {
return try await FudanKit.Authenticator.neo.authenticateRequest(request: proxiedRequest, loginURL: URL(string: "https://webvpn.fudan.edu.cn/login?cas_login=true")!, forceRelogin: true)
}
}

public func createProxiedURL(url: URL) -> URL {
Expand Down
4 changes: 2 additions & 2 deletions Fudan Kit/Authentication/Authenticator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public actor Authenticator {
throw CampusError.loginFailed
}

public func authenticateRequest(request: URLRequest, loginURL: URL) async throws -> (Data, URLResponse) {
public func authenticateRequest(request: URLRequest, loginURL: URL, forceRelogin: Bool = false) async throws -> (Data, URLResponse) {
guard let host = request.url?.host else { throw LocatableError() }

if !isLogged(host: host) {
if (!isLogged(host: host) || forceRelogin) {
_ = try await performAuthenticate(url: loginURL)
}

Expand Down