-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from marconi1992/fix/gzip-encoding
Remove Accept-Encoding for proxied origins
- Loading branch information
Showing
3 changed files
with
138 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
[*] | ||
indent_size = 2 | ||
indent_style = space | ||
indent_style = space | ||
|
||
[*.go] | ||
indent_size = 4 | ||
indent_style = tab |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,181 +1,191 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"net/http" | ||
"net/http/httputil" | ||
"net/url" | ||
"os" | ||
"fmt" | ||
"log" | ||
"strings" | ||
"strconv" | ||
"io/ioutil" | ||
"encoding/json" | ||
"net/url" | ||
"net/http" | ||
"net/http/httputil" | ||
"github.com/PuerkitoBio/goquery" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/PuerkitoBio/goquery" | ||
) | ||
|
||
type HypernovaResult struct { | ||
Success bool | ||
Html string | ||
Name string | ||
Success bool | ||
Html string | ||
Name string | ||
} | ||
|
||
type HypernovaResponse struct { | ||
Results map[string]HypernovaResult | ||
Results map[string]HypernovaResult | ||
} | ||
|
||
type Location struct { | ||
Path string | ||
Host string | ||
ModifyResponse bool | ||
Path string | ||
Host string | ||
ModifyResponse bool | ||
} | ||
|
||
type Configuration struct { | ||
Locations []Location | ||
Locations []Location | ||
} | ||
|
||
func createQuery(tag string, uuid string, name string) string { | ||
query := fmt.Sprintf("%s[data-hypernova-id=\"%s\"][data-hypernova-key=\"%s\"]", tag, uuid, name) | ||
query := fmt.Sprintf("%s[data-hypernova-id=\"%s\"][data-hypernova-key=\"%s\"]", tag, uuid, name) | ||
|
||
return query | ||
return query | ||
} | ||
|
||
func modifyBody(html string) string { | ||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) | ||
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) | ||
|
||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
batch := make(map[string]map[string]interface{}) | ||
|
||
doc.Find("div[data-hypernova-key]").Each(func(i int, s *goquery.Selection) { | ||
uuid, uuidOk := s.Attr("data-hypernova-id") | ||
name, nameOk := s.Attr("data-hypernova-key") | ||
if !uuidOk || !nameOk { | ||
return | ||
} | ||
batch := make(map[string]map[string]interface{}) | ||
|
||
scriptQuery := createQuery("script", uuid, name) | ||
doc.Find("div[data-hypernova-key]").Each(func(i int, s *goquery.Selection) { | ||
uuid, uuidOk := s.Attr("data-hypernova-id") | ||
name, nameOk := s.Attr("data-hypernova-key") | ||
if !uuidOk || !nameOk { | ||
return | ||
} | ||
|
||
script := doc.Find(scriptQuery).First() | ||
scriptQuery := createQuery("script", uuid, name) | ||
|
||
if script == nil { | ||
return | ||
} | ||
script := doc.Find(scriptQuery).First() | ||
|
||
content := script.Text() | ||
content = content[4:(len(content) - 3)] | ||
|
||
var data interface{} | ||
if script == nil { | ||
return | ||
} | ||
|
||
json.Unmarshal([]byte(content), &data) | ||
content := script.Text() | ||
content = content[4:(len(content) - 3)] | ||
|
||
batch[uuid] = make(map[string]interface{}) | ||
batch[uuid]["name"] = name | ||
batch[uuid]["data"] = data | ||
}) | ||
var data interface{} | ||
|
||
b, encodeErr := json.Marshal(batch) | ||
json.Unmarshal([]byte(content), &data) | ||
|
||
if encodeErr != nil { | ||
log.Fatal(encodeErr) | ||
} | ||
batch[uuid] = make(map[string]interface{}) | ||
batch[uuid]["name"] = name | ||
batch[uuid]["data"] = data | ||
}) | ||
|
||
payload := string(b) | ||
b, encodeErr := json.Marshal(batch) | ||
|
||
resp, reqErr := http.Post(os.Getenv("HYPERNOVA_BATCH"), "application/json", strings.NewReader(payload)) | ||
if encodeErr != nil { | ||
log.Fatal(encodeErr) | ||
} | ||
|
||
if reqErr != nil { | ||
log.Fatal(reqErr) | ||
} | ||
payload := string(b) | ||
|
||
defer resp.Body.Close() | ||
resp, reqErr := http.Post(os.Getenv("HYPERNOVA_BATCH"), "application/json", strings.NewReader(payload)) | ||
|
||
body, bodyErr := ioutil.ReadAll(resp.Body) | ||
if reqErr != nil { | ||
log.Fatal(reqErr) | ||
} | ||
|
||
if bodyErr != nil { | ||
log.Fatal(bodyErr) | ||
} | ||
|
||
var hypernovaResponse HypernovaResponse | ||
defer resp.Body.Close() | ||
|
||
json.Unmarshal(body, &hypernovaResponse) | ||
body, bodyErr := ioutil.ReadAll(resp.Body) | ||
|
||
for uuid, result := range hypernovaResponse.Results { | ||
if !result.Success { | ||
break | ||
} | ||
|
||
scriptQuery := createQuery("script", uuid, result.Name) | ||
doc.Find(scriptQuery).Remove() | ||
if bodyErr != nil { | ||
log.Fatal(bodyErr) | ||
} | ||
|
||
divQuery := createQuery("div", uuid, result.Name) | ||
doc.Find(divQuery).ReplaceWithHtml(result.Html) | ||
} | ||
var hypernovaResponse HypernovaResponse | ||
|
||
html, htmlError := doc.Html() | ||
json.Unmarshal(body, &hypernovaResponse) | ||
|
||
if htmlError != nil { | ||
log.Fatal(htmlError) | ||
} | ||
for uuid, result := range hypernovaResponse.Results { | ||
if !result.Success { | ||
break | ||
} | ||
|
||
return html | ||
} | ||
scriptQuery := createQuery("script", uuid, result.Name) | ||
doc.Find(scriptQuery).Remove() | ||
|
||
func main() { | ||
setUpLocations(); | ||
divQuery := createQuery("div", uuid, result.Name) | ||
doc.Find(divQuery).ReplaceWithHtml(result.Html) | ||
} | ||
|
||
log.Fatal(http.ListenAndServe(":8080", nil)) | ||
html, htmlError := doc.Html() | ||
|
||
if htmlError != nil { | ||
log.Fatal(htmlError) | ||
} | ||
|
||
return html | ||
} | ||
|
||
func setUpLocations () error { | ||
b, err := ioutil.ReadFile(os.Getenv("CONFIG_FILE")); | ||
func main() { | ||
setUpLocations() | ||
|
||
if err != nil { | ||
fmt.Println("Config file not found"); | ||
return err | ||
} | ||
log.Fatal(http.ListenAndServe(":8080", nil)) | ||
} | ||
|
||
var configuration Configuration | ||
func setUpLocations() error { | ||
b, err := ioutil.ReadFile(os.Getenv("CONFIG_FILE")) | ||
|
||
json.Unmarshal(b, &configuration) | ||
if err != nil { | ||
fmt.Println("Config file not found") | ||
return err | ||
} | ||
|
||
var configuration Configuration | ||
|
||
json.Unmarshal(b, &configuration) | ||
|
||
fmt.Println(configuration) | ||
|
||
for _, location := range configuration.Locations { | ||
origin, err := url.Parse(location.Host) | ||
if err != nil { | ||
log.Fatal(err) | ||
} else { | ||
proxy := httputil.NewSingleHostReverseProxy(origin) | ||
|
||
if location.ModifyResponse { | ||
proxy.ModifyResponse = ModifyResponse | ||
proxy.Director = func(req *http.Request) { | ||
req.Header.Add("X-Forwarded-Host", req.Host) | ||
req.Header.Add("X-Origin-Host", origin.Host) | ||
req.Header.Del("Accept-Encoding") | ||
req.URL.Scheme = "http" | ||
req.URL.Host = origin.Host | ||
} | ||
} | ||
|
||
http.Handle(location.Path, proxy) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
fmt.Println(configuration) | ||
func ModifyResponse(r *http.Response) error { | ||
contentType := r.Header.Get("Content-Type") | ||
if !strings.HasPrefix(contentType, "text/html") { | ||
return nil | ||
} | ||
|
||
for _, location := range configuration.Locations { | ||
host, err := url.Parse(location.Host) | ||
if err != nil { | ||
log.Fatal(err) | ||
} else { | ||
proxy := httputil.NewSingleHostReverseProxy(host) | ||
|
||
if (location.ModifyResponse) { | ||
proxy.ModifyResponse = ModifyResponse | ||
} | ||
html, err := ioutil.ReadAll(r.Body) | ||
|
||
http.Handle(location.Path, proxy) | ||
} | ||
} | ||
if err != nil { | ||
log.Fatal(err) | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
newHtml := modifyBody(string(html)) | ||
|
||
func ModifyResponse(r *http.Response) error { | ||
contentType := r.Header.Get("Content-Type") | ||
if !strings.HasPrefix(contentType, "text/html") { | ||
return nil | ||
} | ||
|
||
html, err := ioutil.ReadAll(r.Body) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
newHtml := modifyBody(string(html)); | ||
r.Body = ioutil.NopCloser(strings.NewReader(newHtml)) | ||
r.ContentLength = int64(len(newHtml)) | ||
r.Header.Set("Content-Length", strconv.Itoa(len(newHtml))) | ||
return nil | ||
r.Body = ioutil.NopCloser(strings.NewReader(newHtml)) | ||
r.ContentLength = int64(len(newHtml)) | ||
r.Header.Set("Content-Length", strconv.Itoa(len(newHtml))) | ||
return nil | ||
} |