Use Case: I am working on an image uploader which uses ajax upload function.I want to upload images to a subdomain user creates on the website.For example,when the user creates a domain on the website I copy a php script for uploading images to the new domain viz image-cropping.php.I want to send a request to this file when the user uploads any image to his domain.
Issue:When I try to upload an image I get Error: Permission denied to access property 'readyState'.My calling js file is on xyz.google.com and the upload php script is on abc.google.com.
Research
After doing some googling and research I learnt javascript won't allow to send request cross domain and it needs a http proxy to handle this.Here is the code I have tried.The script to run the ajax uploader.In action I have the path to file on other domain(the path is built dynamically).
new AjaxUpload(btnUpload, {
action: 'includes/modules/domain_creation/proxy.php',
name: 'image',
onSubmit: function(file, ext){
if (! (ext && /^(jpg|png|jpeg|gif|JPG|JPEG|PNG|GIF)$/.test(ext))){
alert('Only JPG, PNG or GIF files are allowed');
return false;
}
$('#thumbImg').html('<img src="http://localhost/gobiggi_VS_2_2/images/appImages/imageLoader.png" />');
},
1) Am I doing it in the right way(working on it for first time)?Is the proxy actually needed?2)How and where can I set the proxy so that the error permission can be negotiated?3)What security issues does it open up(Is it safe?If not what's an alternative)?Any pointers or suggestions would be helpful for me.Thank you for your time.
Update:
I am using this proxy script for uploading the image.Part of the code is
$domainUsername = $_SESSION['domainUsername'];
$domainNameWeb = $_SESSION['domainName'];
//$fileParameterProxy = $_FILES['image'];
//Destination URL: Where this proxy leads to the upload script
$destinationURL = 'http://www.'.$domainNameWeb.'/'.$domainUsername.'/upload.php';
//The only domain from which requests are authorized.
$RequestDomain = 'abc.net';
Now I don't get the Error for permission but I am not able to get the image on to the server.When I try to do print_r($_FILES) I get a blank array on my upload script.
I believe I am missing something!!Can someone please correct?
Thank you for your time!
1 and 2) You have to set your proxy as action, because that is the place where you are allowed to upload the files. The proxy then will do the request to the other domain, where it can send the files to.
3) Depends on your proxy implementation. You should avoid to store the files locally or execute/include anything from user input, like always when writing php scripts. Directly send the tmp file to your destination server, this will also be the fastest implementation.
Related
I was wondering if any one can help with following issue.
I have an Api with node/express for image uploads
server1
var upload = multer({ dest: 'uploads/'})
app.post('/api/upload', upload.single('file'), function(req, res, next) {
if (req.file && req.file.path) {
//used to have imgur upload
//imgur.uploadFile(req.file.path)
// .then(function (json) {
//});
}
});
server2
I have PHP Api for image uploads as well which I have set up for self-hosting using pictshare. I want to redirect file uploads to new API by redirecting uploads to PHP Api server.
Have tried multer, multiparty, needle, request and various other methods... but somehow couldn't figure out.
Is there way to direct multer to new destination?
File is being saved in uploads/ folder, maybe better would be to upload/direct that file to new server and return new url from server2 ?
Looked around for pipelining upload images, with not much luck..
note: server1 api is being used by mobile app so wouldn't want to release app update if it can be handled from server side.
To upload a file (image or whatever) you need to have it in your drive first (or in memory, but I will tackle the drive case first). Then you can read it and send it.
The APIs that receive files use to receive forms. Usually they expect to receive a form where the attachment comes as a file field.
Here you can see a working example uploading an existing file in my drive to an external API by using the 'superagent' library for Node.
const
fs = require('fs'),
agent = require('superagent');
const stream = fs.createReadStream('path/to/downloaded/file');
agent.post(`urlOfApi/uploadFileEndpoint`)
.type('form')
.attach('file', stream.path);
Sorry if I did not get this title right.
I have in my server the redirect.php script that receives a URL passed by the client user, fetches the content using file_get_contents() function and them shows it to the user with echo() function.
The problem is when the user points directly to a PDF or JPG file in that URL and them the script shows the file contents as binary code.
When I set the code to recognize when the requested URL points directly to a downloadable file,
What should be the function or header to echo to the user so that his browser ask him to download the file insted of showing it?
Do I have to first put it into a file inside my server or can I do it directly from a command like file_get_contents()? If I can do that without writing it to my server, it would be a much better approuch.
I can't point directly to the server because some sites are blocked by my employee and the third party company that does this service thinks that StakExchenge sites are malicious and not constructive and were tegged as online communities like Facebook.
Try this:
$sourcefile = "http://www.myremotewebsite.com/myfile.jpg";
$destfile = "myfile.jpg";
copy($sourcefile, $destfile);
I'm using AWS PHP sdk to save images on S3. Files are saved privately. Then, I'm showing the image thumbnails using the S3 file url in my web application but since the files are private so the images are displayed as corrupt.
When the user clicks on the name of file, a modal is opened to show the file in larger size but file is displayed as corrupt there as well due to the same issue.
Now, I know that there are two ways to make this working. 1. Make the files public. 2. Generate pre-signed urls for files. But I cannot go with any of these two options due to the requirements of my project.
My question is that is there any third way to resolve this issue?
I'd highly advise against this, but you could create a script on your own server that pulls the image via the API, caches it and serves. You can then restrict access however you like without making the images public.
Example pass through script:
$headers = get_headers($realpath); // Real path being where ever the file really is
foreach($headers as $header) {
header($header);
}
$filename = $version->getFilename();
// These lines if it's a download you want to do
// header('Content-Description: File Transfer');
// header("Content-Disposition: attachment; filename={$filename}");
$file = fopen($realpath, 'r');
fpassthru($file);
fclose($file);
exit;
This will barely "touch the sides" and shouldn't delay the appearance of your files too much, but t's still going to take some resources and bandwidth.
You will need to access the files through a script on your server. That script will do some kind of authentication to make sure the request is valid and you want them to see the file. Then fetch the file from S3 using a valid IAM profile that can access the private files. Output the file
Instead of requesting the file from S3 request it from
http://www.yourdomain.com/fetchimages.php?key=8498439834
Then here is some pseudocode in fetchimages.php
<?php
//if authorized to get this image
$key=$_GET['key'];
//validate key is the proper format
//get s3 url from a database based on the $key
//connect to s3 securely and read the file from s3
//output the file
?>
as far as i know you could try to make your S3 bucket a "web server" like this but then you would probably "Make the files public".Then if you have some kind of logic to restrict the access you could create a bucket policy
uploading image with file_put_contents make 0 byte file.
here is the code that I use. I extract facebook image url and put it into web server.
$fb_image_url = 'https://example.com/229282.jpg'
$filename = substr($fb_image_url, strrpos($fb_image_url, '/') + 1);
file_put_contents('upload/user_pic/original/'.$filename, file_get_contents($fb_image_url));
after I do this, the server receive file name successfully, but it is 0 bytes.
I checked php.ini, and allow_url_fopen is ON.
uploading folder permission is also fine.
To copy images from facebook, script/php program require permission for same. if program/ FB API dont passes validation/permission check, FB dont allows to download any image.
Its looks like your Application don't have permission to download/copy this image from Facebook that's why your getting 0 bytes.
Try giving PUBLIC access to image and keep FB account logged in while coping image
I just put that URL into the browser:
https://fbcdn-profile-a.akamaihd.net/hprofile-ak-snc4/274661_1171545457_6475606_n.jpg
And received 404 Not Found in response. This would explain why you get empty file locally. I strongly suggest that you load the data first, verify what you received and then, if validation passes, save it locally.
here is the solution.
I had a problem with facebook profile address.
$fb_image_url = 'https://graph.facebook.com/'.$facebook_id.'/picture?type=large';
$filename = $fb_id.'_'.time().'.jpg';
$result = file_get_contents($fb_image_url);
file_put_contents('upload/user_pic/original/'.$filename, $result);
with this_ it worked fine. Yeah! Thank you everyone!
I'm writing a web app that at one point allows a user to upload a photo to a flickr account (mine). I want to do this without saving the intermediate image on the server my web app is on.
What I've got so far is a page which implements phpFlickr and accepts a POST from a simple html form. I use $_FILES['file']['tmp_name'] as the path for phpFlickr to use. Here's the code:
<?php
require_once("phpFlickr.php");
$f = new phpFlickr("apikey", "secret", true);
$_SESSION['phpFlickr_auth_redirect'] = "post_upload.php";
$myPerms = $f->auth("write");
$token = $f->auth_checkToken();
$phid = $f->sync_upload($_FILES['file']['tmp_name']);
echo "Uploading Photo..." . $phid;
?>
I'm guessing that the tmp file is being lost because of the redirect that happens when $f->auth("write") is called, but I don't know. Is there a way to preserve it? Is there any way to do this without saving the file to the server?
Answer: There is No way to directly upload a file to Flickr without saving it as an intermediate file.
I've moved on to using move_uploaded_file() followed by a flickr API call, and its working perfectly.
I've also managed to get it to play nice with the excellent Jquery Uploadify, which lets me send multiple files to it in one go.