Created
August 23, 2019 00:03
-
-
Save julik/2bfc895e796531dcb6baf1bd6e7e0dc5 to your computer and use it in GitHub Desktop.
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
class MultipartRangesWriter | |
ALPHABET = ('0'..'9').to_a + ('a'..'z').to_a + ('A'..'Z').to_a | |
def initialize | |
# RFC1521 says that a boundary "must be no longer than 70 characters, not counting the two leading hyphens". | |
# Modulo-based random is biased but it doesn't matter much for us | |
@boundary = SecureRandom.bytes(64).unpack("C*").map {|b| ALPHABET[b % ALPHABET.length] }.join | |
end | |
class NullWriter < Struct.new(:offset) | |
def write(str) | |
advance(str.bytesize) | |
end | |
def advance(by) | |
self.offset += by | |
end | |
end | |
def content_type_header_value | |
"multipart/byte-ranges; boundary=#{@boundary}" | |
end | |
# Compute the full length of the MIME message with all the parts, | |
# headers and whatnot | |
def full_message_length(*http_ranges) | |
writer = NullWriter.new(0) | |
http_ranges.each.with_index do |range, i| | |
write_boundary_and_headers(writer, i, range.begin, range.end) | |
writer.advance(range.end - range.begin + 1) | |
end | |
writer.offset | |
end | |
def write_boundary_and_headers(socket, part_index, http_range) | |
range_size = http_range.end - http_range.begin + 1 | |
if part_index > 0 | |
socket.write("\r\n") | |
end | |
socket.write("--#{@boundary}\r\n") | |
socket.write("Content-Type: binary/octet-stream\r\n") | |
socket.write("Content-Range: bytes #{http_range.begin}-#{http_range.end}/#{range_size}\r\n") | |
socket.write("\r\n") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment