doctrine / orientdb-odm

A set of PHP libraries in order to use OrientDB from PHP
http://odino.org/blog/categories/orientdb/
MIT License
155 stars 54 forks source link

Object value contains '%' sign in class property throws exception in response #158

Open tomcyr opened 11 years ago

tomcyr commented 11 years ago

If any object value contains '%' sign in property, response throws Exception because OrientDB REST API cannot parse url. Any ideas except str_replace('%', '', $value) ??

nrk commented 11 years ago

Could you post a small snippet to reproduce the issue please?

tomcyr commented 11 years ago

My Entity Example class:


namespace ConceptIt\SmartShopperBundle\Entity;

use Doctrine\ODM\OrientDB\Mapper\Annotations as ODM;

/**
* @ODM\Document(class="Test")
*/
class Test
{
    /**
     * @ODM\Property(name="@rid", type="string")
     */
    protected $rid;

    /**
     * @ODM\Property(type="string")
     */
    protected $name;

    public function getRid() {
        return $this->rid;
    }

    public function setRid($rid) {
        $this->rid = $rid;

        return $this;
    }

    public function getName() {
        return $this->name;
    }

    public function setName($name) {
        $this->name = $name;

        return $this;
    }
}

and my Action:

     /**
     * @Route("/api/test")
     */
    public function indexAction()
    {
        $manager = $this->container->get('odm');
        $test = new \ConceptIt\SmartShopperBundle\Entity\Test();
        $test->setName('Johny Walker 40%');
        $manager->persist($test);
        var_dump($test);die;
     }

and I have this exception: java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: ""," 500 Internal Server Error - InvalidQueryException

But if I only do:

        $test->setName('Johny Walker 40');

I have dump: object(ConceptIt\SmartShopperBundle\Entity\Test)#407 (2) { ["rid":protected]=> string(5) "#14:0" ["name":protected]=> string(15) "Johny Walker 40" }

So the problem is in '%' sign. I'm using my persist method for manager from https://github.com/doctrine/orientdb-odm/pull/155

odino commented 11 years ago

Can you check if using urlencode in the toJson method would solve the issue?

nrk commented 11 years ago

I believe this is a bug in OrientDB. It feels just wrong to see a class named URLDecoder throwing an exception like that when we have the % symbol in the JSON payload being sent within the body of the POST request.

I did a quick test using the demo database and the command line curl:

curl --user admin:admin http://127.0.0.1:2480/document/demo -X POST -d '{ "name": "Milano %", "@class": "City" }'

And I get the same error:

java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "","

If I remove the % symbol then the POST request completes successfully by returning the RID for the new record. The same behaviour can be reproduced when updating an existing record.

Ping @lvca, should we move this one to a new issue on OrientDB?

odino commented 11 years ago

thanks @nrk for the deep analysis :)

nrk commented 11 years ago

Now I'm completely sure this is a bug in OrientDB (and probably a bad one at that) since it seems to treat JSON payload as if it was encoded as application/x-www-form-urlencoded, that's what java.net.URLDecoder is made for after all.

If you try with these two basic examples you will get wrong data stored in the database:

I will file a bug later.

odino commented 11 years ago

@nrk any news?

nrk commented 11 years ago

@odino no, I lost track of the time and forgot to provide details on the OrientDB mailing list before filing a bug report :-) Will do that when I'm back at the end of the month.

AaronSchulz commented 9 years ago

Be sure to set "Content-Type: application/json" when POSTing. I was running into % errors before when I forgot to do that.