//
// System.Net.HttpListenerRequest
//
-// Author:
-// Gonzalo Paniagua Javier (gonzalo@novell.com)
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo.mono@gmail.com)
+// Marek Safar (marek.safar@gmail.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
+// Copyright (c) 2011-2012 Xamarin, Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if NET_2_0 && SECURITY_DEP
+#if SECURITY_DEP
+
+#if MONOTOUCH || MONODROID
+using Mono.Security.Protocol.Tls;
+#else
+extern alias MonoSecurity;
+using MonoSecurity::Mono.Security.Protocol.Tls;
+#endif
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text;
+#if NET_4_0
+using System.Security.Authentication.ExtendedProtection;
+#endif
+#if NET_4_5
+using System.Threading.Tasks;
+#endif
+
namespace System.Net {
public sealed class HttpListenerRequest
{
+#if NET_4_0
+ class Context : TransportContext
+ {
+ public override ChannelBinding GetChannelBinding (ChannelBindingKind kind)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+#endif
+
string [] accept_types;
-// int client_cert_error;
-// bool no_get_certificate;
Encoding content_encoding;
long content_length;
bool cl_set;
bool is_chunked;
bool ka_set;
bool keep_alive;
+ delegate X509Certificate2 GCCDelegate ();
+ GCCDelegate gcc_delegate;
+
static byte [] _100continue = Encoding.ASCII.GetBytes ("HTTP/1.1 100 Continue\r\n\r\n");
internal HttpListenerRequest (HttpListenerContext context)
while (true) {
// TODO: test if MS has a timeout when doing this
try {
- if (InputStream.Read (bytes, 0, length) <= 0)
+ IAsyncResult ares = InputStream.BeginRead (bytes, 0, length, null, null);
+ if (!ares.IsCompleted && !ares.AsyncWaitHandle.WaitOne (1000))
+ return false;
+ if (InputStream.EndRead (ares) <= 0)
return true;
} catch {
return false;
get { return accept_types; }
}
- [MonoTODO ("Always returns 0")]
public int ClientCertificateError {
get {
-/*
- if (no_get_certificate)
- throw new InvalidOperationException (
- "Call GetClientCertificate() before calling this method.");
- return client_cert_error;
-*/
+ HttpConnection cnc = context.Connection;
+ if (cnc.ClientCertificate == null)
+ throw new InvalidOperationException ("No client certificate");
+ int [] errors = cnc.ClientCertificateErrors;
+ if (errors != null && errors.Length > 0)
+ return errors [0];
return 0;
}
}
get { return user_languages; }
}
- public IAsyncResult BeginGetClientCertificate (AsyncCallback requestCallback, Object state)
+ public IAsyncResult BeginGetClientCertificate (AsyncCallback requestCallback, object state)
{
- return null;
+ if (gcc_delegate == null)
+ gcc_delegate = new GCCDelegate (GetClientCertificate);
+ return gcc_delegate.BeginInvoke (requestCallback, state);
}
-#if SECURITY_DEP
+
public X509Certificate2 EndGetClientCertificate (IAsyncResult asyncResult)
{
- return null;
- // set no_client_certificate once done.
+ if (asyncResult == null)
+ throw new ArgumentNullException ("asyncResult");
+
+ if (gcc_delegate == null)
+ throw new InvalidOperationException ();
+
+ return gcc_delegate.EndInvoke (asyncResult);
}
public X509Certificate2 GetClientCertificate ()
{
- // set no_client_certificate once done.
+ return context.Connection.ClientCertificate;
+ }
- // InvalidOp if call in progress.
- return null;
+#if NET_4_0
+ [MonoTODO]
+ public string ServiceName {
+ get {
+ return null;
+ }
+ }
+
+ public TransportContext TransportContext {
+ get {
+ return new Context ();
+ }
+ }
+#endif
+
+#if NET_4_5
+ public bool IsWebSocketRequest {
+ get {
+ string connection = headers.Get ("Connection");
+ if (connection == null || ! connection.Equals ("upgrade", StringComparison.OrdinalIgnoreCase)) {
+ return false;
+ }
+ string upgrade = headers.Get ("Upgrade");
+ if (upgrade == null || ! upgrade.Equals ("websocket", StringComparison.OrdinalIgnoreCase)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public Task<X509Certificate2> GetClientCertificateAsync ()
+ {
+ return Task<X509Certificate2>.Factory.FromAsync (BeginGetClientCertificate, EndGetClientCertificate, null);
}
#endif
}