Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeepAliveEnabled property implementation for HttpTransportBindingElement #2370

Merged
merged 1 commit into from
Jan 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
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 @@ internal async Task<HttpClient> GetHttpClientAsync(EndpointAddress to,

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
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public interface IWcfService

[OperationContract]
void ReturnContentType(string contentType);

[OperationContract]
bool IsHttpKeepAliveDisabled();
}

[ServiceContract]
Expand Down
Original file line number Diff line number Diff line change
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);
}
}
}
Original file line number Diff line number Diff line change
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();
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ protected HttpTransportBindingElement(System.ServiceModel.Channels.HttpTransport
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