firering 0.1.0

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.
Files changed (61) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +83 -0
  3. data/Rakefile +143 -0
  4. data/bin/campf-notify +56 -0
  5. data/examples/authenticate.rb +22 -0
  6. data/examples/events.rb +39 -0
  7. data/examples/recent_messages.rb +43 -0
  8. data/examples/rooms.rb +24 -0
  9. data/examples/update_room.rb +33 -0
  10. data/firering.gemspec +99 -0
  11. data/lib/firering/data/message.rb +29 -0
  12. data/lib/firering/data/room.rb +13 -0
  13. data/lib/firering/data/upload.rb +5 -0
  14. data/lib/firering/data/user.rb +16 -0
  15. data/lib/firering/data.rb +35 -0
  16. data/lib/firering/http.rb +43 -0
  17. data/lib/firering/requests.rb +185 -0
  18. data/lib/firering/streaming.rb +51 -0
  19. data/lib/firering.rb +21 -0
  20. data/spec/firering/data_spec.rb +21 -0
  21. data/spec/firering/requests_spec.rb +203 -0
  22. data/spec/fixtures/headers/delete_messages_ID_star.json +30 -0
  23. data/spec/fixtures/headers/get_room_ID.json +30 -0
  24. data/spec/fixtures/headers/get_room_ID_live.json +7 -0
  25. data/spec/fixtures/headers/get_room_ID_recent.json +30 -0
  26. data/spec/fixtures/headers/get_room_ID_transcript.json +30 -0
  27. data/spec/fixtures/headers/get_room_ID_transcript_ID_ID_ID.json +30 -0
  28. data/spec/fixtures/headers/get_room_ID_uploads.json +30 -0
  29. data/spec/fixtures/headers/get_rooms.json +30 -0
  30. data/spec/fixtures/headers/get_search_harmless.json +30 -0
  31. data/spec/fixtures/headers/get_users_ID.json +30 -0
  32. data/spec/fixtures/headers/get_users_me.json +30 -0
  33. data/spec/fixtures/headers/post_messages_ID_star.json +30 -0
  34. data/spec/fixtures/headers/post_room_ID_join.json +28 -0
  35. data/spec/fixtures/headers/post_room_ID_leave.json +28 -0
  36. data/spec/fixtures/headers/post_room_ID_speak.json +30 -0
  37. data/spec/fixtures/headers/post_room_ID_unlock.json +28 -0
  38. data/spec/fixtures/headers/put_room_ID.json +28 -0
  39. data/spec/fixtures/json/delete_messages_ID_star.json +1 -0
  40. data/spec/fixtures/json/get_room_ID.json +1 -0
  41. data/spec/fixtures/json/get_room_ID_live.json +1 -0
  42. data/spec/fixtures/json/get_room_ID_recent.json +33 -0
  43. data/spec/fixtures/json/get_room_ID_transcript.json +33 -0
  44. data/spec/fixtures/json/get_room_ID_transcript_ID_ID_ID.json +33 -0
  45. data/spec/fixtures/json/get_room_ID_uploads.json +1 -0
  46. data/spec/fixtures/json/get_rooms.json +2 -0
  47. data/spec/fixtures/json/get_search_harmless.json +3 -0
  48. data/spec/fixtures/json/get_users_ID.json +1 -0
  49. data/spec/fixtures/json/get_users_me.json +1 -0
  50. data/spec/fixtures/json/post_messages_ID_star.json +1 -0
  51. data/spec/fixtures/json/post_room_ID_join.json +1 -0
  52. data/spec/fixtures/json/post_room_ID_leave.json +1 -0
  53. data/spec/fixtures/json/post_room_ID_lock.json +1 -0
  54. data/spec/fixtures/json/post_room_ID_speak.json +1 -0
  55. data/spec/fixtures/json/post_room_ID_unlock.json +1 -0
  56. data/spec/fixtures/json/put_room_ID.json +1 -0
  57. data/spec/fixtures/load_server.rb +31 -0
  58. data/spec/fixtures/retrieve.rb +55 -0
  59. data/spec/fixtures/server.rb +40 -0
  60. data/spec/spec_helper.rb +10 -0
  61. metadata +231 -0
@@ -0,0 +1,43 @@
1
+ module Firering
2
+ module HTTP
3
+ extend self
4
+
5
+ attr_accessor :host
6
+
7
+ HTTP.host = "campfirenow.com"
8
+
9
+ # helper to perform an http request following redirects
10
+ def http(method, path, data = nil, user = Firering.token, password = "X", &block)
11
+
12
+ if (path =~ /^http/)
13
+ url = path
14
+ else
15
+ # handle nil subdomain for testing (e.g a fake localhost campfire server)
16
+ url = "http://#{[Firering.subdomain, HTTP.host].compact.join(".")}#{path}"
17
+ end
18
+
19
+ parameters = { :head => {'authorization' => [user, password], "Content-Type" => "application/json" } }
20
+ parameters.merge!(:body => data.is_a?(String) ? data : Yajl::Encoder.encode(data)) if data
21
+
22
+ http = EventMachine::HttpRequest.new(url).send method, parameters
23
+
24
+ http.errback do
25
+ raise Firering::Error, "#{http.errors}\n#{url}, #{method}, #{parameters.inspect}\n#{http.response_header.status}\n#{http.response}"
26
+ end
27
+
28
+ http.callback do
29
+ case http.response_header.status.to_s
30
+ when /^2../
31
+ block.call(http)
32
+ when "302"
33
+ http(method, http.response_header["Location"], user, password, &block) # follow redirects
34
+ else
35
+ raise Firering::Error, "#{http.errors}\n#{url}, #{method}, #{parameters.inspect}\n#{http.response_header.status}\n#{http.response}"
36
+ end
37
+ end
38
+
39
+ http
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,185 @@
1
+ module Firering
2
+ include Firering::HTTP
3
+ include Firering::Streaming
4
+
5
+ extend self
6
+
7
+ attr_accessor :token, :subdomain
8
+
9
+ # calls /users/me route on campfire to get the authenticated user information, including token
10
+ def authenticate(subdomain, user, password, &block)
11
+ Firering.subdomain = subdomain
12
+ user("me", user, password) do |user|
13
+ Firering.token = user.token
14
+ block.call(user)
15
+ end
16
+ end
17
+
18
+ # non default user and password parameters are only used when user id is "me"
19
+ # to authenticate the user and get his auth token.
20
+ def user(id, user = Firering.token, password = "X", &block)
21
+ http(:get, "/users/#{id}.json", nil, user, password) do |http|
22
+ user = Firering::User.new(http.response, :user)
23
+ block.call(user)
24
+ end
25
+ end
26
+
27
+ # returns all rooms. For getting the users, each specific room must be queries with Firering.room
28
+ # multi: if true, gets all the users from each room as Firering::User objects
29
+ def rooms(multi = true, &block)
30
+ http(:get, "/rooms.json") do |http|
31
+
32
+ rooms = Yajl::Parser.parse(http.response, :symbolize_keys => true)[:rooms]
33
+ rooms.map! { |room| Firering::Room.new(room) }
34
+
35
+ if multi
36
+ rooms_multi(rooms, &block)
37
+ else
38
+ block.call(rooms)
39
+ end
40
+ end
41
+ end
42
+
43
+ # helper for returning all rooms with all existing users (saves the step of going through each room)
44
+ def rooms_multi(rooms, &block)
45
+ multi = EventMachine::MultiRequest.new
46
+ final_rooms = []
47
+
48
+ rooms.each do |room|
49
+ if room.locked? # can't retrieve aditional info on a locked room.
50
+ final_rooms << room
51
+ else
52
+ multi.add(room(room.id) { |req_room| final_rooms << req_room })
53
+ end
54
+ end
55
+
56
+ multi.callback { block.call(final_rooms) }
57
+ end
58
+
59
+ # Returns an existing room. Also includes all the users currently inside the room.
60
+ def room(id, &block)
61
+ http(:get, "/room/#{id}.json") do |http|
62
+ room = Firering::Room.new(http.response, :room)
63
+ block.call(room)
64
+ end
65
+ end
66
+
67
+ # Updates an existing room. Only admins can rename a room, although any
68
+ # user (except guests) may set the topic. Omitting either tag results in
69
+ # that attribute being ignored. To remove a room topic, simply provide an
70
+ # empty topic tag.
71
+ #
72
+ # update_room "1", "name" => "Name", "topic" => "Topic"
73
+ def update_room(id, data, &block)
74
+ http(:put, "/room/#{id}.json", { :room => data }, &block)
75
+ end
76
+
77
+ # Returns a collection of upto 100 recent messages in the room. Accepts an
78
+ # additional optional parameter ‘limit’ to restrict the number of messages
79
+ # returned.
80
+ def room_recent_messages(id, limit = nil, &block)
81
+ http(:get, "/room/#{id}/recent.json", (limit ? { :limit => limit } : nil)) do |http|
82
+ messages = Yajl::Parser.parse(http.response, :symbolize_keys => true)[:messages]
83
+ messages.map! { |msg| Firering::Message.new(msg) }
84
+ block.call(messages)
85
+ end
86
+ end
87
+
88
+ # Returns all the messages containing the supplied term.
89
+ def search_messages(query, &block)
90
+ http(:get, "/search/#{query}.json") do |http|
91
+ messages = Yajl::Parser.parse(http.response, :symbolize_keys => true)[:messages]
92
+ messages.map! { |msg| Firering::Message.new(msg) }
93
+ block.call(messages)
94
+ end
95
+ end
96
+
97
+ # Returns all the messages sent today to a room.
98
+ def today_messages(room_id, &block)
99
+ http(:get, "/room/#{room_id}/transcript.json") do |http|
100
+ messages = Yajl::Parser.parse(http.response, :symbolize_keys => true)[:messages]
101
+ messages.map! { |msg| Firering::Message.new(msg) }
102
+ block.call(messages)
103
+ end
104
+ end
105
+
106
+ # Returns all the messages sent on a specific date to a room.
107
+ def messages_on(room_id, year, month, day, &block)
108
+ http(:get, "/room/#{room_id}/transcript/#{year}/#{month}/#{day}.xml") do |http|
109
+ messages = Yajl::Parser.parse(http.response, :symbolize_keys => true)[:messages]
110
+ messages.map! { |msg| Firering::Message.new(msg) }
111
+ block.call(messages)
112
+ end
113
+ end
114
+
115
+ # Join a room.
116
+ def room_join(room_id, &block)
117
+ http(:post, "/room/#{room_id}/join.json", &block)
118
+ end
119
+
120
+ # Leave a room.
121
+ def room_leave(room_id, &block)
122
+ http(:post, "/room/#{room_id}/leave.json", &block)
123
+ end
124
+
125
+ # Locks a room.
126
+ def room_lock(room_id, &block)
127
+ http(:post, "/room/#{room_id}/lock.json", &block)
128
+ end
129
+
130
+ # Unlocks a room.
131
+ def room_unlock(room_id, &block)
132
+ http(:post, "/room/#{room_id}/unlock.json", &block)
133
+ end
134
+
135
+ # Sends a new message with the currently authenticated user as the sender.
136
+ # The XML for the new message is returned on a successful request.
137
+ #
138
+ # The valid types are:
139
+ #
140
+ # * TextMessage (regular chat message)
141
+ # * PasteMessage (pre-formatted message, rendered in a fixed-width font)
142
+ # * SoundMessage (plays a sound as determined by the message, which can be either “rimshot”, “crickets”, or “trombone”)
143
+ # * TweetMessage (a Twitter status URL to be fetched and inserted into the chat)
144
+ #
145
+ # If an explicit type is omitted, it will be inferred from the content (e.g.,
146
+ # if the message contains new line characters, it will be considered a paste).
147
+ #
148
+ # :type => "TextMessage", :body => "Hello"
149
+ def speak(room_id, data, &block)
150
+ # Response Status: 201 Created
151
+ http(:post, "/room/#{room_id}/speak.json", "message" => data) do |http|
152
+ block.call(Firering::Message.new(http.response))
153
+ end
154
+ end
155
+
156
+ def text(room_id, text, &block)
157
+ speak(room_id, {:type => "TextMessage", :body => text}, &block)
158
+ end
159
+
160
+ def paste(room_id, paste, &block)
161
+ speak(room_id, {:type => "PasteMessage", :body => paste}, &block)
162
+ end
163
+
164
+ def rimshot(room_id, &block)
165
+ speak(room_id, {:type => "SoundMessage", :body => "rimshot"}, &block)
166
+ end
167
+
168
+ def crickets(room_id, &block)
169
+ speak(room_id, {:type => "SoundMessage", :body => "crickets"}, &block)
170
+ end
171
+
172
+ def trombone(room_id, &block)
173
+ speak(room_id, {:type => "SoundMessage", :body => "trombone"}, &block)
174
+ end
175
+
176
+ def tweet(room_id, tweet_url, &block)
177
+ speak(room_id, {:type => "TweetMessage", :body => tweet_url}, &block)
178
+ end
179
+
180
+ # Highlights a message / Removes a message highlight.
181
+ def highlight_message(message_id, yes_or_no = true, &block)
182
+ http(yes_or_no ? :post : :delete, "/messages/#{message_id}/star.json", &block)
183
+ end
184
+
185
+ end
@@ -0,0 +1,51 @@
1
+ module Firering
2
+ module Streaming
3
+ extend self
4
+
5
+ attr_accessor :protocol, :host, :reconnect_delay
6
+
7
+ Streaming.host = "streaming.campfirenow.com"
8
+ Streaming.protocol = "https"
9
+ Streaming.reconnect_delay = 5
10
+
11
+ # Streaming
12
+ #
13
+ # The Streaming API allows you to monitor a room in real time. The
14
+ # authenticated user must already have joined the room in order to use this
15
+ # API.
16
+ def stream(room_id, url = nil, &block)
17
+ parser = Yajl::Parser.new(:symbolize_keys => true)
18
+
19
+ parser.on_parse_complete = proc do |hash|
20
+ block.call(Firering::Message.new(hash))
21
+ end
22
+
23
+ url ||= "#{Streaming.protocol}://#{Streaming.host}/room/#{room_id}/live.json"
24
+
25
+ params = { :head => {'authorization' => [Firering.token, "X"], "Content-Type" => "application/json" } }
26
+
27
+ http = EventMachine::HttpRequest.new(url).get(params)
28
+
29
+ http.stream { |chunk| parser << chunk }
30
+
31
+ # campfire servers will try to hold the streaming connections open indefinitely.
32
+ # However, API clients must be able to handle occasional timeouts or
33
+ # disruptions. Upon unexpected disconnection, API clients should wait for a
34
+ # few seconds before trying to reconnect. Formats
35
+ http.errback do
36
+ if EventMachine.reactor_running?
37
+ puts "Error: #{http.errors}. Reconnecting in #{Streaming.reconnect_delay} seconds..."
38
+
39
+ EventMachine::add_timer(Streaming.reconnect_delay) do
40
+ puts "reconnecting"
41
+ stream(room_id, url, &block)
42
+ end
43
+ else
44
+ puts "EventMachine loop stopped."
45
+ end
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+
data/lib/firering.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'eventmachine'
2
+ require 'yajl'
3
+ require 'em-http'
4
+ require 'date'
5
+
6
+ module Firering
7
+ VERSION = '0.1.0'
8
+
9
+ class Error < StandardError; end
10
+
11
+ autoload :Data , "firering/data"
12
+
13
+ autoload :User , "firering/data/user"
14
+ autoload :Message , "firering/data/message"
15
+ autoload :Room , "firering/data/room"
16
+ autoload :Upload , "firering/data/upload"
17
+ end
18
+
19
+ require 'firering/http'
20
+ require 'firering/streaming'
21
+ require 'firering/requests'
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ class TestData < Firering::Data
4
+ key :a, :b
5
+ end
6
+
7
+ describe Firering::Data do
8
+
9
+ it "can be initialized from a hash" do
10
+ object = TestData.new({:testdata => { :a => 1, :b => 2}}, :testdata)
11
+ object.a.should == 1
12
+ object.b.should == 2
13
+ end
14
+
15
+ it "can be initialized from a json string" do
16
+ object = TestData.new('{"testdata" : { "a" : 1, "b" : 2}}', :testdata)
17
+ object.a.should == 1
18
+ object.b.should == 2
19
+ end
20
+
21
+ end
@@ -0,0 +1,203 @@
1
+ require 'spec_helper'
2
+ require 'date'
3
+
4
+ Firering::Streaming.protocol = "http"
5
+ Firering::Streaming.host = "localhost:4567"
6
+
7
+ Firering::HTTP.host = "localhost:4567"
8
+
9
+ describe "firering" do
10
+
11
+ it "authenticates a user" do
12
+ EM.run {
13
+ Firering.authenticate(nil, "user", "password") do |user|
14
+ user.token.should == "token"
15
+ EM.stop
16
+ end
17
+ }
18
+ end
19
+
20
+ it "gets a user info" do
21
+ EM.run {
22
+ Firering.user(415731) do |user|
23
+ user.type.should == "Member"
24
+ user.created_at.should == Date.parse("2009/01/27 19:54:36 +0000")
25
+ user.email_address.should == "eoga@mail.com"
26
+ user.should_not be_admin
27
+ user.id.should == 415731
28
+ user.name.should == "Emmanuel"
29
+ EM.stop
30
+ end
31
+ }
32
+ end
33
+
34
+ it "gets a single room" do
35
+ EM.run {
36
+ Firering.room(304355) do |room|
37
+ room.name.should == "test2"
38
+ room.created_at.should == Date.parse("2010/05/29 21:38:02 +0000")
39
+ room.updated_at.should == Date.parse("2010/05/29 21:38:02 +0000")
40
+ room.topic.should == "this and the test room should be deleted by a campfire admin."
41
+ room.should_not be_full
42
+ room.id.should == 304355
43
+ room.should_not be_open_to_guests
44
+ room.membership_limit.should == 12
45
+ room.should_not be_locked
46
+
47
+ room.users.each do |u|
48
+ u.should be_an_instance_of(Firering::User)
49
+ end
50
+
51
+ EM.stop
52
+ end
53
+ }
54
+ end
55
+
56
+ it "gets multiple rooms without performing multiple requests per room" do
57
+ EM.run {
58
+ Firering.rooms(false) do |rooms|
59
+ rooms.each do |room|
60
+ room.should be_an_instance_of(Firering::Room)
61
+ room.users.should be_an_instance_of(Array)
62
+ end
63
+ EM.stop
64
+ end
65
+ }
66
+ end
67
+
68
+ it "gets multiple rooms performing multiple requests per room" do
69
+ EM.run {
70
+ Firering.rooms do |rooms|
71
+ rooms.each do |room|
72
+ room.should be_an_instance_of(Firering::Room)
73
+ room.users.should be_an_instance_of(Array)
74
+ end
75
+
76
+ EM.stop
77
+ end
78
+ }
79
+ end
80
+
81
+ it "updates a room and then calls the block" do
82
+ EM.run {
83
+ Firering.update_room(304355, :topic => "some topic") do
84
+ EM.stop
85
+ end
86
+ }
87
+ end
88
+
89
+ it "gets a collection of recent messages" do
90
+ EM.run {
91
+ Firering.room_recent_messages(304355) do |messages|
92
+
93
+ messages.each do |m|
94
+ m.should be_an_instance_of(Firering::Message)
95
+ end
96
+
97
+ message = messages.first
98
+ message.should be_timestamp
99
+ message.room_id.should == 304355
100
+ message.created_at.should == Date.parse("2010/05/29 22:05:00 +0000")
101
+ message.body.should be_nil
102
+ message.id.should == 224587718
103
+ message.user_id.should be_nil
104
+
105
+ EM.stop
106
+ end
107
+ }
108
+ end
109
+
110
+ it "returns a collection of messages matching certain pattern" do
111
+ EM.run {
112
+ Firering.search_messages("harmless") do |messages|
113
+
114
+ messages.length.should == 3
115
+
116
+ messages.each do |m|
117
+ m.should be_an_instance_of(Firering::Message)
118
+ end
119
+
120
+ message = messages.last
121
+ message.should be_text
122
+ message.room_id.should == 177718
123
+ message.created_at.should == Date.parse("2009/06/02 21:20:32 +0000")
124
+ message.body.should == "q: should i add :case_sensitive =\u003E false to the validation of title name? Looks harmless but who knows..."
125
+ message.id.should == 134405854
126
+ message.user_id.should == 415731
127
+
128
+ EM.stop
129
+ end
130
+ }
131
+ end
132
+
133
+ it "returns the messages of today for a given room" do
134
+ EM.run {
135
+ Firering.today_messages(304355) do |messages|
136
+
137
+ messages.length.should == 33
138
+
139
+ messages.each do |m|
140
+ m.should be_an_instance_of(Firering::Message)
141
+ end
142
+
143
+ message = messages.last
144
+
145
+ message.should be_paste
146
+ message.room_id.should == 304355
147
+ message.created_at.should == Date.parse("2010/05/29 22:41:34 +0000")
148
+ message.body.should == "paste\ntext"
149
+ message.id.should == 224590114
150
+ message.user_id.should == 415731
151
+
152
+ EM.stop
153
+ end
154
+ }
155
+ end
156
+
157
+ it "joins a room an call a block" do
158
+ EM.run { Firering.room_join(304355) { EM.stop } }
159
+ end
160
+
161
+ it "leaves a room an call a block" do
162
+ EM.run { Firering.room_leave(304355) { EM.stop } }
163
+ end
164
+
165
+ it "unlocks a room an call a block" do
166
+ EM.run { Firering.room_unlock(304355) { EM.stop } }
167
+ end
168
+
169
+ it "is able to speak a text message" do
170
+ EM.run { Firering.text(304355, "some text") { EM.stop } }
171
+ end
172
+
173
+ it "is able to speak a paste message" do
174
+ EM.run { Firering.paste(304355, "some\ntext") { EM.stop } }
175
+ end
176
+
177
+ it "is able to speak a tweet" do
178
+ EM.run { Firering.tweet(304355, "http://twitter.com/message") { EM.stop } }
179
+ end
180
+
181
+ it "is able to play a rimshot" do
182
+ EM.run { Firering.rimshot(304355) { EM.stop } }
183
+ end
184
+
185
+ it "is able to play crickets" do
186
+ EM.run { Firering.crickets(304355) { EM.stop } }
187
+ end
188
+
189
+ it "is able to play a trombone" do
190
+ EM.run { Firering.trombone(304355) { EM.stop } }
191
+ end
192
+
193
+ it "is able to highlight / de-highlight a message" do
194
+ EM.run {
195
+ Firering.highlight_message(224590113) {
196
+ Firering.highlight_message(224590113, false) {
197
+ EM.stop
198
+ }
199
+ }
200
+ }
201
+ end
202
+
203
+ end
@@ -0,0 +1,30 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Sat, 29 May 2010 23:21:51 GMT
3
+ Server: Apache
4
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
5
+ X-Runtime: 48
6
+ Cache-Control: private, max-age=0, must-revalidate
7
+ Content-Length: 1
8
+ Status: 200
9
+ Content-Type: application/json; charset=utf-8
10
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:51 GMT
11
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:51 GMT
12
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlYTQ1NmQyNWNmN2I0NWI1MjE3OTE3NjRlNzhlMzAxMWY%3D--6c4d41eaddc75ecb695b23f66e6a18cd096a980a; path=/; HttpOnly
13
+ Via: 1.1 campfirenow.com
14
+ Connection: close
15
+
16
+ HTTP/1.1 404 Not Found
17
+ Date: Sat, 29 May 2010 23:21:51 GMT
18
+ Server: Apache
19
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
20
+ X-Runtime: 31
21
+ Cache-Control: no-cache
22
+ Content-Length: 1
23
+ Status: 404
24
+ Content-Type: application/json; charset=utf-8
25
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:51 GMT
26
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:51 GMT
27
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlMGZmYjM3MTY1MDJiNzExNjliYTcxZDBlOTFiMzJjZDM%3D--293416fe271992252b3fc97d534bd1cb4cc00db2; path=/; HttpOnly
28
+ Via: 1.1 campfirenow.com
29
+ Connection: close
30
+
@@ -0,0 +1,30 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Sat, 29 May 2010 23:21:41 GMT
3
+ Server: Apache
4
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
5
+ ETag: "a58b4ba173d6e0ac50ae6c8c92a104de"
6
+ X-Runtime: 42
7
+ Cache-Control: private, max-age=0, must-revalidate
8
+ Content-Length: 415
9
+ Status: 200
10
+ Content-Type: application/json; charset=utf-8
11
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:41 GMT
12
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlZDBlN2Q0NGRiMmNmODI2NzhjZTcyM2VjNTNkZTc0N2M%3D--a48d355a51c12ece208e00b11f1bfe179ede70f2; path=/; HttpOnly
13
+ Via: 1.1 campfirenow.com
14
+ Connection: close
15
+
16
+ HTTP/1.1 200 OK
17
+ Date: Sat, 29 May 2010 23:21:42 GMT
18
+ Server: Apache
19
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
20
+ ETag: "a58b4ba173d6e0ac50ae6c8c92a104de"
21
+ X-Runtime: 47
22
+ Cache-Control: private, max-age=0, must-revalidate
23
+ Content-Length: 415
24
+ Status: 200
25
+ Content-Type: application/json; charset=utf-8
26
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:42 GMT
27
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlMzk2MDkyZjVlYTEzYTYwZjVmNzc0MjI5OWY4MTc1Mzk%3D--d0b35267abec39fb1a4297f51393510fb6dd35fa; path=/; HttpOnly
28
+ Via: 1.1 campfirenow.com
29
+ Connection: close
30
+
@@ -0,0 +1,7 @@
1
+ HTTP/1.1 200 OK
2
+ Server: nginx/0.8.33
3
+ Date: Sat, 29 May 2010 23:21:57 GMT
4
+ Content-Type: application/json
5
+ Transfer-Encoding: chunked
6
+ Connection: keep-alive
7
+
@@ -0,0 +1,30 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Sat, 29 May 2010 23:21:43 GMT
3
+ Server: Apache
4
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
5
+ ETag: "b1bc074b35d742ddd7b9a1b4b349404d"
6
+ X-Runtime: 49
7
+ Cache-Control: private, max-age=0, must-revalidate
8
+ Content-Length: 4303
9
+ Status: 200
10
+ Content-Type: application/json; charset=utf-8
11
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:43 GMT
12
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlYmY4YzViNzdhZTg0MDM0NzM0ZDJiOGFmNGZhOGFkZDk%3D--1bb0d5d778f87c38349a179ec5f7e1e07f4565ee; path=/; HttpOnly
13
+ Via: 1.1 campfirenow.com
14
+ Connection: close
15
+
16
+ HTTP/1.1 200 OK
17
+ Date: Sat, 29 May 2010 23:21:44 GMT
18
+ Server: Apache
19
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
20
+ ETag: "b1bc074b35d742ddd7b9a1b4b349404d"
21
+ X-Runtime: 42
22
+ Cache-Control: private, max-age=0, must-revalidate
23
+ Content-Length: 4303
24
+ Status: 200
25
+ Content-Type: application/json; charset=utf-8
26
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:44 GMT
27
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlMjdmNzFiNTI0NGU0ZmMwZTI1NDEzMTllMzcyYWY1OGE%3D--b4ecf92995c7ff35bc4faf7f2c5c60b56a8a839f; path=/; HttpOnly
28
+ Via: 1.1 campfirenow.com
29
+ Connection: close
30
+
@@ -0,0 +1,30 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Sat, 29 May 2010 23:21:45 GMT
3
+ Server: Apache
4
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
5
+ ETag: "b1bc074b35d742ddd7b9a1b4b349404d"
6
+ X-Runtime: 60
7
+ Cache-Control: private, max-age=0, must-revalidate
8
+ Content-Length: 4303
9
+ Status: 200
10
+ Content-Type: application/json; charset=utf-8
11
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:45 GMT
12
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlNjUzODNlOWM3ZDMzMTA1YmU5OTRhMWIyNmI1OTU5ZGM%3D--ca4245d3a65445029cf30ae711b4f80486abe59b; path=/; HttpOnly
13
+ Via: 1.1 campfirenow.com
14
+ Connection: close
15
+
16
+ HTTP/1.1 200 OK
17
+ Date: Sat, 29 May 2010 23:21:46 GMT
18
+ Server: Apache
19
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
20
+ ETag: "b1bc074b35d742ddd7b9a1b4b349404d"
21
+ X-Runtime: 58
22
+ Cache-Control: private, max-age=0, must-revalidate
23
+ Content-Length: 4303
24
+ Status: 200
25
+ Content-Type: application/json; charset=utf-8
26
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:46 GMT
27
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlMTU0MDc3Y2VlMTRjYzJkMjYxYThiNDA0Zjg0ZDk5MGM%3D--623f028ee03db3daf72bfba229691cbbdf5a5277; path=/; HttpOnly
28
+ Via: 1.1 campfirenow.com
29
+ Connection: close
30
+
@@ -0,0 +1,30 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Sat, 29 May 2010 23:21:46 GMT
3
+ Server: Apache
4
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
5
+ ETag: "394daf1a187e2f2a82ac593c04a0f637"
6
+ X-Runtime: 22
7
+ Cache-Control: private, max-age=0, must-revalidate
8
+ Content-Length: 15
9
+ Status: 200
10
+ Content-Type: application/json; charset=utf-8
11
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:46 GMT
12
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlZWYzNDgyNjA3MDAxMWQ2NDdmOWJkZTEwZWI0NzU4MWQ%3D--5af5f5e97c30f6ce7be4def8ef7d31187482e99e; path=/; HttpOnly
13
+ Via: 1.1 campfirenow.com
14
+ Connection: close
15
+
16
+ HTTP/1.1 200 OK
17
+ Date: Sat, 29 May 2010 23:21:47 GMT
18
+ Server: Apache
19
+ X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
20
+ ETag: "394daf1a187e2f2a82ac593c04a0f637"
21
+ X-Runtime: 25
22
+ Cache-Control: private, max-age=0, must-revalidate
23
+ Content-Length: 15
24
+ Status: 200
25
+ Content-Type: application/json; charset=utf-8
26
+ Set-Cookie: session_token=; path=/; expires=Wed, 29-May-2030 23:21:47 GMT
27
+ Set-Cookie: _campfire_session=BAh7CDoQaWRlbnRpdHlfaWRpA7F3AjoJYXV0aHsGIg9icm9hZHNwaXJlewY6DHVzZXJfaWRpA%2FNXBjoPc2Vzc2lvbl9pZCIlMGNkYzIzNTdhMDNiODI1ODE3MWZiNjk3NGQzMTliNWE%3D--e313ce480488a29e1768d3049229100def829e4a; path=/; HttpOnly
28
+ Via: 1.1 campfirenow.com
29
+ Connection: close
30
+