Can't detect non present header fields #489

Closed
opened 2025-12-29 15:25:04 +01:00 by adam · 5 comments
Owner

Originally created by @MichaelIDS on GitHub (Feb 16, 2023).

I was trying to do bad/missing header field detection.
I could detect the values of a header fine when it was present, however, I can't seem to get anything to trigger when it's not present.
I lifted the below api-key check from the Wiki, but for me this doesn't ever trigger.

{
        "Swagger Doc Title": "Bad Request",
        "Comment": "Bad JWT token",
        "Priority": 1,
        "Request": {
            "Path": {
                "Matchers": [
                    {
                        "Name": "ExactMatcher",
                        "Pattern": "/timeEntry"
                    }
                ]
            },
            "Headers": [
                {
                    "Name": "api-key",
                    "Matchers": [
                        {
                            "Name": "WildcardMatcher",
                            "Pattern": "*",
                            "IgnoreCase": true,
                            "RejectOnMatch": true
                        }
                    ]
                }
            ]
        },
        "Response": {
            "StatusCode": 400,
            "Headers": {
                "Content-Type": "application/json"
            },
            "BodyAsJson": {
                "errorMessage": "Validation exception",
                "status": 400,
                "WireMock reason": "Bad Authorization bearer token"
            },
            "UseTransformer": false
        }
    }

Log output for sample request without this Header field provided.

