diff --git a/libraries/botbuilder/src/botFrameworkAdapter.ts b/libraries/botbuilder/src/botFrameworkAdapter.ts index 87adeb34b6..a38b00c7cb 100644 --- a/libraries/botbuilder/src/botFrameworkAdapter.ts +++ b/libraries/botbuilder/src/botFrameworkAdapter.ts @@ -9,7 +9,7 @@ import * as z from 'zod'; import { BotFrameworkHttpAdapter } from './botFrameworkHttpAdapter'; import { ConnectorClientBuilder, Request, Response, ResponseT, WebRequest, WebResponse } from './interfaces'; -import { HttpClient, userAgentPolicy } from '@azure/ms-rest-js'; +import { HttpClient, RequestPolicyFactory, userAgentPolicy } from '@azure/ms-rest-js'; import { INodeBufferT, INodeSocketT, LogicT } from './zod'; import { arch, release, type } from 'os'; import { delay, retry } from 'botbuilder-stdlib'; @@ -1514,6 +1514,17 @@ export class BotFrameworkAdapter value: `${USER_AGENT}${userAgent ?? ''}`, }); + const acceptHeader: RequestPolicyFactory = { + create:(nextPolicy) => ({ + sendRequest: (httpRequest)=>{ + if(!httpRequest.headers.contains('accept')) { + httpRequest.headers.set('accept', '*/*'); + } + return nextPolicy.sendRequest(httpRequest); + } + }) + }; + // Resolve any user request policy factories, then include our user agent via a factory policy options.requestPolicyFactories = (defaultRequestPolicyFactories) => { let defaultFactories = []; @@ -1530,11 +1541,11 @@ export class BotFrameworkAdapter // If the user has supplied custom factories, allow them to optionally set user agent // before we do. - defaultFactories = [...defaultFactories, setUserAgent]; + defaultFactories = [...defaultFactories, acceptHeader, setUserAgent]; } else { // In the case that there are no user supplied factories, inject our user agent as // the first policy to ensure none of the default policies override it. - defaultFactories = [setUserAgent, ...defaultRequestPolicyFactories]; + defaultFactories = [acceptHeader, setUserAgent, ...defaultRequestPolicyFactories]; } return defaultFactories; diff --git a/libraries/botbuilder/tests/botFrameworkAdapter.test.js b/libraries/botbuilder/tests/botFrameworkAdapter.test.js index ac71f94c0a..e05aff54e9 100644 --- a/libraries/botbuilder/tests/botFrameworkAdapter.test.js +++ b/libraries/botbuilder/tests/botFrameworkAdapter.test.js @@ -524,6 +524,34 @@ describe('BotFrameworkAdapter', function () { }); }); + it('ConnectorClient should add requestPolicyFactory for accept header', async function () { + let hasAcceptHeader = false; + const mockNextPolicy = { + create: (innerPolicy) => ({ + }), + sendRequest: (httpRequest) => { + return {}; + } + }; + const client = new BotFrameworkAdapter().createConnectorClient('https://localhost') + var length = client._requestPolicyFactories.length; + for (var i = 0; i < length; i++) { + var mockHttp = { + headers: new HttpHeaders() + }; + + var result = client._requestPolicyFactories[i].create(mockNextPolicy); + + result.sendRequest(mockHttp); + if(mockHttp.headers.get("accept") == "*/*") { + hasAcceptHeader = true; + break; + } + } + + assert(hasAcceptHeader, 'accept header from connector client should be */*'); + }); + it('createConnectorClientWithIdentity should throw without identity', async function () { const adapter = new BotFrameworkAdapter(); await assert.rejects( diff --git a/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts b/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts index c5873ac771..aa81c24253 100644 --- a/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts +++ b/libraries/botframework-connector/src/auth/connectorFactoryImpl.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { getDefaultUserAgentValue, userAgentPolicy } from '@azure/ms-rest-js'; +import { getDefaultUserAgentValue, RequestPolicyFactory, userAgentPolicy } from '@azure/ms-rest-js'; import { ConnectorClient } from '../connectorApi/connectorClient'; import { ConnectorClientOptions } from '../connectorApi/models'; import { ConnectorFactory } from './connectorFactory'; @@ -50,6 +50,17 @@ export class ConnectorFactoryImpl extends ConnectorFactory { value: `${USER_AGENT}${userAgent ?? ''}`, }); + const acceptHeader: RequestPolicyFactory = { + create: (nextPolicy) => ({ + sendRequest: (httpRequest) => { + if (!httpRequest.headers.contains('accept')) { + httpRequest.headers.set('accept', '*/*'); + } + return nextPolicy.sendRequest(httpRequest); + }, + }), + }; + // Resolve any user request policy factories, then include our user agent via a factory policy options.requestPolicyFactories = (defaultRequestPolicyFactories) => { let defaultFactories = []; @@ -66,11 +77,11 @@ export class ConnectorFactoryImpl extends ConnectorFactory { // If the user has supplied custom factories, allow them to optionally set user agent // before we do. - defaultFactories = [...defaultFactories, setUserAgent]; + defaultFactories = [...defaultFactories, setUserAgent, acceptHeader]; } else { // In the case that there are no user supplied factories, inject our user agent as // the first policy to ensure none of the default policies override it. - defaultFactories = [setUserAgent, ...defaultRequestPolicyFactories]; + defaultFactories = [acceptHeader, setUserAgent, ...defaultRequestPolicyFactories]; } return defaultFactories; diff --git a/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js b/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js index 5332f4aa27..d202f18ac8 100644 --- a/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js +++ b/libraries/botframework-connector/tests/botFrameworkAuthenticationFactory.test.js @@ -11,6 +11,7 @@ const { PasswordServiceClientCredentialFactory, SkillValidation, } = require('..'); +const { HttpHeaders } = require('@azure/ms-rest-js'); describe('BotFrameworkAuthenticationFactory', function () { it('should create anonymous BotFrameworkAuthentication', function () { @@ -122,6 +123,7 @@ describe('BotFrameworkAuthenticationFactory', function () { assert.strictEqual(connectorFactory.credentialFactory, credsFactory); const connectorClient = await connectorFactory.create(HOST_SERVICE_URL, HOST_AUDIENCE); + assertHasAcceptHeader(connectorClient); assert.strictEqual(connectorClient.credentials.appId, APP_ID); assert.strictEqual(connectorClient.credentials.appPassword, APP_PASSWORD); assert.strictEqual(connectorClient.credentials.oAuthScope, HOST_AUDIENCE); @@ -132,4 +134,31 @@ describe('BotFrameworkAuthenticationFactory', function () { assert.strictEqual(userTokenClient.client.credentials.appPassword, APP_PASSWORD); }); }); + + function assertHasAcceptHeader(client) { + let hasAcceptHeader = false; + const mockNextPolicy = { + create: (_) => ({}), + sendRequest: (_) => { + return {}; + }, + }; + + const length = client._requestPolicyFactories.length; + for (let i = 0; i < length; i++) { + const mockHttp = { + headers: new HttpHeaders(), + }; + + const result = client._requestPolicyFactories[i].create(mockNextPolicy); + + result.sendRequest(mockHttp); + if (mockHttp.headers.get('accept') == '*/*') { + hasAcceptHeader = true; + break; + } + } + + assert(hasAcceptHeader, 'accept header from connector client should be */*'); + } });