Exconn::Errors::SocketError in file upload via Car

2019-03-01 19:01发布

问题:

This is a continuation of the problem I recently had - Stack Level Too Deep error - produced with strong parameters I think

Whenever I do a Post creation, which involves a file upload, I get this error:

Started POST "/posts" for 127.0.0.1 at 2014-08-28 08:47:09 -0500
Processing by PostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"daUAMfiQZ/uiD/0ADg=", "post"=>{"status"=>"confirmed", "title"=>"Ashlee lost 10 pounds in 5 weeks", "photo"=>#<ActionDispatch::Http::UploadedFile:0x000001038f04b8 @tempfile=#<Tempfile:/var/folders/0f/hgplttnd7dg6q9m62qtbnpn00000gn/T/RackMultipart20140828-89271-qwxck1>, @original_filename="Ashlee-Testimonial.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"post[photo]\"; filename=\"Ashlee-Testimonial.png\"\r\nContent-Type: image/png\r\n">, "body"=>"She lost 10 pounds in 5 weeks doing 10PP."}, "commit"=>"Submit"}
  User Load (1.0ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
   (0.4ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["user_id", 1]]
   (0.2ms)  BEGIN
  SQL (2.2ms)  INSERT INTO "posts" ("body", "created_at", "photo", "status", "title", "updated_at", "user_id") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id"  [["body", "She lost 10 pounds in 5 weeks doing 10PP."], ["created_at", "2014-08-28 13:47:09.320765"], ["photo", "Ashlee-Testimonial.png"], ["status", "confirmed"], ["title", "Ashlee lost 10 pounds in 5 weeks"], ["updated_at", "2014-08-28 13:47:09.320765"], ["user_id", 1]]
Digest::Digest is deprecated; use Digest
   (0.3ms)  ROLLBACK
Completed 500 Internal Server Error in 10904ms

Excon::Errors::SocketError - Broken pipe:

My Post model looks like this:

# == Schema Information
#
# Table name: posts
#
#  id         :integer          not null, primary key
#  status     :string(255)
#  title      :string(255)
#  date       :datetime
#  photo      :string(255)
#  body       :text
#  created_at :datetime
#  updated_at :datetime
#  user_id    :integer
#  ancestry   :string(255)
#  file       :string(255)
#

class Post < ActiveRecord::Base
  has_ancestry
  belongs_to :user
  resourcify

  mount_uploader :photo, ImageUploader
  mount_uploader :file, FileUploader
end

My Controller looks like this:

  def create
    @post = current_user.posts.new(post_params)

    respond_to do |format|
      if @post.save
        format.html { redirect_to @post, notice: 'Post was successfully created.' }
        format.json { render :show, status: :created, location: @post }
      else
        format.html { render :new }
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    # Never trust parameters from the scary internet, only allow the white list through.
    def post_params
      params.require(:post).permit(:status, :title, :date, :photo, :body, :parent_id)
    end

This is my image_uploader.rb:

# encoding: utf-8

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick
  storage :fog

  include CarrierWave::MimeTypes
  process :set_content_type

  def store_dir
    "images/#{model.id}-#{model.created_at}"
  end

  version :thumb do
    process :resize_to_fit => [80, 80]
  end

  version :large do
    process :resize_to_limit => [400, 400]
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end

This is my Gemfile:

source 'https://rubygems.org'

gem 'rails', '4.1.1'

group :assets do
  gem 'sass-rails', '~> 4.0.3'
  gem 'uglifier', '>= 1.3.0'
  gem 'coffee-rails', '~> 4.0.0'
  gem "font-awesome-rails"
  gem 'bootstrap-sass', '~> 3.2.0'
  gem 'autoprefixer-rails'
end

group :development do
    gem 'annotate', github: 'ctran/annotate_models'
    gem 'sextant'
  gem "quiet_assets", ">= 1.0.2"
  gem 'better_errors', '~> 1.1.0'
  gem 'binding_of_caller', '~> 0.7.2'
    gem 'meta_request'
    gem 'execjs'
    gem 'therubyracer'  
  gem "letter_opener"
  gem 'bullet'   
  gem 'rack-mini-profiler'     
  gem 'guard-rails'
  gem 'rb-fchange', :require=>false
  gem 'rb-fsevent', :require=>false
  gem 'rb-inotify', :require=>false
  gem 'guard-livereload', '~> 2.3.0', :require=>false
  gem 'rack-livereload', '~> 0.3.15'
end

group :production do
  gem 'rails_12factor'
end

gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0',          group: :doc
gem 'spring',        group: :development
gem 'devise', '~> 3.2.4'
gem 'thin'
gem 'pg'
gem 'cancancan', '~> 1.8.2'
gem 'rolify'
gem 'rmagick', :require => 'RMagick'
gem "mini_magick"
gem 'carrierwave', '~> 0.10.0'
gem "fog", "~> 1.3.1"
gem 'figaro', '~> 0.7.0'
gem 'geocoder', '~> 1.2.2'
gem 'social-share-button', '~> 0.1.6'
gem 'ancestry', '~> 2.1.0'
gem "simple_form"

This is my upload form partial:

<%= simple_form_for @post do |f| %> 
    <%= f.error_notification %>

    <%= f.input :parent_id, as: :hidden %>

    <% if can? :manage, @post %>
      <%= f.input :status, collection: Status.all %>
    <% end %>       

    <%= f.input :title %><br />
    <%= f.input :date %><br />      
    <%= f.input :photo %><br />
    <%= f.input :body %><br />      

  <%= f.button :submit %>

<% end %>

This is my config/carrierwave.rb file:

CarrierWave.configure do |config|
  config.fog_credentials = {
    provider:               'AWS',
    region:                 'us-east-1',                          
    aws_access_key_id:      ENV["AWS_ACCESS_KEY"],         
    aws_secret_access_key:  ENV["AWS_SECRET_ACCESS_KEY"],         
  }
  config.fog_directory  = ENV["AWS_MY_BUCKET"]       
end

Any ideas what may be causing this?

Update 1

Here is some more debugging info. Once I remove the resizing of the images, that Socket Error message disappears.

But this is the new error I get:

Digest::Digest is deprecated; use Digest
   (0.2ms)  ROLLBACK
Completed 500 Internal Server Error in 7372ms

Excon::Errors::Forbidden - Expected(200) <=> Actual(403 Forbidden)
  request => {:connect_timeout=>60, :headers=>{"Content-Length"=>225260, "Content-Type"=>"image/png", "x-amz-acl"=>"public-read", "Date"=>"Thu, 28 Aug 2014 16:34:11 +0000", "Authorization"=>"AWS PUBLIC_KEY:SECRET_KEY=", "Host"=>"my_site.s3.amazonaws.com:443"}, :instrumentor_name=>"excon", :mock=>false, :read_timeout=>60, :retry_limit=>4, :ssl_ca_file=>"/.rvm/gems/ruby-2.1.1@my_site/gems/excon-0.13.4/data/cacert.pem", :ssl_verify_peer=>true, :write_timeout=>60, :host=>"my_site.s3.amazonaws.com", :path=>"/images%2F7-2014-08-28+16%3A34%3A11+UTC%2F10pp-main-banner.png", :port=>"443", :query=>nil, :scheme=>"https", :body=>#<File:/myapp/public/uploads/tmp/1409243651-91536-3147/10pp-main-banner.png>, :expects=>200, :idempotent=>true, :method=>"PUT"}
  response => #<Excon::Response:0x000001035f0f88 @body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>InvalidAccessKeyId</Code><Message>The AWS Access Key Id you provided does not exist in our records.</Message><RequestId>2FDE1E67B32981B7</RequestId><HostId>itxnvlzNTkJ29N3MtyYmL8EP29zrW6s9Hr6Xc2P7QzTElkB56OU26WdzsE/6vSz1</HostId><AWSAccessKeyId>AKIAISIFEOAKO3CNPZTA</AWSAccessKeyId></Error>", @headers={"x-amz-request-id"=>"2FDE1E67B32981B7", "x-amz-id-2"=>"itxnvlzNTkJ29N3MtyYmL8EP29zrW6s9Hr6Xc2P7QzTElkB56OU26WdzsE/6vSz1", "Content-Type"=>"application/xml", "Transfer-Encoding"=>"chunked", "Date"=>"Thu, 28 Aug 2014 16:34:16 GMT", "Connection"=>"close", "Server"=>"AmazonS3"}, @status=403>:

回答1:

I think it might have to do with the locale after all.

Here's an example of someone using s3, but it's the same idea. they say the following:

I was recently working on my website and ran into a problem uploading larger files (like 1.8M) to S3 via Carrierwave/Fog. I was getting the following error: Excon::Errors::SocketError (Broken pipe (Errno::EPIPE)):

What I found out was that the region code needed to be set in my carrierwave.rb initializer file in order to get the larger files uploaded. Apparently it defaults to some region code other than the one I was using and that for some reason leads to an error when uploading larger files.

To find the region code, navigate through S3 to an actual file that has been stored and click on it and click “Properties” on the upper right of the screen. You will see something like the following as the link:

https://s3-us-west-2.amazonaws.com/ginger2/uploads/web_developer_project_image/image/1/thumb_Screen_Shot_2013-09-05_at_2.10.45_PM.png

In this case, the following is the region code you should set in your config: us-west-2



回答2:

I figured it out. What happened was I created a new user in AWS IAM for this app, and I didn't give that user proper credentials. i.e. I never created a security policy or assigned them to a group. So it was generating a 403 error.

Now that I have fixed that, everything works smoothly.

I hope this helps someone else.