static userAgentString(userAgentConfig) {
// eslint-disable-next-line security/detect-object-injection
const _conf = (field, def) => (userAgentConfig && field in userAgentConfig) ? userAgentConfig[field] : def;
- const product = _conf('product', packageName);
+ const product = _conf('product', packageName).split('/').pop();
const version = _conf('version', packageVersion);
let implementation = _conf('implementation', Enum.Specification);
if (implementation) {
const acceptPreferred = [topic.contentType, acceptWildcard].filter((x) => x).join(', ');
return Communication._axiosConfig('GET', topic.url, undefined, {}, {
[Enum.Header.Accept]: acceptPreferred,
+ ...(topic.httpEtag && { [Enum.Header.IfNoneMatch]: topic.httpEtag }),
+ ...(topic.httpLastModified && { [Enum.Header.IfModifiedSince]: topic.httpLastModified }),
});
}
// Cull any expired subscriptions
await this.db.subscriptionDeleteExpired(dbCtx, topicId);
- logInfoData.url = topicId.url;
+ logInfoData.url = topic.url;
if (topic.isDeleted) {
this.logger.debug(_scope, 'topic deleted, skipping update request', logInfoData);
switch (common.httpStatusCodeClass(response.status)) {
case 2:
+ case 3:
// Fall out of switch on success
break;
return;
}
+ if (response.status === 304) {
+ this.logger.info(_scope, 'content has not changed, per server', logInfoData);
+ await this.db.topicFetchComplete(dbCtx, topicId);
+ return;
+ }
+
const contentHash = Communication.contentHash(response.data, topic.contentHashAlgorithm);
logInfoData.contentHash = contentHash;
if (topic.contentHash === contentHash) {
}
const contentType = response.headers[Enum.Header.ContentType.toLowerCase()];
+ const httpETag = response.headers[Enum.Header.ETag.toLowerCase()];
+ const httpLastModified = response.headers[Enum.Header.LastModified.toLowerCase()];
await this.db.transaction(dbCtx, async (txCtx) => {
await this.db.topicSetContent(txCtx, {
content: Buffer.from(response.data),
contentHash,
...(contentType && { contentType }),
+ ...(httpETag && { httpETag }),
+ ...(httpLastModified && { httpLastModified }),
});
await this.db.topicFetchComplete(txCtx, topicId);
await this.db.transaction(dbCtx, async (txCtx) => {
await this.db.verificationInsert(txCtx, verification);
- await this.db.subscriptionDeliveryComplete(txCtx, subscription.callback, subscription.topicId);
+ await this.db.subscriptionDeliveryComplete(txCtx, subscription.callback, subscription.topicId, topic.contentUpdated);
});
this.logger.info(_scope, 'update unsubscription for deleted topic', logInfoData);
return;
return;
}
- await this.db.subscriptionDeliveryComplete(dbCtx, subscription.callback, subscription.topicId);
+ await this.db.subscriptionDeliveryComplete(dbCtx, subscription.callback, subscription.topicId, topic.contentUpdated);
this.logger.info(_scope, 'update success', logInfoData);
}