private void Communicate() { // communicate try { Communication.Communicate(this); } catch (Exception exception) { LogError($"Error: {exception.Message}"); // continue } finally { LogVerbose("Communication completed."); lock (this.instanceLocker) { CloseTcpConnections(); this.proxyCredential = null; this.connectingToProxy = false; this.responseIO = null; this.requestIO = null; } } return; }
protected virtual bool SetModifications(Request request, Response response) { // argument checks if (request == null) { throw new ArgumentNullException(nameof(request)); } // response may be null // Currently only basic authorization for the proxy is handled. // ToDo: convert local function in C# 7 Func <bool, string, Proxy.BasicCredential> getServerBasicCredentials = (firstRequest, realm) => { // set the cached proxy credential Proxy.BasicCredential proxyCredential; lock (this.instanceLocker) { Proxy.BasicCredential currentProxyCredential = this.proxyCredential; proxyCredential = firstRequest ? currentProxyCredential : null; if (proxyCredential == null) { string endPoint = this.server.EndPoint; proxyCredential = this.Proxy.GetServerBasicCredentials(endPoint, realm, firstRequest: firstRequest, oldBasicCredentials: currentProxyCredential); this.proxyCredential = proxyCredential; // may be null } } return(proxyCredential); }; bool retry = false; IReadOnlyCollection <byte> overridingProxyAuthorization = null; if (response == null) { // before requesting firstly if (request.ProxyAuthorizationSpan.IsZeroToZero) { // set the cached proxy credential Proxy.BasicCredential proxyCredential = getServerBasicCredentials(true, null); overridingProxyAuthorization = proxyCredential?.Bytes; } } else { // after responded from the server if (response.StatusCode == 407) { // 407: Proxy Authentication Required // the current credential seems to be invalid (or null) Proxy.BasicCredential proxyCredential = getServerBasicCredentials(false, "Proxy"); // ToDo: extract realm from the field overridingProxyAuthorization = proxyCredential?.Bytes; } else { // no need to resending overridingProxyAuthorization = null; } } // set modifications if necessary if (overridingProxyAuthorization != null) { // set or overwrite the Proxy-Authorization field. Span span = request.ProxyAuthorizationSpan; if (span.IsZeroToZero) { span = request.EndOfHeaderFields; } request.AddModification( span, (modifier) => { modifier.Write(overridingProxyAuthorization); return(true); } ); retry = true; } return(retry); }