Class: SMS::Backend::HTTP::RackApp

Inherits:
Object
  • Object
show all
Defined in:
lib/rubysms/backend/http.rb

Overview

This simple Rack application handles the few HTTP requests that this backend will serve:

GET / – redirect to a random blank session GET /123456.json – export session 123456 as JSON data GET /123456 – view session 123456 (actually a

static HTML page which fetches
the data via javascript+json)

POST /123456/send – add a message to session 123456

Instance Method Summary collapse

Constructor Details

#initialize(http_backend, mootools_url) ⇒ RackApp

Returns a new instance of RackApp.



88
89
90
91
92
93
94
95
96
97
# File 'lib/rubysms/backend/http.rb', line 88

def initialize(http_backend, mootools_url)
	@backend = http_backend
	@mt_url = mootools_url
	
	# generate the html to be returned by replacing the
	# variables in the constant with our instance vars
	@html = HTML.sub(/%(\w+)%/) do
		instance_variable_get("@#{$1}")
	end
end

Instance Method Details

#call(env) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/rubysms/backend/http.rb', line 99

def call(env)
	req = Rack::Request.new(env)
	path = req.path_info
	
	if req.get?
		
		# serve GET /
		# for requests not containing a session id, generate a random
		# new one (between 111111 and 999999) and redirect back to it
		if path == "/"
			while true
			
				# randomize a session id, and stop looping if
				# it's empty - this is just to avoid accidentally
				# jumping into someone elses session (although
				# that's allowed, if explicly requested)
				new_session = (111111 + rand(888888)).to_s
				break unless @backend.msg_log.has_key?(new_session)
			end
		
			return [
				301, 
				{"location" => "/#{new_session}"},
				"Redirecting to session #{new_session}"]
		
		# serve GET /123456
		elsif m = path.match(/^\/\d{6}$/)
		
			# just so render the static HTML content (the
			# log contents are rendered via JSON, above)
			return [200, {"content-type" => "text/html"}, @html]

		# serve GET /123456.json
		elsif m = path.match(/^\/(\d{6})\.json$/)
			msgs = @backend.msg_log[m.captures[0]] || []
			
			return [
				200,
				{"content-type" => "application/json"},
				"[" + (msgs.collect { |msg| msg.inspect }.join(", ")) + "]"]
		
		# serve GET /favicon.ico
		# as if YOU'VE never wasted
		# a minute on frivolous crap
		elsif path == "/favicon.ico"
			icon = File.dirname(__FILE__) + "/cellphone.ico"
			return [200, {"content-type" => "image/x-ico"}, File.read(icon)]
		end
	
	# serve POST /123456/send
	elsif (m = path.match(/^\/(\d{6})\/send$/)) && req.post?
		t = req.POST["msg"]
		s = m.captures[0]
		
		# init the message log for
		# this session if necessary
		@backend.msg_log[s] = []\
			unless @backend.msg_log.has_key?(s)
		
		# log the incoming message, so it shows
		# up in the two-way "conversation" 
		msg_id = @backend.msg_log[s].push\
			[t.object_id.abs.to_s, "in", t]

		# push the incoming message
		# into RubySMS, to distribute
		# to each application
		@backend.router.incoming(
			SMS::Incoming.new(
				@backend, s, Time.now, t))
		
		# acknowledge POST with
		# the new message ID
		return [
			200,
			{"content-type" => "text/plain" },
			t.object_id.abs.to_s]
	end
	
	# nothing else is valid. not 404, because it might be
	# an invalid method, and i can't be arsed right now.
	[500, {"content-type" => "text/plain" }, "FAIL."]
end