Skip to content

Commit

Permalink
KeepAliveEnabled property implementation for HttpTransportBindingElement
Browse files Browse the repository at this point in the history
This property could be used to disable for each HTTP query keep-alive header.
  • Loading branch information
netkill1987 authored and mconnew committed Jan 19, 2018
1 parent 262b42d commit c931e26
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 0 deletions.
Expand Up @@ -50,6 +50,7 @@ internal class HttpChannelFactory<TChannel>
private bool _useDefaultWebProxy;
private Lazy<string> _webSocketSoapContentType;
private SHA512 _hashAlgorithm;
private bool _keepAliveEnabled;

internal HttpChannelFactory(HttpTransportBindingElement bindingElement, BindingContext context)
: base(bindingElement, context, HttpTransportDefaults.GetDefaultMessageEncoderFactory())
Expand Down Expand Up @@ -102,6 +103,7 @@ internal HttpChannelFactory(HttpTransportBindingElement bindingElement, BindingC
_authenticationScheme = bindingElement.AuthenticationScheme;
_maxBufferSize = bindingElement.MaxBufferSize;
_transferMode = bindingElement.TransferMode;
_keepAliveEnabled = bindingElement.KeepAliveEnabled;

if (bindingElement.ProxyAddress != null)
{
Expand Down Expand Up @@ -331,6 +333,9 @@ private HttpCookieContainerManager GetHttpCookieContainerManager()

httpClient = new HttpClient(clientHandler);

if(!_keepAliveEnabled)
httpClient.DefaultRequestHeaders.ConnectionClose = true;

// We provide our own CancellationToken for each request. Setting HttpClient.Timeout to -1
// prevents a call to CancellationToken.CancelAfter that HttpClient does internally which
// causes TimerQueue contention at high load.
Expand Down
Expand Up @@ -83,6 +83,9 @@ public interface IWcfService

[OperationContract]
void ReturnContentType(string contentType);

[OperationContract]
bool IsHttpKeepAliveDisabled();
}

[ServiceContract]
Expand Down
Expand Up @@ -42,4 +42,41 @@ public static void DefaultSettings_Echo_RoundTrips_String()
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}

[WcfFact]
[OuterLoop]
public static void HttpKeepAliveDisabled_Echo_RoundTrips_True()
{
ChannelFactory<IWcfService> factory = null;
IWcfService serviceProxy = null;
Binding binding = null;
CustomBinding customBinding = null;

try
{
// *** SETUP *** \\
binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
customBinding = new CustomBinding(binding);
var httpElement = customBinding.Elements.Find<HttpTransportBindingElement>();
httpElement.KeepAliveEnabled = false;

factory = new ChannelFactory<IWcfService>(customBinding, new EndpointAddress(Endpoints.HttpBaseAddress_Basic));
serviceProxy = factory.CreateChannel();

// *** EXECUTE *** \\
bool result = serviceProxy.IsHttpKeepAliveDisabled();

// *** VALIDATE *** \\
Assert.True(result, "Error: expected response from service: 'true' Actual was: 'false'");

// *** CLEANUP *** \\
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
}
}
Expand Up @@ -155,5 +155,8 @@ public interface IWcfService
ReplyAction = "http://www.contoso.com/IXmlMessageContarctTestService/EchoMessageResquestWithMessageHeaderResponse")]
[XmlSerializerFormat(SupportFaults = true)]
XmlMessageContractTestResponse EchoMessageResquestWithMessageHeader(XmlMessageContractTestRequestWithMessageHeader request);

[OperationContract]
bool IsHttpKeepAliveDisabled();
}
}
Expand Up @@ -424,6 +424,15 @@ public string EchoTimeAndSetCookie(string name)
return value;
}

public bool IsHttpKeepAliveDisabled()
{
MessageProperties properties = new MessageProperties(OperationContext.Current.IncomingMessageProperties);
var property = (HttpRequestMessageProperty)properties[HttpRequestMessageProperty.Name];
WebHeaderCollection collection = property.Headers;
string connectionValue = collection.Get(Enum.GetName(typeof(HttpRequestHeader), HttpRequestHeader.Connection));
return connectionValue.Equals("Close", StringComparison.OrdinalIgnoreCase);
}

private static string StreamToString(Stream stream)
{
var reader = new StreamReader(stream, Encoding.UTF8);
Expand Down
2 changes: 2 additions & 0 deletions src/System.ServiceModel.Http/ref/System.ServiceModel.Http.cs
Expand Up @@ -186,6 +186,8 @@ public partial class HttpTransportBindingElement : System.ServiceModel.Channels.
public System.ServiceModel.Channels.WebSocketTransportSettings WebSocketSettings { get { return default(System.ServiceModel.Channels.WebSocketTransportSettings); } set { } }
[System.ComponentModel.DefaultValue(true)]
public bool UseDefaultWebProxy { get { return default(bool); } set { } }
[System.ComponentModel.DefaultValue(true)]
public bool KeepAliveEnabled { get { return default(bool); } set { } }
public override System.ServiceModel.Channels.IChannelFactory<TChannel> BuildChannelFactory<TChannel>(System.ServiceModel.Channels.BindingContext context) { return default(System.ServiceModel.Channels.IChannelFactory<TChannel>); }
public override bool CanBuildChannelFactory<TChannel>(System.ServiceModel.Channels.BindingContext context) { return default(bool); }
public override System.ServiceModel.Channels.BindingElement Clone() { return default(System.ServiceModel.Channels.BindingElement); }
Expand Down

0 comments on commit c931e26

Please sign in to comment.