/* ------------------------------------------------------------ */ private void generateRequestLine(MetaData.Request request, ByteBuffer header) { header.put(StringUtil.getBytes(request.getMethod())); header.put((byte) ' '); header.put(StringUtil.getBytes(request.getURIString())); switch (request.getVersion()) { case HTTP_1_0: case HTTP_1_1: header.put((byte) ' '); header.put(request.getVersion().toBytes()); break; default: throw new IllegalStateException(); } header.put(HttpTokens.CRLF); }
/* ------------------------------------------------------------ */ public Result generateRequest( MetaData.Request info, ByteBuffer header, ByteBuffer chunk, ByteBuffer content, boolean last) throws IOException { switch (_state) { case START: { if (info == null) return Result.NEED_INFO; // Do we need a request header if (header == null) return Result.NEED_HEADER; // If we have not been told our persistence, set the default if (_persistent == null) { _persistent = info.getVersion().ordinal() > HttpVersion.HTTP_1_0.ordinal(); if (!_persistent && HttpMethod.CONNECT.is(info.getMethod())) _persistent = true; } // prepare the header int pos = BufferUtil.flipToFill(header); try { // generate ResponseLine generateRequestLine(info, header); if (info.getVersion() == HttpVersion.HTTP_0_9) _noContent = true; else generateHeaders(info, header, content, last); boolean expect100 = info.getFields().contains(HttpHeader.EXPECT, HttpHeaderValue.CONTINUE.asString()); if (expect100) { _state = State.COMMITTED; } else { // handle the content. int len = BufferUtil.length(content); if (len > 0) { _contentPrepared += len; if (isChunking()) prepareChunk(header, len); } _state = last ? State.COMPLETING : State.COMMITTED; } return Result.FLUSH; } catch (Exception e) { String message = (e instanceof BufferOverflowException) ? "Request header too large" : e.getMessage(); throw new IOException(message, e); } finally { BufferUtil.flipToFlush(header, pos); } } case COMMITTED: { int len = BufferUtil.length(content); if (len > 0) { // Do we need a chunk buffer? if (isChunking()) { // Do we need a chunk buffer? if (chunk == null) return Result.NEED_CHUNK; BufferUtil.clearToFill(chunk); prepareChunk(chunk, len); BufferUtil.flipToFlush(chunk, 0); } _contentPrepared += len; } if (last) _state = State.COMPLETING; return len > 0 ? Result.FLUSH : Result.CONTINUE; } case COMPLETING: { if (BufferUtil.hasContent(content)) { if (LOG.isDebugEnabled()) LOG.debug("discarding content in COMPLETING"); BufferUtil.clear(content); } if (isChunking()) { // Do we need a chunk buffer? if (chunk == null) return Result.NEED_CHUNK; BufferUtil.clearToFill(chunk); prepareChunk(chunk, 0); BufferUtil.flipToFlush(chunk, 0); _endOfContent = EndOfContent.UNKNOWN_CONTENT; return Result.FLUSH; } _state = State.END; return Boolean.TRUE.equals(_persistent) ? Result.DONE : Result.SHUTDOWN_OUT; } case END: if (BufferUtil.hasContent(content)) { if (LOG.isDebugEnabled()) LOG.debug("discarding content in COMPLETING"); BufferUtil.clear(content); } return Result.DONE; default: throw new IllegalStateException(); } }