Wiremock CORS not working - rest

I've been used wiremock effectively for some time now, and I wanted to enable CORS access to the mocked APIs.
I've tried setting Access-Control-Allow-Origin: * and other headers in the response header, both to no avail.
Here's an example of a mapping that I have:
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/general/login[\\/\\&\\?]*",
"bodyPatterns": [{
"equalToJson": "{\"password\":\"password\",\"username\":\"john#cougar.com\"} ",
"jsonCompareMode": "LENIENT",
"ignoreArrayOrder" : true,
"ignoreExtraElements" : true
}]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Methods" : "*",
"Access-Control-Allow-Headers": "Accept, Content-Type, Content-Encoding, Server, Transfer-Encoding",
"X-Content-Type-Options" : "nosniff",
"x-frame-options" : "DENY",
"x-xss-protection" : "1; mode=block"
},
"bodyFileName": "/login_response_johncougar.json"
}
}
What am I doing wrong here that's causing CORS to not work?
Thanks in advance.

I have just managed to fix this issue. Actually solution was here already Adding headers to Jetty in Wiremock.
Because your browser sends a CORS preflight request before making any actual request, you will need to set up your wiremock to stub the OPTIONS request and send back headers.
For example,
Access-Control-Allow-Origin = "*",
Access-Control-Allow-Headers: "content-type",
Access-Control-Allow-Methods = "POST, GET".
Access-Control-Allow-Headers's value has to be the same values the Access-Control-Request-Headers header contained Request header field Access-Control-Allow-Headers is not allowed by itself in preflight response.
All your responses have to send back header "Access-Control-Allow-Origin": "*" as well.

Here is a sample and this works
{
"request":
{
"urlPattern": "/country/([a-z]*)",
"method": "GET"
},
"response":
{
"status": 200,
"headers":
{
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Methods" : "*",
"Access-Control-Allow-Headers": "Accept, Content-Type, Content-Encoding, Server, Transfer-Encoding",
"X-Content-Type-Options" : "nosniff",
"x-frame-options" : "DENY",
"x-xss-protection" : "1; mode=block"
},
"body": "{ \"statusCode\" : \"S1000\", \"statusDescription\" : \"Success\", \"content\" : [ { \"id\" : \"1111\", \"name\" : \"aaaa\"}, { \"id\" : \"2222\", \"name\" : \"asd\" } ] }"
}
}
Use this as it is, wiremock is peculiar when it comes to spacing, here i have used a single space instead of tab, hope it helps.

I had the same problem. After a long time search without finding the solution I started to play with the groovy file and finally I found the solution.
You just need to add each header in header() method. this will solve the problem. So your sample groovy contract will be like this:
{
"request": {
"method": "POST",
"urlPattern": "/api/v2/general/login[\\/\\&\\?]*",
"bodyPatterns": [{
"equalToJson": "{\"password\":\"password\",\"username\":\"john#cougar.com\"} ",
"jsonCompareMode": "LENIENT",
"ignoreArrayOrder": true,
"ignoreExtraElements": true
}]
},
"response": {
"status": 200,
"headers": {
header("Content-Type": "application/json"),
header("Access-Control-Allow-Origin": "*"),
header("Access-Control-Allow-Methods": "*"),
header("Access-Control-Allow-Headers": "Accept, Content-Type, Content-Encoding, Server, Transfer-Encoding"),
header("X-Content-Type-Options": "nosniff"),
header("x-frame-options": "DENY"),
header("x-xss-protection": "1; mode=block")
},
"bodyFileName": "/login_response_johncougar.json"
}
}
I hope it will solve your problem (Actually it will be useful if you use groovy contracts).

You can disable cors by adding --enable-stub-cors flag
Standalone example :
java -jar wiremock-jre8-standalone-2.31.0.jar --port 8081 --enable-stub-cors
Docker example :
docker run -it --rm -p 8081:8080 --name wiremock-yadoms -v $PWD:/home/wiremock wiremock/wiremock --enable-stub-cors

