Skip to content

Error: Only HTTP(S) protocols are supported When Running Resize-Images Ext Locally #994

@vdiaz1130

Description

@vdiaz1130

Related issues

[REQUIRED] Version info

node: v14.17.5
npm: 7.23.0
firebase: 9.20.0

firebase-admin: ^9.11.1
firebase-functions": ^3.15.6

[REQUIRED] Test case

Code was copied from the extension Resize Image. All the dependencies were copied and/or installed as well.

const resizeImage = async (object): Promise<ResizedImageResult[]> => {
  logs.start();
  const { contentType } = object; // This is the image MIME type

  const tmpFilePath = path.resolve('/', path.dirname(object.name)); // Absolute path to dirname

  if (!contentType) {
    logs.noContentType();
    return;
  }

  if (!contentType.startsWith('image/')) {
    logs.contentTypeInvalid(contentType);
    return;
  }

  if (object.contentEncoding === 'gzip') {
    logs.gzipContentEncoding();
    return;
  }

  if (!supportedContentTypes.includes(contentType)) {
    logs.unsupportedType(supportedContentTypes, contentType);
    return;
  }

  if (config.includePathList && !startsWithArray(config.includePathList, tmpFilePath)) {
    logs.imageOutsideOfPaths(config.includePathList, tmpFilePath);
    return;
  }

  if (config.excludePathList && startsWithArray(config.excludePathList, tmpFilePath)) {
    logs.imageInsideOfExcludedPaths(config.excludePathList, tmpFilePath);
    return;
  }

  if (object.metadata && object.metadata.resizedImage === 'true') {
    logs.imageAlreadyResized();
    return;
  }

  const bucket = admin.storage().bucket(object.bucket);
  const filePath = object.name; // File path in the bucket.
  const fileDir = path.dirname(filePath);
  const fileExtension = path.extname(filePath);
  const fileNameWithoutExtension = extractFileNameWithoutExtension(filePath, fileExtension);
  const objectMetadata = object;

  let originalFile;
  let remoteFile: File;
  try {
    originalFile = path.join(os.tmpdir(), filePath);
    const tempLocalDir = path.dirname(originalFile);

    // Create the temp directory where the storage file will be downloaded.
    logs.tempDirectoryCreating(tempLocalDir);
    await mkdirp(tempLocalDir);
    logs.tempDirectoryCreated(tempLocalDir);

    // Download file from bucket.
    remoteFile = bucket.file(filePath);
    logs.imageDownloading(filePath);
    logs.imageDownloading(originalFile);
    await remoteFile.download({ destination: originalFile }); // **<- Offending line of code...**
    logs.imageDownloaded(filePath, originalFile);

    // Get a unique list of image types
    const imageTypes = new Set(config.imageTypes);

    // Convert to a set to remove any duplicate sizes
    const imageSizes = new Set(config.imageSizes);

    const tasks: Promise<ResizedImageResult>[] = [];

    imageTypes.forEach((format) => {
      imageSizes.forEach((size) => {
        tasks.push(
          modifyImage({
            bucket,
            originalFile,
            fileDir,
            fileNameWithoutExtension,
            fileExtension,
            contentType,
            size,
            objectMetadata: objectMetadata,
            format,
          }),
        );
      });
    });

    const results = await Promise.all(tasks);

    const failed = results.some((result) => result.success === false);
    if (failed) {
      logs.failed();
      return;
    } else {
      if (config.deleteOriginalFile === deleteImage.onSuccess) {
        if (remoteFile) {
          try {
            logs.remoteFileDeleting(filePath);
            await remoteFile.delete();
            logs.remoteFileDeleted(filePath);
          } catch (err) {
            logs.info('Catch 1');
            logs.errorDeleting(err);
          }
        }
      }
      logs.complete();
    }
  } catch (err) {
    logs.info('Catch 2');
    logs.error(err);
  } finally {
    if (originalFile) {
      logs.tempOriginalFileDeleting(filePath);
      fs.unlinkSync(originalFile);
      logs.tempOriginalFileDeleted(filePath);
    }
    if (config.deleteOriginalFile === deleteImage.always) {
      // Delete the original file
      if (remoteFile) {
        try {
          logs.remoteFileDeleting(filePath);
          await remoteFile.delete();
          logs.remoteFileDeleted(filePath);
        } catch (err) {
          logs.errorDeleting(err);
        }
      }
    }
  }
};

[REQUIRED] Steps to reproduce

I've copied over the Resize Images extension locally. The difference I see is the version in the extension's package.json for the following:

"firebase-admin": "^8.0.0",
"firebase-functions": "^3.13.2",

vs what I have locally:
"firebase-admin": "^9.11.1",
"firebase-functions": "^3.15.6",

[REQUIRED] Expected behavior

when executing await remoteFile.download({ destination: originalFile }); it should download the original file. This code is exactly the same as the extension code.

[REQUIRED] Actual behavior

the following error is logged out:

{
  "severity":"ERROR","message":"Error when resizing image TypeError: Only HTTP(S) protocols are supported
    at getNodeRequestOptions (.../node_modules/teeny-request/node_modules/node-fetch/lib/index.js:1309:9)
    at .../node_modules/teeny-request/node_modules/node-fetch/lib/index.js:1410:19
    at new Promise (<anonymous>)
    at Function.fetch [as default] (.../node_modules/teeny-request/node_modules/node-fetch/lib/index.js:1407:9)
    at teenyRequest (.../node_modules/teeny-request/build/src/index.js:184:29)
    at Object.request (.../node_modules/teeny-request/build/src/index.js:241:20)
    at Timeout.makeRequest [as _onTimeout] (.../node_modules/retry-request/index.js:139:28)
    at listOnTimeout (internal/timers.js:557:17)
    at processTimers (internal/timers.js:500:7)"
}

Were you able to successfully deploy your functions?

I am testing in the emulator and have not deployed it. Code functionality is not complete as this error is blocking.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions