From 276662a1473b3b55146f2ab9568ed385b8f09ba7 Mon Sep 17 00:00:00 2001 From: Omar Roth Date: Mon, 4 Feb 2019 15:17:10 -0600 Subject: [PATCH] Use IO::Memory for creating continuation tokens --- spec/helpers_spec.cr | 16 ++++----- src/invidious/channels.cr | 62 +++++++++++++++++++--------------- src/invidious/helpers/utils.cr | 2 +- src/invidious/playlists.cr | 43 ++++++++++++----------- src/invidious/search.cr | 57 ++++++++++++++++++------------- 5 files changed, 101 insertions(+), 79 deletions(-) diff --git a/spec/helpers_spec.cr b/spec/helpers_spec.cr index d5a38c25..fddf55a5 100644 --- a/spec/helpers_spec.cr +++ b/spec/helpers_spec.cr @@ -24,25 +24,25 @@ describe "Helpers" do describe "#produce_channel_search_url" do it "correctly produces token for searching a specific channel" do - produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "", 100).should eq("/browse_ajax?continuation=4qmFsgI-EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWnpaV0Z5WTJnd0FqZ0JZQUZxQUxnQkFIb0RNVEF3WgA%3D") + produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "", 100).should eq("/browse_ajax?continuation=4qmFsgI-EhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaIEVnWnpaV0Z5WTJnd0FqZ0JZQUZxQUxnQkFIb0RNVEF3WgA%3D&gl=US&hl=en") - produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "По ожиशुपतिरपि子而時ஸ்றீனி", 0).should eq("/browse_ajax?continuation=4qmFsgJZEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWnpaV0Z5WTJnd0FqZ0JZQUZxQUxnQkFIb0JNQSUzRCUzRFoX0J_QviDQvtC20LjgpLbgpYHgpKrgpKTgpL_gpLDgpKrgpL_lrZDogIzmmYLgrrjgr43grrHgr4Dgrqngrr8%3D") + produce_channel_search_url("UCXuqSBlHAE6Xw-yeJA0Tunw", "По ожиशुपतिरपि子而時ஸ்றீனி", 0).should eq("/browse_ajax?continuation=4qmFsgJZEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaJEVnWnpaV0Z5WTJnd0FqZ0JZQUZxQUxnQkFIb0JNQSUzRCUzRFoX0J_QviDQvtC20LjgpLbgpYHgpKrgpKTgpL_gpLDgpKrgpL_lrZDogIzmmYLgrrjgr43grrHgr4Dgrqngrr8%3D&gl=US&hl=en") end end describe "#produce_playlist_url" do it "correctly produces url for requesting index `x` of a playlist" do - produce_playlist_url("UUCla9fZca4I7KagBtgRGnOw", 0).should eq("/browse_ajax?continuation=4qmFsgIsEhpWTFVVQ2xhOWZaY2E0STdLYWdCdGdSR25PdxoOZWdaUVZEcERRVUUlM0Q%3D") + produce_playlist_url("UUCla9fZca4I7KagBtgRGnOw", 0).should eq("/browse_ajax?continuation=4qmFsgIsEhpWTFVVQ2xhOWZaY2E0STdLYWdCdGdSR25PdxoOZWdaUVZEcERRVUUlM0Q%3D&gl=US&hl=en") - produce_playlist_url("UCCla9fZca4I7KagBtgRGnOw", 0).should eq("/browse_ajax?continuation=4qmFsgIsEhpWTFVVQ2xhOWZaY2E0STdLYWdCdGdSR25PdxoOZWdaUVZEcERRVUUlM0Q%3D") + produce_playlist_url("UCCla9fZca4I7KagBtgRGnOw", 0).should eq("/browse_ajax?continuation=4qmFsgIsEhpWTFVVQ2xhOWZaY2E0STdLYWdCdGdSR25PdxoOZWdaUVZEcERRVUUlM0Q%3D&gl=US&hl=en") - produce_playlist_url("PLt5AfwLFPxWLNVixpe1w3fi6lE2OTq0ET", 0).should eq("/browse_ajax?continuation=4qmFsgI2EiRWTFBMdDVBZndMRlB4V0xOVml4cGUxdzNmaTZsRTJPVHEwRVQaDmVnWlFWRHBEUVVFJTNE") + produce_playlist_url("PLt5AfwLFPxWLNVixpe1w3fi6lE2OTq0ET", 0).should eq("/browse_ajax?continuation=4qmFsgI2EiRWTFBMdDVBZndMRlB4V0xOVml4cGUxdzNmaTZsRTJPVHEwRVQaDmVnWlFWRHBEUVVFJTNE&gl=US&hl=en") - produce_playlist_url("PLt5AfwLFPxWLNVixpe1w3fi6lE2OTq0ET", 10000).should eq("/browse_ajax?continuation=4qmFsgI0EiRWTFBMdDVBZndMRlB4V0xOVml4cGUxdzNmaTZsRTJPVHEwRVQaDGVnZFFWRHBEU2tKUA%3D%3D") + produce_playlist_url("PLt5AfwLFPxWLNVixpe1w3fi6lE2OTq0ET", 10000).should eq("/browse_ajax?continuation=4qmFsgI0EiRWTFBMdDVBZndMRlB4V0xOVml4cGUxdzNmaTZsRTJPVHEwRVQaDGVnZFFWRHBEU2tKUA%3D%3D&gl=US&hl=en") - produce_playlist_url("PL55713C70BA91BD6E", 0).should eq("/browse_ajax?continuation=4qmFsgImEhRWTFBMNTU3MTNDNzBCQTkxQkQ2RRoOZWdaUVZEcERRVUUlM0Q%3D") + produce_playlist_url("PL55713C70BA91BD6E", 0).should eq("/browse_ajax?continuation=4qmFsgImEhRWTFBMNTU3MTNDNzBCQTkxQkQ2RRoOZWdaUVZEcERRVUUlM0Q%3D&gl=US&hl=en") - produce_playlist_url("PL55713C70BA91BD6E", 10000).should eq("/browse_ajax?continuation=4qmFsgIkEhRWTFBMNTU3MTNDNzBCQTkxQkQ2RRoMZWdkUVZEcERTa0pQ") + produce_playlist_url("PL55713C70BA91BD6E", 10000).should eq("/browse_ajax?continuation=4qmFsgIkEhRWTFBMNTU3MTNDNzBCQTkxQkQ2RRoMZWdkUVZEcERTa0pQ&gl=US&hl=en") end end diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr index c1915a10..28fbdcd6 100644 --- a/src/invidious/channels.cr +++ b/src/invidious/channels.cr @@ -202,50 +202,58 @@ def produce_channel_videos_url(ucid, page = 1, auto_generated = nil, sort_by = " timestamp = seed - (page - 1).months page = "#{timestamp.to_unix}" - switch = "\x36" + switch = 0x36 else page = "#{page}" - switch = "\x00" + switch = 0x00 end - meta = "\x12\x06videos" - meta += "\x30\x02" - meta += "\x38\x01" - meta += "\x60\x01" - meta += "\x6a\x00" - meta += "\xb8\x01\x00" - meta += "\x20#{switch}" - meta += "\x7a" - meta += page.size.to_u8.unsafe_chr - meta += page + meta = IO::Memory.new + meta.write(Bytes[0x12, 0x06]) + meta.print("videos") + + meta.write(Bytes[0x30, 0x02]) + meta.write(Bytes[0x38, 0x01]) + meta.write(Bytes[0x60, 0x01]) + meta.write(Bytes[0x6a, 0x00]) + meta.write(Bytes[0xb8, 0x01, 0x00]) + + meta.write(Bytes[0x20, switch, 0x7a, page.size]) + meta.print(page) case sort_by when "newest" # Empty tags can be omitted - # meta += "\x18\x00" + # meta.write(Bytes[0x18,0x00]) when "popular" - meta += "\x18\x01" + meta.write(Bytes[0x18, 0x01]) when "oldest" - meta += "\x18\x02" + meta.write(Bytes[0x18, 0x02]) end - meta = Base64.urlsafe_encode(meta) + meta.rewind + meta = Base64.urlsafe_encode(meta.to_slice) meta = URI.escape(meta) - continuation = "\x12" - continuation += ucid.size.to_u8.unsafe_chr - continuation += ucid - continuation += "\x1a" - continuation += meta.size.to_u8.unsafe_chr - continuation += meta + continuation = IO::Memory.new + continuation.write(Bytes[0x12, ucid.size]) + continuation.print(ucid) - continuation = continuation.size.to_u8.unsafe_chr + continuation - continuation = "\xe2\xa9\x85\xb2\x02" + continuation + continuation.write(Bytes[0x1a, meta.size]) + continuation.print(meta) - continuation = Base64.urlsafe_encode(continuation) - continuation = URI.escape(continuation) + continuation.rewind + continuation = continuation.gets_to_end - url = "/browse_ajax?continuation=#{continuation}&gl=US&hl=en" + wrapper = IO::Memory.new + wrapper.write(Bytes[0xe2, 0xa9, 0x85, 0xb2, 0x02, continuation.size]) + wrapper.print(continuation) + wrapper.rewind + + wrapper = Base64.urlsafe_encode(wrapper.to_slice) + wrapper = URI.escape(wrapper) + + url = "/browse_ajax?continuation=#{wrapper}&gl=US&hl=en" return url end diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index 07c4bff3..282e8ce5 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -282,7 +282,7 @@ def write_var_int(value : Int) end end - return bytes + return Slice.new(bytes.to_unsafe, bytes.size) end def sha256(text) diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr index 6e48bacf..28f2e4ce 100644 --- a/src/invidious/playlists.cr +++ b/src/invidious/playlists.cr @@ -126,32 +126,37 @@ def produce_playlist_url(id, index) end ucid = "VL" + id - meta = [0x08_u8] + write_var_int(index) - meta = Slice.new(meta.to_unsafe, meta.size) - meta = Base64.urlsafe_encode(meta, false) + meta = IO::Memory.new + meta.write(Bytes[0x08]) + meta.write(write_var_int(index)) + + meta.rewind + meta = Base64.urlsafe_encode(meta.to_slice, false) meta = "PT:#{meta}" - wrapped = "\x7a" - wrapped += meta.bytes.size.unsafe_chr - wrapped += meta + continuation = IO::Memory.new + continuation.write(Bytes[0x7a, meta.size]) + continuation.print(meta) - wrapped = Base64.urlsafe_encode(wrapped) - meta = URI.escape(wrapped) + continuation.rewind + meta = Base64.urlsafe_encode(continuation.to_slice) + meta = URI.escape(meta) - continuation = "\x12" - continuation += ucid.size.unsafe_chr - continuation += ucid - continuation += "\x1a" - continuation += meta.bytes.size.unsafe_chr - continuation += meta + continuation = IO::Memory.new + continuation.write(Bytes[0x12, ucid.size]) + continuation.print(ucid) + continuation.write(Bytes[0x1a, meta.size]) + continuation.print(meta) - continuation = continuation.size.to_u8.unsafe_chr + continuation - continuation = "\xe2\xa9\x85\xb2\x02" + continuation + wrapper = IO::Memory.new + wrapper.write(Bytes[0xe2, 0xa9, 0x85, 0xb2, 0x02, continuation.size]) + wrapper.print(continuation) + wrapper.rewind - continuation = Base64.urlsafe_encode(continuation) - continuation = URI.escape(continuation) + wrapper = Base64.urlsafe_encode(wrapper.to_slice) + wrapper = URI.escape(wrapper) - url = "/browse_ajax?continuation=#{continuation}" + url = "/browse_ajax?continuation=#{wrapper}&gl=US&hl=en" return url end diff --git a/src/invidious/search.cr b/src/invidious/search.cr index 97104b02..20e34c24 100644 --- a/src/invidious/search.cr +++ b/src/invidious/search.cr @@ -203,36 +203,45 @@ end def produce_channel_search_url(ucid, query, page) page = "#{page}" - meta = "\x12\x06search" - meta += "\x30\x02" - meta += "\x38\x01" - meta += "\x60\x01" - meta += "\x6a\x00" - meta += "\xb8\x01\x00" - meta += "\x7a" - meta += page.size.unsafe_chr - meta += page + meta = IO::Memory.new + meta.write(Bytes[0x12, 0x06]) + meta.print("search") - meta = Base64.urlsafe_encode(meta) + meta.write(Bytes[0x30, 0x02]) + meta.write(Bytes[0x38, 0x01]) + meta.write(Bytes[0x60, 0x01]) + meta.write(Bytes[0x6a, 0x00]) + meta.write(Bytes[0xb8, 0x01, 0x00]) + + meta.write(Bytes[0x7a, page.size]) + meta.print(page) + + meta.rewind + meta = Base64.urlsafe_encode(meta.to_slice) meta = URI.escape(meta) - continuation = "\x12" - continuation += ucid.size.unsafe_chr - continuation += ucid - continuation += "\x1a" - continuation += meta.size.unsafe_chr - continuation += meta - continuation += "\x5a" - continuation += query.size.unsafe_chr - continuation += query + continuation = IO::Memory.new + continuation.write(Bytes[0x12, ucid.size]) + continuation.print(ucid) - continuation = continuation.size.unsafe_chr + continuation - continuation = "\xe2\xa9\x85\xb2\x02" + continuation + continuation.write(Bytes[0x1a, meta.size]) + continuation.print(meta) - continuation = Base64.urlsafe_encode(continuation) - continuation = URI.escape(continuation) + continuation.write(Bytes[0x5a, query.size]) + continuation.print(query) - url = "/browse_ajax?continuation=#{continuation}" + continuation.rewind + continuation = continuation.gets_to_end + + wrapper = IO::Memory.new + wrapper.write(Bytes[0xe2, 0xa9, 0x85, 0xb2, 0x02, continuation.size]) + wrapper.print(continuation) + wrapper.rewind + + wrapper = Base64.urlsafe_encode(wrapper.to_slice) + wrapper = URI.escape(wrapper) + + url = "/browse_ajax?continuation=#{wrapper}&gl=US&hl=en" return url end