File: http.rb

package info (click to toggle)
stompserver 0.9.9gem-5
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 424 kB
  • sloc: ruby: 2,765; sh: 162; makefile: 3
file content (128 lines) | stat: -rw-r--r-- 3,469 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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

  class Mongrel::HttpRequest
    attr_reader :body, :params

    def initialize(params, initial_body)
      @params = params
      @body = StringIO.new
      @body.write params.http_body
    end
  end

module StompServer
module StompServer::Protocols

  class Http < EventMachine::Connection

    def initialize *args
      super
      @buf = ''
    end


    def post_init
      @parser = Mongrel::HttpParser.new
      @params = Mongrel::HttpParams.new
      @nparsed = 0
      @request = nil
      @request_method = nil
      @request_length = 0
      @state = :headers
      @headers_out = {'Content-Length' => 0, 'Content-Type' => 'text/plain; charset=UTF-8'}
    end

    def receive_data data
      parse_request(data)
    end

    def parse_request data
      @buf << data
      case @state
      when :headers
        @nparsed = @parser.execute(@params, @buf, @nparsed)
        if @parser.finished?
          @request = Mongrel::HttpRequest.new(@params,@buf)
          @request_method = @request.params[Mongrel::Const::REQUEST_METHOD]
          content_length = @request.params[Mongrel::Const::CONTENT_LENGTH].to_i
          @request_length = @nparsed + content_length
          @remain = content_length - @request.params.http_body.length
          if @remain <= 0
            @buf = @buf[@request_length+1..-1] || ''
            process_request
            post_init
            return
          end
          @request.body.write @request.params.http_body
          @state = :body
        end
      when :body
        @remain -= @request.body.write data[0...@remain]
        if @remain <= 0
          @buf = @buf[@request_length+1..-1] || ''
          process_request
          post_init
          return
        end
      end
    end

    def process_request
      begin
        @request.body.rewind
        dest = @request.params[Mongrel::Const::REQUEST_PATH]
        case @request_method
        when 'PUT'
          @frame = StompServer::StompFrame.new
          @frame.command = 'SEND'
          @frame.body = @request.body.read
          @frame.headers['destination'] = dest
          if @@queue_manager.enqueue(@frame)
            create_response('200','Message Enqueued')
          else
            create_response('500','Error enqueueing message')
          end
        when 'GET'
          if frame = @@queue_manager.dequeue(dest)
            @headers_out['message-id'] = frame.headers['message-id']
            create_response('200',frame.body)
          else
            create_response('404','No messages in queue')
          end
        else
          create_response('500','Invalid Command')
        end
      rescue Exception => e
        puts "err: #{e} #{e.backtrace.join("\n")}"
        create_response('500',e)
      end
    end

    def unbind
      puts "Closing connection"
      close_connection_after_writing
    end

    def create_response(code,response_text)
      response = ''
      @headers_out['Content-Length'] = response_text.size

      case code
      when '200'
        response << "HTTP/1.1 200 OK\r\n"
      when '500'
        response << "HTTP/1.1 500 Server Error\r\n"
      when '404'
        response << "HTTP/1.1 404 Message Not Found\r\n"
      end
      @headers_out.each_pair do |key, value|
        response << "#{key}:#{value}\r\n"
      end
      response << "\r\n"
      response << response_text
      send_data(response)
      unbind if @request.params['HTTP_CONNECTION'] == 'close'
    end
  end

end
end