//
-// HttpRequestChannel.cs
+// HttpRequestChannel.cs
//
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
get { return source.MessageEncoder; }
}
+#if NET_2_1
+ public override T GetProperty<T> ()
+ {
+ if (typeof (T) == typeof (IHttpCookieContainerManager))
+ return source.GetProperty<T> ();
+ return base.GetProperty<T> ();
+ }
+#endif
+
// Request
public override Message Request (Message message, TimeSpan timeout)
destination = Via ?? RemoteAddress.Uri;
}
- var web_request = HttpWebRequest.Create (destination);
+ var web_request = (HttpWebRequest) 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
+#if NET_2_1 || NET_4_0
+ HttpWebRequest hwr = (web_request as HttpWebRequest);
var cmgr = source.GetProperty<IHttpCookieContainerManager> ();
if (cmgr != null)
- ((HttpWebRequest) web_request).CookieContainer = cmgr.CookieContainer;
+ hwr.CookieContainer = cmgr.CookieContainer;
#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;
// 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;
// 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);
+ foreach (var key in hp.Headers.AllKeys) {
+ if (WebHeaderCollection.IsRestricted (key)) { // do not ignore this. WebHeaderCollection rejects restricted ones.
+ // FIXME: huh, there should be any better way to do such stupid conversion.
+ switch (key) {
+ case "Accept":
+ web_request.Accept = hp.Headers [key];
+ break;
+ case "Connection":
+ web_request.Connection = hp.Headers [key];
+ break;
+ //case "ContentLength":
+ // web_request.ContentLength = hp.Headers [key];
+ // break;
+ case "ContentType":
+ web_request.ContentType = hp.Headers [key];
+ break;
+ //case "Date":
+ // web_request.Date = hp.Headers [key];
+ // break;
+ case "Expect":
+ web_request.Expect = hp.Headers [key];
+ break;
+#if NET_4_0
+ case "Host":
+ web_request.Host = hp.Headers [key];
+ break;
+#endif
+ //case "If-Modified-Since":
+ // web_request.IfModifiedSince = hp.Headers [key];
+ // break;
+ case "Referer":
+ web_request.Referer = hp.Headers [key];
+ break;
+ case "Transfer-Encoding":
+ web_request.TransferEncoding = hp.Headers [key];
+ break;
+ case "User-Agent":
+ web_request.UserAgent = hp.Headers [key];
+ break;
+ }
+ }
+ else
+ web_request.Headers [key] = hp.Headers [key];
+ }
web_request.Method = hp.Method;
// FIXME: do we have to handle hp.QueryString ?
if (hp.SuppressEntityBody)
suppressEntityBody = true;
}
+#if !NET_2_1
+ if (source.ClientCredentials != null) {
+ var cred = source.ClientCredentials;
+ if ((cred.ClientCertificate != null) && (cred.ClientCertificate.Certificate != null))
+ ((HttpWebRequest)web_request).ClientCertificates.Add (cred.ClientCertificate.Certificate);
+ }
#endif
if (!suppressEntityBody && String.Compare (web_request.Method, "GET", StringComparison.OrdinalIgnoreCase) != 0) {
channelResult.Complete (we);
return;
}
+
+
+ var hrr2 = (HttpWebResponse) res;
+
+ if ((int) hrr2.StatusCode >= 400 && (int) hrr2.StatusCode < 500) {
+ Exception exception = new WebException (
+ String.Format ("There was an error on processing web request: Status code {0}({1}): {2}",
+ (int) hrr2.StatusCode, hrr2.StatusCode, hrr2.StatusDescription), null,
+ WebExceptionStatus.ProtocolError, hrr2);
+
+ if ((int) hrr2.StatusCode == 404) {
+ // Throw the same exception .NET does
+ exception = new EndpointNotFoundException (
+ "There was no endpoint listening at {0} that could accept the message. This is often caused by an incorrect address " +
+ "or SOAP action. See InnerException, if present, for more details.",
+ exception);
+ }
+
+ channelResult.Complete (exception);
+ return;
+ }
+
+
try {
// The response might contain SOAP fault. It might not.
resstr = res.GetResponseStream ();
// TODO: unit test to make sure an empty response never throws
// an exception at this level
if (hrr.ContentLength == 0) {
- ret = Message.CreateMessage (MessageVersion.Default, String.Empty);
+ ret = Message.CreateMessage (Encoder.MessageVersion, String.Empty);
} else {
using (var responseStream = resstr) {
}
var rp = new HttpResponseMessageProperty () { StatusCode = hrr.StatusCode, StatusDescription = hrr.StatusDescription };
-#if MOONLIGHT
- if (hrr.SupportsHeaders) {
- foreach (string key in hrr.Headers)
- rp.Headers [key] = hrr.Headers [key];
- }
-#else
foreach (var key in hrr.Headers.AllKeys)
rp.Headers [key] = hrr.Headers [key];
-#endif
ret.Properties.Add (HttpResponseMessageProperty.Name, rp);
channelResult.Response = ret;
protected override void OnAbort ()
{
- foreach (var web_request in web_requests)
+ foreach (var web_request in web_requests.ToArray ())
web_request.Abort ();
web_requests.Clear ();
}