Разбор быстрого ответа на запрос на несколько диапазонов - PullRequest
0 голосов
/ 19 октября 2018
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 282

--3d6b6a416f9b5
Content-Type: video/mp4
Content-Range: bytes 0-50/1270

DATA............

--3d6b6a416f9b5
Content-Type: video/mp4
Content-Range: bytes 100-150/1270

eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--

Это пример ответа, который я получил от Mozilla.Я использую swift и создаю запрос диапазона из нескольких частей, используя URLSession.Я получаю ответ, который я конвертирую в [UInt8], а также String с кодировкой ascii, я могу получить граничную строку.Но мне интересно, как я могу извлечь только контент внутри каждого запроса диапазона, надежно независимо от типа контента и диапазона контента.Я понимаю, что могу получить блоки --3d6b6a416f9b5 .... --3d6b6a416f9b5, но как точно удалить заголовок содержимого.

let ranges : [(Int, Int)] = [...]
var range_request = "bytes="
for r in ranges {
    range_request += "\(r.0)-\(r.1), "
}
range_request = String(range_request.dropLast(2))
var streamRequest = URLRequest(url: streamURL)
streamRequest.setValue(range_request, forHTTPHeaderField: "Range")
let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 1
let session = URLSession(configuration: sessionConfig)
let task = session.downloadTask(with: streamRequest) { (tempLocalURL, response, url_error) in
    if url_error != nil {
        //handle error
    } else {
        do {
            //assume successful 206 response for now...
            let httpResponse = response as! HTTPURLResponse 
            let data = try Data(contentsOf: tempLocalURL!)
            let boundaryPhrase = (httpResponse.allHeaderFields["Content-Type"]! as! String).replacingOccurrences(of: "multipart/byteranges; boundary=", with: "")
            let totalData = [UInt8](data)
            let stringTotalData = (String(data: data, encoding: .ascii)!

        } catch {
            //handle error
        }
    }
}
task.resume()

1 Ответ

0 голосов
/ 20 октября 2018
let data = try Data(contentsOf: tempLocalURL!)
let content_type = httpResponse.allHeaderFields["Content-Type"]! as! String
let boundary_word = content_type.replacingOccurrences(of: "multipart/byteranges; boundary=", with: "")
let boundary_phrase = "--\(boundary_word)"
let input_data = [UInt8](data)
var bodies : [[UInt8]] = []
var current_body = 0
if boundary_word != "video/mp4" {
    let boundary_phrase_ints = [UInt8](boundary_phrase.utf8)
    let header_end_ints = [UInt8]("\r\n\r\n".utf8)
    var i = 0
    var potential_body : [UInt8] = []
    while i < (input_data.count - boundary_phrase_ints.count) {
        if potential_body == boundary_phrase_ints {
            let potential_end_header = Array(input_data[i..<(i + header_end_ints.count)])
            if potential_end_header == header_end_ints {
                let start = i + header_end_ints.count
                let upper_limit = start + ranges[current_body].1 - ranges[current_body].0
                bodies.append(Array(input_data[start...upper_limit]))
                current_body += 1
                i = upper_limit
            }
        } else {
            potential_body = Array(input_data[i..<(i + boundary_phrase_ints.count)])
            if potential_body == boundary_phrase_ints {
                i += boundary_phrase_ints.count
            }
        }
        i += 1
    }
    //in my case I don't need to split the data into separate ranges.
} else {
    //handle single range case
}

Итак, я смог решить проблему.Вот мой код.В моем случае мне нужно обрабатывать данные как [UInt8], так как это было видео, которое я запрашивал, поэтому мне пришлось преобразовать граничную фразу в [UInt8], а также конец заголовка.

Таким образом, используя граничную фразу, вы можете извлечь каждое тело - если вы сделали это со строкой, вы можете просто сделать компоненты и удалить первый и последний элементы, так как они являются поддельными.Далее внутри каждого тела вы можете найти конец заголовка, ища «\ r \ n \ r \ n», который кажется уникальным.

...