[mod_python] how to handle xforms with publisher handler

Graham Dumpleton grahamd at dscpl.com.au
Wed Jan 17 15:48:42 EST 2007


Emiliano Moscato wrote ..
> Hi;
> 
> I've followed my tiny work with FieldStorage.
> I changed the line:
>             boundary = ctype[i+9:]
> for:
>             boundary = ctype[i+9:ctype.find(';',i+9)]
> to fix the problem with boundary.

I don't think this will always work. Where there is no semicolon then the
result would be:

  boundary = ctype[i+9:-1]

This would have the affect of dropping off the last character in the value
which may be part of the boundary tag or the quote which might surround
it.

Graham


> I've tried to use this method without any other change to FieldStorage
> and
> works. I only need this bugfix and it is a good new for me.
> On the other hand, I was thinking about the matter with "application/xml"
> serialize method and the name of the method says all: who uses
> "application/xml" as serialize method waits in the server for an xml
> document, not for its mapping to a dict, and it have nothing to do with
> xforms.
> For example: cherryPy, where I come from, uses the same philosophy of put
> the form fields as attributes of an object, but when it receives an
> "application/xml" puts it available in "threadData" attribute.
> Thanks for the attention :)
> 
> Emiliano
> 
> 2007/1/16, Emiliano Moscato <moski666 at gmail.com>:
> >
> > Hi Graham:
> >
> > The point is that the post method to send xforms give you an xml document
> > with all the xforms data. I understand that it have no sense to make
> a
> > dictionary of the xml document, because the goal is to handle the data
> as an
> > structured xml document.
> > Maybe I am wrong trying to use publisher that makes dictionaries with
> the
> > form data...
> > Regards.
> >
> > Emiliano
> >
> > 2007/1/16, Graham Dumpleton < grahamd at dscpl.com.au>:
> > >
> > > Emiliano Moscato wrote ..
> > > > Hi all:
> > > >
> > > > I've added this few lines to FieldStorage and it works fine for me:
> > > >
> > > >         if ctype.lower() == "application/xml":
> > > >             from xml.dom.minidom import parseString
> > > >             xml = req.read(clen)
> > > >             try:
> > > >                 parseString(xml)
> > > >             except:
> > > >                 raise apache.SERVER_RETURN, apache.HTTP_BAD_REQUEST
> > > >             req.xml = xml
> > > >             return
> > > >
> > > > Is this interesting for a patch?
> > > > Regards
> > > >
> > > > Emiliano
> > >
> > > It doesn't really fit in with what FieldStorage is meant to do which
> is
> > > to
> > > decode a post request and convert form parameters into a dictionary
> > > for use. All your code does is leave the content as an attribute of
> req
> > > for something else to deal with. In essence, all you are doing is
> > > hacking
> > > FieldStorage to get around the limitation described in:
> > >
> > >   http://issues.apache.org/jira/browse/MODPYTHON-29
> > >
> > > If you just want to get around that limitation, you might want to
> > > instead
> > > look at 'vampire::publisher' from:
> > >
> > >   http://www.dscpl.com.au/projects/vampire/
> > >
> > > Vampire contains a distinct implementation of publisher which does
> not
> > > have  the limitation and so in your published function you would be
> > > able to simply do:
> > >
> > >   def index(req):
> > >     if req.headers_in ['Content-Type'] == 'application/xml':
> > >       ...
> > >
> > > This will work because 'vampire::publisher' doesn't error when content
> > > type
> > > doesn't equate to something FieldStorage can't handle, instead it just
> > > lets
> > > the function deal with it.
> > >
> > > For any change to FieldStorage to be accepted in this area, it would
> > > have
> > > to properly decode any xforms POST into key/value lists as appropriate
> > > and
> > > populate the FieldStorage data structure. That is if that makes sense
> as
> > > I
> > > haven't looked at what is in an xforms POST and whether it is equivalent
> > > to normal form POST but just a different format.
> > >
> > > Graham
> > >
> > > > 2007/1/12, Graham Dumpleton < grahamd at dscpl.com.au>:
> > > > >
> > > > > If you are using mod_python 3.2.10 or earlier, try 3.3.0b as it
> has
> > > some
> > > > > fixesto FieldStorage class. Can be downloaded from:
> > > > >
> > > > >   http://httpd.apache.org/modules/python-download.cgi
> > > > >
> > > > > I suspect though that it still will not work though, as code is:
> > > > >
> > > > >         # figure out boundary
> > > > >         try:
> > > > >             i = ctype.lower().rindex("boundary=")
> > > > >             boundary = ctype[i+9:]
> > > > >             if len(boundary) >= 2 and boundary[0] == boundary[-1]
> ==
> > >
> > > > '"':
> > > > >                 boundary = boundary[1:-1]
> > > > >             boundary = re.compile("--" + re.escape(boundary) +
> > > > > "(--)?\r?\n")
> > > > >
> > > > > Ie., it assumes that boundary is last field on content type line
> > > which
> > > > is
> > > > > a
> > > > > bad assumption.
> > > > >
> > > > > Graham
> > > > >
> > > > > On 13/01/2007, at 8:41 AM, Emiliano Moscato wrote:
> > > > >
> > > > > Hi all!
> > > > >
> > > > > Thanks for your answers.
> > > > > I've been looking the code of FieldStorage and publisher. I think
> it
> > > > is
> > > > > not soo dificult to patch FieldStorage, but: Is anybody else
> > > interested
> > > > in
> > > > > patch FieldStorage? If so I'll try it on monday.
> > > > >
> > > > > On the other hand, I've trying to use another method to send my
> > > xforms
> > > > > which uses "multipart/related" as Content-type and I realized that
> > > mozilla
> > > > > xforms plugin sends a boundary that is bad handled by
> > > > > publisher-FieldStorage. This is what browser sends:
> > > > >
> > > > > [...]
> > > > > Content-Length: 522
> > > > > Content-Type: multipart/related;
> > > > > boundary=---------------------------13592280651221337293469391600;
> > > > > type="application/xml"; start="<4c599da9.58c746e8 at mozilla.org >"
> > > > > Cookie: lang=1
> > > > >
> > > > > -----------------------------13592280651221337293469391600
> > > > > Content-Type: application/xml
> > > > > Content-ID: < 4c599da9.58c746e8 at mozilla.org>
> > > > >
> > > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > > <idioma xmlns:xf="http://www.w3.org/2002/xforms " xmlns:ev="
> > > http://www.w3.org/2001/xml-events"
> > > > > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance " xmlns:xsd="
> > > http://www.w3.org/2001/XMLSchema
> > > > > ">
> > > > >
> > > > >       <H__interface>main</H__interface>
> > > > >       <idioma>adadsfasd</idioma>
> > > > >     </idioma>
> > > > > -----------------------------13592280651221337293469391600--
> > > > >
> > > > >
> > > > > But FieldStorage parse the content-type line up to the end trying
> to
> > > > get
> > > > > boundary, getting this as boundary:
> > > > > -----------------------------7393760691212604279930853199;
> > > > > type="application/xml"; start="< b8f2849.19571884 at mozilla.org>
> > > > >
> > > > > Is this a firefox problem or a FieldStorage problem?
> > > > > Regards, enjoy the weekend :)
> > > > >
> > > > > Emiliano
> > > > >
> > > > >
> > > > > 2007/1/12, Jim Gallacher <jpg at jgassociates.ca>:
> > > > > >
> > > > > > Graham Dumpleton wrote:
> > > > > > > Jim Gallacher wrote ..
> > > > > > >> Emiliano Moscato wrote:
> > > > > > >>> Hi all!
> > > > > > >>>
> > > > > > >>> I'm getting crazy trying to receive xforms xml data with
> > > mod_python
> > > > > > +
> > > > > > >>> publisher handler.
> > > > > > >
> > > > > > > In what way are you using mod_python.publisher? Depending to
> > > what
> > > > > > > degree you are using it, mod_python 3.3 offers some alternate
> > > > > > mechanisms
> > > > > > > for doing basic dispatch against different resources which
> might
> > > > be
> > > > > > more
> > > > > > > useful and allow you to still access content of response to
> > > decode
> > > > it.
> > > > > > >
> > > > > > >>> In a normal HTML form, the data would be sent as
> > > > > > >>> application/x-www-form-urlencoded, in the XForms world
> > > however,
> > > > this
> > > > > >
> > > > > > >>> information is sent as XML formatted data (application/xml).
> > > > > > >>> Up to now I've used cherryPy as web server and I've got my
> xml
> > > > data
> > > > > > with
> > > > > > >>> cherrypy.threadData.xform.
> > > > > > >>> I've read that PHP receive this in $HTTP_RAW_POST_DATA
> > > variable.
> > > > If
> > > > > > I
> > > > > > >> send
> > > > > > >>> the form to a php script all work fine.
> > > > > > >>> But when I try to submit a xforms with method POST to a script
> > > > > > managed
> > > > > > >> by
> > > > > > >>> publisher handler I get an error with no log in my apache
> > > server
> > > > > > error
> > > > > > >> log.
> > > > > > >>> Any help?
> > > > > > >> You'll need to elaborate on the error you are getting, but
> I
> > > think
> > > > > > part
> > > > > > >> of the problem is that you are bumping up against part of
> the
> > > > > > internal
> > > > > > >> "magic" of publisher.
> > > > > > >>
> > > > > > >> Publisher automatically creates a FieldStorage instance.
> > > > > > Unfortunately
> > > > > > >> FieldStorage assumes that the content-type starts with either
> > > > > > >> "application/x-www-form-urlencoded" or "multipart/". If I
> had
> > > to
> > > > > > guess
> > > > > > >> I'd say that you are getting "501 Not Implemented error" as
> a
> > > result.
> > > > > >
> > > > > > >>
> > > > > > >> Here are a couple of solutions that you might consider as
> a
> > > > > > workaround:
> > > > > > >>
> > > > > > >> 1. Hack util.FieldStorage to properly handle your content-type.
> > > > If
> > > > > > you
> > > > > > >> do this feel free to submit a patch so FieldStorage can be
> > > fixed.
> > > > ;)
> > > > > > >
> > > > > > > Hmmm, xforms is quite different.
> > > > > > >
> > > > > > >   http://www.w3.org/TR/xforms/
> > > > > > >
> > > > > > > Looks like a lot of work.
> > > > > >
> > > > > > Probably. I certainly wasn't offering to do it. ;)
> > > > > >
> > > > > > >> 2. Hack publisher to skip the automatic creation of
> > > FieldStorage.
> > > > > > (Line
> > > > > > >> 424 in publisher.py for mod_python 3.3.0b). You can then use
> > > req.read
> > > > > > ()
> > > > > > >> to read and process the POST'd data within your content
> > > handler.
> > > > > > >
> > > > > > > I've raised this issue before about publisher not being able
> to
> > > accept
> > > > > > other
> > > > > > > content types. See:
> > > > > > >
> > > > > > >   http://issues.apache.org/jira/browse/MODPYTHON-29
> > > > > > >
> > > > > > > Also, like PSP now does, publisher could be made to use '
> > > req.form'
> > > > if
> > > > > > it
> > > > > > > already existed. This would allow a stacked response handler
> > > before
> > > > > > > publisher to decide whether some other form content was
> > > supplied,
> > > > > > decode
> > > > > > > it and set req.form to a compatible class to FieldStorage.
> I
> > > don't
> > > > > > know that I
> > > > > > > have created an issue for that idea before, but have certainly
> > > thought
> > > > > > > about it and perhaps mentioned it on the mailing list.
> > > > > >
> > > > > > That seems like a reasonable solution.
> > > > > >
> > > > > > >> 3. Use a PythonFixupHandler before the content handler. In
> the
> > > > > > >> fixuphandler use req.read() to grab the raw data and adjust
> the
> > > > > > >> content-type header so that FieldStorage doesn't bomb out.
> Note
> > > > that
> > > > > > if
> > > > > > >> you want to pass xml field data as parameters to your handler
> > > method
> > > > > > >> you'll need to do a bit more work. For example
> > > > > > >>
> > > > > > >> def index(foo="bar"):
> > > > > > >>      return "whatever"
> > > > > > >>
> > > > > > >> won't get foo from your xml data. You can likely work around
> > > this
> > > > but
> > > > > > >> you'll need to take a look at the source for FieldStorage
> and
> > > > > > publisher
> > > > > > >> to work out a strategy.
> > > > > > >
> > > > > > > If you are talking about modifying the input stream, an input
> > > filter
> > > > > > would
> > > > > > > perhaps be better. Not sure that that will help since xforms
> is
> > > quite
> > > > > > > different and isn't just a matter of changing content type.
> > > > > >
> > > > > > No, I was just thinking you could get the raw data with req.read()
> > > > > > (parsing the xml or whatever) and then set the content-type to
> > > > > > application/x-www-form-urlencoded. That way the subsequent call
> to
> > > > > > FieldStorage within publisher won't bomb out. The code would
> look
> > > > > > something like this:
> > > > > >
> > > > > > def fixuphandler(req):
> > > > > >      if req.headers_in.has_key("content-type"):
> > > > > >          ctype = req.headers_in ["content-type"]
> > > > > >          if ctype.startswith("application/xml"):
> > > > > >              req.data = parse_the_xml_data_or_whatever(req.read())
> > > > > >              req.headers_in ["content-type"] =
> > > > > >                       "application/x-www-form-urlencoded"
> > > > > >      return apache.OK
> > > > > >
> > > > > > A little too hackish perhaps? (Assuming it would even work).
> > > > > >
> > > > > > Jim
> > > > > > _______________________________________________
> > > > > > Mod_python mailing list
> > > > > > Mod_python at modpython.org
> > > > > > http://mailman.modpython.org/mailman/listinfo/mod_python
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > mOsKi
> > > > > "No hay nada que uno haga mal , lo que hay es poco vino." Autor
> > > Anonimo
> > > > > _______________________________________________
> > > > > Mod_python mailing list
> > > > > Mod_python at modpython.org
> > > > > http://mailman.modpython.org/mailman/listinfo/mod_python
> > > > >
> > > > >
> > > > >
> > > >
> > > >
> > > > --
> > > > mOsKi
> > > > "No hay nada que uno haga mal , lo que hay es poco vino." Autor
> > > Anonimo
> > >
> >
> >
> >
> > --
> > mOsKi
> > "No hay nada que uno haga mal , lo que hay es poco vino." Autor Anonimo
> >
> 
> 
> 
> -- 
> mOsKi
> "No hay nada que uno haga mal , lo que hay es poco vino." Autor Anonimo


More information about the Mod_python mailing list