Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for application/octet-stream uploads and file chunking #9

Open
jlevycpa opened this issue Sep 21, 2016 · 3 comments
Open

Support for application/octet-stream uploads and file chunking #9

jlevycpa opened this issue Sep 21, 2016 · 3 comments

Comments

@jlevycpa
Copy link
Contributor

This looks like a great addon. I like the approach of using a service a lot. For me to use this in my project I would need two things. First, I need to support sending uploads without multipart/form-data encoding. Basically I would just put the blob content in the request body and use application/octet-stream as the content type.

Would you be interested in a PR to add this as an option? Maybe options.encoding with options form (default) or octet?

Second, I'd like to see an option to upload large files using chunking. One way to achieve this would be to depend on something like resumable.js. Is this a direction you are interested in?

Please let me know your thoughts. Thanks!

@tim-evans
Copy link
Collaborator

Yeah, that'd be awesome!

@jelhan
Copy link
Collaborator

jelhan commented Mar 14, 2020

Support for application/octet-stream should be added by #12. Upload in chunks is not supported yet as far as I know. This would either add a lot of additional complexity or require another dependency to be pushed to all consumers. To be honest I'm not sure if this is reasonable for a feature which is only needed for a few special cases. Maybe this is more something for a specialized ember-file-upload-resumable addon? Tending towards closing this one as won't fix.

@fsmanuel
Copy link

fsmanuel commented Oct 16, 2020

I implemented a way to upload the files in chunks. It needs some minor tweeks in the upload and normalizeOptions functions. Let me know what you think and if it's worth to open a PR.

export default function uploadChunks(file, url, opts) {
  let size = get(file, 'size');
  let type = get(file, 'type');

  // Chunk
  let chunkSize = opts.chunkSize || 2000000; // 2 MB
  let chunkStart = opts.chunkStart || 0;
  let chunkEnd = Math.min(chunkStart + chunkSize, size);
  let chunk = get(file, 'blob').slice(chunkStart, chunkEnd, type);

  let filename = get(file, 'name');
  let filenameEncoded = encodeURI(filename)

  // Headers
  opts.headers = {};
  opts.headers['Content-Range'] = `bytes ${chunkStart}-${chunkEnd-1}/${size}`;
  opts.headers['Content-Disposition'] = `attachment; filename="${filenameEncoded}"`;

  // Upload
  return upload(file, url, opts, (request, options) => {
      // Build the form
      let form = new FormData();

      Object.keys(options.data).forEach((key) => {
        if (key === options.fileKey) {
          form.append(key, chunk, filename);
        } else {
          form.append(key, options.data[key]);
        }
      });

      return request.send(form);
    })
    .then((response) => {
      // Progress
      set(file, 'loaded', chunkEnd);
      set(file, 'progress', (chunkEnd / size) * 100);

      // Next chunk
      if ( chunkEnd < size ) {
        opts.chunkStart = chunkEnd;
        return uploadChunks(file, url, opts)
      }

      // All chunks finished
      set(file, 'state', 'uploaded');

      return response;
    })
    .catch(function(error) {
      set(file, 'state', 'failed');
      return RSVP.reject(error);
    })
    .finally(function () {
      let queue = get(file, 'queue');

      if (queue) {
        get(file, 'queue').flush();
      }
    });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants