resque 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6029ead32e829bcc359edabd6540a827fc8dff70768f26dbc6756041c98a6691
4
- data.tar.gz: c6a568f692f54fd91cd8371b029babaf70c096ccb8b020cd3a76eb16f6e0ab56
3
+ metadata.gz: 357503e977394f513419b3146484eab796354a978d6d96e74e16fae0dc2fd3de
4
+ data.tar.gz: 4e3da6258793f0b094cba61c35436d30f1193d8d43553e312b8e5c14cbb7ee5b
5
5
  SHA512:
6
- metadata.gz: bc4575c01a0ad8e803a7a21b707bdcfca8d7a4cbab3d19f80476fce6b28e900857c3a19271358805b16f99bf59e666ff3e7bfb61911ec4271014d4c41aa53322
7
- data.tar.gz: 2af75588506a9e8d54dbe74d6a9f3c5ef96d1daccf3d76b4e2d820bbad388730fe69f829bc3077f06d609c50f131edf9c0b102271ebd70ec8e2143df9e0c4a12
6
+ metadata.gz: 00e3f45822df5638bb129c32c10878e2651cb74081711d4d4ef30da47403195c07276a4dbcb60e650c35dbc40ba0bcfb48d4a2c625eb442dec476e8a18929a7a
7
+ data.tar.gz: 942ff614b651c87ab52726aa88564243fd60b3c87edff7670fcb61491f2a45516a8c91eed44119d5945a322f0598f9be28d3ab5d610146e9d488e261514bf0af
data/HISTORY.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## 3.0.2
2
+
3
+ ### Added
4
+
5
+ * resque-web: Support IPv6 hosts in the server URL (#1938)
6
+
7
+ ### Fixed
8
+
9
+ * resque-web: Escape queue names, worker IDs, job classes, failed job details, Redis keys/values, and the reflected request path; serve `/stats.txt` as `text/plain` (#1946)
10
+ * resque-web: Fix the class filter link URL on the failed jobs page (#1934)
11
+ * Prefer `MultiJson.generate`/`parse` over the deprecated `dump`/`load` (#1944)
12
+ * Add tests covering which hooks run in which process (#1932)
13
+
14
+ ## 3.0.1
15
+
16
+ ### Fixed
17
+
18
+ * resque-web: Fix reflected XSS in the key sets endpoint (#1942)
19
+ * Address multi_json class name deprecation warning (#1940)
20
+ * Update the Rails initializer docs to load Redis config with `config_for` (#1936)
21
+ * Add tests covering queue priority ordering with wildcards (#1930)
22
+
1
23
  ## 3.0.0
2
24
 
3
25
  ### Breaking Changes
@@ -5,6 +27,7 @@
5
27
  * **Minimum Ruby version is now 3.0.0** - Ruby 2.x is no longer supported
6
28
  * **Minimum Sinatra version is now 2.0** - old Sinatra versions (0.9-1.x) are no longer supported
7
29
  * **Rack 1.x is no longer supported** - Resque now requires Rack 2.x or greater
30
+ * **Minimum Rails version is now 7.2** - You can use Resque without Rails, but if you use it with Rails it must be a version that is still supported
8
31
 
9
32
  ### Added
10
33
 
data/README.markdown CHANGED
@@ -495,12 +495,14 @@ Here's our `config/resque.yml`:
495
495
  And our initializer:
496
496
 
497
497
  ``` ruby
498
- rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
499
- rails_env = ENV['RAILS_ENV'] || 'development'
500
- config_file = rails_root + '/config/resque.yml'
498
+ config_file = 'config/resque.yml'
499
+ rails_env = ENV['RAILS_ENV'] || Rails.env
501
500
 
502
- resque_config = YAML::load(ERB.new(IO.read(config_file)).result)
501
+ resque_config = YAML::load_file(config_file)
503
502
  Resque.redis = resque_config[rails_env]
503
+
504
+ # OR auto load with current env
505
+ Resque.redis = Rails.application.config_for(:resque)
504
506
  ```
505
507
 
506
508
  Easy peasy! Why not just use `RAILS_ROOT` and `RAILS_ENV`? Because
@@ -632,7 +634,7 @@ Choose DelayedJob if:
632
634
  * You like numeric priorities
633
635
  * You're not doing a gigantic amount of jobs each day
634
636
  * Your queue stays small and nimble
635
- * There is not a lot failure / chaos
637
+ * There is not a lot of failure / chaos
636
638
  * You want to easily throw anything on the queue
637
639
  * You don't want to setup Redis
638
640
 
@@ -1,14 +1,19 @@
1
1
  require 'multi_json'
2
2
 
3
- # OkJson won't work because it doesn't serialize symbols
4
- # in the same way yajl and json do.
5
- if MultiJson.respond_to?(:adapter)
6
- raise "Please install the yajl-ruby or json gem" if MultiJson.adapter.to_s == 'MultiJson::Adapters::OkJson'
7
- elsif MultiJson.respond_to?(:engine)
8
- raise "Please install the yajl-ruby or json gem" if MultiJson.engine.to_s == 'MultiJson::Engines::OkJson'
9
- end
10
-
11
3
  module Resque
4
+ # multi_json renamed it's top-level constant from MultiJson to MultiJSON,
5
+ # keeping MultiJson as a deprecated alias until v2.0. Reference whichever name the
6
+ # installed version exposes so we stay compatible with future versions of multi_json
7
+ MultiJson = defined?(::MultiJSON) ? ::MultiJSON : ::MultiJson
8
+
9
+ # OkJson won't work because it doesn't serialize symbols
10
+ # in the same way yajl and json do.
11
+ if MultiJson.respond_to?(:adapter)
12
+ raise "Please install the yajl-ruby or json gem" if MultiJson.adapter.to_s.end_with?('::OkJson')
13
+ elsif MultiJson.respond_to?(:engine)
14
+ raise "Please install the yajl-ruby or json gem" if MultiJson.engine.to_s.end_with?('::OkJson')
15
+ end
16
+
12
17
  # Methods used by various classes in Resque.
13
18
  module Helpers
14
19
  class DecodeException < StandardError; end
@@ -5,7 +5,7 @@
5
5
  <% end %>
6
6
 
7
7
  <% unless failed_size.zero? %>
8
- <form method="POST" action="<%= u "failed#{'/' + params[:queue] if params[:queue]}/clear" %>">
8
+ <form method="POST" action="<%= h u("failed#{'/' + params[:queue] if params[:queue]}/clear") %>">
9
9
  <input type="submit" name="" value="Clear <%= params[:queue] ? "'#{escape_html(params[:queue])}'" : 'Failed' %> Jobs" class="confirmSubmission" />
10
10
  </form>
11
11
 
@@ -14,7 +14,7 @@
14
14
  <input type="submit" name="" value="Clear Retried Jobs" onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
15
15
  </form>
16
16
  <% end %>
17
- <form method="POST" action="<%= u "failed#{'/' + params[:queue] if params[:queue]}/requeue/all" %>">
17
+ <form method="POST" action="<%= h u("failed#{'/' + params[:queue] if params[:queue]}/requeue/all") %>">
18
18
  <input type="submit" name="" value="Retry <%= params[:queue] ? "'#{escape_html(params[:queue])}'" : 'Failed' %> Jobs" class="confirmSubmission" />
19
19
  </form>
20
20
  <% end %>
@@ -2,28 +2,28 @@
2
2
  <dl>
3
3
  <% if job.nil? %>
4
4
  <dt>Error</dt>
5
- <dd>Job <%= id %> could not be parsed; perhaps it contains invalid JSON?</dd>
5
+ <dd>Job <%= h id %> could not be parsed; perhaps it contains invalid JSON?</dd>
6
6
  <% else %>
7
7
  <dt>Worker</dt>
8
8
  <dd>
9
- <a href="<%= u(:workers, job['worker']) %>"><%= job['worker'].split(':')[0...2].join(':') %></a> on <b class='queue-tag'><%= job['queue'] %></b > at <b><span class="time"><%= DateTime.parse(job['failed_at']).strftime(failed_date_format) %></span></b>
9
+ <a href="<%= h u(:workers, job['worker']) %>"><%= h job['worker'].split(':')[0...2].join(':') %></a> on <b class='queue-tag'><%= h job['queue'] %></b > at <b><span class="time"><%= DateTime.parse(job['failed_at']).strftime(failed_date_format) %></span></b>
10
10
  <% if job['retried_at'] %>
11
11
  <div class='retried'>
12
12
  Retried <b><span class="time"><%= DateTime.parse(job['retried_at']).strftime(failed_date_format) %></span></b>
13
- <a href="<%= u "#{queue}/remove/#{id}" %>" class="remove" rel="remove">Remove</a>
13
+ <a href="<%= h u("#{queue}/remove/#{id}") %>" class="remove" rel="remove">Remove</a>
14
14
  </div>
15
15
  <% else %>
16
16
  <div class='controls'>
17
- <a href="<%= u "#{queue}/requeue/#{id}" %>" rel="retry">Retry</a>
17
+ <a href="<%= h u("#{queue}/requeue/#{id}") %>" rel="retry">Retry</a>
18
18
  or
19
- <a href="<%= u "#{queue}/remove/#{id}" %>" rel="remove">Remove</a>
19
+ <a href="<%= h u("#{queue}/remove/#{id}") %>" rel="remove">Remove</a>
20
20
  </div>
21
21
  <% end %>
22
22
  </dd>
23
23
  <dt>Class</dt>
24
24
  <dd>
25
25
  <% if job['payload'] && job['payload']['class'] %>
26
- <a href="<%= u "failed/#{params[:queue]}?class=#{job['payload']['class']}" %>">
26
+ <a href="<%= h u("#{queue}?class=#{job['payload']['class']}") %>">
27
27
  <%= partial :job_class, :job => job['payload'] %>
28
28
  </a>
29
29
  <% else %>
@@ -33,7 +33,7 @@
33
33
  <dt>Arguments</dt>
34
34
  <dd><pre><%=h job['payload'] ? show_args(job['payload']['args']) : 'nil' %></pre></dd>
35
35
  <dt>Exception</dt>
36
- <dd><code><%= job['exception'] %></code></dd>
36
+ <dd><code><%= h job['exception'] %></code></dd>
37
37
  <dt>Error</dt>
38
38
  <dd class='error'>
39
39
  <% if job['backtrace'] %>
@@ -7,14 +7,14 @@
7
7
 
8
8
  <% Resque::Failure.queues.sort.each do |queue| %>
9
9
  <tr>
10
- <th><b class="queue-tag"><a href="<%= u "/failed/#{queue}" %>"><%= queue %></a></b></th>
10
+ <th><b class="queue-tag"><a href="<%= h u("/failed/#{queue}") %>"><%= h queue %></a></b></th>
11
11
  <th style="width:75px;" class="center"><%= Resque::Failure.count(queue) %></th>
12
12
  </tr>
13
13
 
14
14
  <% failed_class_counts(queue).sort_by { |name,_| name }.each do |k, v| %>
15
- <tr id="<%= k %>">
15
+ <tr id="<%= h k %>">
16
16
  <td>
17
- <a href="<%= u "/failed/#{queue}?class=#{k}" %>"><span class="failed failed_class"><%= k %></span></a>
17
+ <a href="<%= h u("/failed/#{queue}?class=#{k}") %>"><span class="failed failed_class"><%= h k %></span></a>
18
18
  </td>
19
19
  <td style="text-align: center;" class="failed<%= (v.to_i > 1000) ? '_many' : '' %>"><%= v %></td>
20
20
  </tr>
@@ -1,8 +1,8 @@
1
1
  <% if job['class'] == 'ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper' %>
2
- <code><%= job['args'].first['job_class'] %></code>
2
+ <code><%= h job['args'].first['job_class'] %></code>
3
3
  <small>
4
4
  <a href="http://edgeguides.rubyonrails.org/active_job_basics.html" rel="noopener noreferrer" target="_blank">(via ActiveJob)</a>
5
5
  </small>
6
6
  <% else %>
7
- <code><%= job['class'] %></code>
7
+ <code><%= h job['class'] %></code>
8
8
  <% end %>
@@ -2,12 +2,12 @@
2
2
 
3
3
  <p class='sub'><%= page_entries_info start = params[:start].to_i, start + 20, size = redis_get_size(key) %></p>
4
4
 
5
- <h1>Key "<%= key %>" is a <%= resque.redis.type key %></h1>
5
+ <h1>Key "<%= escape_html(key) %>" is a <%= resque.redis.type key %></h1>
6
6
  <table>
7
7
  <% for row in redis_get_value_as_array(key, start) %>
8
8
  <tr>
9
9
  <td>
10
- <%= row %>
10
+ <%= h row %>
11
11
  </td>
12
12
  </tr>
13
13
  <% end %>
@@ -4,7 +4,7 @@
4
4
  <table>
5
5
  <tr>
6
6
  <td>
7
- <%= redis_get_value_as_array(key) %>
7
+ <%= h redis_get_value_as_array(key) %>
8
8
  </td>
9
9
  </tr>
10
10
  </table>
@@ -19,7 +19,7 @@
19
19
  </ul>
20
20
  <% if Resque.redis.namespace != :resque %>
21
21
  <abbr class="namespace" title="Resque's Redis Namespace">
22
- <%= Resque.redis.namespace %>
22
+ <%= h Resque.redis.namespace %>
23
23
  </abbr>
24
24
  <% end %>
25
25
  </div>
@@ -27,7 +27,7 @@
27
27
  <% if defined?(@subtabs) && @subtabs %>
28
28
  <ul class='subnav'>
29
29
  <% for subtab in @subtabs %>
30
- <li <%= class_if_current "#{current_section}/#{subtab}" %>><a href="<%= current_section %>/<%= subtab %>"><span><%= subtab %></span></a></li>
30
+ <li <%= class_if_current "#{current_section}/#{subtab}" %>><a href="<%= h current_section %>/<%= h subtab %>"><span><%= h subtab %></span></a></li>
31
31
  <% end %>
32
32
  </ul>
33
33
  <% end %>
@@ -38,7 +38,7 @@
38
38
 
39
39
  <div id="footer">
40
40
  <p>Powered by <a href="http://github.com/resque/resque">Resque</a> v<%=Resque::VERSION%></p>
41
- <p>Connected to Redis namespace <%= Resque.redis.namespace %> on <%= h Resque.redis_id %></p>
41
+ <p>Connected to Redis namespace <%= h Resque.redis.namespace %> on <%= h Resque.redis_id %></p>
42
42
  </div>
43
43
 
44
44
  </body>
@@ -4,19 +4,19 @@
4
4
  <%if start - per_page >= 0 || start + per_page <= size%>
5
5
  <div class='pagination'>
6
6
  <% if start - per_page >= 0 %>
7
- <a href="<%= current_page %>?start=<%= start - per_page %>" class='less'>&laquo; Previous</a>
7
+ <a href="<%= h current_page %>?start=<%= start - per_page %>" class='less'>&laquo; Previous</a>
8
8
  <% end %>
9
9
 
10
10
  <% (size / per_page.to_f).ceil.times do |page_num| %>
11
11
  <% if start == page_num * per_page %>
12
12
  <span><%= page_num + 1 %></span>
13
13
  <% else %>
14
- <a href="<%= current_page %>?start=<%= page_num * per_page %>"> <%= page_num + 1 %></a>
14
+ <a href="<%= h current_page %>?start=<%= page_num * per_page %>"> <%= page_num + 1 %></a>
15
15
  <% end %>
16
16
  <% end %>
17
17
 
18
18
  <% if start + per_page < size %>
19
- <a href="<%= current_page %>?start=<%= start + per_page %>" class='more'>Next &raquo;</a>
19
+ <a href="<%= h current_page %>?start=<%= start + per_page %>" class='more'>Next &raquo;</a>
20
20
  <% end %>
21
21
  </div>
22
22
  <%end%>
@@ -1,2 +1,2 @@
1
1
  <%= partial :job_class, :job => job['payload'] %>
2
- <small><a class="queue time" href="<%=u "/working/#{worker}" %>"><%= job['run_at'] %></a></small>
2
+ <small><a class="queue time" href="<%= h u("/working/#{worker}") %>"><%= h job['run_at'] %></a></small>
@@ -2,8 +2,8 @@
2
2
 
3
3
  <% if current_queue = params[:id] %>
4
4
 
5
- <h1>Pending jobs on <span class='hl'><%= h escape_html(current_queue) %></span></h1>
6
- <form method="POST" action="<%=u "/queues/#{escape_html(current_queue)}/remove" %>" class='remove-queue'>
5
+ <h1>Pending jobs on <span class='hl'><%= h current_queue %></span></h1>
6
+ <form method="POST" action="<%= h u("/queues/#{current_queue}/remove") %>" class='remove-queue'>
7
7
  <input type='submit' name='' value='Remove Queue' class="confirmSubmission" />
8
8
  </form>
9
9
  <p class='sub'><%= page_entries_info start = params[:start].to_i, start + 19, size = resque.size(current_queue), 'job' %></p>
@@ -36,14 +36,14 @@
36
36
  </tr>
37
37
  <% resque.queues.sort_by { |q| q.to_s }.each do |queue| %>
38
38
  <tr>
39
- <td class='queue'><a class="queue" href="<%= u "queues/#{queue}" %>"><%= queue %></a></td>
39
+ <td class='queue'><a class="queue" href="<%= h u("queues/#{queue}") %>"><%= h queue %></a></td>
40
40
  <td class='size'><%= resque.size queue %></td>
41
41
  </tr>
42
42
  <% end %>
43
43
  <% if failed_multiple_queues? %>
44
44
  <% Resque::Failure.queues.sort_by { |q| q.to_s }.each_with_index do |queue, i| %>
45
45
  <tr class="<%= Resque::Failure.count(queue).zero? ? "failed" : "failure" %><%= " first_failure" if i.zero? %>">
46
- <td class='queue failed'><a class="queue" href="<%= u "failed/#{queue}" %>"><%= queue %></a></td>
46
+ <td class='queue failed'><a class="queue" href="<%= h u("failed/#{queue}") %>"><%= h queue %></a></td>
47
47
  <td class='size'><%= Resque::Failure.count(queue) %></td>
48
48
  </tr>
49
49
  <% end %>
@@ -11,7 +11,7 @@
11
11
  <% for key, value in resque.info.to_a.sort_by { |i| i[0].to_s } %>
12
12
  <tr>
13
13
  <th>
14
- <%= key %>
14
+ <%= h key %>
15
15
  </th>
16
16
  <td>
17
17
  <%= h value %>
@@ -27,10 +27,10 @@
27
27
  <% for key, value in resque.redis.redis.info.to_a.sort_by { |i| i[0].to_s } %>
28
28
  <tr>
29
29
  <th>
30
- <%= key %>
30
+ <%= h key %>
31
31
  </th>
32
32
  <td>
33
- <%= value %>
33
+ <%= h value %>
34
34
  </td>
35
35
  </tr>
36
36
  <% end %>
@@ -39,7 +39,7 @@
39
39
  <% elsif params[:id] == 'keys' %>
40
40
 
41
41
  <h1>Keys owned by <%= h resque.redis_id %></h1>
42
- <p class='sub'>(All keys are actually prefixed with "<%= Resque.redis.namespace %>:")</p>
42
+ <p class='sub'>(All keys are actually prefixed with "<%= h Resque.redis.namespace %>:")</p>
43
43
  <table class='stats'>
44
44
  <tr>
45
45
  <th>key</th>
@@ -49,7 +49,7 @@
49
49
  <% for key in resque.keys.sort %>
50
50
  <tr>
51
51
  <th>
52
- <a href="<%=u "/stats/keys/#{key}" %>"><%= key %></a>
52
+ <a href="<%= h u("/stats/keys/#{key}") %>"><%= h key %></a>
53
53
  </th>
54
54
  <td><%= resque.redis.type key %></td>
55
55
  <td><%= redis_get_size key %></td>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <% if params[:id] && worker = Resque::Worker.find(params[:id]) %>
4
4
 
5
- <h1>Worker <%= worker %></h1>
5
+ <h1>Worker <%= h worker %></h1>
6
6
  <table class='workers'>
7
7
  <tr>
8
8
  <th>&nbsp;</th>
@@ -16,14 +16,14 @@
16
16
  <th>Processing</th>
17
17
  </tr>
18
18
  <tr>
19
- <td class='icon'><img src="<%=u state = worker.state %>.png" alt="<%= state %>" title="<%= state %>"></td>
19
+ <td class='icon'><img src="<%= h u(state = worker.state) %>.png" alt="<%= h state %>" title="<%= h state %>"></td>
20
20
 
21
21
  <% host, pid, queues = worker.to_s.split(':') %>
22
- <td><%= host %></td>
23
- <td><%= pid %></td>
24
- <td><span class="time"><%= worker.started %></span></td>
25
- <td><span class="time"><%= worker.heartbeat %></span></td>
26
- <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
22
+ <td><%= h host %></td>
23
+ <td><%= h pid %></td>
24
+ <td><span class="time"><%= h worker.started %></span></td>
25
+ <td><span class="time"><%= h worker.heartbeat %></span></td>
26
+ <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + h(u("/queues/#{q}")) + '">' + h(q) + '</a>'}.join('') %></td>
27
27
  <td><%= worker.processed %></td>
28
28
  <td><%= worker.failed %></td>
29
29
  <td class='process'>
@@ -60,11 +60,11 @@
60
60
  </tr>
61
61
  <% for worker in (workers = workers.sort_by { |w| w.to_s }) %>
62
62
  <tr class="<%=state = worker.state%>">
63
- <td class='icon'><img src="<%=u state %>.png" alt="<%= state %>" title="<%= state %>"></td>
63
+ <td class='icon'><img src="<%= h u(state) %>.png" alt="<%= h state %>" title="<%= h state %>"></td>
64
64
 
65
65
  <% host, pid, queues = worker.to_s.split(':') %>
66
- <td class='where'><a href="<%=u "workers/#{worker}"%>"><%= host %>:<%= pid %></a></td>
67
- <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
66
+ <td class='where'><a href="<%= h u("workers/#{worker}") %>"><%= h host %>:<%= h pid %></a></td>
67
+ <td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + h(u("/queues/#{q}")) + '">' + h(q) + '</a>'}.join('') %></td>
68
68
 
69
69
  <td class='process'>
70
70
  <% data = worker.processing || {} %>
@@ -95,7 +95,7 @@
95
95
  </tr>
96
96
  <% for hostname, workers in worker_hosts.sort_by { |h,w| h } %>
97
97
  <tr>
98
- <td class='queue'><a class="queue" href="<%= u "workers/#{hostname}" %>"><%= hostname %></a></td>
98
+ <td class='queue'><a class="queue" href="<%= h u("workers/#{hostname}") %>"><%= h hostname %></a></td>
99
99
  <td class='size'><%= workers.size %></td>
100
100
  </tr>
101
101
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <% if params[:id] && (current_worker = Resque::Worker.find(params[:id])) && (data = current_worker.job) %>
2
- <h1><%= current_worker %>'s job</h1>
2
+ <h1><%= h current_worker %>'s job</h1>
3
3
 
4
4
  <table>
5
5
  <tr>
@@ -13,13 +13,13 @@
13
13
  <tr>
14
14
  <td><img src="<%=u 'working.png' %>" alt="working" title="working"></td>
15
15
  <% host, pid, _ = current_worker.to_s.split(':') %>
16
- <td><a href="<%=u "/workers/#{current_worker}" %>"><%= host %>:<%= pid %></a></td>
16
+ <td><a href="<%= h u("/workers/#{current_worker}") %>"><%= h host %>:<%= h pid %></a></td>
17
17
  <% queue = data['queue'] %>
18
- <td><a class="queue" href="<%=u "/queues/#{queue}" %>"><%= queue %></a></td>
19
- <td><span class="time"><%= data['run_at'] %></span></td>
18
+ <td><a class="queue" href="<%= h u("/queues/#{queue}") %>"><%= h queue %></a></td>
19
+ <td><span class="time"><%= h data['run_at'] %></span></td>
20
20
  <% payload = data.key?('payload') ? data['payload'] : {} %>
21
21
  <td>
22
- <code><%= payload.key?('class') ? payload['class'] : "—" %></code>
22
+ <code><%= payload.key?('class') ? h(payload['class']) : "—" %></code>
23
23
  </td>
24
24
  <td><pre><%=h payload.key?('args') ? show_args(payload['args']) : "—" %></pre></td>
25
25
  </tr>
@@ -51,11 +51,11 @@
51
51
 
52
52
  <% worker_jobs.sort_by { |_w, j| j['run_at'] ? j['run_at'].to_s() : '' }.each do |worker, job| %>
53
53
  <tr>
54
- <td class='icon'><img src="<%=u state = worker.state %>.png" alt="<%= state %>" title="<%= state %>"></td>
54
+ <td class='icon'><img src="<%= h u(state = worker.state) %>.png" alt="<%= h state %>" title="<%= h state %>"></td>
55
55
  <% host, pid, _queues = worker.to_s.split(':') %>
56
- <td class='where'><a href="<%=u "/workers/#{worker}" %>"><%= host %>:<%= pid %></a></td>
56
+ <td class='where'><a href="<%= h u("/workers/#{worker}") %>"><%= h host %>:<%= h pid %></a></td>
57
57
  <td class='queues queue'>
58
- <a class="queue-tag" href="<%=u "/queues/#{job['queue']}" %>"><%= job['queue'] %></a>
58
+ <a class="queue-tag" href="<%= h u("/queues/#{job['queue']}") %>"><%= h job['queue'] %></a>
59
59
  </td>
60
60
  <td class='process'>
61
61
  <% if job['queue'] %>
data/lib/resque/server.rb CHANGED
@@ -168,7 +168,7 @@ module Resque
168
168
  stats << "queues.#{queue}=#{Resque.size(queue)}"
169
169
  end
170
170
 
171
- content_type 'text/html'
171
+ content_type 'text/plain'
172
172
  stats.join "\n"
173
173
  end
174
174
 
@@ -29,7 +29,7 @@ module Resque
29
29
  def tab(name)
30
30
  dname = name.to_s.downcase
31
31
  path = url_path(dname)
32
- "<li #{class_if_current(path)}><a href='#{path.gsub(" ", "_")}'>#{name}</a></li>"
32
+ "<li #{class_if_current(path)}><a href='#{h path.gsub(" ", "_")}'>#{h name}</a></li>"
33
33
  end
34
34
 
35
35
  def tabs
@@ -112,7 +112,7 @@ module Resque
112
112
  if defined?(@polling) && @polling
113
113
  text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
114
114
  else
115
- text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll!!</a>"
115
+ text = "<a href='#{h u(request.path_info)}.poll' rel='poll'>Live Poll!!</a>"
116
116
  end
117
117
  "<p class='poll'>#{text}</p>"
118
118
  end
@@ -1,3 +1,3 @@
1
1
  module Resque
2
- VERSION = '3.0.0'
2
+ VERSION = '3.0.2'
3
3
  end
@@ -85,7 +85,8 @@ module Resque
85
85
  end
86
86
 
87
87
  def url
88
- "http://#{host}:#{port}"
88
+ h = host.include?(':') ? "[#{host}]" : host
89
+ "http://#{h}:#{port}"
89
90
  end
90
91
 
91
92
  def before_run
data/lib/resque.rb CHANGED
@@ -31,8 +31,15 @@ module Resque
31
31
 
32
32
  # Given a Ruby object, returns a string suitable for storage in a
33
33
  # queue.
34
+ #
35
+ # multi_json has renamed its core methods twice: first encode/decode became
36
+ # dump/load, then multi_json 1.21 renamed dump/load to generate/parse. Old
37
+ # names keep working as deprecated aliases. Check the newest name first so
38
+ # we prefer it while staying compatible with older installed versions.
34
39
  def encode(object)
35
- if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
40
+ if MultiJson.respond_to?(:generate) && MultiJson.respond_to?(:parse)
41
+ MultiJson.generate object
42
+ elsif MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
36
43
  MultiJson.dump object
37
44
  else
38
45
  MultiJson.encode object
@@ -40,16 +47,20 @@ module Resque
40
47
  end
41
48
 
42
49
  # Given a string, returns a Ruby object.
50
+ #
51
+ # See `Resque.encode`, above, for why generate/parse are checked before dump/load.
43
52
  def decode(object)
44
53
  return unless object
45
54
 
46
55
  begin
47
- if MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
56
+ if MultiJson.respond_to?(:generate) && MultiJson.respond_to?(:parse)
57
+ MultiJson.parse object
58
+ elsif MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
48
59
  MultiJson.load object
49
60
  else
50
61
  MultiJson.decode object
51
62
  end
52
- rescue ::MultiJson::DecodeError => e
63
+ rescue MultiJson::DecodeError => e
53
64
  raise Helpers::DecodeException, e.message, e.backtrace
54
65
  end
55
66
  end
@@ -251,7 +262,7 @@ module Resque
251
262
  register_hook(:before_fork, block)
252
263
  end
253
264
 
254
- # The `after_fork` hook will be run in the child process and is passed
265
+ # The `after_fork` hook will be run in the **child** process and is passed
255
266
  # the current job. Any changes you make, therefore, will only live as
256
267
  # long as the job currently being processed.
257
268
  #
@@ -266,7 +277,7 @@ module Resque
266
277
  register_hook(:after_fork, block)
267
278
  end
268
279
 
269
- # The `before_pause` hook will be run in the parent process before the
280
+ # The `before_pause` hook will be run in the **parent** process before the
270
281
  # worker has paused processing (via #pause_processing or SIGUSR2).
271
282
  def before_pause(&block)
272
283
  block ? register_hook(:before_pause, block) : hooks(:before_pause)
@@ -277,7 +288,7 @@ module Resque
277
288
  register_hook(:before_pause, block)
278
289
  end
279
290
 
280
- # The `after_pause` hook will be run in the parent process after the
291
+ # The `after_pause` hook will be run in the **parent** process after the
281
292
  # worker has paused (via SIGCONT).
282
293
  def after_pause(&block)
283
294
  block ? register_hook(:after_pause, block) : hooks(:after_pause)
@@ -316,7 +327,7 @@ module Resque
316
327
  register_hook(:worker_exit, block)
317
328
  end
318
329
 
319
- # The `shutdown` hook will be run in the **child** process
330
+ # The `shutdown` hook will be run in the **parent** process
320
331
  # when the worker has received a signal to stop processing
321
332
  #
322
333
  # Call with a block to register a hook.
metadata CHANGED
@@ -1,17 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
8
8
  - Steve Klabnik
9
9
  - Terence Lee
10
10
  - Michael Bianco
11
- autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2026-01-12 00:00:00.000000000 Z
13
+ date: 1980-01-02 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: base64
@@ -229,7 +228,6 @@ licenses:
229
228
  metadata:
230
229
  changelog_uri: https://github.com/resque/resque/blob/master/HISTORY.md
231
230
  rubygems_mfa_required: 'true'
232
- post_install_message:
233
231
  rdoc_options:
234
232
  - "--charset=UTF-8"
235
233
  require_paths:
@@ -245,8 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
243
  - !ruby/object:Gem::Version
246
244
  version: '0'
247
245
  requirements: []
248
- rubygems_version: 3.0.3.1
249
- signing_key:
246
+ rubygems_version: 4.0.6
250
247
  specification_version: 4
251
248
  summary: Resque is a Redis-backed queueing system.
252
249
  test_files: []