diff --git a/lib/transport.js b/lib/transport.js index 03104de3..bc6fa3c3 100644 --- a/lib/transport.js +++ b/lib/transport.js @@ -1,5 +1,6 @@ import co from 'co'; import querystring from 'querystring'; +import { AuthCalc } from 'httpauth'; import XMLHttpRequest from './xmlhttprequest'; @@ -24,12 +25,19 @@ export class Transport { send() {} } +/* +Standard HTTP authentication +- supports both Basic and Digest authentication +- chooses the method automatically +- works better with CORS (passes Authorization directly) +*/ export class Basic extends Transport { /** * @param {dav.Credentials} credentials user authorization. */ constructor(credentials) { super(credentials); + this.auth = new AuthCalc(this.credentials.username, this.credentials.password); } send(request, url, options) { @@ -39,25 +47,39 @@ export class Basic extends Transport { let transformResponse = request.transformResponse; let onerror = request.onerror; - let xhr = new XMLHttpRequest(); - if (sandbox) sandbox.add(xhr); - xhr.open( - request.method, - url, - true /* async */, - this.credentials.username, - this.credentials.password - ); + let result; + let retryCnt = 1; + while (retryCnt >= 0) { + retryCnt--; + let xhr = new XMLHttpRequest(); + if (sandbox) sandbox.add(xhr); + xhr.open( + request.method, + url, + true /* async */ + //WITHOUT login and password + //NO "withCredentials" + ); - if (transformRequest) transformRequest(xhr); + this.auth.sign(xhr.request, {url: url, type: request.method, data: request.requestData}); - let result; - try { - yield xhr.send(request.requestData); - result = transformResponse ? transformResponse(xhr) : xhr; - } catch (error) { - if (onerror) onerror(error); - throw error; + if (transformRequest) transformRequest(xhr); + + try { + yield xhr.send(request.requestData); + result = transformResponse ? transformResponse(xhr) : xhr; + break; //of repeat loop + } catch (error) { + console.debug("dav.Transport.Basic::OnError: "+xhr.request.status); + //Authentication required? Reinitialize the auth context + if (xhr.request.status === 401 || xhr.request.status === 407) { + console.debug("Reinitializing the auth context..."); + this.auth.updateServerResponse(xhr.request); + continue; //try again + } + if (onerror) onerror(error); + throw error; + } } return result; diff --git a/package.json b/package.json index a307f946..80a50c85 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@babel/polyfill": "^7.0.0", "co": "^4.6.0", "debug": "^4.1.1", + "httpauth": "github:himselfv/httpauth", "xmldom": "^0.1.27", "xmlhttprequest": "^1.8.0" },