mirror of
https://github.com/dstotijn/hetty.git
synced 2025-07-01 18:47:29 -04:00
Finish first working version of reqlog
This commit is contained in:
48
cmd/main.go
48
cmd/main.go
@ -1,12 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -44,51 +41,15 @@ func main() {
|
||||
log.Fatalf("[FATAL] Could not parse CA: %v", err)
|
||||
}
|
||||
|
||||
reqLogStore := reqlog.NewRequestLogStore()
|
||||
reqLogService := reqlog.NewService()
|
||||
|
||||
p, err := proxy.NewProxy(caCert, tlsCA.PrivateKey)
|
||||
if err != nil {
|
||||
log.Fatalf("[FATAL] Could not create Proxy: %v", err)
|
||||
}
|
||||
|
||||
p.UseRequestModifier(func(next proxy.RequestModifyFunc) proxy.RequestModifyFunc {
|
||||
return func(req *http.Request) {
|
||||
next(req)
|
||||
clone := req.Clone(req.Context())
|
||||
var body []byte
|
||||
if req.Body != nil {
|
||||
// TODO: Use io.LimitReader.
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] Could not read request body for logging: %v", err)
|
||||
return
|
||||
}
|
||||
req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
reqLogStore.AddRequest(*clone, body)
|
||||
}
|
||||
})
|
||||
|
||||
p.UseResponseModifier(func(next proxy.ResponseModifyFunc) proxy.ResponseModifyFunc {
|
||||
return func(res *http.Response) error {
|
||||
if err := next(res); err != nil {
|
||||
return err
|
||||
}
|
||||
clone := *res
|
||||
var body []byte
|
||||
if res.Body != nil {
|
||||
// TODO: Use io.LimitReader.
|
||||
var err error
|
||||
body, err = ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not read response body: %v", err)
|
||||
}
|
||||
res.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
reqLogStore.AddResponse(clone, body)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
p.UseRequestModifier(reqLogService.RequestModifier)
|
||||
p.UseResponseModifier(reqLogService.ResponseModifier)
|
||||
|
||||
var adminHandler http.Handler
|
||||
|
||||
@ -116,7 +77,7 @@ func main() {
|
||||
// GraphQL server.
|
||||
adminRouter.Path("/api/playground").Handler(playground.Handler("GraphQL Playground", "/api/graphql"))
|
||||
adminRouter.Path("/api/graphql").Handler(handler.NewDefaultServer(api.NewExecutableSchema(api.Config{Resolvers: &api.Resolver{
|
||||
RequestLogStore: &reqLogStore,
|
||||
RequestLogService: &reqLogService,
|
||||
}})))
|
||||
|
||||
// Admin interface.
|
||||
@ -131,6 +92,7 @@ func main() {
|
||||
TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){}, // Disable HTTP/2
|
||||
}
|
||||
|
||||
log.Println("[INFO] Running server on :8080 ...")
|
||||
err = s.ListenAndServe()
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("[FATAL] HTTP server closed: %v", err)
|
||||
|
6
go.mod
6
go.mod
@ -3,8 +3,8 @@ module github.com/dstotijn/gurp
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.11.1
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/vektah/gqlparser v1.2.0
|
||||
github.com/99designs/gqlgen v0.11.3
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/vektah/gqlparser/v2 v2.0.1
|
||||
)
|
||||
|
35
go.sum
35
go.sum
@ -1,24 +1,29 @@
|
||||
github.com/99designs/gqlgen v0.10.2 h1:FfjCqIWejHDJeLpQTI0neoZo5vDO3sdo5oNCucet3A0=
|
||||
github.com/99designs/gqlgen v0.10.2/go.mod h1:aDB7oabSAyZ4kUHLEySsLxnWrBy3lA0A2gWKU+qoHwI=
|
||||
github.com/99designs/gqlgen v0.11.1 h1:QoSL8/AAJ2T3UOeQbdnBR32JcG4pO08+P/g5jdbFkUg=
|
||||
github.com/99designs/gqlgen v0.11.1/go.mod h1:vjFOyBZ7NwDl+GdSD4PFn7BQn5Fy7ohJwXn7Vk8zz+c=
|
||||
github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4=
|
||||
github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/agnivade/levenshtein v1.0.1 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0=
|
||||
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
|
||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
@ -43,23 +48,22 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser v1.2.0 h1:ntkSCX7F5ZJKl+HIVnmLaO269MruasVpNiMOjX9kgo0=
|
||||
github.com/vektah/gqlparser v1.2.0/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=
|
||||
github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=
|
||||
github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -81,8 +85,7 @@ golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96b
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -1,6 +1,6 @@
|
||||
@cert = $HOME/.ssh/gurp_cert.pem
|
||||
@key = $HOME/.ssh/gurp_key.pem
|
||||
@dev = false
|
||||
@dev = true
|
||||
@adminPath = $PWD/admin/build
|
||||
|
||||
**/*.go {
|
||||
|
@ -42,19 +42,26 @@ type DirectiveRoot struct {
|
||||
}
|
||||
|
||||
type ComplexityRoot struct {
|
||||
Query struct {
|
||||
GetRequests func(childComplexity int) int
|
||||
}
|
||||
|
||||
Request struct {
|
||||
HTTPRequest struct {
|
||||
Body func(childComplexity int) int
|
||||
Method func(childComplexity int) int
|
||||
Response func(childComplexity int) int
|
||||
Timestamp func(childComplexity int) int
|
||||
URL func(childComplexity int) int
|
||||
}
|
||||
|
||||
HTTPResponse struct {
|
||||
Body func(childComplexity int) int
|
||||
StatusCode func(childComplexity int) int
|
||||
}
|
||||
|
||||
Query struct {
|
||||
GetHTTPRequests func(childComplexity int) int
|
||||
}
|
||||
}
|
||||
|
||||
type QueryResolver interface {
|
||||
GetRequests(ctx context.Context) ([]Request, error)
|
||||
GetHTTPRequests(ctx context.Context) ([]HTTPRequest, error)
|
||||
}
|
||||
|
||||
type executableSchema struct {
|
||||
@ -72,33 +79,61 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
_ = ec
|
||||
switch typeName + "." + field {
|
||||
|
||||
case "Query.getRequests":
|
||||
if e.complexity.Query.GetRequests == nil {
|
||||
case "HttpRequest.body":
|
||||
if e.complexity.HTTPRequest.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Query.GetRequests(childComplexity), true
|
||||
return e.complexity.HTTPRequest.Body(childComplexity), true
|
||||
|
||||
case "Request.method":
|
||||
if e.complexity.Request.Method == nil {
|
||||
case "HttpRequest.method":
|
||||
if e.complexity.HTTPRequest.Method == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Request.Method(childComplexity), true
|
||||
return e.complexity.HTTPRequest.Method(childComplexity), true
|
||||
|
||||
case "Request.timestamp":
|
||||
if e.complexity.Request.Timestamp == nil {
|
||||
case "HttpRequest.response":
|
||||
if e.complexity.HTTPRequest.Response == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Request.Timestamp(childComplexity), true
|
||||
return e.complexity.HTTPRequest.Response(childComplexity), true
|
||||
|
||||
case "Request.url":
|
||||
if e.complexity.Request.URL == nil {
|
||||
case "HttpRequest.timestamp":
|
||||
if e.complexity.HTTPRequest.Timestamp == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Request.URL(childComplexity), true
|
||||
return e.complexity.HTTPRequest.Timestamp(childComplexity), true
|
||||
|
||||
case "HttpRequest.url":
|
||||
if e.complexity.HTTPRequest.URL == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.HTTPRequest.URL(childComplexity), true
|
||||
|
||||
case "HttpResponse.body":
|
||||
if e.complexity.HTTPResponse.Body == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.HTTPResponse.Body(childComplexity), true
|
||||
|
||||
case "HttpResponse.statusCode":
|
||||
if e.complexity.HTTPResponse.StatusCode == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.HTTPResponse.StatusCode(childComplexity), true
|
||||
|
||||
case "Query.getHttpRequests":
|
||||
if e.complexity.Query.GetHTTPRequests == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Query.GetHTTPRequests(childComplexity), true
|
||||
|
||||
}
|
||||
return 0, false
|
||||
@ -150,23 +185,37 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er
|
||||
}
|
||||
|
||||
var sources = []*ast.Source{
|
||||
&ast.Source{Name: "pkg/api/schema.graphql", Input: `type Request {
|
||||
&ast.Source{Name: "pkg/api/schema.graphql", Input: `type HttpRequest {
|
||||
url: String!
|
||||
method: HttpMethod!
|
||||
body: String
|
||||
timestamp: Time!
|
||||
response: HttpResponse
|
||||
}
|
||||
|
||||
type HttpResponse {
|
||||
statusCode: Int!
|
||||
body: String
|
||||
}
|
||||
|
||||
type Query {
|
||||
getRequests: [Request!]!
|
||||
getHttpRequests: [HttpRequest!]!
|
||||
}
|
||||
|
||||
enum HttpMethod {
|
||||
GET
|
||||
HEAD
|
||||
POST
|
||||
PUT
|
||||
DELETE
|
||||
CONNECT
|
||||
OPTIONS
|
||||
TRACE
|
||||
PATCH
|
||||
}
|
||||
|
||||
scalar Time`, BuiltIn: false},
|
||||
scalar Time
|
||||
`, BuiltIn: false},
|
||||
}
|
||||
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
||||
|
||||
@ -224,7 +273,236 @@ func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArg
|
||||
|
||||
// region **************************** field.gotpl *****************************
|
||||
|
||||
func (ec *executionContext) _Query_getRequests(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
func (ec *executionContext) _HttpRequest_url(ctx context.Context, field graphql.CollectedField, obj *HTTPRequest) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpRequest",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.URL, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _HttpRequest_method(ctx context.Context, field graphql.CollectedField, obj *HTTPRequest) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpRequest",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Method, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(HTTPMethod)
|
||||
fc.Result = res
|
||||
return ec.marshalNHttpMethod2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPMethod(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _HttpRequest_body(ctx context.Context, field graphql.CollectedField, obj *HTTPRequest) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpRequest",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Body, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _HttpRequest_timestamp(ctx context.Context, field graphql.CollectedField, obj *HTTPRequest) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpRequest",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Timestamp, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(time.Time)
|
||||
fc.Result = res
|
||||
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _HttpRequest_response(ctx context.Context, field graphql.CollectedField, obj *HTTPRequest) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpRequest",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Response, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*HTTPResponse)
|
||||
fc.Result = res
|
||||
return ec.marshalOHttpResponse2ᚖgithubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPResponse(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _HttpResponse_statusCode(ctx context.Context, field graphql.CollectedField, obj *HTTPResponse) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpResponse",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.StatusCode, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(int)
|
||||
fc.Result = res
|
||||
return ec.marshalNInt2int(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _HttpResponse_body(ctx context.Context, field graphql.CollectedField, obj *HTTPResponse) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "HttpResponse",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Body, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*string)
|
||||
fc.Result = res
|
||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_getHttpRequests(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
@ -241,7 +519,7 @@ func (ec *executionContext) _Query_getRequests(ctx context.Context, field graphq
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Query().GetRequests(rctx)
|
||||
return ec.resolvers.Query().GetHTTPRequests(rctx)
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
@ -253,9 +531,9 @@ func (ec *executionContext) _Query_getRequests(ctx context.Context, field graphq
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.([]Request)
|
||||
res := resTmp.([]HTTPRequest)
|
||||
fc.Result = res
|
||||
return ec.marshalNRequest2ᚕgithubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐRequestᚄ(ctx, field.Selections, res)
|
||||
return ec.marshalNHttpRequest2ᚕgithubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPRequestᚄ(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
@ -327,108 +605,6 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C
|
||||
return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Request_url(ctx context.Context, field graphql.CollectedField, obj *Request) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Request",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.URL, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(string)
|
||||
fc.Result = res
|
||||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Request_method(ctx context.Context, field graphql.CollectedField, obj *Request) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Request",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Method, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(HTTPMethod)
|
||||
fc.Result = res
|
||||
return ec.marshalNHttpMethod2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPMethod(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Request_timestamp(ctx context.Context, field graphql.CollectedField, obj *Request) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "Request",
|
||||
Field: field,
|
||||
Args: nil,
|
||||
IsMethod: false,
|
||||
}
|
||||
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.Timestamp, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
if !graphql.HasFieldError(ctx, fc) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(time.Time)
|
||||
fc.Result = res
|
||||
return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
@ -1492,6 +1668,76 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co
|
||||
|
||||
// region **************************** object.gotpl ****************************
|
||||
|
||||
var httpRequestImplementors = []string{"HttpRequest"}
|
||||
|
||||
func (ec *executionContext) _HttpRequest(ctx context.Context, sel ast.SelectionSet, obj *HTTPRequest) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, httpRequestImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("HttpRequest")
|
||||
case "url":
|
||||
out.Values[i] = ec._HttpRequest_url(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "method":
|
||||
out.Values[i] = ec._HttpRequest_method(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "body":
|
||||
out.Values[i] = ec._HttpRequest_body(ctx, field, obj)
|
||||
case "timestamp":
|
||||
out.Values[i] = ec._HttpRequest_timestamp(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "response":
|
||||
out.Values[i] = ec._HttpRequest_response(ctx, field, obj)
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
var httpResponseImplementors = []string{"HttpResponse"}
|
||||
|
||||
func (ec *executionContext) _HttpResponse(ctx context.Context, sel ast.SelectionSet, obj *HTTPResponse) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, httpResponseImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("HttpResponse")
|
||||
case "statusCode":
|
||||
out.Values[i] = ec._HttpResponse_statusCode(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "body":
|
||||
out.Values[i] = ec._HttpResponse_body(ctx, field, obj)
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
var queryImplementors = []string{"Query"}
|
||||
|
||||
func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler {
|
||||
@ -1507,7 +1753,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("Query")
|
||||
case "getRequests":
|
||||
case "getHttpRequests":
|
||||
field := field
|
||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||
defer func() {
|
||||
@ -1515,7 +1761,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
}
|
||||
}()
|
||||
res = ec._Query_getRequests(ctx, field)
|
||||
res = ec._Query_getHttpRequests(ctx, field)
|
||||
if res == graphql.Null {
|
||||
atomic.AddUint32(&invalids, 1)
|
||||
}
|
||||
@ -1536,43 +1782,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||
return out
|
||||
}
|
||||
|
||||
var requestImplementors = []string{"Request"}
|
||||
|
||||
func (ec *executionContext) _Request(ctx context.Context, sel ast.SelectionSet, obj *Request) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, requestImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("Request")
|
||||
case "url":
|
||||
out.Values[i] = ec._Request_url(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "method":
|
||||
out.Values[i] = ec._Request_method(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "timestamp":
|
||||
out.Values[i] = ec._Request_timestamp(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
}
|
||||
out.Dispatch()
|
||||
if invalids > 0 {
|
||||
return graphql.Null
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
var __DirectiveImplementors = []string{"__Directive"}
|
||||
|
||||
func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler {
|
||||
@ -1841,11 +2050,11 @@ func (ec *executionContext) marshalNHttpMethod2githubᚗcomᚋdstotijnᚋgurpᚋ
|
||||
return v
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNRequest2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐRequest(ctx context.Context, sel ast.SelectionSet, v Request) graphql.Marshaler {
|
||||
return ec._Request(ctx, sel, &v)
|
||||
func (ec *executionContext) marshalNHttpRequest2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPRequest(ctx context.Context, sel ast.SelectionSet, v HTTPRequest) graphql.Marshaler {
|
||||
return ec._HttpRequest(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNRequest2ᚕgithubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐRequestᚄ(ctx context.Context, sel ast.SelectionSet, v []Request) graphql.Marshaler {
|
||||
func (ec *executionContext) marshalNHttpRequest2ᚕgithubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPRequestᚄ(ctx context.Context, sel ast.SelectionSet, v []HTTPRequest) graphql.Marshaler {
|
||||
ret := make(graphql.Array, len(v))
|
||||
var wg sync.WaitGroup
|
||||
isLen1 := len(v) == 1
|
||||
@ -1869,7 +2078,7 @@ func (ec *executionContext) marshalNRequest2ᚕgithubᚗcomᚋdstotijnᚋgurpᚋ
|
||||
if !isLen1 {
|
||||
defer wg.Done()
|
||||
}
|
||||
ret[i] = ec.marshalNRequest2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐRequest(ctx, sel, v[i])
|
||||
ret[i] = ec.marshalNHttpRequest2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPRequest(ctx, sel, v[i])
|
||||
}
|
||||
if isLen1 {
|
||||
f(i)
|
||||
@ -1882,6 +2091,20 @@ func (ec *executionContext) marshalNRequest2ᚕgithubᚗcomᚋdstotijnᚋgurpᚋ
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) {
|
||||
return graphql.UnmarshalInt(v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler {
|
||||
res := graphql.MarshalInt(v)
|
||||
if res == graphql.Null {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) {
|
||||
return graphql.UnmarshalString(v)
|
||||
}
|
||||
@ -2159,6 +2382,17 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast
|
||||
return ec.marshalOBoolean2bool(ctx, sel, *v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOHttpResponse2githubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPResponse(ctx context.Context, sel ast.SelectionSet, v HTTPResponse) graphql.Marshaler {
|
||||
return ec._HttpResponse(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalOHttpResponse2ᚖgithubᚗcomᚋdstotijnᚋgurpᚋpkgᚋapiᚐHTTPResponse(ctx context.Context, sel ast.SelectionSet, v *HTTPResponse) graphql.Marshaler {
|
||||
if v == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._HttpResponse(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) {
|
||||
return graphql.UnmarshalString(v)
|
||||
}
|
||||
|
@ -9,27 +9,48 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
URL string `json:"url"`
|
||||
Method HTTPMethod `json:"method"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
type HTTPRequest struct {
|
||||
URL string `json:"url"`
|
||||
Method HTTPMethod `json:"method"`
|
||||
Body *string `json:"body"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Response *HTTPResponse `json:"response"`
|
||||
}
|
||||
|
||||
type HTTPResponse struct {
|
||||
StatusCode int `json:"statusCode"`
|
||||
Body *string `json:"body"`
|
||||
}
|
||||
|
||||
type HTTPMethod string
|
||||
|
||||
const (
|
||||
HTTPMethodGet HTTPMethod = "GET"
|
||||
HTTPMethodPost HTTPMethod = "POST"
|
||||
HTTPMethodGet HTTPMethod = "GET"
|
||||
HTTPMethodHead HTTPMethod = "HEAD"
|
||||
HTTPMethodPost HTTPMethod = "POST"
|
||||
HTTPMethodPut HTTPMethod = "PUT"
|
||||
HTTPMethodDelete HTTPMethod = "DELETE"
|
||||
HTTPMethodConnect HTTPMethod = "CONNECT"
|
||||
HTTPMethodOptions HTTPMethod = "OPTIONS"
|
||||
HTTPMethodTrace HTTPMethod = "TRACE"
|
||||
HTTPMethodPatch HTTPMethod = "PATCH"
|
||||
)
|
||||
|
||||
var AllHTTPMethod = []HTTPMethod{
|
||||
HTTPMethodGet,
|
||||
HTTPMethodHead,
|
||||
HTTPMethodPost,
|
||||
HTTPMethodPut,
|
||||
HTTPMethodDelete,
|
||||
HTTPMethodConnect,
|
||||
HTTPMethodOptions,
|
||||
HTTPMethodTrace,
|
||||
HTTPMethodPatch,
|
||||
}
|
||||
|
||||
func (e HTTPMethod) IsValid() bool {
|
||||
switch e {
|
||||
case HTTPMethodGet, HTTPMethodPost:
|
||||
case HTTPMethodGet, HTTPMethodHead, HTTPMethodPost, HTTPMethodPut, HTTPMethodDelete, HTTPMethodConnect, HTTPMethodOptions, HTTPMethodTrace, HTTPMethodPatch:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -1,5 +1,7 @@
|
||||
package api
|
||||
|
||||
//go:generate go run github.com/99designs/gqlgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
@ -8,27 +10,44 @@ import (
|
||||
)
|
||||
|
||||
type Resolver struct {
|
||||
RequestLogStore *reqlog.RequestLogStore
|
||||
RequestLogService *reqlog.Service
|
||||
}
|
||||
|
||||
type queryResolver struct{ *Resolver }
|
||||
|
||||
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }
|
||||
|
||||
func (r *queryResolver) GetRequests(ctx context.Context) ([]Request, error) {
|
||||
reqs := r.RequestLogStore.Requests()
|
||||
resp := make([]Request, len(reqs))
|
||||
func (r *queryResolver) GetHTTPRequests(ctx context.Context) ([]HTTPRequest, error) {
|
||||
logs := r.RequestLogService.Requests()
|
||||
reqs := make([]HTTPRequest, len(logs))
|
||||
|
||||
for i := range resp {
|
||||
method := HTTPMethod(reqs[i].Request.Method)
|
||||
for i, log := range logs {
|
||||
method := HTTPMethod(log.Request.Method)
|
||||
if !method.IsValid() {
|
||||
return nil, fmt.Errorf("request has invalid method: %v", method)
|
||||
}
|
||||
resp[i] = Request{
|
||||
URL: reqs[i].Request.URL.String(),
|
||||
Method: method,
|
||||
|
||||
reqs[i] = HTTPRequest{
|
||||
URL: log.Request.URL.String(),
|
||||
Method: method,
|
||||
Timestamp: log.Timestamp,
|
||||
}
|
||||
|
||||
if len(log.Body) > 0 {
|
||||
reqBody := string(log.Body)
|
||||
reqs[i].Body = &reqBody
|
||||
}
|
||||
|
||||
if log.Response != nil {
|
||||
reqs[i].Response = &HTTPResponse{
|
||||
StatusCode: log.Response.Response.StatusCode,
|
||||
}
|
||||
if len(log.Response.Body) > 0 {
|
||||
resBody := string(log.Response.Body)
|
||||
reqs[i].Response.Body = &resBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
return reqs, nil
|
||||
}
|
||||
|
@ -1,17 +1,30 @@
|
||||
type Request {
|
||||
type HttpRequest {
|
||||
url: String!
|
||||
method: HttpMethod!
|
||||
body: String
|
||||
timestamp: Time!
|
||||
response: HttpResponse
|
||||
}
|
||||
|
||||
type HttpResponse {
|
||||
statusCode: Int!
|
||||
body: String
|
||||
}
|
||||
|
||||
type Query {
|
||||
getRequests: [Request!]!
|
||||
getHttpRequests: [HttpRequest!]!
|
||||
}
|
||||
|
||||
enum HttpMethod {
|
||||
GET
|
||||
HEAD
|
||||
POST
|
||||
PUT
|
||||
DELETE
|
||||
CONNECT
|
||||
OPTIONS
|
||||
TRACE
|
||||
PATCH
|
||||
}
|
||||
|
||||
scalar Time
|
||||
scalar Time
|
||||
|
@ -10,8 +10,14 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type contextKey int
|
||||
|
||||
const ReqIDKey contextKey = 0
|
||||
|
||||
// Proxy implements http.Handler and offers MITM behaviour for modifying
|
||||
// HTTP requests and responses.
|
||||
type Proxy struct {
|
||||
@ -46,6 +52,11 @@ func NewProxy(ca *x509.Certificate, key crypto.PrivateKey) (*Proxy, error) {
|
||||
}
|
||||
|
||||
func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Add a unique request ID, to be used for correlating responses to requests.
|
||||
reqID := uuid.New()
|
||||
ctx := context.WithValue(r.Context(), ReqIDKey, reqID)
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
if r.Method == http.MethodConnect {
|
||||
p.handleConnect(w, r)
|
||||
return
|
||||
@ -69,6 +80,10 @@ func (p *Proxy) modifyRequest(r *http.Request) {
|
||||
r.URL.Scheme = "https"
|
||||
}
|
||||
|
||||
// Setting `X-Forwarded-For` to `nil` ensures that http.ReverseProxy doesn't
|
||||
// set this header.
|
||||
r.Header["X-Forwarded-For"] = nil
|
||||
|
||||
fn := nopReqModifier
|
||||
|
||||
for i := len(p.reqModifiers) - 1; i >= 0; i-- {
|
||||
@ -119,7 +134,7 @@ func (p *Proxy) handleConnect(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
l := &OnceAcceptListener{clientConnNotify.Conn}
|
||||
|
||||
err = http.Serve(l, p.handler)
|
||||
err = http.Serve(l, p)
|
||||
if err != nil && err != ErrAlreadyAccepted {
|
||||
log.Printf("[ERROR] Serving HTTP request failed: %v", err)
|
||||
}
|
||||
|
@ -1,51 +1,150 @@
|
||||
package reqlog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/dstotijn/gurp/pkg/proxy"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
Request http.Request
|
||||
Body []byte
|
||||
ID uuid.UUID
|
||||
Request http.Request
|
||||
Body []byte
|
||||
Timestamp time.Time
|
||||
Response *Response
|
||||
}
|
||||
|
||||
type response struct {
|
||||
res http.Response
|
||||
body []byte
|
||||
type Response struct {
|
||||
Response http.Response
|
||||
Body []byte
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
type RequestLogStore struct {
|
||||
reqStore []Request
|
||||
resStore []response
|
||||
reqMu sync.Mutex
|
||||
resMu sync.Mutex
|
||||
type Service struct {
|
||||
store []Request
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewRequestLogStore() RequestLogStore {
|
||||
return RequestLogStore{
|
||||
reqStore: make([]Request, 0),
|
||||
resStore: make([]response, 0),
|
||||
func NewService() Service {
|
||||
return Service{
|
||||
store: make([]Request, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (store *RequestLogStore) AddRequest(req http.Request, body []byte) {
|
||||
store.reqMu.Lock()
|
||||
defer store.reqMu.Unlock()
|
||||
func (svc *Service) Requests() []Request {
|
||||
// TODO(?): Is locking necessary here?
|
||||
svc.mu.Lock()
|
||||
defer svc.mu.Unlock()
|
||||
|
||||
store.reqStore = append(store.reqStore, Request{req, body})
|
||||
return svc.store
|
||||
}
|
||||
|
||||
func (store *RequestLogStore) Requests() []Request {
|
||||
store.reqMu.Lock()
|
||||
defer store.reqMu.Unlock()
|
||||
func (svc *Service) addRequest(reqID uuid.UUID, req http.Request, body []byte) Request {
|
||||
svc.mu.Lock()
|
||||
defer svc.mu.Unlock()
|
||||
|
||||
return store.reqStore
|
||||
reqLog := Request{
|
||||
ID: reqID,
|
||||
Request: req,
|
||||
Body: body,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
svc.store = append(svc.store, reqLog)
|
||||
|
||||
return reqLog
|
||||
}
|
||||
|
||||
func (store *RequestLogStore) AddResponse(res http.Response, body []byte) {
|
||||
store.resMu.Lock()
|
||||
defer store.resMu.Unlock()
|
||||
func (svc *Service) addResponse(reqID uuid.UUID, res http.Response, body []byte) error {
|
||||
svc.mu.Lock()
|
||||
defer svc.mu.Unlock()
|
||||
|
||||
store.resStore = append(store.resStore, response{res, body})
|
||||
for i := range svc.store {
|
||||
if svc.store[i].ID == reqID {
|
||||
svc.store[i].Response = &Response{
|
||||
Response: res,
|
||||
Body: body,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("no request found with ID: %s", reqID)
|
||||
}
|
||||
|
||||
func (svc *Service) RequestModifier(next proxy.RequestModifyFunc) proxy.RequestModifyFunc {
|
||||
return func(req *http.Request) {
|
||||
next(req)
|
||||
|
||||
clone := req.Clone(req.Context())
|
||||
var body []byte
|
||||
if req.Body != nil {
|
||||
// TODO: Use io.LimitReader.
|
||||
var err error
|
||||
body, err = ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] Could not read request body for logging: %v", err)
|
||||
return
|
||||
}
|
||||
req.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
|
||||
reqID, _ := req.Context().Value(proxy.ReqIDKey).(uuid.UUID)
|
||||
if reqID == uuid.Nil {
|
||||
log.Println("[ERROR] Request is missing a related request ID")
|
||||
return
|
||||
}
|
||||
|
||||
_ = svc.addRequest(reqID, *clone, body)
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *Service) ResponseModifier(next proxy.ResponseModifyFunc) proxy.ResponseModifyFunc {
|
||||
return func(res *http.Response) error {
|
||||
if err := next(res); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clone := *res
|
||||
|
||||
// TODO: Use io.LimitReader.
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reqlog: could not read response body: %v", err)
|
||||
}
|
||||
res.Body = ioutil.NopCloser(bytes.NewBuffer(body))
|
||||
|
||||
if res.Header.Get("Content-Encoding") == "gzip" {
|
||||
gzipReader, err := gzip.NewReader(bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("reqlog: could not create gzip reader: %v", err)
|
||||
}
|
||||
defer gzipReader.Close()
|
||||
body, err = ioutil.ReadAll(gzipReader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reqlog: could not read gzipped response body: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
reqID, _ := res.Request.Context().Value(proxy.ReqIDKey).(uuid.UUID)
|
||||
if reqID == uuid.Nil {
|
||||
return errors.New("reqlog: request is missing ID")
|
||||
}
|
||||
|
||||
if err := svc.addResponse(reqID, clone, body); err != nil {
|
||||
return fmt.Errorf("reqlog: could not add response: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user