コード例 #1
0
  /* ------------------------------------------------------------ */
  protected void commit() throws IOException {
    if (_response.isCommitted()) return;

    int status = _response.getStatus();
    int length = -1;

    // Check if there is missing content expectations
    if (_inputStream.getExpectContinues() != null) {
      // No input read yet - so assume it never will be
      _inputStream.setExpectContinues(null);
      _inputStream.unsafeSetContentLength(0);
    }

    // Handler forced close, listener stopped or no idle threads left.
    boolean has_close = HttpFields.__Close.equals(_response.getField(HttpFields.__Connection));
    if (!_persistent
        || _close
        || _listener != null && (!_listener.isStarted() || _listener.isOutOfResources())) {
      _close = true;
      if (!has_close) _response.setField(HttpFields.__Connection, HttpFields.__Close);
      has_close = true;
    }
    if (_close) _persistent = false;

    // Determine how to limit content length
    if (_persistent) {
      switch (_dotVersion) {
        case 1:
          {
            String transfer_coding = _response.getField(HttpFields.__TransferEncoding);
            if (transfer_coding == null
                || transfer_coding.length() == 0
                || HttpFields.__Identity.equalsIgnoreCase(transfer_coding)) {
              // if (can have content and no content length)
              if (status != HttpResponse.__304_Not_Modified
                  && status != HttpResponse.__204_No_Content
                  && _response.getField(HttpFields.__ContentLength) == null) {
                if (_completing) {
                  length = _outputStream.getBytesWritten();
                  _response.setContentLength(length);
                } else {
                  // Chunk it!
                  _response.setField(HttpFields.__TransferEncoding, HttpFields.__Chunked);
                  _outputStream.setChunking();
                }
              }
            } else {
              // Use transfer encodings to determine length
              _response.removeField(HttpFields.__ContentLength);
              _outputStream.setChunking();

              if (!HttpFields.__Chunked.equalsIgnoreCase(transfer_coding)) {
                // Check against any TE field
                List te = _request.getAcceptableTransferCodings();
                Enumeration enm =
                    _response.getFieldValues(
                        HttpFields.__TransferEncoding, HttpFields.__separators);
                while (enm.hasMoreElements()) {
                  String coding = (String) enm.nextElement();
                  if (HttpFields.__Identity.equalsIgnoreCase(coding)
                      || HttpFields.__Chunked.equalsIgnoreCase(coding)) continue;
                  if (te == null || !te.contains(coding))
                    throw new HttpException(HttpResponse.__501_Not_Implemented, coding);
                }
              }
            }
          }
          break;

        case 0:
          {
            // if (can have content and no content length)
            _response.removeField(HttpFields.__TransferEncoding);
            if (_keepAlive) {
              if (status != HttpResponse.__304_Not_Modified
                  && status != HttpResponse.__204_No_Content
                  && _response.getField(HttpFields.__ContentLength) == null) {
                if (_completing) {
                  length = _outputStream.getBytesWritten();
                  _response.setContentLength(length);
                  _response.setField(HttpFields.__Connection, HttpFields.__KeepAlive);
                } else {
                  _response.setField(HttpFields.__Connection, HttpFields.__Close);
                  has_close = _close = true;
                  _persistent = false;
                }
              } else _response.setField(HttpFields.__Connection, HttpFields.__KeepAlive);
            } else if (!has_close) _response.setField(HttpFields.__Connection, HttpFields.__Close);

            break;
          }
        default:
          {
            _close = true;
            _persistent = false;
            _keepAlive = false;
          }
      }
    }

    // Mark request as handled.
    _request.setHandled(true);

    _outputStream.writeHeader(_response);
    _outputStream.flush();
  }