How to allow download just .zip and exe [Laravel 5.1] - laravel-5.1

How can I allow that user be able just to download zip and exe files?
I am currently use this function:
public function download($id)
{
$headers = array(
'Content-Type: application/x-msdownload',
'Content-Type: application/zip'
);
return response()->download(storage_path() . '/app/' . 'gamers.png', 'gamers.png', $headers);
}
And this allow me download any file, how can I limit it just on zip and exe?

You are trying to send a response so the headers mean only that browser will understand you are sending a file of type Content-Type application/x-msdownload or application/zip. To limit the files from server directly you can try limiting the directory using .htaccess file and in the code you get the $id probably you could get the file object or details of the file(if you have any) and check its type before sending the response.
Example for limiting access to files in folder with extension
Deny access to specific file types in specific directory
you can customize the above as per your needs

Related

Twilio API: Can't download the jpeg file in an MMS

I've built an SMS/MMS Lightning Component in Salesforce that uses Twilio. (You don't need to know anything about Salesforce to answer this question.) I'm able to display incoming MMS images using the MediaUrl provided. For that, I just put the MediaUrl in the img tag in the markup. From there, if I right-click the image, I can save to my computer, and it defaults to the filename used when the file was sent.
Now, I want to add a button to save the image to Salesforce Files (ContentVersion object). To do that, I'm making an HTTP GET call, expecting to get back the data in mime-type image/jpeg -- but instead, I'm getting back this XML response:
<TwilioResponse>
<Media>
<Sid/>
<AccountSid>[myAccountSid]</AccountSid>
<ParentSid/>
<ContentType/>
<DateCreated>Tue, 20 Nov 2018 01:11:04 +0000</DateCreated>
<DateUpdated>Tue, 20 Nov 201801:11:04 +0000</DateUpdated>
<Uri>/2010-04-01/Accounts/[myAccountSid]/Messages/MM96803e1b66cf37deb1bcf044799dbf8c/Media/ME46739a78eb197409a4a031896a22cab7</Uri>
</Media>
</TwilioResponse>
The Twilio docs here say you can get the media in the original mime-type by not including the .xml or .json extension on the URL. I'm not including an extension, and I'm even specifying the image/jpeg mime-type in the header. But still, I get the xml.
So, I can't get the actual media, just xml (or json) data about the media. I saw another thread saying I need to use the Uri to access the data -- but the Uri returned is exactly the same URL I'm calling originally -- the MediaUrl provided when the MMS is received.
Second issue is... how can I get that original file name. The browser knows the file name (it appears by default if I right-click and select Save As...), but I can't see any way to access it through the Twilio API.
This happens when the client you are using doesn't follow all the redirects for a URL of a media object. I was using PHP with file_get_contents() on a PHP 7.3 server and it wasn't following all of the redirects like I would have expected it to. I was getting the XML only like you described. I switched to using Guzzle and everything worked great using this code:
$client = new \GuzzleHttp\Client();
$client->get(
$url,
[
'save_to' => 'test.jpg',
]);
The way I found this was using a library that I was more familiar with that allowed me to disable redirects and I got the same response I was getting with PHPs file_get_contents(). Once I found that I could always get the XML if redirects were disabled, it was much easier to make progress.
I couldn't ever get file_get_contents to work with Twilio media URLs and gave up trying. Even specifying follow_location with file_get_contents() did not work (even though this should be the default) I tried this code, setting follow_location as well as other header values when trying to figure this out DID NOT WORK:
$opts = [
"http" => [
"follow_location" => '1',
"header" => "User-Agent: my-awesome-bot/1.0.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close",
],
];
$context = stream_context_create($opts);
$media = file_put_contents('test.jpg', file_get_contents($url, false, $context));
# got XML for media object only, not the raw image data in test.jpg
As far as the original filename, I don't think that information is available from Twilio. It is possible that it isn't stored with the uploaded file as everything is referenced by the object, parent and/or account SIDs in all the APIs I've seen and the corresponding documentation.
Twilio's MMS urls redirect to an Amazon AWS url. So you have to first use curl to get what the Amazon URL is. Then you can fetch the contents of that amazon URL.
//set the url you're getting from twilio
$twilioUrl=$_POST['MediaUrl0'];
//use some curl to get where that url redirects to
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $twilioURL);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$a = curl_exec($ch);
//here's that amazon url
$amazonURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
//and now you can do stuff to it like get its contents
$contents=file_get_contents($amazonURL);

