Bug 37342 - [Mono 4.2] ArgumentOutOfRangeException when using ChannelFactory if BasicHttpBinding.SendTimeout is set to TimeSpan.MaxValue
Summary: [Mono 4.2] ArgumentOutOfRangeException when using ChannelFactory if BasicHttp...
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: WCF assemblies ()
Version: 4.2.0 (C6)
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: marcos.henrich
: 37338 ()
Depends on:
Reported: 2015-12-31 02:14 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2017-09-06 16:55 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Test case (5.65 KB, application/zip)
2015-12-31 02:14 UTC, Brendan Zagaeski (Xamarin Team, assistant)

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report for Bug 37342 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:

Description Brendan Zagaeski (Xamarin Team, assistant) 2015-12-31 02:14:27 UTC
Created attachment 14418 [details]
Test case

[Mono 4.2] ArgumentOutOfRangeException when using ChannelFactory if BasicHttpBinding.SendTimeout is set to TimeSpan.MaxValue

## Regression status: a "new feature" in Mono 4.2 has exposed a new problem 

In Mono 4.0.5 (1d8d582) and earlier, the local `value` variable was always "60000" during the call to `System.Net.HttpWebRequest.set_Timeout()` that happened during a `BasicHttpBinding` WCF channel setup.

In Mono 4.2 and later, if the user sets `BasicHttpBinding.SendTimeout`, that number now propogates correctly into the `value` variable in the `set_Timeout()` method. Unfortunately, this exposes a place where the .NET behavior differs from the current Mono behavior.

In .NET, you can set `BasicHttpBinding.SendTimeout` to `TimeSpan.MaxValue` and everything works without error.

In Mono, using `TimeSpan.MaxValue` causes an integer overflow, and leads to an ArgumentOutOfRangeException.

There's a chance this is an arbitrary implementation decision in .NET, so Mono's behavior might not necessarily be "wrong." For example, the documentation for `Binding.SendTimeout` [1] does not specify that `TimeSpan.MaxValue` is a valid input value.

[1] https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding.sendtimeout.aspx

## Steps to replicate

1. Build the project:
> $ xbuild /t:Build /p:Configuration=Debug ConsoleWCFClient.csproj

2. Run the resulting `.exe`:
> $ mono bin/Debug/ConsoleWCFClient.exe

## Results

### Mono 4.2 (39edf24)

If you set Xamarin Studio to break on all exceptions, you can see that the program fails because `TimeSpan.MaxValue` overflows the integer `value` variable at:

> System.Net.HttpWebRequest.set_Timeout(int value) in /private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/System/System.Net/HttpWebRequest.cs:605
> System.ServiceModel.Channels.HttpRequestChannel.BeginProcessRequest(System.ServiceModel.Channels.HttpRequestChannel.HttpChannelRequestAsyncResult result) in /private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs:128

#### The stack trace output directly on the standard output of the program is less informative

> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
> Parameter name: value
>   at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_remoting_wrapper (intptr,intptr)
>   at (wrapper remoting-invoke) TempConvertSoap:EndFahrenheitToCelsius (System.IAsyncResult)
>   at ConsoleWCFClient.MainClass.OnTestMethodCompleted (IAsyncResult asyncResult) <0x2cc9828 + 0x000aa> in <filename unknown>:0 

### .NET 4.5 on Windows

The program completes successfully with the following output:

> Sent request...
> The converted value is: 37

Taking a guess that the .NET stack would also call `System.Net.HttpWebRequest.set_Timeout()`, I set a symbolic breakpoint on that method in Visual Studio. I discovered that the code that sets the timeout in .NET uses some extra logic that prevents the WCF channel from trying to set a timeout that overflows the integer. In particular, `HttpWebRequest.set_Timeout()` is called indirectly via `HttpChannelUtilities.SetRequestTimeout()` [2]. And that helper method in turn uses another `TimeoutHelper.ToMilliseconds()` helper method [3] that cleans up the maximum return value, avoiding the overflow.

[2] https://github.com/Microsoft/referencesource/blob/e458f8df6ded689323d4bd1a2a725ad32668aaec/System.ServiceModel/System/ServiceModel/Channels/HttpChannelHelpers.cs#L3279-L3289

[3] https://github.com/Microsoft/referencesource/blob/fa352bbcac7dd189f66546297afaffc98f6a7d15/System.ServiceModel.Internals/System/Runtime/TimeoutHelper.cs#L48-L63
Comment 1 Brendan Zagaeski (Xamarin Team, assistant) 2015-12-31 02:28:15 UTC
*** Bug 37338 has been marked as a duplicate of this bug. ***