function Request(b,a,c,f,d,e,g){this._callback=this._channel=null;this._triedAuth=false;this._headers=d;this._ignoreBody=e;this._ignoreAuthTokens=g;if(a instanceof Object){if(!a.protocol)a.protocol=Xmarks.Settings.GetInt("securityLevel",1)==1||Xmarks.Settings.GetInt("securityLevel",0)==0&&f?"https":"http";if(!a.host)a.host=Xmarks.Settings.Get("syncserver");if(!a.path)a.path="/";if(a.path[0]!="/")a.path="/"+a.path;this._url=a.protocol+"://"+a.host+a.path}else this._url=a;this._bodyobj=c;this._method=
b;this._isAuthRequest=f}
Request.prototype={Start:function(b){Xmarks.LogWrite(">>> "+this._method+" "+this._StripPassword(this._url));if(this._bodyobj&&!this._isAuthRequest)Xmarks.LogWrite(">>> Body is: "+(!Xmarks.Settings.GetBool("no-verbose")?JSON.stringify(this._bodyobj):"(disabled)"));this._callback=b;this._channel=new XMLHttpRequest;this._channel.open("POST",this._url,true);(b=Xmarks.Settings.Get(Xmarks.Settings.GetUserHash()+"authtoken"))&&this._channel.setRequestHeader("x-xmarks-auth",b);this._channel.setRequestHeader("Content-Type","application/json; charset=utf-8");
this._channel.setRequestHeader("X-Xmarks-User-Agent","Xmarks-Cr/"+Xmarks.Settings.Get("version","???"));if(this._headers)for(var a in this._headers)this._channel.setRequestHeader(a,this._headers[a]);var c=this;this._channel.onreadystatechange=function(){c.onStreamComplete(c)};this._channel.send(this._bodyobj?JSON.stringify(this._bodyobj):null)},Cancel:function(){if(this._channel){Xmarks.LogWrite("Cancelling Network Request");this._channel.abort()}},onStreamComplete:function(b){var a={};if(b._channel.readyState==
4){var c=b._channel.status;if(c==200||c==201||c==204){this._ignoreBody||(a=JSON.parse(b._channel.responseText));if(a.status==null)a.status=0;if(a.status==302){Xmarks.LogWrite(">>> Authenticating...");if(this._triedAuth){Xmarks.LogWrite("In authentication loop. Possible proxy server caching issue.");this._callback({status:1012});return}a=a.authtoken_location;b=this;c=a.indexOf("://");var f=a.indexOf("/",c+3);if(c<0||f<0)throw Error("Couldn't parse location string "+a);var d={};d.host=a.substr(c+3,
f-(c+3));d.host=Xmarks.Settings.Get("host-login",d.host);d.path=a.substr(f);Xmarks.GetUserCredentials(function(e){if(e.username){var g=Base64.decode(e.password);g=new Request("POST",d,Xmarks.GetRequestArgs({username:e.username,passwordhash:hex_md5(g)}),true);b._triedAuth=true;g.Start(function(h){if(h.status==0){e.authtoken=h.auth;Xmarks.Settings.SetUserSettings(e);Xmarks.LogWrite("Authenticated as: "+Xmarks.Settings.Get("current-username"));PasswordStore.LoadPasswordDb();UpdateTabListener();b.Start(b._callback)}else{if(h.message==
"Wrong username or password.")h.status=401;b._callback(h)}})}else{Xmarks.LogWrite("User canceled password request.");b._callback(2)}});return}else if(a.status==503){c=new Date;a=60;if(typeof responseBody!="undefined"&&typeof responseBody.backoff_delay!="undefined")a=responseBody.backoff_delay;c=c.getTime()+a*1E3;Xmarks.Settings.Set("backoff-until",c);Xmarks.LogWrite("Server 503: wants us to back off for "+a+" seconds");a={status:-5,errormsg:"Server 503 delay"}}}else a={status:-3,errormsg:"Unknown HTTP response: "+
c,text:b._channel.statusText,len:typeof b._channel.responseText!="undefined"?b._channel.responseText.length:0,seclevel:Xmarks.Settings.GetInt("securityLevel",1)};if(Xmarks.Settings.GetBool("no-verbose"))Xmarks.LogWrite(">>> Callback (disabled)");else{c=a.auth;delete a.auth;Xmarks.LogWrite(">>> Callback "+JSON.stringify(a));a.auth=c}this._callback(a)}},_StripPassword:function(b){var a=b.match(/^(.*):(.*)@(.*)$/);return a?a[1]+"@"+a[3]:b}};
