/* Verify HTTP/1.1 request
   * @exception HttpException problem with the request.
   * @exception IOException problem with the connection.
   */
  private void verifyHTTP_1_1() throws HttpException, IOException {
    // Check Host Field exists
    String host = _request.getField(HttpFields.__Host);
    if (host == null) throw new HttpException(HttpResponse.__400_Bad_Request);

    // check and enable requests transfer encodings.
    String transfer_coding = _request.getField(HttpFields.__TransferEncoding);

    if (transfer_coding != null && transfer_coding.length() > 0) {
      // Handling of codings other than chunking is now
      // the responsibility of handlers, filters or servlets.
      // Thanks to the compression filter, we now don't know if
      // what we can handle here.
      if (transfer_coding.equalsIgnoreCase(HttpFields.__Chunked)
          || StringUtil.endsWithIgnoreCase(transfer_coding, HttpFields.__Chunked))
        _inputStream.setChunking();
      else if (StringUtil.asciiToLowerCase(transfer_coding).indexOf(HttpFields.__Chunked) >= 0)
        throw new HttpException(HttpResponse.__400_Bad_Request);
    }

    // Check input content length can be determined
    int content_length = _request.getIntField(HttpFields.__ContentLength);
    String content_type = _request.getField(HttpFields.__ContentType);
    if (!_inputStream.isChunking()) {
      // If we have a content length, use it
      if (content_length >= 0) _inputStream.setContentLength(content_length);
      // else if we have no content
      else if (content_type == null || content_type.length() == 0) _inputStream.setContentLength(0);
      // else we need a content length
      else {
        // TODO - can't do this check as IE stuff up on
        // a redirect.
        // throw new HttpException(HttpResponse.__411_Length_Required);
        _inputStream.setContentLength(0);
      }
    }

    // Handle Continue Expectations
    String expect = _request.getField(HttpFields.__Expect);
    if (expect != null && expect.length() > 0) {
      if (StringUtil.asciiToLowerCase(expect).equals(HttpFields.__ExpectContinue)) {
        _inputStream.setExpectContinues(_outputStream.getOutputStream());
      } else throw new HttpException(HttpResponse.__417_Expectation_Failed);
    } else if (__2068_Continues
        && _inputStream.available() <= 0
        && (HttpRequest.__PUT.equals(_request.getMethod())
            || HttpRequest.__POST.equals(_request.getMethod()))) {
      // Send continue for RFC 2068 exception
      OutputStream real_out = _outputStream.getOutputStream();
      real_out.write(HttpResponse.__Continue);
      real_out.flush();
    }

    // Persistent unless requested otherwise
    _persistent = !_close;
  }
  /**
   * Setup the reponse output stream. Use the current state of the request and response, to set
   * tranfer parameters such as chunking and content length.
   */
  protected void firstWrite() throws IOException {
    if (_response.isCommitted()) return;

    // Nobble the OutputStream for HEAD requests
    if (HttpRequest.__HEAD.equals(_request.getMethod())) _outputStream.nullOutput();

    int length = _response.getIntField(HttpFields.__ContentLength);
    if (length >= 0) _outputStream.setContentLength(length);
  }