Skip to content

Commit

Permalink
Merge pull request #6 from kumina/fix-json
Browse files Browse the repository at this point in the history
Fix json
  • Loading branch information
BartVerc authored Oct 25, 2021
2 parents cb9fa0a + 81f7711 commit 2f64424
Show file tree
Hide file tree
Showing 343 changed files with 85 additions and 248,279 deletions.
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module github.com/kumina/headers-by-request

go 1.15

require github.com/sirupsen/logrus v1.8.1
go 1.16
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tidwall/gjson v1.9.1 h1:wrrRk7TyL7MmKanNRck/Mcr3VU1sdMvJHvJXzqBIUNo=
github.com/tidwall/gjson v1.9.1/go.mod h1:jydLKE7s8J0+1/5jC4eXcuFlzKizGrCKvLmBVX/5oXc=
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.2 h1:H1Llj/C9G+BoUN2DsybLHjWvr9dx4Uazavf0sXQ+rOs=
github.com/tidwall/sjson v1.2.2/go.mod h1:jmW2RZpbKuExPFUHeFSBMiovT9ZyOziEHDRkbsdp0B0=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
114 changes: 76 additions & 38 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import (
"context"
"encoding/json"
"fmt"
log "github.com/sirupsen/logrus"
"io/ioutil"
"net/http"
"net/url"
"os"
"regexp"
"sort"
"strconv"
"time"
)

Expand All @@ -26,23 +25,62 @@ type Router struct {

// Our custom configuration
dynamicHeaderUrl string
enableTiming bool
log *log.Entry
enableTiming bool
}

type LogLine struct {
Timestamp time.Time `json:"timestamp"`
Msg string `json:"msg,omitempty"`
Level string `json:"level"`
Details map[string]string `json:"details,inline"`
}

func NewLog() *LogLine {
return &LogLine{
Timestamp: time.Now(),
Level: "",
Msg: "",
Details: map[string]string{},
}
}

func Info(msg string) *LogLine {
n := NewLog()
n.Level = "info"
n.Msg = msg
return n
}

func Error(msg string) *LogLine {
n := NewLog()
n.Level = "error"
n.Msg = msg
return n
}

func Warn(msg string) *LogLine {
n := NewLog()
n.Level = "warning"
n.Msg = msg
return n
}

func (l *LogLine) LogJson(values map[string]string) {
for k, v := range values {
l.Details[k] = v
}
l.Timestamp = time.Now()
out, _ := json.Marshal(l)
fmt.Println(string(out))
}

// Function needed for Traefik to recognize this module as a plugin
// Uses a generic http.Handler type from golang that we can use to work with the request
// by overriding different functions of the interface
func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
// Log as JSON instead of the default ASCII formatter.
log.SetFormatter(&log.JSONFormatter{})

log.SetOutput(os.Stdout)

logcontext := log.WithFields(log.Fields{
"middleware": name,
})
logcontext.Info("New middleware created.")
Info("New middleware created.").LogJson(nil)

if len(config.UrlHeaderRequest) == 0 {
return nil, fmt.Errorf("DynamicHeaderUrl cannot be empty")
Expand All @@ -53,15 +91,12 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h

return &Router{
dynamicHeaderUrl: config.UrlHeaderRequest,
enableTiming: config.EnableTiming,
next: next,
name: name,
log: logcontext,
enableTiming: config.EnableTiming,
next: next,
name: name,
}, nil
}



