How can I truncate the HtmlBody when sending emails through postmark - ruby-on-rails

I'm using postmark to send emails in my rails application where the email content is auto generated. The thing is that in some cases I getting this error from postmark.
Postmark::InvalidEmailAddressError
Invalid 'HtmlBody' value. It should be less than 5242880 characters in length.
How can I truncate the HtmlBody content in order to avoid this error using ActionMailer

Related

Ruby 2.0.0 String#Match ArgumentError: invalid byte sequence in UTF-8

I see this a lot and haven't figured out a graceful solution. If user input contains invalid byte sequences, I need to be able to have it not raise an exception. For example:
# #raw_response comes from user and contains invalid UTF-8
# for example: #raw_response = "\xBF"
regex.match(#raw_response)
ArgumentError: invalid byte sequence in UTF-8
Numerous similar questions have been asked and the result appears to be encoding or force encoding the string. Neither of these work for me however:
regex.match(#raw_response.force_encoding("UTF-8"))
ArgumentError: invalid byte sequence in UTF-8
or
regex.match(#raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?"))
ArgumentError: invalid byte sequence in UTF-8
Is this a bug with Ruby 2.0.0 or am I missing something?
What is strange is it appear to be encoding correctly, but match continues to raise an exception:
#raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
=> #<Encoding:UTF-8>
In Ruby 2.0 the encode method is a no-op when encoding a string to its current encoding:
Please note that conversion from an encoding enc to the same encoding enc is a no-op, i.e. the receiver is returned without any changes, and no exceptions are raised, even if there are invalid bytes.
This changed in 2.1, which also added the scrub method as an easier way to do this.
If you are unable to upgrade to 2.1, you’ll have to encode into a different encoding and back in order to remove invalid bytes, something like:
if ! s.valid_encoding?
s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end
Since you're using Rails and not just Ruby you can also use tidy_bytes. This works with Ruby 2.0 and also will probably give you back sensible data instead of just replacement characters.

Testing of graceful handling of invalid UTF-8 in Rails

I'm currently trying to ensure that my rails application handles POST methods with invalid UTF-8 data gracefully (e.g. \xFF) (using rack middleware)
Unfortunately writing tests for this is proving extremely difficult.
One thing I've tried is using Capybara to fill in one of my form fields with invalid UTF-8 and submit, however this causes the following output in the terminal amongst my test output - and it's not being printed by Rails!
error : string is not in utf-8
Is there another way that a POST containing invalid UTF-8 data can be emulated in order to validate that a 400 error (or similar) is displayed?
NB: I'm trying to avoid having to run against a separate running instance of the application (e.g. using 'curl' against it), but just run directly with Capybara (or similar)
You could try posting a file attachment which contains invalid utf-8 data, although this would also depend on your form itself. However, as you're testing a rather obscure edge-case, you could always create a form that is only accessible in dev/test environments, with the route also only available for testing.
This would at least allow you to target the code that handles the processing of the invalid utf-8 data in a safe, test-only way.
What do you mean by filling the form with invalid UTF-8? The characters you fill in the form do not have any encoding, they are encoded when the form is sent. This sentence would make sense for some encodings that cannot encode all characters out there but UTF-8 can.
If you want to send the byte \xFF to the server from a browser, it's as easy as pulling out the developer tools of that browser, editing the form's attributes to accept-charset="ISO-8859-1" writing ÿ somewhere on the form and pressing send. The ÿ will get encoded as a %FF which cannot be decoded as UTF-8:
As detailed in this ThoughtBot blog post, this worked for me in a unit test:
"hello joel\255".force_encoding('UTF-8')
Not sure how you'd convince capybara to do this though.
You should be able to do this by constructing a post with rack-test as opposed to using capybara.
For example the following request spec (spec/requests/utf8_spec.rb):
require 'spec_helper'
describe "Invalid UTF-8" do
it "handles invalid UTF-8 in post data gracefully" do
post "/users", :user => {:name => "Test \xFF boom"}
end
end
Produces the following when run:
1) Invalid UTF-8 handles invalid UTF-8 in post data gracefully
Failure/Error: post "/users", :user => {:name => "Test \xFF boom"}
ArgumentError:
invalid byte sequence in UTF-8
# ./app/controllers/users_controller.rb:17:in `create'
# ./spec/requests/utf8_spec.rb:5:in `block (2 levels) in <top (required)>'

utf-8 and ActionMailer

I'm facing some problems with UTF-8 and ActionMailer. My application has a form (contact) that when it is submitted, it sends an email to me. The problem is that when somebody enters some chars like öäüß, I receive the message encoded like for example
=?UTF-8?Q?funktioniert_oder_nicht.=0D=0A=0D=0Ameine_Stra=C3=9Fe_ist_die?=
=?UTF-8?Q?_Bratwurststra=C3=9Fe=0D=0A=0D=0A=C3=B6=C3=A4?=
As I understand, ActionMailer per default is utf-8 ready. Analyzing the log from my server, when the form is submitted, the params are already well encoded (it means I can read the äüö in my log)
Any idea about what should I change? should I change my application to support ISO-8859-1?
environment: ruby 1.9 and rails 3.1
You are getting the UTF-8 bytes escaped with quoted-printable.
ß is "\xC3\x9F" -> "=C3=9F"
String#unpack('M') will decode it:
$ ruby -e 'puts "Bratwurststra=C3=9Fe=0D=0A=0D=0A=C3=B6=C3=A4".unpack "M"'
Bratwurststraße
öä
`

SMTP errors at sending emails with ruby on rails

I've been trying to send some test newsletter using my gmail account as smtp, but when i tried to send to multiple recipients - ['emai#laddr#email.com, emailaddr2#email.com'] - in this case the first email address is incorrect - it gives me an error 555 - 5.5.2 Syntax error and the process stops without passing through the next email addreses.
My question is:
is there a possibility to bypass those kind of errors in order to skip the incorrect addresses and to continue sending the emails?
You can set ActionMailer to ignore delivery errors, but that's not really considered best practice in a production environment.
# environment.rb (or development/test etc)
ActionMailer::Base.raise_delivery_errors = false
If you don't have a lot of recipients, you could try looping through the array of addresses and sending an email for each one, rescuing a delivery error and adding a message to the log.
# Model
def send_emails(addresses)
addresses.each do |address|
begin
YourMailer.deliver_method(email)
rescue
logger.error "Could not send email to #{email}"
end
end
end

Problems with ActionMailer: 501 <>: missing or malformed local part

I'm having trouble sending mail using SMTP from a Rails app. I have a Mailer class:
class Mailer < ActionMailer::Base
def newsletter_confirmation(subscription)
recipients "my-valid-email#gmail.com" # this is set to my email
# just for testing purposes and will
# be changed to subscription.email
from "\"my-valid-helo-domain.net\" <noreply#my-valid-helo-domain.net>"
subject "Confirm your subscription"
body :subscription => subscription
end
end
When I try to send the mail, I get a Net::SMTPSyntaxError:
501 <["noreply#my-valid-helo-domain.net"]>: missing or malformed local part
If I comment out the from field, the mail gets delivered ok, but with the from information missing (obviously). Any ideas on what I'm doing wrong?
Thanks.
Edit: I'm using Rails 2.3.2 and Ruby 1.9.1
The error code and the description of the error states that this is an error on the mail server.
I suggest you check the mail servers to pinpoint the error.
When it comes to ActionMailer it is supposed to raise an exception if the configuration parameter raise_delivery_errors is set (default in Production but not in Development I believe), so you can check that one and try to resend if it triggers.
EDIT:
Here is the solution (it's a Ruby/Rails 1.9 bug):
https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2340-action-mailer-cant-deliver-mail-via-smtp-on-ruby-191
and the patch:
https://rails.lighthouseapp.com/projects/8994/tickets/2340/a/104008/action_mailer-ruby-1.9-from-address-fix.patch
It is a known bug. https://rails.lighthouseapp.com/projects/8994/tickets/2340

Resources