Read cookies from URL

[quote=188038:@Peter Job]OK sorry. If, say, on Win the HTMLViewer is based on MSIE, would the cookies not be where MSIE stores them? Likewise whatever you are calling to browse? I am sure there is code to unpack the obtuse file names used.

Or do I still misunderstand?[/quote]
Ah, well yeah, you could do that, but it’s generally not done. I honestly don’t know how or where those cookie files are stored any more.

I am sure the location and indexing would vary terribly. Not something I would try to do.

Getting the cookies on OSX/iOS is fairly straightforward… here’s a function I just threw together (just for fun)… it returns an array of dictionaries populated with the cookie data for a given URL or all cookies if URL is empty.

[code]Private Function CookiesForURL(url as text="") As Dictionary()
#if TargetMacOS or TargetIOS
declare function NSClassFromString lib “Foundation” (classname as CFStringRef) as ptr

//NSArray
Declare Function count lib "Foundation" selector "count" (class_ref as ptr) as integer  //returns number of items in array
Declare Function objectAtIndex lib "Foundation" selector "objectAtIndex:" (class_ref as ptr, index as integer) as ptr //gets an object from the array
//NSURL
Declare Function URLWithString lib "Foundation" selector "URLWithString:" (class_ref as ptr,url as CFStringRef) as ptr
//HTTPCookieStorage
Declare Function sharedHTTPCookieStorage lib "Foundation" selector "sharedHTTPCookieStorage" (class_ref as ptr) as ptr
Declare Function cookies lib "Foundation" selector "cookies" (class_ref as ptr) as ptr  //returns an nsarray of nshttpcookies
Declare Function cookiesForURL lib "Foundation" selector "cookiesForURL:" (class_ref as ptr,url as ptr) as ptr
//properties of an NSHTTPCookie
Declare Function path lib "Foundation" selector "path" (class_ref as ptr) as CFStringRef
Declare Function domain lib "Foundation" selector "domain" (class_ref as ptr) as CFStringRef
Declare Function expiresDate lib "Foundation" selector "expiresDate" (class_ref as ptr) as ptr
Declare Function name lib "Foundation" selector "name" (class_ref as ptr) as CFStringRef
Declare Function value lib "Foundation" selector "value" (class_ref as ptr) as CFStringRef
Declare Function sessionOnly lib "Foundation" selector "isSessionOnly" (class_ref as ptr) as Boolean
//NSDate
Declare Function timeIntervalSince1970 lib "Foundation" selector "timeIntervalSince1970" (class_ref as ptr) as Double



dim cookiesArray as ptr

if url="" then
  cookiesArray=cookies(sharedHTTPCookieStorage(NSClassFromString("NSHTTPCookieStorage")))
else
  cookiesArray=cookiesForURL(sharedHTTPCookieStorage(NSClassFromString("NSHTTPCookieStorage")),URLWithString(NSClassFromString("NSURL"),url))
end if

dim myCookies() as Dictionary
for i as integer=0 to count(cookiesArray)-1
  dim nextCookie as new Dictionary
  dim cookiePtr as ptr=objectAtIndex(cookiesArray,i)
  
  nextCookie.Value("name")=name(cookiePtr)
  nextCookie.Value("value")=value(cookiePtr)
  nextCookie.Value("path")=path(cookiePtr)
  nextCookie.Value("domain")=domain(cookiePtr)
  nextCookie.Value("sessionOnly")=sessionOnly(cookiePtr)
  
  dim expiresDate as new xojo.Core.Date(timeIntervalSince1970(expiresDate(cookiePtr)),xojo.core.TimeZone.Current)
  nextCookie.Value("expiresDate")=expiresDate
  myCookies.Append nextCookie
next

Return myCookies()

#endif
End Function

[/code]

Here’s a chunk for win32 to get the cookie data for a url. I’m not sure how to parse it, so I’ll leave that for you.

[code] #elseif TargetWin32

declare Function InternetGetCookieW lib "Wininet" (url as WString, name as ptr, data as ptr, byref size as integer) as Boolean

dim size as integer

if InternetGetCookieW(url,nil,nil,size) then
  dim data As new MemoryBlock(size)
  if InternetGetCookieW(url,nil,data,size) then
    dim res as String=data
    break
  end if
