Merge branch 'master' of github.com:lifo/docrails

This commit is contained in:
aditya-kapoor 2013-12-10 11:44:07 +05:30
commit 0c55335074
588 changed files with 10622 additions and 6859 deletions

@ -1,11 +1,12 @@
script: 'ci/travis.rb'
before_install:
- travis_retry gem install bundler
- "rvm current | grep 'jruby' && export AR_JDBC=true || echo"
rvm:
- 1.9.3
- 2.0.0
- rbx-2.2.1
- jruby-19mode
- rbx-19mode
env:
- "GEM=railties"
- "GEM=ap,am,amo,as,av"
@ -15,8 +16,8 @@ env:
- "GEM=ar:postgresql"
matrix:
allow_failures:
- rvm: rbx-2.2.1
- rvm: jruby-19mode
- rvm: rbx-19mode
notifications:
email: false
irc:

25
Gemfile

@ -8,10 +8,11 @@ gemspec
gem 'mocha', '~> 0.14', require: false
gem 'rack-cache', '~> 1.2'
gem 'bcrypt-ruby', '~> 3.1.0'
gem 'bcrypt-ruby', '~> 3.1.2'
gem 'jquery-rails', '~> 2.2.0'
gem 'turbolinks'
gem 'coffee-rails', '~> 4.0.0'
gem 'arel', github: 'rails/arel'
# This needs to be with require false to avoid
# it being automatically loaded by sprockets
@ -29,7 +30,7 @@ gem 'dalli', '>= 2.2.1'
# Add your own local bundler stuff
local_gemfile = File.dirname(__FILE__) + "/.Gemfile"
instance_eval File.read local_gemfile if File.exists? local_gemfile
instance_eval File.read local_gemfile if File.exist? local_gemfile
group :test do
platforms :mri_19 do
@ -61,15 +62,27 @@ platforms :ruby do
end
platforms :jruby do
git 'git://github.com/jruby/activerecord-jdbc-adapter.git' do
gem 'activerecord-jdbcsqlite3-adapter'
gem 'json'
if ENV['AR_JDBC']
gem 'activerecord-jdbcsqlite3-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'master'
group :db do
gem 'activerecord-jdbcmysql-adapter'
gem 'activerecord-jdbcpostgresql-adapter'
gem 'activerecord-jdbcmysql-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'master'
gem 'activerecord-jdbcpostgresql-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'master'
end
else
gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0'
group :db do
gem 'activerecord-jdbcmysql-adapter', '>= 1.3.0'
gem 'activerecord-jdbcpostgresql-adapter', '>= 1.3.0'
end
end
end
platforms :rbx do
gem 'psych', '~> 2.0'
gem 'rubysl', '~> 2.0'
end
# gems that are necessary for ActiveRecord tests with Oracle database
if ENV['ORACLE_ENHANCED']
platforms :ruby do

@ -59,7 +59,7 @@ independently outside Rails.
Run with `--help` or `-h` for options.
4. Go to http://localhost:3000 and you'll see: "Welcome aboard: You're riding Ruby on Rails!"
4. Using a browser, go to http://localhost:3000 and you'll see: "Welcome aboard: You're riding Ruby on Rails!"
5. Follow the guidelines to start developing your application. You may find
the following resources handy:

@ -113,7 +113,7 @@ what to do in case anything goes wrong:
$ git tag -m'tagging rc release' v3.0.10.rc1
$ git push
$ git push --tags
$ for i in $(ls dist); do gem push $i; done
$ for i in $(ls pkg); do gem push $i; done
=== Send Rails release announcements

@ -36,15 +36,7 @@ task :smoke do
end
desc "Install gems for all projects."
task :install => :build do
version = File.read("RAILS_VERSION").strip
(PROJECTS - ["railties"]).each do |project|
puts "INSTALLING #{project}"
system("gem install #{project}/pkg/#{project}-#{version}.gem --local --no-ri --no-rdoc")
end
system("gem install railties/pkg/railties-#{version}.gem --local --no-ri --no-rdoc")
system("gem install pkg/rails-#{version}.gem --local --no-ri --no-rdoc")
end
task :install => "all:install"
desc "Generate documentation for the Rails framework"
if ENV['EDGE']

@ -1,7 +1,14 @@
* invoke mailer defaults as procs only if they are procs, do not convert
with to_proc. That an object is convertible to a proc does not mean it's
meant to be always used as a proc. Fixes #11533
* Instrument the generation of Action Mailer messages. The time it takes to
generate a message is written to the log.
*Alex Tsukernik*
*Daniel Schierbeck*
* Invoke mailer defaults as procs only if they are procs, do not convert with
`to_proc`. That an object is convertible to a proc does not mean it's meant
to be always used as a proc.
Fixes #11533.
*Alex Tsukernik*
Please check [4-0-stable](https://github.com/rails/rails/blob/4-0-stable/actionmailer/CHANGELOG.md) for previous changes.

@ -61,9 +61,7 @@ generated would look like this:
Thank you for signing up!
In previous version of Rails you would call <tt>create_method_name</tt> and
<tt>deliver_method_name</tt>. Rails 3.0 has a much simpler interface - you
simply call the method and optionally call +deliver+ on the return value.
In order to send mails, you simply call the method and then call +deliver+ on the return value.
Calling the method returns a Mail Message object:
@ -76,7 +74,7 @@ Or you can just chain the methods together like:
== Setting defaults
It is possible to set default values that will be used in every method in your Action Mailer class. To implement this functionality, you just call the public class method <tt>default</tt> which you get for free from ActionMailer::Base. This method accepts a Hash as the parameter. You can use any of the headers e-mail messages has, like <tt>:from</tt> as the key. You can also pass in a string as the key, like "Content-Type", but Action Mailer does this out of the box for you, so you won't need to worry about that. Finally, it is also possible to pass in a Proc that will get evaluated when it is needed.
It is possible to set default values that will be used in every method in your Action Mailer class. To implement this functionality, you just call the public class method <tt>default</tt> which you get for free from <tt>ActionMailer::Base</tt>. This method accepts a Hash as the parameter. You can use any of the headers e-mail messages has, like <tt>:from</tt> as the key. You can also pass in a string as the key, like "Content-Type", but Action Mailer does this out of the box for you, so you won't need to worry about that. Finally, it is also possible to pass in a Proc that will get evaluated when it is needed.
Note that every value you set with this method will get overwritten if you use the same key in your mailer method.

@ -373,6 +373,12 @@ class Base < AbstractController::Base
include AbstractController::AssetPaths
include AbstractController::Callbacks
PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout]
def _protected_ivars # :nodoc:
PROTECTED_IVARS
end
helper ActionMailer::MailHelper
private_class_method :new #:nodoc:
@ -385,10 +391,6 @@ class Base < AbstractController::Base
parts_order: [ "text/plain", "text/enriched", "text/html" ]
}.freeze
def self.default_protected_instance_vars
super.concat [:@_action_has_layout]
end
class << self
# Register one or more Observers which will be notified when mail is delivered.
def register_observers(*observers)
@ -513,11 +515,18 @@ def initialize(method_name=nil, *args)
process(method_name, *args) if method_name
end
def process(*args) #:nodoc:
lookup_context.skip_default_locale!
def process(method_name, *args) #:nodoc:
payload = {
mailer: self.class.name,
action: method_name
}
super
@_message = NullMail.new unless @_mail_was_called
ActiveSupport::Notifications.instrument("process.action_mailer", payload) do
lookup_context.skip_default_locale!
super
@_message = NullMail.new unless @_mail_was_called
end
end
class NullMail #:nodoc:
@ -687,9 +696,9 @@ def mail(headers = {}, &block)
content_type = headers[:content_type]
# Call all the procs (if any)
class_default = self.class.default
default_values = class_default.merge(class_default) do |k,v|
v.is_a?(Proc) ? instance_eval(&v) : v
default_values = {}
self.class.default.each do |k,v|
default_values[k] = v.is_a?(Proc) ? instance_eval(&v) : v
end
# Handle defaults

@ -64,7 +64,7 @@ def wrap_delivery_behavior(mail, method=nil, options=nil) # :nodoc:
raise "Delivery method cannot be nil"
when Symbol
if klass = delivery_methods[method]
mail.delivery_method(klass,(send(:"#{method}_settings") || {}).merge!(options || {}))
mail.delivery_method(klass, (send(:"#{method}_settings") || {}).merge(options || {}))
else
raise "Invalid delivery method #{method.inspect}"
end

@ -19,6 +19,13 @@ def receive(event)
debug(event.payload[:mail])
end
# An email was generated.
def process(event)
mailer = event.payload[:mailer]
action = event.payload[:action]
debug("\n#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms")
end
# Use the logger configured for ActionMailer::Base
def logger
ActionMailer::Base.logger

@ -152,6 +152,9 @@ def teardown
assert_equal "overridden", delivery_method_instance.settings[:user_name]
assert_equal "somethingobtuse", delivery_method_instance.settings[:password]
assert_equal delivery_method_instance.settings.merge(overridden_options), delivery_method_instance.settings
# make sure that overriding delivery method options per mail instance doesn't affect the Base setting
assert_equal settings, ActionMailer::Base.smtp_settings
end
test "non registered delivery methods raises errors" do

@ -1 +1 @@
<%= t('.greet_user', :name => 'lifo') %>
<%= t('.greet_user', name: 'lifo') %>

@ -1,20 +0,0 @@
Return-Path: <xxx@xxxx.xxx>
Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id C1B953B4CB6 for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:05 -0500
Received: from SMS-GTYxxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id ca for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:04 -0500
Received: from xxx.xxxx.xxx by SMS-GTYxxx.xxxx.xxx with ESMTP id j4AKR3r23323 for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:03 -0500
Date: Tue, 10 May 2005 15:27:03 -0500
From: xxx@xxxx.xxx
Sender: xxx@xxxx.xxx
To: xxxxxxxxxxx@xxxx.xxxx.xxx
Message-Id: <xxx@xxxx.xxx>
X-Original-To: xxxxxxxxxxx@xxxx.xxxx.xxx
Delivered-To: xxx@xxxx.xxx
Importance: normal
Content-Type: text/plain; charset=X-UNKNOWN
Test test. Hi. Waving. m
----------------------------------------------------------------
Sent via Bell Mobility's Text Messaging service.
Envoyé par le service de messagerie texte de Bell Mobilité.
----------------------------------------------------------------

@ -1,32 +0,0 @@
Mime-Version: 1.0 (Apple Message framework v730)
Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151
Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com>
From: foo@example.com
Subject: testing
Date: Mon, 6 Jun 2005 22:21:22 +0200
To: blah@example.com
--Apple-Mail-13-196941151
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=ISO-8859-1;
delsp=yes;
format=flowed
This is the first part.
--Apple-Mail-13-196941151
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Location: Photo25.jpg
Content-ID: <qbFGyPQAS8>
Content-Disposition: inline
jamisSqGSIb3DQEHAqCAMIjamisxCzAJBgUrDgMCGgUAMIAGCSqGSjamisEHAQAAoIIFSjCCBUYw
ggQujamisQICBD++ukQwDQYJKojamisNAQEFBQAwMTELMAkGA1UEBhMCRjamisAKBgNVBAoTA1RE
QzEUMBIGjamisxMLVERDIE9DRVMgQ0jamisNMDQwMjI5MTE1OTAxWhcNMDYwMjamisIyOTAxWjCB
gDELMAkGA1UEjamisEsxKTAnBgNVBAoTIEjamisuIG9yZ2FuaXNhdG9yaXNrIHRpbjamisRuaW5=
--Apple-Mail-13-196941151--

@ -1,29 +0,0 @@
Mime-Version: 1.0 (Apple Message framework v730)
Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151
Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com>
From: foo@example.com
Subject: testing
Date: Mon, 6 Jun 2005 22:21:22 +0200
To: blah@example.com
--Apple-Mail-13-196941151
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=ISO-8859-1;
delsp=yes;
format=flowed
This is the first part.
--Apple-Mail-13-196941151
Content-Type: text/x-ruby-script; name="hello.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="api.rb"
puts "Hello, world!"
gets
--Apple-Mail-13-196941151--

@ -1,114 +0,0 @@
From xxxxxxxxx.xxxxxxx@gmail.com Sun May 8 19:07:09 2005
Return-Path: <xxxxxxxxx.xxxxxxx@gmail.com>
X-Original-To: xxxxx@xxxxx.xxxxxxxxx.com
Delivered-To: xxxxx@xxxxx.xxxxxxxxx.com
Received: from localhost (localhost [127.0.0.1])
by xxxxx.xxxxxxxxx.com (Postfix) with ESMTP id 06C9DA98D
for <xxxxx@xxxxx.xxxxxxxxx.com>; Sun, 8 May 2005 19:09:13 +0000 (GMT)
Received: from xxxxx.xxxxxxxxx.com ([127.0.0.1])
by localhost (xxxxx.xxxxxxxxx.com [127.0.0.1]) (amavisd-new, port 10024)
with LMTP id 88783-08 for <xxxxx@xxxxx.xxxxxxxxx.com>;
Sun, 8 May 2005 19:09:12 +0000 (GMT)
Received: from xxxxxxx.xxxxxxxxx.com (xxxxxxx.xxxxxxxxx.com [69.36.39.150])
by xxxxx.xxxxxxxxx.com (Postfix) with ESMTP id 10D8BA960
for <xxxxx@xxxxxxxxx.org>; Sun, 8 May 2005 19:09:12 +0000 (GMT)
Received: from zproxy.gmail.com (zproxy.gmail.com [64.233.162.199])
by xxxxxxx.xxxxxxxxx.com (Postfix) with ESMTP id 9EBC4148EAB
for <xxxxx@xxxxxxxxx.com>; Sun, 8 May 2005 14:09:11 -0500 (CDT)
Received: by zproxy.gmail.com with SMTP id 13so1233405nzp
for <xxxxx@xxxxxxxxx.com>; Sun, 08 May 2005 12:09:11 -0700 (PDT)
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=beta; d=gmail.com;
h=received:message-id:date:from:reply-to:to:subject:in-reply-to:mime-version:content-type:references;
b=cid1mzGEFa3gtRa06oSrrEYfKca2CTKu9sLMkWxjbvCsWMtp9RGEILjUz0L5RySdH5iO661LyNUoHRFQIa57bylAbXM3g2DTEIIKmuASDG3x3rIQ4sHAKpNxP7Pul+mgTaOKBv+spcH7af++QEJ36gHFXD2O/kx9RePs3JNf/K8=
Received: by 10.36.10.16 with SMTP id 16mr1012493nzj;
Sun, 08 May 2005 12:09:11 -0700 (PDT)
Received: by 10.36.5.10 with HTTP; Sun, 8 May 2005 12:09:11 -0700 (PDT)
Message-ID: <e85734b90505081209eaaa17b@mail.gmail.com>
Date: Sun, 8 May 2005 14:09:11 -0500
From: xxxxxxxxx xxxxxxx <xxxxxxxxx.xxxxxxx@gmail.com>
Reply-To: xxxxxxxxx xxxxxxx <xxxxxxxxx.xxxxxxx@gmail.com>
To: xxxxx xxxx <xxxxx@xxxxxxxxx.com>
Subject: Fwd: Signed email causes file attachments
In-Reply-To: <F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@mac.com>
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_5028_7368284.1115579351471"
References: <F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@mac.com>
------=_Part_5028_7368284.1115579351471
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
We should not include these files or vcards as attachments.
---------- Forwarded message ----------
From: xxxxx xxxxxx <xxxxxxxx@xxx.com>
Date: May 8, 2005 1:17 PM
Subject: Signed email causes file attachments
To: xxxxxxx@xxxxxxxxxx.com
Hi,
Just started to use my xxxxxxxx account (to set-up a GTD system,
natch) and noticed that when I send content via email the signature/
certificate from my email account gets added as a file (e.g.
"smime.p7s").
Obviously I can uncheck the signature option in the Mail compose
window but how often will I remember to do that?
Is there any way these kind of files could be ignored, e.g. via some
sort of exclusions list?
------=_Part_5028_7368284.1115579351471
Content-Type: application/pkcs7-signature; name=smime.p7s
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGFDCCAs0w
ggI2oAMCAQICAw5c+TANBgkqhkiG9w0BAQQFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt
YWlsIElzc3VpbmcgQ0EwHhcNMDUwMzI5MDkzOTEwWhcNMDYwMzI5MDkzOTEwWjBCMR8wHQYDVQQD
ExZUaGF3dGUgRnJlZW1haWwgTWVtYmVyMR8wHQYJKoZIhvcNAQkBFhBzbWhhdW5jaEBtYWMuY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn90dPsYS3LjfMY211OSYrDQLzwNYPlAL
7+/0XA+kdy8/rRnyEHFGwhNCDmg0B6pxC7z3xxJD/8GfCd+IYUUNUQV5m9MkxfP9pTVXZVIYLaBw
o8xS3A0a1LXealcmlEbJibmKkEaoXci3MhryLgpaa+Kk/sH02SNatDO1vS28bPsibZpcc6deFrla
hSYnL+PW54mDTGHIcCN2fbx/Y6qspzqmtKaXrv75NBtuy9cB6KzU4j2xXbTkAwz3pRSghJJaAwdp
+yIivAD3vr0kJE3p+Ez34HMh33EXEpFoWcN+MCEQZD9WnmFViMrvfvMXLGVFQfAAcC060eGFSRJ1
ZQ9UVQIDAQABoy0wKzAbBgNVHREEFDASgRBzbWhhdW5jaEBtYWMuY29tMAwGA1UdEwEB/wQCMAAw
DQYJKoZIhvcNAQEEBQADgYEAQMrg1n2pXVWteP7BBj+Pk3UfYtbuHb42uHcLJjfjnRlH7AxnSwrd
L3HED205w3Cq8T7tzVxIjRRLO/ljq0GedSCFBky7eYo1PrXhztGHCTSBhsiWdiyLWxKlOxGAwJc/
lMMnwqLOdrQcoF/YgbjeaUFOQbUh94w9VDNpWZYCZwcwggM/MIICqKADAgECAgENMA0GCSqGSIb3
DQEBBQUAMIHRMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlD
YXBlIFRvd24xGjAYBgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0
aW9uIFNlcnZpY2VzIERpdmlzaW9uMSQwIgYDVQQDExtUaGF3dGUgUGVyc29uYWwgRnJlZW1haWwg
Q0ExKzApBgkqhkiG9w0BCQEWHHBlcnNvbmFsLWZyZWVtYWlsQHRoYXd0ZS5jb20wHhcNMDMwNzE3
MDAwMDAwWhcNMTMwNzE2MjM1OTU5WjBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENv
bnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWlsIElz
c3VpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMSmPFVzVftOucqZWh5owHUEcJ3f
6f+jHuy9zfVb8hp2vX8MOmHyv1HOAdTlUAow1wJjWiyJFXCO3cnwK4Vaqj9xVsuvPAsH5/EfkTYk
KhPPK9Xzgnc9A74r/rsYPge/QIACZNenprufZdHFKlSFD0gEf6e20TxhBEAeZBlyYLf7AgMBAAGj
gZQwgZEwEgYDVR0TAQH/BAgwBgEB/wIBADBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLnRo
YXd0ZS5jb20vVGhhd3RlUGVyc29uYWxGcmVlbWFpbENBLmNybDALBgNVHQ8EBAMCAQYwKQYDVR0R
BCIwIKQeMBwxGjAYBgNVBAMTEVByaXZhdGVMYWJlbDItMTM4MA0GCSqGSIb3DQEBBQUAA4GBAEiM
0VCD6gsuzA2jZqxnD3+vrL7CF6FDlpSdf0whuPg2H6otnzYvwPQcUCCTcDz9reFhYsPZOhl+hLGZ
GwDFGguCdJ4lUJRix9sncVcljd2pnDmOjCBPZV+V2vf3h9bGCE6u9uo05RAaWzVNd+NWIXiC3CEZ
Nd4ksdMdRv9dX2VPMYIC5zCCAuMCAQEwaTBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3Rl
IENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVtYWls
IElzc3VpbmcgQ0ECAw5c+TAJBgUrDgMCGgUAoIIBUzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcB
MBwGCSqGSIb3DQEJBTEPFw0wNTA1MDgxODE3NDZaMCMGCSqGSIb3DQEJBDEWBBQSkG9j6+hB0pKp
fV9tCi/iP59sNTB4BgkrBgEEAYI3EAQxazBpMGIxCzAJBgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3
dGUgQ29uc3VsdGluZyAoUHR5KSBMdGQuMSwwKgYDVQQDEyNUaGF3dGUgUGVyc29uYWwgRnJlZW1h
aWwgSXNzdWluZyBDQQIDDlz5MHoGCyqGSIb3DQEJEAILMWugaTBiMQswCQYDVQQGEwJaQTElMCMG
A1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNv
bmFsIEZyZWVtYWlsIElzc3VpbmcgQ0ECAw5c+TANBgkqhkiG9w0BAQEFAASCAQAm1GeF7dWfMvrW
8yMPjkhE+R8D1DsiCoWSCp+5gAQm7lcK7V3KrZh5howfpI3TmCZUbbaMxOH+7aKRKpFemxoBY5Q8
rnCkbpg/++/+MI01T69hF/rgMmrGcrv2fIYy8EaARLG0xUVFSZHSP+NQSYz0TTmh4cAESHMzY3JA
nHOoUkuPyl8RXrimY1zn0lceMXlweZRouiPGuPNl1hQKw8P+GhOC5oLlM71UtStnrlk3P9gqX5v7
Tj7Hx057oVfY8FMevjxGwU3EK5TczHezHbWWgTyum9l2ZQbUQsDJxSniD3BM46C1VcbDLPaotAZ0
fTYLZizQfm5hcWEbfYVzkSzLAAAAAAAA
------=_Part_5028_7368284.1115579351471--

@ -1,70 +0,0 @@
From xxxx@xxxx.com Tue May 10 11:28:07 2005
Return-Path: <xxxx@xxxx.com>
X-Original-To: xxxx@xxxx.com
Delivered-To: xxxx@xxxx.com
Received: from localhost (localhost [127.0.0.1])
by xxx.xxxxx.com (Postfix) with ESMTP id 50FD3A96F
for <xxxx@xxxx.com>; Tue, 10 May 2005 17:26:50 +0000 (GMT)
Received: from xxx.xxxxx.com ([127.0.0.1])
by localhost (xxx.xxxxx.com [127.0.0.1]) (amavisd-new, port 10024)
with LMTP id 70060-03 for <xxxx@xxxx.com>;
Tue, 10 May 2005 17:26:49 +0000 (GMT)
Received: from xxx.xxxxx.com (xxx.xxxxx.com [69.36.39.150])
by xxx.xxxxx.com (Postfix) with ESMTP id 8B957A94B
for <xxxx@xxxx.com>; Tue, 10 May 2005 17:26:48 +0000 (GMT)
Received: from xxx.xxxxx.com (xxx.xxxxx.com [64.233.184.203])
by xxx.xxxxx.com (Postfix) with ESMTP id 9972514824C
for <xxxx@xxxx.com>; Tue, 10 May 2005 12:26:40 -0500 (CDT)
Received: by xxx.xxxxx.com with SMTP id 68so1694448wri
for <xxxx@xxxx.com>; Tue, 10 May 2005 10:26:40 -0700 (PDT)
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=beta; d=xxxxx.com;
h=received:message-id:date:from:reply-to:to:subject:mime-version:content-type;
b=g8ZO5ttS6GPEMAz9WxrRk9+9IXBUfQIYsZLL6T88+ECbsXqGIgfGtzJJFn6o9CE3/HMrrIGkN5AisxVFTGXWxWci5YA/7PTVWwPOhJff5BRYQDVNgRKqMl/SMttNrrRElsGJjnD1UyQ/5kQmcBxq2PuZI5Zc47u6CILcuoBcM+A=
Received: by 10.54.96.19 with SMTP id t19mr621017wrb;
Tue, 10 May 2005 10:26:39 -0700 (PDT)
Received: by 10.54.110.5 with HTTP; Tue, 10 May 2005 10:26:39 -0700 (PDT)
Message-ID: <xxxx@xxxx.com>
Date: Tue, 10 May 2005 11:26:39 -0600
From: Test Tester <xxxx@xxxx.com>
Reply-To: Test Tester <xxxx@xxxx.com>
To: xxxx@xxxx.com, xxxx@xxxx.com
Subject: Another PDF
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_2192_32400445.1115745999735"
X-Virus-Scanned: amavisd-new at textdrive.com
------=_Part_2192_32400445.1115745999735
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Just attaching another PDF, here, to see what the message looks like,
and to see if I can figure out what is going wrong here.
------=_Part_2192_32400445.1115745999735
Content-Type: application/pdf; name="broken.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="broken.pdf"
JVBERi0xLjQNCiXk9tzfDQoxIDAgb2JqDQo8PCAvTGVuZ3RoIDIgMCBSDQogICAvRmlsdGVyIC9G
bGF0ZURlY29kZQ0KPj4NCnN0cmVhbQ0KeJy9Wt2KJbkNvm/od6jrhZxYln9hWEh2p+8HBvICySaE
ycLuTV4/1ifJ9qnq09NpSBimu76yLUuy/qzqcPz7+em3Ixx/CDc6CsXxs3b5+fvfjr/8cPz6/BRu
rbfAx/n3739/fuJylJ5u5fjX81OuDr4deK4Bz3z/aDP+8fz0yw8g0Ofq7ktr1Mn+u28rvhy/jVeD
QSa+9YNKHP/pxjvDNfVAx/m3MFz54FhvTbaseaxiDoN2LeMVMw+yA7RbHSCDzxZuaYB2E1Yay7QU
x89vz0+tyFDKMlAHK5yqLmnjF+c4RjEiQIUeKwblXMe+AsZjN1J5yGQL5DHpDHksurM81rF6PKab
gK6zAarIDzIiUY23rJsN9iorAE816aIu6lsgAdQFsuhhkHOUFgVjp2GjMqSewITXNQ27jrMeamkg
1rPI3iLWG2CIaSBB+V1245YVRICGbbpYKHc2USFDl6M09acQVQYhlwIrkBNLISvXhGlF1wi5FHCw
wxZkoGNJlVeJCEsqKA+3YAV5AMb6KkeaqEJQmFKKQU8T1pRi2ihE1Y4CDrqoYFFXYjJJOatsyzuI
8SIlykuxKTMibWK8H1PgEvqYgs4GmQSrEjJAalgGirIhik+p4ZQN9E3ETFPAHE1b8pp1l/0Rc1gl
fQs0ABWvyoZZzU8VnPXwVVcO9BEsyjEJaO6eBoZRyKGlrKoYoOygA8BGIzgwN3RQ15ouigG5idZQ
fx2U4Db2CqiLO0WHAZoylGiCAqhniNQjFjQPSkmjwfNTgQ6M1Ih+eWo36wFmjIxDJZiGUBiWsAyR
xX3EekGOizkGI96Ol9zVZTAivikURhRsHh2E3JhWMpSTZCnnonrLhMCodgrNcgo4uyJUJc6qnVss
nrGd1Ptr0YwisCOYyIbUwVjV4xBUNLbguSO2YHujonAMJkMdSI7bIw91Akq2AUlMUWGFTMAOamjU
OvZQCxIkY2pCpMFo/IwLdVLHs6nddwTRrgoVbvLU9eB0G4EMndV0TNoxHbt3JBWwK6hhv3iHfDtF
yokB302IpEBTnWICde4uYc/1khDbSIkQopO6lcqamGBu1OSE3N5IPSsZX00CkSHRiiyx6HQIShsS
HSVNswdVsaOUSAWq9aYhDtGDaoG5a3lBGkYt/lFlBFt1UqrYnzVtUpUQnLiZeouKgf1KhRBViRRk
ExepJCzTwEmFDalIRbLEGtw0gfpESOpIAF/NnpPzcVCG86s0g2DuSyd41uhNGbEgaSrWEXORErbw
------=_Part_2192_32400445.1115745999735--

@ -1,59 +0,0 @@
Return-Path: <xxx@xxxx.xxx>
Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id 6AAEE3B4D23 for <xxx@xxxx.xxx>; Sun, 8 May 2005 12:30:23 -0500
Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id j48HUC213279 for <xxx@xxxx.xxx>; Sun, 8 May 2005 12:30:13 -0500
Received: from conversion-xxx.xxxx.xxx.net by xxx.xxxx.xxx id <0IG600901LQ64I@xxx.xxxx.xxx> for <xxx@xxxx.xxx>; Sun, 8 May 2005 12:30:12 -0500
Received: from agw1 by xxx.xxxx.xxx with ESMTP id <0IG600JFYLYCAxxx@xxxx.xxx> for <xxx@xxxx.xxx>; Sun, 8 May 2005 12:30:12 -0500
Date: Sun, 8 May 2005 12:30:08 -0500
From: xxx@xxxx.xxx
To: xxx@xxxx.xxx
Message-Id: <7864245.1115573412626.JavaMxxx@xxxx.xxx>
Subject: Filth
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary=mimepart_427e4cb4ca329_133ae40413c81ef
X-Mms-Priority: 1
X-Mms-Transaction-Id: 3198421808-0
X-Mms-Message-Type: 0
X-Mms-Sender-Visibility: 1
X-Mms-Read-Reply: 1
X-Original-To: xxx@xxxx.xxx
X-Mms-Message-Class: 0
X-Mms-Delivery-Report: 0
X-Mms-Mms-Version: 16
Delivered-To: xxx@xxxx.xxx
X-Nokia-Ag-Version: 2.0
This is a multi-part message in MIME format.
--mimepart_427e4cb4ca329_133ae40413c81ef
Content-Type: multipart/mixed; boundary=mimepart_427e4cb4cbd97_133ae40413c8217
--mimepart_427e4cb4cbd97_133ae40413c8217
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Content-Location: text.txt
Some text
--mimepart_427e4cb4cbd97_133ae40413c8217--
--mimepart_427e4cb4ca329_133ae40413c81ef
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
--
This Orange Multi Media Message was sent wirefree from an Orange
MMS phone. If you would like to reply, please text or phone the
sender directly by using the phone number listed in the sender's
address. To learn more about Orange's Multi Media Messaging
Service, find us on the Web at xxx.xxxx.xxx.uk/mms
--mimepart_427e4cb4ca329_133ae40413c81ef
--mimepart_427e4cb4ca329_133ae40413c81ef-

@ -1,19 +0,0 @@
Return-Path: <xxx@xxxx.xxx>
Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id C1B953B4CB6 for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:05 -0500
Received: from SMS-GTYxxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id ca for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:04 -0500
Received: from xxx.xxxx.xxx by SMS-GTYxxx.xxxx.xxx with ESMTP id j4AKR3r23323 for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:03 -0500
Date: Tue, 10 May 2005 15:27:03 -0500
From: xxx@xxxx.xxx
Sender: xxx@xxxx.xxx
To: xxxxxxxxxxx@xxxx.xxxx.xxx
Message-Id: <xxx@xxxx.xxx>
X-Original-To: xxxxxxxxxxx@xxxx.xxxx.xxx
Delivered-To: xxx@xxxx.xxx
Importance: normal
Test test. Hi. Waving. m
----------------------------------------------------------------
Sent via Bell Mobility's Text Messaging service.
Envoyé par le service de messagerie texte de Bell Mobilité.
----------------------------------------------------------------

@ -1,20 +0,0 @@
Return-Path: <xxx@xxxx.xxx>
Received: from xxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id C1B953B4CB6 for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:05 -0500
Received: from SMS-GTYxxx.xxxx.xxx by xxx.xxxx.xxx with ESMTP id ca for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:04 -0500
Received: from xxx.xxxx.xxx by SMS-GTYxxx.xxxx.xxx with ESMTP id j4AKR3r23323 for <xxxxx@Exxx.xxxx.xxx>; Tue, 10 May 2005 15:27:03 -0500
Date: Tue, 10 May 2005 15:27:03 -0500
From: xxx@xxxx.xxx
Sender: xxx@xxxx.xxx
To: xxxxxxxxxxx@xxxx.xxxx.xxx
Message-Id: <xxx@xxxx.xxx>
X-Original-To: xxxxxxxxxxx@xxxx.xxxx.xxx
Delivered-To: xxx@xxxx.xxx
Importance: normal
Content-Type: text/plain; charset=us-ascii
Test test. Hi. Waving. m
----------------------------------------------------------------
Sent via Bell Mobility's Text Messaging service.
Envoyé par le service de messagerie texte de Bell Mobilité.
----------------------------------------------------------------

@ -1,66 +0,0 @@
Mime-Version: 1.0 (Apple Message framework v730)
Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151
Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com>
From: foo@example.com
Subject: testing
Date: Mon, 6 Jun 2005 22:21:22 +0200
To: blah@example.com
--Apple-Mail-13-196941151
Content-Type: multipart/mixed;
boundary=Apple-Mail-12-196940926
--Apple-Mail-12-196940926
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=ISO-8859-1;
delsp=yes;
format=flowed
This is the first part.
--Apple-Mail-12-196940926
Content-Transfer-Encoding: 7bit
Content-Type: text/x-ruby-script;
x-unix-mode=0666;
name="test.rb"
Content-Disposition: attachment;
filename=test.rb
puts "testing, testing"
--Apple-Mail-12-196940926
Content-Transfer-Encoding: base64
Content-Type: application/pdf;
x-unix-mode=0666;
name="test.pdf"
Content-Disposition: inline;
filename=test.pdf
YmxhaCBibGFoIGJsYWg=
--Apple-Mail-12-196940926
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
--Apple-Mail-12-196940926--
--Apple-Mail-13-196941151
Content-Transfer-Encoding: base64
Content-Type: application/pkcs7-signature;
name=smime.p7s
Content-Disposition: attachment;
filename=smime.p7s
jamisSqGSIb3DQEHAqCAMIjamisxCzAJBgUrDgMCGgUAMIAGCSqGSjamisEHAQAAoIIFSjCCBUYw
ggQujamisQICBD++ukQwDQYJKojamisNAQEFBQAwMTELMAkGA1UEBhMCRjamisAKBgNVBAoTA1RE
QzEUMBIGjamisxMLVERDIE9DRVMgQ0jamisNMDQwMjI5MTE1OTAxWhcNMDYwMjamisIyOTAxWjCB
gDELMAkGA1UEjamisEsxKTAnBgNVBAoTIEjamisuIG9yZ2FuaXNhdG9yaXNrIHRpbjamisRuaW5=
--Apple-Mail-13-196941151--

@ -1,47 +0,0 @@
From xxxxxxxxx.xxxxxxx@gmail.com Sun May 8 19:07:09 2005
Return-Path: <xxxxxxxxx.xxxxxxx@gmail.com>
Message-ID: <e85734b90505081209eaaa17b@mail.gmail.com>
Date: Sun, 8 May 2005 14:09:11 -0500
From: xxxxxxxxx xxxxxxx <xxxxxxxxx.xxxxxxx@gmail.com>
Reply-To: xxxxxxxxx xxxxxxx <xxxxxxxxx.xxxxxxx@gmail.com>
To: xxxxx xxxx <xxxxx@xxxxxxxxx.com>
Subject: Fwd: Signed email causes file attachments
In-Reply-To: <F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@mac.com>
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_5028_7368284.1115579351471"
References: <F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@mac.com>
------=_Part_5028_7368284.1115579351471
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
We should not include these files or vcards as attachments.
---------- Forwarded message ----------
From: xxxxx xxxxxx <xxxxxxxx@xxx.com>
Date: May 8, 2005 1:17 PM
Subject: Signed email causes file attachments
To: xxxxxxx@xxxxxxxxxx.com
Hi,
Test attachments oddly encoded with japanese charset.
------=_Part_5028_7368284.1115579351471
Content-Type: application/octet-stream; name*=iso-2022-jp'ja'01%20Quien%20Te%20Dij%8aat.%20Pitbull.mp3
Content-Transfer-Encoding: base64
Content-Disposition: attachment
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGFDCCAs0w
ggI2oAMCAQICAw5c+TANBgkqhkiG9w0BAQQFADBiMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh
d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEsMCoGA1UEAxMjVGhhd3RlIFBlcnNvbmFsIEZyZWVt
YWlsIElzc3VpbmcgQ0EwHhcNMDUwMzI5MDkzOTEwWhcNMDYwMzI5MDkzOTEwWjBCMR8wHQYDVQQD
ExZUaGF3dGUgRnJlZW1haWwgTWVtYmVyMR8wHQYJKoZIhvcNAQkBFhBzbWhhdW5jaEBtYWMuY29t
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn90dPsYS3LjfMY211OSYrDQLzwNYPlAL
7+/0XA+kdy8/rRnyEHFGwhNCDmg0B6pxC7z3xxJD/8GfCd+IYUUNUQV5m9MkxfP9pTVXZVIYLaBw
------=_Part_5028_7368284.1115579351471--

@ -1,28 +0,0 @@
Received: from xxx.xxx.xxx ([xxx.xxx.xxx.xxx] verified)
by xxx.com (CommuniGate Pro SMTP 4.2.8)
with SMTP id 2532598 for xxx@xxx.com; Wed, 23 Feb 2005 17:51:49 -0500
Received-SPF: softfail
receiver=xxx.com; client-ip=xxx.xxx.xxx.xxx; envelope-from=xxx@xxx.xxx
quite Delivered-To: xxx@xxx.xxx
Received: by xxx.xxx.xxx (Wostfix, from userid xxx)
id 0F87F333; Wed, 23 Feb 2005 16:16:17 -0600
Date: Wed, 23 Feb 2005 18:20:17 -0400
From: "xxx xxx" <xxx@xxx.xxx>
Message-ID: <4D6AA7EB.6490534@xxx.xxx>
To: xxx@xxx.com
Subject: Stop adware/spyware once and for all.
X-Scanned-By: MIMEDefang 2.11 (www dot roaringpenguin dot com slash mimedefang)
You are infected with:
Ad Ware and Spy Ware
Get your free scan and removal download now,
before it gets any worse.
http://xxx.xxx.info?aid=3D13&?stat=3D4327kdzt
no more? (you will still be infected)
http://xxx.xxx.info/discon/?xxx@xxx.com

@ -1,14 +0,0 @@
Mime-Version: 1.0 (Apple Message framework v730)
Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com>
From: foo@example.com
Subject: testing
Date: Mon, 6 Jun 2005 22:21:22 +0200
To: blah@example.com
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain
A fax has arrived from remote ID ''.=0D=0A-----------------------=
-------------------------------------=0D=0ATime: 3/9/2006 3:50:52=
PM=0D=0AReceived from remote ID: =0D=0AInbound user ID XXXXXXXXXX, r=
outing code XXXXXXXXX=0D=0AResult: (0/352;0/0) Successful Send=0D=0AP=
age record: 1 - 1=0D=0AElapsed time: 00:58 on channel 11=0D=0A

@ -1,104 +0,0 @@
Return-Path: <mikel.other@baci>
Received: from some.isp.com by baci with ESMTP id 632BD5758 for <mikel.lindsaar@baci>; Sun, 21 Oct 2007 19:38:21 +1000
Date: Sun, 21 Oct 2007 19:38:13 +1000
From: Mikel Lindsaar <mikel.other@baci>
Reply-To: Mikel Lindsaar <mikel.other@baci>
To: mikel.lindsaar@baci
Message-Id: <009601c813c6$19df3510$0437d30a@mikel091a>
Subject: Testing outlook
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=----=_NextPart_000_0093_01C81419.EB75E850
Delivered-To: mikel.lindsaar@baci
X-Mimeole: Produced By Microsoft MimeOLE V6.00.2900.3138
X-Msmail-Priority: Normal
This is a multi-part message in MIME format.
------=_NextPart_000_0093_01C81419.EB75E850
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: Quoted-printable
Hello
This is an outlook test
So there.
Me.
------=_NextPart_000_0093_01C81419.EB75E850
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: Quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.6000.16525" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Hello</FONT></DIV>
<DIV><FONT face=3DArial size=3D2><STRONG>This is an outlook=20
test</STRONG></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><STRONG></STRONG></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><STRONG>So there.</STRONG></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>Me.</FONT></DIV></BODY></HTML>
------=_NextPart_000_0093_01C81419.EB75E850--
Return-Path: <mikel.other@baci>
Received: from some.isp.com by baci with ESMTP id 632BD5758 for <mikel.lindsaar@baci>; Sun, 21 Oct 2007 19:38:21 +1000
Date: Sun, 21 Oct 2007 19:38:13 +1000
From: Mikel Lindsaar <mikel.other@baci>
Reply-To: Mikel Lindsaar <mikel.other@baci>
To: mikel.lindsaar@baci
Message-Id: <009601c813c6$19df3510$0437d30a@mikel091a>
Subject: Testing outlook
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=----=_NextPart_000_0093_01C81419.EB75E850
Delivered-To: mikel.lindsaar@baci
X-Mimeole: Produced By Microsoft MimeOLE V6.00.2900.3138
X-Msmail-Priority: Normal
This is a multi-part message in MIME format.
------=_NextPart_000_0093_01C81419.EB75E850
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: Quoted-printable
Hello
This is an outlook test
So there.
Me.
------=_NextPart_000_0093_01C81419.EB75E850
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: Quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.6000.16525" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Hello</FONT></DIV>
<DIV><FONT face=3DArial size=3D2><STRONG>This is an outlook=20
test</STRONG></FONT></DIV>
<DIV><FONT face=3DArial size=3D2><STRONG></STRONG></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2><STRONG>So there.</STRONG></FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>Me.</FONT></DIV></BODY></HTML>
------=_NextPart_000_0093_01C81419.EB75E850--

@ -1,100 +0,0 @@
From jamis@37signals.com Thu Feb 22 11:20:31 2007
Mime-Version: 1.0 (Apple Message framework v752.3)
Message-Id: <2CCE0408-10C7-4045-9B16-A1C11C31469B@37signals.com>
Content-Type: multipart/signed;
micalg=sha1;
boundary=Apple-Mail-42-587703407;
protocol="application/pkcs7-signature"
To: Jamis Buck <jamis@jamisbuck.org>
Subject: Testing attachments
From: Jamis Buck <jamis@37signals.com>
Date: Thu, 22 Feb 2007 11:20:31 -0700
--Apple-Mail-42-587703407
Content-Type: multipart/mixed;
boundary=Apple-Mail-41-587703287
--Apple-Mail-41-587703287
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
Here is a test of an attachment via email.
- Jamis
--Apple-Mail-41-587703287
Content-Transfer-Encoding: base64
Content-Type: image/png;
x-unix-mode=0644;
name=byo-ror-cover.png
Content-Disposition: inline;
filename=truncated.png
iVBORw0KGgoAAAANSUhEUgAAAKUAAADXCAYAAAB7wZEQAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz
AAALEgAACxIB0t1+/AAAABd0RVh0Q3JlYXRpb24gVGltZQAxLzI1LzIwMDeD9CJVAAAAGHRFWHRT
b2Z0d2FyZQBBZG9iZSBGaXJld29ya3NPsx9OAAAyBWlUWHRYTUw6Y29tLmFkb2JlLnhtcDw/eHBh
Y2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1l
dGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDQuMS1j
MDIwIDEuMjU1NzE2LCBUdWUgT2N0IDEwIDIwMDYgMjM6MTY6MzQiPgogICA8cmRmOlJERiB4bWxu
czpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAg
ICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4YXA9Imh0
dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eGFwOkNyZWF0b3JUb29sPkFk
b2JlIEZpcmV3b3JrcyBDUzM8L3hhcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhhcDpDcmVhdGVE
YXRlPjIwMDctMDEtMjVUMDU6Mjg6MjFaPC94YXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhhcDpN
b2RpZnlEYXRlPjIwMDctMDEtMjVUMDU6Mjg6MjFaPC94YXA6TW9kaWZ5RGF0ZT4KICAgICAgPC9y
ZGY6RGVzY3JpcHRpb24+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAg
ICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CiAgICAg
ICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0
hhojpmnJMfaYFmSkXWg5PGCmHXVj/c9At0hSK2xGdd8F3muk0VFjb4f5Ue0ksQ8qAcq0delaXhdb
DjKNnF+3B3t9kObZYmk7AZgWYqO9anpR3wpM9sQ5XslB9a+kWyTtNb0fOmudzGHfPFBQDKesyycm
DBL7Cw5bXjIEuci+SSOm/LYnXDZu6iuPEj8lYBb+OU8xx1f9m+e5rhJiYKqjo5vHfiZp+VUkW9xc
Ufd6JHNWc47PkQqb9ie3SLEZB/ZqyAssiqURY+G35iOMZUrHbasHnb80QAPv9FHtAbJIyro7bi5b
ai2TEAKen5+LJNWrglZjm3UbZvt7KryA2J5b5J1jZF8kL6GzvG1Zqx54Y1y7J7n20wMOt9frG2sW
uwGP07kNz3732vf6bfvAvLldfS+9fts2euXY37D+R29FGZdlnhzV4TTFmPJduBP2RbNNua4rTqcT
Qt7Xy1KUB0AHSdP5AZQYvHZg7WD1XvYeMO1A9HhZPqMX5KXbMBrn2efxns/ee21674efxz4Tp/fq
2HZ648dgYaC1i3Vq1IbNPq3PvDTPezY9FaRISjvnzWqdgcWN8EJgjnNq+Z7ktOm9l2Nfth28EZi4
bG/we5JwxM+Tql47/D/X6b38I8/RyxvxPJrX6zvQbo3h9jyJx+C0ALX327QETHl5eYlaYCT5rPTb
+5/rAq26t3lKIxV/p88hq6ptngdgCzoPjJqndiLfc/6y5A14WeDFGNPct4iUsJBV2bYzLEV7m83s
6Rp63VPhHKC/g/LzaU9qexJRr56043JWinqAtfZqsSm1sjoznthl54dtCqv+uL4nIY+oYWuc3+nH
kGfn8b0HQpvOYLQAZUDanbJs3jQhITZEgdarZK+cO6ySlL13rut5nFaN23s7u3Snz6eRPTkCoc2/
Vp1zHfZVFpZ87FiMVLV1iqyK5rlzfji2GzjfDsodlD+Weo5UD4h6PwKqzQMqID0tq2VjjFVSMpis
ZLRAs7sePZBZAHI+gIanB8I7MD+femAceeUe2Kxa5jS950kZ1p5eNEdeX1+jFmSpZ+1EdWCsDcne
NPNgUHNw3aYpnzv9PGTX0uo94EtN9qq1rOdxe3kc79T8ukeHJJ8Fnxej6qlylbLLsjQLOy6Xy2a1
kefs/N+nM7+S7IG5/E5Yc7F003pWErLjbH0O5cGadiMptSB/DZ5U5DI9yeg5MFYyMj8lC/Y7/Xjq
OZlWcnpg9aQfXz2HRq+Wn5xOp6gN8tWq8R44e2pfyzLYemEgprst+XXk2Zj2nXlbsG05BprndTMv
C3QRaXczshhVsHnMgfYn80Y2g5JureA6wBasPeP7LkE/jvZMJAaf/g/U2RelHsisvan5FqweIAHg
Pwc7L68GxvVDAAAAAElFTkSuQmCC
--Apple-Mail-41-587703287--
--Apple-Mail-42-587703407
Content-Transfer-Encoding: base64
Content-Type: application/pkcs7-signature;
name=smime.p7s
Content-Disposition: attachment;
filename=smime.p7s
MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIGJzCCAuAw
ggJJoAMCAQICEFjnFNYXwDEZRWY5EkfzopUwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCWkEx
JTAjBgNVBAoTHFRoYXd0ZSBDb25zdWx0aW5nIChQdHkpIEx0ZC4xLDAqBgNVBAMTI1RoYXd0ZSBQ
ZXJzb25hbCBGcmVlbWFpbCBJc3N1aW5nIENBMB4XDTA2MDkxMjE3MDExMloXDTA3MDkxMjE3MDEx
MlowRTEfMB0GA1UEAxMWVGhhd3RlIEZyZWVtYWlsIE1lbWJlcjEiMCAGCSqGSIb3DQEJARYTamFt
aXNAMzdzaWduYWxzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO2A9JeOFIFJ
G6z8pTcAldrZ2nMe+Xb1tNrbHgoVzN/QhHXM4qst2Ml93cmFLjMmwG7P9RJeU4oNx+jTqVoBB7NV
Ne1/o56Do0KhfMZ9iUDQdPLbkZMq4EEpFMdm6PyM3muRKwPhj66iAWe/osCb8DowUK2f66vaRx0Z
Y0MQHIIrXE02Ta4IfAhIfPqBLkZ4WgTYBHN9vMdYea1jF0GO4gqGk1wqwb3yxv2QMYMbwJ6SI+k/
ZjkSR/OilTCBhwYLKoZIhvcNAQkQAgsxeKB2MGIxCzAJBgNVBAYTAlpBMSUwIwYDVQQKExxUaGF3
dGUgQ29uc3VsdGluZyAoUHR5KSBMdGQuMSwwKgYDVQQDEyNUaGF3dGUgUGVyc29uYWwgRnJlZW1h
aWwgSXNzdWluZyBDQQIQWOcU1hfAMRlFZjkSR/OilTANBgkqhkiG9w0BAQEFAASCAQCfwQiC3v6/
yleRDGv3bJ4nQYQ+c3mz3+mn3Xi6uU35n3piwxZZaWRdmLyiXPvU+QReHpSf3l2qsEZM3sdE0XF9
eRul/+QTFJcDNXOEAxG1zC2Gpz+6c6RrX4Ou12Pwkp+pNrZWTSY/mZgdqcArupOBcZi7qBjoWcy5
wb54dfvSSjrjmqLbkH/E8ww/6gGQuU/xXpAUZgUrTmQHrNKeIdSh5oDkOxFaFWvnmb8Z/2ixKqW/
Ux6WqamyvBtTs/5YBEtnpZOk+uVoscYEUBhU+DVJ2OSvTdXSivMtBdXmGTsG22k+P1NGUHi/A7ev
xPaO0uk4V8xyjNlN4HPuGpkrlXwPAAAAAAAA
--Apple-Mail-42-587703407--

@ -1,14 +0,0 @@
From jamis@37signals.com Mon May 2 16:07:05 2005
Mime-Version: 1.0 (Apple Message framework v622)
Content-Transfer-Encoding: base64
Message-Id: <d3b8cf8e49f04480850c28713a1f473e@37signals.com>
Content-Type: text/plain;
charset=EUC-KR;
format=flowed
To: jamis@37signals.com
From: Jamis Buck <jamis@37signals.com>
Subject: Re: Test: =?UTF-8?B?Iua8ouWtlyI=?= mid =?UTF-8?B?Iua8ouWtlyI=?= tail
Date: Mon, 2 May 2005 16:07:05 -0600
tOu6zrrQwMcguLbC+bChwfa3ziwgv+y4rrTCIMfPs6q01MC7ILnPvcC0z7TZLg0KDQrBpiDAzLin
wLogSmFtaXPA1LTPtNku

@ -1 +1 @@
Hey Ho, <%= render :partial => "subtemplate" %>
Hey Ho, <%= render partial: "subtemplate" %>

@ -24,10 +24,13 @@ def set_logger(logger)
def test_deliver_is_notified
BaseMailer.welcome.deliver
wait
assert_equal(1, @logger.logged(:info).size)
assert_match(/Sent mail to system@test.lindsaar.net/, @logger.logged(:info).first)
assert_equal(1, @logger.logged(:debug).size)
assert_match(/Welcome/, @logger.logged(:debug).first)
assert_equal(2, @logger.logged(:debug).size)
assert_match(/BaseMailer#welcome: processed outbound mail in [\d.]+ms/, @logger.logged(:debug).first)
assert_match(/Welcome/, @logger.logged(:debug).second)
end
def test_receive_is_notified
@ -39,4 +42,4 @@ def test_receive_is_notified
assert_equal(1, @logger.logged(:debug).size)
assert_match(/Jamis/, @logger.logged(:debug).first)
end
end
end

@ -120,7 +120,7 @@ def without_mail_call
end
def with_nil_as_return_value
mail(:template_name => "welcome")
mail(template_name: "welcome")
nil
end

@ -1,7 +1,126 @@
* Introduce `BasicRendering` which is the most basic rendering implementation. It
allows to `render :text` and `render :nothing` without depending on Action View.
* Fix formatting for `rake routes` when a section is shorter than a header.
*Łukasz Strzałkowski*
*Sıtkı Bağdat*
* Take a hash with options inside array in `#url_for`.
Example:
url_for [:new, :admin, :post, { param: 'value' }]
# => http://example.com/admin/posts/new?param=value
*Andrey Ognevsky*
* Add `session#fetch` method
fetch behaves similarly to [Hash#fetch](http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch),
with the exception that the returned value is always saved into the session.
It returns a value from the hash for the given key.
If the key cant be found, there are several options:
* With no other arguments, it will raise an KeyError exception.
* If a default value is given, then that will be returned.
* If the optional code block is specified, then that will be run and its result returned.
*Damien Mathieu*
* Don't let strong parameters mutate the given hash via `fetch`
Create a new instance if the given parameter is a `Hash` instead of
passing it to the `convert_hashes_to_parameters` method since it is
overriding its default value.
*Brendon Murphy*, *Doug Cole*
* Add `params` option to `button_to` form helper, which renders the given hash
as hidden form fields.
*Andy Waite*
* Make assets helpers work in the controllers like it works in the views.
Example:
# config/application.rb
config.asset_host = 'http://mycdn.com'
ActionController::Base.helpers.asset_path('fallback.png')
# => http://mycdn.com/assets/fallback.png
Fixes #10051.
*Tima Maslyuchenko*
* Respect `SCRIPT_NAME` when using `redirect` with a relative path
Example:
# application routes.rb
mount BlogEngine => '/blog'
# engine routes.rb
get '/admin' => redirect('admin/dashboard')
This now redirects to the path `/blog/admin/dashboard`, whereas before it would've
generated an invalid url because there would be no slash between the host name and
the path. It also allows redirects to work where the application is deployed to a
subdirectory of a website.
Fixes #7977.
*Andrew White*
* Fixing repond_with working directly on the options hash
This fixes an issue where the respond_with worked directly with the given
options hash, so that if a user relied on it after calling respond_with,
the hash wouldn't be the same.
Fixes #12029.
*bluehotdog*
* Fix `ActionDispatch::RemoteIp::GetIp#calculate_ip` to only check for spoofing
attacks if both `HTTP_CLIENT_IP` and `HTTP_X_FORWARDED_FOR` are set.
Fixes #10844.
*Tamir Duberstein*
* Strong parameters should permit nested number as key.
Fixes #12293.
*kennyj*
* Fix regex used to detect URI schemes in `redirect_to` to be consistent with
RFC 3986.
*Derek Prior*
* Fix incorrect `assert_redirected_to` failure message for protocol-relative
URLs.
*Derek Prior*
* Fix an issue where router can't recognize downcased url encoding path.
Fixes #12269.
*kennyj*
* Fix custom flash type definition. Misusage of the `_flash_types` class variable
caused an error when reloading controllers with custom flash types.
Fixes #12057.
*Ricardo de Cillo*
* Do not break params filtering on `nil` values.
Fixes #12149.
*Vasiliy Ermolovich*
* Separate Action View completely from Action Pack.
@ -14,21 +133,21 @@
* Fix an issue where :if and :unless controller action procs were being run
before checking for the correct action in the :only and :unless options.
Fixes #11799
Fixes #11799.
*Nicholas Jakobsen*
* Fix an issue where `assert_dom_equal` and `assert_dom_not_equal` were
ignoring the passed failure message argument.
Fixes #11751
Fixes #11751.
*Ryan McGeary*
* Allow REMOTE_ADDR, HTTP_HOST and HTTP_USER_AGENT to be overridden from
the environment passed into `ActionDispatch::TestRequest.new`.
Fixes #11590
Fixes #11590.
*Andrew White*
@ -43,7 +162,7 @@
* Skip routes pointing to a redirect or mounted application when generating urls
using an options hash as they aren't relevant and generate incorrect urls.
Fixes #8018
Fixes #8018.
*Andrew White*
@ -61,7 +180,7 @@
* Fix `ActionDispatch::ParamsParser#parse_formatted_parameters` to rewind body input stream on
parsing json params.
Fixes #11345
Fixes #11345.
*Yuri Bol*, *Paul Nikitochkin*
@ -94,7 +213,7 @@
was setting `request.formats` with an array containing a `nil` value, which
raised an error when setting the controller formats.
Fixes #10965
Fixes #10965.
*Becker*
@ -103,15 +222,17 @@
no `:to` present in the options hash so should only affect routes using the
shorthand syntax (i.e. endpoint is inferred from the path).
Fixes #9856
Fixes #9856.
*Yves Senn*, *Andrew White*
* ActionView extracted from ActionPack
* ActionView extracted from ActionPack.
*Piotr Sarnacki*, *Łukasz Strzałkowski*
* Fix removing trailing slash for mounted apps #3215
* Fix removing trailing slash for mounted apps.
Fixes #3215.
*Piotr Sarnacki*

@ -21,10 +21,9 @@
s.add_dependency 'activesupport', version
s.add_dependency 'rack', '~> 1.5.2'
s.add_dependency 'rack-test', '~> 0.6.2'
s.add_dependency 'rack', '~> 1.5.2'
s.add_dependency 'rack-test', '~> 0.6.2'
s.add_development_dependency 'actionview', version
s.add_development_dependency 'activemodel', version
s.add_development_dependency 'tzinfo', '~> 0.3.37'
s.add_development_dependency 'actionview', version
s.add_development_dependency 'activemodel', version
end

@ -114,11 +114,6 @@ def method_added(name)
end
end
# Define some internal variables that should not be propagated to the view.
def self.default_protected_instance_vars
[]
end
abstract!
# Calls the action going through the entire action dispatch stack.

@ -1,5 +1,6 @@
require 'active_support/concern'
require 'active_support/core_ext/class/attribute'
require 'set'
module AbstractController
class DoubleRenderError < Error
@ -13,8 +14,14 @@ def initialize(message = nil)
module Rendering
extend ActiveSupport::Concern
def self.default_protected_instance_vars
super.concat [:@_action_name, :@_response_body, :@_formats, :@_prefixes, :@_config]
# Normalize arguments, options and then delegates render_to_body and
# sticks the result in self.response_body.
# :api: public
def render(*args, &block)
options = _normalize_render(*args, &block)
self.response_body = render_to_body(options)
_process_format(rendered_format)
self.response_body
end
# Raw rendering of a template to a string.
@ -29,40 +36,49 @@ def self.default_protected_instance_vars
# overridden in order to still return a string.
# :api: plugin
def render_to_string(*args, &block)
options = _normalize_render(*args, &block)
render_to_body(options)
end
# Raw rendering of a template.
# :api: plugin
# Performs the actual template rendering.
# :api: public
def render_to_body(options = {})
end
# Normalize arguments, options and then delegates render_to_body and
# sticks the result in self.response_body.
# :api: public
def render(*args, &block)
end
# Return Content-Type of rendered content
# Returns Content-Type of rendered content
# :api: public
def rendered_format
Mime::TEXT
end
DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %w(
@_action_name @_response_body @_formats @_prefixes @_config
@_view_context_class @_view_renderer @_lookup_context
@_routes @_db_runtime
).map(&:to_sym)
# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
# :api: public
def view_assigns
hash = {}
(instance_variables - self.class.default_protected_instance_vars).each do |name|
hash[name[1..-1]] = instance_variable_get(name)
end
hash
protected_vars = _protected_ivars
variables = instance_variables
variables.reject! { |s| protected_vars.include? s }
variables.each_with_object({}) { |name, hash|
hash[name.slice(1, name.length)] = instance_variable_get(name)
}
end
# Normalize args by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :file => "foo/bar".
# :api: plugin
def _normalize_args(action=nil, options={})
options
if action.is_a? Hash
action
else
options
end
end
# Normalize options.
@ -76,5 +92,22 @@ def _normalize_options(options)
def _process_options(options)
options
end
# Process the rendered format.
# :api: private
def _process_format(format)
end
# Normalize args and options.
# :api: private
def _normalize_render(*args, &block)
options = _normalize_args(*args, &block)
_normalize_options(options)
options
end
def _protected_ivars # :nodoc:
DEFAULT_PROTECTED_INSTANCE_VARIABLES
end
end
end

@ -13,7 +13,6 @@ module ActionController
autoload :Middleware
autoload_under "metal" do
autoload :BasicRendering, 'action_controller/metal/rendering'
autoload :Compatibility
autoload :ConditionalGet
autoload :Cookies

@ -3,7 +3,7 @@
module ActionController
# The <tt>metal</tt> anonymous class was introduced to solve issue with including modules in <tt>ActionController::Base</tt>.
# Modules needes to be included in particluar order. First wee need to have <tt>AbstractController::Rendering</tt> included,
# Modules needs to be included in particluar order. First we need to have <tt>AbstractController::Rendering</tt> included,
# next we should include actuall implementation which would be for example <tt>ActionView::Rendering</tt> and after that
# <tt>ActionController::Rendering</tt>. This order must be preserved and as we want to have middle module included dynamicaly
# <tt>metal</tt> class was introduced. It has <tt>AbstractController::Rendering</tt> included and is parent class of
@ -14,7 +14,6 @@ module ActionController
#
metal = Class.new(Metal) do
include AbstractController::Rendering
include ActionController::BasicRendering
end
# Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
@ -74,7 +73,7 @@ module ActionController
# <input type="text" name="post[address]" value="hyacintvej">
#
# A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
# If the address input had been named "post[address][street]", the params would have included
# If the address input had been named <tt>post[address][street]</tt>, the params would have included
# <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
#
# == Sessions
@ -261,11 +260,17 @@ def self.without_modules(*modules)
include mod
end
def self.default_protected_instance_vars
super.concat [
:@_status, :@_headers, :@_params, :@_env, :@_response, :@_request,
:@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout
]
# Define some internal variables that should not be propagated to the view.
PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [
:@_status, :@_headers, :@_params, :@_env, :@_response, :@_request,
:@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout ]
def _protected_ivars # :nodoc:
PROTECTED_IVARS
end
def self.protected_instance_variables
PROTECTED_IVARS
end
ActiveSupport.run_load_hooks(:action_controller, self)

@ -37,7 +37,7 @@ def add_flash_types(*types)
end
helper_method type
_flash_types << type
self._flash_types += [type]
end
end
end

@ -48,7 +48,7 @@ module ClassMethods
# You can pass any of the following options to affect the redirect status and response
# * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
# * <tt>flash</tt> - Set a flash message when redirecting
# * <tt>alert</tt> - Set a alert message when redirecting
# * <tt>alert</tt> - Set an alert message when redirecting
# * <tt>notice</tt> - Set a notice message when redirecting
#
# ==== Action Options

@ -1,8 +1,6 @@
module ActionController
module Head
extend ActiveSupport::Concern
# Return a response that has no content (merely headers). The options
# Returns a response that has no content (merely headers). The options
# argument is interpreted to be a hash of header names and values.
# This allows you to easily return a response that consists only of
# significant headers:

@ -73,7 +73,11 @@ def helper_attr(*attrs)
# Provides a proxy to access helpers methods from outside the view.
def helpers
@helper_proxy ||= ActionView::Base.new.extend(_helpers)
@helper_proxy ||= begin
proxy = ActionView::Base.new
proxy.config = config.inheritable_copy
proxy.extend(_helpers)
end
end
# Overwrite modules_for_helpers to accept :all as argument, which loads

@ -326,6 +326,7 @@ def respond_with(*resources, &block)
if collector = retrieve_collector_from_mimes(&block)
options = resources.size == 1 ? {} : resources.extract_options!
options = options.clone
options[:default_response] = collector.response
(options.delete(:responder) || self.class.responder).call(self, resources, options)
end
@ -364,9 +365,7 @@ def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
format = collector.negotiate_format(request)
if format
self.content_type ||= format.to_s
lookup_context.formats = [format.to_sym]
lookup_context.rendered_format = lookup_context.formats.first
_process_format(format)
collector
else
raise ActionController::UnknownFormat
@ -397,10 +396,10 @@ def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
# request, with this response then being accessible by calling #response.
class Collector
include AbstractController::Collector
attr_accessor :order, :format
attr_accessor :format
def initialize(mimes)
@order, @responses = [], {}
@responses = {}
mimes.each { |mime| send(mime) }
end
@ -415,7 +414,6 @@ def any(*args, &block)
def custom(mime_type, &block)
mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
@order << mime_type
@responses[mime_type] ||= block
end
@ -424,7 +422,7 @@ def response
end
def negotiate_format(request)
@format = request.negotiate_mime(order)
@format = request.negotiate_mime(@responses.keys)
end
end
end

@ -71,6 +71,26 @@ def redirect_to(options = {}, response_status = {}) #:doc:
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.h(location)}\">redirected</a>.</body></html>"
end
def _compute_redirect_to_location(options) #:nodoc:
case options
# The scheme name consist of a letter followed by any combination of
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
# characters; and is terminated by a colon (":").
# See http://tools.ietf.org/html/rfc3986#section-3.1
# The protocol relative scheme starts with a double slash "//".
when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
options
when String
request.protocol + request.host_with_port + options
when :back
request.headers["Referer"] or raise RedirectBackError
when Proc
_compute_redirect_to_location options.call
else
url_for(options)
end.delete("\0\r\n")
end
private
def _extract_redirect_to_status(options, response_status)
if options.is_a?(Hash) && options.key?(:status)
@ -81,24 +101,5 @@ def _extract_redirect_to_status(options, response_status)
302
end
end
def _compute_redirect_to_location(options)
case options
# The scheme name consist of a letter followed by any combination of
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
# characters; and is terminated by a colon (":").
# The protocol relative scheme starts with a double slash "//"
when %r{\A(\w[\w+.-]*:|//).*}
options
when String
request.protocol + request.host_with_port + options
when :back
request.headers["Referer"] or raise RedirectBackError
when Proc
_compute_redirect_to_location options.call
else
url_for(options)
end.delete("\0\r\n")
end
end
end

@ -8,8 +8,7 @@ def self.add_renderer(key, &block)
class MissingRenderer < LoadError
def initialize(format)
@format = format
super("No renderer defined for format: #{@format}")
super "No renderer defined for format: #{format}"
end
end

@ -1,36 +1,4 @@
module ActionController
# Basic rendering implements the most minimal rendering layer.
# It only supports rendering :text and :nothing. Passing any other option will
# result in `UnsupportedOperationError` exception. For more functionality like
# different formats, layouts etc. you should use `ActionView` gem.
module BasicRendering
extend ActiveSupport::Concern
# Render text or nothing (empty string) to response_body
# :api: public
def render(*args, &block)
super(*args, &block)
opts = args.first
if opts.has_key?(:text) && opts[:text].present?
self.response_body = opts[:text]
elsif opts.has_key?(:nothing) && opts[:nothing]
self.response_body = " "
else
raise UnsupportedOperationError
end
end
def rendered_format
Mime::TEXT
end
class UnsupportedOperationError < StandardError
def initialize
super "Unsupported render operation. BasicRendering supports only :text and :nothing options. For more, you need to include ActionView."
end
end
end
module Rendering
extend ActiveSupport::Concern
@ -44,27 +12,31 @@ def process_action(*) #:nodoc:
def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if self.response_body
super
self.content_type ||= rendered_format.to_s
self.response_body
end
# Overwrite render_to_string because body can now be set to a rack body.
def render_to_string(*)
if self.response_body = super
result = super
if result.respond_to?(:each)
string = ""
self.response_body.each { |r| string << r }
result.each { |r| string << r }
string
else
result
end
ensure
self.response_body = nil
end
def render_to_body(*)
super || " "
def render_to_body(options = {})
super || options[:text].presence || ' '
end
private
def _process_format(format)
super
self.content_type ||= format.to_s
end
# Normalize arguments by catching blocks and setting them on :update.
def _normalize_args(action=nil, options={}, &blk) #:nodoc:
options = super

@ -124,6 +124,9 @@ def initialize(env)
@loaded = true
end
# no-op
def destroy; end
def exists?
true
end

@ -144,7 +144,7 @@ def initialize(controller, resources, options={})
undef_method(:to_json) if method_defined?(:to_json)
undef_method(:to_yaml) if method_defined?(:to_yaml)
# Initializes a new responder an invoke the proper format. If the format is
# Initializes a new responder and invokes the proper format. If the format is
# not defined, call to_format.
#
def self.call(*args)

@ -17,7 +17,7 @@ class ParameterMissing < KeyError
def initialize(param) # :nodoc:
@param = param
super("param not found: #{param}")
super("param is missing or the value is empty: #{param}")
end
end
@ -284,7 +284,14 @@ def [](key)
# params.fetch(:none, 'Francesco') # => "Francesco"
# params.fetch(:none) { 'Francesco' } # => "Francesco"
def fetch(key, *args)
convert_hashes_to_parameters(key, super)
value = super
# Don't rely on +convert_hashes_to_parameters+
# so as to not mutate via a +fetch+
if value.is_a?(Hash)
value = self.class.new(value)
value.permit! if permitted?
end
value
rescue KeyError
raise ActionController::ParameterMissing.new(key)
end
@ -334,7 +341,7 @@ def convert_hashes_to_parameters(key, value)
def each_element(object)
if object.is_a?(Array)
object.map { |el| yield el }.compact
elsif object.is_a?(Hash) && object.keys.all? { |k| k =~ /\A-?\d+\z/ }
elsif fields_for_style?(object)
hash = object.class.new
object.each { |k,v| hash[k] = yield v }
hash
@ -343,6 +350,10 @@ def each_element(object)
end
end
def fields_for_style?(object)
object.is_a?(Hash) && object.all? { |k, v| k =~ /\A-?\d+\z/ && v.is_a?(Hash) }
end
def unpermitted_parameters!(params)
unpermitted_keys = unpermitted_keys(params)
if unpermitted_keys.any?
@ -421,7 +432,7 @@ def hash_filter(params, filter)
# Slicing filters out non-declared keys.
slice(*filter.keys).each do |key, value|
return unless value
next unless value
if filter[key] == EMPTY_ARRAY
# Declaration { comment_ids: [] }.

@ -299,17 +299,24 @@ def local?
LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
end
protected
# Extracted into ActionDispatch::Request::Utils.deep_munge, but kept here for backwards compatibility.
def deep_munge(hash)
ActiveSupport::Deprecation.warn(
"This method has been extracted into ActionDispatch::Request::Utils.deep_munge. Please start using that instead."
)
def parse_query(qs)
Utils.deep_munge(super)
Utils.deep_munge(hash)
end
protected
def parse_query(qs)
Utils.deep_munge(super)
end
private
def check_method(name)
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
name
end
def check_method(name)
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
name
end
end
end

@ -41,7 +41,7 @@ class Response
# Get and set headers for this response.
attr_accessor :header
alias_method :headers=, :header=
alias_method :headers, :header
@ -181,9 +181,9 @@ def message
end
alias_method :status_message, :message
def respond_to?(method)
def respond_to?(method, include_private = false)
if method.to_s == 'to_path'
stream.respond_to?(:to_path)
stream.respond_to?(method)
else
super
end

@ -9,8 +9,8 @@ class TransitionTable # :nodoc:
attr_reader :memos
def initialize
@regexp_states = Hash.new { |h,k| h[k] = {} }
@string_states = Hash.new { |h,k| h[k] = {} }
@regexp_states = {}
@string_states = {}
@accepting = {}
@memos = Hash.new { |h,k| h[k] = [] }
end
@ -43,9 +43,7 @@ def move(t, a)
move_string(t, a).concat(move_regexp(t, a))
end
def to_json
require 'json'
def as_json(options = nil)
simple_regexp = Hash.new { |h,k| h[k] = {} }
@regexp_states.each do |from, hash|
@ -54,11 +52,11 @@ def to_json
end
end
JSON.dump({
{
regexp_states: simple_regexp,
string_states: @string_states,
accepting: @accepting
})
}
end
def to_svg
@ -111,14 +109,8 @@ def visualizer(paths, title = 'FSM')
end
def []=(from, to, sym)
case sym
when String
@string_states[from][sym] = to
when Regexp
@regexp_states[from][sym] = to
else
raise ArgumentError, 'unknown symbol: %s' % sym.class
end
to_mappings = states_hash_for(sym)[from] ||= {}
to_mappings[sym] = to
end
def states
@ -137,18 +129,35 @@ def transitions
private
def states_hash_for(sym)
case sym
when String
@string_states
when Regexp
@regexp_states
else
raise ArgumentError, 'unknown symbol: %s' % sym.class
end
end
def move_regexp(t, a)
return [] if t.empty?
t.map { |s|
@regexp_states[s].map { |re, v| re === a ? v : nil }
if states = @regexp_states[s]
states.map { |re, v| re === a ? v : nil }
end
}.flatten.compact.uniq
end
def move_string(t, a)
return [] if t.empty?
t.map { |s| @string_states[s][a] }.compact
t.map do |s|
if states = @string_states[s]
states[a]
end
end.compact
end
end
end

@ -7,15 +7,18 @@ class Utils # :nodoc:
# Normalizes URI path.
#
# Strips off trailing slash and ensures there is a leading slash.
# Also converts downcase url encoded string to uppercase.
#
# normalize_path("/foo") # => "/foo"
# normalize_path("/foo/") # => "/foo"
# normalize_path("foo") # => "/foo"
# normalize_path("") # => "/"
# normalize_path("/%ab") # => "/%AB"
def self.normalize_path(path)
path = "/#{path}"
path.squeeze!('/')
path.sub!(%r{/+\Z}, '')
path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase }
path = '/' if path == ''
path
end
@ -35,7 +38,7 @@ module UriEscape # :nodoc:
UNSAFE_FRAGMENT = Regexp.new("[^#{safe_fragment}]", false).freeze
end
Parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
Parser = URI::Parser.new
def self.escape_path(path)
Parser.escape(path.to_s, UriEscape::UNSAFE_SEGMENT)

@ -1,9 +1,12 @@
# encoding: utf-8
require 'thread_safe'
module ActionDispatch
module Journey # :nodoc:
module Visitors # :nodoc:
class Visitor # :nodoc:
DISPATCH_CACHE = Hash.new { |h,k|
DISPATCH_CACHE = ThreadSafe::Cache.new { |h,k|
h[k] = :"visit_#{k}"
}
@ -84,44 +87,43 @@ def visit_GROUP(node)
# Used for formatting urls (url_for)
class Formatter < Visitor # :nodoc:
attr_reader :options, :consumed
attr_reader :options
def initialize(options)
@options = options
@consumed = {}
end
private
def visit_GROUP(node)
if consumed == options
nil
else
route = visit(node.left)
route.include?("\0") ? nil : route
def visit(node, optional = false)
case node.type
when :LITERAL, :SLASH, :DOT
node.left
when :STAR
visit(node.left)
when :GROUP
visit(node.left, true)
when :CAT
visit_CAT(node, optional)
when :SYMBOL
visit_SYMBOL(node)
end
end
def terminal(node)
node.left
end
def visit_CAT(node, optional)
left = visit(node.left, optional)
right = visit(node.right, optional)
def binary(node)
[visit(node.left), visit(node.right)].join
end
def nary(node)
node.children.map { |c| visit(c) }.join
if optional && !(right && left)
""
else
[left, right].join
end
end
def visit_SYMBOL(node)
key = node.to_sym
if value = options[key]
consumed[key] = value
if value = options[node.to_sym]
Router::Utils.escape_path(value)
else
"\0"
end
end
end

@ -8,14 +8,14 @@ class Callbacks
class << self
delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
end
def self.before(*args, &block)
set_callback(:call, :before, *args, &block)
end
def before(*args, &block)
set_callback(:call, :before, *args, &block)
end
def self.after(*args, &block)
set_callback(:call, :after, *args, &block)
def after(*args, &block)
set_callback(:call, :after, *args, &block)
end
end
def initialize(app)

@ -96,7 +96,7 @@ def backtrace_cleaner
def source_fragment(path, line)
return unless Rails.respond_to?(:root) && Rails.root
full_path = Rails.root.join(path)
if File.exists?(full_path)
if File.exist?(full_path)
File.open(full_path, "r") do |file|
start = [line - 3, 0].max
lines = file.each_line.drop(start).take(6)

@ -143,7 +143,7 @@ def calculate_ip
# proxies with incompatible IP header conventions, and there is no way
# for us to determine which header is the right one after the fact.
# Since we have no idea, we give up and explode.
should_check_ip = @check_ip && client_ips.last
should_check_ip = @check_ip && client_ips.last && forwarded_ips.last
if should_check_ip && !forwarded_ips.include?(client_ips.last)
# We don't know which came from the proxy, and which from the user
raise IpSpoofAttackError, "IP spoofing attack?! " +

@ -29,8 +29,11 @@ def initialize(app, exceptions_app)
def call(env)
@app.call(env)
rescue Exception => exception
raise exception if env['action_dispatch.show_exceptions'] == false
render_exception(env, exception)
if env['action_dispatch.show_exceptions'] == false
raise exception
else
render_exception(env, exception)
end
end
private

@ -127,6 +127,18 @@ def delete(key)
@delegate.delete key.to_s
end
def fetch(key, default=nil)
if self.key?(key)
self[key]
elsif default
self[key] = default
elsif block_given?
self[key] = yield(key)
else
raise KeyError
end
end
def inspect
if loaded?
super

@ -179,7 +179,8 @@ def no_routes
private
def draw_section(routes)
name_width, verb_width, path_width = widths(routes)
header_lengths = ['Prefix', 'Verb', 'URI Pattern'].map(&:length)
name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max)
routes.map do |r|
"#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"

@ -147,14 +147,16 @@ def normalize_defaults!
@defaults.merge!(options[:defaults]) if options[:defaults]
options.each do |key, default|
next if Regexp === default || IGNORE_OPTIONS.include?(key)
@defaults[key] = default
unless Regexp === default || IGNORE_OPTIONS.include?(key)
@defaults[key] = default
end
end
if options[:constraints].is_a?(Hash)
options[:constraints].each do |key, default|
next unless URL_OPTIONS.include?(key) && (String === default || Fixnum === default)
@defaults[key] ||= default
if URL_OPTIONS.include?(key) && (String === default || Fixnum === default)
@defaults[key] ||= default
end
end
end
@ -166,19 +168,21 @@ def normalize_defaults!
end
def normalize_conditions!
@conditions.merge!(:path_info => path)
@conditions[:path_info] = path
constraints.each do |key, condition|
next if segment_keys.include?(key) || key == :controller
@conditions[key] = condition
unless segment_keys.include?(key) || key == :controller
@conditions[key] = condition
end
end
@conditions[:required_defaults] = []
required_defaults = []
options.each do |key, required_default|
next if segment_keys.include?(key) || IGNORE_OPTIONS.include?(key)
next if Regexp === required_default
@conditions[:required_defaults] << key
unless segment_keys.include?(key) || IGNORE_OPTIONS.include?(key) || Regexp === required_default
required_defaults << key
end
end
@conditions[:required_defaults] = required_defaults
via_all = options.delete(:via) if options[:via] == :all
@ -192,8 +196,7 @@ def normalize_conditions!
end
if via = options[:via]
list = Array(via).map { |m| m.to_s.dasherize.upcase }
@conditions.merge!(:request_method => list)
@conditions[:request_method] = Array(via).map { |m| m.to_s.dasherize.upcase }
end
end
@ -226,11 +229,13 @@ def default_controller_and_action
action = action.to_s unless action.is_a?(Regexp)
if controller.blank? && segment_keys.exclude?(:controller)
raise ArgumentError, "missing :controller"
message = "Missing :controller key on routes definition, please check your routes."
raise ArgumentError, message
end
if action.blank? && segment_keys.exclude?(:action)
raise ArgumentError, "missing :action"
message = "Missing :action key on routes definition, please check your routes."
raise ArgumentError, message
end
if controller.is_a?(String) && controller !~ /\A[a-z_0-9\/]*\z/
@ -362,8 +367,9 @@ def root(options = {})
# # Yes, controller actions are just rack endpoints
# match 'photos/:id', to: PhotosController.action(:show)
#
# Because request various HTTP verbs with a single action has security
# implications, is recommendable use HttpHelpers[rdoc-ref:HttpHelpers]
# Because requesting various HTTP verbs with a single action has security
# implications, you must either specify the actions in
# the via options or use one of the HtttpHelpers[rdoc-ref:HttpHelpers]
# instead +match+
#
# === Options
@ -383,7 +389,7 @@ def root(options = {})
# The namespace for :controller.
#
# match 'path', to: 'c#a', module: 'sekret', controller: 'posts'
# #=> Sekret::PostsController
# # => Sekret::PostsController
#
# See <tt>Scoping#namespace</tt> for its scope equivalent.
#
@ -432,10 +438,10 @@ def root(options = {})
#
# match 'json_only', constraints: { format: 'json' }
#
# class Blacklist
# class Whitelist
# def matches?(request) request.remote_ip == '1.2.3.4' end
# end
# match 'path', to: 'c#a', constraints: Blacklist.new
# match 'path', to: 'c#a', constraints: Whitelist.new
#
# See <tt>Scoping#constraints</tt> for more examples with its scope
# equivalent.
@ -1066,18 +1072,18 @@ def resources_path_names(options)
# a singular resource to map /profile (rather than /profile/:id) to
# the show action:
#
# resource :geocoder
# resource :profile
#
# creates six different routes in your application, all mapping to
# the +GeoCoders+ controller (note that the controller is named after
# the +Profiles+ controller (note that the controller is named after
# the plural):
#
# GET /geocoder/new
# POST /geocoder
# GET /geocoder
# GET /geocoder/edit
# PATCH/PUT /geocoder
# DELETE /geocoder
# GET /profile/new
# POST /profile
# GET /profile
# GET /profile/edit
# PATCH/PUT /profile
# DELETE /profile
#
# === Options
# Takes same options as +resources+.

@ -74,6 +74,19 @@ module PolymorphicRoutes
# * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
# Default is <tt>:url</tt>.
#
# Also includes all the options from <tt>url_for</tt>. These include such
# things as <tt>:anchor</tt> or <tt>:trailing_slash</tt>. Example usage
# is given below:
#
# polymorphic_url([blog, post], anchor: 'my_anchor')
# # => "http://example.com/blogs/1/posts/1#my_anchor"
# polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
# # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
#
# For all of these options, see the documentation for <tt>url_for</tt>.
#
# ==== Functionality
#
# # an Article record
# polymorphic_url(record) # same as article_url(record)
#

@ -17,7 +17,7 @@ def initialize(status, block)
def call(env)
req = Request.new(env)
# If any of the path parameters has a invalid encoding then
# If any of the path parameters has an invalid encoding then
# raise since it's likely to trigger errors further on.
req.symbolized_path_parameters.each do |key, value|
unless value.valid_encoding?
@ -30,6 +30,10 @@ def call(env)
uri.host ||= req.host
uri.port ||= req.port unless req.standard_port?
if relative_path?(uri.path)
uri.path = "#{req.script_name}/#{uri.path}"
end
body = %(<html><body>You are being <a href="#{ERB::Util.h(uri.to_s)}">redirected</a>.</body></html>)
headers = {
@ -48,6 +52,11 @@ def path(params, request)
def inspect
"redirect(#{status})"
end
private
def relative_path?(path)
path && !path.empty? && path[0] != '/'
end
end
class PathRedirect < Redirect
@ -81,6 +90,11 @@ def path(params, request)
url_options[:path] = (url_options[:path] % escape_path(params))
end
if relative_path?(url_options[:path])
url_options[:path] = "/#{url_options[:path]}"
url_options[:script_name] = request.script_name
end
ActionDispatch::Http::URL.url_for url_options
end
@ -104,6 +118,10 @@ module Redirection
#
# get 'docs/:article', to: redirect('/wiki/%{article}')
#
# Note that if you return a path without a leading slash then the url is prefixed with the
# current SCRIPT_NAME environment variable. This is typically '/' but may be different in
# a mounted engine or where the application is deployed to a subdirectory of a website.
#
# Alternatively you can use one of the other syntaxes:
#
# The block version of redirect allows for the easy encapsulation of any logic associated with

@ -28,7 +28,7 @@ def initialize(options={})
def call(env)
params = env[PARAMETERS_KEY]
# If any of the path parameters has a invalid encoding then
# If any of the path parameters has an invalid encoding then
# raise since it's likely to trigger errors further on.
params.each do |key, value|
next unless value.respond_to?(:valid_encoding?)
@ -514,11 +514,12 @@ def initialize(options, recall, set)
@recall = recall.dup
@set = set
normalize_recall!
normalize_options!
normalize_controller_action_id!
use_relative_controller!
normalize_controller!
handle_nil_action!
normalize_action!
end
def controller
@ -537,6 +538,11 @@ def use_recall_for(key)
end
end
# Set 'index' as default action for recall
def normalize_recall!
@recall[:action] ||= 'index'
end
def normalize_options!
# If an explicit :controller was given, always make :action explicit
# too, so that action expiry works as expected for things like
@ -552,8 +558,8 @@ def normalize_options!
options[:controller] = options[:controller].to_s
end
if options[:action]
options[:action] = options[:action].to_s
if options.key?(:action)
options[:action] = (options[:action] || 'index').to_s
end
end
@ -563,8 +569,6 @@ def normalize_options!
# :controller, :action or :id is not found, don't pull any
# more keys from the recall.
def normalize_controller_action_id!
@recall[:action] ||= 'index' if current_controller
use_recall_for(:controller) or return
use_recall_for(:action) or return
use_recall_for(:id)
@ -586,13 +590,11 @@ def normalize_controller!
@options[:controller] = controller.sub(%r{^/}, '') if controller
end
# This handles the case of action: nil being explicitly passed.
# It is identical to action: "index"
def handle_nil_action!
if options.has_key?(:action) && options[:action].nil?
options[:action] = 'index'
# Move 'index' action from options to recall
def normalize_action!
if @options[:action] == 'index'
@recall[:action] = @options.delete(:action)
end
recall[:action] = options.delete(:action) if options[:action] == 'index'
end
# Generates a path from routes, returns [path, params].

@ -20,7 +20,7 @@ module Routing
#
# <%= link_to('Click here', controller: 'users',
# action: 'new', message: 'Welcome!') %>
# # => "/users/new?message=Welcome%21"
# # => <a href="/users/new?message=Welcome%21">Click here</a>
#
# link_to, and all other functions that require URL generation functionality,
# actually use ActionController::UrlFor under the hood. And in particular,
@ -155,6 +155,8 @@ def url_for(options = nil)
_routes.url_for(options.symbolize_keys.reverse_merge!(url_options))
when String
options
when Array
polymorphic_url(options, options.extract_options!)
else
polymorphic_url(options)
end

@ -67,21 +67,11 @@ def parameterize(value)
end
def normalize_argument_to_redirection(fragment)
normalized = case fragment
when Regexp
fragment
when %r{^\w[A-Za-z\d+.-]*:.*}
fragment
when String
@request.protocol + @request.host_with_port + fragment
when :back
raise RedirectBackError unless refer = @request.headers["Referer"]
refer
else
@controller.url_for(fragment)
end
normalized.respond_to?(:delete) ? normalized.delete("\0\r\n") : normalized
if Regexp === fragment
fragment
else
@controller._compute_redirect_to_location(fragment)
end
end
end
end

@ -242,7 +242,7 @@ def https!(flag = true)
@https = flag
end
# Return +true+ if the session is mimicking a secure HTTPS request.
# Returns +true+ if the session is mimicking a secure HTTPS request.
#
# if session.https?
# ...

@ -39,6 +39,8 @@ def redirect_to_named_route() redirect_to route_one_url end
def redirect_external() redirect_to "http://www.rubyonrails.org"; end
def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org"; end
def response404() head '404 AWOL' end
def response500() head '500 Sorry' end
@ -258,6 +260,19 @@ def test_assert_redirected_to_top_level_named_route_with_same_controller_name_in
end
end
def test_assert_redirect_failure_message_with_protocol_relative_url
begin
process :redirect_external_protocol_relative
assert_redirected_to "/foo"
rescue ActiveSupport::TestCase::Assertion => ex
assert_no_match(
/#{request.protocol}#{request.host}\/\/www.rubyonrails.org/,
ex.message,
'protocol relative url was incorrectly normalized'
)
end
end
def test_template_objects_exist
process :assign_this
assert !@controller.instance_variable_defined?(:"@hi")
@ -309,6 +324,9 @@ def test_redirection_location
process :redirect_external
assert_equal 'http://www.rubyonrails.org', @response.redirect_url
process :redirect_external_protocol_relative
assert_equal '//www.rubyonrails.org', @response.redirect_url
end
def test_no_redirect_url

@ -20,7 +20,7 @@ def setup
@controller = FragmentCachingMetalTestController.new
@controller.perform_caching = true
@controller.cache_store = @store
@params = { controller: 'posts', action: 'index'}
@params = { controller: 'posts', action: 'index' }
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller.params = @params
@ -40,7 +40,7 @@ class CachingController < ActionController::Base
end
class FragmentCachingTestController < CachingController
def some_action; end;
def some_action; end
end
class FragmentCachingTest < ActionController::TestCase

@ -17,7 +17,7 @@ def before_filters
def assigns(key = nil)
assigns = {}
instance_variables.each do |ivar|
next if ActionController::Base.default_protected_instance_vars.include?(ivar)
next if ActionController::Base.protected_instance_variables.include?(ivar)
assigns[ivar[1..-1]] = instance_variable_get(ivar)
end

@ -214,6 +214,18 @@ def test_redirect_to_with_adding_flash_types
get :redirect_with_foo_flash
assert_equal "for great justice", @controller.send(:flash)[:foo]
end
class SubclassesTestController < TestController; end
def test_add_flash_type_to_subclasses
TestController.add_flash_types :foo
assert SubclassesTestController._flash_types.include?(:foo)
end
def test_do_not_add_flash_type_to_parent_class
SubclassesTestController.add_flash_types :bar
assert_not TestController._flash_types.include?(:bar)
end
end
class FlashIntegrationTest < ActionDispatch::IntegrationTest

@ -201,6 +201,12 @@ def test_helper_proxy
# fun/pdf_helper.rb
assert methods.include?(:foobar)
end
def test_helper_proxy_config
AllHelpersController.config.my_var = 'smth'
assert_equal 'smth', AllHelpersController.helpers.config.my_var
end
private
def expected_helper_methods

@ -21,7 +21,7 @@ def display
def authenticate
authenticate_or_request_with_http_digest("SuperSecret") do |username|
# Return the password
# Returns the password
USERS[username]
end
end

@ -65,7 +65,17 @@ def respond; @controller.render :text => "respond #{format}"; end
respond_with(resource, :responder => responder)
end
def respond_with_additional_params
@params = RespondWithController.params
respond_with({:result => resource}, @params)
end
protected
def self.params
{
:foo => 'bar'
}
end
def resource
Customer.new("david", request.delete? ? nil : 13)
@ -145,6 +155,11 @@ def teardown
Mime::Type.unregister(:mobile)
end
def test_respond_with_shouldnt_modify_original_hash
get :respond_with_additional_params
assert_equal RespondWithController.params, assigns(:params)
end
def test_using_resource
@request.accept = "application/xml"
get :using_resource

@ -92,7 +92,7 @@ class StreamingTest < Rack::TestCase
io.rewind
assert_match "(undefined method `invalid!' for nil:NilClass)", io.read
ensure
ActionController::Base.logger = _old
ActionView::Base.logger = _old
end
end

@ -1,6 +1,15 @@
require 'abstract_unit'
module RenderText
class MinimalController < ActionController::Metal
include AbstractController::Rendering
include ActionController::Rendering
def index
render text: "Hello World!"
end
end
class SimpleController < ActionController::Base
self.view_paths = [ActionView::FixtureResolver.new]
@ -63,6 +72,12 @@ def with_ivar_in_layout
end
class RenderTextTest < Rack::TestCase
test "rendering text from a minimal controller" do
get "/render_text/minimal/index"
assert_body "Hello World!"
assert_status 200
end
test "rendering text from an action with default options renders the text with the layout" do
with_routing do |set|
set.draw { get ':controller', :action => 'index' }

@ -169,4 +169,19 @@ def assert_filtered_out(params, key)
assert_filtered_out permitted[:book][:authors_attributes]['-1'], :age_of_death
end
test "nested number as key" do
params = ActionController::Parameters.new({
product: {
properties: {
'0' => "prop0",
'1' => "prop1"
}
}
})
params = params.require(:product).permit(:properties => ["0"])
assert_not_nil params[:properties]["0"]
assert_nil params[:properties]["1"]
assert_equal "prop0", params[:properties]["0"]
end
end

@ -107,6 +107,15 @@ def assert_filtered_out(params, key)
assert_equal [], permitted[:id]
end
test 'do not break params filtering on nil values' do
params = ActionController::Parameters.new(a: 1, b: [1, 2, 3], c: nil)
permitted = params.permit(:a, c: [], b: [])
assert_equal 1, permitted[:a]
assert_equal [1, 2, 3], permitted[:b]
assert_equal nil, permitted[:c]
end
test 'key to empty array: arrays of permitted scalars pass' do
[['foo'], [1], ['foo', 'bar'], [1, 2, 3]].each do |array|
params = ActionController::Parameters.new(id: array)
@ -138,6 +147,12 @@ def assert_filtered_out(params, key)
assert_equal :foo, e.param
end
test "fetch with a default value of a hash does not mutate the object" do
params = ActionController::Parameters.new({})
params.fetch :foo, {}
assert_equal nil, params[:foo]
end
test "fetch doesnt raise ParameterMissing exception if there is a default" do
assert_equal "monkey", @params.fetch(:foo, "monkey")
assert_equal "monkey", @params.fetch(:foo) { "monkey" }

@ -78,6 +78,11 @@ def encrypted
cookies.encrypted[:foo] = 'bar'
render :nothing => true
end
def try_to_reset_session
reset_session
render :nothing => true
end
end
class FreeCookieController < RequestForgeryProtectionControllerUsingResetSession
@ -320,6 +325,11 @@ def setup
post :encrypted
assert_response :ok
end
test 'should allow reset_session' do
post :try_to_reset_session
assert_response :ok
end
end
class RequestForgeryProtectionControllerUsingExceptionTest < ActionController::TestCase

@ -2,6 +2,7 @@
require 'abstract_unit'
require 'controller/fake_controllers'
require 'active_support/core_ext/object/with_options'
require 'active_support/core_ext/object/json'
class MilestonesController < ActionController::Base
def index() head :ok end
@ -86,36 +87,36 @@ def setup
def test_symbols_with_dashes
rs.draw do
get '/:artist/:song-omg', :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end
hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/faithfully-omg'))
assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
end
def test_id_with_dash
rs.draw do
get '/journey/:id', :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end
hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/faithfully-omg'))
assert_equal({"id"=>"faithfully-omg"}, hash)
end
def test_dash_with_custom_regexp
rs.draw do
get '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end
hash = JSON.load get(URI('http://example.org/journey/123-omg'))
hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/123-omg'))
assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
assert_equal 'Not Found', get(URI('http://example.org/journey/faithfully-omg'))
end
@ -123,24 +124,24 @@ def test_dash_with_custom_regexp
def test_pre_dash
rs.draw do
get '/:artist/omg-:song', :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end
hash = JSON.load get(URI('http://example.org/journey/omg-faithfully'))
hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/omg-faithfully'))
assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
end
def test_pre_dash_with_custom_regexp
rs.draw do
get '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
resp = ActiveSupport::JSON.encode env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end
hash = JSON.load get(URI('http://example.org/journey/omg-123'))
hash = ActiveSupport::JSON.decode get(URI('http://example.org/journey/omg-123'))
assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
assert_equal 'Not Found', get(URI('http://example.org/journey/omg-faithfully'))
end
@ -160,14 +161,14 @@ def test_star_paths_are_greedy
def test_star_paths_are_greedy_but_not_too_much
rs.draw do
get "/*path", :to => lambda { |env|
x = JSON.dump env["action_dispatch.request.path_parameters"]
x = ActiveSupport::JSON.encode env["action_dispatch.request.path_parameters"]
[200, {}, [x]]
}
end
expected = { "path" => "foo/bar", "format" => "html" }
u = URI('http://example.org/foo/bar.html')
assert_equal expected, JSON.parse(get(u))
assert_equal expected, ActiveSupport::JSON.decode(get(u))
end
def test_optional_star_paths_are_greedy
@ -185,7 +186,7 @@ def test_optional_star_paths_are_greedy
def test_optional_star_paths_are_greedy_but_not_too_much
rs.draw do
get "/(*filters)", :to => lambda { |env|
x = JSON.dump env["action_dispatch.request.path_parameters"]
x = ActiveSupport::JSON.encode env["action_dispatch.request.path_parameters"]
[200, {}, [x]]
}
end
@ -193,7 +194,7 @@ def test_optional_star_paths_are_greedy_but_not_too_much
expected = { "filters" => "ne_27.065938,-80.6092/sw_25.489856,-82",
"format" => "542794" }
u = URI('http://example.org/ne_27.065938,-80.6092/sw_25.489856,-82.542794')
assert_equal expected, JSON.parse(get(u))
assert_equal expected, ActiveSupport::JSON.decode(get(u))
end
def test_regexp_precidence
@ -1904,6 +1905,10 @@ def test_unicode_path
assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界'), :method => :get))
end
def test_downcased_unicode_path
assert_equal({:controller => 'news', :action => 'index'}, @routes.recognize_path(URI.parser.escape('こんにちは/世界').downcase, :method => :get))
end
private
def sort_extras!(extras)
if extras.length == 2

@ -1,5 +1,6 @@
require 'abstract_unit'
require 'controller/fake_controllers'
require 'active_support/json/decoding'
class TestCaseTest < ActionController::TestCase
class TestController < ActionController::Base
@ -622,7 +623,7 @@ def test_params_passing_doesnt_modify_in_place
@request.headers['Referer'] = "http://nohost.com/home"
@request.headers['Content-Type'] = "application/rss+xml"
get :test_headers
parsed_env = JSON.parse(@response.body)
parsed_env = ActiveSupport::JSON.decode(@response.body)
assert_equal "http://nohost.com/home", parsed_env["HTTP_REFERER"]
assert_equal "application/rss+xml", parsed_env["CONTENT_TYPE"]
end
@ -631,7 +632,7 @@ def test_params_passing_doesnt_modify_in_place
@request.headers['HTTP_REFERER'] = "http://example.com/about"
@request.headers['CONTENT_TYPE'] = "application/json"
get :test_headers
parsed_env = JSON.parse(@response.body)
parsed_env = ActiveSupport::JSON.decode(@response.body)
assert_equal "http://example.com/about", parsed_env["HTTP_REFERER"]
assert_equal "application/json", parsed_env["CONTENT_TYPE"]
end

@ -370,6 +370,24 @@ def test_false_url_params_are_included_in_query
assert_equal("/c/a?show=false", W.new.url_for(:only_path => true, :controller => 'c', :action => 'a', :show => false))
end
def test_url_generation_with_array_and_hash
with_routing do |set|
set.draw do
namespace :admin do
resources :posts
end
end
kls = Class.new { include set.url_helpers }
kls.default_url_options[:host] = 'www.basecamphq.com'
controller = kls.new
assert_equal("http://www.basecamphq.com/admin/posts/new?param=value",
controller.send(:url_for, [:new, :admin, :post, { param: 'value' }])
)
end
end
private
def extract_params(url)
url.split('?', 2).last.split('&').sort

@ -1,4 +1,5 @@
require 'abstract_unit'
require 'active_support/json/decoding'
class WebServiceTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
@ -54,7 +55,7 @@ def test_put_json
def test_register_and_use_json_simple
with_test_route_set do
with_params_parsers Mime::JSON => Proc.new { |data| JSON.parse(data)['request'].with_indifferent_access } do
with_params_parsers Mime::JSON => Proc.new { |data| ActiveSupport::JSON.decode(data)['request'].with_indifferent_access } do
post "/", '{"request":{"summary":"content...","title":"JSON"}}',
'CONTENT_TYPE' => 'application/json'

@ -31,6 +31,14 @@ def self.routes
get "/polymorphic_path_for_engine", :to => "inside_engine_generating#polymorphic_path_for_engine"
get "/conflicting_url", :to => "inside_engine_generating#conflicting"
get "/foo", :to => "never#invoked", :as => :named_helper_that_should_be_invoked_only_in_respond_to_test
get "/relative_path_redirect", :to => redirect("foo")
get "/relative_option_redirect", :to => redirect(:path => "foo")
get "/relative_custom_redirect", :to => redirect { |params, request| "foo" }
get "/absolute_path_redirect", :to => redirect("/foo")
get "/absolute_option_redirect", :to => redirect(:path => "/foo")
get "/absolute_custom_redirect", :to => redirect { |params, request| "/foo" }
end
routes
@ -182,6 +190,48 @@ def setup
assert_equal "engine", last_response.body
end
test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_path_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/awesome/blog/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/awesome/blog/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_option_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/awesome/blog/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/awesome/blog/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do
get "/awesome/blog/relative_custom_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/awesome/blog/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/awesome/blog/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_path_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_option_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do
get "/awesome/blog/absolute_custom_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
# Inside Application
test "[APP] generating engine's route includes prefix" do
get "/generate"
@ -281,6 +331,14 @@ def self.routes
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
get "/posts/:id", :to => "posts#show", :as => :post
get "/relative_path_redirect", :to => redirect("foo")
get "/relative_option_redirect", :to => redirect(:path => "foo")
get "/relative_custom_redirect", :to => redirect { |params, request| "foo" }
get "/absolute_path_redirect", :to => redirect("/foo")
get "/absolute_option_redirect", :to => redirect(:path => "/foo")
get "/absolute_custom_redirect", :to => redirect { |params, request| "/foo" }
end
routes
@ -331,5 +389,47 @@ def app
get "/posts/1"
assert_equal "/posts/1", last_response.body
end
test "[ENGINE] relative path redirect uses SCRIPT_NAME from request" do
get "/relative_path_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] relative option redirect uses SCRIPT_NAME from request" do
get "/relative_option_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] relative custom redirect uses SCRIPT_NAME from request" do
get "/relative_custom_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] absolute path redirect doesn't use SCRIPT_NAME from request" do
get "/absolute_path_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] absolute option redirect doesn't use SCRIPT_NAME from request" do
get "/absolute_option_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
test "[ENGINE] absolute custom redirect doesn't use SCRIPT_NAME from request" do
get "/absolute_custom_redirect"
assert_equal 301, last_response.status
assert_equal "http://example.org/foo", last_response.headers["Location"]
assert_equal %(<html><body>You are being <a href="http://example.org/foo">redirected</a>.</body></html>), last_response.body
end
end
end

@ -61,6 +61,23 @@ def test_clear
assert_equal([], s.values)
end
def test_fetch
session = Session.create(store, {}, {})
session['one'] = '1'
assert_equal '1', session.fetch(:one)
assert_equal '2', session.fetch(:two, '2')
assert_equal '2', session.fetch(:two)
assert_equal 'three', session.fetch(:three) {|el| el.to_s }
assert_equal 'three', session.fetch(:three)
assert_raise KeyError do
session.fetch(:four)
end
end
private
def store
Class.new {

@ -212,6 +212,11 @@ def test_response_body_encoding
ActionDispatch::Response.default_headers = nil
end
end
test "respond_to? accepts include_private" do
assert_not @response.respond_to?(:method_missing)
assert @response.respond_to?(:method_missing, true)
end
end
class ResponseIntegrationTest < ActionDispatch::IntegrationTest

@ -46,11 +46,11 @@ def self.inspect
assert_equal [
" Prefix Verb URI Pattern Controller#Action",
"custom_assets GET /custom/assets(.:format) custom_assets#show",
" blog /blog Blog::Engine",
"custom_assets GET /custom/assets(.:format) custom_assets#show",
" blog /blog Blog::Engine",
"",
"Routes for Blog::Engine:",
"cart GET /cart(.:format) cart#show"
" cart GET /cart(.:format) cart#show"
], output
end
@ -61,7 +61,7 @@ def test_cart_inspect
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
"cart GET /cart(.:format) cart#show"
" cart GET /cart(.:format) cart#show"
], output
end
@ -72,7 +72,7 @@ def test_inspect_shows_custom_assets
assert_equal [
" Prefix Verb URI Pattern Controller#Action",
"custom_assets GET /custom/assets(.:format) custom_assets#show"
"custom_assets GET /custom/assets(.:format) custom_assets#show"
], output
end
@ -101,7 +101,7 @@ def test_inspect_routes_shows_root_route
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
"root GET / pages#main"
" root GET / pages#main"
], output
end
@ -112,7 +112,7 @@ def test_inspect_routes_shows_dynamic_action_route
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" GET /api/:action(.:format) api#:action"
" GET /api/:action(.:format) api#:action"
], output
end
@ -123,7 +123,7 @@ def test_inspect_routes_shows_controller_and_action_only_route
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" GET /:controller/:action(.:format) :controller#:action"
" GET /:controller/:action(.:format) :controller#:action"
], output
end
@ -134,7 +134,7 @@ def test_inspect_routes_shows_controller_and_action_route_with_constraints
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" GET /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"
" GET /:controller(/:action(/:id))(.:format) :controller#:action {:id=>/\\d+/}"
], output
end
@ -145,7 +145,7 @@ def test_rake_routes_shows_route_with_defaults
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
%Q[ GET /photos/:id(.:format) photos#show {:format=>"jpg"}]
%Q[ GET /photos/:id(.:format) photos#show {:format=>"jpg"}]
], output
end
@ -156,7 +156,7 @@ def test_rake_routes_shows_route_with_constraints
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" GET /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}"
" GET /photos/:id(.:format) photos#show {:id=>/[A-Z]\\d{5}/}"
], output
end
@ -172,7 +172,7 @@ def test_rake_routes_shows_route_with_rack_app
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" GET /foo/:id(.:format) #{RackApp.name} {:id=>/[A-Z]\\d{5}/}"
" GET /foo/:id(.:format) #{RackApp.name} {:id=>/[A-Z]\\d{5}/}"
], output
end
@ -191,7 +191,7 @@ def inspect
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" /foo #{RackApp.name} {:constraint=>( my custom constraint )}"
" /foo #{RackApp.name} {:constraint=>( my custom constraint )}"
], output
end
@ -212,9 +212,9 @@ def test_redirect
assert_equal [
"Prefix Verb URI Pattern Controller#Action",
" foo GET /foo(.:format) redirect(301, /foo/bar) {:subdomain=>\"admin\"}",
" bar GET /bar(.:format) redirect(307, path: /foo/bar)",
"foobar GET /foobar(.:format) redirect(301)"
" foo GET /foo(.:format) redirect(301, /foo/bar) {:subdomain=>\"admin\"}",
" bar GET /bar(.:format) redirect(307, path: /foo/bar)",
"foobar GET /foobar(.:format) redirect(301)"
], output
end
@ -241,7 +241,7 @@ def test_regression_route_with_controller_regexp
end
assert_equal ["Prefix Verb URI Pattern Controller#Action",
" GET /:controller(/:action) (?-mix:api\\/[^\\/]+)#:action"], output
" GET /:controller(/:action) (?-mix:api\\/[^\\/]+)#:action"], output
end
end
end

@ -1102,6 +1102,19 @@ def test_scoped_root
assert_equal 'projects#index', @response.body
end
def test_scoped_root_as_name
draw do
scope '(:locale)', :locale => /en|pl/ do
root :to => 'projects#index', :as => 'projects'
end
end
assert_equal '/en', projects_path(:locale => 'en')
assert_equal '/', projects_path
get '/en'
assert_equal 'projects#index', @response.body
end
def test_scope_with_format_option
draw do
get "direct/index", as: :no_format_direct, format: false

@ -37,6 +37,10 @@ def test_serves_static_index_file_in_directory
end
def test_served_static_file_with_non_english_filename
if RUBY_ENGINE == 'jruby '
skip "Stop skipping if following bug gets fixed: " \
"http://jira.codehaus.org/browse/JRUBY-7192"
end
assert_html "means hello in Japanese\n", get("/foo/#{Rack::Utils.escape("こんにちは.html")}")
end

@ -1,5 +1,3 @@
module AbcHelper
def bare_a() end
def bare_b() end
def bare_c() end
end

@ -1,5 +0,0 @@
module HelperyTestHelper
def helpery_test
"Default"
end
end

@ -1,5 +1,5 @@
require 'abstract_unit'
require 'json'
require 'active_support/json/decoding'
module ActionDispatch
module Journey
@ -13,7 +13,7 @@ def test_to_json
/articles/:id(.:format)
}
json = JSON.load table.to_json
json = ActiveSupport::JSON.decode table.to_json
assert json['regexp_states']
assert json['string_states']
assert json['accepting']

@ -15,6 +15,14 @@ def test_fragment_escape
def test_uri_unescape
assert_equal "a/b c+d", Utils.unescape_uri("a%2Fb%20c+d")
end
def test_normalize_path_not_greedy
assert_equal "/foo%20bar%20baz", Utils.normalize_path("/foo%20bar%20baz")
end
def test_normalize_path_uppercase
assert_equal "/foo%AAbar%AAbaz", Utils.normalize_path("/foo%aabar%aabaz")
end
end
end
end

@ -96,88 +96,6 @@ def relevances_attributes=(attributes); end
attr_accessor :body
end
class Tag
extend ActiveModel::Naming
include ActiveModel::Conversion
attr_reader :id
attr_reader :post_id
def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
def to_key; id ? [id] : nil end
def save; @id = 1; @post_id = 1 end
def persisted?; @id.present? end
def to_param; @id; end
def value
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
attr_accessor :relevances
def relevances_attributes=(attributes); end
end
class CommentRelevance
extend ActiveModel::Naming
include ActiveModel::Conversion
attr_reader :id
attr_reader :comment_id
def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
def to_key; id ? [id] : nil end
def save; @id = 1; @comment_id = 1 end
def persisted?; @id.present? end
def to_param; @id; end
def value
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
end
class Sheep
extend ActiveModel::Naming
include ActiveModel::Conversion
attr_reader :id
def to_key; id ? [id] : nil end
def save; @id = 1 end
def new_record?; @id.nil? end
def name
@id.nil? ? 'new sheep' : "sheep ##{@id}"
end
end
class TagRelevance
extend ActiveModel::Naming
include ActiveModel::Conversion
attr_reader :id
attr_reader :tag_id
def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
def to_key; id ? [id] : nil end
def save; @id = 1; @tag_id = 1 end
def persisted?; @id.present? end
def to_param; @id; end
def value
@id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
end
end
class Author < Comment
attr_accessor :post
def post_attributes=(attributes); end
end
class HashBackedAuthor < Hash
extend ActiveModel::Naming
include ActiveModel::Conversion
def persisted?; false; end
def name
"hash backed author"
end
end
module Blog
def self.use_relative_model_naming?
true
@ -193,21 +111,8 @@ def persisted?
end
end
class ArelLike
def to_ary
true
end
def each
a = Array.new(2) { |id| Comment.new(id + 1) }
a.each { |i| yield i }
end
end
class RenderJsonTestException < Exception
def to_json(options = nil)
return { :error => self.class.name, :message => self.to_s }.to_json
def as_json(options = nil)
{ :error => self.class.name, :message => self.to_s }
end
end
class Car < Struct.new(:color)
end

@ -1,7 +1,60 @@
* Only cache template digests if `config.cache_template_loading` id true.
* Use `set_backtrace` instead of instance variable `@backtrace` in ActionView exceptions
*Shimpei Makimoto*
* Fix `simple_format` escapes own output when passing `sanitize: true`
*Paul Seidemann*
* Ensure `ActionView::Digestor.cache` is correctly cleaned up when
combining recursive templates with `ActionView::Resolver.caching = false`.
*wyaeld*
* Fix `collection_check_boxes` generated hidden input to use the name attribute provided
in the options hash.
*Angel N. Sciortino*
* Fix some edge cases for AV `select` helper with `:selected` option.
*Bogdan Gusiev*
* Ability to pass block to `select` helper
<%= select(report, "campaign_ids") do %>
<% available_campaigns.each do |c| -%>
<%= content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json }) %>
<% end -%>
<% end -%>
*Bogdan Gusiev*
* Handle `:namespace` form option in collection labels.
*Vasiliy Ermolovich*
* Fix `form_for` when both `namespace` and `as` options are present.
`as` option no longer overwrites `namespace` option when generating
html id attribute of the form element.
*Adam Niedzielski*
* Fix `excerpt` when `:separator` is `nil`.
*Paul Nikitochkin*
* Only cache template digests if `config.cache_template_loading` is true.
*Josh Lauer*, *Justin Ridgewell*
* Fixed a bug where the lookup details were not being taken into account
when caching the digest of a template - changes to the details now
cause a different cache key to be used.
*Daniel Schierbeck*
* Added an `extname` hash option for `javascript_include_tag` method.
Before:

@ -18,7 +18,7 @@ which can be further narrowed down to one test:
== Dependency on Active Record and database setup
Test cases in the test/active_record/ directory depend on having
Test cases in the test/activerecord/ directory depend on having
activerecord and sqlite installed. If Active Record is not in
actionview/../activerecord directory, or the sqlite rubygem is not installed,
these tests are skipped.

@ -11,7 +11,7 @@ task :test => ["test:template", "test:integration:action_pack", "test:integratio
namespace :test do
task :isolated do
Dir.glob("test/{active_record,template}/**/*_test.rb").all? do |file|
Dir.glob("test/{actionpack,activerecord,template}/**/*_test.rb").all? do |file|
sh(Gem.ruby, '-w', '-Ilib:test', file)
end or raise "Failures"
end

@ -5,7 +5,7 @@
s.name = 'actionview'
s.version = version
s.summary = 'Rendering framework putting the V in MVC (part of Rails).'
s.description = ''
s.description = 'Simple, battle-tested conventions and helpers for building web pages.'
s.required_ruby_version = '>= 1.9.3'

@ -10,7 +10,10 @@ class Digestor
class << self
def digest(name, format, finder, options = {})
cache_key = ([name, format] + Array.wrap(options[:dependencies])).join('.')
details_key = finder.details_key.hash
dependencies = Array.wrap(options[:dependencies])
cache_key = ([name, details_key, format] + dependencies).join('.')
# this is a correctly done double-checked locking idiom
# (ThreadSafe::Cache's lookups have volatile semantics)
@@cache[cache_key] || @@digest_monitor.synchronize do
@ -32,13 +35,13 @@ def compute_and_store_digest(cache_key, name, format, finder, options) # called
Digestor
end
digest = klass.new(name, format, finder, options).digest
# Store the actual digest if config.cache_template_loading is true
klass.new(name, format, finder, options).digest.tap do |digest|
@@cache[cache_key] = digest if ActionView::Resolver.caching?
end
rescue Exception
@@cache.delete_pair(cache_key, false) if pre_stored # something went wrong, make sure not to corrupt the @@cache
raise
@@cache[cache_key] = stored_digest = digest if ActionView::Resolver.caching?
digest
ensure
# something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
@@cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
end
end

@ -153,14 +153,14 @@ def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
#
# ==== Examples
#
# favicon_link_tag '/myicon.ico'
# favicon_link_tag 'myicon.ico'
# # => <link href="/assets/myicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
#
# Mobile Safari looks for a different <link> tag, pointing to an image that
# will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad.
# The following call would generate such a tag:
#
# favicon_link_tag '/mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
# favicon_link_tag 'mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
# # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
def favicon_link_tag(source='favicon.ico', options={})
tag('link', {
@ -224,14 +224,14 @@ def image_tag(source, options={})
#
# ==== Examples
#
# image_tag('rails.png')
# # => <img alt="Rails" src="/assets/rails.png" />
# image_alt('rails.png')
# # => Rails
#
# image_tag('hyphenated-file-name.png')
# # => <img alt="Hyphenated file name" src="/assets/hyphenated-file-name.png" />
# image_alt('hyphenated-file-name.png')
# # => Hyphenated file name
#
# image_tag('underscored_file_name.png')
# # => <img alt="Underscored file name" src="/assets/underscored_file_name.png" />
# image_alt('underscored_file_name.png')
# # => Underscored file name
def image_alt(src)
File.basename(src, '.*').sub(/-[[:xdigit:]]{32}\z/, '').tr('-_', ' ').capitalize
end

@ -143,9 +143,9 @@ def asset_path(source, options = {})
"#{source}#{tail}"
end
alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with a asset_path named route
alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with an asset_path named route
# Computes the full URL to a asset in the public directory. This
# Computes the full URL to an asset in the public directory. This
# will use +asset_path+ internally, so most of their behaviors
# will be the same.
def asset_url(source, options = {})

Some files were not shown because too many files have changed in this diff Show More