em-eventsource 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +1 -1
  3. data/lib/em-eventsource.rb +42 -24
  4. metadata +53 -25
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjlhZjYyOTUyZDQwZTE5MjcyYjE0Y2FmOTczMWI3ODk3ZGRhZGNiMA==
5
+ data.tar.gz: !binary |-
6
+ NjhlNjk1ZjgwNTE0YjlkZDUwODM0ZjE4ZGNjYmFlMjA5OTM1NzY2OA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ N2E0NWU5YWNmMWNjYTUzNDA1YjFiOWI1ZTllYzdkOWQ3YjAwOWNkNTk3Yzg0
10
+ Yjg1MzdhMTBiZjIxYTVjZjBkMGJmZDA0NTI0MTc5NWE0ZmRhNDE2Yjc4MjQ4
11
+ OGY4YmZiZDdjM2E4M2I3NGJiNTJhZjQ3YWQxYzVhMGEzMmVkYmU=
12
+ data.tar.gz: !binary |-
13
+ OThjZDhhM2Q3ZGE1ODAzNWU5ZGIwZjUyY2ZhNTNkNDM2ZDg5NzFlNGJjYTc4
14
+ NzA1Y2QzN2IxMjcxNWMzZTJhNmM4MDdjNDQyYmVmYjg1YTE1YWY4NTQ5OTI0
15
+ NTI3MmMzMGM5YjEyMjAzMDI3NmJhNDAwNDkzM2E0YTEwODZkZDU=
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
@@ -28,11 +28,12 @@ module EventMachine
28
28
  OPEN = 1
29
29
  # The connection is not open, and the user agent is not trying to reconnect. Either there was a fatal error or the close() method was invoked.
30
30
  CLOSED = 2
31
+
31
32
  # Create a new stream
32
33
  #
33
- # @param [String] url
34
- # @param [Hash] query
35
- # @param [Hash] headers
34
+ # url - the url as string
35
+ # query - the query string as hash
36
+ # headers - the headers for the request as hash
36
37
  def initialize(url, query={}, headers={})
37
38
  @url = url
38
39
  @query = query
@@ -51,40 +52,56 @@ module EventMachine
51
52
  end
52
53
 
53
54
  # Add open event handler
55
+ #
56
+ # Returns nothing
54
57
  def open(&block)
55
58
  @opens << block
56
59
  end
57
60
 
58
61
  # Add a specific event handler
59
62
  #
60
- # @param [String] name of event
63
+ # name - name of event
64
+ #
65
+ # Returns nothing
61
66
  def on(name, &block)
62
67
  @on[name] ||= []
63
68
  @on[name] << block
64
69
  end
65
70
 
66
71
  # Add message event handler
72
+ #
73
+ # Returns nothing
67
74
  def message(&block)
68
75
  @messages << block
69
76
  end
70
77
 
71
78
  # Add error event handler
79
+ #
80
+ # Returns nothing
72
81
  def error(&block)
73
82
  @errors << block
74
83
  end
75
84
 
76
85
  # Add a middleware
86
+ #
87
+ # *args - the middleware class
88
+ #
89
+ # Returns nothing
77
90
  def use(*args, &block)
78
91
  @middlewares << (args << block)
79
92
  end
80
93
 
81
94
  # Start subscription
95
+ #
96
+ # Returns nothing
82
97
  def start
83
98
  @ready_state = CONNECTING
84
99
  listen
85
100
  end
86
101
 
87
102
  # Cancel subscription
103
+ #
104
+ # Returns nothing
88
105
  def close
89
106
  @ready_state = CLOSED
90
107
  @conn.close('requested') if @conn
@@ -94,27 +111,13 @@ module EventMachine
94
111
 
95
112
  def listen
96
113
  @conn, @req = prepare_request
114
+ @req.headers(&method(:handle_headers))
97
115
  @req.errback(&method(:handle_reconnect))
98
116
  @req.callback(&method(:handle_reconnect))
99
- @req.headers do |headers|
100
- if headers.status != 200
101
- close
102
- @errors.each { |error| error.call("Unexpected response status #{headers.status}") }
103
- next
104
- end
105
- if /^text\/event-stream/.match headers['CONTENT_TYPE']
106
- @ready_state = OPEN
107
- @opens.each { |open| open.call }
108
- else
109
- close
110
- @errors.each { |error| error.call("The content-type '#{headers['CONTENT_TYPE']}' is not text/event-stream") }
111
- end
112
- end
113
117
  buffer = ""
114
118
  @req.stream do |chunk|
115
119
  buffer += chunk
116
- # TODO: manage \r, \r\n, \n
117
- while index = buffer.index("\n\n")
120
+ while index = buffer.index(/\r\n\r\n|\n\n/)
118
121
  stream = buffer.slice!(0..index)
119
122
  handle_stream(stream)
120
123
  end
@@ -130,10 +133,25 @@ module EventMachine
130
133
  end
131
134
  end
132
135
 
