You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
5.6 KiB

package main
import (
"bytes"
"compress/gzip"
"errors"
"flag"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"os"
"strings"
"codefirst.iut.uca.fr/git/thomas.bellembois/codefirst-menu/v2/menu"
log "github.com/sirupsen/logrus"
)
var (
updatedMenu, updatedStringbody string
proxyURL, codefirstURL string
debug, dump bool
)
func gUnzipData(data []byte) (resData []byte, err error) {
b := bytes.NewBuffer(data)
var r io.Reader
r, err = gzip.NewReader(b)
if err != nil {
return
}
var resB bytes.Buffer
_, err = resB.ReadFrom(r)
if err != nil {
return
}
resData = resB.Bytes()
return
}
func UpdateResponse(r *http.Response) error {
contentType := r.Header[http.CanonicalHeaderKey("content-type")]
contentEncoding := r.Header[http.CanonicalHeaderKey("content-encoding")]
location := r.Header[http.CanonicalHeaderKey("location")]
statusCode := r.StatusCode
log.WithFields(
log.Fields{
"r.Header": r.Header,
"r.Request.URL.Path": r.Request.URL.Path,
"proxyURL": proxyURL,
"statusCode": statusCode,
"contentType": contentType,
"contentEncoding": contentEncoding,
"location": location,
},
).Debug()
if statusCode == http.StatusFound && strings.HasPrefix(proxyURL, "http://pastebin") && len(contentType) == 0 {
if len(location) > 0 {
r.Header.Del("location")
r.Header.Set("location", fmt.Sprintf("/pastebin%s", location[0]))
}
}
if statusCode != http.StatusOK {
log.Debug("skipping not status ok reponse")
return nil
}
if len(contentType) > 0 && strings.HasPrefix(contentType[0], "text/html") {
var (
body []byte
err error
)
if body, err = io.ReadAll(r.Body); err != nil {
fmt.Println(err)
return err
}
if len(contentEncoding) > 0 && strings.HasPrefix(contentEncoding[0], "gzip") {
if body, err = gUnzipData(body); err != nil {
fmt.Println(err)
return err
}
}
stringBody := string(body)
if strings.HasPrefix(proxyURL, "http://pastebin") {
updatedStringbody = strings.Replace(stringBody, "action=\"/\"", "action=\"/pastebin/\"", 1)
} else if strings.HasPrefix(proxyURL, "http://cinny") {
updatedStringbody = strings.Replace(stringBody, `<body id="appBody">`, `<body id="appBody">`+updatedMenu, 1)
} else if strings.HasPrefix(proxyURL, "http://nginx") {
if r.Request.URL.Path == "/" {
updatedStringbody = strings.Replace(stringBody, "<body>", "<body>"+updatedMenu, 1)
} else {
updatedStringbody = stringBody
}
} else {
updatedStringbody = strings.Replace(stringBody, "<body>", "<body>"+updatedMenu, 1)
}
buf := bytes.NewBufferString(updatedStringbody)
r.Body = ioutil.NopCloser(buf)
r.Header.Del("content-encoding")
r.Header.Del("content-type")
r.Header.Set("content-type", "text/html; charset=utf-8")
r.Header.Set("content-length", fmt.Sprint(buf.Len()))
}
return nil
}
func init() {
flag.StringVar(&proxyURL, "proxyurl", "", "proxy URL")
flag.StringVar(&codefirstURL, "codefirsturl", "", "codefirst URL")
flag.BoolVar(&debug, "debug", false, "enable debug")
flag.BoolVar(&dump, "dump", false, "dump menu")
flag.Parse()
updatedMenu = menu.CodeFirstMenu
if dump {
updatedMenu = strings.Replace(updatedMenu, "<!--gitea", "", 1)
updatedMenu = strings.Replace(updatedMenu, "gitea-->", "", 1)
fmt.Println(updatedMenu)
os.Exit(0)
}
if proxyURL == "" {
panic(errors.New("empty proxy URL"))
}
if debug {
log.SetLevel(log.DebugLevel)
}
updatedMenu = strings.ReplaceAll(updatedMenu, "CODEFIRST_HOSTNAME", codefirstURL)
if strings.HasPrefix(proxyURL, "http://gitea") {
updatedMenu = strings.Replace(updatedMenu, "<!--gitea", "", 1)
updatedMenu = strings.Replace(updatedMenu, "gitea-->", "", 1)
} else if strings.HasPrefix(proxyURL, "http://drone") {
updatedMenu = strings.Replace(updatedMenu, "<!--drone", "", 1)
updatedMenu = strings.Replace(updatedMenu, "drone-->", "", 1)
} else if strings.HasPrefix(proxyURL, "http://dockerproxy-clientweb") {
updatedMenu = strings.Replace(updatedMenu, "<!--dockerrunner", "", 1)
updatedMenu = strings.Replace(updatedMenu, "dockerrunner-->", "", 1)
} else if strings.HasPrefix(proxyURL, "http://registryui") {
updatedMenu = strings.Replace(updatedMenu, "<!--dockerregistry", "", 1)
updatedMenu = strings.Replace(updatedMenu, "dockerregistry-->", "", 1)
} else if strings.HasPrefix(proxyURL, "http://sonarqube") {
updatedMenu = strings.Replace(updatedMenu, "<!--sonar", "", 1)
updatedMenu = strings.Replace(updatedMenu, "sonar-->", "", 1)
} else if strings.HasPrefix(proxyURL, "http://nginx") {
updatedMenu = strings.Replace(updatedMenu, "<!--documentation", "", 1)
updatedMenu = strings.Replace(updatedMenu, "documentation-->", "", 1)
} else if strings.HasPrefix(proxyURL, "http://cinny") {
updatedMenu = strings.Replace(updatedMenu, "<!--cinny", "", 1)
updatedMenu = strings.Replace(updatedMenu, "cinny-->", "", 1)
}
}
func main() {
remote, err := url.Parse(proxyURL)
if err != nil {
panic(err)
}
log.WithFields(
log.Fields{
"proxyURL": proxyURL,
"updatedMenu": updatedMenu,
},
).Debug()
handler := func(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
log.WithFields(
log.Fields{
"r.Host": r.Host,
"r.RequestURI": r.RequestURI,
},
).Debug()
r.Host = remote.Host
p.ServeHTTP(w, r)
}
}
proxy := httputil.NewSingleHostReverseProxy(remote)
proxy.ModifyResponse = UpdateResponse
http.HandleFunc("/", handler(proxy))
err = http.ListenAndServe(":8081", nil)
if err != nil {
panic(err)
}
}