[python-win32] Classic ASP -> Response.Cookies access

Steven Manross steven at manross.net
Sat Oct 26 13:24:24 EDT 2024


Thanks for your tips, Mark!

By looking at  what win32com.client.dynamic._getitem_() does, and handling a call in my invoke_item method, I was able to get the values of the cookie.  I haven’t ventured into _setitem_() yet, but at least this is a break-through and hope this helps someone else on a similar path.

<% @Language="Python"%>
<%
from win32com.client.dynamic import LCID

def invoke_item(self, index):
    # partially taken from code in win32com.client.dynamic._getitem_()

    if self.__dict__["_enum_"] is None:
        self.__dict__["_enum_"] = self._NewEnum()
    if self.__dict__["_enum_"] is not None:
        invkind, dispid = self._find_dispatch_type_("Item")

    if invkind is not None:
        return self._get_good_object_(
            self._oleobj_.Invoke(dispid, LCID, invkind, 1, index)
        )
    else:
        return None

# don’t output anything in your ASP code prior to this or it will fail
Response.AddHeader("Set-Cookie", "MYCOOKIE=TYPE1=sugar&TYPE2=ginger+snap") # correctly sets a cookie

for cookie in Request.Cookies:
    # correctly reads the overall cookie --> TYPE2=ginger+snap&TYPE1=sugar
    Response.Write(f" all cookie data = {Request.Cookies(cookie)}<BR><BR>")

    # tells us there are 2 items in the cookie
    Response.Write(f"cookie count = {Request.Cookies(cookie).Count}<BR><BR>")

    # Shows "TYPE2"
    Response.Write(f"cookie ITEM 1 = {Request.Cookies(cookie).__getitem__(0)}<BR><BR>")
    # Shows "TYPE1"
    Response.Write(f"cookie ITEM 2 = {Request.Cookies(cookie).__getitem__(1)}<BR><BR>")

    # Shows "TYPE2"
    Response.Write(f"cookie Key(1) = {Request.Cookies(cookie).Key(1)}<BR><BR>")
    # Shows "TYPE1"
    Response.Write(f"cookie Key(2) = {Request.Cookies(cookie).Key(2)}<BR><BR>")

    testing = invoke_item(Request.Cookies(cookie), 1)
    # Shows "ginger snap"
    Response.Write(f"cookie TEST 1 using my special invoke_item = {testing}<BR><BR>")
    testing = invoke_item(Request.Cookies(cookie), 2)
    # Shows "sugar"
    Response.Write(f"cookie TEST 2 using my special invoke_item = {testing}<BR><BR>")

this = Request.Cookies("THIS")

methods = ["AddRef", "GetTypeInfo", "GetTypeInfoCount", "HasKeys", "Invoke", "Item", "Key", "QueryInterface"]
for method in methods:
    invkind, dispid = this._find_dispatch_type_(method)
    Response.Write(f" method dispatch type: {method} = {invkind}, {dispid}<BR><BR>")
    # shows:
    # method dispatch type: AddRef = 3, 1610612737
    # method dispatch type: GetTypeInfo = 3, 1610678273
    # method dispatch type: GetTypeInfoCount = 3, 1610678272
    # method dispatch type: HasKeys = 3, 1610743809
    # method dispatch type: Invoke = 3, 1610678275
    # method dispatch type: Item = 3, 0
    # method dispatch type: Key = 3, 1610743812
    # method dispatch type: QueryInterface = 3, 1610612736

# Displays None
Response.Write(f"DEFAULT DISPATCH NAME = {this._olerepr_.defaultDispatchName}<BR><BR>")

# displays all the methods/attributes of the object and helped me create the “method” for loop above
Response.Write(f"this.__dir__() = {this.__dir__()}<BR><BR>")

Response.Write("DONE<BR>")
%>
From: python-win32 <python-win32-bounces+steven=manross.net at python.org> On Behalf Of Steven Manross
Sent: Wednesday, October 23, 2024 9:39 PM
To: Mark Hammond <mhammond at skippinet.com.au>; python-win32 at python.org
Subject: Re: [python-win32] Classic ASP -> Response.Cookies access