For Angular developers:
first Install wiremock with following command:
npm install wiremock
Then:
"scripts": {
"ng": "ng",
"start": "ng serve",
"wiremock": "wiremock --root-dir ./wiremock --port 8080 --enable-stub-cors true --enable-browser-proxying",
...
}

Related

VSCode httpClient plugin showing Header name must be a valid HTTP token

I have this API call in the VSCode RESTAPI caller plugin:
###
POST {{endpoint}}/snapcenter/SnapCenterInventory/account/{{accountId}} {{#protocol}}
content-type: application/json
Authorization: {{token}}
{
"Server": "10.10.10.10",
"ApplicationCount": 10,
"User": "admin",
"Password": "foo",
"Port": 3000,
"RoleName": "bar"
}
###
I have all the variables defined, working fine in GET cases.
However for POST/PATCH/PUT, it's giving this error:
Header name must be a valid HTTP token ["{"]
Not able to figure out what I am missing here.
Any help will be highly appreciated.
Thanks,
Pradip
I think I can able to find it out. I need to keep a newline b/w the header and the content.
This works:
POST {{endpoint}}/servers/account/{{accountId}} {{#protocol}}
Content-Type: application/json
Authorization: {{token}}
{
"k1": "v5",
"k2": 110,
"k3": true,
"k4": ["v1", "v2", "v3", "v4", "v5"],
"k5": {
"k51": "v5",
"k52": 2
},
"k6": {
"k61": true
}
}
Mind the gap b/w the content and the header.

Avoid logging specific requests in Wiremock

I'm using Wiremock 2.28.1 in a Scala 2.13 project and I would like to skip logging specific requests/responses in Wiremock because they are just liveness/readiness HTTP calls targeting health/ready and health/alive endpoints:
{
"mappings": [
{
"request": {
"method": "GET",
"url": "/api/v1/health/ready"
},
"response": {
"status": 200,
"body": "",
"headers": {
"Content-Type": "text/plain"
}
}
},
{
"request": {
"method": "GET",
"url": "/api/v1/health/alive"
},
"response": {
"status": 200,
"body": "",
"headers": {
"Content-Type": "text/plain"
}
}
}
]
}
The WireMock server configuration is:
new WireMockConfiguration()
.bindAddress(configOptions.host)
.port(configOptions.port)
.stubCorsEnabled(configOptions.enableCors)
.disableRequestJournal() // avoid JVM heap exhaustion for recorded requests
.usingFilesUnderClasspath(s"$confBasePath/${configOptions.mappingsFolder}")
.notifier(new ConsoleNotifier(configOptions.verboseNotifier)) // <-- TRUE
.httpsPort(...)
Is there a way to tell WireMock to simply skip logging the /health/* API calls?
There are a couple of ways you could do this:
Write your own Notifier implementation that filters messages based on their content and use this in place of ConsoleNotifier in your startup options.
Make the healthcheck an admin API function by implementing AdminApiExtension and registering it in the startup options (this will mean the URL will have to be under /__admin/.

Google Apps Script doesn't recognize "Host" header in HTTP POST request?

I'm trying to query ArcGIS Rest API from Google Apps script. Building the request in Postman works perfectly fine, but when I get the code into apps script, I'm having trouble that I cant seem to figure out. Here's the code:
function callEsri () {
var url = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query"
var params =
{
"async": true,
"crossDomain": true,
"url": "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0/query",
"method": "POST",
"headers": {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "PostmanRuntime/7.20.1",
"Accept": "*/*",
"Cache-Control": "no-cache",
"Postman-Token": "[TOKEN]",
"Host": "services3.arcgis.com",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "125",
"Connection": "keep-alive",
"cache-control": "no-cache"
},
"data": {
"f": "json",
"where": "CITY_JUR LIKE '%Los Angeles%'",
"outSr": "4326",
"outFields": "TRL_NAME,ELEV_FT,CITY_JUR,PARK_NAME,FID"
}
}
var response = UrlFetchApp.fetch(url, params);
var json = response.getContentText();
var data = JSON.parse(json);
Logger.log(data);
}
The Error I am getting is: Execution failed: Attribute provided with invalid value: Header:Host (line 28, file "Code")
Any reason why Google is not recognizing this and is there a way to fix this? Any help/advice is greatly appreciated.
As #TheMaster has already noted in the comments. You are already specifying the Host in the url.
Also you can take a look at the official documentation of URLFetchApp.
And in case you want more information in the head here you have the mozilla documentation on that header and also the RFC specifying the Host header.

WireMock not mapping request by body contains

My http request send to this: https://myhost.com/ap
My http request with body :
{
"Body": {
"CommandName": "GetApplicationProfile"
},
"Header": {
"Command": "GetApplicationProfile",
}
}
I want to mapping this request by WireMock.
Here WireMock's mapping file.
{
"request": {
"url": "/my_host/ap",
"bodyPatterns": [
{
"contains": "GetApplicationProfile"
}
]
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"bodyFileName": "get_profile.json"
}
}
I start wireMock like this:
java -jar wiremock-standalone-2.18.0.jar --port 8080 --enable-browser-proxying -verbose
But when request was started the WireMock not map this request. Nothing happened.
why?
The problem you're having is that you shouldn't have the hostname in the url part. This is not needed. Your example message can be sent and will be matched using the following rule.
{
"request": {
"url": "/app",
"bodyPatterns": [
{
"contains": "GetApplicationProfile"
}
]
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"body": "ddd"
}
}
The URL should not contain the host name. It should only contain the resource path.
The url format should start with "/" e.g. /https://myhost.com/ap.
Now if u r trying this on localhost then the URL should be localhost:<port>/https://myhost.com/ap.
The file should be present at src/test/resources/__files
If not it will give error file not present.
I see 2 issues here:
1. you need to remove the host name from the url in the mapping file.
2. your request is HTTPS which means you need to start your wiremock port with https: --https-port 8080 or you change your request to HTTP

Wiremock - How can I apply response templating to the header name?

I am trying to provide a MOCK service that takes a headerName and value from the query and returns it as a (dynamic) header with the response. I am using the following response definition:
"response" : {
"status" : 200,
"statusMessage": "OK",
"headers" : {
"Content-Type" : "application/json",
"{{request.query.debugHeader}}" : "{{request.query.debugHeaderValue}}"
},
"jsonBody" : {
"headerSent": "{{request.query.debugHeader}} {{request.query.debugHeaderValue}}"
},
"transformers": ["response-template"],
"base64Body" : ""
}
The header value is correctly evaluated and put into the response template, however I can't get the header name to be taken from the request.
When sending a request:
http://localhost:8090/example?debugHeader=name&debugHeaderValue=value
The result headers I get back are:
HTTP/1.1 200 OK
Content-Type: application/json
{{request.query.debugHeader}}: value
However I want {{request.query.debugHeader}} to be replaced with the actual request parameter value ("name" in the example above).
Any ideas?
Thanks in advance
Alex
This is supported in WireMock.Net.
The request which you need to specify looks like this:
{
"Guid": "90356dba-b36c-469a-a17e-669cd84f1f05",
"Priority": 0,
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/trans",
"IgnoreCase": false
}
]
},
"Methods": [
"get"
]
},
"Response": {
"StatusCode": 200,
"BodyDestination": "SameAsSource",
"Body": "{\"msg\": \"Hello world : {{request.path}}\" }",
"UseTransformer": true,
"Headers": {
"Content-Type": "application/json",
"Transformed-Postman-Token_{{request.path}}": "token is {{request.headers.Postman-Token}}"
}
}
}
This will add the transformed header Transformed-Postman-Token_{{request.path}} in the response.
Presently this type of variability is not part of the out-of-the-box WireMock application and would have to be custom added. In the WireMock documentation the section Extending WireMock and in particular the part on Transforming Responses.