Created
January 25, 2017 18:46
-
-
Save denysvitali/76e5e27b5182717797343de9e9f686a4 to your computer and use it in GitHub Desktop.
This file contains 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
require "./kemal.cr" | |
get "/" do |env| | |
env.response.content_type = "text/html" | |
%(<!DOCTYPE html><html><head><title>Kemal Static Serving Test</title></head><body><h1>Stream test</h1><video controls autoplay><source src="http://dv/video1" type="video/mp4"></video><video controls autoplay><source src="http://dv/nginxstatic/toystory.mp4" type="video/mp4"></video></body></html>) | |
end | |
get "/video1" do |env| | |
env.response.content_type = "video/mp4" | |
video_path = "/srv/http/dv/toystory.mp4" | |
if !File.file?(video_path) | |
env.response.status_code = 404 | |
next "" | |
end | |
if env.request.headers.has_key?("Range") && env.request.method == "GET" | |
puts "STREAM! #{env.request.headers["Range"]}" | |
fileb = File.size(video_path) | |
range = env.request.headers["Range"] | |
match = range.match(/bytes=(\d{1,})-(\d{0,})/) | |
startb = 0 | |
endb = 0 | |
if match | |
if match.size >= 2 | |
#puts "ok" | |
startb = match[1].to_i { 0 } | |
end | |
if match.size >= 3 | |
puts "match size: #{match.size}" | |
endb = match[2].to_i { 0 } | |
end | |
puts "MATCH #{match[1]}, #{match[2]}" | |
end | |
if startb == 0 && endb == 0 | |
startb = 0 | |
endb = fileb | |
elsif endb == 0 | |
endb=fileb | |
#if startb + 114887 > fileb | |
# endb = fileb | |
#else | |
# endb = startb + 114887 | |
#end | |
end | |
puts "#{startb}-#{endb}" | |
# A byte-range-spec is invalid if the last-byte-pos value is present and less than the first-byte-pos. | |
if startb < endb && endb <= fileb | |
env.response.status_code = 206 | |
env.response.headers.add("Content-Length", "#{endb - startb}") | |
env.response.headers.add("Content-Range", "bytes #{startb}-#{endb-1}/#{fileb}") # MUST | |
File.open(video_path) do |file| | |
puts file.size | |
puts typeof(file) | |
begin | |
if startb > 1024 | |
skipped = 0 | |
until skipped + 1024 <= startb | |
puts "skipping #{skipped}/#{startb}" | |
file.skip(1024) | |
skipped += 1024 | |
end | |
if skipped - startb > 0 | |
file.skip(skipped-startb) | |
end | |
else | |
file.skip(startb) | |
end | |
rescue ex | |
puts "#{ex.message} #{ex.backtrace}" | |
end | |
IO.copy(file, env.response.output, endb) | |
end | |
else | |
env.response.status_code = 200 # Range not satisfable | |
# See 4.4 Note | |
File.open(video_path) do |file| | |
IO.copy(file, env.response) | |
end | |
end | |
# env.request.headers | |
end | |
"" | |
end | |
public_folder "static" | |
# serve_static({"gzip" => true, "dir_listing" => false}) | |
Kemal.run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment