Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Cache put parameters in CHttpRequest getRestParams method #173

Closed
qiangxue opened this Issue Feb 15, 2012 · 3 comments

Comments

4 participants
Owner

qiangxue commented Feb 15, 2012

Hello,

My request is to cache the PUT parameters of a request.

CURRENT IMPLEMENTATION

The way the PUT parameters are currently being read is by parsing the php://input stream (see the implementation (http://code.google.com/p/yii/source/browse/tags/1.1.8/framework/web/CHttpRequest.php#199))

According to the php documentation regarding the php://input stream, this stream can be read only once (pay attention to the NOTE section in the php documentation (http://php.net/manual/en/wrappers.php.php)).

My tests have also shown that I can successfully get the PUT params once, but not twice, by calling:

Yii::app()->getRequest()->restParams

REASONING

I am developing a Yii based REST based web service and I want to implement authentication. Part of my authentication scheme (which imitates the authentication used in the Amazon AWS REST API calls) is to calculate a signature of the incoming request parameters (among other things).

This requires me to get the PUT parameters ONCE during the authentication process (done in a filter that runs before my controller) and then a SECOND time during the implementation of the PUT request.

Unfortunately, by the time the actual PUT request gets it's opportunity to execute, I have lost access to the PUT parameters (since they are consumed by the authentication check).

SOLUTION

I would suggest that the PUT parameters are cached, during their first request, and then served from the cached variable in any subsequent requests.

I could also cache the PUT parameters somewhere in my application (something I am trying to work on now) but I think that this should be a responsibility of the framework and not mine.

COMMENTS

I have already posted at Feauture Requests forum on yiiframework.com (http://www.yiiframework.com/forum/index.php?/topic/25962-cache-put-parameters-in-chttprequest-getrestparams-method/)

Migrated from http://code.google.com/p/yii/issues/detail?id=2973


earlier comments

stratosgear said, at 2011-11-21T23:05:21.000Z:

I saw by looking at the code that the _putParams and _deleteParams are populated by the same method, getRestParams.

Therefore I introduced another member variable, _restParams to cache the reading of the rest params.

I also included two new methods, getPutParams and getDeleteParams that return ALL the PUT and DELETE params.

This is a diff of the edited file, as I have changed it in my installation. At the moment it works fine and, at least, I can continue with my development.

--- CHttpRequest.orig.php 2011-07-16 18:59:27.000000000 +0300
+++ CHttpRequest.php 2011-11-22 00:55:59.620786000 +0200
@@ -65,6 +65,7 @@
private $_csrfToken;
private $_deleteParams;
private $_putParams;

  • private $_restParams;

    /**

    • Initializes the application component.
      @@ -198,12 +199,29 @@
      */
      protected function getRestParams()
      {
  •   $result=array();
    
  •   if(function_exists('mb_parse_str'))
    
  •       mb_parse_str(file_get_contents('php://input'), $result);
    
  •   else
    
  •       parse_str(file_get_contents('php://input'), $result);
    
  •   return $result;
    
  •   if ($this->_restParams === null) {
    
  •       $result=array();
    
  •       if(function_exists('mb_parse_str'))
    
  •           mb_parse_str(file_get_contents('php://input'), $result);
    
  •       else
    
  •           parse_str(file_get_contents('php://input'), $result);
    
  •       $this->_restParams = $result;
    
  •   }
    
  •   return $this->_restParams;
    
  • }

  • protected function getDeleteParams()

  • {

  •   if($this->_deleteParams===null)
    
  •       $this->_putParams=$this->getIsDeleteRequest() ? $this->getRestParams() : array();
    
  •   return $this->_deleteParams;
    
  • }

  • protected function getPutParams()

  • {

  •   if($this->_putParams===null)
    
  •       $this->_putParams=$this->getIsPutRequest() ? $this->getRestParams() : array();
    
  •   return $this->_putParams;
    

    }

    /**

    cebe.cc said, at 2011-12-12T17:25:51.000Z:

this might be done in one step together with issue 2993

alexander.makarow said, at 2011-12-12T17:33:13.000Z:

Yes, these are related.

qiang.xue said, at 2012-01-01T03:36:55.000Z:

set for 1.1.10 milestone

Owner

cebe commented Feb 16, 2012

related issue 2993 is now at #259

@stratosgear stratosgear added a commit to stratosgear/yii that referenced this issue Feb 17, 2012

@stratosgear stratosgear Fixes #173
Implements caching of PUT and DELETE parameters during CHttpRequest getRestParams method.
7ffa636

@stratosgear stratosgear added a commit to stratosgear/yii that referenced this issue Feb 18, 2012

@stratosgear stratosgear Refactored based on comments for fixing #173. 6a20325

Related issue #357 closed as this is already discussed here: getRestParams should be public (or there should be another way to retrieve PUT/DELETE params).

@qiangxue qiangxue was assigned Feb 21, 2012

@samdark samdark was assigned Sep 24, 2012

Owner

samdark commented Sep 24, 2012

Fixed. See details in #1443.

@samdark samdark closed this Sep 24, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment