# File lib/em-http/client.rb, line 558
    def parse_response_header
      return false unless parse_header(@response_header)

      # invoke headers callback after full parse if one
      # is specified by the user
      @headers.call(@response_header) if @headers

      unless @response_header.http_status and @response_header.http_reason
        @state = :invalid
        on_error "no HTTP response"
        return false
      end

      if @state == :connect_http_proxy
        # when a successfull tunnel is established, the proxy responds with a
        # 200 response code. from here, the tunnel is transparent.
        if @response_header.http_status.to_i == 200
          @response_header = HttpResponseHeader.new
          connection_completed
          return true
        else
          @state = :invalid
          on_error "proxy not accessible"
          return false
        end
      end

      # correct location header - some servers will incorrectly give a relative URI
      if @response_header.location
        begin
          location = Addressable::URI.parse(@response_header.location)

          if location.relative?
            location = @uri.join(location)
            @response_header[LOCATION] = location.to_s
          else
            # if redirect is to an absolute url, check for correct URI structure
            raise if location.host.nil?
          end

          # store last url on any sign of redirect
          @last_effective_url = location

        rescue
          on_error "Location header format error"
          return false
        end
      end

      # Fire callbacks immediately after recieving header requests
      # if the request method is HEAD. In case of a redirect, terminate
      # current connection and reinitialize the process.
      if @method == "HEAD"
        @state = :finished
        close_connection
        return false
      end

      if websocket?
        if @response_header.status == 101
          @state = :websocket
          succeed
        else
          fail "websocket handshake failed"
        end

      elsif @response_header.chunked_encoding?
        @state = :chunk_header
      elsif @response_header.content_length
        @state = :body
        @bytes_remaining = @response_header.content_length
      else
        @state = :body
        @bytes_remaining = nil
      end

      if decoder_class = HttpDecoders.decoder_for_encoding(response_header[CONTENT_ENCODING])
        begin
          @content_decoder = decoder_class.new do |s| on_decoded_body_data(s) end
        rescue HttpDecoders::DecoderError
          on_error "Content-decoder error"
        end
      end

      true
    end