代码之家  ›  专栏  ›  技术社区  ›  Adrian Grigore

正在复制HTTP请求输入流

  •  6
  • Adrian Grigore  · 技术社区  · 16 年前

    我正在实现一个代理操作方法,它将传入的Web请求转发到另一个网页,并添加一些标题。action方法对get请求起作用,但我仍在努力转发传入的post请求。

    问题是我不知道如何正确地将请求体写入传出的HTTP请求流。

    以下是迄今为止我得到的简短版本:

    //the incoming request stream
    var requestStream=HttpContext.Current.Request.InputStream;
    //the outgoing web request
    var webRequest = (HttpWebRequest)WebRequest.Create(url);
    ...
    
    //copy incoming request body to outgoing request
    if (requestStream != null && requestStream.Length>0)
                {
                    long length = requestStream.Length;
                    webRequest.ContentLength = length;
                    requestStream.CopyTo(webRequest.GetRequestStream())                    
                }
    
    //THE NEXT LINE THROWS A ProtocolViolationException
     using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse())
                    {
                        ...
                    }
    

    一旦我对传出的HTTP请求调用GetResponse,就会得到以下异常:

    ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.
    

    我不明白为什么会发生这种情况,因为requeststream.copyto应该负责编写正确数量的字节。

    任何建议都将不胜感激。

    谢谢,

    阿德里安

    3 回复  |  直到 14 年前
        1
  •  13
  •   Brian    15 年前

    是的,.net对此非常挑剔。解决这个问题的方法是两个都冲洗 关闭流。换言之:

    Stream webStream = null;
    
    try
    {
        //copy incoming request body to outgoing request
        if (requestStream != null && requestStream.Length>0)
        {
            long length = requestStream.Length;
            webRequest.ContentLength = length;
            webStream = webRequest.GetRequestStream();
            requestStream.CopyTo(webStream);
        }
    }
    finally
    {
        if (null != webStream)
        {
            webStream.Flush();
            webStream.Close();    // might need additional exception handling here
        }
    }
    
    // No more ProtocolViolationException!
    using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse())
    {
        ...
    }
    
        2
  •  2
  •   Seth    14 年前

    然而,答案@brian有效,我发现一旦调用了requeststream.copyto(stream),它就会触发我的httpwebresponse。这是个问题,因为我还没有准备好发送请求。因此,如果有人对发送的不是所有请求头或其他数据有问题,那是因为CopyTo正在触发您的请求。

        3
  •  1
  •   ajay_whiz    16 年前

    尝试修改if语句内的块

    long length = requestStream.Length;
    webRequest.ContentLength = length;
    requestStream.CopyTo(webRequest.GetRequestStream())
    

    具有

    webRequest.Method = "POST";
    webRequest.ContentLength = requestStream.Length;
    webRequest.ContentType = "application/x-www-form-urlencoded";
    Stream stream = webRequest.GetRequestStream();
    requestStream.CopyTo(stream);
    stream.Close();