http_parser.rb 0.5.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gitignore +11 -0
  2. data/.gitmodules +6 -0
  3. data/README.md +45 -0
  4. data/Rakefile +6 -0
  5. data/bench/thin.rb +57 -0
  6. data/ext/ruby_http_parser/.gitignore +1 -0
  7. data/ext/ruby_http_parser/RubyHttpParserService.java +18 -0
  8. data/ext/ruby_http_parser/ext_help.h +18 -0
  9. data/ext/ruby_http_parser/extconf.rb +16 -0
  10. data/ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java +403 -0
  11. data/ext/ruby_http_parser/ruby_http_parser.c +474 -0
  12. data/ext/ruby_http_parser/vendor/.gitkeep +0 -0
  13. data/ext/ruby_http_parser/vendor/http-parser-java/CONTRIBUTIONS +4 -0
  14. data/ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT +19 -0
  15. data/ext/ruby_http_parser/vendor/http-parser-java/README.md +171 -0
  16. data/ext/ruby_http_parser/vendor/http-parser-java/TODO +19 -0
  17. data/ext/ruby_http_parser/vendor/http-parser-java/compile +1 -0
  18. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.c +1590 -0
  19. data/ext/ruby_http_parser/vendor/http-parser-java/http_parser.h +167 -0
  20. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java +7 -0
  21. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java +90 -0
  22. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java +31 -0
  23. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java +13 -0
  24. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java +5 -0
  25. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java +25 -0
  26. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java +7 -0
  27. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java +1894 -0
  28. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java +78 -0
  29. data/ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/Util.java +112 -0
  30. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java +487 -0
  31. data/ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java +115 -0
  32. data/ext/ruby_http_parser/vendor/http-parser-java/test.c +1865 -0
  33. data/ext/ruby_http_parser/vendor/http-parser-java/test_permutations +1 -0
  34. data/ext/ruby_http_parser/vendor/http-parser-java/test_unit +1 -0
  35. data/ext/ruby_http_parser/vendor/http-parser-java/tests.dumped +539 -0
  36. data/ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb +6 -0
  37. data/ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb +13 -0
  38. data/ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb +15 -0
  39. data/ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb +33 -0
  40. data/ext/ruby_http_parser/vendor/http-parser/CONTRIBUTIONS +4 -0
  41. data/ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT +19 -0
  42. data/ext/ruby_http_parser/vendor/http-parser/README.md +171 -0
  43. data/ext/ruby_http_parser/vendor/http-parser/http_parser.c +1590 -0
  44. data/ext/ruby_http_parser/vendor/http-parser/http_parser.h +167 -0
  45. data/ext/ruby_http_parser/vendor/http-parser/test.c +1755 -0
  46. data/http_parser.rb.gemspec +15 -0
  47. data/lib/http/parser.rb +1 -0
  48. data/lib/http_parser.rb +4 -0
  49. data/lib/ruby_http_parser.rb +2 -0
  50. data/spec/parser_spec.rb +187 -0
  51. data/spec/spec_helper.rb +2 -0
  52. data/spec/support/requests.json +381 -0
  53. data/spec/support/responses.json +186 -0
  54. data/tasks/compile.rake +39 -0
  55. data/tasks/spec.rake +5 -0
  56. data/tasks/submodules.rake +7 -0
  57. metadata +124 -0
