stomp_parser 1.0.0-universal-java

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.
@@ -0,0 +1,3 @@
1
+ describe StompParser::RubyParser do
2
+ it_behaves_like "a stomp_parser parser"
3
+ end
@@ -0,0 +1,9 @@
1
+ describe StompParser do
2
+ specify { defined?(StompParser::VERSION).should be_true }
3
+
4
+ describe ".max_frame_size" do
5
+ it "has a sane default value" do
6
+ StompParser.max_frame_size.should be_a(Fixnum)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,268 @@
1
+ # encoding: UTF-8
2
+ RSpec.shared_examples_for "a stomp_parser parser" do
3
+ let(:parser) { described_class.new }
4
+
5
+ context "#parse" do
6
+ def parse_all(data)
7
+ frames = []
8
+ parser.parse(data) { |m| frames << m }
9
+ frames
10
+ end
11
+
12
+ it "parses frame as binary" do
13
+ frames = parse_all("CONNECT\n\n\x00")
14
+ frames.length.should eq(1)
15
+ frames[0].command.encoding.should eq Encoding::BINARY
16
+ end
17
+
18
+ context "command" do
19
+ it "can parse commands" do
20
+ frames = parse_all("CONNECT\n\n\x00")
21
+ frames.length.should eq(1)
22
+ frames[0].command.should eq("CONNECT")
23
+ end
24
+ end
25
+
26
+ context "headers" do
27
+ it "can parse simple headers" do
28
+ frames = parse_all("CONNECT\nmoo:cow\n\n\x00")
29
+ frames.length.should eq(1)
30
+ frames[0].headers.should eq("moo" => "cow")
31
+ end
32
+
33
+ it "can parse multiple headers" do
34
+ frames = parse_all("CONNECT\nmoo:cow\nbaah:sheep\n\n\x00")
35
+ frames.length.should eq(1)
36
+ frames[0].headers.should eq("moo" => "cow", "baah" => "sheep")
37
+ end
38
+
39
+ it "can parse headers with NULLs in them" do
40
+ frames = parse_all("CONNECT\nnull\x00:null\x00\n\n\x00")
41
+ frames.length.should eq(1)
42
+ frames[0].headers.should eq("null\x00" => "null\x00")
43
+ end
44
+
45
+ it "can parse headers with escape characters" do
46
+ frames = parse_all("CONNECT\nnull\\c:\\r\\n\\c\\\\\n\n\x00")
47
+ frames.length.should eq(1)
48
+ frames[0].headers.should eq("null:" => "\r\n:\\")
49
+ end
50
+
51
+ it "can parse headers with no value" do
52
+ frames = parse_all("CONNECT\nmoo:\n\n\x00")
53
+ frames.length.should eq(1)
54
+ frames[0].headers.should eq("moo" => nil)
55
+ end
56
+
57
+ it "nullifies previous headers" do
58
+ frames = parse_all("CONNECT\nmoo:\nmoo:hello\n\n\x00")
59
+ frames.length.should eq(1)
60
+ frames[0].headers.should eq("moo" => nil)
61
+ end
62
+
63
+ it "prioritises first header when given multiple of same key" do
64
+ frames = parse_all("CONNECT\nkey:first\nkey:second\n\n\x00")
65
+ frames.length.should eq(1)
66
+ frames[0].headers.should eq("key" => "first")
67
+ end
68
+
69
+ it "parses multibyte headers as UTF-8 even if content type specifies something else" do
70
+ frames = parse_all("MESSAGE\ncontent-type:text/plain;charset=ISO-8859-1\nwhät:üp\n\n\x00")
71
+ frames.length.should eq(1)
72
+
73
+ key, value = frames[0].headers.to_a[1]
74
+
75
+ key.should eq "wh\xC3\xA4t".force_encoding("UTF-8")
76
+ key.encoding.should eq Encoding::UTF_8
77
+
78
+ value.should eq "\xC3\xBCp".force_encoding("UTF-8")
79
+ value.encoding.should eq Encoding::UTF_8
80
+ end
81
+ end
82
+
83
+ context "body" do
84
+ it "can parse body" do
85
+ frames = parse_all("CONNECT\n\nbody\x00")
86
+ frames.length.should eq(1)
87
+ frames[0].body.should eq "body"
88
+ end
89
+
90
+ it "can parse binary body" do
91
+ frames = parse_all("CONNECT\ncontent-length:5\n\nbo\x00dy\x00")
92
+ frames.length.should eq(1)
93
+ frames[0].body.should eq "bo\x00dy"
94
+ end
95
+
96
+ it "parses body as binary string when no content-type given" do
97
+ frames = parse_all("MESSAGE\n\nWhat üp\x00")
98
+ frames.length.should eq(1)
99
+ frames[0].body.should eq "What \xC3\xBCp".force_encoding("BINARY")
100
+ frames[0].body.encoding.should eq Encoding::BINARY
101
+ end
102
+
103
+ it "parses body as encoded string when content-type is a text type and charset is given" do
104
+ frames = parse_all("MESSAGE\ncontent-type:text/plain;charset=ISO-8859-1\n\nWhat \xFCp\x00")
105
+ frames.length.should eq(1)
106
+ frames[0].body.should eq "What \xFCp".force_encoding("iso-8859-1")
107
+ frames[0].body.encoding.should eq Encoding::ISO_8859_1
108
+ end
109
+
110
+ it "parses body as encoded string when content-type is not a text type and charset is given" do
111
+ frames = parse_all("MESSAGE\ncontent-type:application/octet-stream;charset=ISO-8859-1\n\nWhat \xFCp\x00")
112
+ frames.length.should eq(1)
113
+ frames[0].body.should eq "What \xFCp".force_encoding("iso-8859-1")
114
+ frames[0].body.encoding.should eq Encoding::ISO_8859_1
115
+ end
116
+
117
+ it "parses body as utf-8 encoded string when content-type is a text type and charset is not given" do
118
+ frames = parse_all("MESSAGE\ncontent-type:text/plain\n\nWhat üp\x00")
119
+ frames.length.should eq(1)
120
+ frames[0].body.should eq "What \xC3\xBCp".force_encoding("UTF-8")
121
+ frames[0].body.encoding.should eq Encoding::UTF_8
122
+ end
123
+
124
+ it "parses body as binary string when content-type is not a text type and charset is not given" do
125
+ frames = parse_all("MESSAGE\ncontent-type:application/octet-stream\n\nWhat \xFCp\x00")
126
+ frames.length.should eq(1)
127
+ frames[0].body.should eq "What \xFCp".force_encoding("BINARY")
128
+ frames[0].body.encoding.should eq Encoding::BINARY
129
+ end
130
+ end
131
+
132
+ context "multiple frames" do
133
+ it "yields multiple frames in a single invocation" do
134
+ frames = parse_all("CONNECT\n\n\x00CONNECT\n\n\x00CONNECT\n\n\x00")
135
+ frames.length.should eq(3)
136
+ frames.map(&:command).should eq %w[CONNECT CONNECT CONNECT]
137
+ frames.uniq.length.should eq(3)
138
+ end
139
+
140
+ it "allows newlines between frames" do
141
+ frames = parse_all("\n\r\n\nCONNECT\n\n\x00\n\n\r\nCONNECT\n\n\x00\n\n")
142
+ frames.length.should eq(2)
143
+ frames.map(&:command).should eq %w[CONNECT CONNECT]
144
+ frames.uniq.length.should eq(2)
145
+ end
146
+ end
147
+
148
+ context "multiple invocations" do
149
+ it "parses simple split up frames" do
150
+ frames = parse_all("CONNECT\n")
151
+ frames.should be_empty
152
+
153
+ frames = parse_all("\n\x00")
154
+ frames.length.should eq(1)
155
+ frames[0].command.should eq "CONNECT"
156
+ end
157
+
158
+ it "parses frames split across buffer markings" do
159
+ frames = parse_all("\n\nCONN")
160
+ frames.should be_empty
161
+
162
+ frames = parse_all("ECT\n\n\x00")
163
+ frames.length.should eq(1)
164
+ frames[0].command.should eq "CONNECT"
165
+ end
166
+
167
+ it "parses frames split across header keys" do
168
+ frames = parse_all("CONNECT\nheader:")
169
+ frames.should be_empty
170
+
171
+ frames = parse_all("value\n\n\x00")
172
+ frames.length.should eq(1)
173
+ frames[0].command.should eq "CONNECT"
174
+ frames[0].headers.should eq("header" => "value")
175
+ end
176
+
177
+ it "parses binary frame split across body" do
178
+ frames = parse_all("CONNECT\ncontent-length:4\n\n\x00a")
179
+ frames.should be_empty
180
+
181
+ frames = parse_all("b\x00\x00")
182
+ frames.length.should eq(1)
183
+ frames[0].command.should eq "CONNECT"
184
+ frames[0].body.should eq("\x00ab\x00")
185
+ end
186
+
187
+ it "parses frames split across frames" do
188
+ frames = parse_all("CONNECT\n")
189
+ frames.should be_empty
190
+
191
+ frames = parse_all("\n\x00CONNEC")
192
+ frames.length.should eq(1)
193
+ frames[0].command.should eq "CONNECT"
194
+
195
+ frames = parse_all("T\n\n\x00")
196
+ frames.length.should eq(1)
197
+ frames[0].command.should eq "CONNECT"
198
+ end
199
+ end
200
+
201
+ context "fails on invalid frames" do
202
+ specify "no block given" do
203
+ expect { parser.parse("CONNECT\n\n\x00") }.to raise_error(LocalJumpError)
204
+ end
205
+
206
+ specify "invalid command" do
207
+ expect { parser.parse("CONNET\n\n\x00") }.to raise_error(StompParser::ParseError)
208
+ end
209
+
210
+ specify "unfinished command" do
211
+ expect { parser.parse("CONNECT\x00") }.to raise_error(StompParser::ParseError)
212
+ end
213
+
214
+ specify "header with colon" do
215
+ expect { parser.parse("CONNECT\nfoo: :bar\n\n\x00") }.to raise_error(StompParser::ParseError)
216
+ end
217
+
218
+ specify "header with invalid escape" do
219
+ expect { parser.parse("CONNECT\nfoo:\\t\n\n\x00") }.to raise_error(StompParser::ParseError)
220
+ end
221
+
222
+ specify "body longer than content length" do
223
+ expect { parser.parse("CONNECT\ncontent-length:0\n\nx\x00") }.to raise_error(StompParser::ParseError)
224
+ end
225
+
226
+ specify "invalid content length" do
227
+ expect { parser.parse("CONNECT\ncontent-length:LAWL\n\nx\x00") }.to raise_error(StompParser::Error, /invalid content length "LAWL"/)
228
+ end
229
+
230
+ specify "re-trying invocation after an error" do
231
+ first_error = begin
232
+ parser.parse("CONNET")
233
+ rescue StompParser::ParseError => ex
234
+ ex
235
+ end
236
+
237
+ first_error.should be_a(StompParser::ParseError)
238
+
239
+ second_error = begin
240
+ parser.parse("")
241
+ rescue StompParser::ParseError => ex
242
+ ex
243
+ end
244
+
245
+ second_error.should eql(first_error)
246
+ end
247
+
248
+ specify "total size bigger than global max frame size setting" do
249
+ StompParser.stub(:max_frame_size => 30)
250
+ parser = described_class.new
251
+ parser.parse("CONNECT\n") # 8
252
+ parser.parse("header:value\n") # 21
253
+ expect {
254
+ parser.parse("other:val\n") # 31
255
+ }.to raise_error(StompParser::FrameSizeExceeded)
256
+ end
257
+
258
+ specify "total size bigger than local max frame size setting" do
259
+ parser = described_class.new(max_frame_size = 30)
260
+ parser.parse("CONNECT\n") # 8
261
+ parser.parse("header:value\n") # 21
262
+ expect {
263
+ parser.parse("other:val\n") # 31
264
+ }.to raise_error(StompParser::FrameSizeExceeded)
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'stomp_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "stomp_parser"
8
+ spec.version = StompParser::VERSION
9
+ spec.authors = ["Kim Burgestrand", "Jonas Nicklas"]
10
+ spec.email = ["kim@burgestrand.se", "jonas.nicklas@gmail.com"]
11
+ spec.summary = %q{STOMP frame parser.}
12
+ spec.homepage = "https://github.com/stompede/stomp_parser"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.files += ["lib/stomp_parser/ruby_parser.rb"]
17
+ spec.files += ["ext/stomp_parser/c_parser.c"]
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+ spec.extensions = %w[ext/stomp_parser/extconf.rb]
22
+
23
+ spec.add_development_dependency "bundler", "~> 0"
24
+ spec.add_development_dependency "rake", "~> 0"
25
+ spec.add_development_dependency "rake-compiler", "~> 0"
26
+ spec.add_development_dependency "rspec", "~> 0"
27
+ spec.add_development_dependency "pry", "~> 0"
28
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stomp_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: universal-java
6
+ authors:
7
+ - Kim Burgestrand
8
+ - Jonas Nicklas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake-compiler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description:
85
+ email:
86
+ - kim@burgestrand.se
87
+ - jonas.nicklas@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".rspec"
94
+ - ".travis.yml"
95
+ - Brewfile
96
+ - Gemfile
97
+ - MIT-LICENSE.txt
98
+ - README.md
99
+ - Rakefile
100
+ - ext/java/stomp_parser/JavaParser.java.rl
101
+ - ext/java/stomp_parser/JavaParserService.java
102
+ - ext/stomp_parser/c_parser.c
103
+ - ext/stomp_parser/c_parser.c.rl
104
+ - ext/stomp_parser/extconf.rb
105
+ - lib/stomp_parser.rb
106
+ - lib/stomp_parser/error.rb
107
+ - lib/stomp_parser/frame.rb
108
+ - lib/stomp_parser/java_parser.jar
109
+ - lib/stomp_parser/ruby_parser.rb
110
+ - lib/stomp_parser/ruby_parser.rb.rl
111
+ - lib/stomp_parser/version.rb
112
+ - parser_common.rl
113
+ - spec/bench_helper.rb
114
+ - spec/benchmarks/message_bench.rb
115
+ - spec/benchmarks/parser_bench.rb
116
+ - spec/profile.rb
117
+ - spec/profile/.gitkeep
118
+ - spec/spec_helper.rb
119
+ - spec/stomp_parser/c_parser_spec.rb
120
+ - spec/stomp_parser/java_parser_spec.rb
121
+ - spec/stomp_parser/message_spec.rb
122
+ - spec/stomp_parser/ruby_parser_spec.rb
123
+ - spec/stomp_parser_spec.rb
124
+ - spec/support/shared_parser_examples.rb
125
+ - stomp_parser.gemspec
126
+ homepage: https://github.com/stompede/stomp_parser
127
+ licenses:
128
+ - MIT
129
+ metadata: {}
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubyforge_project:
146
+ rubygems_version: 2.2.0.rc.1
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: STOMP frame parser.
150
+ test_files:
151
+ - spec/bench_helper.rb
152
+ - spec/benchmarks/message_bench.rb
153
+ - spec/benchmarks/parser_bench.rb
154
+ - spec/profile.rb
155
+ - spec/profile/.gitkeep
156
+ - spec/spec_helper.rb
157
+ - spec/stomp_parser/c_parser_spec.rb
158
+ - spec/stomp_parser/java_parser_spec.rb
159
+ - spec/stomp_parser/message_spec.rb
160
+ - spec/stomp_parser/ruby_parser_spec.rb
161
+ - spec/stomp_parser_spec.rb
162
+ - spec/support/shared_parser_examples.rb