MediaRecorder's Ajax post failed;Could not GET

PennController for IBEX Forums Support MediaRecorder's Ajax post failed;Could not GET

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #8250
    bgardner
    Participant

    Hi!

    I’m just about ready to launch my experiment, and I’m trying to get it hooked up to an AWS bucket following the instructions here: https://doc.pcibex.net/how-to-guides/sending-recordings-to-an-s3-bucket/ Putting the API gateway URL into my experiment and into the MediaRecorder template gives the error “MediaRecorder’s Ajax post failed;Could not GET [my url]” after async() and SendResults().

    I’ve gone through my setup a couple of times and it follows the instructions as exactly as possible (the UI seems to have changed a bit):

    * Created the S3 bucket, with no public access allowed. (Right now I have the version control on, which wasn’t mentioned in the instructions, but it also doesn’t work with that turned off).

    * Put this code in the CORS section of permissions, and left everything else default:

    [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "POST"
            ],
            "AllowedOrigins": [
                "https://farm.pcibex.net"
            ],
            "ExposeHeaders": [],
            "MaxAgeSeconds": 3000
        }
    ]

    * Left the S3 bucket section and went to the Lambda tools. Went through the “create from scratch” and gave it a name, left everything else the same.

    * It looks like the UI here is a little different from when the screenshots were taken? I went down to “code source” and put the javascript code (but with my bucket name) into the editor, which was setup to save it as index.js

    /*global crypto*/
    const crypto = require("crypto");
    const CreateUUID = () =>
      ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
        (c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)
      );
    const S3 = require("aws-sdk/clients/s3");
    
    /**
    * Use AWS SDK to create pre-signed POST data.
    * We also put a file size limit (100B - 10MB).
    * @param key
    * @param contentType
    * @returns {Promise<object>}
    */
    const createPresignedPost = ({ key, contentType }) => {
      const s3 = new S3();
      console.log("key",key,"contentType",contentType);
      const params = {
        Expires: 60,
        Bucket: "4examplebucket123",
        Fields: {
          "Content-Type": contentType,
          key
        }
      };
      return new Promise(async (resolve, reject) => {
        s3.createPresignedPost(params, (err, data) => {
          if (err) {
            reject(err);
            return;
          }
          resolve(data);
        });
      });
    };
    /**
    * We need to respond with adequate CORS headers.
    * @type Access-Control-Allow-Origin
    */
    const headers = {
      "Access-Control-Allow-Origin": "https://farm.pcibex.net",
      "Access-Control-Allow-Credentials": true,
      "Access-Control-Allow-Methods": "OPTIONS,GET",
      "Access-Control-Allow-Headers": "content-type"
    };
    module.exports.getPresignedPost = async (event,context) => {
      try {
        const { filename , mimetype } = event.queryStringParameters;
        const presignedPostData = await createPresignedPost({
          key: <code>${CreateUUID()}_${filename}</code>,
          contentType: mimetype
        });
        const r = presignedPostData.fields;
        r.url = presignedPostData.url;
        return {
          statusCode: 200,
          headers,
          body: JSON.stringify(r)
        };
      } catch (e) {
        return {
          statusCode: 500,
          headers,
          body: JSON.stringify({
            error: true,
            data: null,
            message: e.message
          })
        };
      }
    };

    * Went to Configuration > Permissions > Execution Role > Role name. In the new window that opens, Permissions policies > Add permissions > Create inline policy > switch to JSON view and enter (with my bucket name)

    {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::4examplebucket123/*"
        }
      ]
    }

    * Went back to Lambda editor > Permissions > Execution role and added the permission policy I just made. Here, there was also a default permission policy added. It didn’t work with or without it included.

    * Went to Code > Runtime settings and changed the handler to “index.getPresignedPost”, deployed

    * Went up to Function overview > Add trigger. That opens a trigger configuration window, and I selected API Gateway > Create a new API > AI Type: HTTP, and then didn’t do anything to the other security settings.

    * Copied the API Gateway URL into the InitiateRecorder trial

    Do you have any idea what could be wrong? Thanks!

    #8260
    Jeremy
    Keymaster

    Hi,

    Apologies for the late reply. Do you mind sharing the link to your experiment and API gateway URL with me, here or at support@pcibex.net so I can proceed to some tests for troubleshooting? Thank you

    EDIT: after an email exchange, it was determined that this was a case of Cross-Origin Resource Sharing (CORS) misconfiguration on the API gateway’s side that comes with the default configuration. It was fixed by opening the API gateway in the AWS console, visiting the CORS tab, and then clicking the “Clear” button: after that, the API allows the Lambda function to return the headers, including the CORS-relevant ones

    Jeremy

    • This reply was modified 1 year, 9 months ago by Jeremy. Reason: problem solved
Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.