Skip to content

Commit

Permalink
Merge pull request #1 from marconi1992/fix/gzip-encoding
Browse files Browse the repository at this point in the history
Remove Accept-Encoding for proxied origins
  • Loading branch information
marconi1992 authored May 6, 2019
2 parents 192723f + 4fe8d64 commit ddf750a
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 124 deletions.
6 changes: 5 additions & 1 deletion .editorconfig
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Hypernova Proxy needs a configuration file in order to setup the location for th
## Using Hypernova Proxy with Docker

```Dockerfile
FROM marconi1992/hypernova-proxy:1.0.0
FROM marconi1992/hypernova-proxy:1.0.1

COPY config.json config.json
```
254 changes: 132 additions & 122 deletions main.go
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
}

0 comments on commit ddf750a

Please sign in to comment.