mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Pad proxied request sizes.
This commit is contained in:
parent
daa58c2ac8
commit
40768825c8
1 changed files with 57 additions and 0 deletions
|
@ -669,6 +669,7 @@ open class ProxiedContentDownloader: NSObject, URLSessionTaskDelegate, URLSessio
|
||||||
request.httpShouldUsePipelining = true
|
request.httpShouldUsePipelining = true
|
||||||
let rangeHeaderValue = "bytes=\(segmentStart)-\(segmentStart + segmentLength - 1)"
|
let rangeHeaderValue = "bytes=\(segmentStart)-\(segmentStart + segmentLength - 1)"
|
||||||
request.addValue(rangeHeaderValue, forHTTPHeaderField: "Range")
|
request.addValue(rangeHeaderValue, forHTTPHeaderField: "Range")
|
||||||
|
padRequestSize(request: &request)
|
||||||
let task = downloadSession.dataTask(with: request, completionHandler: { data, response, error -> Void in
|
let task = downloadSession.dataTask(with: request, completionHandler: { data, response, error -> Void in
|
||||||
self.handleAssetSizeResponse(assetRequest: assetRequest, data: data, response: response, error: error)
|
self.handleAssetSizeResponse(assetRequest: assetRequest, data: data, response: response, error: error)
|
||||||
})
|
})
|
||||||
|
@ -688,6 +689,7 @@ open class ProxiedContentDownloader: NSObject, URLSessionTaskDelegate, URLSessio
|
||||||
request.httpShouldUsePipelining = true
|
request.httpShouldUsePipelining = true
|
||||||
let rangeHeaderValue = "bytes=\(assetSegment.segmentStart)-\(assetSegment.segmentStart + assetSegment.segmentLength - 1)"
|
let rangeHeaderValue = "bytes=\(assetSegment.segmentStart)-\(assetSegment.segmentStart + assetSegment.segmentLength - 1)"
|
||||||
request.addValue(rangeHeaderValue, forHTTPHeaderField: "Range")
|
request.addValue(rangeHeaderValue, forHTTPHeaderField: "Range")
|
||||||
|
padRequestSize(request: &request)
|
||||||
let task: URLSessionDataTask = downloadSession.dataTask(with: request)
|
let task: URLSessionDataTask = downloadSession.dataTask(with: request)
|
||||||
task.assetRequest = assetRequest
|
task.assetRequest = assetRequest
|
||||||
task.assetSegment = assetSegment
|
task.assetSegment = assetSegment
|
||||||
|
@ -699,6 +701,61 @@ open class ProxiedContentDownloader: NSObject, URLSessionTaskDelegate, URLSessio
|
||||||
processRequestQueueSync()
|
processRequestQueueSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func padRequestSize(request: inout URLRequest) {
|
||||||
|
guard let sizeEstimate: UInt = estimateRequestSize(request: request) else {
|
||||||
|
owsFailDebug("Could not estimate request size.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// We pad the estimated size to an even multiple of paddingQuantum (plus the
|
||||||
|
// extra ": " and "\r\n"). The exact size doesn't matter so long as the
|
||||||
|
// padding is consistent.
|
||||||
|
let paddingQuantum: UInt = 1024
|
||||||
|
let paddingSize = paddingQuantum - (sizeEstimate % paddingQuantum)
|
||||||
|
let padding = String(repeating: ".", count: Int(paddingSize))
|
||||||
|
request.addValue(padding, forHTTPHeaderField: "SignalPadding")
|
||||||
|
}
|
||||||
|
|
||||||
|
private func estimateRequestSize(request: URLRequest) -> UInt? {
|
||||||
|
// iOS doesn't offer an exact way to measure request sizes on the wire,
|
||||||
|
// but we can reliably estimate request sizes using the "knowns", e.g.
|
||||||
|
// HTTP method, path, querystring, headers. The "unknowns" should be
|
||||||
|
// consistent between requests.
|
||||||
|
|
||||||
|
guard let url = request.url?.absoluteString else {
|
||||||
|
owsFailDebug("Request missing URL.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
guard let components = URLComponents(string: url) else {
|
||||||
|
owsFailDebug("Request has invalid URL.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result: Int = 0
|
||||||
|
|
||||||
|
if let httpMethod = request.httpMethod {
|
||||||
|
result += httpMethod.count
|
||||||
|
}
|
||||||
|
result += components.percentEncodedPath.count
|
||||||
|
if let percentEncodedQuery = components.percentEncodedQuery {
|
||||||
|
result += percentEncodedQuery.count
|
||||||
|
}
|
||||||
|
if let allHTTPHeaderFields = request.allHTTPHeaderFields {
|
||||||
|
if allHTTPHeaderFields.count != 1 {
|
||||||
|
owsFailDebug("Request has unexpected number of headers.")
|
||||||
|
}
|
||||||
|
for (key, value) in allHTTPHeaderFields {
|
||||||
|
// Each header has 4 extra bytes:
|
||||||
|
//
|
||||||
|
// * Two for the key/value separator ": "
|
||||||
|
// * Two for "\r\n", the line break in the HTTP protocol spec.
|
||||||
|
result += key.count + value.count + 4
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
owsFailDebug("Request has no headers.")
|
||||||
|
}
|
||||||
|
return UInt(result)
|
||||||
|
}
|
||||||
|
|
||||||
private func handleAssetSizeResponse(assetRequest: ProxiedContentAssetRequest, data: Data?, response: URLResponse?, error: Error?) {
|
private func handleAssetSizeResponse(assetRequest: ProxiedContentAssetRequest, data: Data?, response: URLResponse?, error: Error?) {
|
||||||
guard error == nil else {
|
guard error == nil else {
|
||||||
assetRequest.state = .failed
|
assetRequest.state = .failed
|
||||||
|
|
Loading…
Reference in a new issue