{
  "Guid": "a5054f98-75e7-4b04-b110-0ed2e53b3ece",
  "Request": {
    "ClientIP": "::1",
    "DateTime": "2023-02-16T14:03:06.5702065Z",
    "Path": "/timeEntry",
    "AbsolutePath": "/timeEntry",
    "Url": "http://localhost:9091/timeEntry",
    "AbsoluteUrl": "http://localhost:9091/timeEntry",
    "ProxyUrl": null,
    "Query": {},
    "Method": "POST",
    "Headers": {
      "Postman-Token": [
        "89b82b0b-8fa9-4185-8240-945029798d16"
      ],
      "Connection": [
        "keep-alive"
      ],
      "Content-Length": [
        "54"
      ],
      "Content-Type": [
        "application/json"
      ],
      "Accept": [
        "*/*"
      ],
      "Accept-Encoding": [
        "gzip, deflate, br"
      ],
      "Host": [
        "localhost:9091"
      ],
      "User-Agent": [
        "PostmanRuntime/7.31.0"
      ]
    },
    "Cookies": {},
    "Body": "{\n  \"username\": \"username\",\n  \"password\": \"password\"\n}",
    "BodyAsJson": {
      "username": "username",
      "password": "password"
    },
    "BodyAsBytes": null,
    "BodyEncoding": {
      "CodePage": 65001,
      "EncodingName": "Unicode (UTF-8)",
      "WebName": "utf-8"
    },
    "DetectedBodyType": "Json",
    "DetectedBodyTypeFromContentType": "Json"
  },
  "Response": {
    "StatusCode": 404,
    "Headers": {
      "Content-Type": [
        "application/json"
      ]
    },
    "BodyDestination": null,
    "Body": null,
    "BodyAsJson": {
      "Guid": null,
      "Status": "No matching mapping found"
    },
    "BodyAsBytes": null,
    "BodyAsFile": null,
    "BodyAsFileIsCached": null,
    "BodyOriginal": null,
    "BodyEncoding": null,
    "DetectedBodyType": 2,
    "DetectedBodyTypeFromContentType": null,
    "FaultType": null,
    "FaultPercentage": null
  },
  "MappingGuid": null,
  "MappingTitle": null,
  "RequestMatchResult": null,
  "PartialMappingGuid": "35eda15f-6568-4a71-8fb7-a98d2eea1be4",
  "PartialMappingTitle": null,
  "PartialRequestMatchResult": {
    "TotalScore": 3.0,
    "TotalNumber": 4,
    "IsPerfectMatch": false,
    "AverageTotalScore": 0.75,
    "MatchDetails": [
      {
        "Name": "PathMatcher",
        "Score": 0.0
      },
      {
        "Name": "MethodMatcher",
        "Score": 1.0
      },
      {
        "Name": "HeaderMatcher",
        "Score": 1.0
      },
      {
        "Name": "BodyMatcher",
        "Score": 1.0
      }
    ]
  }
}
Originally created by @MichaelIDS on GitHub (Feb 16, 2023). I was trying to do bad/missing header field detection. I could detect the values of a header fine when it was present, however, I can't seem to get anything to trigger when it's not present. I lifted the below api-key check from the Wiki, but for me this doesn't ever trigger. ``` json { "Swagger Doc Title": "Bad Request", "Comment": "Bad JWT token", "Priority": 1, "Request": { "Path": { "Matchers": [ { "Name": "ExactMatcher", "Pattern": "/timeEntry" } ] }, "Headers": [ { "Name": "api-key", "Matchers": [ { "Name": "WildcardMatcher", "Pattern": "*", "IgnoreCase": true, "RejectOnMatch": true } ] } ] }, "Response": { "StatusCode": 400, "Headers": { "Content-Type": "application/json" }, "BodyAsJson": { "errorMessage": "Validation exception", "status": 400, "WireMock reason": "Bad Authorization bearer token" }, "UseTransformer": false } } ``` Log output for sample request without this Header field provided. ```json { "Guid": "a5054f98-75e7-4b04-b110-0ed2e53b3ece", "Request": { "ClientIP": "::1", "DateTime": "2023-02-16T14:03:06.5702065Z", "Path": "/timeEntry", "AbsolutePath": "/timeEntry", "Url": "http://localhost:9091/timeEntry", "AbsoluteUrl": "http://localhost:9091/timeEntry", "ProxyUrl": null, "Query": {}, "Method": "POST", "Headers": { "Postman-Token": [ "89b82b0b-8fa9-4185-8240-945029798d16" ], "Connection": [ "keep-alive" ], "Content-Length": [ "54" ], "Content-Type": [ "application/json" ], "Accept": [ "*/*" ], "Accept-Encoding": [ "gzip, deflate, br" ], "Host": [ "localhost:9091" ], "User-Agent": [ "PostmanRuntime/7.31.0" ] }, "Cookies": {}, "Body": "{\n \"username\": \"username\",\n \"password\": \"password\"\n}", "BodyAsJson": { "username": "username", "password": "password" }, "BodyAsBytes": null, "BodyEncoding": { "CodePage": 65001, "EncodingName": "Unicode (UTF-8)", "WebName": "utf-8" }, "DetectedBodyType": "Json", "DetectedBodyTypeFromContentType": "Json" }, "Response": { "StatusCode": 404, "Headers": { "Content-Type": [ "application/json" ] }, "BodyDestination": null, "Body": null, "BodyAsJson": { "Guid": null, "Status": "No matching mapping found" }, "BodyAsBytes": null, "BodyAsFile": null, "BodyAsFileIsCached": null, "BodyOriginal": null, "BodyEncoding": null, "DetectedBodyType": 2, "DetectedBodyTypeFromContentType": null, "FaultType": null, "FaultPercentage": null }, "MappingGuid": null, "MappingTitle": null, "RequestMatchResult": null, "PartialMappingGuid": "35eda15f-6568-4a71-8fb7-a98d2eea1be4", "PartialMappingTitle": null, "PartialRequestMatchResult": { "TotalScore": 3.0, "TotalNumber": 4, "IsPerfectMatch": false, "AverageTotalScore": 0.75, "MatchDetails": [ { "Name": "PathMatcher", "Score": 0.0 }, { "Name": "MethodMatcher", "Score": 1.0 }, { "Name": "HeaderMatcher", "Score": 1.0 }, { "Name": "BodyMatcher", "Score": 1.0 } ] } } ```
adam added the question label 2025-12-29 15:25:04 +01:00
adam closed this issue 2025-12-29 15:25:04 +01:00
Author
Owner

