Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# HTTP proxy
Hi All
I have to major the HTTP traffic via proxy, When I try to upload any image or any files  it goes to hang or block. As my observation the StreamReader make it block and it is bind with NetworkStream.
   while (totalBytesRead < contentLen && (bytesRead = clientStreamReader.ReadBlock(postBuffer, 0, contentLen)) > 0)
                    {
                        totalBytesRead += bytesRead;
                        sw.Write(postBuffer, 0, bytesRead);
                        Console.Write(postBuffer, 0, bytesRead);
                    }
Can you help me why it block or Hang?
 
private  void ProxyProcessing(TcpClient client)
        {
         //   client.ReceiveTimeout = 150000;
          //  client.SendTimeout = 150000;
            Stream mainStream = client.GetStream();
            Stream outStream = mainStream; 
            SslStream sslStream = null;
            StreamReader clientStreamReader = new StreamReader(mainStream);
           
            MemoryStream cacheStream = null;            
      
            try
            {
                //read the first line HTTP command
                String httpCmd = clientStreamReader.ReadLine();
                if (String.IsNullOrEmpty(httpCmd))
                {
                    clientStreamReader.Close();
                    mainStream.Close();
                    return;
                }
                //break up the line into three components
                String[] splitBuffer = httpCmd.Split(spaceSplit, 3);
 
                String method = splitBuffer[0];
                String remoteUri = splitBuffer[1];
                Version version = new Version(1, 1);
 
                HttpWebRequest webReq;
                HttpWebResponse response = null;
                if (splitBuffer[0].ToUpper() == "CONNECT")
                {
                    clientStreamReader.Close();
                    mainStream.Close();
                    return;
                }
 
                //construct the web request that we are going to issue on behalf of the client.
                webReq = (HttpWebRequest)HttpWebRequest.Create(remoteUri);
                webReq.Method = method;
                webReq.ProtocolVersion = version;
 
                //read the request headers from the client and copy them to our request
                int contentLen = ReadRequestHeaders(clientStreamReader, webReq);
                
                webReq.Proxy = null;
                webReq.KeepAlive = false;
                webReq.AllowAutoRedirect = false;
                webReq.AutomaticDecompression = DecompressionMethods.None;
        
              
                if (method.ToUpper() == "POST")
                {
                    char[] postBuffer = new char[contentLen];
                    int bytesRead;
                    int totalBytesRead = 0;
                    StreamWriter sw = new StreamWriter(webReq.GetRequestStream());
 
                    while (totalBytesRead < contentLen && (bytesRead = clientStreamReader.ReadBlock(postBuffer, 0, contentLen)) > 0)
                    {                       
                        totalBytesRead += bytesRead;
                        sw.Write(postBuffer, 0, bytesRead);                        
                        Console.Write(postBuffer, 0, bytesRead);
                    }    
                    sw.Close();
                }
                    
                   webReq.Timeout = 15000;
 
                    try
                    {
                        response = (HttpWebResponse)webReq.GetResponse();
                    }
                    catch (WebException webEx)
                    {
                        response = webEx.Response as HttpWebResponse;
                    }
                    if (response != null)
                    {
                        List<Tuple<String,String>> responseHeaders = ProcessResponse(response);
                        StreamWriter myResponseWriter = new StreamWriter(outStream);
                        Stream responseStream = response.GetResponseStream();
                        try
                        {
                            //send the response status and response headers
                            WriteResponseStatus(response.StatusCode,response.StatusDescription, myResponseWriter);
                            WriteResponseHeaders(myResponseWriter, responseHeaders);
 
                            Byte[] buffer;
                            if (response.ContentLength > 0)
                                buffer = new Byte[response.ContentLength];
                            else
                                buffer = new Byte[BUFFER_SIZE];
 
                            int bytesRead;
 
                            while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                if (cacheStream != null)
                                    cacheStream.Write(buffer, 0, bytesRead);
                                outStream.Write(buffer, 0, bytesRead);                             
                            }
 
                            responseStream.Close();                         
 
                            outStream.Flush();
                         
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        finally
                        {
                            responseStream.Close();
                            response.Close();
                            myResponseWriter.Close();
                        }
                    }                
              
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                clientStreamReader.Close();
                mainStream.Close();
                if (sslStream != null)
                    sslStream.Close();
                outStream.Close();              
            }
        }
Posted 23-May-13 5:30am
GAJERA1.8K

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

This is a blocking code indeed, and this blocking is efficient in terms of performance; the thread is put to wait state and will be waken up when data arrives. This is a good thing, not bad. That's why all the communications should be done in a separate thread.
 
—SA
  Permalink  
Comments
GAJERA at 24-May-13 0:45am
   
ok,Why any images or document are not uploaded?
Sergey Alexandrovich Kryukov at 24-May-13 1:06am
   
You can run your code under the debugger and figure this out. Can you do it by yourself?
—SA
GAJERA at 24-May-13 1:15am
   
Can you suggest the other way to read networkStream?
Sergey Alexandrovich Kryukov at 24-May-13 1:23am
   
Why? This is one of the stream classes. All stream classes are read in exact same way. This is a good thing, not bad. Your problem is that you don't want to embrace the idea of blocking calls, which is very efficient. You just need to block the thread and work in other threads in parallel. This is much better then async. API, because you develop your methods of thread synchronization and use them again and again. Unlike async. API, these techniques are not application-specific.
—SA
GAJERA at 24-May-13 1:31am
   
When i read the request http header ,the "content length:24565",but when read StreamReader, ReadBlock API return 23562.Means the less then original one.
Sergey Alexandrovich Kryukov at 24-May-13 1:36am
   
Hm. This would probably be harder to debug...
—SA
GAJERA at 24-May-13 1:44am
   
Without any image or document,the ReadBlock API return the as it original "content length".

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 315
1 Jochen Arndt 190
2 DamithSL 125
3 PIEBALDconsult 110
4 Garth J Lancaster 90
0 OriginalGriff 5,790
1 DamithSL 4,601
2 Maciej Los 4,012
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,195


Advertise | Privacy | Mobile
Web01 | 2.8.141220.1 | Last Updated 23 May 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100