Laravel: Output array of bytes to browser in pdf format - laravel

I am getting a response from an external api which contains an array of bytes I'd like to convert to pdf.
Sample response from the api.
So far, I have tried below code in laravel with no success.
$data is received from api.
return response($data)
->withHeaders([
'Content-Type'=> 'application/pdf'
]);

The trick is to set the Content-Disposition header to force a download.
return response($data, 200, [
'Content-type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="api.pdf"',
]);
You could also replace attachment with inline to render the pdf in the browser (most modern browser support this).

Related

Laravel HTTP Client Bad Request on Discord API Access Token Exchange

I have a laravel application setup and I'm configuring a Discord auth system.
I have sent & requested authorization & recieved a confirmation code back.
When I try to exchange the code for an access token I'm receiving a 400 bad request and I'm not sure why.
I'm new to laravel and can't seem to find any sort of error that may help to pin point the problem.
Controller function that discord redirects after authorization
public function exchange(Request $request) {
//exchange discord code for access_token
$code = Request::get('code',false);
$params = array(
'grant_type' => 'authorization_code',
'client_id' => env('CLIENT_ID'),
'client_secret' => env('OAUTH2_CLIENT_SECRET'),
'redirect_uri' => Request::root().'/discord/return',
'scope' => 'identify guilds guilds.join',
'code' => $code
);
$access_token = Http::withOptions([
'debug' => true,
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded'
],
'json' => $params
])->post('https://discordapp.com/api/oauth2/token');
dd($access_token);
return redirect()->route('return.discord',['token' => $access_token->access_token]);
}
I've dumped out $params and all the data is pulling in as it should.
Guzzle dumps this:
[CONNECT] [FAILURE] severity: "2" message: "HTTP/1.1 400 Bad Request " message_code: "400" [MIME_TYPE_IS] message: "application/json" [FILE_SIZE_IS] message: "Content-Length: 26" bytes_max: "26" [PROGRESS] bytes_max: "26"
I know that 400 bad request means an issue with the data being sent along, but I can't figure out what I'm doing that's not producing the correct result. The documentation states the required content type which I have set, so I'm really scratching my head here.
Any help would be much appreciated.
Here's the Discord API documentation:
https://discord.com/developers/docs/topics/oauth2#authorization-code-grant
To anyone looking for an answer...
The "invalid grant" error is due to an issue with the Discord API and non-standard requests. I could not get the Laravel HTTP class request to work for exchanging the access token. Instead, I used native php cURL within Laravel.
As for the issue with receiving '400 bad request', that was due to using incorrect function withOptions() as oppossed to asJson()->withHeaders(). Thanks #Zachary Craig!
However, I could not use this in the end due to the problem described above.
If any others find a better solution, let me know :)!
For all who have the same problem.
The solution is to use ->asForm() before the post. This changes the handling of the data from json to form_params. This way the Discord API accepts the parameters.
return Http::asForm()->post($this->endpoint.'/oauth2/token', $data);

Why is checking for a json mimetype not working in my Request?

I have a Laravel API and I make a custom Request to validate the values. I'm testing my routes via Postman and I added a JSON file to my settings field. But when I try to validate the mimetype in my custom request an error gets thrown. When I remove |mimetypes:application/json the route returns a response successfully. Why is this happening?
public function rules()
{
return [
'name' => 'required|string|min:2|max:32|unique:game_templates',
'path' => 'required|string|url|unique:game_templates',
'settings' => 'required|file|mimetypes:application/json',
'orientation' => Rule::in(GameTemplate::$orientations),
];
}
The JSON content
{
"name":"test"
}
Are you sure you are actually uploading a file with the application/json mimetype? A .json extension doesn't automatically mean it's application/json. Also note the following from the documentation:
To determine the MIME type of the uploaded file, the file's contents will be read and the framework will attempt to guess the MIME type, which may be different from the client provided MIME type.

Laravel api header request

Route::resource('get-users','api\UserController#get_users');
Route::resource('register','api\UserController#register');
My Api is giving me the response I checked it using POSTMAN but android developer is asking me that what should he sent in header for my API .
I am not getting that how to create a header I am using laravel and I have written functions in controller .
You should go through this part of the documentation: https://laravel.com/docs/5.6/responses#attaching-headers-to-responses
He maybe wants additional header in the response.
Your return value in api\UserController can be extended like this:
return response($content)
->withHeaders([
'Content-Type' => $type,
'X-Header-One' => 'Header Value',
'X-Header-Two' => 'Header Value',
]);

What is the most fast way to show "secure" images with Laravel and Amazon s3?

In my Laravel application I have a gallery for logged-in users with Amazon S3.
Now I download EVERY thumbnail and image in this way:
public function download($file_url){ // is safe, but slow...
$mime = \Storage::disk('s3')->getDriver()->getMimetype($file_url);
$size = \Storage::disk('s3')->getDriver()->getSize($file_url);
$response = [
'Content-Type' => $mime,
'Content-Length' => $size,
'Content-Description' => 'File Transfer',
'Content-Disposition' => "attachment; filename={$file_name}",
'Content-Transfer-Encoding' => 'binary',
];
return \Response::make(\Storage::disk('s3')->get($file_url), 200, $response);
}
This is safe (because I have a router with middleware('auth'), but is very server-intensive and slow.
Is it possible to download a file directly from Amazon:
only for (in my Laravel)-loggedin users (mayby with a temporery download link)?
OR only with a secure unique link?
You can use temporary URLs:
$url = Storage::disk('s3')->temporaryUrl(
'file.jpg', now()->addMinutes(5)
);
First param is the path on S3, second param is how long you want the URL to work for. Set this to a low value if you only want the URL to work for a single page load.
https://laravel.com/docs/5.6/filesystem (under Temporary URLs)

Downloading zip file results in .cpgz file after extraction

I am using the following code do download a zip file. I am sure the file is existing and working on the server. The result is .cpgz file after extraction.
return response()->download('/Applications/XAMPP/xamppfiles/htdocs/stoproject/source/storage/app/Copy of StoTherm Classic®.zip');
The code was working and without any change, it stopped.
I also tried adding headers:
$headers = array(
'Content-Type' => 'application/zip',
);
return response()->download('/Applications/XAMPP/xamppfiles/htdocs/stoproject/source/storage/app/Copy of StoTherm Classic®.zip', basename('/Applications/XAMPP/xamppfiles/htdocs/stoproject/source/storage/app/Copy of StoTherm Classic®.zip'), $headers);
Also tried with:
'Content-Type' => 'application/octet-stream'
Calling ob_end_clean() fixed the issue
$response = response()->download($pathToFile)->deleteFileAfterSend(true);
ob_end_clean();
return $response;
Laravel 4 Response download issue

Resources