"Forging" (= mocking) an AMFPHP remoting request - php

I am using AMFPHP with great success to link my database with my Flex application. However I want to be able to test the remoting requests outside of flash, by typing something like:
http://localhost/amfphp/gateway.php?[WHAT DO I PUT HERE]
What do I put after the questionmark in order to have the browser (or a C++ http component) call the amfphp service, so that the http request needn't "initiate" from flash.

It sounds like you want to make an AMF call from PHP. You can't do this directly from a browser. The data would be returned in the binary AMF format, which of course PHP or a browser can't handle directly. I don't even think it can make the request.
You'll need a AMF client to make the call and decode the data - I suggest using SabreAMF.
Sabre AMF homepage
This is what simple client method call code looks like.
require 'SabreAMF/Client.php';
function make_request($param1,$param2){
$client = new SabreAMF_Client('http://your.server/amfphp/gateway.php');
return $client->sendRequest('your_amf_service.yourAMFmethod',array($param1, $param2));
}
you then invoke this like
$result=make_request('cow',300);
and it returns an array.
You'd probably want to set up a PHP class with all of your methods so you can call each one easily, of course.

AMFPHP has the service browser, which lets you simulate calls to your server-side service and see the responses. It basically does an internal CURL request back to the same service file and passes in the arguments you provided, and acts as if it was done directly from the client-side Flash app.

AMF being a binary format, things are probably not going to be that simple : you'll have to find out how your data is encoded...
As a first step, maybe you could, from your gateway.php script, just dump everything it receives to a file, when it's called from your flash component ?
This way, you could see how the received data looks like (and you'd know if it's passed in POST, or in GET).
Depending on what that data looks like, maybe you'll be able to "forge" a request to your server -- but I don't think it'll be as simple as just calling an URL from your browser...

Considering the AMFPHP gateway is just a mechanism to translate (from/to binary) and dispatch to a class/method with various incoming parameters and finally a return() of data - can you just unit-test directly against the method, thus skipping the entire AMF layer?

Related

php scrape dynamically loaded content via ajax using knockout.js

I need to scrape some data from a website which is being loaded via ajax using knockout.js (I don't know exactly on which technology it is working.)
Site is www.msc.com. Here I am searching for schedules like from Barcelona to Miami. So the result is loaded via ajax but doesn't show up in console or firebug.
I have tried too many times. Any help or suggestion will be appreciable.
Their script is located at: https://www.msc.com/CMSTemplates/CraftedCMS/WebServices/RouteFinder.svc/Routes
They prevent you from calling it directly in a browser tab/window, probably because what you're trying to do is against their policy. If they wanted people to scrape their DATA, they would not block direct requests to their API or they would provide another publicly documented API for you to use on your server.
With that said, you can see in your browser console that their web service returns JSON objects. You will have to hack (maybe illegally) your way by faking protocol variables in order to accomplish what you're aiming for. The first things to consider is that they only return results through that web service when:
a) The call is made through XMLHttpRequest as POST. (This you can fake it easily, but the next points, not so much...)
b) The call is made using a referer, in this precise case, the referer is: https://www.msc.com/routefinder?fromId=406&isCountryFrom=false&toId=83&isCountryTo=false
c) The call passes a cookie to the server, which is encrypted and signed, so each session is in their database and your key is probably unique, so good luck decrypting this: CMSPreferredCulture=fr-FR; ASP.NET_SessionId=gza5rfjrog2eb21ukrzma223; BIGipServerkentico.app~kentico_pool=439883018.20480.0000; bbbbbbbbbbbbbbb=LIKIGEACDJHDJPGPEOKGJBKODKDGOMHNKAEGEGKNODEDAEILEICBMLNLEFMAOIPPKMOIBBFAILFEEKJPIJDCBDDLFNBBMBPBGGKAIDOCMGHBEEIDMLPMIJJAMNFNIFMI; rxVisitor=1497537754979PTPODMSFNIR8BFVAKK353FS76M2D1KNN; dtPC=3$537845860_975h-vCQTABPJMGEOKDPDVNLHPCPDASGAPMCPCBA; rxvt=1497539656937|1497537754995; dtSa=-; dtLatC=8; _ga=GA1.2.1247106544.1497537756; _gid=GA1.2.879601947.1497537756; _gali=results; cookiePolicyApproved=true; MSCAgencyId=355840; _gat=1; _gat_local=1; dtCookie=3$B74DFC30736F7DBF485B79C31C55B167|www.msc.com|1

Using Delphi and HTTP POST to do web actions

