Handling complex GET parameters with Slim Framework HTTP routing - php

Assuming the following naive code:
$app->get( '(/store(/:url)+)', function( $url = NULL ) use ( $app )
{
// Execute actions on $url
});
The above works fine for the following:
http://localhost/api/0001/store/url-data
But it fails for:
http://localhost/api/0001/store/http%3A%2F%2Fexample.com%2FSomething
http://localhost/api/0001/store/http://example.com/Something
// and other variations
I wish to pass a full encoded URI to handle on the server side. How can I manage to do that with Slim?
Notes:
Other types of HTTP Requests (POST, PUT) won't work for this given problem.
It can be solved on the other end by reformatting (serializing) the URI, but I wish this to be my last resort.
Important Edit - Answer
So it turns out the above is a bug in the framework which is currently being tested and hopefully fixed and released soon. I solved the problem temporarily by serializing the URI before it reaches the server side.

So it turns out the above is a bug in the framework which is currently being tested and hopefully fixed and released soon. I solved the problem temporarily by serializing the URI before it reaches the server side.

Related

WP_REST_Response vs WP_Error

I'm a bit confused about how errors are handled in Wordpress's REST API. In their examples, they suggest using WP_Error to return errors, but WP_REST_Response has the HTTP status code as a second parameter, which makes it shorter and somewhat cleaner to my taste.
So I'm comparing this way of returning an error:
return new WP_REST_Response(array('error' => 'Error message.'), 400);
With this one:
return new WP_Error('rest_custom_error', 'Error message.', array('status' => 400));
With the first option, I can have just the error text in my response and it's enough for me. So the response would look like so:
{"error":"Error message."}
With the second one it's more detailed:
{"code":"rest_custom_error","message":"Error message.","data":{"status":403}}
But I also need to specify the error code (first parameter), which doesn't give any advantage to my front-end implementation. Other than the syntax, I'm curious about differences in performance, security and future-proof factors.
So is there any reason to prefer one over the other than personal preferences?
I do as follows:
WP_REST_Response // Used when endpoint code runs just fine but needs to
// tell the client about some other downstream error (e.g. 4xx)
WP_Error // Used when endpoint code has an issue and needs to tell you
// it didn't compute or couldn't find resources etc (e.g. 5xx)
As far as I can tell, WordPress changes the status codes of the responses in unpredictable ways. This is dumb. For instance, if you create a WP_REST_RESPONSE with status 400, it actually sends it as status 200 with "status:400" as data in the body.
What I do:
Just use PHP response functions:
http_response_code(400);
exit;
If you tell me I'm wrong, please explain the benefit of using these two function wrappers. I see the benefit if you work for Automattic and are creating regressions in core itself. If you're a plugin or theme dev, [and you're assuming core works] these functions should be avoided as having no use.

Set Request (not Response) Headers in Laravel 5 for Non-Ajax Routes

I am actually completely baffled that this is such a difficult task to accomplish and/or find any relevant information about. My guess is that it must be something SO simple, that no one has to ask about it (except for me! :-) ), so I am hoping that someone can easily point me in the right direction...
I need to set headers in my Requests - not in my Responses (I've got that part handled), and not for Ajax routes (I've got that part handled as well). How on Earth do I accomplish this on internal app routes in Laravel 5.1?
Essentially, I need to attach an 'Authorization' header to certain Requests. (i.e.
$request->headers->set('Authorization', 'my-authorization-token');
)This line of code does not work, however. No matter where I put it. It doesn't work from middleware. It doesn't work from routes.php. It doesn't work from my controllers... it just simply does not work period. (For the sake of clarity, '$request' is 'Illuminate\Http\Request').
What am I missing? Where/How can I set request headers before a request is sent? Please help! Thanks in advance.
Some of the answers here might give you an idea, you could adapt them for the request: Where can I set headers in laravel
This also looks relevant: Laravel 5 / Lumen Request Header?
The request is sent from the client to the server (i.e. your Laravel app). So you set the request headers on the client site using Javascript.
The Laravel documentation has an example of setting the X-CSRF-TOKEN header using jQuery.
$.ajaxSetup({
headers: {
'X-MY-HEADER': 'whateveryouwant
}
});
Using VueJS it would look like this
Vue.http.headers.common['X-MY-HEADER'] = 'whateveryouwant';
You need to create a new request object and then set the header like this:
// e.g., Inside controller method
$request = new \Illuminate\Http\Request();
$request->setMethod('POST'); // or whatever your request type is
$request->header('Authorization', 'my-authorization-token');

Laravel's Response::json() returns nothing to the client under HHVM

I have HHVM running on a virtualbox VM, with the webroot mapping to my local laravel install, being served out at an internal IP.
Locally, I'm serving the site out under http://[localhost]:8000.
The codebase is identical.
code of MembersController.php (resourceful controller):
public function show($id)
{
$member = Member::findOrFail($id);
$data = array();
$data['id'] = $member->id;
$data['first_name'] = $member->first_name;
$data['last_name'] = $member->last_name;
return Response::json($data);
}
Assuming everything is working normally:
When I run a GET request to LOCALHOST: http://[localhost]:8000/api/v1/member/1, the client returns the JSON as normal - all good.
When I run a GET request to HHVM (same client, identical codebase): http://[vm_ip_address]/api/v1/member/1, the client receives no data.
The data is being passed back through the calls within HHVM though, as if I change the 'return' to 'echo', the payload is returned in both cases (headers also)
It looks like HHVM is affecting with laravel's Response::json() function and disallowing the reply contents from being displayed in the client.
Has anyone else seen this?
This is not something I can set up a unit test for, as it always passes, because the final reply always has data in it :/
Any input would be great - I'm interested to learn how to get around this.
Thanks.
Sadly you're probably going to have to get your hands dirty debugging. HHVM probably has a very slight difference in how it does something which this code-path is sensitive to. We pass 100% of laravel unit tests, but there probably isn't one covering this case.
If you can, please trace down the code to where the data changes. Put in echos and error_logs until you can build a very small test case then then open an issue on github and we'll get it fixed.

Enabling CORS in CakePHP app

I am trying to enable CORS for an API built in CakePHP so that all requests are accessible with the following in the AppController:
public function beforeFilter()
{
header("Access-Control-Allow-Origin: *");
}
Is this in the wrong place? As requests are still being blocked.
Update: It seems this does in fact work BUT because I am doing something like:
header('Content-Type: application/json');
echo json_encode(array('message'=>'Hello world!'));
In some of my methods it's acting as though it's overriding the header set the AppController so it's not appearing in the response for the JSON calls.
Any ideas?
Update 2: Returning JSON like below, fixes the problem:
$this->response->type('json');
$this->response->body(json_encode(array('message'=>'Hello world!')));
So apparently using header() in Cake breaks previous headers?
You can do this using the cake response object;
$this->response->header('Access-Control-Allow-Origin', '*');
More info on the response object;
http://book.cakephp.org/2.0/en/controllers/request-response.html#setting-headers
However, the beforeRender() callback seems a more logical location.
Another option is to add this header in your apache vhost or htaccess examples can be found in the htaccess file of Html5Boilerplate which is a very interesting thing to look at (well documented), because it contains a lot of optimisations that work nicely with cakephp as well;
https://github.com/h5bp/server-configs-apache/blob/master/dist/.htaccess
http://html5boilerplate.com/
Based on what I found out here: Sending correct JSON content type for CakePHP
The correct way to return JSON in CakePHP is like so:
$this->response->type('json');
$this->response->body(json_encode(array('message'=>'Hello world!')));
This is because the headers can be overridden and therefore the CORS doesn't work unless you do it the 'proper' way using the response object in Cake.

Access the webserver by using javascript instead of php

I'm now using phonegap to develop a application. I have found a similar php code which can assess to a local server here, but unfortunately phonegap doesn't support php.
Can anyone help me to 'translate' the php code below into JQuery ajax or any other javascript code? Thanks!
require_once('nusoap.php');
/* create client */
$endpoint = "http://www.pascalbotte.be/rcx-ws/rcx";
$ns = "http://phonedirlux.homeip.net/types";
$client = new soapclient($endpoint);
// queryRcx is the name of the method you want to consume
// RcxQuery_1 is the name of parameter object you have to send
// x and y are the names of the integers contained in the object
$result = $client->call('queryRcx',array('RcxQuery_1' => array('x' => 12,'y' => 13)), $ns);
print_r($result);
Step 1. Resolve the 404 associated with http://www.pascalbotte.be/rcx-ws-rpc/rcx?WSDL
Step 2. Get a JavaScript SOAP client.
Step 3. ... ... ...
Step 4. PROFIT!
Seriously though. All this really takes is a JavaScript based SOAP client. While they aren't a dime-a-dozen, they are pretty common. The one above is for jQuery, but it is easy enough to find other implementations.
The fact that the WSDL definition causes a 404 may or may not be a problem as the actual wsdl definition is technically optional, but you really want to figure out what happened.
You can add this header to the PHP file or .htaccess to avoid problems with cross domain reqs:
header('Access-Control-Allow-Origin: *');
Replace the all(*) with your domain ;)
Good luck!

Categories