CloudFront doesn't fetch from custom origin for root url using Lambda#Edge - aws-lambda

I have a Lambda#Edge function that decides which origin to use on the origin request, depending on a header value.
It doesn't work for the root url (mysite.com), but it works for subroutes (mysite.com/sth/abc). I am looking for help while trying to figure out why it doesn't work for the root url.
It looks like this:
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const isBot = headers['formaviva-agent'] && headers['formaviva-agent'][0].value === 'bot';
console.log("request before" + JSON.stringify(request));
console.log("isBot:" + isBot);
const shouldPrerender = isBot;
if (shouldPrerender) {
request.origin = {
custom: {
domainName: 'fast.formaviva.com',
port: 80,
protocol: 'http',
path: '',
sslProtocols: ['TLSv1', 'TLSv1.1'],
readTimeout: 5,
keepaliveTimeout: 5,
customHeaders: {}
}
};
request.headers['host'] = [{ key: 'host', value: 'fast.formaviva.com'}];
console.log("request after" + JSON.stringify(request));
}
callback(null, request);
};
The default origin is S3 static page hosting. formaviva-agent is set in a Viewer Request Lambda function that checks whether User-Agent belongs to a bot.
Formaviva-agent is whitelisted.
Judging by the logs, all goes well, the bot is recognized and the origin gets changed to a custom origin:
2019-05-07T09:56:45.627Z 3a2831f4-2a6b-46ea-8850-d89651a9b19e request after
{
"clientIp": "92.37.21.9",
"headers": {
"if-modified-since": [
{
"key": "If-Modified-Since",
"value": "Mon, 06 May 2019 10:50:39 GMT"
}
],
"if-none-match": [
{
"key": "If-None-Match",
"value": "W/\"41cc-16a8cc45892\""
}
],
"user-agent": [
{
"key": "User-Agent",
"value": "Amazon CloudFront"
}
],
"via": [
{
"key": "Via",
"value": "1.1 b38e161751a953866db739b688c09996.cloudfront.net (CloudFront)"
}
],
"formaviva-agent": [
{
"key": "formaviva-agent",
"value": "bot"
}
],
"x-forwarded-for": [
{
"key": "X-Forwarded-For",
"value": "92.37.21.9"
}
],
"host": [
{
"key": "host",
"value": "fast.formaviva.com"
}
]
},
"method": "GET",
"origin": {
"custom": {
"domainName": "fast.formaviva.com",
"port": 80,
"protocol": "http",
"path": "",
"sslProtocols": [
"TLSv1",
"TLSv1.1"
],
"readTimeout": 5,
"keepaliveTimeout": 5,
"customHeaders": {}
}
},
"querystring": "",
"uri": "/index.html"
}
In this case, Cloudfront still serves the content from S3 origin. The custom origin server does not get hit (confirmed). Even though the custom origin is specified. Why?

Related

Wiremock request.query not working with a paramter that contains dots

I'm using sprint-boot with wiremock-jre8, what i'm trying to to is to get a value from URL params, but this value contains dots "product.productCharacteristic.value"
{
"request": {
"urlPath": "/exampleOfPath",
"method": "GET",
"queryParameters": {
"product.productCharacteristic.name": {
"equalTo": "MSISDN"
},
"product.productCharacteristic.value": {
"matches": ".*"
}
}
},
"response": {
"status": 200,
"jsonBody": {
"key": "the value should be here {{request.query['product.productCharacteristic.value']}}"
},
"transformers": [
"response-template"
],
"headers": {
"Content-Type": "application/json"
}
}
}
i have tested all of those
{{request.query.['product.productCharacteristic.value']}}
{{request.query['product.productCharacteristic.value']}}
{{request.query['product%2EproductCharacteristic%2Evalue']}}
{{request.query.['product%2EproductCharacteristic%2Evalue']}}
{{request.query.product%2EproductCharacteristic%2Evalue}}
{{request.query.product.productCharacteristic.value}}
{{lookup request.query 'product.productCharacteristic.value'}}
{{lookup request.query 'product%2EproductCharacteristic%2Evalue'}}
You can use this format:
{{request.query.[product.productCharacteristic.value]}}
See WireMock - Response Templating - The request model:
request.headers.[<key>] - Header with awkward characters e.g. request.headers.[$?blah]

Is there a way to send metadata in krakend endpoint configuration?

I'm using Krakend as API-Gateway, and my configuration looks like this :
{
"plugin": {
"folder": "/etc/krakend/plugins/authenticator/",
"pattern":".so"
},
"port": 8080,
"extra_config": {
"github_com/devopsfaith/krakend/transport/http/server/handler": {
"name": "authenticator"
}
},
"endpoints": [
{
"output_encoding": "no-op",
"backend": [
{
"encoding": "no-op",
"host": [
"127.0.0.1:8080"
],
"url_pattern": "/api/v1/address/{id}",
"method": "GET"
}
],
"endpoint": "/api/v1/addresses/{id}",
"method": "GET"
}
],
"name": "gateway",
"timeout": "30s",
"version": 2
}
I want to pass some metadata per end point and access it in my predefined plugin .
In this case authenticator plugin.
What you are trying to achieve is perfectly possible, and is the way all components work in KrakenD. Your plugin can access the KrakenD configuration using the namespace you define. For instance, you could set your metadata like this (I am assuming you have in your Go code a pluginName = "slifer2015-authenticator" ):
{
"endpoints": [
{
"output_encoding": "no-op",
"backend": [
{
"encoding": "no-op",
"host": [
"127.0.0.1:8080"
],
"url_pattern": "/api/v1/address/{id}"
}
],
"endpoint": "/api/v1/addresses/{id}",
"extra_config": {
"github_com/devopsfaith/krakend/transport/http/server/handler": {
"name": [
"slifer2015-authenticator",
"some-other-plugin-here"
],
"slifer2015-authenticator": {
"Metadata1": "value1",
"Metadata2": {
"Some": 10,
"Thing": 100,
"Here": "60s"
}
}
}
}
}
]
}
Then your metada is available in the extra parameter when the registerer kicks in, inside the key you have chosen.
func (r registerer) registerHandlers(ctx context.Context, extra map[string]interface{}, h http.Handler) (http.Handler, error) {
``

Dynamics 365 Search Resource Availability With Constraints

I've been trying to add filters to my Search Resource Availability api call following this page: Search resource availability API
No matter what I do I can't seem to filter by Organizational Unit.
Here's my http call body:
{
"Version": "3",
"IsWebApi": true,
"Requirement": {
"msdyn_fromdate": "2021-11-01T00:00:00Z",
"msdyn_todate": "2021-11-30T23:59:00Z",
"msdyn_remainingduration": 60,
"msdyn_duration": 60,
"#odata.type": "Microsoft.Dynamics.CRM.msdyn_resourcerequirement"
},
"Settings": {
"ConsiderSlotsWithProposedBookings": false,
"MovePastStartDateToCurrentDate": true,
"#odata.type": "Microsoft.Dynamics.CRM.expando"
},
"ResourceSpecification":{
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"ResourceTypes#odata.type": "Collection(Microsoft.Dynamics.CRM.expando)",
"ResourceTypes": [
{
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"value": "3"
}
],
"Constraints": {
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"OrganizationalUnits#odata.type": "Collection(Microsoft.Dynamics.CRM.expando)",
"OrganizationalUnits":[
{
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"value": "b2054232-a114-ec11-b6e7-000d3a842ab8"
}
]
}
}
}
And here's the response I get:
{
"#odata.context": "https://orga215da53.api.crm3.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.msdyn_SearchResourceAvailabilityResponse",
"TimeSlots": [],
"Resources": [],
"Related": {
"#odata.type": "#Microsoft.Dynamics.CRM.expando",
"TimeSlots#odata.type": "#Collection(Microsoft.Dynamics.CRM.crmbaseentity)",
"TimeSlots": [],
"Resources#odata.type": "#Collection(Microsoft.Dynamics.CRM.crmbaseentity)",
"Resources": []
},
"Exceptions": {
"#odata.type": "#Microsoft.Dynamics.CRM.expando"
}
}
But i KNOW that that organization unit exists in CRM.
I tried changing the odata.type to the actual Organization Unit CRM type (msdyn_organizationalunit) but that just gives me an error (An error occurred while validating input parameters: System.ArgumentNullException: Value cannot be null)
What is it that I'm doing wrong?
Thanks!
Good day,
I'm not sure but maybe "Constraints" should be outside "ResourceSpecification" like:
{
"Version": "3",
"IsWebApi": true,
"Requirement": {
"msdyn_fromdate": "2021-11-01T00:00:00Z",
"msdyn_todate": "2021-11-30T23:59:00Z",
"msdyn_remainingduration": 60,
"msdyn_duration": 60,
"#odata.type": "Microsoft.Dynamics.CRM.msdyn_resourcerequirement"
},
"Settings": {
"ConsiderSlotsWithProposedBookings": false,
"MovePastStartDateToCurrentDate": true,
"#odata.type": "Microsoft.Dynamics.CRM.expando"
},
"ResourceSpecification":{
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"ResourceTypes#odata.type": "Collection(Microsoft.Dynamics.CRM.expando)",
"ResourceTypes": [
{
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"value": "3"
}
]
},
"Constraints": {
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"OrganizationalUnits#odata.type": "Collection(Microsoft.Dynamics.CRM.expando)",
"OrganizationalUnits":[
{
"#odata.type": "Microsoft.Dynamics.CRM.expando",
"value": "b2054232-a114-ec11-b6e7-000d3a842ab8"
}
]
}
}

Jira API does not work while using for create issue

I'm develop an chrome extension for jira which get a data from a DIV element of another website and use the data to raise a jira ticket by my chrome extension automatically.
the issue is when I call below jira api in my code I faced below error
content.js:107 POST http://myjira.com:9090/rest/api/2/issue/ 403 (Forbidden)
but as I checked my request in Post Man app everything is fine and new ticket raise in Jira.
I'm really appreciated if someone can help me to fix the issue.
moreover, I used my personal computer and the jira is on another server.
totally I want to have a extension to integrate a ticketing system with jira, without access to that site.
please have following code.
content.js
$(document).ready(function () {
var key = '';
var summary = 'undefined';
var description = '';
var comment = '';
window.setInterval(function () {
/// call your function here
console.log($('Div1').html());
console.log($('Div2').html());
console.log($('#Div3').html());
console.log($('Div4').html());
key = $('.a span:first').html();
summary = $('#b').html();
description = $('#r'')').html();
comment = $('#u').html();
if (summary == 'undefined') {
return;
}
var data = JSON.stringify({
"fields": {
"project": {
"key": "RTF"
},
"summary": "" + summary + "",
"description": "" + description + "",
"issuetype": {
"self": "http://myjira.com/rest/api/2/issuetype/10111",
"id": "10111",
"description": "Service Request",
"iconUrl": "http:/myjira.com/secure/viewavatar?size=xsmall&avatarId=10720&avatarType=issuetype",
"name": "MS Task (SR)",
"subtask": false,
"avatarId": 10720
},
"customfield_10106": {
"self": "http://myjira.com/rest/api/2/customFieldOption/10476",
"value": "EMAIL",
"id": "10476"
},
"customfield_10129": [
{
"self": "http://myjira.com/rest/api/2/customFieldOption/10450",
"value": "TEST",
"id": "10450"
}
],
"customfield_10188": [
{
"self": "http://myjira.com/rest/api/2/customFieldOption/10469",
"value": "Billing",
"id": "10469"
}
],
"customfield_10180": {
"self": "http://myjira.com/rest/api/2/customFieldOption/11000",
"value": "Support",
"id": "11000"
},
"assignee": {
"self": "http://myjira.com/rest/api/2/user?username=e.pirjahandideh",
"name": "e.jj",
"key": "e.jj",
"emailAddress": "e.jj#jj.com",
"avatarUrls": {
"48x48": "http://www.gravatar.com/avatar/68e54d1c135e85b994eb12cb9a3b7b9b?d=mm&s=48",
"24x24": "http://www.gravatar.com/avatar/68e54d1c135e85b994eb12cb9a3b7b9b?d=mm&s=24",
"16x16": "http://www.gravatar.com/avatar/68e54d1c135e85b994eb12cb9a3b7b9b?d=mm&s=16",
"32x32": "http://www.gravatar.com/avatar/68e54d1c135e85b994eb12cb9a3b7b9b?d=mm&s=32"
},
"displayName": "Emil jj",
"active": true,
"timeZone": "Asia/Tehran"
},
"components": [
{
"self": "http://myjira.com/rest/api/2/component/10071",
"id": "10071",
"name": "RR",
"description": "Managed RR"
}
],
"customfield_10189": {
"self": "http://myjira.com/rest/api/2/customFieldOption/10489",
"value": "RR/IT",
"id": "10489"
}
}
});
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "myjira.com/rest/api/2/issue/");
xhr.setRequestHeader("authorization", "Basic dasfasegsdfgsdfgsdfg");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("postman-token", "c6475a5e-6741-6894-5b8e-2350c7c5a176");
xhr.send(data);
}, 10000);
});
manifest.json
{
"manifest_version": 2,
"name": "Name",
"description": "Description",
"browser_action": {
"default_popup": "popup.html"
},
"background": {
"page": "background.html"
},
"version": "1.0",
"permissions": [
"http://myjira.com/",
"http://ticketing2.com"
],
"content_scripts": [
{
"matches": [ "http://*/*", "https://*/*"],
"js": [
"jquery.js",
"jquery-ui.min.js",
"content.js"
],
"run_at": "document_end",
"all_frames": true
}
]
}

Accessing VSTS service endpoints from javascript

I am trying to access the service endpoint setup in my extension code.
The extension is as follows:
{
"manifestVersion": 1,
"id": "vsts-extensions-myExtensions",
"version": "0.5.1",
"name": "xxx Projects Time Entry",
"description": "Record time spent in xxx Projects",
"publisher": "xxx",
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"icons": {
"default": "img/logo.png"
},
"contributions":
[
{
"id": "xxTimeEntry",
"type": "ms.vss-dashboards-web.widget",
...
},
{
"id": "service-endpoint",
"description": "Service Endpoint type for xx connections",
"type": "ms.vss-endpoint.service-endpoint-type",
"targets": [ "ms.vss-endpoint.endpoint-types" ],
"properties": {
"name": "xxxyyy",
"displayName": "xx server connection",
"url": {
"displayName": "Server Url",
"helpText": "Url for the xxx server to connect to."
},
"dataSources": [
{
"name": "xxx Projects",
"endpointUrl": "{{endpoint.url}}api/timesheetwidgetprojects",
"resultSelector": "jsonpath:$[*].nm"
}
],
"authenticationSchemes": [
{
"type": "ms.vss-endpoint.endpoint-auth-scheme-basic",
"inputDescriptors": [
{
"id": "username",
"name": "Username",
"description": "Username",
"inputMode": "textbox",
"validation": {
"isRequired": false,
"dataType": "string"
}
},
{
"id": "password",
"name": "Password",
"description": "Password",
"inputMode": "passwordbox",
"isConfidential": true,
"validation": {
"isRequired": false,
"dataType": "string"
}
}
]
}
]
}
}
],
...
The code to access the service endpoint is something like :
VSS.require(["VSS/Service", "VSS/WebApi/RestClient"],
function (VSS_Service, RestClient) {
var webContext = VSS.getWebContext();
var client = VSS_Service.getCollectionClient(DistributedTask.TaskAgentRestClient);
client.getServiceEndpoints(webContext.project.id).then(
function (endpoints) {
alert('endpoints')
}
);
}
);
however I am not using a task and just have my endpoint in the main vss-extension.json.
Any ideas?
Thanks
Martin
Based on the supported scopes, there isn’t the scope for service endpoint, so you can’t do it.
I submit a user voice here: VSTS extension service endpoint scope, you can vote and follow up.
The workaround is that you can call REST API by using JS code with Personal Access Token in your extension.
Simple code to call REST API:
$.ajax({
url: 'https://fabrikam.visualstudio.com/defaultcollection/_apis/projects?api-version=1.0',
dataType: 'json',
headers: {
'Authorization': 'Basic ' + btoa("" + ":" + myPatToken)
}
}).done(function( results ) {
console.log( results.value[0].id + " " + results.value[0].name );
});
The scope has been added now and it is "vso.serviceendpoint"

Resources