WebRequest web_request;
- // FIXME: supply maxSizeOfHeaders.
- int max_headers = 0x10000;
-
// Constructor
public HttpRequestChannel (HttpChannelFactory<IRequestChannel> factory,
this.source = factory;
}
- public int MaxSizeOfHeaders {
- get { return max_headers; }
- }
-
public MessageEncoder Encoder {
get { return source.MessageEncoder; }
}
// FIXME: is distination really like this?
Uri destination = message.Headers.To;
if (destination == null) {
- if (source.Source.ManualAddressing)
+ 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;
web_request.Method = "POST";
web_request.ContentType = Encoder.ContentType;
-#if !NET_2_1 // until we support NetworkCredential like SL4 will do.
+#if NET_2_1
+ var cmgr = source.GetProperty<IHttpCookieContainerManager> ();
+ if (cmgr != null)
+ ((HttpWebRequest) web_request).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.Source;
+ var httpbe = (HttpTransportBindingElement) source.Transport;
string authType = null;
switch (httpbe.AuthenticationScheme) {
// AuthenticationSchemes.Anonymous is the default, ignored.
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 ?
}
#endif
+/*
+// FIXME: this causes invalid message security.
+var mb = message.CreateBufferedCopy (0x10000);
+message = mb.CreateMessage ();
+Console.WriteLine (mb.CreateMessage ());
+*/
+
if (!suppressEntityBody && String.Compare (web_request.Method, "GET", StringComparison.OrdinalIgnoreCase) != 0) {
MemoryStream buffer = new MemoryStream ();
Encoder.WriteMessage (message, buffer);
}
var hrr = (HttpWebResponse) res;
- if ((int) hrr.StatusCode >= 400) {
+ if ((int) hrr.StatusCode >= 400 && (int) hrr.StatusCode < 500) {
channelResult.Complete (new WebException (String.Format ("There was an error on processing web request: Status code {0}({1}): {2}", (int) hrr.StatusCode, hrr.StatusCode, hrr.StatusDescription)));
}
}
ms.Seek (0, SeekOrigin.Begin);
- channelResult.Response = Encoder.ReadMessage (
- //responseStream, MaxSizeOfHeaders);
- ms, MaxSizeOfHeaders, res.ContentType);
+ Message ret = Encoder.ReadMessage (
+ ms, (int) source.Transport.MaxReceivedMessageSize, res.ContentType);
+ var rp = new HttpResponseMessageProperty () { StatusCode = hrr.StatusCode, StatusDescription = hrr.StatusDescription };
+ foreach (var key in hrr.Headers.AllKeys)
+ rp.Headers [key] = hrr.Headers [key];
+ ret.Properties.Add (HttpResponseMessageProperty.Name, rp);
/*
MessageBuffer buf = ret.CreateBufferedCopy (0x10000);
ret = buf.CreateMessage ();
buf.CreateMessage ().WriteMessage (w);
w.Close ();
*/
+ channelResult.Response = ret;
channelResult.Complete ();
}
} catch (Exception ex) {
AsyncCallback callback;
ManualResetEvent wait;
Exception error;
+ object locker = new object ();
+ bool is_completed;
public HttpChannelRequestAsyncResult (Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
- CompletedSynchronously = true;
Message = message;
Timeout = timeout;
this.callback = callback;
AsyncState = state;
-
- wait = new ManualResetEvent (false);
}
public Message Response {
}
public WaitHandle AsyncWaitHandle {
- get { return wait; }
+ get {
+ lock (locker) {
+ if (wait == null)
+ wait = new ManualResetEvent (is_completed);
+ }
+ return wait;
+ }
}
public object AsyncState {
error = error ?? ex;
IsCompleted = true;
- wait.Set ();
if (callback != null)
callback (this);
}
}
public bool IsCompleted {
- get; private set;
+ get { return is_completed; }
+ set {
+ is_completed = value;
+ lock (locker) {
+ if (is_completed && wait != null)
+ wait.Set ();
+ }
+ }
}
public void WaitEnd ()
// FIXME: Do we need to use the timeout? If so, what happens when the timeout is reached.
// Is the current request cancelled and an exception thrown? If so we need to pass the
// exception to the Complete () method and allow the result to complete 'normally'.
-#if NET_2_1 || MONOTOUCH
+#if NET_2_1
// neither Moonlight nor MonoTouch supports contexts (WaitOne default to false)
- bool result = wait.WaitOne (Timeout);
+ bool result = AsyncWaitHandle.WaitOne (Timeout);
#else
- bool result = wait.WaitOne (Timeout, true);
+ bool result = AsyncWaitHandle.WaitOne (Timeout, true);
#endif
if (!result)
throw new TimeoutException ();