@MichaelIDS commented on GitHub (Feb 16, 2023):

I also tried a simple ExactMatcher and neither RejectOnMatch true or false matched.
If I remove the header check entirely then it matches, so I know the path element is correct.

"Headers": [
                {
                    "Name": "api-key",
                    "Matchers": [
                        {
                            "Name": "ExactMatcher",
                            "Pattern": "",
                            "IgnoreCase": true,
                            "RejectOnMatch": false
                        }
                    ]
                }
            ]

Built against WireMock 1.5.16 from NuGet.

@MichaelIDS commented on GitHub (Feb 16, 2023): I also tried a simple ExactMatcher and neither RejectOnMatch true or false matched. If I remove the header check entirely then it matches, so I know the path element is correct. ``` json "Headers": [ { "Name": "api-key", "Matchers": [ { "Name": "ExactMatcher", "Pattern": "", "IgnoreCase": true, "RejectOnMatch": false } ] } ] ``` Built against WireMock 1.5.16 from NuGet.
Author
Owner

@MichaelIDS commented on GitHub (Feb 17, 2023):

As a workaround I set a requirement on my valid response for a wildcard result "*" for this header, thus stopping a request missing it from reaching the valid response matcher. It does mean that it ends up in my final generic catch-all bad request mapping, which is less ideal, but documentable.

EDIT: I have ended up with a second catch-all request handler to differentiate requests missing this header from any other unhandled bad requests. But I hoped to avoid this as it means I have duplication of request requirement logic across multiple mappings.

@MichaelIDS commented on GitHub (Feb 17, 2023): As a workaround I set a requirement on my valid response for a wildcard result "*" for this header, thus stopping a request missing it from reaching the valid response matcher. It does mean that it ends up in my final generic catch-all bad request mapping, which is less ideal, but documentable. EDIT: I have ended up with a second catch-all request handler to differentiate requests missing this header from any other unhandled bad requests. But I hoped to avoid this as it means I have duplication of request requirement logic across multiple mappings.
Author
Owner

@StefH commented on GitHub (Mar 23, 2023):

@MichaelIDS
From your logging:
image

It seems that the path is not matched, which means that the whole mapping is not matched.

@StefH commented on GitHub (Mar 23, 2023): @MichaelIDS From your logging: ![image](https://user-images.githubusercontent.com/249938/227327820-01c3a216-57c9-44d6-bc07-cd3e026d470b.png) It seems that the path is not matched, which means that the whole mapping is not matched.
Author
Owner

@MichaelIDS commented on GitHub (Mar 23, 2023):

In the log it has the path captured and it looks identical to the stub definition in the original message here to me.

@MichaelIDS commented on GitHub (Mar 23, 2023): In the log it has the path captured and it looks identical to the stub definition in the original message here to me.
Author
Owner

@StefH commented on GitHub (Mar 23, 2023):

@MichaelIDS
I did some testing and this works, but you have to configure the mapping for the header in a different way.

It should be:

"Headers": [
                {
                    "Name": "api-key",
                    "IgnoreCase": true,
                    "RejectOnMatch": true
                }
            ]

This means that when the header-key ("api-key") or "API-Key" (ignorecase = true) is missing the header mapping will match because RejectOnMatch is true.

I'll add this to the wiki.

@StefH commented on GitHub (Mar 23, 2023): @MichaelIDS I did some testing and this works, but you have to configure the mapping for the header in a different way. It should be: ``` json "Headers": [ { "Name": "api-key", "IgnoreCase": true, "RejectOnMatch": true } ] ``` This means that when the header-key ("api-key") or "API-Key" (ignorecase = true) is missing the header mapping will match because RejectOnMatch is true. I'll add this to the wiki.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#489