Is it possible to compose URL that forces browser to download file instead of play it?

Let say we have some file at http://somedomain.com/somedir/file.mp4.
When I send such URL to someone, I would like that browser start download, not play automatically.
Is it possible to compose URL in such manner to give browser instruction to start download instead of play it? With some parameter included maybe?
You can't do that by just sending the URL to someone.
What you can do is create a simple file which forces the user to download the file by setting the mime type of the response to octet/stream, which is the way of telling the browser the file can not embedded.
Below is an example in PHP taken from this website.
<?php
$file = $_GET['file'];
header ("Content-type: octet/stream");
header ("Content-disposition: attachment; filename=".$file.";");
header("Content-Length: ".filesize($file));
readfile($file);
exit;
?>

XML file generation to user specified location

I am generating a xml file using JAXB but at present file is generated at specified location,How can i use a browse button to specify the location of folder to save the generated file.
Have tried with input type="file" of HTML but it is useful for uploading the file.Want it to do from rich faces only.
Just write it directly to the HTTP response along with a Content-Disposition header with a value of attachment. This will force the browser to pop a Save As dialogue.
So, essentially all you need to do is to marshal the XML tree straight to the output stream of the HTTP response instead of the output stream of the file after having set the proper headers.
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
// ...
ec.responseReset(); // Make sure the response is clean and crisp.
ec.setResponseContentType("text/xml"); // Tell browser which application to associate with obtained response.
ec.setResponseCharacterEncoding("UTF-8"); // Tell browser how to decode the characters in obtanied response.
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // Tell browser to pop "Save As" dialogue to save obtained response on disk.
marshaller.marshal(model, ec.getResponseOutputStream()); // Look ma, just marshal JAXB model straight to the response body!
fc.responseComplete(); // Tell JSF that we've already handled the response ourselves so that it doesn't need to navigate.
Note: downloading a file via ajax is not possible. Remember to turn off the ajax feature of the RichFaces/Ajax4jsf command component invoking this method, if any.
See also:
How to provide a file download from a JSF backing bean?

how to set the save location in run time in mvc application

I need to set the save location in run time in mvc application . In windows appication we use the
System.Windows.Forms.SaveFileDialog();
But, what we use the web Application?
It is not clear what you want to save. In a web application you could use the file input to upload files to the server:
<input type="file" name="file" />
For more information about uploading files in an ASP.NET MVC application you may take a look at the following post.
If on the other hand you want the user to be able to download some file from the server and prompted for the location where he wants to save this file you could return a File result from a controller action and specify the MIME type and filename:
public ActionResult Download()
{
var file = Server.MapPath("~/App_Data/foo.txt");\
return File(file, "text/plain", "foo.txt");
}
There are also other overloads of the File method that allow you to dynamically generate a file and pass it as a stream to the client. But the important part to understand in a web application when downloading a file from a server is the Content-Disposition header. It has 2 possible values: inline and attachment. For example with the above code the following header will be added to the response:
Content-Type: text/plain
Content-Disposition: attachment; filename=foo.txt
... contents of the file ...
When the browser receives this response from the server it will prompt the user with a Save As dialog allowing him to choose the location on his computer to store the downloaded file.
UPDATE:
Here's how you could achieve similar in a web application:
public ActionResult Download()
{
var file1 = File.ReadAllLines(Firstfilpath);
var file2 = File.ReadAllLines(2ndfilpath);
var mergedFile = string.Concat(file1, file2);
return File(mergedFile, "text/plain", "result.txt");
}

Receive file from server in Chrome extension

I would like to connect my Chrome Extension to be able to download a file from my Ruby on Rails server. In particular, when the user clicks a button on the extension, the extension should send an AJAX request to the server, and then the server should send a file file.zip back to the user.
How would the server send a file back to the extension of the user?
On the Rails side, make sure the returned Content-Type header is application/zip. You can use #send_file or #send_data to send zip file to client. See ActionController::DataStreaming
Use #send_file
send_file '/path/to.zip', :type => 'application/zip'
Or use #send_data
zip_data = generate_zip_data()
send_data zip_data, :type => 'application/zip', :filename => 'data.zip'
For generating dynamic zip file, see other topics:
How can I generate zip file without saving to the disk with Ruby?
On google chrome extension, you might want to create new tab with the zip file url. That causes browser downloads file.
function buttonClickHandler() {
chrome.tabs.create({ url: "the url to zip file"}, function() {});
}

Resources