Announcement

Collapse
No announcement yet.

Easy way to read a cookie contents

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Easy way to read a cookie contents

    Hello everyone,

    I was wondering if there is an easy way to read a cookies contents. For example I set a cookie..

    <MvEVAL EXPR="{miva_output_header('Set-Cookie','name=peter')}">
    <MvEVAL EXPR="{miva_output_header('Set-Cookie','color=red')}">

    But the only means by which I can see to access the cookies contents is the s.http_cookie variable but that only returns the following...

    name=peter; color=red

    Is there an easier way of accessing the cookies contents (The s.http_cookie variable does not have any arrays or branches) or do I need to get creative with the gettoken() function?

    Many thanks for any assistance anyone can provide.
    Last edited by keffa; 12-01-13, 06:00 PM. Reason: Typo

    #2
    Re: Easy way to read a cookie contents

    There is a built in function in the lib/util.mvc. You can view it in the Limited Source Kit (http://www.mivamerchant.com/support/downloads) in the /lib/util_public.mv file. The function name is called ParseCookies.

    This will do the heavy lifting for you so you don't have to parse them yourself.
    Brennan Heyde
    VP Product
    Miva, Inc.
    [email protected]
    https://www.miva.com

    Comment


      #3
      Re: Easy way to read a cookie contents

      Yes, you need to create a loop to iterate through s.http_cookie with gettoken().

      The basic pseudo-code would be

      l.pos = 1
      l.cookie = gettoken( s.http_cookie, ';', l.pos )
      while len( l.cookie )
      assign l.array[l.pos]:name = gettoken( l.cookie, '=', 1 )
      assign l.array[l.pos]:value = gettoken( l.cookie, '=', 2 )

      l.pos = l.pos + 1
      l.cookie = gettoken( s.http_cookie, ';', l.pos )
      /while

      You can get fancier, change how things are stored, etc but that's the general idea.

      Comment


        #4
        Re: Easy way to read a cookie contents

        Thanks guys. Rather odd Miva doesn't pre-populate an environment variable with the cookie fields for you though. Suggestion for the next version maybe?

        Comment


          #5
          Re: Easy way to read a cookie contents

          Miva does do this for you automatically in the page templates.

          There is a global variable called g.request_cookies:cookiename which has the each cookie already parsed out for you.
          Brennan Heyde
          VP Product
          Miva, Inc.
          [email protected]
          https://www.miva.com

          Comment


            #6
            Re: Easy way to read a cookie contents

            Keffa,

            Well, it sort of does via the s.http_cookie...but since cookies can contain a variety of information and to some degree format, would be kind of hard to have a normalized variable/array containing all available cookie data. AFAIK, this is the same basic way you'd read cookies in javascript and php...

            But like Brennen said about Merchant having an 'api' for this in Merchant, creating a library of common procedures would be a pretty cool effort for us all to use on non-Merchant mivascript projects.
            Bruce Golub
            Phosphor Media - "Your Success is our Business"

            Improve Your Customer Service | Get MORE Customers | Edit CSS/Javascript/HTML Easily | Make Your Site Faster | Get Indexed by Google | Free Modules | Follow Us on Facebook
            phosphormedia.com

            Comment


              #7
              Re: Easy way to read a cookie contents

              I think I have discovered a bug!! At least I think it's a bug, it might be an intended limitation.

              Consider the following script, it's about as simple as it gets...

              <MIVA STANDARDOUTPUTLEVEL = "html, text, compresswhitespace">
              <MvEVAL EXPR="{miva_output_header('Set-Cookie','name=peter')}">
              <MvEVAL EXPR="{miva_output_header('Set-Cookie','age=old')}">
              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml">
              <head>
              <title> new document </title>
              </head>
              <body>
              <MvEVAL EXPR="{ s.http_cookie }">
              </body>
              </html>


              Now what should happen is that two cookies get set, one with the crumb 'name' and the other with the crumb 'old' and it should display in the browser as...

              1 1 name=peter; age=old

              Except it doesn't. You get this instead...

              1 1 age=old

              It will only set 1 cookie with the the last crumb you specify in the code, in this case its 'age'. The weird thing is you still get a '1' returned to show that the other crumbs where set, even though they weren't.

              This initially got me to thinking that this was a limitation on the part of Mivascript, limiting you to setting one cookie per output. However, very occasionally the script will perform as expected and set both cookies. Also, enabling the htscallerid cookie will make this script perform as expected more often, but not reliably so.

              So...bug? Or limitation? If it is a limitation is the fact you can occasionally set more than one cookie also a bug LOL? :)

              Comment


                #8
                Re: Easy way to read a cookie contents

                Originally posted by keffa View Post
                I think I have discovered a bug!! At least I think it's a bug, it might be an intended limitation.

                Consider the following script, it's about as simple as it gets...

                <MIVA STANDARDOUTPUTLEVEL = "html, text, compresswhitespace">
                <MvEVAL EXPR="{miva_output_header('Set-Cookie','name=peter')}">
                <MvEVAL EXPR="{miva_output_header('Set-Cookie','age=old')}">
                <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                <html xmlns="http://www.w3.org/1999/xhtml">
                <head>
                <title> new document </title>
                </head>
                <body>
                <MvEVAL EXPR="{ s.http_cookie }">
                </body>
                </html>


                Now what should happen is that two cookies get set, one with the crumb 'name' and the other with the crumb 'old' and it should display in the browser as...

                1 1 name=peter; age=old

                Except it doesn't. You get this instead...

                1 1 age=old

                It will only set 1 cookie with the the last crumb you specify in the code, in this case its 'age'. The weird thing is you still get a '1' returned to show that the other crumbs where set, even though they weren't.

                This initially got me to thinking that this was a limitation on the part of Mivascript, limiting you to setting one cookie per output. However, very occasionally the script will perform as expected and set both cookies. Also, enabling the htscallerid cookie will make this script perform as expected more often, but not reliably so.

                So...bug? Or limitation? If it is a limitation is the fact you can occasionally set more than one cookie also a bug LOL? :)
                Would you believe all of the above?

                I did a lot of testing of cookies a few months ago, so while I know a lot about this, it's been a while so I may be suffering from post-trauma bad memory.

                1. You can set more than one cookie at a time, but you can only have one 'Set-Cookie' header. By making two statements, you overwrite the first with the second.
                2. You cannot set a cookie, and read it from the same load. Most likely, the "setting" doesn't happen until all the s.* variables are set. So first Empresa gets and sets all s.*, then it processes the page. The only exception I can think of is time_t. There is a s.time_t which holds the UNIX time_t value when the page starts and a s.dyn_time_t which gets refreshed as the page executes.

                Given those two factors, your results are completely expected.
                - Each EVAL returns ones, because it did set the Header. But you are setting the same variable; just like if you set x = 1, then x = 2. Both assignments work, but 2 overwrote 1.
                - The cookie you are seeing is actually most likely from a previous attempt to load the page. A better test would be first clear all site cookies then load your page. You should only see "1 1" for both Set-Cookies but no s.http_cookie. If you load it again, you'll see "1 1 age=old" as the cookie was set on the last load and can be displayed on this load.
                - the htscallerid is a special cookie set by Empresa that was/is used by Merchant from the very beginning. It's similar to PHP's $_SESSION.

                There are basically four functions you'll need for handling cookies:
                1) GetCookies() - Loads in and parses all existing cookies. Preferably into a structure for easy retrieval.
                2) BakeCookie() - Formats a string for adding/updating a cookie
                3) EatCookie() - Formats a string for deleting/expiring a cookie (To delete a cookie, you update the value to "" and/or the expiration date to something in the past)
                4) SetCookie() - Takes the strings from 2 & 3 and combines them into a single 'Set-Cookie' header.

                After building those, create a test page:
                a) read all cookies
                b) look for two cookies, val1 and val2
                c) if val2 exists, eat it. if val2 does not exist, bake it
                d) update val1 to something random, time_t, or something else so you can see change
                e) set the cookies
                f) display the string for making the cookie
                g) display the read-in cookie structure

                As you refresh, val1 will keep changing and val2 will pop in and out of existence. You can get a feel for how cookies work by watching the string and the cookies that exist.

                Hope this puts you in the right direction!

                Comment


                  #9
                  Re: Easy way to read a cookie contents

                  Hi Scott,

                  I'm aware that the cookies crumb string will not show in the s.http_cookie variable until the page has been reloaded or on the next load, this is the same as pretty much every other web scripting language out there, I forgot to mention that the page would need to be reloaded to see the expected results.

                  However, the issue is not so much when the cookies crumb string gets populated and appears in the s.http_cookie variable. It's that it only shows the last crumb to be set in the code when you have in fact specified two. If as you say, this is a limitation of Miva and the miva_output_header() function being overwritten then there isn't actually an issue (Save for the fact that sometimes you ARE able to store two crumbs at once which may be a bug).

                  However I would argue that this limitation is somewhat puzzling. As per the RFC it is perfectly acceptable to set more than one crumb per page load, cookies are set by the server sending one crumb per header. So something like this...

                  HTTP/1.0 200 OK
                  Content-type: text/html
                  Set-Cookie: name=value
                  Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 13:00:00 GMT


                  (content of page)


                  Per the RFC, each crumb must be a separate header so the below header wont work (Or shouldn't, I haven't managed to get it to work either)...

                  Set-Cookie: name=value; name2=value2; Expires=Wed, 09 Jun 2021 13:00:00 GMT

                  It would therefore be logical that to set multiple crumbs you would send several miva_output_header() strings as each crumb needs to be on a separate header much as you would per PHP, etc. However if each miva_output_header() you send overwrites the previous one, I can't see a way of setting more than one cookie per page unless someone can enlighten me on a clever way of coding it?

                  Obviously there are workarounds but one feels there shouldn't have to be. :)
                  Last edited by keffa; 12-04-13, 01:09 PM.

                  Comment

                  Working...
                  X