I have a web application which I wrote in PHP. Each of my forms do an HTTP POST to a PHP file which processes the data and returns a result.
Now I want to use RAD Studio's Delphi XE4 to create an application which can be used on phones to perform basic functions on the site.
For example...
I have a function in my PHP file called F.
F Does some calculations with parameters passed using the $_REQUEST[''] directive.
So my question is: is there a way that I can use Delphi to post to my website and return the result.
I've searched for similar requests but no-one seems to have done this before.
I would even use a JavaScript file if someone can tell me how I can incorporate it?
I know jQuery has a $.ajax method, is there maybe a way to implement that?
I can assure you that you're not the first person to do an HTTP request via Delphi :)
You state that you're fetching the request data via $_REQUEST, so you'll get both POST and GET data, so perhaps these links might be of interest:
What's the simplest way to call Http GET url using Delphi?
What’s the simplest way to call Http POST url using Delphi?

How to print http response first and do the heavy db operations later?

I'm implementing a mobile api. One of the requests processes json data and returns afterwards a predefined message( is independent from the calculation) back to the device. I'm using kohana 3.
How do I return the http response first and do the calculation afterwards?
What do you think about, using a message queue and a separate program that does the processing and db operations?
One option would be to use gearman. There is a Kohana gearman module made by one of the Kohana devs.
Maybe you can help flush() function, which send buffer (and header also). But flush() don't guarantee header send, because between php and web browser stays a web server (like apache)
Not sure I understand your question, but if you want to buffer output you can use ob_start() and ob_get_clean()
I think you might be looking for something like
ignore_user_abort(true)
http://www.php.net/manual/en/function.ignore-user-abort.php
After making the call you can send your response back to the browser and finish wrapping up your calculations/logging after the connection is closed and the client is off doing something else.
This enables you to do some quick processing without hanging up the client or having to use an external process to handle your tasks

ZendAMF - what is all this traffic?

I am using ZendAMP php and Flex (Flash Builder 4). It works great, but I noticed when I am looking at the traffic going between my flex application and ZendAMF, there packets moving even though I am not requesting communications in my code.
For example, this is what my service looks like in flex:
var activityLogService:RemoteObject = new RemoteObject("zend");
activityLogService.showBusyCursor=true;
activityLogService.endpoint="http://myserver:80/amf/";
activityLogService.source="ActivityLogService";
Then I call something like activityLogService.getRecord(myPassedParams) after setting up my addlistener.
When I watch the network traffic using something such as fiddler, I can see my request and the response come back.
However, I also see these request packets that do not contain names of my zend service objects:
�����null�/1����
���
�Mflex.messaging.messages.CommandMessageoperationcorrelationIdmessageIdtimeToLivetimestampdestinationheaders bodyclientIdI3961D727-35B9-F41C-713A-AA42625FCFD9��
%DSMessagingVersion DSIdnil
The response coming back is pretty vague too:
�����
/1/onResult������
�Uflex.messaging.messages.AcknowledgeMessagecorrelationIdclientIddestinationmessageIdtimestamptimeToLiveheaders bodyI3961D727-35B9-F41C-713A-AA42625FCFD9I53D9441D-E1DC-4829-9B3F-000040DA9368I1322EAF2-B588-9929-0AC4-000013A22D80131282149600�
Are these just some kind of 'keep alive' messages?
If so, is there a way to turn them off?
Also, if so, is there a way I can use them to keep some kind of session alive on the server side maybe (maybe that's what they are for)?
The RemoteObject AMF implementation requires that the server-side implementations are stateful. This is defined as part of the protocol, so it shouldn't matter which back-end you;re talking to (ie., my experience is in BlazeDS, LCDS and WebOrb, but it should be the same with PHP)
When your application makes it's first AMF call to a RemoteObject, it checks to see if the client has a DSid value set. This is essentially a unique ID which identifies the flex client to the server.
If not, then a call is issued to get a new DSid, and all outbound calls are suspended until that call returns. From then on, the DSid is passed on all outbound calls in the header of the AMF packet.
If you ever reset the DSid on the client, (by calling FlexClient.getInstance().id = 'nil') this process will repeat. (ie., all calls will be suspended again until the server has issued a new DSid to the client.)
Basically, these are internal messages required for the AMF Protocol to work

SoapClient save request to file instead of sending it

Is there a way to save the soap request SoapClient sends when calling __soapCall to a file instead of sending it to the actual server?
I'm trying to save the soap requests to a queue and then send them over a period of time (the requests will be very different).
I'm using Zend_Soap.
Take a look at Zend_Soap_Client_Local, especially the _doRequest() method and build your own class with your own logic.
If you want so see how they used Zend_Soap_Client_Local, take a look in tests/Zend/Soap/ClientTest.php, method testGetFunctions().

Categories