Skip to content
This repository

Fixed invalid detection of MIME type with upper case file extensions. #33

Closed
wants to merge 5 commits into from

2 participants

Brady Doll Jeremy Lindblom
Brady Doll

When using the S3->create_object() function with the 'fileUpload' option without manually setting the 'contentType', if the file path passed with this option has an extension with either all caps or mixed case, then the file will always be detected as the 'application/octect-stream' MIME type. This is due to this block of code in the s3.class.php file (line 735):

$extension = explode('.', $opt['fileUpload']);
$extension = array_pop($extension);
$mime_type = CFMimeTypes::get_mimetype($extension);
$headers['Content-Type'] = $mime_type;

The extension is pulled straight from the fileUpload option and passed to the CFMimeTypes::get_mimetype() function.

That function is relatively simple:

public static function get_mimetype($ext)
{
    return (isset(self::$mime_types[$ext]) ? self::$mime_types[$ext] : 'application/octet-stream');
}

Just check if the extension exists in the $mime_types array. However, all of the array keys are lower case so an upper or mixed case extension will never match.

A simple fix, included in my pull request, is to change the function CFMimeTypes::get_mimetype() to:

public static function get_mimetype($ext)
{
    $ext = strtolower( $ext );  // Make sure the passed extension is lowercase
    return (isset(self::$mime_types[$ext]) ? self::$mime_types[$ext] : 'application/octet-stream');
}

This will ensure that the check happens with a lowercase extension and resolves the MIME detection error.

I've also included the files _samples/s3_mime_error.php and _samples/test_files/plain2.TXT (which is just a copy of plain.txt), which demonstrate the issue.

Brady Doll

I wanted to also point out that this can't be resolve by simply doing:

s3->create_object( $bucket, $filename, array( 'fileUpload' => strtolower( $file ) ) );

This would not be the same file on case sensitive file systems (although this would work on Windows).

Jeremy Lindblom
Owner

Makes sense, I'll look into it and see if we can get into an upcoming version. We can't accept pull requests directly right now, but we'll make sure you are added to the contributors document.

Jeremy Lindblom
Owner