end if

declare function GetLastError lib "Kernel32" () as integer
dim err as integer=GetLastError

#endif[/code]

Thanks,

is this the right way to use your method?

if I, for example, call Google I get Exception on first s.Append (on other pages not)
Project Example

Sub DocumentComplete(URL as String)
  dim myDictionary() As Dictionary
  dim s() as string
  dim t as text = URL.ToText
  
  myDictionary = CookiesForURL(t)
  
  For i As integer = 0 to myDictionary.Ubound-1
    s.Append myDictionary(i).Key(i).StringValue
    s.Append ": "
    if myDictionary(i).HasKey("value") then
      s.Append myDictionary(i).Value("value").StringValue + eof + eof
    end if
    if myDictionary(i).HasKey("path") then
      s.Append myDictionary(i).Value("path").StringValue + eof + eof
    end if
    if myDictionary(i).HasKey("domain") then
      s.Append myDictionary(i).Value("domain").StringValue + eof + eof
    end if
    if myDictionary(i).HasKey("sessionOnly") then
      s.Append myDictionary(i).Value("sessionOnly").StringValue + eof + eof
    end if
    ///// not working - Exception
    // if myDictionary(i).HasKey("expiresDate") then
    // s.Append myDictionary(i).Value("expiresDate").StringValue + eof + eof
    // end if
  Next
  
  lbl.Text = Join(s, "")
  
  Exception err as KeyNotFoundException
    MsgBox "You tried to access a nonexistent item!"
End Sub

“i” is your iterator for the number of cookies rather than the number of keys. As soon as i >4 you’ll get an exception.

Thanks,

I changed one line in your method( added ‘.ToText’), now expiresDate works

nextCookie.Value(“expiresDate”)=expiresDate.ToText

the working version

[code]Sub DocumentComplete(URL as String)
dim myDictionary() As Dictionary
dim s() as string
dim t as text = URL.ToText

redim myDictionary(-1)
redim s(-1)

myDictionary = CookiesForURL(t)

For i As integer = 0 to myDictionary.Ubound-1
if myDictionary(i).HasKey(“name”) then
s.Append "name: "
s.Append myDictionary(i).Value(“name”).StringValue + eof + eof
end if
if myDictionary(i).HasKey(“value”) then
s.Append "value: "
s.Append myDictionary(i).Value(“value”).StringValue + eof + eof
end if
if myDictionary(i).HasKey(“path”) then
s.Append "path: "
s.Append myDictionary(i).Value(“path”).StringValue + eof + eof
end if
if myDictionary(i).HasKey(“domain”) then
s.Append "domain: "
s.Append myDictionary(i).Value(“domain”).StringValue + eof + eof
end if
if myDictionary(i).HasKey(“sessionOnly”) then
s.Append "sessionOnly: "
s.Append myDictionary(i).Value(“sessionOnly”).StringValue + eof + eof
end if
if myDictionary(i).HasKey(“expiresDate”) then
s.Append "expiresDate: "
s.Append myDictionary(i).Value(“expiresDate”).StringValue + eof + eof
end if
Next

lbl.Text = Join(s, “”)

Exception err as KeyNotFoundException
MsgBox “You tried to access a nonexistent item!”
End Sub[/code]

eof is method for EndOfLine

Function eof() As string return EndOfLine End Function

[quote=188083:@jim mckay]Here’s a chunk for win32 to get the cookie data for a url. I’m not sure how to parse it, so I’ll leave that for you.
[/quote]

That is very interesting, thanks. Only if you use MSIE I assume? I doubt Firefox and Chrome have any leanings towards Wininet.

That would be my assumption. And I would guess only with safari on mac/ios. Would need to do more research to see if it is reliable with Chrome and Firefox (but I would bet not).

Looks like Chrome stores an SQLite database of cookies…
where-does-chrome-store-its-cookie-file

Firefox does the same, but in it’s own location.
cookies-information-websites-store-on-your-computer

You should be able to access the contents from inside Xojo with little effort.

Ok Its fine, With this I can get the Value that was looking for. But I only can see one cookie. Is there a way to see all cookies?

Currently not.