Kohana module restify URL - rest

Hi I am trying to work with this module ->
http://kohana-modules.com/modules/michealmorgan/kohana-restify
It works great except when I use curl to send requests, if I send this
localhost/restify/test?id=1
then I get the value of id
If I do this
localhost/restify/test/1 or
localhost/restify/test/index/1 I get routed to the defualt page (error page)
So I asume Index is mapped to GET ,so anything thats not test/index is routed, but I cant figure out how to allow it to accept it.
Has anyone solved this ?
thanks
if (trim(Request::detect_uri(), '/') == 'restify/test')
{
Route::set('restify/test', '<directory>(/<controller>(/<action>(id/<id>)))')
->defaults(array
(
'directory' => 'restify',
'controller' => 'test'

try inserting this in your bootstrap...
echo Debug::vars(trim(Request::detect_uri(), '/'));
if it does not equal restify/test when you curl the request, something is up and you might need to fix the module

Related

Use route prefix with RESTful routes in CakePHP

Working on building an API and would like to use RESTful routes.
I got it to work just fine like this:
http://www.mysite.com/events.json // returns json results with my events
http://www.mysite.com/events/123.json // returns json results with event of id '123'
BUT - I want to be able to do this using an 'api' prefix.
So, I added the api Routing prefix:
Configure::write('Routing.prefixes', array('admin', 'api'));
And changed my actions from 'view' and 'index' to 'api_view' and 'api_index'.
But now it doesn't work. (eg. I have to write the action name or it won't find the correct one based on HTTP.
The end goal would be to be able to do something like this:
GET http://www.mysite.com/api/1.0/events.json // loads events/api_index()
GET http://www.mysite.com/api/1.0/events/123.json // loads events/api_view($id)
DELETE http://www.mysite.com/api/1.0/events/123.json // loads events/api_delete($id)
...etc
I ended up having to just write the routes manually:
Router::parseExtensions('json', 'xml');
Router::connect('/api/:version/:controller/:id/*',
array('[method]'=>'GET', 'prefix'=>'api', 'action'=>'view'),
array('version'=>'[0-9]+\.[0-9]+', 'id'=>'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'));
Router::connect('/api/:version/:controller/*',
array('[method]'=>'GET', 'prefix'=>'api', 'action'=>'index'),
array('version'=>'[0-9]+\.[0-9]+'));
Router::connect('/api/*', array('controller'=>'events', 'action'=>'index', 'ext'=>'html'));
Notes:
The [method] is what forces the HTTP type (eg. RESTful)
The parseExtensions() makes it so you can have it display the data in different formats automatically by changing the extension in your URL.
The last Router:: line was just a catchall for anything /api/ that didn't match - it forwarded it to the homepage. Eventually I'll probably just route this to an API error page.
The 'ext'=>'html' of the last Router:: line was to keep parseExtensions from trying to use whatever extension was in the URL - if it's redirecting for reasons they made the call wrong, I just want it to go back to the homepage (or whatever) and use the normal view.
Try something like this.
Router::connect('/:api/:apiVersion/:controller/:action/*',
array(),
array(
'api' => 'api',
'apiVersion' => '1.0|1.1|'
)
);
With prefix routing
Router::connect('/:prefix/:apiVersion/:controller/:action/*',
array(),
array(
'prefix' => 'api',
'apiVersion' => '1.0|1.1|'
)
);
Will match only valid API versions like 1.0 and 1.1 here. If you want something else use a regex there.
I know this is an old post, but there is a routing method called mapResources which creates the special method based routing for you.
http://book.cakephp.org/2.0/en/development/rest.html
You put it in routes.php like so:
Router::mapResources(array('controller1', 'controller2'));
The docs have a nice little table showing how the requests are mapped to different actions, which you can always override if you need to.

Register new memer for vBulletin via Mobile API

I'm trying to use the vBulletin REST Mobile API to simply register.
The sourced are installed on my local machine and according the documentation https://www.vbulletin.com/forum/content.php/393-User-Registration-Process-Mobile-API
This procedure should not be so hard, especially without humanity and COPPA authentication.
However I've stacked!
The method definition describes "addnewmember" clear, so I've generated a test link, which should do the job.
https://www.vbulletin.com/forum/content.php/365-User-Related-Methods
The link is:
.../forum/api.php?&api_m=register_addmember&api_c=1&api_s=76ec9eec61e7fdfef2f3feee28d5f392&api_sig=8fe54313b333cc0fef4ddd8e398b5c80&api_v=6&agree=1&username=testuser&email=XXXXXX%40gmail.com&emailconfirm=XXXXX%40gmail.com&password=12345678&passwordconfirm=12345678
As a response I get: register_not_agreed
The Docs: register_not_agreed
The agree parameter should be set to 1.
Which is also clear - agree parameter was not there.
Here comes the funny part - In the API-Log I can see that the 'agree' parameter is correctly passed
*1 test_client Gast 13:23, 18.06.2012 register_addmember Array ( [api_m] => register_addmember [api_c] => 1 [api_s] => 76ec9eec61e7fdfef2f3feee28d5f392 [api_sig] => 8fe54313b333cc0fef4ddd8e398b5c80 [api_v] => 6 [agree] => 1 [username] => testuser [email] => ....*
Is there anybody with experience with the Mobile API that could help?
I don't know why it does not work with a pure GET call but I'm sure it will work (because I'm working on a vBulletin API client in Python and I did it this way) if you:
use GET parameters to send api_c, api_sm, api_m, and api_sig
use POST data for all the rest (username, email, agree, etc)

receiving this msg from zend: 'Zend_Soap_Client_Exception' with message 'Invalid URN'

does anyone know what this means
im doing a pretty simple call here in my indexAction -
private $wsdl = "https://mywsdlserver.com/open?wsdl";
$options = array(
"location"=>$this->wsdl,
"uri"=>$this->wsdl
);
$client = new Zend_Soap_Client($this->wsdl, $options);
print_r($client);
fyi i have tried this with and without the options
when i set the options i get the error
when i dont set the options i get an empty client
what id like to get back
is the xml i get when i just put https://mywsdlserver.com/open?wsdl in the addressbar
thanks for your help
The error indicates that the URL you are passing in the options is not valid. The one in your example is fine, so presumably this is not what you are really using.
However, the location and URI options don't apply in WSDL mode, so you're best off omitting them completely. See the docs for the Zend_Soap_Client constructor at: http://framework.zend.com/manual/en/zend.soap.client.html

PHPUnit and Zend Framework assertRedirectTo() issue

I'm having an issue with assertRedirectTo() in a test I have created, below is the code I have used:
public function testLoggedInIndexAction() {
$this->dispatch('/');
$this->assertController('index');
$this->resetResponse();
$this->request->setPost(array(
'type' => 'login',
'username' => 'root',
'password' => 'asdasd',
));
$this->request->setMethod('POST');
$this->dispatch('/');
$this->assertRedirectTo('/feed/');
}
You log in through / (index.php/) and submit post details there and the it redirects you to /feed/ (index.php/feed/). The details I have supplied are correct and should work however I am having issues whereby PHPUnit is saying they are incorrect:
There was 1 failure:
1) IndexControllerTest::testLoggedInIndexAction
Failed asserting response redirects to "/feed/"
/home/public_html/mashhr/library/Zend/Test/PHPUnit/Constraint/Redirect.php:190
/home/public_html/mashhr/library/Zend/Test/PHPUnit/ControllerTestCase.php:701
/home/public_html/mashhr/tests/application/controllers/UserControllerTest.php:36
#poelinca: No, it is simply a case of Zend_Test being unreliable in registering a redirect (even if it has been called correctly!)
In his case, the real app is no doubt redirecting the user properly, but the Zend_Test environment is having trouble registering properly called redirects. The best response I can think of is to omit any failing assertRedirect which actually works in the application.
This is not an optimal situation, but unless you're prepared to dig into the Zend code to see where the problem is, this may be your best bet for efficiency. This is an example of what causes unit testing to get a bad name: Having to alter code to pass tests which actually work already.
See http://framework.zend.com/issues/browse/ZF-7496 Which is misleadingly specific in its title: the problem relates to all redirects, especially those which must set headers and exit instead of dispatching the original controller.
For whatever reason, this behavior causes Redirects not to always fail, but to be highly unreliable instead! If anyone knows a better workaround to this problem (which is general, and probably unrelated to the OP's code) please let us know.
stumbled on this question while having the same problem. I ended up doing the following:
$this->assertRedirect();
$responseHeaders = $this->response->getHeaders();
$this->assertTrue(count($responseHeaders) != 0);
$this->assertArrayHasKey('value', $responseHeaders[0]);
// in my case I'm redirecting to another module
$this->assertEquals('/module/controller/action', $responseHeaders[0]['value']);
I've responded this answer in http://zend-framework-community.634137.n4.nabble.com/Zend-Test-failing-on-AssertRedirectTo-td3325845.html#a4451217
I'm having this same issue... A possible way to assert it could be in
PHPUnit and Zend Framework assertRedirectTo() issue
But the problem is there.. My example is (wich actually works if done manually):
// controller modules/picking/orders/product
$orderId = $this->_getParam('oId');
if (empty($orderId)) {
return $this->_redirect('picking/orders/browse/invalid/empty');
}
// test
$this->dispatch('picking/orders/product');
$this->assertRedirect(); // ok
$this->assertRedirectTo('picking/orders/browse'); // error
$this->assertRedirectTo('picking/orders/browse/invalid/empty'); // error
After I've found the error!
Actually, following the example above i've found that the string comparizon in my example has an error:
'.../public//picking/orders/browse/invalid/empty'
'.../public/picking/orders/browse/invalid/empty'
... fixing the preprended slash solve the problem! ;)
So if i understand right , you wrote a test that fails ( id say this is perfect ) .
In order to make the test pass you need to debug you're app and see where the problem is , in this case you need to have a look at the actual redirection ( or eaven the post fields sent by the form ) , maybe check the routing too . I gues nobody here will be able to answer you're question unless you post the code in you're index controller/form/view and feed controller .
For future reference, I had this issue today and it was caused by the Url class failing to build a valid url (I was passing the wrong parameters) but not reporting an error to PHPUnit (probably because PHPUnit masks the error).
Correcting the url parameters fixes the url and with it the assertion.

How do I use and debug WWW::Mechanize?

I am very new to Perl and i am learning on the fly while i try to automate some projects for work. So far its has been a lot of fun.
I am working on generating a report for a customer. I can get this report from a web page i can access.
First i will need to fill a form with my user name, password and choose a server from a drop down list, and log in.
Second i need to click a link for the report section.
Third a need to fill a form to create the report.
Here is what i wrote so far:
my $mech = WWW::Mechanize->new();
my $url = 'http://X.X.X.X/Console/login/login.aspx';
$mech->get( $url );
$mech->submit_form(
form_number => 1,
fields =>{
'ctl00$ctl00$cphVeriCentre$cphLogin$txtUser' => 'someone',
'ctl00$ctl00$cphVeriCentre$cphLogin$txtPW' => '12345',
'ctl00$ctl00$cphVeriCentre$cphLogin$ddlServers' => 'Live',
button => 'Sign-In'
},
);
die unless ($mech->success);
$mech->dump_forms();
I dont understand why, but, after this i look at the what dump outputs and i see the code for the first login page, while i belive i should have reached the next page after my successful login.
Could there be something with a cookie that can effect me and the login attempt?
Anythings else i am doing wrong?
Appreciate you help,
Yaniv
This is several months after the fact, but I resolved the same issue based on a similar questions I asked. See Is it possible to automate postback from the client side? for more info.
I used Python's Mechanize instead or Perl, but the same principle applies.
Summarizing my earlier response:
ASP.NET pages need a hidden parameter called __EVENTTARGET in the form, which won't exist when you use mechanize normally.
When visited by a normal user, there is a __doPostBack('foo') function on these pages that gives the relevant value to __EVENTTARGET via a javascript onclick event on each of the links, but since mechanize doesn't use javascript you'll need to set these values yourself.
The python solution is below, but it shouldn't be too tough to adapt it to perl.
def add_event_target(form, target):
#Creates a new __EVENTTARGET control and adds the value specified
#.NET doesn't generate this in mechanize for some reason -- suspect maybe is
#normally generated by javascript or some useragent thing?
form.new_control('hidden','__EVENTTARGET',attrs = dict(name='__EVENTTARGET'))
form.set_all_readonly(False)
form["__EVENTTARGET"] = target
You can only mechanize stuff that you know. Before you write any more code, I suggest you use a tool like Firebug and inspect what is happening in your browser when you do this manually.
Of course there might be cookies that are used. Or maybe your forgot a hidden form parameter? Only you can tell.
EDIT:
WWW::Mechanize should take care of cookies without any further intervention.
You should always check whether the methods you called were successful. Does the first get() work?
It might be useful to take a look at the server logs to see what is actually requested and what HTTP status code is sent as a response.
If you are on Windows, use Fiddler to see what data is being sent when you perform this process manually, and then use Fiddler to compare it to the data captured when performed by your script.
In my experience, a web debugging proxy like Fiddler is more useful than Firebug when inspecting form posts.
I have found it very helpful to use Wireshark utility when writing web automation with WWW::Mechanize. It will help you in few ways:
Enable you realize whether your HTTP request was successful or not.
See the reason of failure on HTTP level.
Trace the exact data which you pass to the server and see what you receive back.
Just set an HTTP filter for the network traffic and start your Perl script.
The very short gist of aspx pages it that they hold all of the local session information within a couple of variables prefixed by "__" in the general aspxform. Usually this is a top level form and all form elements will be part of it, but I guess that can vary by implementation.
For the particular implementation I was dealing with I needed to worry about 2 of these state variables, specifically:
__VIEWSTATE
__EVENTVALIDATION.
Your goal is to make sure that these variables are submitted into the form you are submitting, since they might be part of that main form aspxform that I mentioned above, and you are probably submitting a different form than that.
When a browser loads up an aspx page a piece of javascript passes this session information along within the asp server/client interaction, but of course we don't have that luxury with perl mechanize, so you will need to manually post these yourself by adding the elements to the current form using mechanize.
In the case that I just solved I basically did this:
my $browser = WWW::Mechanize->new( );
# fetch the login page to get the initial session variables
my $login_page = 'http://www.example.com/login.aspx';
$response = $browser->get( $login_page);
# very short way to find the fields so you can add them to your post
$viewstate = ($browser->find_all_inputs( type => 'hidden', name => '__VIEWSTATE' ))[0]->value;
$validation = ($browser->find_all_inputs( type => 'hidden', name => '__EVENTVALIDATION' ))[0]->value;
# post back the formdata you need along with the session variables
$browser->post( $login_page, [ username => 'user', password => 'password, __VIEWSTATE => $viewstate, __EVENTVALIDATION => $validation ]);
# finally get back the content and make sure it looks right
print $response->content();