### Home Classes Methods

### In Files

- lib/yajl/http_stream.rb

### Parent

Object

### Namespace

- CLASS Yajl::HttpStream::HttpError
- CLASS Yajl::HttpStream::InvalidContentType

### Methods

- ::delete
- ::get
- ::post
- ::put
- ::request
- #delete
- #get
- #post
- #put
- #terminate

### Files

- README.rdoc
- Makefile

### Class/Module Index

Quicksearch

- Yajl
- Yajl::Bzip2
- Yajl::Bzip2::StreamReader
- Yajl::Bzip2::StreamWriter
- Yajl::Deflate
- Yajl::Deflate::StreamReader
- Yajl::Deflate::StreamWriter
- Yajl::EncodeError
- Yajl::Encoder
- Yajl::Gzip
- Yajl::Gzip::StreamReader
- Yajl::Gzip::StreamWriter
- Yajl::HttpStream
- Yajl::HttpStream::HttpError
- Yajl::HttpStream::InvalidContentType
- Yajl::ParseError
- Yajl::Parser
- Yajl::Stream
- JSON
- JSON::GeneratorError
- JSON::JSONError
- JSON::ParserError
- Array
- FalseClass
- Fixnum
- Float
- Hash
- Kernel
- NilClass
- Object
- String
- TrueClass

No matching classes.

# 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 67
    def self.delete(uri, opts = {}, &block)
      request("DELETE", uri, opts, &block)
    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 28
    def self.get(uri, opts = {}, &block)
      request("GET", uri, opts, &block)
    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 41
    def self.post(uri, body, opts = {}, &block)
      request("POST", uri, opts.merge({:body => body}), &block)
    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 54
    def self.put(uri, body, opts = {}, &block)
      request("PUT", uri, opts.merge({:body => body}), &block)
    end

### Protected Class Methods

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

    # File lib/yajl/http_stream.rb, line 86
    def self.request(method, uri, opts = {}, &block)
      if uri.is_a?(String)
        uri = URI.parse(uri)
      end

      user_agent = opts.has_key?('User-Agent') ? opts.delete(['User-Agent']) : "Yajl::HttpStream #{Yajl::VERSION}"
      if method == "POST" || method == "PUT"
        content_type = opts.has_key?('Content-Type') ? opts.delete(['Content-Type']) : "application/x-www-form-urlencoded"
        body = opts.delete(:body)
        if body.is_a?(Hash)
          body = body.keys.collect {|param| "#{URI.escape(param.to_s)}=#{URI.escape(body[param].to_s)}"}.join('&')
        end
      end

      socket = opts.has_key?(:socket) ? opts.delete(:socket) : TCPSocket.new(uri.host, uri.port)
      request = "#{method} #{uri.path}#{uri.query ? "?"+uri.query : nil} HTTP/1.1\r\n"
      request << "Host: #{uri.host}\r\n"
      request << "Authorization: Basic #{[uri.userinfo].pack('m').strip!}\r\n" unless uri.userinfo.nil?
      request << "User-Agent: #{user_agent}\r\n"
      request << "Accept: */*\r\n"
      if method == "POST" || method == "PUT"
        request << "Content-Length: #{body.length}\r\n"
        request << "Content-Type: #{content_type}\r\n"
      end
      encodings = []
      encodings << "bzip2" if defined?(Yajl::Bzip2)
      encodings << "gzip" if defined?(Yajl::Gzip)
      encodings << "deflate" if defined?(Yajl::Deflate)
      request << "Accept-Encoding: #{encodings.join(',')}\r\n" if encodings.any?
      request << "Accept-Charset: utf-8\r\n\r\n"
      if method == "POST" || method == "PUT"
        request << body
      end
      socket.write(request)
      response_head = {}
      response_head[:headers] = {}

      socket.each_line do |line|
        if line == "\r\n" # end of the headers
          break
        else
          header = line.split(": ")
          if header.size == 1
            header = header[0].split(" ")
            response_head[:version] = header[0]
            response_head[:code] = header[1].to_i
            response_head[:msg] = header[2]
            # this is the response code line
          else
            response_head[:headers][header[0]] = header[1].strip
          end
        end
      end

      if (response_head[:code] != 200)
        raise HttpError.new("Code 200 expected got #{response_head[:code]}", response_head[:headers])
      end

      parser = Yajl::Parser.new(opts)
      parser.on_parse_complete = block if block_given?
      if response_head[:headers]["Transfer-Encoding"] == 'chunked'
        if block_given?
          chunkLeft = 0
          while !socket.eof? && (line = socket.gets)
            break if line.match /0.*?\r\n/
            next if line == "\r\n"
            size = line.hex
            json = socket.read(size)
            next if json.nil?
            chunkLeft = size-json.size
            if chunkLeft == 0
              parser << json
            else
              # received only part of the chunk, grab the rest
              parser << socket.read(chunkLeft)
            end
          end
        else
          raise Exception, "Chunked responses detected, but no block given to handle the chunks."
        end
      else
        content_type = response_head[:headers]["Content-Type"].split(';')
        content_type = content_type.first
        if ALLOWED_MIME_TYPES.include?(content_type)
          case response_head[:headers]["Content-Encoding"]
          when "gzip"
            return Yajl::Gzip::StreamReader.parse(socket, opts, &block)
          when "deflate"
            return Yajl::Deflate::StreamReader.parse(socket, opts.merge({:deflate_options => -Zlib::MAX_WBITS}), &block)
          when "bzip2"
            return Yajl::Bzip2::StreamReader.parse(socket, opts, &block)
          else
            return parser.parse(socket)
          end
        else
          raise InvalidContentType, "The response MIME type #{content_type}"
        end
      end
    ensure
      socket.close if !socket.nil? and !socket.closed?
    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 72
    def delete(uri, opts = {}, &block)
      initialize_socket(uri, opts)
      HttpStream::delete(uri, opts, &block)
    rescue IOError => e
      raise e unless @intentional_termination
    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 33
    def get(uri, opts = {}, &block)
      initialize_socket(uri, opts)
      HttpStream::get(uri, opts, &block)
    rescue IOError => e
      raise e unless @intentional_termination
    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 46
    def post(uri, body, opts = {}, &block)
      initialize_socket(uri, opts)
      HttpStream::post(uri, body, opts, &block)
    rescue IOError => e
      raise e unless @intentional_termination
    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 59
    def put(uri, body, opts = {}, &block)
      initialize_socket(uri, opts)
      HttpStream::put(uri, body, opts, &block)
    rescue IOError => e
      raise e unless @intentional_termination
    end

terminate() click to toggle source

Terminate a running HTTPStream instance

    # File lib/yajl/http_stream.rb, line 80
    def terminate
      @intentional_termination = true
      @socket.close
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.