Create a gist now

Instantly share code, notes, and snippets.

@gleicon /go-yeah.go
Last active Aug 29, 2015

What would you like to do?
proxy and redirect html, injects an mp3 on it, change base attr.
package main
/*
Yello - Oh Yeah
$ go-yeah -f path_of_oh_yeah_.mp3 -p 8080
*/
import (
"bufio"
"bytes"
"encoding/base32"
"encoding/binary"
"flag"
"fmt"
"hash/crc32"
"net/http"
"os"
"strings"
"github.com/gorilla/handlers"
)
func usage() {
fmt.Println("Usage: go-yeah [-p port] -f path_to_oh_yeah.mp3")
fmt.Println("default port: 8080")
os.Exit(1)
}
func getBase32(wot string) string {
h := crc32.NewIEEE()
fmt.Fprintf(h, wot)
data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, h.Sum32())
str := base32.StdEncoding.EncodeToString(data)
return str
}
type ContentPlusHeader struct {
Body bytes.Buffer
Header http.Header
}
func getAndReplaceContent(url string, host string, w http.ResponseWriter) (ContentPlusHeader, error) {
base := fmt.Sprintf("<head><base href=\"%s\" target=\"_blank\">", url)
ohyeah := fmt.Sprintf("<audio id=\"player\" preload=\"auto\" autoplay loop><source id=\"mp3_source\" src=\"http://%s/oh_yeah.mp3\" type=\"audio/mpeg\"></audio></body>", host)
var ch ContentPlusHeader
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error http.GET: ", err)
return ContentPlusHeader{}, err
}
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
ch = ContentPlusHeader{Header: resp.Header}
for scanner.Scan() {
b := scanner.Text()
rr := strings.Replace(b, "<head>", base, 1)
rr = strings.Replace(rr, "</body>", ohyeah, 1)
brr := ([]byte(rr))
w.Write(brr)
ch.Body.Write(brr)
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading: ", err)
return ContentPlusHeader{}, err
}
return ch, nil
}
func WrapLogHandlerFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
http.Handle(pattern, handlers.CombinedLoggingHandler(os.Stdout, http.HandlerFunc(handler)))
}
// WrapLogHandlerFunc("/", indexHandler)
func main() {
cache := map[string]ContentPlusHeader{}
port := flag.String("p", "8080", "Bind Port")
filename := flag.String("f", "", "Path of mp3 to be embedded")
flag.Usage = usage
flag.Parse()
if *filename == "" {
usage()
}
WrapLogHandlerFunc("/api/v1/url", func(w http.ResponseWriter, r *http.Request) {
var content ContentPlusHeader
var ok bool
var err error
site := r.FormValue("p")
if site == "" {
http.Error(w, "No URL given", http.StatusNotFound)
return
}
id32 := getBase32(site)
content, ok = cache[id32]
if !ok {
content, err = getAndReplaceContent(site, r.Host, w)
if err != nil {
fmt.Println(err)
http.Error(w, "Internal Error", http.StatusInternalServerError)
return
}
cache[id32] = content
}
for k, v := range content.Header {
w.Header().Set(k, v[0])
}
fmt.Fprintf(w, string(content.Body.Bytes()))
return
})
WrapLogHandlerFunc("/oh_yeah.mp3", func(w http.ResponseWriter, r *http.Request) {
fmt.Println("oh yeah served")
http.ServeFile(w, r, *filename)
})
WrapLogHandlerFunc("/", func(w http.ResponseWriter, r *http.Request) {
host := r.Host
fmt.Fprintf(w, "try me: curl %s/api/v1/url?p=http://example.com", host)
})
address := fmt.Sprintf(":%s", *port)
fmt.Println(address)
panic(http.ListenAndServe(address, nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment