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 68 68: def self.delete(uri, opts = {}, &block) 69: request("DELETE", uri, opts, &block) 70: end
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
# 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
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
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
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
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
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.
Generated with the Darkfish Rdoc Generator 1.1.6.