HttpWebRequest不在POST上发送cookie

时间:2014-05-22 08:07:12

标签: vb.net iis post cookies httpwebrequest

我正在编写一个http模块作为反向代理,即接收来自浏览器的请求,将其发送到目标站点,接收响应并将其发送回浏览器。

除了将浏览器请求中的cookie转发到Post上的目标站点之外,它的工作正常。传出请求中的所有标头和表单数据都是正确的,但不包含任何cookie。

我在浏览器到IIS和传出的httpwebrequest的请求上都运行了fiddler,并证明了这一点。在调试中运行模块表明,在浏览器的请求中找到了cookie并成功放入httpwebrequest的cookiecontainer中,但它们只是没有出现在发送的实际请求中。

如果我(在调试中)将传出请求方法破解为Get,那么它们会继续,但是它们不会用于Post。

我还使用Fiddler跟踪从浏览器直接到目标站点的请求/响应,并且请求在所有三种情况下都是相同的(浏览器到目标,浏览器到我的IIS模块,IIS模块到目标),除了要定位的IIS模块省略了cookie。

这是代码(VB.Net,并在2.0和4.5中尝试过):

' set up the request to the target
Dim reqTarget As System.Net.HttpWebRequest 
reqTarget = CType(System.Net.HttpWebRequest.Create(strTargetURL & strTargetPath & qstring), System.Net.HttpWebRequest)

' copy relevant info, cookies etc from the application request to the target request
CopyAppRequest(application.Context.Request, reqTarget)

' send the request and get the response
Dim rspTarget As System.Net.HttpWebResponse = CType(reqTarget.GetResponse(), System.Net.HttpWebResponse)


Private Sub CopyAppRequest(ByRef reqApp As System.Web.HttpRequest, ByRef reqTarget As System.Net.HttpWebRequest)

    ' copy over the headers
    For Each key As String In reqApp.Headers.AllKeys
        Select Case key
            Case "Host", "Connection", "Content-Length", "Accept-Encoding", "Expect",  "Authorization", "If-Modified-Since"
                ' not sure if we need to process these
            Case "Connection"
                reqTarget.Connection = reqApp.Headers(key)
            Case "Content-Type"
                reqTarget.ContentType = reqApp.Headers(key)
            Case "Accept"
                reqTarget.Accept = reqApp.Headers(key)
            Case "Referer"
                reqTarget.Referer = reqApp.Headers(key)
            Case "User-Agent"
                reqTarget.UserAgent = reqApp.Headers(key)
            Case "Cookie"
                ' do nothing, cookies are handled below..
            Case Else
                reqTarget.Headers.Add(key, reqApp.Headers(key)
        End Select
    Next

    reqTarget.Method = reqApp.HttpMethod
    reqTarget.AllowAutoRedirect = False

    If reqTarget.Method = "POST" Then
        reqTarget.ContentLength = reqApp.ContentLength
        Dim datastream() As Byte = System.Text.Encoding.UTF8.GetBytes(reqApp.Form.ToString)
        reqTarget.ContentLength = datastream.Length
        Dim requestwriter As System.IO.Stream = reqTarget.GetRequestStream
        requestwriter.Write(datastream, 0, datastream.Length)
        requestwriter.Close()
        requestwriter.Dispose()
    End If

    Dim CookieJar As New System.Net.CookieContainer
    reqTarget.CookieContainer = CookieJar

    For Each key As String In reqApp.Cookies.AllKeys
        Dim tgtCookie As New System.Net.Cookie
        With tgtCookie 
            .Name = reqApp.Cookies.Item(key).Name
            .Value = reqApp.Cookies.Item(key).Value
            .Domain = ".domain.com"
            .Path = "/"
            .Expires = DateAdd(DateInterval.Month, 1, System.DateTime.Now)
            .HttpOnly = True
      End With
        CookieJar.Add(tgtCookie)
    Next

End Sub

注意:我想要访问的域名为abc.domain.com(即它是子域名,没有www),我尝试.domain.com表单的原因就是表单用于响应中收到的cookie。我也尝试了其他组合,如abc.domain.com,.abc.domain.com等。此外,我尝试创建一个Uri对象,并使用该方法将cookie添加到cookiecontainer中。

我已经尝试了我能想到的一切,并且可以在论坛上找到......有人有什么建议吗?我怀疑我错过了一些明显的东西!

当然,任何其他关于如何改进上述代码的评论都将受到赞赏。

感谢。

1 个答案:

答案 0 :(得分:3)

好的,我发现了这个问题......

我正在使用Fiddler查看http发生了什么,而且Fiddler是正确的。但是,当我使用Wireshark时,我发现http请求的发送时间比我想象的要早,而且只发布在Post上。

事实证明,requestwriter.write行导致发送http请求,而不是GetResponse(与Get的情况一样)。所以,在requestwriter.write没有被发送之后,我在httpwebrequest中更改了任何内容。

修复 - 我刚刚将所有标题和cookie设置在requestwriter.write之上,并且一切正常。

多么令人沮丧,但至少现在已经修好了:)

如果有人对我是否有错误导致这种情况有任何反馈,请告诉我。