I've made the changes in my local copy and have added you to the CONTRIBUTORS doc. Your changes will appear in the next version of the SDK. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
137 _samples/s3_mime_error.php
... ... @@ -0,0 +1,137 @@
  1 +<?php
  2 +/*
  3 + * Copyright 2010-2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4 + *
  5 + * Licensed under the Apache License, Version 2.0 (the "License").
  6 + * You may not use this file except in compliance with the License.
  7 + * A copy of the License is located at
  8 + *
  9 + * http://aws.amazon.com/apache2.0
  10 + *
  11 + * or in the "license" file accompanying this file. This file is distributed
  12 + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13 + * express or implied. See the License for the specific language governing
  14 + * permissions and limitations under the License.
  15 + */
  16 +
  17 +/*
  18 + PREREQUISITES:
  19 + In order to run this sample, I'll assume a few things:
  20 +
  21 + * You already have a valid Amazon Web Services developer account, and are
  22 + signed up to use Amazon S3 <http://aws.amazon.com/s3>.
  23 +
  24 + * You already understand the fundamentals of object-oriented PHP.
  25 +
  26 + * You've verified that your PHP environment passes the SDK Compatibility Test.
  27 +
  28 + * You've already added your credentials to your config.inc.php file, as per the
  29 + instructions in the Getting Started Guide.
  30 +
  31 + TO RUN:
  32 + * Run this file on your web server by loading it in your browser, OR...
  33 + * Run this file from the command line with `php s3_mime_error.php`.
  34 +*/
  35 +
  36 +
  37 +/*%******************************************************************************************%*/
  38 +// SETUP
  39 +
  40 + // Enable full-blown error reporting. http://twitter.com/rasmus/status/7448448829
  41 + error_reporting(-1);
  42 +
  43 + // Set plain text headers
  44 + header("Content-type: text/plain; charset=utf-8");
  45 +
  46 + // Include the SDK
  47 + require_once '../sdk.class.php';
  48 +
  49 +
  50 +/*%******************************************************************************************%*/
  51 +// UPLOAD FILES TO S3
  52 +
  53 + // Instantiate the AmazonS3 class
  54 + $s3 = new AmazonS3();
  55 +
  56 + // Determine a completely unique bucket name (all lowercase)
  57 + $bucket = 'temp-bucket-' . strtolower($s3->key) . '-' . time();
  58 +
  59 + // Create our new bucket in the US-West region.
  60 + $create_bucket_response = $s3->create_bucket($bucket, AmazonS3::REGION_US_W1);
  61 +
  62 + // Provided that the bucket was created successfully...
  63 + if ($create_bucket_response->isOK())
  64 + {
  65 + /* Since AWS follows an "eventual consistency" model, sleep and poll
  66 + until the bucket is available. */
  67 + $exists = $s3->if_bucket_exists($bucket);
  68 + while (!$exists)
  69 + {
  70 + // Not yet? Sleep for 1 second, then check again
  71 + sleep(1);
  72 + $exists = $s3->if_bucket_exists($bucket);
  73 + }
  74 +
  75 + /*
  76 + Get a list of files to upload. We'll use some helper functions we've
  77 + defined below. This assumes that you have a directory called "test_files"
  78 + that actually contains some files you want to upload.
  79 + */
  80 + $list_of_files = filter_file_list(glob('./test_files/*'));
  81 +
  82 + // Prepare to hold the individual filenames
  83 + $individual_filenames = array();
  84 +
  85 + // Loop over the list, referring to a single file at a time
  86 + foreach ($list_of_files as $file)
  87 + {
  88 + // Grab only the filename part of the path
  89 + $filename = explode(DIRECTORY_SEPARATOR, $file);
  90 + $filename = array_pop($filename);
  91 +
  92 + // Store the filename for later use
  93 + $individual_filenames[] = $filename;
  94 +
  95 + /* Prepare to upload the file to our new S3 bucket. Add this
  96 + request to a queue that we won't execute quite yet. */
  97 + $s3->batch()->create_object($bucket, $filename, array(
  98 + 'fileUpload' => $file
  99 + ));
  100 + }
  101 +
  102 + /* Execute our queue of batched requests. This may take a few seconds to a
  103 + few minutes depending on the size of the files and how fast your upload
  104 + speeds are. */
  105 + $file_upload_response = $s3->batch()->send();
  106 +
  107 + /* Since a batch of requests will return multiple responses, let's
  108 + make sure they ALL came back successfully using `areOK()` (singular
  109 + responses use `isOK()`). */
  110 + if ($file_upload_response->areOK())
  111 + {
  112 + // Loop through the individual filenames
  113 + foreach ($individual_filenames as $filename)
  114 + {
  115 + // Display the file content types
  116 + echo $filename . ' ';
  117 + echo $s3->get_object_headers( $bucket, $filename )->header['content-type'];
  118 + echo PHP_EOL . PHP_EOL;
  119 + }
  120 + }
  121 + }
  122 +
  123 +
  124 +/*%******************************************************************************************%*/
  125 +// HELPER FUNCTIONS
  126 +
  127 + // Filters the list for only files
  128 + function filter_file_list($arr)
  129 + {
  130 + return array_values(array_filter(array_map('file_path', $arr)));
  131 + }
  132 +
  133 + // Callback used by filter_file_list()
  134 + function file_path($file)
  135 + {
  136 + return !is_dir($file) ? realpath($file) : null;
  137 + }
1  _samples/test_files/plain2.TXT
... ... @@ -0,0 +1 @@
  1 +This is a sample file that I'm uploading to S3.
1  utilities/mimetypes.class.php
@@ -218,6 +218,7 @@ class CFMimeTypes
218 218 */
219 219 public static function get_mimetype($ext)
220 220 {
  221 + $ext = strtolower( $ext ); // Make sure the passed extension is lowercase
221 222 return (isset(self::$mime_types[$ext]) ? self::$mime_types[$ext] : 'application/octet-stream');
222 223 }
223 224 }

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.