📄 webresponse.java
字号:
private String _characterSet; private WebRequest _refreshRequest; private int _refreshDelay = -1; // initialized to invalid value private String _responseText; private InputStream _inputStream; private final URL _pageURL; private final WebClient _client; private Scriptable _scriptable; protected void loadResponseText() throws IOException { if (_responseText != null) throw new IllegalStateException( "May only invoke loadResponseText once" ); _responseText = ""; InputStream inputStream = getInputStream(); try { final int contentLength = this.encodedUsingGZIP() ? -1 : getContentLength(); int bytesRemaining = contentLength < 0 ? Integer.MAX_VALUE : contentLength; byte[] bytes = readFromStream( inputStream, bytesRemaining ); readTags( bytes ); _responseText = new String( bytes, getCharacterSet() ); _inputStream = new ByteArrayInputStream( bytes ); if (HttpUnitOptions.isCheckContentLength() && contentLength >= 0 && bytes.length != contentLength) { throw new IOException("Truncated message. Expected length: " + contentLength + ", Actual length: " + bytes.length); } } finally { inputStream.close(); } } private byte[] readFromStream( InputStream inputStream, int maxBytes ) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[8 * 1024]; int count = 0; if (maxBytes > 0) { do { outputStream.write( buffer, 0, count ); maxBytes -= count; if (maxBytes <= 0) break; count = inputStream.read( buffer, 0, Math.min( maxBytes, buffer.length ) ); } while (count != -1); } else { do { outputStream.write( buffer, 0, count ); int available = getAvailableBytes( inputStream ); count = (available == 0) ? -1 : inputStream.read( buffer, 0, buffer.length ); } while (count != -1); } byte[] bytes = outputStream.toByteArray(); return bytes; } private int getAvailableBytes( InputStream inputStream ) throws IOException { int timeLeft = UNKNOWN_LENGTH_TIMEOUT; int available; do { timeLeft -= UNKNOWN_LENGTH_RETRY_INTERVAL; try { Thread.sleep( UNKNOWN_LENGTH_RETRY_INTERVAL ); } catch (InterruptedException e) {} available = inputStream.available(); } while (available == 0 && timeLeft > 0); return available; } private void readTags( byte[] rawMessage ) throws UnsupportedEncodingException, MalformedURLException { ByteTagParser parser = new ByteTagParser( rawMessage ); ByteTag tag = parser.getNextTag(); while (tag != null ) { if (tag.getName().equalsIgnoreCase( "meta" )) processMetaTag( tag ); if (tag.getName().equalsIgnoreCase( "base" )) processBaseTag( tag ); if (tag.getName().equalsIgnoreCase( "noscript") && HttpUnitOptions.isScriptingEnabled()) { do { tag = parser.getNextTag(); } while (tag.getName().equalsIgnoreCase( "/noscript") ); } tag = parser.getNextTag(); } } private void processBaseTag( ByteTag tag ) throws MalformedURLException { if (tag.getAttribute( "href" ) != null) _baseURL = new URL( getURL(), tag.getAttribute( "href" ) ); if (tag.getAttribute( "target" ) != null) _baseTarget = tag.getAttribute( "target" ); } private void processMetaTag( ByteTag tag ) { if (isHttpEquivMetaTag( tag, "content-type" )) { inferContentType( tag.getAttribute( "content" ) ); } else if (isHttpEquivMetaTag( tag, "refresh" )) { inferRefreshHeader( tag.getAttribute( "content" ) ); } } private boolean isHttpEquivMetaTag( ByteTag tag, String headerName ) { return headerName.equalsIgnoreCase( tag.getAttribute( "http_equiv" ) ) || headerName.equalsIgnoreCase( tag.getAttribute( "http-equiv" ) ); } private void inferRefreshHeader( String refreshHeader ) { String originalHeader = getHeaderField( "Refresh" ); if (originalHeader == null) { _refreshHeader = refreshHeader; } } private void readRefreshRequest() { if (_refreshDelay >= 0) return; _refreshDelay = 0; String refreshHeader = _refreshHeader != null ? _refreshHeader : getHeaderField( "Refresh" ); if (refreshHeader == null) return; int semicolonIndex = refreshHeader.indexOf( ';' ); if (semicolonIndex < 0) { interpretRefreshHeaderElement( refreshHeader, refreshHeader ); } else { interpretRefreshHeaderElement( refreshHeader.substring( 0, semicolonIndex ), refreshHeader ); interpretRefreshHeaderElement( refreshHeader.substring( semicolonIndex+1 ), refreshHeader ); } if (_refreshRequest == null) _refreshRequest = new GetMethodWebRequest( _pageURL, _pageURL.toString(), _frame.getName() ); } private void interpretRefreshHeaderElement( String token, String refreshHeader ) { if (token.length() == 0) return; try { if (Character.isDigit( token.charAt(0) )) { _refreshDelay = Integer.parseInt( token ); } else { _refreshRequest = new GetMethodWebRequest( _pageURL, getRefreshURL( token ), _frame.getName() ); } } catch (NumberFormatException e) { System.out.println( "Unable to interpret refresh tag: \"" + refreshHeader + '"' ); } } private String getRefreshURL( String text ) { text = text.trim(); if (!text.toUpperCase().startsWith( "URL" )) { return HttpUnitUtils.stripQuotes( text ); } else { int splitIndex = text.indexOf( '=' ); String value = text.substring( splitIndex+1 ).trim(); return HttpUnitUtils.replaceEntities( HttpUnitUtils.stripQuotes( value ) ); } } private void inferContentType( String contentTypeHeader ) { String originalHeader = getHeaderField( "Content-type" ); if (originalHeader == null || originalHeader.indexOf( "charset" ) < 0) { setContentTypeHeader( contentTypeHeader ); } } CookieJar getCookieJar() { if (_cookies == null) _cookies = new CookieJar( this ); return _cookies; } private CookieJar _cookies; private void readContentTypeHeader() { String contentHeader = (_contentHeader != null) ? _contentHeader : getHeaderField( "Content-type" ); if (contentHeader == null) { _contentType = HttpUnitOptions.getDefaultContentType(); setCharacterSet( HttpUnitOptions.getDefaultCharacterSet() ); _contentHeader = _contentType + ";charset=" + _characterSet; } else { String[] parts = HttpUnitUtils.parseContentTypeHeader( contentHeader ); _contentType = parts[0]; if (parts[1] != null) setCharacterSet( parts[1] ); } } private WebFrame[] getFrames() throws SAXException { return getReceivedPage().getFrames(); } HTMLPage getReceivedPage() throws SAXException { if (_page == null) { try { _parsingPage = true; if (!isHTML()) throw new NotHTMLException( getContentType() ); _page = new HTMLPage( this, _frame, _baseURL, _baseTarget, getCharacterSet() ); _page.parse( getText(), _pageURL ); if (_page == null) throw new IllegalStateException( "replaceText called in the middle of getReceivedPage()" ); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException( e.toString() ); } finally { _parsingPage = false; } } return _page; } private static String _defaultEncoding; private final static String[] DEFAULT_ENCODING_CANDIDATES = { HttpUnitUtils.DEFAULT_CHARACTER_SET, "us-ascii", "utf-8", "utf8" }; static String getDefaultEncoding() { if (_defaultEncoding == null) { for (int i = 0; i < DEFAULT_ENCODING_CANDIDATES.length; i++) { try { _defaultEncoding = DEFAULT_ENCODING_CANDIDATES[i]; "abcd".getBytes( _defaultEncoding ); // throws an exception if the encoding is not supported return _defaultEncoding; } catch (UnsupportedEncodingException e) { } } } return (_defaultEncoding = System.getProperty( "file.encoding" )); } private void setCharacterSet( String characterSet ) { if (characterSet == null) return; try { "abcd".getBytes( characterSet ); _characterSet = characterSet; } catch (UnsupportedEncodingException e) { _characterSet = getDefaultEncoding(); } } void setCookie( String name, String value ) { _client.putCookie( name, value ); } String getCookieHeader() { return _client.getCookieJar().getCookieHeaderField( getURL() ); } String getReferer() { return null; }//======================================================================================= static class ByteTag { ByteTag( byte[] buffer, int start, int length ) throws UnsupportedEncodingException { _buffer = new String( buffer, start, length, WebResponse.getDefaultEncoding() ).toCharArray(); _name = nextToken(); String attribute = ""; String token = nextToken(); while (token.length() != 0) { if (token.equals( "=" ) && attribute.length() != 0) { getAttributes().put( attribute.toLowerCase(), nextToken() ); attribute = ""; } else { if (attribute.length() > 0) getAttributes().put( attribute.toLowerCase(), "" ); attribute = token; } token = nextToken(); } } public String getName() { return _name; } public String getAttribute( String attributeName ) { return (String) getAttributes().get( attributeName ); } public String toString() { return "ByteTag[ name=" + _name + ";attributes = " + _attributes + ']'; } private Hashtable getAttributes() { if (_attributes == null) _attributes = new Hashtable(); return _attributes; } private String _name = ""; private Hashtable _attributes; private char[] _buffer; private int _start; private int _end = -1; private String nextToken() { _start = _end+1; while (_start < _buffer.length && Character.isWhitespace( _buffer[ _start ] )) _start++; if (_start >= _buffer.length) { return ""; } else if (_buffer[ _start ] == '"') { for (_end = _start+1; _end < _buffer.length && _buffer[ _end ] != '"'; _end++); return new String( _buffer, _start+1, _end-_start-1 ); } else if (_buffer[ _start ] == '\'') { for (_end = _start+1; _end < _buffer.length && _buffer[ _end ] != '\''; _end++); return new String( _buffer, _start+1, _end-_start-1 ); } else if (_buffer[ _start ] == '=') { _end = _start; return "="; } else { for (_end = _start+1; _end < _buffer.length && _buffer[ _end ] != '=' && !Character.isWhitespace( _buffer[ _end ] ); _end++); return new String( _buffer, _start, (_end--)-_start ); } } }//======================================================================================= static class ByteTagParser { ByteTagParser( byte[] buffer ) { _buffer = buffer; } ByteTag getNextTag() throws UnsupportedEncodingException { ByteTag byteTag = null; do { _start = _end+1; while (_start < _buffer.length && _buffer[ _start ] != '<') _start++; for (_end =_start+1; _end < _buffer.length && _buffer[ _end ] != '>'; _end++); if (_end >= _buffer.length || _end < _start) return null; byteTag = new ByteTag( _buffer, _start+1, _end-_start-1 ); if (byteTag.getName().equalsIgnoreCase("script")) { _scriptDepth++; return byteTag; } if (byteTag.getName().equalsIgnoreCase("/script")) _scriptDepth--; } while (_scriptDepth > 0); return byteTag; } private int _scriptDepth = 0; private int _start = 0; private int _end = -1; private byte[] _buffer; }}//=======================================================================================class DefaultWebResponse extends WebResponse { DefaultWebResponse( String text ) { this( null, null, text ); } DefaultWebResponse( WebClient client, URL url, String text ) { this( client, FrameSelector.TOP_FRAME, url, text ); } DefaultWebResponse( WebClient client, FrameSelector frame, URL url, String text ) { super( client, frame, url, text ); } /** * Returns the response code associated with this response. **/ public int getResponseCode() { return HttpURLConnection.HTTP_OK; } /** * Returns the response message associated with this response. **/ public String getResponseMessage() { return "OK"; } public String[] getHeaderFieldNames() { return new String[] { "Content-type" }; } /** * Returns the value for the specified header field. If no such field is defined, will return null. **/ public String getHeaderField( String fieldName ) { if (fieldName.equalsIgnoreCase( "Content-type" )) { return "text/html; charset=us-ascii"; } else { return null; } } public String[] getHeaderFields( String fieldName ) { String value = getHeaderField( fieldName ); return value == null ? new String[0] : new String[]{ value }; } public String toString() { try { return "DefaultWebResponse [" + getText() + "]"; } catch (IOException e) { // should never happen return "DefaultWebResponse [???]"; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -