Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load matchers #41

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions 00-main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func main() {
HTTPRetryDelay: httpRetryDelay,
LogContext: false,
LogFunctions: false,
Matchers: make(map[string]string),
MaxHTTPAttempts: maxHTTPAttempts,
Pathnames: flag.Args(),
ResultGathererChannel: make(chan context),
Expand All @@ -75,6 +76,12 @@ func main() {
WaitGroup: &sync.WaitGroup{},
}

err = loadMatchers(context)

if err != nil {
panic(err)
}

context.log("00 main")

go resultGatherer(*context)
Expand Down
28 changes: 5 additions & 23 deletions 05-expected-response-match-parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,11 @@ func expectedResponseMatchParser(context *context) {

reString := "("

switch parts[i+1] {
case ":date":
reString +=
"(Mon|Tue|Wed|Thu|Fri|Sat|Sun), " +
"(0\\d|1\\d|2\\d|3[01]) " +
"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) " +
"2\\d{3} " +
"(0\\d|1\\d|2[0-3]):" +
"(0\\d|1\\d|2\\d|3\\d|4\\d|5\\d):" +
"(0\\d|1\\d|2\\d|3\\d|4\\d|5\\d) " +
"(A|M|N|Y|Z|UT|GMT|[A-Z]{3}|[+-](0\\d|1[012]))"
case ":b62:22":
reString += "[0-9A-Za-z]{22}"
case ":iso8601:µs:z":
reString += "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[.]\\d{6}Z"
case ":uuid":
reString +=
"[[:xdigit:]]{8}-" +
"[[:xdigit:]]{4}-" +
"[[:xdigit:]]{4}-" +
"[[:xdigit:]]{4}-" +
"[[:xdigit:]]{12}"
default:
_, ok := context.Matchers[parts[i+1]]

if ok {
reString += context.Matchers[parts[i+1]]
} else {
reString += parts[i+1]
}

Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ RUN apk update && \
COPY * /go/src/github.com/tmornini/http-spec/

RUN cd /go/src/github.com/tmornini/http-spec && \
go get ./... && \
go install .

WORKDIR /
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ MAINTAINER Tom Mornini <tmornini@incentivenetworks.com>
COPY run-http-specs /run-http-specs

COPY *.htsf /

COPY matchers.yml /
```

## Basic Usage
Expand Down Expand Up @@ -155,6 +157,24 @@ for 128+ bit UUIDs.
⧆optional-name⧆:iso8601:µs:z⧆ is a matcher for ISO 8601 format timestamps
with microsecond resolution and zulu (Z) timezone.

## Custom Matchers

Custom matchers work just like built-in matchers and are loaded from an optionally
provided matchers.yml file in the docker container. See the example-Dockerfile and
matchers.yml file.

The matchers.yml file is a basic YAML file with the keys coresponding to the mandatory-regexp
portion of the matcher and the value corresponding to the actual regexp.

matchers.yml example:
```
RFC4122v4: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
```
usage of the custom matcher:
```
⧆optional-name⧆:RFC4122v4⧆
```

## Built-in Substitutes

⧈YYYY-MM-DD⧈ is a substitute for today's date
Expand Down
2 changes: 2 additions & 0 deletions example-Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ MAINTAINER Tom Mornini <tmornini@incentivenetworks.com>
COPY run-http-specs /run-http-specs

COPY *.htsf /

COPY matchers.yml /
15 changes: 15 additions & 0 deletions example-custom-matcher.htsf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
> GET https://api.subledger.com/v3/system/status HTTP/1.1
>

< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
< X-Frame-Options: ⧆⧆:same-origin⧆
< X-Xss-Protection: 1; mode=block
<
< {"dynamodb":true,"sqs":true,"redis":true}
2 changes: 1 addition & 1 deletion example-do-not-follow-redirect.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
< Content-Type: text/html;charset=ISO-8859-1
< Date: ⧆⧆:date⧆
< Location: https://jigsaw.w3.org/HTTP/300/Overview.html
< Public-Key-Pins: pin-sha256="cN0QSpPIkuwpT6iP2YjEo1bEwGpH/yiUn6yhdy+HNto="; pin-sha256="WGJkyYjx1QMdMe0UqlyOKXtydPDVrk7sl2fV+nNm1r4="; pin-sha256="LrKdTxZLRTvyHM4/atX2nquX9BeHRZMCxg3cf4rhc2I="; max-age=864000
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=864000
< Server: Jigsaw/2.3.0-beta⧆⧆\d+⧆
< Strict-Transport-Security: max-age=15552015; includeSubDomains; preload
< X-Frame-Options: deny
Expand Down
2 changes: 1 addition & 1 deletion example-not-found.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Content-Type: text/html
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand Down
4 changes: 2 additions & 2 deletions example-post.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Content-Type: application/json
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< Vary: Origin
Expand All @@ -34,7 +34,7 @@
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< Www-Authenticate: Basic realm="Subledger API v2"
Expand Down
4 changes: 2 additions & 2 deletions example-regexp-and-substitution.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand All @@ -21,7 +21,7 @@
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand Down
2 changes: 1 addition & 1 deletion example-scheme-and-hostname-2.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand Down
4 changes: 2 additions & 2 deletions example-sleep.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand All @@ -21,7 +21,7 @@
< Connection: keep-alive
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="NRx3RbA+pNNyfX8GvCJGysRCFQJnqiNhM+u8dVaqn90="; pin-sha256="wn7UqCaQr4O5YYeHLnz52CD6jasiTYyFz0plWceOlgM="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand Down
2 changes: 1 addition & 1 deletion example-uuid.htsf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
< Connection: keep-alive ⧆⧆:uuid⧆
< Content-Security-Policy: default-src https: data: 'unsafe-inline' 'unsafe-eval'
< Date: ⧆⧆:date⧆
< Public-Key-Pins: pin-sha256="hEJVeNxwqLnjseFv/doE3XU6Nr/hXJnoKdhn12iwavY="; pin-sha256="cTduB9g7EP4xd2glLUNhEq40f/jtyJF24dTzgVuKsZk="; max-age=300
< Public-Key-Pins: pin-sha256="⧆⧆[^"]+⧆"; pin-sha256="⧆⧆[^"]+⧆"; max-age=300
< Server: nginx
< Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
< X-Content-Type-Options: nosniff
Expand Down
43 changes: 43 additions & 0 deletions load-matchers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"errors"
"io/ioutil"

yaml "gopkg.in/yaml.v2"
)

func loadMatchers(context *context) error {
// load default matchers
context.Matchers[":date"] = "(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (0\\d|1\\d|2\\d|3[01]) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) 2\\d{3} (0\\d|1\\d|2[0-3]):(0\\d|1\\d|2\\d|3\\d|4\\d|5\\d):(0\\d|1\\d|2\\d|3\\d|4\\d|5\\d) (A|M|N|Y|Z|UT|GMT|[A-Z]{3}|[+-](0\\d|1[012]))"
context.Matchers[":b62:22"] = "[0-9A-Za-z]{22}"
context.Matchers[":iso8601:µs:z"] = "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[.]\\d{6}Z"
context.Matchers[":uuid"] = "[[:xdigit:]]{8}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{4}-[[:xdigit:]]{12}"

// load custom matchers if provided
var ymlData map[string]string

ymlFile, err := ioutil.ReadFile("/matchers.yml")
// ignore error (perhaps they didn't provide a custom matcher file)
if err == nil {
err = yaml.Unmarshal(ymlFile, &ymlData)

if err != nil {
return err
}

for key, value := range ymlData {
trueKey := ":" + key

_, ok := context.Matchers[trueKey]

if ok {
return errors.New(key + " is a default matcher and cannot be used")
}

context.Matchers[trueKey] = value
}
}

return nil
}
3 changes: 3 additions & 0 deletions matchers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
RFC3339: "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"
RFC4122v4: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
same-origin: SAMEORIGIN
2 changes: 2 additions & 0 deletions run-http-specs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ time (

http-spec example-built-in-substitution.htsf || exit 1

http-spec example-custom-matcher.htsf || exit 1

http-spec -hostname api.subledger.com -scheme http \
example-scheme-and-hostname-1.htsf || exit 1

Expand Down
1 change: 1 addition & 0 deletions type-context.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type context struct {
ID *big.Int
LogContext bool
LogFunctions bool
Matchers map[string]string
MaxHTTPAttempts int
Pathname string
Pathnames []string
Expand Down