@@ -0,0 +1,186 @@
1
+ [
2
+ {
3
+ "name": "google 301",
4
+ "type": "HTTP_RESPONSE",
5
+ "raw": "HTTP/1.1 301 Moved Permanently\r\nLocation: http://www.google.com/\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Sun, 26 Apr 2009 11:11:49 GMT\r\nExpires: Tue, 26 May 2009 11:11:49 GMT\r\nCache-Control: public, max-age=2592000\r\nServer: gws\r\nContent-Length: 219\r\n\r\n<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.com/\">here</A>.\r\n</BODY></HTML>\r\n",
6
+ "should_keep_alive": true,
7
+ "message_complete_on_eof": false,
8
+ "http_major": 1,
9
+ "http_minor": 1,
10
+ "status_code": 301,
11
+ "num_headers": 7,
12
+ "headers": {
13
+ "Location": "http://www.google.com/",
14
+ "Content-Type": "text/html; charset=UTF-8",
15
+ "Date": "Sun, 26 Apr 2009 11:11:49 GMT",
16
+ "Expires": "Tue, 26 May 2009 11:11:49 GMT",
17
+ "Cache-Control": "public, max-age=2592000",
18
+ "Server": "gws",
19
+ "Content-Length": "219"
20
+ },
21
+ "body": "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\nThe document has moved\n<A HREF=\"http://www.google.com/\">here</A>.\r\n</BODY></HTML>\r\n"
22
+ },
23
+ {
24
+ "name": "no content-length response",
25
+ "type": "HTTP_RESPONSE",
26
+ "raw": "HTTP/1.1 200 OK\r\nDate: Tue, 04 Aug 2009 07:59:32 GMT\r\nServer: Apache\r\nX-Powered-By: Servlet/2.5 JSP/2.1\r\nContent-Type: text/xml; charset=utf-8\r\nConnection: close\r\n\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <SOAP-ENV:Body>\n <SOAP-ENV:Fault>\n <faultcode>SOAP-ENV:Client</faultcode>\n <faultstring>Client Error</faultstring>\n </SOAP-ENV:Fault>\n </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>",
27
+ "should_keep_alive": false,
28
+ "message_complete_on_eof": true,
29
+ "http_major": 1,
30
+ "http_minor": 1,
31
+ "status_code": 200,
32
+ "num_headers": 5,
33
+ "headers": {
34
+ "Date": "Tue, 04 Aug 2009 07:59:32 GMT",
35
+ "Server": "Apache",
36
+ "X-Powered-By": "Servlet/2.5 JSP/2.1",
37
+ "Content-Type": "text/xml; charset=utf-8",
38
+ "Connection": "close"
39
+ },
40
+ "body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <SOAP-ENV:Body>\n <SOAP-ENV:Fault>\n <faultcode>SOAP-ENV:Client</faultcode>\n <faultstring>Client Error</faultstring>\n </SOAP-ENV:Fault>\n </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>"
41
+ },
42
+ {
43
+ "name": "404 no headers no body",
44
+ "type": "HTTP_RESPONSE",
45
+ "raw": "HTTP/1.1 404 Not Found\r\n\r\n",
46
+ "should_keep_alive": true,
47
+ "message_complete_on_eof": false,
48
+ "http_major": 1,
49
+ "http_minor": 1,
50
+ "status_code": 404,
51
+ "num_headers": 0,
52
+ "headers": {
53
+
54
+ },
55
+ "body_size": 0,
56
+ "body": ""
57
+ },
58
+ {
59
+ "name": "301 no response phrase",
60
+ "type": "HTTP_RESPONSE",
61
+ "raw": "HTTP/1.1 301\r\n\r\n",
62
+ "should_keep_alive": true,
63
+ "message_complete_on_eof": false,
64
+ "http_major": 1,
65
+ "http_minor": 1,
66
+ "status_code": 301,
67
+ "num_headers": 0,
68
+ "headers": {
69
+
70
+ },
71
+ "body": ""
72
+ },
73
+ {
74
+ "name": "200 trailing space on chunked body",
75
+ "type": "HTTP_RESPONSE",
76
+ "raw": "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nTransfer-Encoding: chunked\r\n\r\n25 \r\nThis is the data in the first chunk\r\n\r\n1C\r\nand this is the second one\r\n\r\n0 \r\n\r\n",
77
+ "should_keep_alive": true,
78
+ "message_complete_on_eof": false,
79
+ "http_major": 1,
80
+ "http_minor": 1,
81
+ "status_code": 200,
82
+ "num_headers": 2,
83
+ "headers": {
84
+ "Content-Type": "text/plain",
85
+ "Transfer-Encoding": "chunked"
86
+ },
87
+ "body_size": 65,
88
+ "body": "This is the data in the first chunk\r\nand this is the second one\r\n"
89
+ },
90
+ {
91
+ "name": "no carriage ret",
92
+ "type": "HTTP_RESPONSE",
93
+ "raw": "HTTP/1.1 200 OK\nContent-Type: text/html; charset=utf-8\nConnection: close\n\nthese headers are from http://news.ycombinator.com/",
94
+ "should_keep_alive": false,
95
+ "message_complete_on_eof": true,
96
+ "http_major": 1,
97
+ "http_minor": 1,
98
+ "status_code": 200,
99
+ "num_headers": 2,
100
+ "headers": {
101
+ "Content-Type": "text/html; charset=utf-8",
102
+ "Connection": "close"
103
+ },
104
+ "body": "these headers are from http://news.ycombinator.com/"
105
+ },
106
+ {
107
+ "name": "proxy connection",
108
+ "type": "HTTP_RESPONSE",
109
+ "raw": "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 11\r\nProxy-Connection: close\r\nDate: Thu, 31 Dec 2009 20:55:48 +0000\r\n\r\nhello world",
110
+ "should_keep_alive": false,
111
+ "message_complete_on_eof": false,
112
+ "http_major": 1,
113
+ "http_minor": 1,
114
+ "status_code": 200,
115
+ "num_headers": 4,
116
+ "headers": {
117
+ "Content-Type": "text/html; charset=UTF-8",
118
+ "Content-Length": "11",
119
+ "Proxy-Connection": "close",
120
+ "Date": "Thu, 31 Dec 2009 20:55:48 +0000"
121
+ },
122
+ "body": "hello world"
123
+ },
124
+ {
125
+ "name": "underscore header key",
126
+ "type": "HTTP_RESPONSE",
127
+ "raw": "HTTP/1.1 200 OK\r\nServer: DCLK-AdSvr\r\nContent-Type: text/xml\r\nContent-Length: 0\r\nDCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n",
128
+ "should_keep_alive": true,
129
+ "message_complete_on_eof": false,
130
+ "http_major": 1,
131
+ "http_minor": 1,
132
+ "status_code": 200,
133
+ "num_headers": 4,
134
+ "headers": {
135
+ "Server": "DCLK-AdSvr",
136
+ "Content-Type": "text/xml",
137
+ "Content-Length": "0",
138
+ "DCLK_imp": "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o"
139
+ },
140
+ "body": ""
141
+ },
142
+ {
143
+ "name": "bonjourmadame.fr",
144
+ "type": "HTTP_RESPONSE",
145
+ "raw": "HTTP/1.0 301 Moved Permanently\r\nDate: Thu, 03 Jun 2010 09:56:32 GMT\r\nServer: Apache/2.2.3 (Red Hat)\r\nCache-Control: public\r\nPragma: \r\nLocation: http://www.bonjourmadame.fr/\r\nVary: Accept-Encoding\r\nContent-Length: 0\r\nContent-Type: text/html; charset=UTF-8\r\nConnection: keep-alive\r\n\r\n",
146
+ "should_keep_alive": true,
147
+ "message_complete_on_eof": false,
148
+ "http_major": 1,
149
+ "http_minor": 0,
150
+ "status_code": 301,
151
+ "num_headers": 9,
152
+ "headers": {
153
+ "Date": "Thu, 03 Jun 2010 09:56:32 GMT",
154
+ "Server": "Apache/2.2.3 (Red Hat)",
155
+ "Cache-Control": "public",
156
+ "Pragma": "",
157
+ "Location": "http://www.bonjourmadame.fr/",
158
+ "Vary": "Accept-Encoding",
159
+ "Content-Length": "0",
160
+ "Content-Type": "text/html; charset=UTF-8",
161
+ "Connection": "keep-alive"
162
+ },
163
+ "body": ""
164
+ },
165
+ {
166
+ "name": "field space",
167
+ "type": "HTTP_RESPONSE",
168
+ "raw": "HTTP/1.1 200 OK\r\nServer: Microsoft-IIS/6.0\r\nX-Powered-By: ASP.NET\r\nen-US Content-Type: text/xml\r\nContent-Type: text/xml\r\nContent-Length: 16\r\nDate: Fri, 23 Jul 2010 18:45:38 GMT\r\nConnection: keep-alive\r\n\r\n<xml>hello</xml>",
169
+ "should_keep_alive": true,
170
+ "message_complete_on_eof": false,
171
+ "http_major": 1,
172
+ "http_minor": 1,
173
+ "status_code": 200,
174
+ "num_headers": 7,
175
+ "headers": {
176
+ "Server": "Microsoft-IIS/6.0",
177
+ "X-Powered-By": "ASP.NET",
178
+ "en-US Content-Type": "text/xml",
179
+ "Content-Type": "text/xml",
180
+ "Content-Length": "16",
181
+ "Date": "Fri, 23 Jul 2010 18:45:38 GMT",
182
+ "Connection": "keep-alive"
183
+ },
184
+ "body": "<xml>hello</xml>"
185
+ }
186
+ ]
@@ -0,0 +1,39 @@
1
+ require 'rake/gempackagetask'
2
+ require 'rake/extensiontask'
3
+ require 'rake/javaextensiontask'
4
+
5
+ def gemspec
6
+ @clean_gemspec ||= eval(File.read(File.expand_path('../../http_parser.rb.gemspec', __FILE__)))
7
+ end
8
+
9
+ Rake::GemPackageTask.new(gemspec) do |pkg|
10
+ end
11
+
12
+ if RUBY_PLATFORM =~ /java/
13
+ Rake::JavaExtensionTask.new("ruby_http_parser", gemspec)
14
+ else
15
+ Rake::ExtensionTask.new("ruby_http_parser", gemspec) do |ext|
16
+ unless RUBY_PLATFORM =~ /mswin|mingw/
17
+ ext.cross_compile = true
18
+ ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60']
19
+
20
+ # inject 1.8/1.9 pure-ruby entry point
21
+ ext.cross_compiling do |spec|
22
+ spec.files += ['lib/ruby_http_parser.rb']
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ file 'lib/ruby_http_parser.rb' do |t|
29
+ File.open(t.name, 'wb') do |f|
30
+ f.write <<-eoruby
31
+ RUBY_VERSION =~ /(\\d+.\\d+)/
32
+ require "\#{$1}/ruby_http_parser"
33
+ eoruby
34
+ end
35
+ end
36
+
37
+ if Rake::Task.task_defined?(:cross)
38
+ task :cross => 'lib/ruby_http_parser.rb'
39
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,5 @@
1
+ require "rspec/core/rake_task"
2
+
3
+ RSpec::Core::RakeTask.new do |t|
4
+ t.rspec_opts = %w(-fs -c)
5
+ end
@@ -0,0 +1,7 @@
1
+ desc "Fetch upstream submodules"
2
+ task :submodules do
3
+ if Dir['ext/ruby_http_parser/vendor/http-parser/*'].empty?
4
+ sh 'git submodule init'
5
+ sh 'git submodule update'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_parser.rb
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
+ platform: x86-mswin32-60
11
+ authors:
12
+ - Marc-Andre Cournoyer
13
+ - Aman Gupta
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-28 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Ruby bindings to http://github.com/ry/http-parser and http://github.com/a2800276/http-parser.java
23
+ email:
24
+ - macournoyer@gmail.com
25
+ - aman@tmm1.net
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - .gitignore
34
+ - .gitmodules
35
+ - README.md
36
+ - Rakefile
37
+ - bench/thin.rb
38
+ - ext/ruby_http_parser/.gitignore
39
+ - ext/ruby_http_parser/RubyHttpParserService.java
40
+ - ext/ruby_http_parser/ext_help.h
41
+ - ext/ruby_http_parser/extconf.rb
42
+ - ext/ruby_http_parser/org/ruby_http_parser/RubyHttpParser.java
43
+ - ext/ruby_http_parser/ruby_http_parser.c
44
+ - ext/ruby_http_parser/vendor/.gitkeep
45
+ - http_parser.rb.gemspec
46
+ - lib/http/parser.rb
47
+ - lib/http_parser.rb
48
+ - spec/parser_spec.rb
49
+ - spec/spec_helper.rb
50
+ - spec/support/requests.json
51
+ - spec/support/responses.json
52
+ - tasks/compile.rake
53
+ - tasks/spec.rake
54
+ - tasks/submodules.rake
55
+ - ext/ruby_http_parser/vendor/http-parser/CONTRIBUTIONS
56
+ - ext/ruby_http_parser/vendor/http-parser/http_parser.c
57
+ - ext/ruby_http_parser/vendor/http-parser/http_parser.h
58
+ - ext/ruby_http_parser/vendor/http-parser/LICENSE-MIT
59
+ - ext/ruby_http_parser/vendor/http-parser/Makefile
60
+ - ext/ruby_http_parser/vendor/http-parser/README.md
61
+ - ext/ruby_http_parser/vendor/http-parser/test.c
62
+ - ext/ruby_http_parser/vendor/http-parser-java/compile
63
+ - ext/ruby_http_parser/vendor/http-parser-java/CONTRIBUTIONS
64
+ - ext/ruby_http_parser/vendor/http-parser-java/http_parser.c
65
+ - ext/ruby_http_parser/vendor/http-parser-java/http_parser.h
66
+ - ext/ruby_http_parser/vendor/http-parser-java/LICENSE-MIT
67
+ - ext/ruby_http_parser/vendor/http-parser-java/Makefile
68
+ - ext/ruby_http_parser/vendor/http-parser-java/README.md
69
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPException.java
70
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPMethod.java
71
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/HTTPParser.java
72
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPCallback.java
73
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPDataCallback.java
74
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPErrorCallback.java
75
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/HTTPParser.java
76
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/ParserSettings.java
77
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/lolevel/Util.java
78
+ - ext/ruby_http_parser/vendor/http-parser-java/src/impl/http_parser/ParserType.java
79
+ - ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/TestLoaderNG.java
80
+ - ext/ruby_http_parser/vendor/http-parser-java/src/test/http_parser/lolevel/UnitTest.java
81
+ - ext/ruby_http_parser/vendor/http-parser-java/test.c
82
+ - ext/ruby_http_parser/vendor/http-parser-java/test_permutations
83
+ - ext/ruby_http_parser/vendor/http-parser-java/test_unit
84
+ - ext/ruby_http_parser/vendor/http-parser-java/tests.dumped
85
+ - ext/ruby_http_parser/vendor/http-parser-java/TODO
86
+ - ext/ruby_http_parser/vendor/http-parser-java/tools/byte_constants.rb
87
+ - ext/ruby_http_parser/vendor/http-parser-java/tools/const_char.rb
88
+ - ext/ruby_http_parser/vendor/http-parser-java/tools/lowcase.rb
89
+ - ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb
90
+ - lib/1.8/ruby_http_parser.so
91
+ - lib/1.9/ruby_http_parser.so
92
+ - lib/ruby_http_parser.rb
93
+ has_rdoc: true
94
+ homepage: http://github.com/tmm1/http_parser.rb
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options: []
99
+
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.3.6
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: Simple callback-based HTTP request/response parser
123
+ test_files: []
124
+