void BeginProcessRequest (HttpChannelRequestAsyncResult result)
{
Message message = result.Message;
TimeSpan timeout = result.Timeout;
// FIXME: is distination really like this?
Uri destination = message.Headers.To;
if (destination == null) {
if (source.Transport.ManualAddressing)
throw new InvalidOperationException ("When manual addressing is enabled on the transport, every request messages must be set its destination address.");
else
destination = Via ?? RemoteAddress.Uri;
}
var web_request = HttpWebRequest.Create (destination);
web_requests.Add (web_request);
result.WebRequest = web_request;
web_request.Method = "POST";
web_request.ContentType = Encoder.ContentType;
#if NET_2_1
HttpWebRequest hwr = (web_request as HttpWebRequest);
#if MOONLIGHT
if (hwr.SupportsCookieContainer) {
#endif
var cmgr = source.GetProperty<IHttpCookieContainerManager> ();
if (cmgr != null)
hwr.CookieContainer = cmgr.CookieContainer;
#if MOONLIGHT
}
#endif
#endif
#if !MOONLIGHT // until we support NetworkCredential like SL4 will do.
// client authentication (while SL3 has NetworkCredential class, it is not implemented yet. So, it is non-SL only.)
var httpbe = (HttpTransportBindingElement) source.Transport;
string authType = null;
switch (httpbe.AuthenticationScheme) {
// AuthenticationSchemes.Anonymous is the default, ignored.
case AuthenticationSchemes.Basic:
authType = "Basic";
break;
case AuthenticationSchemes.Digest:
authType = "Digest";
break;
case AuthenticationSchemes.Ntlm:
authType = "Ntlm";
break;
case AuthenticationSchemes.Negotiate:
authType = "Negotiate";
break;
}
if (authType != null) {
var cred = source.ClientCredentials;
string user = cred != null ? cred.UserName.UserName : null;
string pwd = cred != null ? cred.UserName.Password : null;
if (String.IsNullOrEmpty (user))
throw new InvalidOperationException (String.Format ("Use ClientCredentials to specify a user name for required HTTP {0} authentication.", authType));
var nc = new NetworkCredential (user, pwd);
web_request.Credentials = nc;
// FIXME: it is said required in SL4, but it blocks full WCF.
//web_request.UseDefaultCredentials = false;
}
#endif
#if !NET_2_1 // FIXME: implement this to not depend on Timeout property
web_request.Timeout = (int) timeout.TotalMilliseconds;
#endif
// There is no SOAP Action/To header when AddressingVersion is None.
if (message.Version.Envelope.Equals (EnvelopeVersion.Soap11) ||
message.Version.Addressing.Equals (AddressingVersion.None)) {
if (message.Headers.Action != null) {
web_request.Headers ["SOAPAction"] = String.Concat ("\"", message.Headers.Action, "\"");
message.Headers.RemoveAll ("Action", message.Version.Addressing.Namespace);
}
}
// apply HttpRequestMessageProperty if exists.
bool suppressEntityBody = false;
#if !NET_2_1
string pname = HttpRequestMessageProperty.Name;
if (message.Properties.ContainsKey (pname)) {
HttpRequestMessageProperty hp = (HttpRequestMessageProperty) message.Properties [pname];
web_request.Headers.Clear ();
web_request.Headers.Add (hp.Headers);
web_request.Method = hp.Method;
// FIXME: do we have to handle hp.QueryString ?
if (hp.SuppressEntityBody)
suppressEntityBody = true;
}
#endif
if (!suppressEntityBody && String.Compare (web_request.Method, "GET", StringComparison.OrdinalIgnoreCase) != 0) {
MemoryStream buffer = new MemoryStream ();
Encoder.WriteMessage (message, buffer);
if (buffer.Length > int.MaxValue)
throw new InvalidOperationException ("The argument message is too large.");
#if !NET_2_1
web_request.ContentLength = (int) buffer.Length;
#endif
web_request.BeginGetRequestStream (delegate (IAsyncResult r) {
try {
result.CompletedSynchronously &= r.CompletedSynchronously;
using (Stream s = web_request.EndGetRequestStream (r))
s.Write (buffer.GetBuffer (), 0, (int) buffer.Length);
web_request.BeginGetResponse (GotResponse, result);
} catch (WebException ex) {
switch (ex.Status) {
#if !NET_2_1
case WebExceptionStatus.NameResolutionFailure:
#endif
case WebExceptionStatus.ConnectFailure:
result.Complete (new EndpointNotFoundException (new EndpointNotFoundException ().Message, ex));
break;
default:
result.Complete (ex);
break;
}
} catch (Exception ex) {
result.Complete (ex);
}
}, null);
} else {
web_request.BeginGetResponse (GotResponse, result);
}
}