136
+ def handle_headers(headers)
137
+ if headers.status != 200
138
+ close
139
+ @errors.each { |error| error.call("Unexpected response status #{headers.status}") }
140
+ return
141
+ end
142
+ if /^text\/event-stream/.match headers['CONTENT_TYPE']
143
+ @ready_state = OPEN
144
+ @opens.each { |open| open.call }
145
+ else
146
+ close
147
+ @errors.each { |error| error.call("The content-type '#{headers['CONTENT_TYPE']}' is not text/event-stream") }
148
+ end
149
+ end
150
+
133
151
  def handle_stream(stream)
134
152
  data = ""
135
153
  name = nil
136
- stream.split("\n").each do |part|
154
+ stream.split(/\r?\n/).each do |part|
137
155
  /^data:(.+)$/.match(part) do |m|
138
156
  data += m[1].strip
139
157
  data += "\n"
@@ -151,7 +169,7 @@ module EventMachine
151
169
  end
152
170
  end
153
171
  return if data.empty?
154
- data.chomp!("\n")
172
+ data.chomp!
155
173
  if name.nil?
156
174
  @messages.each { |message| message.call(data) }
157
175
  else
@@ -163,9 +181,9 @@ module EventMachine
163
181
  conn = EM::HttpRequest.new(@url, :inactivity_timeout => @inactivity_timeout)
164
182
  @middlewares.each { |middleware|
165
183
  block = middleware.pop
166
- conn.use *middleware, &block
184
+ conn.use(*middleware, &block)
167
185
  }
168
- headers = @headers.merge({'Cache-Control' => 'no-cache'})
186
+ headers = @headers.merge({'Cache-Control' => 'no-cache', 'Accept' => 'text/event-stream'})
169
187
  headers.merge!({'Last-Event-Id' => @last_event_id }) if not @last_event_id.nil?
170
188
  [conn, conn.get({ :query => @query,
171
189
  :head => headers})]
metadata CHANGED
@@ -1,71 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-eventsource
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - François de Metz
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-05-13 00:00:00.000000000Z
11
+ date: 2014-08-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: eventmachine
16
- requirement: &17007600 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ~>
17
+ - - ! '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 1.0.0.beta3
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *17007600
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0.beta3
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: em-http-request
27
- requirement: &17007020 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ~>
31
+ - - ! '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: 1.0.0
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *17007020
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: minitest
38
- requirement: &17006480 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
40
51
  requirements:
41
- - - ~>
52
+ - - ! '>='
42
53
  - !ruby/object:Gem::Version
43
54
  version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-spec-context
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
44
62
  type: :development
45
63
  prerelease: false
46
- version_requirements: *17006480
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
47
69
  - !ruby/object:Gem::Dependency
48
70
  name: bundler
49
- requirement: &17005880 !ruby/object:Gem::Requirement
50
- none: false
71
+ requirement: !ruby/object:Gem::Requirement
51
72
  requirements:
52
73
  - - ! '>='
53
74
  - !ruby/object:Gem::Version
54
75
  version: '0'
55
76
  type: :development
56
77
  prerelease: false
57
- version_requirements: *17005880
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
58
83
  - !ruby/object:Gem::Dependency
59
84
  name: rake
60
- requirement: &17005080 !ruby/object:Gem::Requirement
61
- none: false
85
+ requirement: !ruby/object:Gem::Requirement
62
86
  requirements:
63
87
  - - ! '>='
64
88
  - !ruby/object:Gem::Version
65
89
  version: '0'
66
90
  type: :development
67
91
  prerelease: false
68
- version_requirements: *17005080
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description: ! " em-eventsource is an eventmachine library to consume Server-Sent
70
98
  Events streaming API.\n You can find the specification here: http://dev.w3.org/html5/eventsource/\n"
71
99
  email: francois@2metz.fr
@@ -79,27 +107,27 @@ files:
79
107
  - lib/em-eventsource.rb
80
108
  homepage: http://github.com/AF83/em-eventsource
81
109
  licenses: []
110
+ metadata: {}
82
111
  post_install_message:
83
112
  rdoc_options: []
84
113
  require_paths:
85
114
  - lib
86
115
  required_ruby_version: !ruby/object:Gem::Requirement
87
- none: false
88
116
  requirements:
89
117
  - - ! '>='
90
118
  - !ruby/object:Gem::Version
91
119
  version: '0'
92
120
  required_rubygems_version: !ruby/object:Gem::Requirement
93
- none: false
94
121
  requirements:
95
122
  - - ! '>='
96
123
  - !ruby/object:Gem::Version
97
124
  version: '0'
98
125
  requirements: []
99
126
  rubyforge_project:
100
- rubygems_version: 1.8.10
127
+ rubygems_version: 2.0.7
101
128
  signing_key:
102
- specification_version: 3
129
+ specification_version: 4
103
130
  summary: em-eventsource is an eventmachine library to consume Server-Sent Events streaming
104
131
  API.
105
132
  test_files: []
133
+ has_rdoc: