Attaching file in Rails 3 - mimepart Mailer - ruby-on-rails

I'm sending an email using Rails like this:
attachments["ticket.pdf"] = WickedPdf.new.pdf_from_string(render_to_body(pdf: "ticket", template: 'template' }))
This works well in Gmail but in several other clients the attached pdf just doesn't appear.
Looking at the source code I realized it's a problem with mimeparts.
I'm having a hard time making an attachment file show in yahoo and several other email clients such as Thunderbird, if I analize the source code of the email sent I discover this:
The mimepart is the same for each part of the file...
the hierarchy (as far as i understand) must be like this:
multipart/mixed
multipart/alternative
multipart/related
text/html
image/png (e.g. for an inline attachment; pdf would be another good example)
text/plain
application/zip (e.g for an attachment--not inline)
This i extracted from https://github.com/jcoleman/mail_alternatives_with_attachments
Here, is the email source (just chunks of the content for better understanding):
Delivered-To: someone#yahoo.com
Received: by 10.194.54.135 with SMTP id j7csp144091wjp;
Fri, 28 Sep 2012 10:55:03 -0700 (PDT)
Received: by 10.224.187.146 with SMTP id cw18mr18768052qab.35.1348854902751;
Fri, 28 Sep 2012 10:55:02 -0700 (PDT)
Return-Path: <somewhare#company.com>
Received: from mail-qa0-f46.company.com (mail-qa0-f46.company.com [209.85.216.46])
by mx.company.com with ESMTPS id c6si13006455qao.34.2012.09.28.10.55.02
(version=TLSv1/SSLv3 cipher=OTHER);
Fri, 28 Sep 2012 10:55:02 -0700 (PDT)
Received-SPF: pass (company.com: domain of somewhere#company.com designates 209.85.216.46 as permitted sender) client-ip=xx.xxx.xxx.xxx;
Authentication-Results: mx.company.com; spf=pass (company.com: domain of somwhere#company.com designates 209.85.216.46 as permitted sender) smtp.mail=somewhere#company.com; dkim=pass header.i=#company.com
Received: by mail-qa0-f46.company.com with SMTP id c26so105866qad.5
for <someone#company.com>; Fri, 28 Sep 2012 10:55:02 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=company.com; s=20120113;
h=date:from:reply-to:to:message-id:subject:mime-version:content-type
:content-transfer-encoding;
bh=nETVpMomUq0PkrNf9ScGjdaBPc5tYF0m1Rphx5FNS4c=;
b=I1ICSRRK10cdrqXxkNWmK5cLvXOqFpxXmzxNMlIVa8jh+4U1GwqwI1GZF7BRXh5FAU
wCyTzXfSkBrmn2cVGwUUiNEh956KT2ssWx37cQIb915lSp6rdIqflgQcF9yKwmtJoxDL
qO+nEVse7+Azi828zC7D6VV7ebAbmnr006KmppkH9bxILk+syiPKLvp4rZXAMIp0IFW8
nYZ2jY+n/ryduTSl0qDaBDCzVrky2eNwpqfJYizoYWIhxFuDmUWwaPpKzfWoxzT4b0+P
Mp/Ugv6iN1QyETJWbOfX4lpGezFzcaV7reZaBXLzcqUe1dc8elxFfWncsE0vozmFaj8m
z37Q==
Received: by 10.224.58.134 with SMTP id g6mr18690371qah.40.1348854902269;
Fri, 28 Sep 2012 10:55:02 -0700 (PDT)
Return-Path: <somwhere#company.com>
Received: from localhost.localdomain (company.com. [xx.xxx.xxx.xx])
by mx.company.com with ESMTPS id ck11sm13357478qab.17.2012.09.28.10.54.56
(version=TLSv1/SSLv3 cipher=OTHER);
Fri, 28 Sep 2012 10:55:00 -0700 (PDT)
Return-Path: <bounces1#somewhere.com>
Date: Fri, 28 Sep 2012 15:09:56 -0300
From: somewhere <somewhere#company.com>
Reply-To: someone#company.com
To: someone#company.com
Message-ID: <5065e7f4b41bf_a9e43fdbdd45a7601574c#megara.local.mail>
Subject: algun subject
Mime-Version: 1.0
Content-Type: multipart/alternative;
boundary="--==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9";
charset=UTF-8
Content-Transfer-Encoding: 7bit
----==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9
Date: Fri, 28 Sep 2012 15:09:56 -0300
Mime-Version: 1.0
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-ID: <5065e7f4b0ead_a9e43fdbdd45a7601546#megara.local.mail>
********
texto cualquiera
********
----==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9
Date: Fri, 28 Sep 2012 15:09:56 -0300
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-ID: <5065e7f4b1d7d_a9e43fdbdd45a76015576#megara.local.mail>
<html xmlns=3D'http://www.w3.org/1999/xhtml'>
<html xml:lang=3D'en' xmlns=3D'http://www.w3.org/1999/xhtml'>
<head>
<meta content=3D'text/html; charset=3Dutf-8' http-equiv=3D'Content-=
Type'>
<title>somewhere</title>
<link href=3D'/assets/ev_classic_mailer.css' rel=3D'stylesheet' typ=
e=3D'text/css'>
<link href=3D'/assets/mailer_colors.css' rel=3D'stylesheet' type=3D=
'text/css'>
</head>
<body>
<table class=3D'mail-container-table'>
<tr>
<td class=3D'decoration' colspan=3D'3'></td>
</tr>
<tr>
<th background=3D'https://here.company.com/ass=
ets/mail/ev_classic_hd.png' class=3D'bcolor12 border header-01' colspan=3D=
'3'>
<h1>cogotudo</h1>
</th>
</tr>
</table>
</body>
</html>
</html>
----==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9
Date: Fri, 28 Sep 2012 15:09:56 -0300
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-ID: <5065e7f4b2ede_a9e43fdbdd45a76015666#megara.local.mail>
<html xmlns=3D"http://www.w3.org/1999/xhtml" style=3D"outline: 0; font-we=
ight: inherit; font-style: inherit; font-size: 100%; font-family: inherit=
; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
<html xml:lang=3D"en" xmlns=3D"http://www.w3.org/1999/xhtml" style=3D"o=
utline: 0; font-weight: inherit; font-style: inherit; font-size: 100%; fo=
nt-family: inherit; vertical-align: baseline; margin: 0; padding: 0; bord=
er: 0;">
<head>
<meta content=3D'text/html; charset=3Dutf-8' http-equiv=3D'Content-=
Type'>
<title>somewhere</title>
<link href=3D'/assets/ev_classic_mailer.css' rel=3D'stylesheet' typ=
e=3D'text/css'>
<link href=3D'/assets/mailer_colors.css' rel=3D'stylesheet' type=3D=
'text/css'>
</head>
<body style=3D"outline: 0; font-weight: inherit; font-style: inherit;=
</body>
</html>
</html>
----==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9
Date: Fri, 28 Sep 2012 15:09:56 -0300
Mime-Version: 1.0
Content-Type: application/pdf;
charset=UTF-8;
filename=ticket.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=ticket.pdf
Content-ID: <5065e7f43b81b_a9e43fdbdd45a760150c9#megara.local.mail>
JVBERi0xLjQKMSAwIG9iago8PAovVGl0bGUgKP7/KQovQ3JlYXRvciAo/v8p
Ci9Qcm9kdWNlciAo/v8AUQB0ACAANAAuADgALgAyACAAXCgAQwBcKQAgADIA
MAAxADEAIABOAG8AawBpAGEAIABDAG8AcgBwAG8AcgBhAHQAaQBvAG4AIABh
AG4AZAAvAG8AcgAgAGkAdABzACAAcwB1AGIAcwBpAGQAaQBhAHIAeQBcKAAt
AGkAZQBzAFwpKQovQ3JlYXRpb25EYXRlIChEOjIwMTIwOTI4MTgwOTU1KQo+
PgplbmRvYmoKMiAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMyAw
IFIKPj4KZW5kb2JqCjQgMCBvYmoKPDwKL1R5cGUgL0V4dEdTdGF0ZQovU0Eg
dHJ1ZQovU00gMC4wMgovY2EgMS4wCi9DQSAxLjAKL0FJUyBmYWxzZQovU01h
c2sgL05vbmU+PgplbmRvYmoKNSAwIG9iagpbL1BhdHRlcm4gL0RldmljZVJH
----==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9--

All of your mimepart boundaries are the same...they're all the 'alternative' boundary.
--==_mimepart_5065e7f4af345_a9e43fdbdd45a760153b9
For an email with HTML, plain text AND attachments, you need to declare and properly encapsulate the separate parts by properly putting the boundaries in their right places. The easiest way to get a grasp of what that looks like is to manually create an email in an email client with all the 'features' you want (HTML + plain text + attachments) and then view the source and take note of how the mimepart boundaries are laid out.
Each "part" of the email source actually declares what the boundary looks like, and then at the end of each part there are one or more of those boundary lines indicating the end of the part. Parts can and should be encapsulated within other parts. It's damn complicated but the take-home note is that in your example, you only have one mimepart declared and used when you should have more (as you indicated in your hierarchy).
Now as for where/when this goes awry, we'd have to see the code you're using to generate the email from start to finish.

Related

SSL_connect returned=1 errno=0 state=unknown state: unknown protocol rails 4

I've been having issues setting up mailer on to my ruby on rails application, I know that this question was asked before but none of the other one solved my problem so I said I'll give it a try.
My current development log is.
Rendered example_mailer/sample_email.html.erb within layouts/mailer (0.1ms)
Rendered example_mailer/sample_email.text.erb within layouts/mailer (0.0ms)
ExampleMailer#sample_email: processed outbound mail in 13.5ms
Sent mail to admin#exampler.ca (20.8ms)
Date: Wed, 09 Aug 2017 13:46:42 +0000
From: noreply#exampler.ca
To: admin#exampler.ca
Message-ID: <598b1242ae925_95383fe3f1445b7852366#team-version-5166637.mail>
Subject: Hello from Postmark
Mime-Version: 1.0
Content-Type: multipart/alternative;
boundary="--==_mimepart_598b1242ad242_95383fe3f1445b78522a1";
charset=UTF-8
Content-Transfer-Encoding: 7bit
html-body: <strong>Hello</strong> dear Postmark user.
track-opens: true
----==_mimepart_598b1242ad242_95383fe3f1445b78522a1
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 7bit
Hi
Sample mail sent using smtp.
----==_mimepart_598b1242ad242_95383fe3f1445b78522a1
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<html>
<body>
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h1>Hi </h1>
<p>
Sample mail sent using smtp.
</p>
</body>
</html>
</body>
</html>
----==_mimepart_598b1242ad242_95383fe3f1445b78522a1--
Completed 500 Internal Server Error in 102ms (ActiveRecord: 60.6ms)
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=unknown state: unknown protocol):
app/controllers/confessions_controller.rb:42:in `block in create'
app/controllers/confessions_controller.rb:39:in `create'
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_source.erb (4.5ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.8ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.7ms)
Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (35.9ms)
and my application.rb is
config.action_mailer.delivery_method = :postmark
config.action_mailer.postmark_settings = { :api_token => "A_token" }
and my
It appears that if i try to connect using the command line with something like:
openssl s_client -connect aristo4stu3.bgu.ac.il:443 -no_tls1 ####this works
openssl s_client -connect aristo4stu3.bgu.ac.il:443 #### this doesn't work
my ruby version
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
my openssl version
OpenSSL 1.0.1f 6 Jan 2014
linux version:
Linux team-version-5166637 4.9.17-c9 #1 SMP Thu Mar 23 01:38:54 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Any help will be appreciated, Thank you!

Mechanize is not loading full webpage after search submit

Why I am not getting the products on [this][1] page when searching a " " space in the search form I only get the menus but not the search result products
Ruby code:
require 'nokogiri'
require 'mysql2'
require 'logger'
require 'mechanize'
agent = Mechanize.new{|a| a.log = Logger.new(STDERR) }
agent.user_agent_alias = 'Windows Mozilla'
agent.read_timeout = 60
def add_cookie(agent, uri, cookie)
uri = URI.parse(uri)
Mechanize::Cookie.parse(uri, cookie) do |cookie|
agent.cookie_jar.add(uri, cookie)
end
end
login_page = agent.get "http://www.example.com.mx/login.php?location=%2F"
login_form = login_page.form_with(:method => 'POST')
email_field = login_form.field_with(name: "correo_ingresar")
password_field = login_form.field_with(name: "password")
email_field.value = 'user#example.com'
password_field.value = 'password'
home_page = login_form.submit
myarray = home_page.body.scan(/SetCookie\(\"(.+)\", \"(.+)\"\)/)
myarray.each{|line| add_cookie agent, 'http://www.example.com.mx', "#{line[0]}=#{line[1]}"}
add_cookie(agent, 'http://www.example.com.mx', "forzar_existencias=1; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "articulos_mostrar=50; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "forz_existencias=1=; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "no_actualiza=1; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "orden_mostrar=8; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "page=1; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "precio_inicio=0; path=/; domain=www.example.com.mx")
add_cookie(agent, 'http://www.example.com.mx', "location=%2Farticulos.php%3Fbuscar%3D%2B; path=/; domain=www.example.com.mx")
search_form = home_page.forms.first
search_field = search_form.field_with(name: "buscar")
search_field.value = ' '
search_results = search_form.submit
resultados = 'http://example.com.mx/articulos.php?buscar=+'
I downloaded the Live HTTP Headers addon for firefox with firebug. when I fill with a space and click on the search button on the [webpage][1] I get the following results on live HTTP headers.
http://example.com.mx/articulos.php?buscar=+
GET /articulos.php?buscar=+ HTTP/1.1
Host: example.com.mx
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://example.com.mx/articulos.php?buscar=+
Cookie: _ga=GA1.3.162897808.1438611502; _gat=1
Connection: keep-alive
HTTP/1.1 200 OK
Date: Sat, 08 Aug 2015 04:29:40 GMT
Server: Apache
x-powered-by: PHP/5.4.30
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
----------------------------------------------------------
http://www.google-analytics.com/collect?v=1&_v=j37&a=1988602157&t=pageview&_s=1&dl=http%3A%2F%2Fexample.com.mx%2Farticulos.php%3Fbuscar%3D%2B&ul=en-us&de=UTF-8&dt=Sistemas%20Aplicados&sd=24-bit&sr=1920x1080&vp=1903x969&je=0&_u=AACAAEABI~&jid=&cid=162897808.1438611502&tid=UA-58813310-1&z=90642832
GET /collect?v=1&_v=j37&a=1988602157&t=pageview&_s=1&dl=http%3A%2F%2Fexample.com.mx%2Farticulos.php%3Fbuscar%3D%2B&ul=en-us&de=UTF-8&dt=Sistemas%20Aplicados&sd=24-bit&sr=1920x1080&vp=1903x969&je=0&_u=AACAAEABI~&jid=&cid=162897808.1438611502&tid=UA-58813310-1&z=90642832 HTTP/1.1
Host: www.google-analytics.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://example.com.mx/articulos.php?buscar=+
Connection: keep-alive
HTTP/1.1 200 OK
Pragma: no-cache
Expires: Mon, 07 Aug 1995 23:30:00 GMT
Access-Control-Allow-Origin: *
Last-Modified: Sun, 17 May 1998 03:00:00 GMT
x-content-type-options: nosniff
Content-Type: image/gif
Date: Wed, 29 Jul 2015 12:33:33 GMT
Server: Golfe2
Content-Length: 35
Age: 834969
Alternate-Protocol: 80:quic,p=0
Cache-Control: private, no-cache, no-cache=Set-Cookie, proxy-revalidate
----------------------------------------------------------
http://example.com.mx/resultados.php
POST /resultados.php HTTP/1.1
Host: example.com.mx
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://example.com.mx/articulos.php?buscar=+
Content-Length: 204
Cookie: _ga=GA1.3.162897808.1438611502; _gat=1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
opcion=&buscar=+&page=1&articulos_mostrar=10&orden_mostrar=1&seccion=&linea=&sublinea=&forz_existencias=1&precio_inicio=0&precio_final=20000&location=%252Farticulos.php%253Fbuscar%253D%252B&no_actualiza=1
HTTP/1.1 200 OK
Date: Sat, 08 Aug 2015 04:29:42 GMT
Server: Apache
x-powered-by: PHP/5.4.30
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
----------------------------------------------------------
Question is: how do I get the full products to show on the webpage so I can start scraping if it has a referer link and it does not automatically gets the products. [This][2] is the resulting HTML:
I give 2 solutions, but only one uses a POST as you requested in your question:
require 'mechanize'
agent = Mechanize.new
agent.get("http://www.sistemasaplicados.com.mx/")
agent.page.forms.first.field_with(name: "buscar").value = ' '
result_page = agent.page.forms.first.submit
The other option is to encode your search term and use it in a simple the GET request (encoded in the URL) directly with nokogiri. In your particular case a search for "160GB" leads to following URL http://www.sistemasaplicados.com.mx/articulos.php?buscar=160GB, which you can just GET.
Btw, you do not necessarily need mechanize for all that, except you want to place orders into your account automatically or something like that. I assume you do that in the interest of sistemasaplicados otherwise I would consider this rude and it would bring you bad karma.
Update
When manually checking what is happening you should look what happens if JavaScript is disabled (in this case, there are no results). Then, with the "inspector", "console" or "developer tools" of your Browser (often opened by pressing F12) find out what happens. In your case a POST request to resultados.php is done. I found out with firefox, dev tools, "Network" tab. There also you find the relevant parameters to fire up in your POST request.

Testing schema action buttons from self

I tried running the test script on script.google.com ( https://developers.google.com/gmail/schemas/apps-script-tutorial ), and while the email sent, the action button wasn't enabled.
I'm wondering if this is because I am logged in as a google apps user (me#mydomain.com). I see SPF pass and DKIM in the mail headers, and I do see other action buttons in my google apps gmail.
Delivered-To: me#mydomain.com
Received: by 10.49.47.9 with SMTP id z9csp53721qem;
Wed, 12 Jun 2013 09:56:05 -0700 (PDT)
X-Received: by 10.182.126.226 with SMTP id nb2mr15714364obb.34.1371056165241;
Wed, 12 Jun 2013 09:56:05 -0700 (PDT)
Return-Path: <3JKi4UQUJBekOLcjYOLcjY.YPeOLcjYOLcjY.YPe#maestro.bounces.google.com>
Received: from mail-oa0-x246.google.com (mail-oa0-x246.google.com [2607:f8b0:4003:c02::246])
by mx.google.com with ESMTPS id r7si17176840obg.111.2013.06.12.09.56.04
for <me#mydomain.com>
(version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
Wed, 12 Jun 2013 09:56:05 -0700 (PDT)
Received-SPF: pass (google.com: domain of 3JKi4UQUJBekOLcjYOLcjY.YPeOLcjYOLcjY.YPe#maestro.bounces.google.com designates 2607:f8b0:4003:c02::246 as permitted sender) client-ip=2607:f8b0:4003:c02::246;
Authentication-Results: mx.google.com;
spf=pass (google.com: domain of 3JKi4UQUJBekOLcjYOLcjY.YPeOLcjYOLcjY.YPe#maestro.bounces.google.com designates 2607:f8b0:4003:c02::246 as permitted sender) smtp.mail=3JKi4UQUJBekOLcjYOLcjY.YPeOLcjYOLcjY.YPe#maestro.bounces.google.com
Received: by mail-oa0-f70.google.com with SMTP id i4so1520067oah.9
for <me#mydomain.com>; Wed, 12 Jun 2013 09:56:04 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=google.com; s=20120113;
h=mime-version:message-id:date:subject:from:to:content-type
:x-gm-message-state;
bh=nniz4GW4RjisC3jKnq4Um4I4sY/FfW0e4vae0CbzrBM=;
b=ZdAFsXiPt/07HwxkeNc1VDF+5XzOKT73W9gweiNQOiyeixAVYoLpmlrRWY6XXo3X1j
O/kHu7wMMNJI84Pcv4GLB8LmIedGKTgKYvo+WIx9FAfZxYf2zW41mwPh7GysdZQ7RivF
1euibwDPLypdd89MSTCSA3MBk62VnpExUMra0Og0yPjGszqIYW/Jt0YAREGP7ldOr/7j
K0b/Fi3XB11sG+3ywu3ctNs+7RzZ7IyV3pXGEV6OvMjkZzOX+NnnXVqw8ZoAHm1wJHIc
iqQrhiZ0AeT8HGip+lfbPrSuH5PLF1CtGlFce9GUCqIWWy/TiiVQ5Hat7I9cN/uuo7aO
RDqg==
MIME-Version: 1.0
X-Received: by 10.182.56.200 with SMTP id c8mr4437548obq.33.1371056164810;
Wed, 12 Jun 2013 09:56:04 -0700 (PDT)
Message-ID: <001a11c2c236ac8fb004def7e33f#google.com>
Date: Wed, 12 Jun 2013 16:56:04 +0000
Subject: Test Actions in the Inbox - Wed Jun 12 2013 09:56:04 GMT-0700 (PDT)
From: me#mydomain.com
To: me#mydomain.com
Content-Type: multipart/alternative; boundary=001a11c2c236ac8fa304def7e33c
X-Gm-Message-State: ALoCoQk0dwVXVKag+tFK/DdT/gjAPLfjoz8w8Rfbzz8Q2GT0xh0oIly9+Yi2acnPA69hEefyluux
--001a11c2c236ac8fa304def7e33c
Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes
This a test for a Go-To action in Gmail.
--001a11c2c236ac8fa304def7e33c
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<script type="application/ld+json">
{
"#context": "http://schema.org",
"#type": "EmailMessage",
"description": "Check this out",
"action": {
"#type": "ViewAction",
"url": "https://www.youtube.com/watch?v=eH8KwfdkSqU"
}
}
</script>
</head>
<body>
<p>
This a test for a Go-To action in Gmail.
</p>
</body>
</html>
--001a11c2c236ac8fa304def7e33c--
Google Apps domain get updates on a different schedule than Gmail users and actually the domain administrators can choose to be on the Scheduled Release Track or the Rapid Release Track for updates:
http://whatsnew.googleapps.com/release-tracks
I guess your domain is on the Scheduled Release Track and the support for Actions hasn't rolled out yet.

Rails 3 HTTP-header If-Modified-Since using curl

I have a simple out of the box rails server running and I am trying to figure out how to make it work with the If-Modified-Since header. I am using the following curl request.
curl -I localhost:3000/shows/1 --header 'If-Modified-Since: Thu, 21 Jun 2012 19:16:20 GMT'
I always get 200 OK but I want 304 Not Modified.
When I do this through the browser I get a 304 Not Modified but not with curl.
Am I doing it wrong?
UPDATE
If I run
curl -v -I localhost:3000/shows/1 --header 'If-Modified-Since: Thu, 21 Jun 2012 19:16:20 GMT'
I get:
* About to connect() to localhost port 3000 (#0)
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 3000 (#0)
> HEAD /shows/1 HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
> Host: localhost:3000
> Accept: */*
> If-Modified-Since: Thu, 21 Jun 2012 19:16:20 GMT
>
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< X-Ua-Compatible: IE=Edge
< Etag: "35ec119e3b6c7ccde9eeee82afcd4ee9"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: dd365eb0b80f5b9ff62bc16f3dbbe494
< X-Runtime: 0.007800
< Content-Length: 0
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-02-16)
< Date: Thu, 21 Jun 2012 19:37:55 GMT
< Connection: Keep-Alive
< Set-Cookie: _spacebarfm- rails_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWY0NzNjYmFlYzJhNzgzZWRjMjc2MmU4YWFkZDc1OTIwBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMWhjU3NvQ2VuRkR1NmJRREV1SmxOMUlaK3VhQU0ycjY2am94cFFmOTVnTTg9BjsARg%3D%3D--f9c756d08065c423cdecba2d710b1b74bf798c12; path=/; HttpOnly
Set-Cookie: _spacebarfm-rails_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWY0NzNjYmFlYzJhNzgzZWRjMjc2MmU4YWFkZDc1OTIwBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMWhjU3NvQ2VuRkR1NmJRREV1SmxOMUlaK3VhQU0ycjY2am94cFFmOTVnTTg9BjsARg%3D%3D--f9c756d08065c423cdecba2d710b1b74bf798c12; path=/; HttpOnly
* Connection #0 to host localhost left intact
* Closing connection #0
The rails code for the controller is:
def index
#shows = Show.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #shows }
end
end
The Chrome output is as follows:
Request URL:http://localhost:3000/shows/1.json
Request Method:GET
Status Code:304 Not Modified
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:_btest_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTNkNzI3ODc1NjU0M2EyZTViOWY0ZTgzMjU0M2IzYmY4BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMUFVZVN0ZHp6L0JRNGVMZDZST2JSNG54Zlg4T3VmSnk4RFNhWXRHbmljK3c9BjsARg%3D%3D--ceb783671372cbcc3ecf971340f2a2e2424c9620; _spacebarfm-rails_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTNhMTcxNjMyNzJkMWRjYzAxY2NiN2EwN2JjMzE5YWFjBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMTZZREp5ZC92VTlEQk9oKytCK0hKYW5na1M4bzRPRUM3U3lmWURzU09neWs9BjsARg%3D%3D--793b15b38511bd0805df3a210d7e72152905b8b9
Host:localhost:3000
If-None-Match:"bb012b3a16e7e80ec271b0d234a9b8ce"
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5
Response Headersview source
Cache-Control:max-age=0, private, must-revalidate
Connection:close
Date:Thu, 21 Jun 2012 21:09:28 GMT
Etag:"bb012b3a16e7e80ec271b0d234a9b8ce"
Server:WEBrick/1.3.1 (Ruby/1.9.3/2012-02-16)
Set-Cookie:_spacebarfm-rails_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTNhMTcxNjMyNzJkMWRjYzAxY2NiN2EwN2JjMzE5YWFjBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMTZZREp5ZC92VTlEQk9oKytCK0hKYW5na1M4bzRPRUM3U3lmWURzU09neWs9BjsARg%3D%3D--793b15b38511bd0805df3a210d7e72152905b8b9; path=/; HttpOnly
X-Request-Id:2435168fa20699508e9282c37566c015
X-Runtime:0.005378
X-Ua-Compatible:IE=Edge
You need to use the stale? method to tell Rails that you want to use if-modified-then
You're actually calling the show method. Change it to be:
def show
#show = Show.find(params[:id])
if stale?(:etag => #show, :last_modified => #show.updated_at.utc)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #show }
end
end
end

Why is Rack::Cache not hitting cache when etag matches?

Starting with no cache on server or client
FIRST REQUEST
GET /post/1 HTTP/1.1
HTTP/1.1 200 OK
Date: Fri, 05 Mar 2010 09:05:46 GMT
Last-Modified: Thu, 04 Mar 2010 21:00:08 GMT
X-Rack-Cache: miss
Etag: "c226165d5817af7c91592dab0bc0ac63"
Cache-Control: max-age=3600, public
The Cache is missed and Rails gets hit and queries the database:
if stale?(:etag => #document, :last_modified => #document.updated_at.utc) # => true
expires_in 1.hour, :public => true
#post = Post.find(params[:id])
end
SECOND REQUEST
GET /post/1 HTTP/1.1
If-Modified-Since: Thu, 04 Mar 2010 21:00:08 GMT
If-None-Match: "c226165d5817af7c91592dab0bc0ac63"
Cache-Control: max-age=0
HTTP/1.1 304 Not Modified
Date: Fri, 05 Mar 2010 09:10:04 GMT
X-Rack-Cache: miss
Etag: "c226165d5817af7c91592dab0bc0ac63"
Cache-Control: max-age=3600, public
The Cache is missed and Rails gets hit, but this time it sends 304 Not Modified and the database is not hit:
if stale?(:etag => #document, :last_modified => #document.updated_at.utc) # => false
expires_in 1.hour, :public => true
#post = Post.find(params[:id])
end
However I was under the impression this should hit the Cache since the etag matches (If-None-Match/Etag)?
I'm doing a full refresh (F5) so the browser is adding Cache-Control: max-age=0 which is preventing the cache thinking the page is fresh.
It's my understanding that the If-None-Match and If-Modified-Since headers are sent when the browser's cached content expires (the content has been in the browser's cache for more than the maxage in the Cache-Control header). This allows your application to verify that the content is still fresh and if it is, then send the 304 with a new maxage and the same Etag as before.

Resources