copleykj / socialize-cloudinary

A Meteor package for integrating a meteor application with Cloudinary image/video managment service
MIT License
11 stars 4 forks source link

Uploading images to Meteor app on Heroku gives 503 (service unavailable) #1

Closed GoaGit closed 6 years ago

GoaGit commented 6 years ago

When using this package in a Meteor app deployed on Heroku, uploads for images that are (approximately) more than 30kB fail with a client-side 503 response error. The uploading function that I use is similar to the one in the documentation of this package.

Server error message on Heroku:

sock=backend at=error code=H18 desc="Server Request Interrupted" method=POST path="/app/items/uYHL88FBE2oBbjewv/edit" host=platform.XXX request_id=YYY fwd="IP_ZZZ" dyno=web.1 connect=0ms service=39ms status=503 bytes=2140 protocol=https

Heroku H18 error message definition:

The backend socket, belonging to your app’s web process was closed before the backend returned an HTTP response

Uploads that do work for me when using this package:

So apparently Heroku terminates the connection before the upload was completed. Heroku supports Cloudinary as a plugin and in the docs they give a basic example to use the uploader API:

(Heroku docs for Cloudinary)

var cloudinary = require('cloudinary')
cloudinary.uploader.upload("my_picture.jpg",
function(result) { console.log(result) })

The code above looks similar to the one in this package.

I am looking for some pointers for me to tackle this issue.

copleykj commented 6 years ago

What is your upload flow? Client -> Server -> Cloudinary? Unless absolutely necessary I would choose direct Client -> Cloudinary uploads and avoid Heroku all together.

GoaGit commented 6 years ago

Uploading is done from the client, but the server is involved for verifcation as defined in the setup in the description of the package (with my own credentials of course):

// Server
import { Cloudinary } from 'meteor/socialize:cloudinary';

Cloudinary.config({
    cloud_name: 'cloud_name',
    api_key: '1237419',
    api_secret: 'asdf24adsfjk',
});

// Rules are bound to the connection from which they are are executed. This means you have a userId available as this.userId if there is a logged in user. Throw a new Meteor.Error to stop the method from executing and propagate the error to the client. If rule is not set a standard error will be thrown.
Cloudinary.rules.delete = function (publicId) {
    if (!this.userId && !publicId) throw new Meteor.Error("Not Authorized", "Sorry, you can't do that!");
};

Cloudinary.rules.sign_upload = function () {
    if (!this.userId) throw new Meteor.Error("Not Authorized", "Sorry, you can't do that!")
};

Cloudinary.rules.private_resource = function (publicId) {
    if (!this.userId && !publicId) throw new Meteor.Error("Not Authorized", "Sorry, you can't do that!");
};

Cloudinary.rules.download_url = function (publicId) {
    if (!this.userId && !publicId) throw new Meteor.Error("Not Authorized", "Sorry, you can't do that!");
};

I want to check the user status so the rule Cloudinary.rules.sign_upload is something I want to use. I will see what it does if I leave out this check (and use a preset).

copleykj commented 6 years ago

While there is a request to the server for signing the upload, it shouldn't take more than a few hundred miliseconds unless you are doing something inside the sign_upload rule that takes time, and even then I don't see why it wold generate this error since the upload signing would have to complete before the upload would start.

GoaGit commented 6 years ago

Well I am puzzled. I stripped down the implementation making sure that I the control flow is transparent. It should be a client-side only process but somehow the server gets involved. I am using a component from ant design which has no dependency on Meteor.

I will try to get it working somehow so that I can give an explanation.

GoaGit commented 6 years ago

Found the cause of the issue. Something else in my code was interfering with the upload process. Had nothing to do with this package.

micthiesen commented 5 years ago

@GoaGit I hate to revive an old issue, but do you remember what the actual cause was? I'm seeing these errors on my Django app and I'm stumped.

GoaGit commented 5 years ago

@micthiesen as far as I can remember it had something to do with providing the api key (from a json file). It was not available because I imported it incorrectly. So really nothing with the package itself.

micthiesen commented 5 years ago

Thanks. Our 503s (H18 errors) were caused by us not consuming POST data from the socket for some requests.