Module: AdhdRESTServer

Defined in:
lib/adhd/adhd_rest_server.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#proxy_connObject

Returns the value of attribute proxy_conn.



34
35
36
# File 'lib/adhd/adhd_rest_server.rb', line 34

def proxy_conn
  @proxy_conn
end

Instance Method Details

#handle_getObject



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/adhd/adhd_rest_server.rb', line 182

def handle_get  
  resume
  # We need to connect to the right server and build a header
  server_uri = URI.parse(@our_doc[:db].server.uri)
  server_addr = server_uri.host
  server_port = server_uri.port
  
  docid = @our_doc[:doc]._id
  dbname = @our_doc[:db].name
  request = "GET /#{dbname}/#{docid}/#{@our_doc[:doc].filename} HTTP/1.0\r\n\r\n"
  #send_data request
  #close_connection_after_writing
  puts "Connect to #{server_addr} port #{server_port}"
  conn = EM::connect server_addr, server_port, ProxyToServer, self, request
  EM::enable_proxy proxy_conn, self, 1024    
end

#handle_putObject



210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/adhd/adhd_rest_server.rb', line 210

def handle_put
  resume
  
  # We need to connect to the right server and build a header
  server_uri = URI.parse(@our_doc[:db].server.uri)
  server_addr = server_uri.host
  server_port = server_uri.port
  
  docid = @our_doc[:doc]._id
  dbname = @our_doc[:db].name
  request = "PUT /#{dbname}/#{docid}/#{@our_doc[:doc].filename}?rev=#{@our_doc[:doc]["_rev"]} HTTP/1.0\r\n"
  request += "Content-Type: #{@our_doc[:doc].mime_type}\r\n"
  request += "Content-Length: #{@our_doc[:doc].size_bytes}\r\n"
  request += "\r\n"
  request += @buffer
  #send_data request
  #close_connection_after_writing
  puts "Connect to #{server_addr} port #{server_port}"
  conn = EM::connect server_addr, server_port, ProxyToServer, self, request
  EM::enable_proxy self, proxy_conn, 1024  
end

#initialize(node_manager) ⇒ Object



36
37
38
39
40
# File 'lib/adhd/adhd_rest_server.rb', line 36

def initialize node_manager
  @node_manager = node_manager
  @buffer = ""
  @status = :header
end

#proxy_receive_data(data) ⇒ Object



204
205
206
207
# File 'lib/adhd/adhd_rest_server.rb', line 204

def proxy_receive_data data
  # Response to a PUT request only
  send_data data
end

#proxy_unbindObject



199
200
201
202
# File 'lib/adhd/adhd_rest_server.rb', line 199

def proxy_unbind
  # Our cpnnection to the CouchDB has just been torn down
  close_connection_after_writing
end

#receive_data(data) ⇒ Object

The format we are expecting:

PUT somedatabase/document/attachment?rev=123 HTTP/1.0 Content-Length: 245 Content-Type: image/jpeg

<JPEG data>



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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
# File 'lib/adhd/adhd_rest_server.rb', line 54

def receive_data data

  # First we get all the headers in to find out which resource 
  # we are looking for.
  
  if @status == :header
    @buffer += data
           
    if data =~ /\r\n\r\n/

     # Detected end of headers
     header_data = @buffer[0...($~.begin(0))]
    
    @web_config = WEBrick::Config::HTTP.clone
    @web_config[:HTTPVersion] = WEBrick::HTTPVersion.new("1.0")
    
     # Try the webrick parser
     @req = WEBrick::HTTPRequest.new(@web_config)
     @res = WEBrick::HTTPResponse.new(@web_config)
     
     
     puts @res.to_s

     StringIO.open(header_data, 'rb') do |socket|
       @req.parse(socket)
     end
     
     # The rest of the incomming connection        
     @buffer = @buffer[($~.end(0))..-1]
     
     # Compute the ID of the sought resource
     if @req.path =~ /\/adhd\/(.*)/
       @req.header["Filename"] = $1
       @req.header["ID"] = MD5.new($1).to_s
     else
       # Throw an error          
     end
    
     # Change the status once headers are found
     @status = :find_node 
    else
     # Avoid DoS via buffer filling
     close_connection if @buffer.length > 1000
    end
    
  end
  
  # Now we have the headers, but maybe not the full body, and we are looking
  # for the right node in our network to handle the call.
  if @status == :find_node
     pause # We want to tell the remote host to wait a bit
           # This would allow us to defer the execution of the calls to find 
           # the right nodes, and extract the doc.
     
     # TODO: We need to push all the chit-chat with the remote servers to 
     #       A deferable object, or some other connection, not to block.
     #       Right now we are blocking and it sucks.  
           
     # Now get or write the document associated with this file
     if @req.request_method == "GET"
       
       @our_doc = @node_manager.srdb.get_doc_directly(@req.header["ID"])
       
       # TODO: handle erros if file does not exist
       if @our_doc[:ok]
         @status == :get
         handle_get
       else
         send_data "Problem"
       end          
     end
     
     if @req.request_method == "PUT"
       # Define a Doc with the data so far
       @our_doc = ContentDoc.new
       
       @our_doc._id = @req.header["ID"]
       @our_doc.internal_id = @req.header["ID"]
       @our_doc.size_bytes = @req.content_length
       @our_doc.filename = @req.header["Filename"]
       @our_doc.mime_type = @req.content_type
       
       # Write to the right node
       @our_doc = @node_manager.srdb.write_doc_directly(@our_doc)
       
       # TODO: if an error is returned here, we cannot execute the query
       if @our_doc[:ok]
         @status = :put
         handle_put
       else          
         send_data "Problem"
       end
     end
   
     # Now send the reply as an HTTP1.0 reponse
   
     # HTTP/1.0 200 OK
     # Date: Fri, 08 Aug 2003 08:12:31 GMT
     # Server: Apache/1.3.27 (Unix)
     # MIME-version: 1.0
     # Last-Modified: Fri, 01 Aug 2003 12:45:26 GMT
     # Content-Type: text/html
     # Content-Length: 2345
     # ** a blank line *
     # <HTML> ...
   
   
   
   # response = @our_doc.to_s
   # 
   # send_data "HTTP/1.0 200 OK\r\n"
   # send_data "Content-Type: text/plain\r\n"
   # send_data "Content-Length: #{response.length}\r\n"
   # send_data "\r\n"
   # send_data response
   #
   # # Close the connection
   # close_connection_after_writing      

  end
  
  # We have the header and the node, and now we execute the request
  if @status == :execute_request
  
  end
  
end

#unbindObject



232
233
234
# File 'lib/adhd/adhd_rest_server.rb', line 232

def unbind
  puts "-- someone disconnected from the echo server!"
end