Created
January 3, 2014 18:28
-
-
Save wader/8243459 to your computer and use it in GitHub Desktop.
Parse multipart byte ranges mime
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # multipart byte ranges mime -> [[offset, content], ...] | |
| def parse_multipart_byteranges(body, content_type) | |
| # match boundary=... | |
| match = /boundary=(.*)$/.match(content_type) | |
| return nil if match.nil? | |
| boundary = match[1] | |
| # (\r\n)--boundary\r\npart\r\n--boundary(--)\r\n -> [part, ..] | |
| parts = body.split(/(?:\r\n)?--#{boundary}(?:--)?\r\n/) | |
| ranges = [] | |
| total_length = 0 | |
| parts.each do |part| | |
| # filter out empty parts | |
| next if /\A\s*\Z/.match(part) | |
| # key: value\r\nkey: value\r\n\r\nbody -> [key: value, body] | |
| part_header, part_body = part.split("\r\n\r\n", 2) | |
| return nil if part_body.nil? | |
| # key: value\r\n -> {key: value} | |
| headers = Hash[part_header.lines.map do |line| | |
| line.strip! | |
| key, value = line.split(/:\s*/, 2) | |
| return nil if value.nil? | |
| [key.downcase, value] | |
| end] | |
| content_range = headers["content-range"] | |
| return nil if content_range.nil? | |
| # match bytes offset-length/total_length | |
| match = /^bytes (\d+)-(\d+)\/(\d+)$/.match(content_range) | |
| return nil if match.nil? | |
| offset, length, total_length = match[1].to_i, match[2].to_i, match[3].to_i | |
| ranges << [offset, part_body[0,length]] | |
| end | |
| return ranges, total_length | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment