[Mono-bugs] [Bug 687580] New: Mono 2.10.1WCF fails with '(400) Bad Request' when the calling client uses URIs that should be functionally equivalent such as IP address instead of machine name
bugzilla_noreply at novell.com
bugzilla_noreply at novell.com
Thu Apr 14 11:50:19 EDT 2011
https://bugzilla.novell.com/show_bug.cgi?id=687580
https://bugzilla.novell.com/show_bug.cgi?id=687580#c0
Summary: Mono 2.10.1WCF fails with '(400) Bad Request' when the
calling client uses URIs that should be functionally
equivalent such as IP address instead of machine name
Classification: Mono
Product: Mono: Runtime
Version: 2.10.x
Platform: 64bit
OS/Version: Windows Server 2008 R2
Status: NEW
Severity: Normal
Priority: P5 - None
Component: remoting
AssignedTo: lluis at novell.com
ReportedBy: emily.lewis at lumension.com
QAContact: mono-bugs at lists.ximian.com
Found By: ---
Blocker: ---
Created an attachment (id=424965)
--> (http://bugzilla.novell.com/attachment.cgi?id=424965)
This is a working example to reproduces the bug
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64;
Trident/5.0)
I am presently evaluating whether mono 2.10 WCF is stable enough for a project
we are working on. I have written a very simple WCF REST client/server test jig
upon which to make this assessment and for the most part it works. However it
has revealed some oddity in URI syntax that I don't understand - this oddity
only shows up in mono whereas it works fine in Microsoft.NET on windows. I
would like to know if this behavior is normal for mono, or simply a known or
new bug. My searches in bugzilla seem to indicate this exact bug isn't
reported.
To understand the issue, consider that when I run my WCF server I add a service
endpoint with the URI "http://localhost:8080/ProfileREST". Of course, on the
client side I also connect using an endpoint address with the URI
"http://localhost:8080/ProfileREST" and that works fine.
I have discovered however, that mono is very literal about these URIs. For
example, if I run my server with the URI "http://localhost:8080/ProfileREST"
the client can ONLY connect using the like URI
"http://localhost:8080/ProfileREST". If I try to connect the client instead to
say a URI with my explicit machine name "http://mymachinename:8080/ProfileREST"
or even its IP address "http://10.12.12.161:8080/ProfileREST" I receive this
error on the client (and no error on the server):
System.ServiceModel.ProtocolException Message The remote server returned an
unexpected response: (400) Bad Request. Stack Server stack trace: at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestRe
plyResponse(HttpWebRequest request, HttpWebResponse response,
HttpChannelFactory factory, WebException responseException, ChannelBinding
channelBinding) at
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.
HttpChannelRequest.WaitForReply(TimeSpan timeout) at
System.ServiceModel.Channels.RequestChannel.Request(Message message , TimeSpan
timeout) at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message
message, TimeSpan timeout) at
System.ServiceModel.Channels.ServiceChannel.Call(String action, Boo lean
oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeS pan
timeout) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMet
hodCallMessage methodCall, ProxyOperationRuntime operation) at
System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage me ssage)
Exception rethrown at [0]: at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMess age reqMsg,
IMessage retMsg) at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData & msgData,
Int32 type) at client.IProfileREST.Ping() at
client.ProfileRESTClient.client.IProfileREST.Ping() in c:\temp\FunW
ithMonoRESTClient\client\Program.cs:line 35 at client.Program.DoMain(String[]
args) in c:\temp\FunWithMonoRESTClie nt\client\Program.cs:line 79 at
client.Program.Main(String[] args) in c:\temp\FunWithMonoRESTClient
\client\Program.cs:line 54 ---->System.Net.WebException Message The remote
server returned an error: (400) Bad Request. Stack at
System.Net.HttpWebRequest.GetResponse() at
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestCha
nnel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Here are the details of my test setup (I have included the fully Visual Studio
2010 solution in an attachment as well):
Contract
[ServiceContract]
public interface IProfileREST
{
[OperationContract, WebGet(UriTemplate = "Ping")]
void Ping();
}
Server
[ServiceBehavior
(
InstanceContextMode = InstanceContextMode .Single ,
ConcurrencyMode = ConcurrencyMode .Multiple
)
]
public class ProfileRest : IProfileREST
{
#region members
long _hits = 0;
#endregion
#region .ctor
public ProfileRest()
{
}
#endregion
#region IProfileREST
void IProfileREST.Ping()
{
Console.WriteLine("Ping {0}",Interlocked.Increment(ref _hits));
}
#endregion
}
static void Main(string[] args)
{
var address = new Uri("http://localhost:8080/ProfileREST");
var binding = new WebHttpBinding ();
var server = new ProfileRest();
var host = new WebServiceHost(server);
host.AddServiceEndpoint(typeof(IProfileREST), binding, address);
host.Open();
Console.WriteLine("The server is running, press a key to stop...");
Console.ReadKey();
}
Client
public class ProfileRESTClient : ClientBase<IProfileREST>, IProfileREST
{
#region .ctor
public ProfileRESTClient() : base()
{
}
public ProfileRESTClient(Binding binding, EndpointAddress address) :
base(binding, address)
{
base.Endpoint.Behaviors.Add(new WebHttpBehavior());
}
#endregion
#region IProfileREST
void IProfileREST.Ping()
{
base.Channel.Ping();
}
#endregion
}
static void Main(string[] args)
{
EndpointAddress address = new EndpointAddress(new
Uri("http://localhost:8080/ProfileREST"));
Binding binding = new WebHttpBinding();
using (IProfileREST client = new ProfileRESTClient(binding,
address))
{
client.Ping();
}
}
Here is a Wireshark dump of the inbound request:
GET /ProfileREST/Ping HTTP/1.1\r\n [Expert Info (Chat/Sequence): GET
/ProfileREST/Ping HTTP/1.1\r\n] Request Method: GET Request URI:
/ProfileREST/Ping Request Version: HTTP/1.1Content-Type: application/xml;
charset=utf-8\r\nHost: elewisdesktopr2:8080\r\nAccept-Encoding: gzip,
deflate\r\nConnection: Keep-Alive\r\n
And the response:
HTTP/1.1 400 Bad Request\r\n [Expert Info (Chat/Sequence): HTTP/1.1 400 Bad
Request\r\n] Request Version: HTTP/1.1 Response Code: 400Content-Type:
text/html; charset=Windows-1252\r\nServer: Mono-HTTPAPI/1.0\r\nDate: Wed, 13
Apr 2011 17:40:17 GMT\r\nContent-Length: 35\r\nConnection: close\r\n
I have noticed that when I run the server under Microsoft .NET, TCPView reports
the following ports open:
System 4 TCP elewisdesktopr2 8080 elewisdesktopr2 0
LISTENING
System 4 TCPV6 elewisdesktopr2.patchlink.com 8080
elewisdesktopr2.patchlink.com 0 LISTENING
When I run the server under mono I see this:
mono.exe 1816 TCP elewisdesktopr2 8080 elewisdesktopr2 0
LISTENING
mono.exe 1816 TCP elewisdesktopr2 64935 localhost 64934
ESTABLISHED
mono.exe 1816 TCP elewisdesktopr2 64934 localhost 64935
ESTABLISHED
Reproducible: Always
Steps to Reproduce:
1. Open the attach solution and build it
2. Run the server under mono
3. Run the client under windows (a different bug appears to prevent the client
from working in mono, I will report that in a different bug).
4. Observe that the client connects to the server and the server prints out the
message "Ping 1".
5. Edit the client's "Program.cs" file and replace the line:
EndpointAddress address = new EndpointAddress(new
Uri("http://localhost:8080/ProfileREST"));
With
EndpointAddress address = new EndpointAddress(new
Uri("http://YOURMACHINENAME:8080/ProfileREST"));
Where "YOURMACHINENAME" is the name of your windows machine.
6. Re-run the client - observe that this time you get a crash dump
Actual Results:
The client program catches an exception:
---->System.ServiceModel.ProtocolException
Message
The remote server returned an unexpected response: (400) Bad Request.
Stack
Server stack trace:
at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestRe
plyResponse(HttpWebRequest request, HttpWebResponse response,
HttpChannelFactory
factory, WebException responseException, ChannelBinding channelBinding)
at
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.
HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message
message
, TimeSpan timeout)
at
System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message
message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action,
Boo
lean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs,
TimeS
pan timeout)
at
System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMet
hodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage
me
ssage)
Exception rethrown at [0]:
at
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMess
age reqMsg, IMessage retMsg)
at
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData
& msgData, Int32 type)
at client.IProfileREST.Ping()
at client.ProfileRESTClient.client.IProfileREST.Ping() in
C:\Temp\FunW
ithMonoRESTClient.Report\client\Program.cs:line 35
at client.Program.DoMain(String[] args) in
C:\Temp\FunWithMonoRESTClie
nt.Report\client\Program.cs:line 68
at client.Program.Main(String[] args) in
C:\Temp\FunWithMonoRESTClient
Report\client\Program.cs:line 54
---->System.Net.WebException
Message
The remote server returned an error: (400) Bad Request.
Stack
at System.Net.HttpWebRequest.GetResponse()
at
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestCha
nnel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Expected Results:
The client should be able to contact the server with a URI that specifies the
machine name or IP address without throwing an exception.
This test was performed with the server running on Windows Server 2008 R2 and
Ubuntu 10.10, they both act the same way.
I don't know why I always have to run the client on windows .net, i think this
is another bug that I will report.
--
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
More information about the mono-bugs
mailing list