Parent

Yajl::HttpStream

This module is for making HTTP requests to which the response bodies (and possibly requests in the near future) are streamed directly into Yajl.

Constants

ALLOWED_MIME_TYPES

The mime-type we expect the response to be. If it’s anything else, we can’t parse it and an InvalidContentType is raised.

Public Class Methods

delete(uri, opts = {}, &block) click to toggle source

Makes a basic HTTP DELETE request to the URI provided

    # File lib/yajl/http_stream.rb, line 68
68:     def self.delete(uri, opts = {}, &block)
69:       request("DELETE", uri, opts, &block)
70:     end
get(uri, opts = {}, &block) click to toggle source

Makes a basic HTTP GET request to the URI provided

    # File lib/yajl/http_stream.rb, line 29
29:     def self.get(uri, opts = {}, &block)
30:       request("GET", uri, opts, &block)
31:     end
post(uri, body, opts = {}, &block) click to toggle source

Makes a basic HTTP POST request to the URI provided

    # File lib/yajl/http_stream.rb, line 42
42:     def self.post(uri, body, opts = {}, &block)
43:       request("POST", uri, opts.merge({:body => body}), &block)
44:     end
put(uri, body, opts = {}, &block) click to toggle source

Makes a basic HTTP PUT request to the URI provided

    # File lib/yajl/http_stream.rb, line 55
55:     def self.put(uri, body, opts = {}, &block)
56:       request("PUT", uri, opts.merge({:body => body}), &block)
57:     end

Protected Class Methods

request(method, uri, opts = {}, &block) click to toggle source
     # File lib/yajl/http_stream.rb, line 87
 87:       def self.request(method, uri, opts = {}, &block)
 88:         if uri.is_a?(String)
 89:           uri = URI.parse(uri)
 90:         end
 91: 
 92:         user_agent = opts.has_key?('User-Agent') ? opts.delete(['User-Agent']) : "Yajl::HttpStream #{Yajl::VERSION}"
 93:         if method == "POST" || method == "PUT"
 94:           content_type = opts.has_key?('Content-Type') ? opts.delete(['Content-Type']) : "application/x-www-form-urlencoded"
 95:           body = opts.delete(:body)
 96:           if body.is_a?(Hash)
 97:             body = body.keys.collect {|param| "#{URI.escape(param.to_s)}=#{URI.escape(body[param].to_s)}"}.join('&')
 98:           end
 99:         end
100: 
101:         socket = opts.has_key?(:socket) ? opts.delete(:socket) : TCPSocket.new(uri.host, uri.port)
102:         request = "#{method} #{uri.path}#{uri.query ? "?"+uri.query : nil} HTTP/1.1\r\n"
103:         request << "Host: #{uri.host}\r\n"
104:         request << "Authorization: Basic #{[uri.userinfo].pack('m').strip!}\r\n" unless uri.userinfo.nil?
105:         request << "User-Agent: #{user_agent}\r\n"
106:         request << "Accept: */*\r\n"
107:         if method == "POST" || method == "PUT"
108:           request << "Content-Length: #{body.length}\r\n"
109:           request << "Content-Type: #{content_type}\r\n"
110:         end
111:         encodings = []
112:         encodings << "bzip2" if defined?(Yajl::Bzip2)
113:         encodings << "gzip" if defined?(Yajl::Gzip)
114:         encodings << "deflate" if defined?(Yajl::Deflate)
115:         request << "Accept-Encoding: #{encodings.join(',')}\r\n" if encodings.any?
116:         request << "Accept-Charset: utf-8\r\n\r\n"
117:         if method == "POST" || method == "PUT"
118:           request << body
119:         end
120:         socket.write(request)
121:         response_head = {}
122:         response_head[:headers] = {}
123: 
124:         socket.each_line do |line|
125:           if line == "\r\n" # end of the headers
126:             break
127:           else
128:             header = line.split(": ")
129:             if header.size == 1
130:               header = header[0].split(" ")
131:               response_head[:version] = header[0]
132:               response_head[:code] = header[1].to_i
133:               response_head[:msg] = header[2]
134:               # this is the response code line
135:             else
136:               response_head[:headers][header[0]] = header[1].strip
137:             end
138:           end
139:         end
140: 
141:         if (response_head[:code] != 200)
142:           raise HttpError.new("Code 200 expected got #{response_head[:code]}", response_head[:headers])
143:         end
144: 
145:         parser = Yajl::Parser.new(opts)
146:         parser.on_parse_complete = block if block_given?
147:         if response_head[:headers]["Transfer-Encoding"] == 'chunked'
148:           if block_given?
149:             chunkLeft = 0
150:             while !socket.eof? && (line = socket.gets)
151:               break if line.match /0.*?\r\n/
152:               next if line == "\r\n"
153:               size = line.hex
154:               json = socket.read(size)
155:               next if json.nil?
156:               chunkLeft = size-json.size
157:               if chunkLeft == 0
158:                 parser << json
159:               else
160:                 # received only part of the chunk, grab the rest
161:                 parser << socket.read(chunkLeft)
162:               end
163:             end
164:           else
165:             raise Exception, "Chunked responses detected, but no block given to handle the chunks."
166:           end
167:         else
168:           content_type = response_head[:headers]["Content-Type"].split(';')
169:           content_type = content_type.first
170:           if ALLOWED_MIME_TYPES.include?(content_type)
171:             case response_head[:headers]["Content-Encoding"]
172:             when "gzip"
173:               return Yajl::Gzip::StreamReader.parse(socket, opts, &block)
174:             when "deflate"
175:               return Yajl::Deflate::StreamReader.parse(socket, opts.merge({:deflate_options => -Zlib::MAX_WBITS}), &block)
176:             when "bzip2"
177:               return Yajl::Bzip2::StreamReader.parse(socket, opts, &block)
178:             else
179:               return parser.parse(socket)
180:             end
181:           else
182:             raise InvalidContentType, "The response MIME type #{content_type}"
183:           end
184:         end
185:       ensure
186:         socket.close if !socket.nil? and !socket.closed?
187:       end

Public Instance Methods

delete(uri, opts = {}, &block) click to toggle source

Makes a basic HTTP DELETE request to the URI provided allowing the user to terminate the connection

    # File lib/yajl/http_stream.rb, line 73
73:     def delete(uri, opts = {}, &block)
74:       initialize_socket(uri, opts)
75:       HttpStream::delete(uri, opts, &block)
76:     rescue IOError => e
77:       raise e unless @intentional_termination
78:     end
get(uri, opts = {}, &block) click to toggle source

Makes a basic HTTP GET request to the URI provided allowing the user to terminate the connection

    # File lib/yajl/http_stream.rb, line 34
34:     def get(uri, opts = {}, &block)
35:       initialize_socket(uri, opts)
36:       HttpStream::get(uri, opts, &block)
37:     rescue IOError => e
38:       raise e unless @intentional_termination
39:     end
post(uri, body, opts = {}, &block) click to toggle source

Makes a basic HTTP POST request to the URI provided allowing the user to terminate the connection

    # File lib/yajl/http_stream.rb, line 47
47:     def post(uri, body, opts = {}, &block)
48:       initialize_socket(uri, opts)
49:       HttpStream::post(uri, body, opts, &block)
50:     rescue IOError => e
51:       raise e unless @intentional_termination
52:     end
put(uri, body, opts = {}, &block) click to toggle source

Makes a basic HTTP PUT request to the URI provided allowing the user to terminate the connection

    # File lib/yajl/http_stream.rb, line 60
60:     def put(uri, body, opts = {}, &block)
61:       initialize_socket(uri, opts)
62:       HttpStream::put(uri, body, opts, &block)
63:     rescue IOError => e
64:       raise e unless @intentional_termination
65:     end
terminate() click to toggle source

Terminate a running HTTPStream instance

    # File lib/yajl/http_stream.rb, line 81
81:     def terminate
82:       @intentional_termination = true
83:       @socket.close
84:     end

Private Instance Methods

initialize_socket(uri, opts = {}) click to toggle source

Initialize socket and add it to the opts

     # File lib/yajl/http_stream.rb, line 191
191:     def initialize_socket(uri, opts = {})
192:       @socket = TCPSocket.new(uri.host, uri.port)
193:       opts.merge!({:socket => @socket})
194:       @intentional_termination = false
195:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.