📄 httpgenerator.java
字号:
{ _header.put(CONNECTION_CLOSE); if (connection!=null) { _header.setPutIndex(_header.putIndex()-2); _header.put((byte)','); _header.put(connection.toString().getBytes()); _header.put(CRLF); } } else if (keep_alive) { _header.put(CONNECTION_KEEP_ALIVE); if (connection!=null) { _header.setPutIndex(_header.putIndex()-2); _header.put((byte)','); _header.put(connection.toString().getBytes()); _header.put(CRLF); } } else if (connection!=null) { _header.put(CONNECTION_); _header.put(connection.toString().getBytes()); _header.put(CRLF); } } if (!has_server && _status>100 && getSendServerVersion()) _header.put(SERVER); // end the header. _header.put(HttpTokens.CRLF); _state = STATE_CONTENT; } /* ------------------------------------------------------------ */ /** * Complete the message. * * @throws IOException */ public void complete() throws IOException { if (_state == STATE_END) return; super.complete(); if (_state < STATE_FLUSHING) { _state = STATE_FLUSHING; if (_contentLength == HttpTokens.CHUNKED_CONTENT) _needEOC = true; } flush(); } /* ------------------------------------------------------------ */ public long flush() throws IOException { try { if (_state == STATE_HEADER) throw new IllegalStateException("State==HEADER"); prepareBuffers(); if (_endp == null) { if (_needCRLF && _buffer!=null) _buffer.put(HttpTokens.CRLF); if (_needEOC && _buffer!=null && !_head) _buffer.put(LAST_CHUNK); _needCRLF=false; _needEOC=false; return 0; } // Keep flushing while there is something to flush (except break below) int total= 0; long last_len = -1; Flushing: while (true) { int len = -1; int to_flush = ((_header != null && _header.length() > 0)?4:0) | ((_buffer != null && _buffer.length() > 0)?2:0) | ((_bypass && _content != null && _content.length() > 0)?1:0); switch (to_flush) { case 7: throw new IllegalStateException(); // should never happen! case 6: len = _endp.flush(_header, _buffer, null); break; case 5: len = _endp.flush(_header, _content, null); break; case 4: len = _endp.flush(_header); break; case 3: throw new IllegalStateException(); // should never happen! case 2: len = _endp.flush(_buffer); break; case 1: len = _endp.flush(_content); break; case 0: { // Nothing more we can write now. if (_header != null) _header.clear(); _bypass = false; _bufferChunked = false; if (_buffer != null) { _buffer.clear(); if (_contentLength == HttpTokens.CHUNKED_CONTENT) { // reserve some space for the chunk header _buffer.setPutIndex(CHUNK_SPACE); _buffer.setGetIndex(CHUNK_SPACE); // Special case handling for small left over buffer from // an addContent that caused a buffer flush. if (_content != null && _content.length() < _buffer.space() && _state != STATE_FLUSHING) { _buffer.put(_content); _content.clear(); _content = null; break Flushing; } } } // Are we completely finished for now? if (!_needCRLF && !_needEOC && (_content == null || _content.length() == 0)) { if (_state == STATE_FLUSHING) _state = STATE_END; if (_state==STATE_END && _close && _status!=100) _endp.close(); break Flushing; } // Try to prepare more to write. prepareBuffers(); } } // break If we failed to flush if (len > 0) total+=len; else break Flushing; last_len = len; } return total; } catch (IOException e) { Log.ignore(e); throw (e instanceof EofException) ? e:new EofException(e); } } /* ------------------------------------------------------------ */ private void prepareBuffers() { // if we are not flushing an existing chunk if (!_bufferChunked) { // Refill buffer if possible if (_content != null && _content.length() > 0 && _buffer != null && _buffer.space() > 0) { int len = _buffer.put(_content); _content.skip(len); if (_content.length() == 0) _content = null; } // Chunk buffer if need be if (_contentLength == HttpTokens.CHUNKED_CONTENT) { int size = _buffer == null ? 0 : _buffer.length(); if (size > 0) { // Prepare a chunk! _bufferChunked = true; // Did we leave space at the start of the buffer. if (_buffer.getIndex() == CHUNK_SPACE) { // Oh yes, goodie! let's use it then! _buffer.poke(_buffer.getIndex() - 2, HttpTokens.CRLF, 0, 2); _buffer.setGetIndex(_buffer.getIndex() - 2); BufferUtil.prependHexInt(_buffer, size); if (_needCRLF) { _buffer.poke(_buffer.getIndex() - 2, HttpTokens.CRLF, 0, 2); _buffer.setGetIndex(_buffer.getIndex() - 2); _needCRLF = false; } } else { // No space so lets use the header buffer. if (_needCRLF) { if (_header.length() > 0) throw new IllegalStateException("EOC"); _header.put(HttpTokens.CRLF); _needCRLF = false; } BufferUtil.putHexInt(_header, size); _header.put(HttpTokens.CRLF); } // Add end chunk trailer. if (_buffer.space() >= 2) _buffer.put(HttpTokens.CRLF); else _needCRLF = true; } // If we need EOC and everything written if (_needEOC && (_content == null || _content.length() == 0)) { if (_needCRLF) { if (_buffer == null && _header.space() >= 2) { _header.put(HttpTokens.CRLF); _needCRLF = false; } else if (_buffer!=null && _buffer.space() >= 2) { _buffer.put(HttpTokens.CRLF); _needCRLF = false; } } if (!_needCRLF && _needEOC) { if (_buffer == null && _header.space() >= LAST_CHUNK.length) { if (!_head) { _header.put(LAST_CHUNK); _bufferChunked=true; } _needEOC = false; } else if (_buffer!=null && _buffer.space() >= LAST_CHUNK.length) { if (!_head) { _buffer.put(LAST_CHUNK); _bufferChunked=true; } _needEOC = false; } } } } } if (_content != null && _content.length() == 0) _content = null; } public int getBytesBuffered() { return(_header==null?0:_header.length())+ (_buffer==null?0:_buffer.length())+ (_content==null?0:_content.length()); } public boolean isEmpty() { return (_header==null||_header.length()==0) && (_buffer==null||_buffer.length()==0) && (_content==null||_content.length()==0); } public String toString() { return "HttpGenerator s="+_state+ " h="+(_header==null?"null":(""+_header.length()))+ " b="+(_buffer==null?"null":(""+_buffer.length()))+ " c="+(_content==null?"null":(""+_content.length())); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -