* HttpClientChannel.cs: Changed text for user-agent header (removed references
authorLluis Sanchez <lluis@novell.com>
Fri, 22 Aug 2003 14:09:48 +0000 (14:09 -0000)
committerLluis Sanchez <lluis@novell.com>
Fri, 22 Aug 2003 14:09:48 +0000 (14:09 -0000)
  to MS.NET).
  Removed try/catch from AsyncProcessRequest. If there is an exception it must
  flow to the caller.
  in AsyncRequestHandler, improved management of exceptions. HttpWebRequest
  throws an exception if the result code is 400, 500. Is is not a communication
  error, but an application or server error. The content of the body must be
  deserialized like in normal responses.
  In CreateWebRequest, if the stream being sent is a MemoryStream, use a more
  efficient way of writing the content.
  In SendAndRecieve, same as in AsyncRequestHandler. Also moved some code to a
  new method named ReceiveResponse, so it can be reused from AsyncRequestHandler.
* HttpHelper.cs: Removed some debugging code that is not needed.
* HttpServer.cs: Improved formatting of some code.
  In CheckRequest method, send a 100-continue response if the request has
  the header: expect:100-continue.
  Method SendResponse: the remoting formatter may include the result code and
  reason phrase to use in the transport headers. Used them if provided.
* HttpServerChannel.cs: Use ThreadPool to create the thread that will answer
  a request.

svn path=/trunk/mcs/; revision=17515

mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/ChangeLog [new file with mode: 0644]
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/HttpClientChannel.cs
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/HttpHelper.cs
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/HttpServer.cs
mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/HttpServerChannel.cs

diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/ChangeLog b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Http/ChangeLog
new file mode 100644 (file)
index 0000000..2b9ff52
--- /dev/null
@@ -0,0 +1,34 @@
+2003-08-22  Lluis Sanchez Gual <lluis@ximian.com>
+
+       * HttpClientChannel.cs: Changed text for user-agent header (removed references
+         to MS.NET).
+         Removed try/catch from AsyncProcessRequest. If there is an exception it must
+         flow to the caller.
+         in AsyncRequestHandler, improved management of exceptions. HttpWebRequest
+         throws an exception if the result code is 400, 500. Is is not a communication
+         error, but an application or server error. The content of the body must be
+         deserialized like in normal responses.
+         In CreateWebRequest, if the stream being sent is a MemoryStream, use a more
+         efficient way of writing the content.
+         In SendAndRecieve, same as in AsyncRequestHandler. Also moved some code to a
+         new method named ReceiveResponse, so it can be reused from AsyncRequestHandler.
+       * HttpHelper.cs: Removed some debugging code that is not needed.
+       * HttpServer.cs: Improved formatting of some code.
+         In CheckRequest method, send a 100-continue response if the request has
+         the header: expect:100-continue.
+         Method SendResponse: the remoting formatter may include the result code and
+         reason phrase to use in the transport headers. Used them if provided.
+       * HttpServerChannel.cs: Use ThreadPool to create the thread that will answer
+         a request.
+
+2003-08-18  Lluis Sanchez Gual <lluis@ximian.com>
+
+       * HttpClientChannel.cs, HttpServerChannel.cs: Fixed bug #47703
+
+2003-06-21  Lluis Sanchez Gual <lluis@ximian.com>
+
+       * HttpChannel.cs, HttpClientChannel.cs, HttpHelper.cs, HttpServer.cs,
+         HttpServerChannel.cs, HttpThread.cs: added new implementation of the HttpChannel
+         by Ahmad Tantawy, Ahmad Kadry and Hussein Mehanna.
+       * unix.args: added HttpHelper.cs,HttpServer.cs,HttpThread.cs.
+
index d58cf9dab0aae12c59c9a9ae9c5839760c5a8107..8e43472700d82411c3577cd60df54c5e1e3d3865 100644 (file)
@@ -28,11 +28,6 @@ using System.Text;
 
 namespace System.Runtime.Remoting.Channels.Http
 {
-
-
-
-
-
        public class HttpClientChannel : IChannelSender,IChannel
        {
                // Property Keys (purposely all lower-case)
@@ -252,8 +247,7 @@ namespace System.Runtime.Remoting.Channels.Http
                private const String s_defaultVerb = "POST";
 
                private static String s_userAgent =
-                       "Mozilla/4.0+(compatible; MSIE 6.0; Windows " + 
-                       "; MS .NET Remoting; MS .NET CLR " + System.Environment.Version.ToString() + " )";
+                       "Mono Remoting Client (Mono CLR " + System.Environment.Version.ToString() + ")";
         
                // Property keys (purposely all lower-case)
                private const String UserNameKey = "username";
@@ -306,8 +300,6 @@ namespace System.Runtime.Remoting.Channels.Http
                        ITransportHeaders requestHeaders, Stream requestStream,
                        out ITransportHeaders responseHeaders, out Stream responseStream)
                {
-                       
-
                        string url = null;
                        string uri = (string)requestHeaders[CommonTransportKeys.RequestUri];
                        CreateUrl(uri,out url);
@@ -321,22 +313,14 @@ namespace System.Runtime.Remoting.Channels.Http
                public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg,
                        ITransportHeaders headers, Stream stream)
                {
-                       try
-                       {
-                               string url = null;
-                               string uri = (string)headers[CommonTransportKeys.RequestUri];
-                               CreateUrl(uri,out url);
-
-                               HttpWebRequest httpWebRequest = CreateWebRequest(url,headers,stream);
-                               RequestState reqState = new RequestState(httpWebRequest,sinkStack);
+                       string url = null;
+                       string uri = (string)headers[CommonTransportKeys.RequestUri];
+                       CreateUrl(uri,out url);
 
-                               httpWebRequest.BeginGetResponse(new AsyncCallback(AsyncRequestHandler),reqState);
+                       HttpWebRequest httpWebRequest = CreateWebRequest(url,headers,stream);
+                       RequestState reqState = new RequestState(httpWebRequest,sinkStack);
 
-                       }
-                       catch
-                       {
-                               Console.WriteLine("Error Sending Async Request");
-                       }
+                       httpWebRequest.BeginGetResponse(new AsyncCallback(AsyncRequestHandler),reqState);
                }
 
                private void AsyncRequestHandler(IAsyncResult ar)
@@ -345,36 +329,29 @@ namespace System.Runtime.Remoting.Channels.Http
 
                        RequestState reqState = (RequestState) ar.AsyncState;
                        HttpWebRequest httpWebRequest = reqState.webRquest;
+                       IClientChannelSinkStack sinkStack = reqState.sinkStack;
 
                        try
                        {
                                httpWebResponse = (HttpWebResponse) httpWebRequest.EndGetResponse(ar);
-                               
-                               Stream responseStream ;
-                               ITransportHeaders responseHeaders;
-
-                               IClientChannelSinkStack sinkStack = reqState.sinkStack;
+                       }
+                       catch (WebException ex)
+                       {
+                               httpWebResponse = ex.Response as HttpWebResponse;
+                               if (httpWebResponse == null) sinkStack.DispatchException (ex);
+                       }
 
-                               responseStream = new MemoryStream();
-                               HttpHelper.CopyStream(httpWebResponse.GetResponseStream(),ref responseStream);
-                       
-                       
-                               responseHeaders = new TransportHeaders();
-                       
-                               for(int i=0; i < httpWebResponse.Headers.Count; ++i)
-                                       responseHeaders[httpWebResponse.Headers.Keys[i].ToString()] = httpWebResponse.Headers[i].ToString();
+                       Stream responseStream;
+                       ITransportHeaders responseHeaders;
 
-                               sinkStack.AsyncProcessResponse(responseHeaders,responseStream);
-                                       
-                       }
-                       catch
+                       try
                        {
-                               Console.WriteLine("Error Recieving Async Response");
+                               ReceiveResponse (httpWebResponse, out responseHeaders, out responseStream);
+                               sinkStack.AsyncProcessResponse(responseHeaders,responseStream);
                        }
-                       finally
+                       catch (Exception ex)
                        {
-                               if(httpWebResponse!=null)
-                                       httpWebResponse.Close();        
+                               sinkStack.DispatchException (ex);
                        }
                }
 
@@ -533,10 +510,6 @@ namespace System.Runtime.Remoting.Channels.Http
 
                private HttpWebRequest CreateWebRequest(string url, ITransportHeaders requestHeaders, Stream requestStream)
                {
-
-                       
-
-                       
                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);;
                        request.AllowAutoRedirect = _bAllowAutoRedirect;
                        request.ContentLength = requestStream.Length;
@@ -575,57 +548,74 @@ namespace System.Runtime.Remoting.Channels.Http
                        }
 
                        Stream reqStream = request.GetRequestStream();
-                       HttpHelper.CopyStream(requestStream,ref reqStream);
-                       
+                       if (requestStream is MemoryStream)
+                       {
+                               MemoryStream memStream = (MemoryStream)requestStream;
+                               reqStream.Write (memStream.GetBuffer(), 0, (int)memStream.Length);
+                       }
+                       else
+                               HttpHelper.CopyStream(requestStream, reqStream);
+
                        reqStream.Close();
                        
                        return request;
                }       
         
-               private bool SendAndRecieve(HttpWebRequest httpRequest,out ITransportHeaders responseHeaders,out Stream responseStream)
+               private void SendAndRecieve(HttpWebRequest httpRequest,out ITransportHeaders responseHeaders,out Stream responseStream)
                {
                        responseStream = null;
                        responseHeaders = null;
                        HttpWebResponse httpWebResponse = null;
 
-                       bool returnValue = false;
-
-
                        try
                        {
                                httpWebResponse = (HttpWebResponse)httpRequest.GetResponse();
+                       }
+                       catch (WebException ex)
+                       {
+                               httpWebResponse = ex.Response as HttpWebResponse;
+                               if (httpWebResponse == null) throw ex;
+                       }
 
-                               responseStream = new MemoryStream();
-                               HttpHelper.CopyStream(httpWebResponse.GetResponseStream(),ref responseStream);
+                       ReceiveResponse (httpWebResponse, out responseHeaders, out responseStream);
+               }
 
+               private void ReceiveResponse (HttpWebResponse httpWebResponse, out ITransportHeaders responseHeaders, out Stream responseStream)
+               {
+                       responseHeaders = new TransportHeaders();
+
+                       try
+                       {
+                               Stream webStream = httpWebResponse.GetResponseStream();
+
+                               if (httpWebResponse.ContentLength != -1)
+                               {
+                                       byte[] buffer = new byte [httpWebResponse.ContentLength];
+                                       int nr = 0;
+                                       while (nr < buffer.Length)
+                                               nr += webStream.Read (buffer, nr, buffer.Length - nr);
+                                       responseStream = new MemoryStream (buffer);
+                               }
+                               else
+                               {
+                                       responseStream = new MemoryStream();
+                                       HttpHelper.CopyStream(webStream, responseStream);
+                               }
 
-                               responseHeaders = new TransportHeaders();
-                               
-                               
                                //Use the two commented lines below instead of the 3 below lines when HttpWebResponse
                                //class is fully implemented in order to support custom headers
                                //for(int i=0; i < httpWebResponse.Headers.Count; ++i)
                                //      responseHeaders[httpWebResponse.Headers.Keys[i].ToString()] = httpWebResponse.Headers[i].ToString();
-                               
+
                                responseHeaders["Content-Type"] = httpWebResponse.ContentType;
                                responseHeaders["Server"] = httpWebResponse.Server;
                                responseHeaders["Content-Length"] = httpWebResponse.ContentLength;
-                       
-                               returnValue =true;
                        }
-                       catch(Exception e)
-                       {
-                               
-                               Console.WriteLine(e);
-                               returnValue = false;
-                       }
-
                        finally
                        {
                                if(httpWebResponse!=null)
-                                       httpWebResponse.Close();                        
+                                       httpWebResponse.Close();
                        }
-                       return returnValue;
                }
 
                private void ProcessErrorCode()
index 400f27908a60af1242fc6e4ee2113de72146c038..5cde8444f9f75cfd8dd5ac3252e574fd10e5640d 100644 (file)
@@ -22,7 +22,6 @@ namespace System.Runtime.Remoting.Channels.Http
 {
        internal class HttpHelper
        {
-               public static int d;
                public static string Parse(string URL , out string ObjectURI)
                {
 
@@ -39,9 +38,9 @@ namespace System.Runtime.Remoting.Channels.Http
                                Pos = URL.IndexOf("/",0);
                        }
 
-                       if(Pos>0 || Pos == 0)
+                       if(Pos >= 0)
                        {
-                               ObjectURI = URL.Substring(Pos);
+                               ObjectURI = URL.Substring(Pos + 1);
                                return URL.Substring(0,Pos);
                        }
                        return URL;
@@ -82,32 +81,21 @@ namespace System.Runtime.Remoting.Channels.Http
                        
                        return outStream;
                }
-               public static bool CopyStream(Stream inStream,ref Stream outStream)
+               public static bool CopyStream(Stream inStream, Stream outStream)
                {
                        int  temp;
-                       d++;
+
                        try
                        {
-                               FileStream f=null;
-                               if(d==2)
-                                       f = new FileStream("f.txt",System.IO.FileMode.Create);
-
                                while(true)
                                {
                                        temp = inStream.ReadByte();
-                    
-                                       
-                                       if(d==2)
-                                               f.WriteByte((byte)temp);
-                                               
-                                       
+                                                                               
                                        if(temp==-1)
                                                break;
                                        outStream.WriteByte((byte)temp);
                                }
                                
-                               if(d==2)
-                               f.Close();
                                outStream.Flush();
                                
                                if(outStream.CanSeek)
index e4d2c2c5f84c0a3d5a08e445ed64d02f460f72ac..64577e879d7e637818f7c5d6cf59327e22d07238 100644 (file)
@@ -60,11 +60,9 @@ namespace System.Runtime.Remoting.Channels.Http
                
                public static void ProcessRequest(object Object)
                {
-                       
                        if(Object as RequestArguments == null)
                                return;
 
-
                        Socket socket;
                        HttpServerTransportSink snk;
 
@@ -73,40 +71,30 @@ namespace System.Runtime.Remoting.Channels.Http
                        socket = reqArg.socket;
                        snk = reqArg.snk;
                                
-                        if(!socket.Connected)
-                                       return;
-
-                               //Step (1) Start Reciceve the header
-                               ArrayList  Headers = RecieveHeader(socket);
-                               
-                               
-                               //Step (2) Start Parse the header
-                               IDictionary HeaderFields = new Hashtable();
-                               IDictionary CustomHeaders = new Hashtable();
-                               if(!ParseHeader(socket,Headers,HeaderFields,CustomHeaders))
-                                       return;
-                       
-
-
-
-                               //Step (3)
-                           if(!CheckRequest(socket,HeaderFields,CustomHeaders))
-                                       return;
-
+                       if(!socket.Connected)
+                               return;
 
-                               //Step (4) Recieve the entity body
-                               byte [] buffer =new byte[(int)HeaderFields["content-length"]];
-                               if(!RecieveEntityBody(socket,buffer))
-                                       return ;
-                               
+                       //Step (1) Start Reciceve the header
+                       ArrayList  Headers = RecieveHeader(socket);
                                
+                       //Step (2) Start Parse the header
+                       IDictionary HeaderFields = new Hashtable();
+                       IDictionary CustomHeaders = new Hashtable();
+                       if(!ParseHeader(socket,Headers,HeaderFields,CustomHeaders))
+                               return;
 
-                               //Step (5)
+                       //Step (3)
+                       if(!CheckRequest(socket,HeaderFields,CustomHeaders))
+                               return;
 
-                           if(! SendRequestForChannel(socket,snk,HeaderFields,CustomHeaders,buffer))
-                                       return ;
+                       //Step (4) Recieve the entity body
+                       byte [] buffer =new byte[(int)HeaderFields["content-length"]];
+                       if(!RecieveEntityBody(socket,buffer))
+                               return ;
 
-       
+                       //Step (5)
+                   if(! SendRequestForChannel(socket,snk,HeaderFields,CustomHeaders,buffer))
+                               return ;
                }
 
                private static ArrayList RecieveHeader(Socket socket)
@@ -117,8 +105,6 @@ namespace System.Runtime.Remoting.Channels.Http
                        byte[] buffer = new byte[1024];
                        ArrayList  Headers = new ArrayList();
 
-
-
                        int index =0;
                        while(!bLastLine)
                        { 
@@ -154,8 +140,6 @@ namespace System.Runtime.Remoting.Channels.Http
                                        continue;
                        Headers.Add( Encoding.ASCII.GetString(buffer,0,index));
 
-                               
-
                        }//end while loop
                        
                        return Headers;
@@ -194,6 +178,9 @@ namespace System.Runtime.Remoting.Channels.Http
                 return false;
                        }
 
+                       if (HeaderFields["expect"].ToString() == "100-continue")
+                               SendResponse(socket,100,null,null);
+
                        //Check for the content-length field
                        if(HeaderFields["content-length"]==null)
                        {
@@ -206,11 +193,8 @@ namespace System.Runtime.Remoting.Channels.Http
                
                private static bool RecieveEntityBody(Socket socket, byte[] buffer)
                {
-                       
-
                        try
                        {
-                               //Recieved = socket.Receive(buffer,0,buffer.Length,SocketFlags.None);
                                int nr = 0;
                                while (nr < buffer.Length)
                                        nr += socket.Receive (buffer, nr, buffer.Length - nr,SocketFlags.None);
@@ -235,14 +219,10 @@ namespace System.Runtime.Remoting.Channels.Http
        
                private static bool SendRequestForChannel(Socket socket ,HttpServerTransportSink snk ,IDictionary HeaderFields , IDictionary CustomHeaders, byte[]buffer)
                {
-
-
                        TransportHeaders THeaders = new TransportHeaders();
 
-
                        Stream stream = new MemoryStream(buffer);
 
-
                        if(stream.Position !=0)
                                stream.Seek(0,SeekOrigin.Begin);
 
@@ -282,19 +262,26 @@ namespace System.Runtime.Remoting.Channels.Http
                        byte [] headersBuffer = null;
                        byte [] entityBuffer = null;
 
-                       StringBuilder ResponseStr ;             
+                       StringBuilder ResponseStr;
                        String Reason = GetReasonPhrase(HttpStatusCode);
 
+                       if (headers != null && headers["__HttpStatusCode"] != null) {
+                               // The formatter can override the result code
+                               HttpStatusCode = int.Parse ((string)headers["__HttpStatusCode"]);
+                               Reason = (string)headers["__HttpReasonPhrase"];
+                       }
                        
                        //Response Line 
-                       ResponseStr = new StringBuilder( "HTTP/1.1 " + HttpStatusCode.ToString() + " " + Reason + "\r\n" );
+                       ResponseStr = new StringBuilder( "HTTP/1.0 " + HttpStatusCode + " " + Reason + "\r\n" );
                        if(headers!=null)
                                foreach(DictionaryEntry entry in headers)
                                {
-                                       ResponseStr.Append(entry.Key.ToString()+": "+entry.Value.ToString()+"\r\n");
+                                       string key = entry.Key.ToString();
+                                       if (key != "__HttpStatusCode" && key != "__HttpReasonPhrase")
+                                               ResponseStr.Append(key + ": " + entry.Value.ToString() + "\r\n");
                                }
                        
-                       ResponseStr.Append("Server: MS .NET Remoting, MS .NET CLR 1.0.3705.0\r\n");
+                       ResponseStr.Append("Server: Mono Remoting, Mono CLR " + System.Environment.Version.ToString() + "\r\n");
 
                        if(responseStream != null)
                        if(responseStream.Length!=0)
@@ -343,7 +330,7 @@ namespace System.Runtime.Remoting.Channels.Http
                {
                        switch (HttpStatusCode)
                        {
-                               case 100 : return " Continue" ;
+                               case 100 : return "Continue" ;
                                case 101  :return "Switching Protocols";
                                case 200  :return "OK";
                                case 201  :return "Created";
index 076662d824e73e6c3bea7eef75d90bf4ec4534dc..c3bcf6a87a51100a86cfbb46914cb976425c9a23 100644 (file)
@@ -150,8 +150,6 @@ namespace System.Runtime.Remoting.Channels.Http
                        if(_sinkProvider == null)
                                _sinkProvider = new SoapServerFormatterSinkProvider();
 
-                       
-                       
                        // collect channel data from all providers
                        IServerChannelSinkProvider provider = _sinkProvider;
                        while (provider != null) 
@@ -163,7 +161,6 @@ namespace System.Runtime.Remoting.Channels.Http
                        // create the sink chain
                        IServerChannelSink snk = 
                                ChannelServices.CreateServerChannelSinkChain(_sinkProvider,this);
-                       
 
                        _transportSink = new HttpServerTransportSink(snk);
 
@@ -181,8 +178,7 @@ namespace System.Runtime.Remoting.Channels.Http
                        {
                                Socket socket = _tcpListener.AcceptSocket();
                                RequestArguments reqArg = new RequestArguments(socket,_transportSink);
-                               HttpThread httpThread = new HttpThread(reqArg);
-                       
+                               ThreadPool.QueueUserWorkItem (new WaitCallback (HttpServer.ProcessRequest), reqArg);
                        }
 
                } 
@@ -197,14 +193,11 @@ namespace System.Runtime.Remoting.Channels.Http
                                ThreadStart t = new ThreadStart(this.Listen);
                                _listenerThread = new Thread(t);
                                _listenerThread.IsBackground = true;
-
                        }
                        
                        if(!_listenerThread.IsAlive)
                                _listenerThread.Start();
                        
-                       
-                       
                        _bListening = true;
                } 
 
@@ -212,6 +205,7 @@ namespace System.Runtime.Remoting.Channels.Http
                {
                        if( _bListening)
                        {
+                               _listenerThread.Abort ();
                                _tcpListener.Stop();
                        }
 
@@ -371,7 +365,7 @@ namespace System.Runtime.Remoting.Channels.Http
                        ITransportHeaders responseHeaders;
                        Stream responseStream;
 
-                       ServerProcessing processing= ServerProcessing.Complete;
+                       ServerProcessing processing = ServerProcessing.Complete;
                        try
                        {
                                processing =
@@ -379,8 +373,6 @@ namespace System.Runtime.Remoting.Channels.Http
                                        out responseMessage,
                                        out responseHeaders, out responseStream);
 
-
-                       
                                switch (processing)
                                {                    
                                        case ServerProcessing.Complete:
@@ -405,10 +397,7 @@ namespace System.Runtime.Remoting.Channels.Http
                        catch(Exception )
                        {
                        }
-
-} 
-      
-
+               }
 
 
                //