How to modify HTML content on Webrick proxy server?

326 Views Asked by At

How can I use Ruby Webrick to do html content modification as it passes through a proxy server?

require 'webrick'
require 'webrick/httpproxy'

handler = proc do |req, res|
  # if the_site_url == "youtube.com"
  #    html_of_the_page = "<body>Custom Html<body>"
  # end
end

proxy = WEBrick::HTTPProxyServer.new(
  Port: 8080, 
  ProxyContentHandler: handler
)

trap 'INT'  do proxy.shutdown end
server.start

This question is similar but its solution does not work. If Webrick does not support content-altering functionality, is there another proxy server library that does?

Update

Ideally, I should be able to modify existing HTML. I would think there is some other variable like res.body in a proxy handler that represents the html of the page: writable, parsable, readable (whether that is a stream of data or the full data).

1

There are 1 best solutions below

2
Giuseppe Schembri On

If you just need to create a custom html

require 'webrick'
require 'webrick/httpproxy'
# require 'uri' no needed

handler = proc do |req, res|
  content_body = <<-HTML
  <body>
    Custom Html
  <body>
  HTML

  res.header['content-length'] = content_body.size.to_s

  res.body = content_body if req.request_uri.host =~ /youtube/
end

proxy = WEBrick::HTTPProxyServer.new Port: 8080, ProxyContentHandler: handler

trap 'INT'  do proxy.shutdown end
trap 'TERM' do proxy.shutdown end

proxy.start

If you want to put a message before and after the original HTML (I do not know if it could be possible to actually parse and change the original HTML content):

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'

handler = proc do |req, res|
  content_after = "CA "
  content_before = " CB"
  add_to_content_length = "#{content_after}#{content_before}".size.to_i

  res.header['content-length'] = (res.header['content-length'].to_i + add_to_content_length).to_s

  compose = lambda do |add_first, original_body|
    proc do |sock|
      original_body.(add_first.(sock))
      sock.write content_after
    end
  end

  add_before = lambda { |sock| sock.write content_before; sock}

  res.body = compose.(add_before,res.body)
end

proxy = WEBrick::HTTPProxyServer.new Port: 8080, ProxyContentHandler: handler

trap 'INT'  do proxy.shutdown end
trap 'TERM' do proxy.shutdown end

proxy.start