Thanks for the response!

Dir gives me this:

dir = ['AddRef', '_oleobj_', '__hash__', 'GetTypeInfo', '_username_', '_FlagAsMethod', '__str__', '__format__', '_wrap_dispatch_', '_enum_', '__call__', '__int__', '_get_good_object_', '_print_details_', 'Invoke', '__sizeof__', 'Key', '_mapCachedItems_', '__setattr__', '_dir_ole_', '__class__', '__subclasshook__', 'Release', '_builtMethods_', '_olerepr_', '__repr__', '_find_dispatch_type_', '__ge__', '__weakref__', 'GetTypeInfoCount', '__dict__', 'GetIDsOfNames', '_proc_', '_get_good_single_object_', '__gt__', '__doc__', '__ne__', 'QueryInterface', '__module__', '_Release_', '__eq__', '__getattribute__', '__le__', '__reduce_ex__', '__delattr__', '__new__', '_NewEnum', '__lt__', '_LazyAddAttr_', '__LazyMap__', '__len__', '_ApplyTypes_', '__dir__', '__bool__', '_lazydata_', '__getattr__', '_make_method_', '__AttrToID__', '__init__', '_unicode_to_string_', 'Count', '__reduce__', '__setitem__', 'Item', '__getitem__', '__init_subclass__', '_UpdateWithITypeInfo_']

I’ll continue to play with the parameters!

Steven
From: python-win32 <python-win32-bounces+steven=manross.net at python.org<mailto:python-win32-bounces+steven=manross.net at python.org>> On Behalf Of Mark Hammond
Sent: Wednesday, October 23, 2024 7:53 PM
To: python-win32 at python.org<mailto:python-win32 at python.org>
Subject: Re: [python-win32] Classic ASP -> Response.Cookies access


On 2024-10-23 7:42 p.m., Steven Manross wrote:
I’m not sure if this is implemented or not in the Python ASP code or not, but I am trying to duplicate some VBS code in Python, and use the URL below as a primer as I couldn’t find any info on the internet about how Python might implement this kind of ASP code.

I know the link is SUPER OLD but it’s the best docs I have been able to find on the subject.

https://learn.microsoft.com/en-us/previous-versions/iis/6.0-sdk/ms524757(v=vs.90)

I am trying to create cookies similar to how the Microsoft Certificate Authority Website on Windows Server 2016/2019/2022 does.

Here’s my Python ASP code
<% @Language="Python"%>
<%
Response.Write("Here<BR>")
for cookie in Response.Cookies:
    Response.Write(Response.Cookies(cookie)["expires"])

Response.Write(f"dir = {Response.Cookies.__dir__()}")

if not "Type" in Response.Cookies:
    cookie = Response.Cookies["type"] = "peanut-butter" # simplistic example of trying to create one

Response.Write("Past Cookie Creation code<BR>")
%>


Here’s my error:

Python ActiveX Scripting Engine error '80020009'

Traceback (most recent call last): File "<Script Block >", line 3, in <module> cookie = Response.Cookies["type"] = "peanut-butter" File "C:\Python310\lib\site-packages\win32com\client\dynamic.py", line 348, in __setitem__ self._oleobj_.Invoke(*allArgs), self._olerepr_.defaultDispatchName, None COM Error: OLE error 0x80020101
/testcookies.asp, line 5

cookie = Response.Cookies["type"] = "peanut-butter"

Any guidance would be appreciated as I’ve scoured google for all it was worth.

Response.Cookies is "just" a dynamic COM object/collection and pywin32 has never been great with them and "magic" things like properties etc due to various semantic mismatches. If you are lucky, there might be a method on the object taking 2 params? I'm guessing `__dir__` didn't help?

Regardless, a last resort would be to unwrap that __setitem__ call and experiment with the correct "DISPATCH_*" flags (and in particular, trying "DISPATCH_METHOD", because the examples are all showing function calls to "set" a value, which python has no concept of!) - the other values are probably correct.

HTH,

Mark

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.python.org/pipermail/python-win32/attachments/20241026/254c96f6/attachment-0001.html>


More information about the python-win32 mailing list