diy_rails 0.1.0 → 0.1.1
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 +4 -4
- data/lib/diy_rails/version.rb +1 -1
- data/lib/diy_rails.rb +7 -3
- metadata +12 -151
- data/vendor/bundle/ruby/3.0.0/bin/rackup +0 -29
- data/vendor/bundle/ruby/3.0.0/bin/rake +0 -29
- data/vendor/bundle/ruby/3.0.0/cache/rack-2.2.4.gem +0 -0
- data/vendor/bundle/ruby/3.0.0/cache/rake-13.0.6.gem +0 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/CHANGELOG.md +0 -708
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/CONTRIBUTING.md +0 -136
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/MIT-LICENSE +0 -20
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/README.rdoc +0 -306
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/Rakefile +0 -130
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/SPEC.rdoc +0 -288
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/bin/rackup +0 -5
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack.png +0 -0
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack.svg +0 -150
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rack_logo.svg +0 -164
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/contrib/rdoc.css +0 -412
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/lobster.ru +0 -6
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/protectedlobster.rb +0 -16
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/example/protectedlobster.ru +0 -10
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/abstract/handler.rb +0 -39
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/abstract/request.rb +0 -47
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/basic.rb +0 -61
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/md5.rb +0 -131
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/nonce.rb +0 -54
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/params.rb +0 -54
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/auth/digest/request.rb +0 -43
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/body_proxy.rb +0 -45
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/builder.rb +0 -257
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/cascade.rb +0 -68
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/chunked.rb +0 -117
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/common_logger.rb +0 -83
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/conditional_get.rb +0 -83
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/config.rb +0 -22
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/content_length.rb +0 -38
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/content_type.rb +0 -30
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/core_ext/regexp.rb +0 -14
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/deflater.rb +0 -144
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/directory.rb +0 -199
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/etag.rb +0 -77
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/events.rb +0 -153
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/file.rb +0 -7
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/files.rb +0 -218
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/cgi.rb +0 -59
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/fastcgi.rb +0 -100
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/lsws.rb +0 -61
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/scgi.rb +0 -71
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/thin.rb +0 -36
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler/webrick.rb +0 -129
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/handler.rb +0 -104
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/head.rb +0 -25
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lint.rb +0 -806
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lobster.rb +0 -70
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/lock.rb +0 -32
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/logger.rb +0 -20
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/media_type.rb +0 -43
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/method_override.rb +0 -52
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/mime.rb +0 -685
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/mock.rb +0 -273
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/generator.rb +0 -97
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/parser.rb +0 -365
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart/uploaded_file.rb +0 -41
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/multipart.rb +0 -64
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/null_logger.rb +0 -39
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/query_parser.rb +0 -221
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/recursive.rb +0 -64
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/reloader.rb +0 -114
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/request.rb +0 -659
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/response.rb +0 -318
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/rewindable_input.rb +0 -94
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/runtime.rb +0 -34
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/sendfile.rb +0 -162
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/server.rb +0 -466
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/abstract/id.rb +0 -523
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/cookie.rb +0 -203
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/memcache.rb +0 -10
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/session/pool.rb +0 -85
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/show_exceptions.rb +0 -390
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/show_status.rb +0 -113
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/static.rb +0 -187
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/tempfile_reaper.rb +0 -22
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/urlmap.rb +0 -97
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/utils.rb +0 -616
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack/version.rb +0 -29
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/lib/rack.rb +0 -141
- data/vendor/bundle/ruby/3.0.0/gems/rack-2.2.4/rack.gemspec +0 -46
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/History.rdoc +0 -2403
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/MIT-LICENSE +0 -21
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/README.rdoc +0 -155
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/command_line_usage.rdoc +0 -158
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/Rakefile1 +0 -38
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/Rakefile2 +0 -35
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/a.c +0 -6
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/b.c +0 -6
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/example/main.c +0 -11
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/glossary.rdoc +0 -42
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/jamis.rb +0 -592
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/proto_rake.rdoc +0 -127
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rake.1 +0 -156
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rakefile.rdoc +0 -622
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/doc/rational.rdoc +0 -151
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/exe/rake +0 -27
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb +0 -831
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/backtrace.rb +0 -24
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/clean.rb +0 -78
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/cloneable.rb +0 -17
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/cpu_counter.rb +0 -107
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/default_loader.rb +0 -15
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/dsl_definition.rb +0 -195
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/early_time.rb +0 -22
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/ext/core.rb +0 -26
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/ext/string.rb +0 -176
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_creation_task.rb +0 -25
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_list.rb +0 -435
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_task.rb +0 -54
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_utils.rb +0 -134
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/file_utils_ext.rb +0 -134
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/invocation_chain.rb +0 -57
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/invocation_exception_mixin.rb +0 -17
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/late_time.rb +0 -18
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/linked_list.rb +0 -112
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/loaders/makefile.rb +0 -54
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/multi_task.rb +0 -14
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/name_space.rb +0 -38
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/packagetask.rb +0 -222
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/phony.rb +0 -16
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/private_reader.rb +0 -21
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/promise.rb +0 -100
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/pseudo_status.rb +0 -30
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_module.rb +0 -67
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_test_loader.rb +0 -27
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rule_recursion_overflow_error.rb +0 -20
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/scope.rb +0 -43
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb +0 -434
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_argument_error.rb +0 -8
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_arguments.rb +0 -109
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_manager.rb +0 -331
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/tasklib.rb +0 -12
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/testtask.rb +0 -189
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/thread_history_display.rb +0 -49
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/thread_pool.rb +0 -163
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/trace_output.rb +0 -23
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/version.rb +0 -10
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/win32.rb +0 -51
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake.rb +0 -71
- data/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/rake.gemspec +0 -100
- data/vendor/bundle/ruby/3.0.0/specifications/rack-2.2.4.gemspec +0 -41
- data/vendor/bundle/ruby/3.0.0/specifications/rake-13.0.6.gemspec +0 -26
@@ -1,365 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'strscan'
|
4
|
-
|
5
|
-
module Rack
|
6
|
-
module Multipart
|
7
|
-
class MultipartPartLimitError < Errno::EMFILE; end
|
8
|
-
|
9
|
-
class Parser
|
10
|
-
(require_relative '../core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
11
|
-
|
12
|
-
BUFSIZE = 1_048_576
|
13
|
-
TEXT_PLAIN = "text/plain"
|
14
|
-
TEMPFILE_FACTORY = lambda { |filename, content_type|
|
15
|
-
Tempfile.new(["RackMultipart", ::File.extname(filename.gsub("\0", '%00'))])
|
16
|
-
}
|
17
|
-
|
18
|
-
BOUNDARY_REGEX = /\A([^\n]*(?:\n|\Z))/
|
19
|
-
|
20
|
-
class BoundedIO # :nodoc:
|
21
|
-
def initialize(io, content_length)
|
22
|
-
@io = io
|
23
|
-
@content_length = content_length
|
24
|
-
@cursor = 0
|
25
|
-
end
|
26
|
-
|
27
|
-
def read(size, outbuf = nil)
|
28
|
-
return if @cursor >= @content_length
|
29
|
-
|
30
|
-
left = @content_length - @cursor
|
31
|
-
|
32
|
-
str = if left < size
|
33
|
-
@io.read left, outbuf
|
34
|
-
else
|
35
|
-
@io.read size, outbuf
|
36
|
-
end
|
37
|
-
|
38
|
-
if str
|
39
|
-
@cursor += str.bytesize
|
40
|
-
else
|
41
|
-
# Raise an error for mismatching Content-Length and actual contents
|
42
|
-
raise EOFError, "bad content body"
|
43
|
-
end
|
44
|
-
|
45
|
-
str
|
46
|
-
end
|
47
|
-
|
48
|
-
def rewind
|
49
|
-
@io.rewind
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
MultipartInfo = Struct.new :params, :tmp_files
|
54
|
-
EMPTY = MultipartInfo.new(nil, [])
|
55
|
-
|
56
|
-
def self.parse_boundary(content_type)
|
57
|
-
return unless content_type
|
58
|
-
data = content_type.match(MULTIPART)
|
59
|
-
return unless data
|
60
|
-
data[1]
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.parse(io, content_length, content_type, tmpfile, bufsize, qp)
|
64
|
-
return EMPTY if 0 == content_length
|
65
|
-
|
66
|
-
boundary = parse_boundary content_type
|
67
|
-
return EMPTY unless boundary
|
68
|
-
|
69
|
-
io = BoundedIO.new(io, content_length) if content_length
|
70
|
-
outbuf = String.new
|
71
|
-
|
72
|
-
parser = new(boundary, tmpfile, bufsize, qp)
|
73
|
-
parser.on_read io.read(bufsize, outbuf)
|
74
|
-
|
75
|
-
loop do
|
76
|
-
break if parser.state == :DONE
|
77
|
-
parser.on_read io.read(bufsize, outbuf)
|
78
|
-
end
|
79
|
-
|
80
|
-
io.rewind
|
81
|
-
parser.result
|
82
|
-
end
|
83
|
-
|
84
|
-
class Collector
|
85
|
-
class MimePart < Struct.new(:body, :head, :filename, :content_type, :name)
|
86
|
-
def get_data
|
87
|
-
data = body
|
88
|
-
if filename == ""
|
89
|
-
# filename is blank which means no file has been selected
|
90
|
-
return
|
91
|
-
elsif filename
|
92
|
-
body.rewind if body.respond_to?(:rewind)
|
93
|
-
|
94
|
-
# Take the basename of the upload's original filename.
|
95
|
-
# This handles the full Windows paths given by Internet Explorer
|
96
|
-
# (and perhaps other broken user agents) without affecting
|
97
|
-
# those which give the lone filename.
|
98
|
-
fn = filename.split(/[\/\\]/).last
|
99
|
-
|
100
|
-
data = { filename: fn, type: content_type,
|
101
|
-
name: name, tempfile: body, head: head }
|
102
|
-
end
|
103
|
-
|
104
|
-
yield data
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
class BufferPart < MimePart
|
109
|
-
def file?; false; end
|
110
|
-
def close; end
|
111
|
-
end
|
112
|
-
|
113
|
-
class TempfilePart < MimePart
|
114
|
-
def file?; true; end
|
115
|
-
def close; body.close; end
|
116
|
-
end
|
117
|
-
|
118
|
-
include Enumerable
|
119
|
-
|
120
|
-
def initialize(tempfile)
|
121
|
-
@tempfile = tempfile
|
122
|
-
@mime_parts = []
|
123
|
-
@open_files = 0
|
124
|
-
end
|
125
|
-
|
126
|
-
def each
|
127
|
-
@mime_parts.each { |part| yield part }
|
128
|
-
end
|
129
|
-
|
130
|
-
def on_mime_head(mime_index, head, filename, content_type, name)
|
131
|
-
if filename
|
132
|
-
body = @tempfile.call(filename, content_type)
|
133
|
-
body.binmode if body.respond_to?(:binmode)
|
134
|
-
klass = TempfilePart
|
135
|
-
@open_files += 1
|
136
|
-
else
|
137
|
-
body = String.new
|
138
|
-
klass = BufferPart
|
139
|
-
end
|
140
|
-
|
141
|
-
@mime_parts[mime_index] = klass.new(body, head, filename, content_type, name)
|
142
|
-
|
143
|
-
check_open_files
|
144
|
-
end
|
145
|
-
|
146
|
-
def on_mime_body(mime_index, content)
|
147
|
-
@mime_parts[mime_index].body << content
|
148
|
-
end
|
149
|
-
|
150
|
-
def on_mime_finish(mime_index)
|
151
|
-
end
|
152
|
-
|
153
|
-
private
|
154
|
-
|
155
|
-
def check_open_files
|
156
|
-
if Utils.multipart_part_limit > 0
|
157
|
-
if @open_files >= Utils.multipart_part_limit
|
158
|
-
@mime_parts.each(&:close)
|
159
|
-
raise MultipartPartLimitError, 'Maximum file multiparts in content reached'
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
attr_reader :state
|
166
|
-
|
167
|
-
def initialize(boundary, tempfile, bufsize, query_parser)
|
168
|
-
@query_parser = query_parser
|
169
|
-
@params = query_parser.make_params
|
170
|
-
@boundary = "--#{boundary}"
|
171
|
-
@bufsize = bufsize
|
172
|
-
|
173
|
-
@full_boundary = @boundary
|
174
|
-
@end_boundary = @boundary + '--'
|
175
|
-
@state = :FAST_FORWARD
|
176
|
-
@mime_index = 0
|
177
|
-
@collector = Collector.new tempfile
|
178
|
-
|
179
|
-
@sbuf = StringScanner.new("".dup)
|
180
|
-
@body_regex = /(?:#{EOL})?#{Regexp.quote(@boundary)}(?:#{EOL}|--)/m
|
181
|
-
@rx_max_size = EOL.size + @boundary.bytesize + [EOL.size, '--'.size].max
|
182
|
-
@head_regex = /(.*?#{EOL})#{EOL}/m
|
183
|
-
end
|
184
|
-
|
185
|
-
def on_read(content)
|
186
|
-
handle_empty_content!(content)
|
187
|
-
@sbuf.concat content
|
188
|
-
run_parser
|
189
|
-
end
|
190
|
-
|
191
|
-
def result
|
192
|
-
@collector.each do |part|
|
193
|
-
part.get_data do |data|
|
194
|
-
tag_multipart_encoding(part.filename, part.content_type, part.name, data)
|
195
|
-
@query_parser.normalize_params(@params, part.name, data, @query_parser.param_depth_limit)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
MultipartInfo.new @params.to_params_hash, @collector.find_all(&:file?).map(&:body)
|
199
|
-
end
|
200
|
-
|
201
|
-
private
|
202
|
-
|
203
|
-
def run_parser
|
204
|
-
loop do
|
205
|
-
case @state
|
206
|
-
when :FAST_FORWARD
|
207
|
-
break if handle_fast_forward == :want_read
|
208
|
-
when :CONSUME_TOKEN
|
209
|
-
break if handle_consume_token == :want_read
|
210
|
-
when :MIME_HEAD
|
211
|
-
break if handle_mime_head == :want_read
|
212
|
-
when :MIME_BODY
|
213
|
-
break if handle_mime_body == :want_read
|
214
|
-
when :DONE
|
215
|
-
break
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def handle_fast_forward
|
221
|
-
if consume_boundary
|
222
|
-
@state = :MIME_HEAD
|
223
|
-
else
|
224
|
-
raise EOFError, "bad content body" if @sbuf.rest_size >= @bufsize
|
225
|
-
:want_read
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def handle_consume_token
|
230
|
-
tok = consume_boundary
|
231
|
-
# break if we're at the end of a buffer, but not if it is the end of a field
|
232
|
-
@state = if tok == :END_BOUNDARY || (@sbuf.eos? && tok != :BOUNDARY)
|
233
|
-
:DONE
|
234
|
-
else
|
235
|
-
:MIME_HEAD
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def handle_mime_head
|
240
|
-
if @sbuf.scan_until(@head_regex)
|
241
|
-
head = @sbuf[1]
|
242
|
-
content_type = head[MULTIPART_CONTENT_TYPE, 1]
|
243
|
-
if name = head[MULTIPART_CONTENT_DISPOSITION, 1]
|
244
|
-
name = Rack::Auth::Digest::Params::dequote(name)
|
245
|
-
else
|
246
|
-
name = head[MULTIPART_CONTENT_ID, 1]
|
247
|
-
end
|
248
|
-
|
249
|
-
filename = get_filename(head)
|
250
|
-
|
251
|
-
if name.nil? || name.empty?
|
252
|
-
name = filename || "#{content_type || TEXT_PLAIN}[]".dup
|
253
|
-
end
|
254
|
-
|
255
|
-
@collector.on_mime_head @mime_index, head, filename, content_type, name
|
256
|
-
@state = :MIME_BODY
|
257
|
-
else
|
258
|
-
:want_read
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
def handle_mime_body
|
263
|
-
if (body_with_boundary = @sbuf.check_until(@body_regex)) # check but do not advance the pointer yet
|
264
|
-
body = body_with_boundary.sub(/#{@body_regex}\z/m, '') # remove the boundary from the string
|
265
|
-
@collector.on_mime_body @mime_index, body
|
266
|
-
@sbuf.pos += body.length + 2 # skip \r\n after the content
|
267
|
-
@state = :CONSUME_TOKEN
|
268
|
-
@mime_index += 1
|
269
|
-
else
|
270
|
-
# Save what we have so far
|
271
|
-
if @rx_max_size < @sbuf.rest_size
|
272
|
-
delta = @sbuf.rest_size - @rx_max_size
|
273
|
-
@collector.on_mime_body @mime_index, @sbuf.peek(delta)
|
274
|
-
@sbuf.pos += delta
|
275
|
-
@sbuf.string = @sbuf.rest
|
276
|
-
end
|
277
|
-
:want_read
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
def full_boundary; @full_boundary; end
|
282
|
-
|
283
|
-
def consume_boundary
|
284
|
-
while read_buffer = @sbuf.scan_until(BOUNDARY_REGEX)
|
285
|
-
case read_buffer.strip
|
286
|
-
when full_boundary then return :BOUNDARY
|
287
|
-
when @end_boundary then return :END_BOUNDARY
|
288
|
-
end
|
289
|
-
return if @sbuf.eos?
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def get_filename(head)
|
294
|
-
filename = nil
|
295
|
-
case head
|
296
|
-
when RFC2183
|
297
|
-
params = Hash[*head.scan(DISPPARM).flat_map(&:compact)]
|
298
|
-
|
299
|
-
if filename = params['filename']
|
300
|
-
filename = $1 if filename =~ /^"(.*)"$/
|
301
|
-
elsif filename = params['filename*']
|
302
|
-
encoding, _, filename = filename.split("'", 3)
|
303
|
-
end
|
304
|
-
when BROKEN
|
305
|
-
filename = $1
|
306
|
-
filename = $1 if filename =~ /^"(.*)"$/
|
307
|
-
end
|
308
|
-
|
309
|
-
return unless filename
|
310
|
-
|
311
|
-
if filename.scan(/%.?.?/).all? { |s| /%[0-9a-fA-F]{2}/.match?(s) }
|
312
|
-
filename = Utils.unescape_path(filename)
|
313
|
-
end
|
314
|
-
|
315
|
-
filename.scrub!
|
316
|
-
|
317
|
-
if filename !~ /\\[^\\"]/
|
318
|
-
filename = filename.gsub(/\\(.)/, '\1')
|
319
|
-
end
|
320
|
-
|
321
|
-
if encoding
|
322
|
-
filename.force_encoding ::Encoding.find(encoding)
|
323
|
-
end
|
324
|
-
|
325
|
-
filename
|
326
|
-
end
|
327
|
-
|
328
|
-
CHARSET = "charset"
|
329
|
-
|
330
|
-
def tag_multipart_encoding(filename, content_type, name, body)
|
331
|
-
name = name.to_s
|
332
|
-
encoding = Encoding::UTF_8
|
333
|
-
|
334
|
-
name.force_encoding(encoding)
|
335
|
-
|
336
|
-
return if filename
|
337
|
-
|
338
|
-
if content_type
|
339
|
-
list = content_type.split(';')
|
340
|
-
type_subtype = list.first
|
341
|
-
type_subtype.strip!
|
342
|
-
if TEXT_PLAIN == type_subtype
|
343
|
-
rest = list.drop 1
|
344
|
-
rest.each do |param|
|
345
|
-
k, v = param.split('=', 2)
|
346
|
-
k.strip!
|
347
|
-
v.strip!
|
348
|
-
v = v[1..-2] if v.start_with?('"') && v.end_with?('"')
|
349
|
-
encoding = Encoding.find v if k == CHARSET
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
name.force_encoding(encoding)
|
355
|
-
body.force_encoding(encoding)
|
356
|
-
end
|
357
|
-
|
358
|
-
def handle_empty_content!(content)
|
359
|
-
if content.nil? || content.empty?
|
360
|
-
raise EOFError
|
361
|
-
end
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|
365
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
module Multipart
|
5
|
-
class UploadedFile
|
6
|
-
# The filename, *not* including the path, of the "uploaded" file
|
7
|
-
attr_reader :original_filename
|
8
|
-
|
9
|
-
# The content type of the "uploaded" file
|
10
|
-
attr_accessor :content_type
|
11
|
-
|
12
|
-
def initialize(filepath = nil, ct = "text/plain", bin = false,
|
13
|
-
path: filepath, content_type: ct, binary: bin, filename: nil, io: nil)
|
14
|
-
if io
|
15
|
-
@tempfile = io
|
16
|
-
@original_filename = filename
|
17
|
-
else
|
18
|
-
raise "#{path} file does not exist" unless ::File.exist?(path)
|
19
|
-
@original_filename = filename || ::File.basename(path)
|
20
|
-
@tempfile = Tempfile.new([@original_filename, ::File.extname(path)], encoding: Encoding::BINARY)
|
21
|
-
@tempfile.binmode if binary
|
22
|
-
FileUtils.copy_file(path, @tempfile.path)
|
23
|
-
end
|
24
|
-
@content_type = content_type
|
25
|
-
end
|
26
|
-
|
27
|
-
def path
|
28
|
-
@tempfile.path if @tempfile.respond_to?(:path)
|
29
|
-
end
|
30
|
-
alias_method :local_path, :path
|
31
|
-
|
32
|
-
def respond_to?(*args)
|
33
|
-
super or @tempfile.respond_to?(*args)
|
34
|
-
end
|
35
|
-
|
36
|
-
def method_missing(method_name, *args, &block) #:nodoc:
|
37
|
-
@tempfile.__send__(method_name, *args, &block)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'multipart/parser'
|
4
|
-
|
5
|
-
module Rack
|
6
|
-
# A multipart form data parser, adapted from IOWA.
|
7
|
-
#
|
8
|
-
# Usually, Rack::Request#POST takes care of calling this.
|
9
|
-
module Multipart
|
10
|
-
autoload :UploadedFile, 'rack/multipart/uploaded_file'
|
11
|
-
autoload :Generator, 'rack/multipart/generator'
|
12
|
-
|
13
|
-
EOL = "\r\n"
|
14
|
-
MULTIPART_BOUNDARY = "AaB03x"
|
15
|
-
MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni
|
16
|
-
TOKEN = /[^\s()<>,;:\\"\/\[\]?=]+/
|
17
|
-
CONDISP = /Content-Disposition:\s*#{TOKEN}\s*/i
|
18
|
-
VALUE = /"(?:\\"|[^"])*"|#{TOKEN}/
|
19
|
-
BROKEN = /^#{CONDISP}.*;\s*filename=(#{VALUE})/i
|
20
|
-
MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{EOL}/ni
|
21
|
-
MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:.*;\s*name=(#{VALUE})/ni
|
22
|
-
MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{EOL}]*)/ni
|
23
|
-
# Updated definitions from RFC 2231
|
24
|
-
ATTRIBUTE_CHAR = %r{[^ \t\v\n\r)(><@,;:\\"/\[\]?='*%]}
|
25
|
-
ATTRIBUTE = /#{ATTRIBUTE_CHAR}+/
|
26
|
-
SECTION = /\*[0-9]+/
|
27
|
-
REGULAR_PARAMETER_NAME = /#{ATTRIBUTE}#{SECTION}?/
|
28
|
-
REGULAR_PARAMETER = /(#{REGULAR_PARAMETER_NAME})=(#{VALUE})/
|
29
|
-
EXTENDED_OTHER_NAME = /#{ATTRIBUTE}\*[1-9][0-9]*\*/
|
30
|
-
EXTENDED_OTHER_VALUE = /%[0-9a-fA-F]{2}|#{ATTRIBUTE_CHAR}/
|
31
|
-
EXTENDED_OTHER_PARAMETER = /(#{EXTENDED_OTHER_NAME})=(#{EXTENDED_OTHER_VALUE}*)/
|
32
|
-
EXTENDED_INITIAL_NAME = /#{ATTRIBUTE}(?:\*0)?\*/
|
33
|
-
EXTENDED_INITIAL_VALUE = /[a-zA-Z0-9\-]*'[a-zA-Z0-9\-]*'#{EXTENDED_OTHER_VALUE}*/
|
34
|
-
EXTENDED_INITIAL_PARAMETER = /(#{EXTENDED_INITIAL_NAME})=(#{EXTENDED_INITIAL_VALUE})/
|
35
|
-
EXTENDED_PARAMETER = /#{EXTENDED_INITIAL_PARAMETER}|#{EXTENDED_OTHER_PARAMETER}/
|
36
|
-
DISPPARM = /;\s*(?:#{REGULAR_PARAMETER}|#{EXTENDED_PARAMETER})\s*/
|
37
|
-
RFC2183 = /^#{CONDISP}(#{DISPPARM})+$/i
|
38
|
-
|
39
|
-
class << self
|
40
|
-
def parse_multipart(env, params = Rack::Utils.default_query_parser)
|
41
|
-
extract_multipart Rack::Request.new(env), params
|
42
|
-
end
|
43
|
-
|
44
|
-
def extract_multipart(req, params = Rack::Utils.default_query_parser)
|
45
|
-
io = req.get_header(RACK_INPUT)
|
46
|
-
io.rewind
|
47
|
-
content_length = req.content_length
|
48
|
-
content_length = content_length.to_i if content_length
|
49
|
-
|
50
|
-
tempfile = req.get_header(RACK_MULTIPART_TEMPFILE_FACTORY) || Parser::TEMPFILE_FACTORY
|
51
|
-
bufsize = req.get_header(RACK_MULTIPART_BUFFER_SIZE) || Parser::BUFSIZE
|
52
|
-
|
53
|
-
info = Parser.parse io, content_length, req.get_header('CONTENT_TYPE'), tempfile, bufsize, params
|
54
|
-
req.set_header(RACK_TEMPFILES, info.tmp_files)
|
55
|
-
info.params
|
56
|
-
end
|
57
|
-
|
58
|
-
def build_multipart(params, first = true)
|
59
|
-
Generator.new(params, first).dump
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
class NullLogger
|
5
|
-
def initialize(app)
|
6
|
-
@app = app
|
7
|
-
end
|
8
|
-
|
9
|
-
def call(env)
|
10
|
-
env[RACK_LOGGER] = self
|
11
|
-
@app.call(env)
|
12
|
-
end
|
13
|
-
|
14
|
-
def info(progname = nil, &block); end
|
15
|
-
def debug(progname = nil, &block); end
|
16
|
-
def warn(progname = nil, &block); end
|
17
|
-
def error(progname = nil, &block); end
|
18
|
-
def fatal(progname = nil, &block); end
|
19
|
-
def unknown(progname = nil, &block); end
|
20
|
-
def info? ; end
|
21
|
-
def debug? ; end
|
22
|
-
def warn? ; end
|
23
|
-
def error? ; end
|
24
|
-
def fatal? ; end
|
25
|
-
def level ; end
|
26
|
-
def progname ; end
|
27
|
-
def datetime_format ; end
|
28
|
-
def formatter ; end
|
29
|
-
def sev_threshold ; end
|
30
|
-
def level=(level); end
|
31
|
-
def progname=(progname); end
|
32
|
-
def datetime_format=(datetime_format); end
|
33
|
-
def formatter=(formatter); end
|
34
|
-
def sev_threshold=(sev_threshold); end
|
35
|
-
def close ; end
|
36
|
-
def add(severity, message = nil, progname = nil, &block); end
|
37
|
-
def <<(msg); end
|
38
|
-
end
|
39
|
-
end
|