Skip to content

Instantly share code, notes, and snippets.

@sguzman
Created March 2, 2017 01:26
Show Gist options
  • Save sguzman/39841ee11edb7309d4f78c9fccfa1d38 to your computer and use it in GitHub Desktop.
Save sguzman/39841ee11edb7309d4f78c9fccfa1d38 to your computer and use it in GitHub Desktop.
A proxy RESTful server with caching
package main
import (
"fmt"
"net/http"
"strings"
"net/url"
"io/ioutil"
"log"
)
var mappy map[string]string
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
if mappy[r.RequestURI] != "" {
log.Println("Found cached response for '" + r.RequestURI + "'")
log.Println("Returning '" + mappy[r.RequestURI] + "'")
fmt.Fprint(w, mappy[r.RequestURI])
return
}
log.Println("Got request = [")
if len(r.URL.RawQuery) == 0 {
fmt.Fprint(w, "dummy")
return
}
log.Println("\tPath is '" + r.URL.Path + "'")
qMap := buildQueryMap(strings.Split(r.URL.RawQuery, "&"))
body := get(buildHost(qMap), r.URL.Path, buildBody(qMap), buildQueryParamString(qMap), buildHeadersMap(qMap))
mappy[r.RequestURI] = body
fmt.Fprint(w, body)
log.Println("] = " + body)
}
func buildQueryMap(query[] string) map[string] string {
queryMap := make(map[string]string)
for _, v := range query {
keyVal := strings.Split(v, "=")
queryMap[keyVal[0]] = keyVal[1]
}
return queryMap
}
func buildHost(query map[string]string) string {
body, _ := url.QueryUnescape(query["gyg-host"])
log.Println("\tHost is '" + body + "'")
return body
}
func buildBody(query map[string]string) string {
body, _ := url.QueryUnescape(query["gyg-body"])
log.Println("\tBody is '" + body + "'")
return body
}
func buildQueryParamString(query map[string]string) string {
qs := ""
for k, v := range query {
if !strings.HasPrefix(k, "gyg-") {
if len(qs) != 0 {
qs += "&"
}
qs += k + "=" + v
}
}
log.Println("\tQuery string is '" + qs + "'")
return qs
}
func buildHeadersMap(query map[string]string) map[string]string {
headers := make(map[string]string)
for k, v := range query {
if strings.HasPrefix(k, "gyg-header-") {
key := strings.Title(strings.TrimPrefix(k, "gyg-header-"))
value, _ := url.QueryUnescape(v)
headers[key] = value
log.Println("\t\tHeader processed: key[" + key + "] = " + value)
}
}
return headers
}
func get(host string, path string, bodyStr string, queryParams string, headers map[string]string) string {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://" + host + path + "?" + queryParams, strings.NewReader(bodyStr))
if err != nil {
log.Fatalln(err)
return string(err.Error())
}
for k, v := range headers {
req.Header.Set(k, v)
}
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
return string(err.Error())
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
return string(err.Error())
}
defer resp.Body.Close()
return string(body)
}
func main() {
mappy = make(map[string]string)
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment