Skip to content

Commit

Permalink
Add first version of zoom reverse proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
YaroslavPshenichnikov committed Jul 30, 2024
1 parent 1ce2d68 commit 4691e2f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
23 changes: 23 additions & 0 deletions develop-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ Resources:
ApplyOn: None
PackageType: Zip
Role: !GetAtt DocspaceReverseProxyRole.Arn

zoomreverseproxy:
Type: AWS::Serverless::Function
Properties:
CodeUri: zoom-reverse-proxy/
Description: ""
MemorySize: 128
Timeout: 3
Handler: index.handler
Runtime: nodejs18.x
Architectures:
- x86_64
EventInvokeConfig:
MaximumEventAgeInSeconds: 21600
MaximumRetryAttempts: 2
EphemeralStorage:
Size: 512
RuntimeManagementConfig:
UpdateRuntimeOn: Auto
SnapStart:
ApplyOn: None
PackageType: Zip
Role: !GetAtt DocspaceReverseProxyRole.Arn

GlobalDynamoDBTable:
Type: AWS::DynamoDB::GlobalTable
Expand Down
80 changes: 80 additions & 0 deletions zoom-reverse-proxy/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'use strict';

const AWS = require('aws-sdk');
const cachedItem = {};
const regionsMap = {
'us-west-2': 'oforms.onlyoffice.com',
'eu-central-1': 'blog.onlyoffice.com',
'default': 'onlyoffice.com'
};

const ddbRegionsMap = {
ddbRegionsMap_placeholder
};

const dynamodbTableName = "dynamodb_table_name_placeholder";

const execRegionCode = process.env.AWS_REGION;
var ddbClientRegion = ddbRegionsMap[execRegionCode] || ddbRegionsMap["default"];

console.log("DynamoDB client region set to: %s", ddbClientRegion);

const { DynamoDBClient, GetItemCommand } = require("@aws-sdk/client-dynamodb");

async function getTenantRegion(ddbRegion, tenantDomain) {
console.log("Fetching tenant region for domain: %s from DynamoDB region: %s", tenantDomain, ddbRegion);
const ddbClient = new DynamoDBClient({ region: ddbRegion });
const getItemParams = {
Key: { 'tenant_domain': { S: tenantDomain } },
ProjectionExpression: "tenant_region",
TableName: dynamodbTableName
};

try {
const response = await ddbClient.send(new GetItemCommand(getItemParams));
if (response.Item) {
const tenantRegion = regionsMap[response.Item["tenant_region"]["S"]];
console.log("Tenant region fetched: %s", tenantRegion);
return tenantRegion;
} else {
console.warn("No data found for domain: %s", tenantDomain);
return null;
}
} catch (err) {
console.error("Error fetching from DynamoDB: %s", err);
return null;
}
}

exports.handler = async (event) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
const fullDomain = headers.host[0].value.toLowerCase();
const domainParts = fullDomain.split('.');

if (domainParts.length === 4 && domainParts[1] === 'devops' && domainParts[2] === 'onlyoffice' && domainParts[3] === 'io') {
const tenantDomain = fullDomain;

// Check the cache first
if (cachedItem[tenantDomain] && cachedItem[tenantDomain].expiresOn > Date.now()) {
request.origin.custom.domainName = cachedItem[tenantDomain].value;
console.log("Origin fetched from cache for domain: %s", tenantDomain);
} else {
// Fetch the region from DynamoDB and update the origin
const tenantRegion = await getTenantRegion(ddbClientRegion, tenantDomain);
if (tenantRegion) {
request.origin.custom.domainName = tenantRegion;
cachedItem[tenantDomain] = {
value: tenantRegion,
expiresOn: Date.now() + 15 * 60 * 1000 // Cache for 15 minutes
};
console.log("Origin updated to %s for domain: %s", tenantRegion, tenantDomain);
} else {
request.origin.custom.domainName = regionsMap["default"];
console.log("Default origin used for domain: %s", tenantDomain);
}
}
}

return request;
};

0 comments on commit 4691e2f

Please sign in to comment.