This module is for making HTTP requests to which the response bodies (and possibly requests in the near future) are streamed directly into Yajl.
The mime-type we expect the response to be. If it’s anything else, we can’t parse it and an InvalidContentType is raised.
Makes a basic HTTP DELETE request to the URI provided
# File lib/yajl/http_stream.rb, line 70 70: def self.delete(uri, opts = {}, &block) 71: request("DELETE", uri, opts, &block) 72: end
Makes a basic HTTP GET request to the URI provided
# File lib/yajl/http_stream.rb, line 31 31: def self.get(uri, opts = {}, &block) 32: request("GET", uri, opts, &block) 33: end
# File lib/yajl/http_stream.rb, line 89 89: def self.request(method, uri, opts = {}, &block) 90: if uri.is_a?(String) 91: uri = URI.parse(uri) 92: end 93: 94: default_headers = { 95: "User-Agent" => opts["User-Agent"] || "Yajl::HttpStream #{Yajl::VERSION}", 96: "Accept" => "*/*", 97: "Accept-Charset" => "utf-8" 98: } 99: 100: if method == "POST" || method == "PUT" 101: default_headers["Content-Type"] = opts["Content-Type"] || "application/x-www-form-urlencoded" 102: body = opts.delete(:body) 103: if body.is_a?(Hash) 104: body = body.keys.collect {|param| "#{URI.escape(param.to_s)}=#{URI.escape(body[param].to_s)}"}.join('&') 105: end 106: default_headers["Content-Length"] = body.length 107: end 108: 109: unless uri.userinfo.nil? 110: default_headers["Authorization"] = "Basic #{[uri.userinfo].pack('m').strip!}\r\n" 111: end 112: 113: encodings = [] 114: encodings << "bzip2" if defined?(Yajl::Bzip2) 115: encodings << "gzip" if defined?(Yajl::Gzip) 116: encodings << "deflate" if defined?(Yajl::Deflate) 117: if encodings.any? 118: default_headers["Accept-Encoding"] = "#{encodings.join(',')}\r\n" 119: end 120: 121: headers = default_headers.merge(opts[:headers] || {}) 122: 123: socket = opts.delete(:socket) || TCPSocket.new(uri.host, uri.port) 124: request = "#{method} #{uri.path}#{uri.query ? "?"+uri.query : nil} HTTP/1.1\r\n" 125: request << "Host: #{uri.host}\r\n" 126: headers.each do |k, v| 127: request << "#{k}: #{v}\r\n" 128: end 129: request << "\r\n" 130: if method == "POST" || method == "PUT" 131: request << body 132: end 133: socket.write(request) 134: response_head = {} 135: response_head[:headers] = {} 136: 137: socket.each_line do |line| 138: if line == "\r\n" # end of the headers 139: break 140: else 141: header = line.split(": ") 142: if header.size == 1 143: header = header[0].split(" ") 144: response_head[:version] = header[0] 145: response_head[:code] = header[1].to_i 146: response_head[:msg] = header[2] 147: # this is the response code line 148: else 149: response_head[:headers][header[0]] = header[1].strip 150: end 151: end 152: end 153: 154: if (response_head[:code] != 200) 155: raise HttpError.new("Code 200 expected got #{response_head[:code]}", response_head[:headers]) 156: end 157: 158: parser = Yajl::Parser.new(opts) 159: parser.on_parse_complete = block if block_given? 160: if response_head[:headers]["Transfer-Encoding"] == 'chunked' 161: if block_given? 162: chunkLeft = 0 163: while !socket.eof? && (line = socket.gets) 164: break if line.match /^0.*?\r\n/ 165: next if line == "\r\n" 166: size = line.hex 167: json = socket.read(size) 168: next if json.nil? 169: chunkLeft = size-json.size 170: if chunkLeft == 0 171: parser << json 172: else 173: # received only part of the chunk, grab the rest 174: parser << socket.read(chunkLeft) 175: end 176: end 177: else 178: raise Exception, "Chunked responses detected, but no block given to handle the chunks." 179: end 180: else 181: content_type = response_head[:headers]["Content-Type"].split(';') 182: content_type = content_type.first 183: if ALLOWED_MIME_TYPES.include?(content_type) 184: case response_head[:headers]["Content-Encoding"] 185: when "gzip" 186: return Yajl::Gzip::StreamReader.parse(socket, opts, &block) 187: when "deflate" 188: return Yajl::Deflate::StreamReader.parse(socket, opts.merge({:deflate_options => -Zlib::MAX_WBITS}), &block) 189: when "bzip2" 190: return Yajl::Bzip2::StreamReader.parse(socket, opts, &block) 191: else 192: return parser.parse(socket) 193: end 194: else 195: raise InvalidContentType, "The response MIME type #{content_type}" 196: end 197: end 198: ensure 199: socket.close if !socket.nil? and !socket.closed? 200: end
Makes a basic HTTP DELETE request to the URI provided allowing the user to terminate the connection
# File lib/yajl/http_stream.rb, line 75 75: def delete(uri, opts = {}, &block) 76: initialize_socket(uri, opts) 77: HttpStream::delete(uri, opts, &block) 78: rescue IOError => e 79: raise e unless @intentional_termination 80: end
Makes a basic HTTP GET request to the URI provided allowing the user to terminate the connection
# File lib/yajl/http_stream.rb, line 36 36: def get(uri, opts = {}, &block) 37: initialize_socket(uri, opts) 38: HttpStream::get(uri, opts, &block) 39: rescue IOError => e 40: raise e unless @intentional_termination 41: end
Makes a basic HTTP POST request to the URI provided allowing the user to terminate the connection
# File lib/yajl/http_stream.rb, line 49 49: def post(uri, body, opts = {}, &block) 50: initialize_socket(uri, opts) 51: HttpStream::post(uri, body, opts, &block) 52: rescue IOError => e 53: raise e unless @intentional_termination 54: end
Makes a basic HTTP PUT request to the URI provided allowing the user to terminate the connection
# File lib/yajl/http_stream.rb, line 62 62: def put(uri, body, opts = {}, &block) 63: initialize_socket(uri, opts) 64: HttpStream::put(uri, body, opts, &block) 65: rescue IOError => e 66: raise e unless @intentional_termination 67: end
Initialize socket and add it to the opts
# File lib/yajl/http_stream.rb, line 204 204: def initialize_socket(uri, opts = {}) 205: return if opts[:socket] 206: 207: @socket = TCPSocket.new(uri.host, uri.port) 208: opts.merge!({:socket => @socket}) 209: @intentional_termination = false 210: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.