Page 1 of 1

WinHttpRequest Object with Cookies

Posted: 01 Mar 2014, 16:24
by Bruttosozialprodukt
I did a lot of research on cookies and how they are sent and received etc to make this happen and I think it works as it should. I haven't really tested it though. So it would be cool if you would try it out and share your experience. :)
You need my functions SaveCookies() and SetCookies() and provide a variable in which the cookies can be stored.
Let me explain it by this example:

Code: Select all

cookies := Object() ;the variable in which the cookies are going to be stored in
WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")

WebRequest.Open("GET", "http://google.com") ;If you want to send the cookies from this domain that are in the cookies variable you have to call SetCookies now:
SetCookies(WebRequest, cookies) ;The first parameter is the variable to which we intialized the WinHttpRequest object, the second parameter is the variable from which we will read our cookies.

WebRequest.Send() ;If you want to save the cookies for this request, you have to call SaveCookies now:
SaveCookies(WebRequest, cookies) ;The first parameter is the variable to which we intialized the WinHttpRequest object, the second parameter is the variable to which we will add our new cookies.
The functions:

Code: Select all

SaveCookies(ByRef WebRequest, ByRef cookies) {
    While (p := RegexMatch(WebRequest.GetAllResponseHeaders, "U)(^|\R)Set-Cookie:\s(.+)=(.+);.+domain=(.+)(\R|;|$)", match, p?p+1:1))
        cookies[match4, match2] := match3
}

SetCookies(ByRef WebRequest, ByRef cookies) {
    url := WebRequest.Option(1) ;the url that we are going to send our request to
    If (p := InStr(url,"://"))
        url := SubStr(url, p+3)
    If (p := InStr(url,"/"))
        url := SubStr(url, 1, p-1)
    If (p := InStr(url,"@"))
        url := SubStr(url, p+1)
    If (p := InStr(url,":"))
        url := SubStr(url, 1, p-1)
    StringSplit, a, url, .
    b := a0-1
    domain := a%b%
    ext := a%a0%
    url := "." . domain . "." . ext
    
    cookieString := ""
    For id, value in cookies[url]
        cookieString .= id . "=" . value . "; "
    
    If (cookieString) ;if there are any cookies
        WebRequest.SetRequestHeader("Cookie", cookieString)
}
Todo:
Automatically remove cookies that expired.

Re: WinHttpRequest Object with Cookies

Posted: 02 Mar 2014, 00:08
by magusneo
Good.It works.
How about make it Class style?

Re: WinHttpRequest Object with Cookies

Posted: 02 Mar 2014, 18:48
by Bruttosozialprodukt
I'm not so much into OOP. I haven't created classes in AHK so far.
May I ask what the advantage would be? Maybe an example of usage imagining that we'd have my functions as a class?

Re: WinHttpRequest Object with Cookies

Posted: 03 Mar 2014, 05:27
by magusneo
Class!=OOP,Class can simplify some coding.

like this

Code: Select all

wq:=new WebReq()
wq.WebRequest.Open("GET", "http://google.com")
wq.SetCookies()
wq.WebRequest.Send()
wq.SaveCookies()
wq:=""  ;cookies be removed
return

class WebReq{
    cookies:={},WebRequest:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
    __New(){
    }
    __Delete(){
    }
    SetCookies(){
        url := this.WebRequest.Option(1) ;the url that we are going to send our request to
        If (p := InStr(url,"://"))
            url := SubStr(url, p+3)
        If (p := InStr(url,"/"))
            url := SubStr(url, 1, p-1)
        If (p := InStr(url,"@"))
            url := SubStr(url, p+1)
        If (p := InStr(url,":"))
            url := SubStr(url, 1, p-1)
        StringSplit, a, url, .
        b := a0-1
        domain := a%b%
        ext := a%a0%
        url := "." . domain . "." . ext
        
        cookieString := ""
        For id, value in this.cookies[url]
            cookieString .= id . "=" . value . "; "
        
        If (cookieString) ;if there are any cookies
            this.WebRequest.SetRequestHeader("Cookie", cookieString)
    }
    SaveCookies(){
        While (p := RegexMatch(this.WebRequest.GetAllResponseHeaders, "U)(^|\R)Set-Cookie:\s(.+)=(.+);.+domain=(.+)(\R|;|$)", match, p?p+1:1))
            this.cookies[match4, match2] := match3
    }
}

Re: WinHttpRequest Object with Cookies

Posted: 31 Jul 2020, 12:39
by hisrRB57
Hi,

I hope you are still active in this forum.
I have tested the script and discovered that the script finds the following cookies:
1P_JAR
NID

However when I open google.com in my browser after I have cleaned the cookies from the browser history I get the following list:
ANID
CGIC
CONSENT
NID
SNID

and the browser also display additional data:
Content
Domain
Path
Send for
Created
Expires

I have two questions:

1) Can you clarify the difference in the list of cookies.
2) Can you enhance the script so that additional info is also retrieved.

Hoping on an answer soon.
Kind regards,

HisrRB57

Re: WinHttpRequest Object with Cookies

Posted: 29 Sep 2020, 15:39
by Bruttosozialprodukt
Sorry, unfortunately I have switched to Linux a long time ago. So no more AHK for me.

Using my script you only get the cookies that the exact URL you are opening returns.
In your browser when you open google.com, it automatically loads a shit ton of images, scripts, css files and fonts and for every single of these files that google forces your browser to load, more cookies can be set. In addition to that cookies can also be set during runtime using JavaScript.
The only way for you to get all the cookies is to subsequently request all the URLs that load cookies in your browser. And maybe you even have to manually take care of cookies that are being set through JS directly... probably not though.

To find out which URLs are setting cookies in your browser, open a new tab, press F12, click the network tab and then go to google.com.
gg.png
gg.png (94.6 KiB) Viewed 1906 times