mirror of
https://github.com/dstotijn/hetty.git
synced 2025-07-01 18:47:29 -04:00
Add filter support for HTTP headers
This commit is contained in:
@ -76,6 +76,7 @@ function Search(): JSX.Element {
|
|||||||
<ClickAwayListener onClickAway={handleClickAway}>
|
<ClickAwayListener onClickAway={handleClickAway}>
|
||||||
<Paper
|
<Paper
|
||||||
component="form"
|
component="form"
|
||||||
|
autoComplete="off"
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
ref={filterRef}
|
ref={filterRef}
|
||||||
sx={{
|
sx={{
|
||||||
@ -109,6 +110,8 @@ function Search(): JSX.Element {
|
|||||||
value={searchExpr}
|
value={searchExpr}
|
||||||
onChange={(e) => setSearchExpr(e.target.value)}
|
onChange={(e) => setSearchExpr(e.target.value)}
|
||||||
onFocus={() => setFilterOpen(true)}
|
onFocus={() => setFilterOpen(true)}
|
||||||
|
autoCorrect="false"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
<Tooltip title="Search">
|
<Tooltip title="Search">
|
||||||
<IconButton type="submit" sx={{ padding: 1.25 }}>
|
<IconButton type="submit" sx={{ padding: 1.25 }}>
|
||||||
|
@ -133,6 +133,15 @@ func matchReqInfixExpr(req *http.Request, expr search.InfixExpression) (bool, er
|
|||||||
return false, fmt.Errorf("failed to get string literal from request for left operand: %w", err)
|
return false, fmt.Errorf("failed to get string literal from request for left operand: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if leftVal == "headers" {
|
||||||
|
match, err := search.MatchHTTPHeaders(expr.Operator, expr.Right, req.Header)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to match request HTTP headers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match, nil
|
||||||
|
}
|
||||||
|
|
||||||
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
||||||
right, ok := expr.Right.(search.RegexpLiteral)
|
right, ok := expr.Right.(search.RegexpLiteral)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -324,6 +333,15 @@ func matchResInfixExpr(res *http.Response, expr search.InfixExpression) (bool, e
|
|||||||
return false, fmt.Errorf("failed to get string literal from response for left operand: %w", err)
|
return false, fmt.Errorf("failed to get string literal from response for left operand: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if leftVal == "headers" {
|
||||||
|
match, err := search.MatchHTTPHeaders(expr.Operator, expr.Right, res.Header)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to match request HTTP headers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match, nil
|
||||||
|
}
|
||||||
|
|
||||||
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
||||||
right, ok := expr.Right.(search.RegexpLiteral)
|
right, ok := expr.Right.(search.RegexpLiteral)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -98,6 +98,24 @@ func (reqLog RequestLog) matchInfixExpr(expr search.InfixExpression) (bool, erro
|
|||||||
|
|
||||||
leftVal := reqLog.getMappedStringLiteral(left.Value)
|
leftVal := reqLog.getMappedStringLiteral(left.Value)
|
||||||
|
|
||||||
|
if leftVal == "req.headers" {
|
||||||
|
match, err := search.MatchHTTPHeaders(expr.Operator, expr.Right, reqLog.Header)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to match request HTTP headers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if leftVal == "res.headers" && reqLog.Response != nil {
|
||||||
|
match, err := search.MatchHTTPHeaders(expr.Operator, expr.Right, reqLog.Response.Header)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to match response HTTP headers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match, nil
|
||||||
|
}
|
||||||
|
|
||||||
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
||||||
right, ok := expr.Right.(search.RegexpLiteral)
|
right, ok := expr.Right.(search.RegexpLiteral)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
82
pkg/search/http.go
Normal file
82
pkg/search/http.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MatchHTTPHeaders(op TokenType, expr Expression, headers http.Header) (bool, error) {
|
||||||
|
if headers == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch op {
|
||||||
|
case TokOpEq:
|
||||||
|
strLiteral, ok := expr.(StringLiteral)
|
||||||
|
if !ok {
|
||||||
|
return false, errors.New("search: expression must be a string literal")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return `true` if at least one header (<key>: <value>) is equal to the string literal.
|
||||||
|
for key, values := range headers {
|
||||||
|
for _, value := range values {
|
||||||
|
if strLiteral.Value == fmt.Sprintf("%v: %v", key, value) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
case TokOpNotEq:
|
||||||
|
strLiteral, ok := expr.(StringLiteral)
|
||||||
|
if !ok {
|
||||||
|
return false, errors.New("search: expression must be a string literal")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return `true` if none of the headers (<key>: <value>) are equal to the string literal.
|
||||||
|
for key, values := range headers {
|
||||||
|
for _, value := range values {
|
||||||
|
if strLiteral.Value == fmt.Sprintf("%v: %v", key, value) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
case TokOpRe:
|
||||||
|
re, ok := expr.(RegexpLiteral)
|
||||||
|
if !ok {
|
||||||
|
return false, errors.New("search: expression must be a regular expression")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return `true` if at least one header (<key>: <value>) matches the regular expression.
|
||||||
|
for key, values := range headers {
|
||||||
|
for _, value := range values {
|
||||||
|
if re.MatchString(fmt.Sprintf("%v: %v", key, value)) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
case TokOpNotRe:
|
||||||
|
re, ok := expr.(RegexpLiteral)
|
||||||
|
if !ok {
|
||||||
|
return false, errors.New("search: expression must be a regular expression")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return `true` if none of the headers (<key>: <value>) match the regular expression.
|
||||||
|
for key, values := range headers {
|
||||||
|
for _, value := range values {
|
||||||
|
if re.MatchString(fmt.Sprintf("%v: %v", key, value)) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
default:
|
||||||
|
return false, fmt.Errorf("search: unsupported operator %q", op.String())
|
||||||
|
}
|
||||||
|
}
|
@ -91,6 +91,24 @@ func (req Request) matchInfixExpr(expr search.InfixExpression) (bool, error) {
|
|||||||
|
|
||||||
leftVal := req.getMappedStringLiteral(left.Value)
|
leftVal := req.getMappedStringLiteral(left.Value)
|
||||||
|
|
||||||
|
if leftVal == "req.headers" {
|
||||||
|
match, err := search.MatchHTTPHeaders(expr.Operator, expr.Right, req.Header)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to match request HTTP headers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if leftVal == "res.headers" && req.Response != nil {
|
||||||
|
match, err := search.MatchHTTPHeaders(expr.Operator, expr.Right, req.Response.Header)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("failed to match response HTTP headers: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return match, nil
|
||||||
|
}
|
||||||
|
|
||||||
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
if expr.Operator == search.TokOpRe || expr.Operator == search.TokOpNotRe {
|
||||||
right, ok := expr.Right.(search.RegexpLiteral)
|
right, ok := expr.Right.(search.RegexpLiteral)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
Reference in New Issue
Block a user