Skip to content

Instantly share code, notes, and snippets.

@aaronpk
Last active March 6, 2021 23:47
  • Select an option

Select an option

Revisions

  1. aaronpk revised this gist Sep 29, 2018. 1 changed file with 62 additions and 38 deletions.
    100 changes: 62 additions & 38 deletions media-endpoint.php
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,4 @@
    <?php
    $token_endpoint = 'https://tokens.indieauth.com/token';
    $base_url = 'https://media.aaronpk.com/';

    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: Authorization');

    @@ -34,7 +31,7 @@
    $token = $match[1];

    // Check whether the access token is valid
    $ch = curl_init($token_endpoint);
    $ch = curl_init('https://aaronparecki.com/auth/token');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $token,
    @@ -60,41 +57,64 @@
    die();
    }

    // Check for a file
    if(!array_key_exists('file', $_FILES)) {
    header('HTTP/1.1 400 Bad Request');
    echo json_encode([
    'error' => 'invalid_request',
    'error_description' => 'The request must have a file upload named "file"'
    ]);
    die();
    }

    $file = $_FILES['file'];

    $ext = mime_type_to_ext($file['type']);
    if(!$ext) {
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    if(!$ext)
    $ext = 'txt';
    }
    $filename = 'file-'.date('YmdHis').'-'.mt_rand(1000,9999).'.'.$ext;

    copy($file['tmp_name'], $filename);

    $url = $base_url . $filename;
    header('HTTP/1.1 201 Created');
    header('Location: '.$url);

    if($format == 'text') {
    echo $url."\n";
    if(isset($_GET['q'])) {

    switch($_GET['q']) {
    case 'last':
    $url = null;
    if(file_exists('.last')) {
    // Only use the file if it was uploaded in the last 5 minutes
    if(filemtime('.last') >= time() - 300) {
    $filename = trim(file_get_contents('.last'));
    $url = 'https://media.aaronpk.com/' . $filename;
    }
    }
    echo json_encode([
    'url' => $url
    ]);
    break;
    }

    } else {
    echo json_encode([
    'url' => $url
    ]);
    }



    // Check for a file
    if(!array_key_exists('file', $_FILES)) {
    header('HTTP/1.1 400 Bad Request');
    echo json_encode([
    'error' => 'invalid_request',
    'error_description' => 'The request must have a file upload named "file". Found: '.implode(', ',array_keys($_POST))
    ]);
    die();
    }

    $file = $_FILES['file'];

    $ext = mime_type_to_ext($file['type']);
    if(!$ext) {
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    if(!$ext)
    $ext = 'txt';
    }
    $filename = 'file-'.date('YmdHis').'-'.mt_rand(1000,9999).'.'.$ext;

    copy($file['tmp_name'], $filename);

    file_put_contents('.last', $filename);

    $url = 'https://media.aaronpk.com/' . $filename;
    header('HTTP/1.1 201 Created');
    header('Location: '.$url);

    if($format == 'text') {
    echo $url."\n";
    } else {
    echo json_encode([
    'url' => $url
    ]);
    }
    }


    function mime_type_to_ext($type) {
    $types = [
    @@ -126,6 +146,10 @@ function mime_type_to_ext($type) {
    ];
    if(array_key_exists($type, $types))
    return $types[$type];
    else
    else {
    $fp = fopen('content-types.txt', 'a');
    fwrite($fp, "Unrecognized: $type\n");
    fclose($fp);
    return false;
    }
    }
  2. aaronpk revised this gist Feb 20, 2018. 1 changed file with 1 addition and 5 deletions.
    6 changes: 1 addition & 5 deletions media-endpoint.php
    Original file line number Diff line number Diff line change
    @@ -126,10 +126,6 @@ function mime_type_to_ext($type) {
    ];
    if(array_key_exists($type, $types))
    return $types[$type];
    else {
    $fp = fopen('content-types.txt', 'a');
    fwrite($fp, "Unrecognized: $type\n");
    fclose($fp);
    else
    return false;
    }
    }
  3. aaronpk created this gist Jul 27, 2017.
    135 changes: 135 additions & 0 deletions media-endpoint.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,135 @@
    <?php
    $token_endpoint = 'https://tokens.indieauth.com/token';
    $base_url = 'https://media.aaronpk.com/';

    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: Authorization');

    if(isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'text/plain') !== false) {
    $format = 'text';
    } else {
    header('Content-Type: application/json');
    $format = 'json';
    }

    // Require access token
    if(!array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) {
    header('HTTP/1.1 401 Unauthorized');
    echo json_encode([
    'error' => 'unauthorized',
    'error_description' => 'No authorization header was present in the request'
    ]);
    die();
    }

    if(!preg_match('/Bearer (.+)/', $_SERVER['HTTP_AUTHORIZATION'], $match)) {
    header('HTTP/1.1 400 Bad Request');
    echo json_encode([
    'error' => 'invalid_authorization',
    'error_description' => 'Invalid authorization header'
    ]);
    die();
    }

    $token = $match[1];

    // Check whether the access token is valid
    $ch = curl_init($token_endpoint);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $token,
    'Accept: application/json'
    ]);
    $response = curl_exec($ch);

    $data = json_decode($response, true);

    if(!$data || !array_key_exists('scope', $data)) {
    header('HTTP/1.1 401 Unauthorized');
    echo $response;
    die();
    }

    // Only tokens with "create" or "media" scope can upload files
    if(!array_intersect(['create','media'], $data['scope'])) {
    header('HTTP/1.1 401 Unauthorized');
    echo json_encode([
    'error' => 'insufficient_scope',
    'error_description' => 'The access token provided does not have the necessary scope to upload files'
    ]);
    die();
    }

    // Check for a file
    if(!array_key_exists('file', $_FILES)) {
    header('HTTP/1.1 400 Bad Request');
    echo json_encode([
    'error' => 'invalid_request',
    'error_description' => 'The request must have a file upload named "file"'
    ]);
    die();
    }

    $file = $_FILES['file'];

    $ext = mime_type_to_ext($file['type']);
    if(!$ext) {
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    if(!$ext)
    $ext = 'txt';
    }
    $filename = 'file-'.date('YmdHis').'-'.mt_rand(1000,9999).'.'.$ext;

    copy($file['tmp_name'], $filename);

    $url = $base_url . $filename;
    header('HTTP/1.1 201 Created');
    header('Location: '.$url);

    if($format == 'text') {
    echo $url."\n";
    } else {
    echo json_encode([
    'url' => $url
    ]);
    }



    function mime_type_to_ext($type) {
    $types = [
    'image/jpeg' => 'jpg',
    'image/pjpeg' => 'jpg',
    'image/gif' => 'gif',
    'image/png' => 'png',
    'image/x-png' => 'png',
    'image/svg' => 'svg',
    'audio/x-wav' => 'wav',
    'audio/wave' => 'wav',
    'audio/wav' => 'wav',
    'video/mpeg' => 'mpg',
    'video/quicktime' => 'mov',
    'video/mp4' => 'mp4',
    'audio/x-m4a' => 'm4a',
    'audio/mp3' => 'mp3',
    'audio/mpeg3' => 'mp3',
    'audio/mpeg' => 'mp3',
    'application/json' => 'json',
    'text/json' => 'json',
    'text/html' => 'html',
    'text/plain' => 'txt',
    'application/xml' => 'xml',
    'text/xml' => 'xml',
    'application/x-zip' => 'zip',
    'application/zip' => 'zip',
    'text/csv' => 'csv',
    ];
    if(array_key_exists($type, $types))
    return $types[$type];
    else {
    $fp = fopen('content-types.txt', 'a');
    fwrite($fp, "Unrecognized: $type\n");
    fclose($fp);
    return false;
    }
    }