chupa-text 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae05a44da20490f2d7833d513cfc423819dd65ef5e1d6285e5a82db8482673fa
4
- data.tar.gz: b202c67426ca48058422f169339c069cb6bc42e892a40fd9c72bda3463610b94
3
+ metadata.gz: 99a53085d7eca8e459b0944e44cdb415036d19b6dc5a366e10bc3921a8c8cb09
4
+ data.tar.gz: ce808a0a9e9352e2b4cf92c9e7348b57e522ee1717dc8070631451aa6a3b9a29
5
5
  SHA512:
6
- metadata.gz: 28126643d65dc7ef423dccc0f727be7b275db0005f66f4c40f0c8e5dafe8b159cdea2b6c8aeca98bf7e9979849cf531ddd5afad81f30c85d031dae925029e763
7
- data.tar.gz: 498fb93a26bfd139d9fba1d15d00bbc17547b9e326c403301794b89f2548c78e8d000ed45c3404c3b0a00073e677c1783c64b1423357893c89326d60efeb07d3
6
+ metadata.gz: 334356c90df57f22ae1fe0871e93147470c7505782487f71613f3fa794ea7fe0ed03b16980892beb46d662f830b876b6b4ff5132b8677892be1246ea26e38f40
7
+ data.tar.gz: 86de4013d3f07d4d89c2113d01d78d4e6685b95af28ab1ad72267908d3c4b9ea30720eec515380989b6fb2a50d913041ee8223197cbcfa00c51b61b97506d1d7
@@ -1,5 +1,21 @@
1
1
  # News
2
2
 
3
+ ## 1.2.1: 2019-03-04
4
+
5
+ ### Improvements
6
+
7
+ * `ChupaText::ExternalCommand`:
8
+
9
+ * Added more logs.
10
+
11
+ * Added support for ensuring killing external command.
12
+
13
+ * Added default value API.
14
+
15
+ * `ChupaText::VirtualFileContent`:
16
+
17
+ * Added support for inlining small data.
18
+
3
19
  ## 1.2.0: 2019-03-03
4
20
 
5
21
  ### Improvements
@@ -40,18 +40,9 @@ module ChupaText
40
40
  path_converter = PathConverter.new(entry.full_name,
41
41
  uri_escape: true)
42
42
  entry_uri.path = "#{base_path}/#{path_converter.convert}"
43
- size = entry.header.size
44
- if size < (32 * 1024)
45
- entry_data = Data.new(source_data: data)
46
- entry_data.uri = entry_uri
47
- body = entry.read || ""
48
- entry_data.body = body
49
- entry_data.size = body.bytesize
50
- else
51
- entry_data = VirtualFileData.new(entry_uri,
52
- entry,
53
- :source_data => data)
54
- end
43
+ entry_data = VirtualFileData.new(entry_uri,
44
+ entry,
45
+ :source_data => data)
55
46
  yield(entry_data)
56
47
  end
57
48
  end
@@ -49,18 +49,9 @@ module ChupaText
49
49
  encoding: base_path.encoding,
50
50
  uri_escape: true)
51
51
  entry_uri.path = "#{base_path}/#{path_converter.convert}"
52
- size = entry.raw_data.window_size
53
- if size < (8 * 1024)
54
- entry_data = Data.new(source_data: data)
55
- entry_data.uri = entry_uri
56
- body = entry.file_data.read
57
- entry_data.body = body
58
- entry_data.size = body.bytesize
59
- else
60
- entry_data = VirtualFileData.new(entry_uri,
61
- entry.file_data,
62
- source_data: data)
63
- end
52
+ entry_data = VirtualFileData.new(entry_uri,
53
+ entry.file_data,
54
+ source_data: data)
64
55
  yield(entry_data)
65
56
  end
66
57
  end
@@ -22,6 +22,42 @@ module ChupaText
22
22
  class ExternalCommand
23
23
  include Loggable
24
24
 
25
+ @default_timeout = nil
26
+ @default_limit_cpu = nil
27
+ @default_limit_as = nil
28
+ class << self
29
+ def default_timeout
30
+ @default_timeout || ENV["CHUPA_TEXT_EXTERNAL_COMMAND_TIMEOUT"]
31
+ end
32
+
33
+ def default_timeout=(timeout)
34
+ @default_timeout = timeout
35
+ end
36
+
37
+ def default_limit_cpu
38
+ @default_limit_cpu || limit_env("CPU")
39
+ end
40
+
41
+ def default_limit_cpu=(cpu)
42
+ @default_limit_cpu = cpu
43
+ end
44
+
45
+ def default_limit_as
46
+ @default_limit_as || limit_env("AS")
47
+ end
48
+
49
+ def default_limit_as=(as)
50
+ @default_limit_as = as
51
+ end
52
+
53
+ private
54
+ def limit_env(name)
55
+ ENV["CHUPA_TEXT_EXTERNAL_COMMAND_LIMIT_#{name}"] ||
56
+ # For backward compatibility
57
+ ENV["CHUPA_EXTERNAL_COMMAND_LIMIT_#{name}"]
58
+ end
59
+ end
60
+
25
61
  attr_reader :path
26
62
  def initialize(path)
27
63
  @path = Pathname.new(path)
@@ -37,7 +73,18 @@ module ChupaText
37
73
  @path.to_s,
38
74
  *arguments,
39
75
  spawn_options(options[:spawn_options]))
40
- status = wait_process(pid, options[:timeout])
76
+ status = nil
77
+ begin
78
+ status = wait_process(pid, options[:timeout])
79
+ ensure
80
+ unless status
81
+ begin
82
+ Process.kill(:KILL, pid)
83
+ Process.waitpid(pid)
84
+ rescue SystemCallError
85
+ end
86
+ end
87
+ end
41
88
  status.success?
42
89
  end
43
90
 
@@ -72,11 +119,8 @@ module ChupaText
72
119
  return if options[option_key]
73
120
 
74
121
  tag = "[limit][#{key}]"
75
- value =
76
- ENV["CHUPA_TEXT_EXTERNAL_COMMAND_LIMIT_#{key.to_s.upcase}"] ||
77
- # For backward compatibility
78
- ENV["CHUPA_EXTERNAL_COMMAND_LIMIT_#{key.to_s.upcase}"]
79
- value = send("parse_#{type}", tag, value)
122
+ value = self.class.__send__("default_limit_#{key}")
123
+ value = __send__("parse_#{type}", tag, value)
80
124
  return if value.nil?
81
125
  rlimit_number = Process.const_get("RLIMIT_#{key.to_s.upcase}")
82
126
  soft_limit, hard_limit = Process.getrlimit(rlimit_number)
@@ -96,67 +140,87 @@ module ChupaText
96
140
  end
97
141
 
98
142
  def parse_int(tag, value)
99
- return nil if value.nil?
100
- return nil if value.empty?
101
- begin
102
- Integer(value)
103
- rescue ArgumentError
104
- log_invalid_value(tag, value, type, "int")
143
+ case value
144
+ when nil
105
145
  nil
146
+ when Integer
147
+ value
148
+ when Float
149
+ value.round
150
+ else
151
+ return nil if value.empty?
152
+ begin
153
+ Integer(value)
154
+ rescue ArgumentError
155
+ log_invalid_value(tag, value, type, "int")
156
+ nil
157
+ end
106
158
  end
107
159
  end
108
160
 
109
161
  def parse_size(tag, value)
110
- return nil if value.nil?
111
- return nil if value.empty?
112
- scale = 1
113
162
  case value
114
- when /GB?\z/i
115
- scale = 1024 ** 3
116
- number = $PREMATCH
117
- when /MB?\z/i
118
- scale = 1024 ** 2
119
- number = $PREMATCH
120
- when /KB?\z/i
121
- scale = 1024 ** 1
122
- number = $PREMATCH
123
- when /B?\z/i
124
- number = $PREMATCH
163
+ when nil
164
+ nil
165
+ when Numeric
166
+ value
125
167
  else
126
- number = value
127
- end
128
- begin
129
- number = Float(number)
130
- rescue ArgumentError
131
- log_invalid_value(tag, value, "size")
132
- return nil
168
+ return nil if value.empty?
169
+ scale = 1
170
+ case value
171
+ when /GB?\z/i
172
+ scale = 1024 ** 3
173
+ number = $PREMATCH
174
+ when /MB?\z/i
175
+ scale = 1024 ** 2
176
+ number = $PREMATCH
177
+ when /KB?\z/i
178
+ scale = 1024 ** 1
179
+ number = $PREMATCH
180
+ when /B?\z/i
181
+ number = $PREMATCH
182
+ else
183
+ number = value
184
+ end
185
+ begin
186
+ number = Float(number)
187
+ rescue ArgumentError
188
+ log_invalid_value(tag, value, "size")
189
+ return nil
190
+ end
191
+ (number * scale).to_i
133
192
  end
134
- (number * scale).to_i
135
193
  end
136
194
 
137
195
  def parse_time(tag, value)
138
- return nil if value.nil?
139
- return nil if value.empty?
140
- scale = 1
141
196
  case value
142
- when /h\z/i
143
- scale = 60 * 60
144
- number = $PREMATCH
145
- when /m\z/i
146
- scale = 60
147
- number = $PREMATCH
148
- when /s\z/i
149
- number = $PREMATCH
197
+ when nil
198
+ nil
199
+ when Numeric
200
+ value
150
201
  else
151
- number = value
152
- end
153
- begin
154
- number = Float(number)
155
- rescue ArgumentError
156
- log_invalid_value(tag, value, "time")
157
- return nil
202
+ return nil if value.empty?
203
+ scale = 1
204
+ case value
205
+ when /h\z/i
206
+ scale = 60 * 60
207
+ number = $PREMATCH
208
+ when /m\z/i
209
+ scale = 60
210
+ number = $PREMATCH
211
+ when /s\z/i
212
+ number = $PREMATCH
213
+ else
214
+ number = value
215
+ end
216
+ begin
217
+ number = Float(number)
218
+ rescue ArgumentError
219
+ log_invalid_value(tag, value, "time")
220
+ return nil
221
+ end
222
+ (number * scale).to_f
158
223
  end
159
- (number * scale).to_f
160
224
  end
161
225
 
162
226
  def log_invalid_value(tag, value, type)
@@ -164,17 +228,17 @@ module ChupaText
164
228
  end
165
229
 
166
230
  def wait_process(pid, timeout)
167
- if timeout.nil?
168
- timeout_env = ENV["CHUPA_TEXT_EXTERNAL_COMMAND_TIMEOUT"]
169
- timeout = parse_time("[timeout]", timeout_env) if timeout_env
170
- end
171
-
231
+ tag = "[timeout]"
232
+ timeout = parse_time(tag, timeout || self.class.default_timeout)
172
233
  if timeout
234
+ info("#{log_tag}#{tag}[use] <#{timeout}s>: <#{pid}>")
173
235
  status = wait_process_timeout(pid, timeout)
174
236
  return status if status
237
+ info("#{log_tag}#{tag}[terminate] <#{pid}>")
175
238
  Process.kill(:TERM, pid)
176
239
  status = wait_process_timeout(pid, 5)
177
240
  return status if status
241
+ info("#{log_tag}#{tag}[kill] <#{pid}>")
178
242
  Process.kill(:KILL, pid)
179
243
  end
180
244
  _, status = Process.waitpid2(pid)
@@ -15,5 +15,5 @@
15
15
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
  module ChupaText
18
- VERSION = "1.2.0"
18
+ VERSION = "1.2.1"
19
19
  end
@@ -20,12 +20,10 @@ require "tempfile"
20
20
 
21
21
  module ChupaText
22
22
  class VirtualContent
23
- KILO_BYTE = 1024
24
- BUFFER_SIZE = 64 * KILO_BYTE
23
+ INLINE_MAX_SIZE = 64 * 1024
25
24
 
26
25
  attr_reader :size
27
26
  def initialize(input, original_path=nil)
28
- @file = nil
29
27
  if original_path.is_a?(String)
30
28
  if original_path.empty?
31
29
  original_path = nil
@@ -34,28 +32,56 @@ module ChupaText
34
32
  end
35
33
  end
36
34
  @original_path = original_path
37
- setup_file do |file|
38
- @size = IO.copy_stream(input, file)
35
+ body = input.read(INLINE_MAX_SIZE + 1) || ""
36
+ if body.bytesize <= INLINE_MAX_SIZE
37
+ @body = body
38
+ @size = @body.bytesize
39
+ @file = nil
40
+ @path = nil
41
+ else
42
+ @body = nil
43
+ setup_file do |file|
44
+ file.write(body)
45
+ @size = body.bytesize
46
+ @size += IO.copy_stream(input, file)
47
+ end
39
48
  end
40
49
  end
41
50
 
42
51
  def open(&block)
43
- File.open(path, "rb", &block)
52
+ if @body
53
+ yield(StringIO.new(@body))
54
+ else
55
+ File.open(path, "rb", &block)
56
+ end
44
57
  end
45
58
 
46
59
  def body
47
- open do |file|
48
- file.read
60
+ if @body
61
+ @body
62
+ else
63
+ open do |file|
64
+ file.read
65
+ end
49
66
  end
50
67
  end
51
68
 
52
69
  def peek_body(size)
53
- open do |file|
54
- file.read(size)
70
+ if @body
71
+ @body[0, size]
72
+ else
73
+ open do |file|
74
+ file.read(size)
75
+ end
55
76
  end
56
77
  end
57
78
 
58
79
  def path
80
+ if @path.nil?
81
+ setup_file do |file|
82
+ file.write(@body)
83
+ end
84
+ end
59
85
  @path
60
86
  end
61
87
 
@@ -77,6 +103,7 @@ module ChupaText
77
103
  def setup_file
78
104
  basename = compute_tempfile_basename
79
105
  @file = Tempfile.new(basename)
106
+ @file.binmode
80
107
  @path = @file.path
81
108
  yield(@file)
82
109
  @file.close
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2013-2019 Kouhei Sutou <kou@clear-code.com>
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -53,7 +53,7 @@ class TestVirtualContent < Test::Unit::TestCase
53
53
 
54
54
  sub_test_case("large data") do
55
55
  def setup
56
- @body = "X" * (ChupaText::VirtualContent::BUFFER_SIZE + 1)
56
+ @body = "X" * (ChupaText::VirtualContent::INLINE_MAX_SIZE + 1)
57
57
  end
58
58
 
59
59
  def test_size
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chupa-text
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-02 00:00:00.000000000 Z
11
+ date: 2019-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: archive-zip