gautamsi / ews-javascript-api

EWS API for TypeScript/JavaScript - ported from OfficeDev/ews-managed-api - node, cordova, meteor, Ionic, Electron, Outlook Add-Ins
MIT License
282 stars 73 forks source link

socket hang up #228

Closed omatrot closed 5 years ago

omatrot commented 6 years ago

Environment: EWS Exchange 2010

The following typescript code fails with "socket hang up" error:

var exch = new ExchangeService(ExchangeVersion.Exchange2010_SP2);

    exch.Url = new Uri("https://webmail.hidden_for_privacy.fr/ews/Exchange.asmx");
    exch.Credentials = new WebCredentials("TestBP_User1@hidden_for_privacy.fr", "password");

    try {
        console.info(`About to get Room Lists`);
        const myRoomLists: EmailAddressCollection = await exch.GetRoomLists();
        console.info(`Found [${myRoomLists.Count}] Lists`);
        for (let roomListEmailAddress in myRoomLists) {
            console.debug(`Parsing List [${roomListEmailAddress}]...`);
            //for(let room in exch.GetRooms(roomList))
        }

    }
    catch (e) {
        fail(e);
    }

Not sure which side is the problem located...

EWS logging:

sending ews request EwsLogging.js:38 { url: 'https://webmail.hidden_for_privacy.fr/ews/Exchange.asmx', EwsLogging.js:36 headers: { 'Content-Type': 'text/xml; charset=utf-8', Accept: 'text/xml', Authorization: 'Basic blahblah...' }, type: 'POST', data: '</t:RequestServerVersion></soap:Header></m:GetRoomLists></soap:Body></soap:Envelope>' } Error in calling service, error code:0 EwsLogging.js:29 problem with request: socket hang up test.ts:4

stack: [Error: socket hang up test.ts:5 at TLSSocket.onHangUp (_tls_wrap.js:1135:19) at Object.onceWrapper (events.js:313:30) at emitNone (events.js:111:20) at TLSSocket.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1056:12) at _combinedTickCallback (internal/process/next_tick.js:138:11) at process._tickCallback (internal/process/next_tick.js:180:9)]

Any help appreciated.

gautamsi commented 6 years ago

do you have any other server or may be Office 365 mailbox to test against? may be specific issue with exchange.

omatrot commented 6 years ago

Unfortunately no. I asked my client to see if it could see the incoming requests in the logs though.

May be you can take a look at these issues Error: socket hang up #2047 and http.Agent: idle sockets throw unhandled ECONNRESET. This may be tied to Node.js.

omatrot commented 6 years ago

My customer is investigating a potential firewall issue.

gautamsi commented 6 years ago

I am using different library. for investigation and testing you can modify XHRDefaults with http/s agent keepAlive options. you have to modify line https://github.com/gautamsi/ews-javascript-api/blob/6fa705079141a9ea5ce76d877a132d86d2bad1ca/src/js/XHRDefaults.ts#L17 and https://github.com/gautamsi/ews-javascript-api/blob/6fa705079141a9ea5ce76d877a132d86d2bad1ca/src/js/XHRDefaults.ts#L64 and add agentHTTPS option, see https://github.com/andris9/fetch#options, you can change corresponding js file instead of building it from source.

omatrot commented 6 years ago

Adding agentHttps: xhroptions.agentHttps, has no effect...

This is probably a backend firewall issue.

gautamsi commented 6 years ago

xhroptions has no agentHttps property. in js file you want to do like this.

const https = require('https');
const keepAliveAgent = new https.Agent({ keepAlive: true });
// .... other lines
agentHttps: keepAliveAgent,
omatrot commented 6 years ago

I've used an alternate method to set the header, still the same problem. I'll wait for an answer from my customer regarding their firewall.

omatrot commented 6 years ago

FYI, the equivalent .NET Code run on Windows does not suffer this problem. This is defintely tied to the context of my Customer because I'm running it without error against an Office 365 system.

omatrot commented 6 years ago

I've used fiddler to see what's going on underneath. The first request to the service fails with a HTTP 401 (Unauthorized). But the response hearders contains a cookie:

Set-Cookie: exchangecookie=44b8fffe783c4e00a95554cae1f27651; expires=Wed, 16-Jan-2019 12:24:30 GMT; path=/; HttpOnly

The .NET client tries again with another request that include the cookie header received from the first call:

Cookie: exchangecookie=44b8fffe783c4e00a95554cae1f27651

This time it works. I have a response back. Full Headers (minus HOST) in first request:

Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/15.00.0913.015
Accept-Encoding: gzip,deflate
Content-Length: 3369
Expect: 100-continue
Connection: Keep-Alive

Second one:

Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/15.00.0913.015
Accept-Encoding: gzip,deflate
Authorization: Basic VGVzdEJQX1VzZXIxQGdyb3VwYW1hLWltbW9iaWxpZXIuZnI6RWx5c2Vlc0Ax
Cookie: exchangecookie=44b8fffe783c4e00a95554cae1f27651
Content-Length: 3369
Expect: 100-continue

I'll try with Fiddler Mac to see what's going on exactly with the Javascript API.

gautamsi commented 6 years ago

what is the authentication mode set on EWS Virtual Directory?

omatrot commented 6 years ago

I'll have to ask.

gautamsi commented 6 years ago

you can test add cookie jar support used in fetch if cookies is a problem.

this may have changed in latest Exchange Patch or so, had not seen this as issue unless you are running behind reverse proxy of some kind.

omatrot commented 6 years ago

Your right. My Customer tells me that there is an ISA server (reverse proxy) between us and the IIS Server. They'll try to let us through by modifying the configuration.

gautamsi commented 6 years ago

what authentication is being used for ISA? if it is allowed to bypass login by ISA (usual case with latest exchange) you should use basic authentication (included in ews-javascript-api). if they have published EWS over Form based Authentication, You have to use cookieAuthXhrApi in ews-javascript-api-auth

omatrot commented 6 years ago

EWS seems to be published over Form based Authentication because we are indeed redirected to a login form when testing the EWS url in a browser.

gautamsi commented 6 years ago

must use cookieAuthXhrApi

omatrot commented 6 years ago

I'll try that tonight, thanks.

omatrot commented 6 years ago

Unfortunately it does not work. I have the same error message.

gautamsi commented 6 years ago

ping me on gitter

gautamsi commented 6 years ago

issue is with cipher used in https/tls, could be specific to site you are using. this helped me troubleshoot further https://github.com/nodejs/node/issues/9845

gautamsi commented 6 years ago

I have to update cookie auth api with additional option, like for HttpAgent pass through to underlying api

omatrot commented 6 years ago

great news !

gautamsi commented 5 years ago

there is no need to update anything here, this is how it should be used

import { XhrApi } from "@ewsjs/xhr"
const xhrApi = new XhrApi({ agentOptions: { ciphers: "DES-CBC3-SHA" } })
ewsService.xhrApi = xhrApi; // or ews.ConfigurationApi.ConfigureXHR(xhrApi)

agentOptions are passed to tls tunnel creation.