Closed (won't fix)
Project:
Services
Version:
6.x-3.3
Component:
Code
Priority:
Normal
Category:
Task
Assigned:
Reporter:
Created:
28 Jul 2011 at 21:16 UTC
Updated:
6 Jun 2013 at 00:09 UTC
Jump to comment: Most recent file
New to drupal, please let me know if I should open this up under the rest_server project. I am not sure if the http://drupal.org/project/rest_server is obsoleted now that rest_server is a sub project of services. (also the rest_server project page show no mention of a 7.x version).
I am also having some issues updating documents so I was unable to fully test whether the patch works in the grand scheme of things. The impl seems pretty straight forward though and I run into the same issues with the application/json mime type (i.e. it might just be me).
Please let me know if this works.
Comments
Comment #1
iphands commentedI got around to making a working test using PUT and XML. So the patch does fully work.
Comment #2
marcingy commentedSetting to normal as this is a feature.
Comment #3
marcingy commentedComment #4
marcingy commentedYuri can you review this as I don't really feel that I have the knowledge too.
Comment #5
kylebrowning commentediphands, can you supply the test in your patch and re-roll?
Comment #6
mradcliffeIt would be nicer if the patch had some error checking with libxml_get_errors(). It should also have the same for text/xml, not just application/xml.
Another question: how does json_encode and json_decode handle XML element attributes (text)?
Here's basically what I have been using for a custom xml parser. Some things would be different in the latest version of Services 3.0, but I am still stuck using RC3 because of the session bug.
This would probably be better (code morphed from a custom xml parser I have):
Comment #7
iphands commentedkylebrowning, sorry. It sounds like you were expecting that my test was a PHP unit test. The test I wrote to prove the patch does work is not a unit test but rather a functional test from a client (using curl as a client and bash as the language).
Here is the test that I was using. It basically uses curl to:
- authenticate
- store cookies
- fetch the node via an http GET and expecting XML from the server
- modify the XML retrieved (change the title)
- change the node that exists by supplying the modified XML via an http PUT command
Please let me know if this helps.
Comment #8
cotto commentediphands, what's the reason for round-tripping the data through json?
Comment #9
cotto commentedHere's a 6.x version that implements mradcliffe's suggestions without the roundtrip through json. I hate that none of the current request parsers do error checking (I'm looking at you, json) and don't see the benefit of continuing that trend. I'll need xml request parsing for work (no idea why they'd want it, but there are better battles) so once a consensus starts to form around the right fix, I can put together a 7.x version and tests.
Comment #10
kylebrowning commentedIm fin with this, lets see a 7.x version.
Comment #11
cotto commentedHere's a direct port to 7.x-3.x, though without any tests. It also might be appropriate to either conditionally enable the xml parser if libxml is present or to check for libxml in hook_requirements.
Comment #12
ygerasimov commented@cotto I think conditionally enable xml parser is very good idea. Also we would need documentation update that if you would like to use XML parser please make sure libxml is available.
Regarding tests, lets have it similar way like ServicesParserTests::testJSONCall() test does.
Comment #13
iphands commentedWow! Thanks guys, I disappear for a bit and this thing continues to make progress. In response to cotto, the only reason for round tripping through JSON is that the JSON to PHP array conversion is/was a known supported conversion (it is what was already being used in the json content-type handler). I looked for a direct XML to PHP array method, but could not find such a thing. I figured it would more bug free to convert XML to JSON via a known good method, then JSON to PHP array via a known good method than to roll something myself.
aka. I am a PHP/Drupal n00b :-)
Here is one thing that have noticed when enabling XML support (it does not really make a difference which patch I try if I recall correctly (currently I am using the patch proovided in comment #11)).
Certain data structures within Drupal do not get serialized or unserialized correctly (I am not sure which one). Please bear with me as I try to coherently express the issue.
Lets say I do a GET on /node/123 with the "Accept: application/json" header set, and in the response I notice the following:
In a PUT with "Content-Type: application/json" if I wish to modify the value of this field I use this in the request payload:
I would expect that using XML in the GET and PUT would behave similarly, but alas it does not.
For example, a GET "Accept: application/xml" on the same node would give a response with the following:
But if I PUT "Content-Type: application/xml" with this in my payload:
I see no change on the node.
To debug this I have used the following patch:
What I find is that the $form_state Array in the working example (JSON) looks like this:
But using the non working example (XML) the $form_state Array looks as follows:
I hope my explanation makes sense. Can anyone offer some insight here? Also, this issue seems to only affect feilds where the value is an array.
Would this be an issue with the serialization in the first reponse? or an issue with deserialization in the resulting request?
Thanks,
-Ian Page Hands
Comment #14
mradcliffeYour serialization issue has to do with the XML result formatter, not the XML request parser. It is escaping tags that may not be valid. You can customize how results are formatted to change this behavior. For instance, I wrap data that I found like this in CDATA tags (I have to format nested XML documents :*( ).
In terms of request parsing, I think everyone writes their own XML to Array parser at some point (there's even one on the PHP SimpleXML manual page). I did so that I could handle those XML attributes in a specific way per my own Rest API.
Comment #15
iphands commentedCan you elaborate here or restate this? I don't quite grok the explanation, but I think it is due to my own lack of experience with the issue at hand.
Thanks.
Comment #16
iphands commentedI wonder about this statement.
The thing is, after this code is run (RESTServer.inc->parseRequest()):
I think (but I am not sure) the $data that is returned is Content-Type agnostic.
i.e. no matter which content-type is choosen parseRequest() should return a similar data structure.
Right?
And if that is true, I can't see what XML would ever result in an array like:
I would always get arrays like:
And the second array is not acceptable.
Am I right in my assumption? or again, am I missing something.
Comment #17
iphands commentedFor what it is worth I came up with and am using this patch for servers/rest_server/includes/RESTServer.inc
The patch correctly unmarshals the XML so that Services accepts the same style/format of XML payload that Services sends down.
Please let me know if this is not the desired solution, or if there is some bug in the algorithm.
Thanks,
-Ian Page Hands
Comment #18
kylebrowning commentedi don't mind the patch, but it needs a lot of work.
Theres watchdog statements that run regardless of if the endpoint is in the debug mode, and you have really commented anything your doing.
Does this require libxml be enabled for php/apache and if so, there needs to be a hook_requirements change if this option is enabled for any endpoint.
Comment #19
mradcliffeYes, SimpleXML itself requires libxml to be enabled. This is a default configuration option for PHP so it should be on most servers out there (including Windows). I don't think that it's necessary to have this in hook_requirements for this reason.
I'm going to take a look at this a bit more in depth and compare it to my own custom parser.
Comment #20
iphands commentedD'OH that watchdog statement was left over from development / unintentional. Here is a new patch without the debug statements and commented code.
Comment #21
kylebrowning commented6.x patch please then we will commit.
Comment #22
ygerasimov commentedComment #23
hypertext200This is the patch with protected on
unmarshalXMLsince in case of altering data.Comment #25
hypertext200#23 with do-not-test flag.
Comment #26
hypertext200#20, #23 and #25 has some issue when we have one or more elements in a field. So here is the structure of node.xml.
Patch attached.
Comment #27
hypertext200Fixed the issue with checkboxes. For the checkboxes we need to send XML as below.
Comment #29
kylebrowning commented#27: 1232984-services-xml-parser-27.diff queued for re-testing.
Comment #30
kylebrowning commentedComment #31
klokie commentedI've re-rolled the patch from #27 for 6.x-3.x.
Comment #33
marcingy commentedDrupal 6 is no longer supported