Skip to content

Instantly share code, notes, and snippets.

@soba1104
Created January 24, 2015 10:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soba1104/d952610c62408217da03 to your computer and use it in GitHub Desktop.
Save soba1104/d952610c62408217da03 to your computer and use it in GitHub Desktop.
kankore proxy
#!/usr/bin/env/ruby
# coding: UTF-8
require 'webrick'
require 'webrick/httpproxy'
require 'zlib'
class Converter
class ConverterException < Exception; end
public
def convert(swf)
log("Convert start!!!")
swf.force_encoding('ASCII-8BIT')
format, version, size = parse_header(swf)
body = parse_body(swf, format, size)
replace(format, version, size, body)
end
private
def parse_header(swf)
log("Parsing header...")
format = swf.slice(0..2)
log("Format = #{format}.")
version = swf.slice(3..3).unpack('C').first()
log("Version = #{version}.")
size = swf.slice(4..7).unpack('I').first()
log("Size = #{size}.")
[format, version, size]
end
def parse_body(swf, format, size)
body = swf.slice(8..-1)
case format
when 'CWS'
body = Zlib::Inflate.inflate(body)
log('Inflating zipped swf body...')
unless (body.size + 8) == size
throw ConverterException.new('Invalid swf.')
end
when 'FWS'
# Nothing to do.
else
throw ConverterException.new("Unsupported format #{format}.")
end
body
end
def replace(format, version, size, body)
new_body = replace_body(body)
new_format = format
new_size = [new_body.size + 8].pack('I')
new_version = [version].pack('C')
case new_format
when 'CWS'
new_body = Zlib::Deflate.deflate(new_body)
when 'FWS'
# Nothing to do.
else
throw ConverterException.new("Unsupported format #{new_format}.")
end
new_format + new_version + new_size + new_body
end
def replace_body(body)
rect_field_size = calc_rect_field_size(body)
prefix = body.slice(0..(rect_field_size - 1))
frame_rate_bin = body.slice(rect_field_size..(rect_field_size + 1))
suffix = body.slice((rect_field_size + 2)..-1)
frame_rate = frame_rate_bin.unpack('v').first()
log("Frame rate = #{frame_rate}.")
new_frame_rate = frame_rate * 6
if new_frame_rate > 0xffff
new_frame_rate = 0xffff
end
log("New frame rate = #{new_frame_rate}.")
new_frame_rate_bin = [new_frame_rate].pack('v')
prefix + new_frame_rate_bin + suffix
end
def calc_rect_field_size(body)
log('Calculating rect field size...')
nbits = body.unpack('B5').first.to_i(2)
log("Nbits = #{nbits}.")
all_bits_size = 5 + nbits * 4
rect_field_size = all_bits_size / 8
if all_bits_size % 8 > 0
rect_field_size += 1
end
rect_field_size
end
def log(msg)
STDERR.puts(msg)
end
end
handler = lambda{|request, response|
begin
STDERR.puts "response"
#STDERR.puts request.header.inspect
STDERR.puts request.header['connection']
#STDERR.puts response.header.inspect
return unless response.status == 200
body = response.body
uri = request.unparsed_uri
if /[a-zA-Z0-9]+\.swf$/ =~ uri.split('?').first()
STDERR.puts "Converting #{uri}..."
converter = Converter.new()
new_body = converter.convert(body)
response.header['content-length'] = new_body.size
response.body = new_body
#STDERR.puts "Content-Length = #{response.header['content-length'].class}"
STDERR.puts "Size: #{body.size} => #{new_body.size}"
end
rescue => e
STDERR.puts(e)
end
}
request_handler = lambda{|request, response|
#STDERR.puts request.header.inspect
#STDERR.puts response.header.inspect
STDERR.puts "----- (REQUEST HEADER)connection: #{request.header['connection']}"
}
server = WEBrick::HTTPProxyServer.new({
:BindAddress => '127.0.0.1',
:Port => 8765,
:Logger => WEBrick::Log::new('proxy.log', WEBrick::Log::DEBUG),
:ProxyVia => false,
:ProxyTimeout => true,
:RequestCallback => request_handler,
:ProxyContentHandler => handler,
})
Signal.trap('INT'){ server.shutdown() }
server.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment