-1

I am currently working on a file upload module for my webapp, which will allow user uploads.

Every time I upload a file (png, jpg, pdf, etc), the file arrives in the S3 bucket as a TMP file.

I believe I am doing the right thing, as apache should store the file as a tmp file first, and then it should be successfully uploaded. But for some reason the files do not get converted back to their actual file type. Please help, code below:

Index.php

<html>
    <body>
        <form action="http://localhost:7777/centresafe/s3test/upload-form.php" method="post" enctype="multipart/form-data">
              Select image to upload:
              <input type="file" name="fileToUpload" id="fileToUpload">
              <input type="submit" value="Upload Image" name="submit">
        </form>
    </body>
</html>

upload-form.php

    require 'C:\xampp\htdocs\webapp/vendor/autoload.php';
    
    use Aws\S3\S3Client;
    use Aws\S3\Exception\S3Exception;

    // AWS Info
    $bucketName = 'webapp';
    $IAM_KEY = 'MY_KEY';
    $IAM_SECRET = 'MY_SECRET';

    // Connect to AWS
    try {
        // You may need to change the region. It will say in the URL when the bucket is open
        // and on creation.
        $s3 = S3Client::factory(
            array(
                'credentials' => array(
                    'key' => $IAM_KEY,
                    'secret' => $IAM_SECRET
                ),
                'version' => 'latest',
                'region'  => 'ap-southeast-2'
            )
        );
    } catch (Exception $e) {
        // We use a die, so if this fails. It stops here. Typically this is a REST call so this would
        // return a json object.
        die("Error: " . $e->getMessage());
    }

    
    // For this, I would generate a unqiue random string for the key name. But you can do whatever.
    $keyName = 'test_example/' . basename($_FILES["fileToUpload"]['tmp_name']);
    $pathInS3 = 'https://s3.ap-southeast-2.amazonaws.com/' . $bucketName . '/' . $keyName;

    print_r($_FILES);
$file = $_FILES["fileToUpload"]['tmp_name'];
echo "<br>";
echo $file;

    exit;
    // Add it to S3
    try {
        // Uploaded:
        $file = $_FILES["fileToUpload"]['tmp_name'];

        $s3->putObject(
            array(
                'Bucket'=>$bucketName,
                'Key' =>  $keyName,
                'SourceFile' => $file,
                'StorageClass' => 'REDUCED_REDUNDANCY'
            )
        );

    } catch (S3Exception $e) {
        die('Error:' . $e->getMessage());
    } catch (Exception $e) {
        die('Error:' . $e->getMessage());
    }


    echo 'Done';

    // Now that you have it working, I recommend adding some checks on the files.
    // Example: Max size, allowed file types, etc.
?>```

cTho
  • 57
  • 3

1 Answers1

3

This has nothing to do with S3, and files don't have a type, they have names. When you say "it's uploading a TMP file", what you're seeing is that it's uploading a file with "tmp" in its name. This shouldn't be surprising, because you have this line:

$keyName = 'test_example/' . basename($_FILES["fileToUpload"]['tmp_name']);

Note the key you're using is called "tmp_name" - it's the temporary name assigned to the uploaded file by PHP. If you want to use the name specified by the user, you need to look at "name" - although beware that like all input from the user it should be considered "untrusted", as in someone could specify whatever name they wanted, unrelated to the actual content of the file. See the manual page on file uploads.

If you want to name the file based on what's actually in it, you need to examine its content, for instance using the finfo functions. You can then generate your own file names with an expected "extension" for that file type, e.g. $randomString . '.pdf' if it's a PDF file.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • 1
    @AnonCoward I'm not sure what you mean. The reason PHP picks a random name is that you can't trust the filename or type information from the client; the reason to give it a different name is to label it with the correct type for the next person to download it. S3, file system, database, wherever, both of those reasons still apply. – IMSoP Feb 14 '21 at 18:35