Seahorse::Client::NetworkingError Amazon S3 file u

2020-04-14 08:13发布

问题:

In my rails 4 application I'm trying to download and then upload a regular png file to my s3 bucket using the aws-sdk (using gem 'aws-sdk', '~> 2').

In development environment, the code works totally fine. But if I try rails s -e production or if I test out the upload on my heroku instance, I get the following error when I test out the image upload functionality,

Seahorse::Client::NetworkingError (Connection reset by peer):
  app/helpers/aws_s3.rb:73:in `upload_to_s3'
  app/controllers/evaluations_controller.rb:19:in `test'

my upload_to_s3 method mentioned in the trace looks like:

def upload_to_s3(folder_name)
  url = "http://i.imgur.com/WKeQQox.png"
  filename = "ss-" + DateTime.now.strftime("%Y%d%m-%s") + "-" + SecureRandom.hex(4) + ".png"
  full_bucket_path = Pathname(folder_name.to_s).join(filename).to_s
  file = save_to_tempfile(url, filename)
  s3 = Aws::S3::Resource.new(access_key_id: ENV["IAM_ID"], secret_access_key: ENV["IAM_SECRET"], region: 'us-east-1')
  s3_file = s3.bucket(ENV["BUCKET"]).object(full_bucket_path)
  s3_file.upload_file(file.path)
  raise s3_file.public_url.to_s.inspect
end

The environment variables are the same between both environments. I don't really know where else to turn to debug this. Why would it work in development, but not in production? I have a feeling I'm missing something pretty obvious.

UPDATE:

Let's simplify this further since I'm not getting very much feedback.

s3 = Aws::S3::Resource.new
bucket = s3.bucket(ENV["BUCKET"])
bucket.object("some_file.txt").put(body:'Hello World!')

The above totally works in my development environment, but not my production environment. In production it faults when I call put(body:'Hello World!'). I know this is probably related to write permissions or something, but again, I've checked my environment variables, and they are identical. Is there some configuration that I'm not aware of that I should be checking?

I've tried using a new IAM user. I also temporarily copied the entire contents of development.rb over to production.rb just to see if the configuration for the development or production was affecting it, to no avail. I ran bundle update as well. Again, no luck.

I wish the error was more descriptive, but it just says Seahorse::Client::NetworkingError (Connection reset by peer) no matter what I try.

回答1:

Well I never found the solution for this problem and had to resort to other options since I was on a deadline. I'm assuming it is a bug on Amazon's end or with the aws-sdk gem, because I have checked my configuration many times, and it is correct.

My workaround was to use the fog gem, which is actually very handy. after adding gem 'fog' to my gemfile and running bundle install my code now looks like this:

def upload_to_s3(folder_name)
  filename = "ss-" + DateTime.now.strftime("%Y%d%m-%s") + "-" + SecureRandom.hex(4) + ".png"
  full_bucket_path = Pathname(folder_name.to_s).join(filename).to_s
  image_contents = open(url).read

  connection = Fog::Storage.new({
    :provider                 => 'AWS',
    :aws_access_key_id        => ENV["AWS_ACCESS_KEY_ID"],
    :aws_secret_access_key    => ENV["AWS_SECRET_ACCESS_KEY"]
  })

  directory = connection.directories.get(ENV["BUCKET"])
  file = directory.files.create(key: full_bucket_path, public: true)
  file.body = image_contents
  file.save
  return file.public_url

end

Which is simple enough and was a breeze to implement. Wish I knew what was messing up with the aws-sdk gem, but for anyone else who has problems, give fog a go.