I am using AMFPHP/services modules to interact with Flash. I am having an intermittent problem when executing system.connect: When it's working properly it returns a response like this:

HTTP/1.1 200 OK
Date: Thu, 10 Sep 2009 15:20:29 GMT
Server: Apache
Expires: Thu, 10 Sep 2009 19:20:29 GMT
Last-Modified: Thu, 10 Sep 2009 15:20:29 GMT
Cache-Control: no-store
Pragma: no-store
Content-length: 291
Keep-Alive: timeout=15, max=83
Connection: Keep-Alive
Content-Type: application/x-amf

????AppendToGatewayUrl????I?F?SESS9e6947a6cfb27634029d183eeb11f96a=ba5061a12a72f4483935e8c7212c62fb??
/1/onResult?null?????sessid? ba5061a12a72f4483935e8c7212c62fb?user?userid??????????hostname?10.224.224.159?roles????1?anonymous user?? ?session???cache??????????? ??

When it fails it returns this:

HTTP/1.1 200 OK
Date: Thu, 10 Sep 2009 08:19:36 GMT
Server: Apache
Expires: Thu, 10 Sep 2009 01:19:36 GMT
Last-Modified: Thu, 10 Sep 2009 08:19:36 GMT
Cache-Control: no-store
Pragma: no-store
Content-length: 129
Keep-Alive: timeout=15, max=84
Connection: Keep-Alive
Content-Type: application/x-amf

????AppendToGatewayUrl????I?F?SESS3e923b281653185b85089c59e79637ef=963fc4f1ed2f0154fa423a46b661c771??
/1/onResult?null????

It doesn't seem to matter whether I am logged in or not and I am not even to the point of calling views.get or node.get.

I know that I can use an alternate method of getting the session id into the flash but this has worked perfectly except that sometimes it doesn't return the full response.

Here is the actionscript (entry point called from the flash is startLoad()):

package {
import flash.display.MovieClip;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.events.Event;

import nl.demonsters.debugger.MonsterDebugger;

public class DrupalConnector extends MovieClip{
private var myService:NetConnection;
private var sessionID:String;
public var infoArray:Array;
var debugger:MonsterDebugger;
private var service_url:String;
private var service_name:String;
private var drupalEvent:Event;
/**
* Contructor
*/
public function DrupalConnector(serviceURL:String, serviceName:String){

debugger = new MonsterDebugger(this);
infoArray = new Array();
myService = new NetConnection();
service_url = serviceURL;
service_name = serviceName;

}

public function startLoad():void{

myService.objectEncoding = ObjectEncoding.AMF0;
myService.connect(service_url);
var myResponder:Responder = new Responder(getView, onFault);
myService.call('system.connect', myResponder);

}

private function getView(returnObject:*) {

var myResponder2:Responder = new Responder(getNodeInfo, onFault);
sessionID = returnObject.sessid;
myService.call('views.get', myResponder2, sessionID, service_name);
}

private function getNodeInfo(returnObject:*) {
for (var item:* in returnObject) {
infoArray.push(returnObject[item]);
}
dispatchEvent(new DrupalEvent(DrupalEvent.NODES_COMPLETE) );
}

private function onFault(f:*) {
MonsterDebugger.trace(this, "Error" + f);
for (var item:* in f) {
MonsterDebugger.trace(this, item + ": " + f[item]);
}
}
}
}

CommentFileSizeAuthor
#6 amfphp_uid_fix.patch1.76 KBwaldmanm

Comments

ahb’s picture

Status: Active » Closed (fixed)

Sorry, looks like this doesn't touch AMFPHP at all, it's in services module.

ahb’s picture

I traced this down to the amfphp_fix_uid method.

The deserialization after replacing uid with user_id (amfphp.module line 92) returns nothing. No error, just nothing.

For now I have commented out the call since I'm not using flex, but would like to be able to stay on new release path.

ahb’s picture

Category: support » bug
Status: Closed (fixed) » Active
snelson’s picture

Status: Active » Postponed (maintainer needs more info)

Hi,

I have released a beta2 of amfphp.module. If you are able, can you tell me if this issue still occurs with the new release?

Thanks,
Scott

lionstone’s picture

Version: 6.x-1.0-beta1 » 6.x-1.0-beta2

I had this problem both with beta1 and beta2, but only with user accounts that had been created via the drupal for facebook module using fb connect.

After a day of head-scratching, I was able to comment out the following line to resolve the issue from amfphp.module:

// $result = amfphp_fix_uid($result);

I am using a flex client that calls custom services. What exactly is this line needed for? There do not seem to be any consequences for me disabling this line.

Unrelated: I should also mention that I had to disable this line to avoid char-encoding issues with Spanish characters, too (also seemingly with no negative consequences) :

$gateway->setCharsetHandler(variable_get('charset_method','utf8_decode'), variable_get('charset_php','ISO-8859-1'), variable_get('charset_sql','ISO-8859-1'));
waldmanm’s picture

StatusFileSize
new1.76 KB

Scott,

I've been chasing this problem for a couple of weeks and finally was able to figure it out. The culprit is indeed the amfphp_fix_uid() function.

This problem happens when part of the method arguments or result contains a string which is in itself a serialized value. I ran into this with the Drupal for Facebook (fb) module, which puts some serialized session info in the $user variable, including some 'uid' properties. The call to str_replace() in amfphp_fix_uid() replaces the 's:3:"uid";' that is within the (already) serialized string but it doesn't change the encoded total length of that serialized string. unserialize() then fails, returning false.

The only solution that I can see is to do the uid<->userid replacement more selectively. I've written the attached patch that does this replacement only for array or object keys and not to their values. Since the reason for all this translation is the 'uid' property that Flex adds to some objects, I think it is safe to treat properties only and don't really see a need to handle literal values. Of course, nested arrays or objects should be handled. I added the handling of objects in addition to arrays since most if not all of the structured values returned from services methods are objects.

If uid<->userid replacement is needed in values too, in addition to keys, then the last return statement in _amfphp_serialize_lite_replace() will need to be modified, but this will require extra caution as theoretically you might have a serialized string within a serialized string. I personally don't think that's necessary, but this patch does change functionality a bit from existing code.

This works for me so far, but more testing would be great, and a committed fix even better :)

Thanks,
Micah

idot’s picture

Hi Micah,

the patch nearly work fine. I'm just experiencing some problems with saving an node with node.save.
The node is saved withoud the user (node author: guest). This only happens when the user is connected to Facebook.

Do you know what's causing this?

Thanks,
Tobi

idot’s picture

Does anyone has an idea how to fix this?

waldmanm’s picture

Hi Tobi,

Only saw your question now for some reason. Anyway, I'm saving nodes fine without setting the user (id or name) while using FB Connect, and the right user is being filled automatically by services. So I'm guessing that the problem might be in how FB is setup in your installation, not with services or AMFPHP.
If it helps, my FB setup has:
Set FB Cookie - checked
Store tokens in session - checked
Username Style for Automatically Created Accounts: Machine-friendly
Facebook Connect is set as Primary for this app.
Create local account: If user has authorized the app
Map accounts: both checked (Map account when both local uid and Facebook id are known; Map account when Facebook email exactly matches local account)

HTH,
Micah

avpaderno’s picture

Version: 6.x-1.0-beta2 » 6.x-1.x-dev
Status: Postponed (maintainer needs more info) » Closed (outdated)

I am closing this issue, since it has been opened for a version that does not use a supported Drupal release. Furthermore, this project does not have versions for a supported Drupal release.