type Header struct {
Id int `json:"id"`
Name string `json:"name"`
Expand All @@ -70,22 +105,20 @@ type Header struct {
}

type Rewrite struct {
Id int `json:"id"`
Pattern string `json:"pattern"`
ServiceId int `json:"service_id"`
Template string `json:"template"`
Weight int `json:"weight"`
Id int `json:"id"`
Pattern string `json:"pattern"`
ServiceId int `json:"service_id"`
Template string `json:"template"`
Weight int `json:"weight"`
}


type Requested struct {
Payload struct{
Headers []Header `json:"headers,omitempty"`
Payload struct {
Headers []Header `json:"headers,omitempty"`
Rewrites []Rewrite `json:"rewrites,omitempty"`
} `json:"payload"`
}


func (a *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
startTime := time.Time{}
if a.enableTiming {
Expand All @@ -103,31 +136,32 @@ func (a *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

fullUrl := fmt.Sprintf("%s%s", req.URL.Host, req.URL.Path)

a.log.WithField("url", fullUrl).Info("Resolving route")
Info("Resolving route.").LogJson(map[string]string{"url": fullUrl})

requestBody, err := json.Marshal(map[string]string{
"request": fullUrl,
})
if err != nil {
a.log.Error("Requestbody marshalling error.")
Error("Requestbody marshalling error.").LogJson(map[string]string{"url": fullUrl})
rw.WriteHeader(http.StatusNotFound)
return
}

resp, err := Client.Post(a.dynamicHeaderUrl, "application/json", bytes.NewBuffer(requestBody))

if err != nil {
a.log.Error("Request error.")
//a.log.Error("Request error.")
rw.WriteHeader(http.StatusNotFound)
return
}
if resp.StatusCode != 200 {
if resp.StatusCode == 409 {
a.log.WithField("url", fullUrl).Warn(fmt.Sprintf("Ambiguous request."))
Info("Ambiguous request.").LogJson(map[string]string{"url": fullUrl})
rw.WriteHeader(http.StatusNotFound)
return
}
a.log.WithField("code", resp.StatusCode).Error(fmt.Sprintf("Unknown statuscode."))
Info("Unknown status code response from DynamicHeaderUrl.").
LogJson(map[string]string{"url": fullUrl, "code": strconv.Itoa(resp.StatusCode)})
rw.WriteHeader(http.StatusNotFound)
return
}
Expand All @@ -136,20 +170,22 @@ func (a *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
a.log.Error("Could not read requests body.")
Info("Could not read requests body.").LogJson(map[string]string{"url": fullUrl})
rw.WriteHeader(http.StatusNotFound)
return
}
requested := &Requested{}
err = json.Unmarshal(body, requested)
if err != nil {
a.log.Error("Could not unmarshal requests body.")
Info("Could not unmarshal requests body.").LogJson(map[string]string{"url": fullUrl})
rw.WriteHeader(http.StatusNotFound)
return
}

for _, header := range requested.Payload.Headers {
a.log.WithField("header", fmt.Sprintf("%s:%s", header.Name, header.Value)).Info("Setting header.")

Info("Setting header.").LogJson(map[string]string{"url": fullUrl, "header_key": header.Name,
"header_value": header.Value})
req.Header.Set(header.Name, header.Value)
}

Expand All @@ -166,7 +202,8 @@ func (a *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
for _, rewrite := range rewrites {
check, err := regexp.Compile(rewrite.Pattern)
if err != nil {
a.log.WithField("pattern", rewrite.Pattern).Warn("Could not compile regex.")
Warn("Could not compile regex.").LogJson(map[string]string{"url": fullUrl,
"pattern": rewrite.Pattern})
continue
}

Expand All @@ -176,18 +213,19 @@ func (a *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
newpath := check.ReplaceAll([]byte(path), t)
req.URL.Path, err = url.PathUnescape(string(newpath))
if err != nil {
a.log.WithField("path", newpath).Warn("Could not rewrite Path.")
//a.log.WithField("path", newpath).Warn("Could not rewrite Path.")
continue
}
a.log.WithField("old_path", path).WithField("new_path", string(newpath)).Info("Apply rewrite.")
Warn("Apply rewrite.").LogJson(map[string]string{"url": fullUrl,
"old_path": path, "new_path": string(newpath)})
req.RequestURI = req.URL.RequestURI()
break
}
}

if a.enableTiming {
timeDiff := time.Now().Sub(startTime)
a.log.WithField("duration", timeDiff.Nanoseconds()).Info()
Info("Resolving time.").LogJson(map[string]string{"url": fullUrl, "duration": strconv.FormatInt(timeDiff.Nanoseconds(), 10)})
}

a.next.ServeHTTP(rw, req)
Expand Down
4 changes: 0 additions & 4 deletions vendor/github.com/sirupsen/logrus/.gitignore

This file was deleted.

40 changes: 0 additions & 40 deletions vendor/github.com/sirupsen/logrus/.golangci.yml

This file was deleted.

15 changes: 0 additions & 15 deletions vendor/github.com/sirupsen/logrus/.travis.yml

This file was deleted.

Loading

0 comments on commit 2f64424

Please sign in to comment.