Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Background: Working on a Widget that uses a remote API using wp_remote_post to log into the service, once logged in storing the cookies received for the second request to query data with wp_remote_get.

Problem: The cookies from the first request are stored in the response as WP_Http_Cookie objects and their values are run through urldecode as seen in class-http.php. One of the cookies has an original value of l0xl4+7abTT2St+1UVA thanks to the urldecode this value becomes l0xl4 7abTT2St 1UVA in the WP_Http_Cookie object and therefore is not the same. This makes the cookie object unusable as is for the second request.

Workaround: I came up with a nasty little workaround for this problem:

// Replace space with + from cookie value
// because WP_Http_Cookie does urldecode( value )
$response['cookies'][0]->value = str_replace(' ', '+', $response['cookies'][0]->value);

// Set cookies for the second request
$this->cookies = $response['cookies'];

Question: Does anyone know why there is an urldecode instead of a filter in WP_Http_Cookie? Should I file a trac issue?

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

AFAIK URL encoding the cookie value is still kind of a defacto standard, it's an ancient relict based on the old, ugly Netscape cookie specs, that basically says that semicolons, commas and whitespaces are disallowed, and should be encoded, for example using URL encoding. Neither does it does it require enocding, nor does it force the use or URL encoding, but that's how it was implemented.

So when passing a string to the constructor, WP_Http_Cookie assumes that the data is from a cookie, and therefore the cookie value is encoded and needs to be decoded. Personally i think it should not do that, and leave it up to the developer to handle values as needed, as mentioned in Ticket 19922.

However, when dispatching a request, WP_Http_Cookie::getHeaderValue is invoked, and this is where a filter is available, wp_http_cookie_value. Assuming that the cookie value you are receiving is URL encoded, you could re-encode it using this filter.

function wp_http_cookie_value_filter($value, $name)
{
    return urlencode($value);
}
add_filter('wp_http_cookie_value', 'wp_http_cookie_value_filter', 10, 2);

However this would ofcourse apply to all requests, so as long as you can't tell for sure that you are the only one using this filter and/or making requests that contain cookies, it's probably a pretty bad idea.

Maybe if your cookie has a very unique name you could use that to filter only your specific cookie values:

function wp_http_cookie_value_filter($value, $name)
{
    if($name === 'my_very_special_cookie')
    {
        return urlencode($value);
    }
    return $value;
}
add_filter('wp_http_cookie_value', 'wp_http_cookie_value_filter', 10, 2);

Other than that you are probably better off using your workaround, ie manipulate the cookie value only for your specific requests.

share|improve this answer
    
Thanks for your reply didn't know about the filter being applied there, but makes sense. Maybe I'll figure out a workaround including the filter, but at the moment it looks like the easiest way is to keep going with my version. –  Silvan Hagen Oct 19 '12 at 4:44
add comment

Virtually all implementations of cookies are URL encoded. If you're sending a raw cookie, without encoding, then you need to control both ends of the pipeline. Since you don't, urlencode your cookies.

share|improve this answer
    
Thanks four your reply Otto, since there are also / in the cookie value the service I'm coding against doesn't accept the value that is passed through urlencode as it turns / into %2F, so I basically have to filter the the value through my own code. –  Silvan Hagen Oct 19 '12 at 4:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.