📄 protocol.java
字号:
chunk = readLine(streamInput); } catch (IOException ioe) { /* throw new IOException(ioe.getMessage()); */ } if (chunk == null) { throw new IOException("No Chunk Size"); } int i; for (i = 0; i < chunk.length(); i++) { char ch = chunk.charAt(i); if (Character.digit(ch, 16) == -1) break; } /* look at extensions?.... */ size = Integer.parseInt(chunk.substring(0, i), 16); } catch (NumberFormatException e) { throw new IOException("invalid chunk size number format"); } return size; } /** * Skips the CRLF at the end of each chunk in the InputStream. * * @exception IOException if the LF half of the ending CRLF * is missing. */ private void skipEndOfChunkCRLF() throws IOException { int ch; if (stringbuffer.length() > 1) { /* * readChunkSizeNonBlocking does not leave CRLF in the buffer * so assume that the ending CRLF has been skipped already */ return; } // readChunkSizeNonBlocking could have left a \r single in the buffer if (stringbuffer.length() == 1) { if (stringbuffer.charAt(0) != '\r') { // assume that the ending CRLF has been skipped already return; } // remove the '\r' stringbuffer.setLength(0); ch = streamInput.read(); if (ch != '\n') { throw new IOException("missing the LF of an expected CRLF"); } return; } ch = streamInput.read(); if (ch != '\r') { /* * assume readChunkSizeNonBlocking has read the end of the chunk * and that this is the next chunk size, so put the char in the * buffer for readChunkSize and return */ stringbuffer.append(ch); return; } ch = streamInput.read(); if (ch != '\n') { throw new IOException("missing the LF of an expected CRLF"); } } /** * Writes <code>len</code> bytes from the specified byte array * starting at offset <code>off</code> to this output stream. * * <p> * This method can only be called after an OutputStream setup has be * done. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * * @return int number of bytes written to stream * * @exception IOException if an I/O error occurs. In particular, * an <code>IOException</code> is thrown if the output * stream is closed. */ protected int writeBytes(byte b[], int off, int len) throws IOException { int bytesToCopy; if (requestFinished) { throw new IllegalStateException( "Write attempted after request finished"); } if (bytesToWrite == outputDataSize) { /* * Send the bytes in the write buffer as a chunk to the server * so more bytes can be put in the buffer. */ sendRequest(true, false); } /* * Our parent class will call this method in a loop until all the bytes * are written. So this method does not have to process all the bytes * in one call. */ bytesToCopy = outputDataSize - bytesToWrite; if (len < bytesToCopy) { bytesToCopy = len; } System.arraycopy(b, off, writebuf, HTTP_OUTPUT_DATA_OFFSET + bytesToWrite, bytesToCopy); bytesToWrite += bytesToCopy; return bytesToCopy; } /** * If any output data, turn on chunking send it to the server. * * @exception IOException if an I/O error occurs */ public void flush() throws IOException { if (requestFinished) { throw new IllegalStateException( "Flush attempted after request finished"); } if (bytesToWrite > 0) { sendRequest(true, false); } } /** * Get the original URL used to open the HTTP connection. * * @return HTTP URL used in the current connection */ public String getURL() { /* * RFC: Add back protocol stripped by Content Connection. */ return protocol + ":" + saved_url; } /** * Get the protocol scheme parsed from the URL. * * @return protocol scheme is "http" */ public String getProtocol() { return protocol; } /** * Get the host name parsed from the URL. * * @return host name from the parsed URL */ public String getHost() { return url.host; } /** * Get the file path name parsed from the URL. * * @return file path name from the parsed URL */ public String getFile() { return url.path; } /** * Get the fragment identifier parsed from the URL. * * @return reference component from the parsed URL */ public String getRef() { return url.fragment; } /** * Get the query string parsed from the URL. * * @return query string from the parsed URL */ public String getQuery() { return url.query; } /** * Get the query string parsed from the URL. * * @return query string from the parsed URL */ public int getPort() { return url.port; } /** * Get the request method of the current connection. * * @return request method is GET, HEAD or POST * @see #setRequestMethod */ public String getRequestMethod() { return method; } /** * Set the request method of the current connection. * * @param method request method is GET, HEAD or POST * @exception IOException is thrown if the connection is already open * @see #getRequestMethod */ public void setRequestMethod(String method) throws IOException { ensureOpen(); if (streamConnection != null) { throw new IOException("connection already open"); } /* * The request method can not be changed once the output * stream has been opened. */ if (maxOStreams == 0) { return; } if (!method.equals(HEAD) && !method.equals(GET) && !method.equals(POST)) { throw new IOException("unsupported method: " + method); } this.method = method; } /** * Get the request header value for the named property. * * @param key property name of specific HTTP 1.1 header field * @return value of the named property, if found, null otherwise. * @see #setRequestProperty */ public String getRequestProperty(String key) { /* https handles the proxy fields in a different way */ if (key.startsWith("Proxy-")) { return proxyHeaders.getProperty(key); } return reqProperties.getProperty(key); } /** * Set the request header name/value of specific HTTP 1.1 header field. * * @param key property name * @param value property value * @exception IllegalArgumentException is thrown if value contains CRLF. * @exception IOException If some other kind of I/O error occurs. * @see #getRequestProperty */ public void setRequestProperty(String key, String value) throws IOException { int index = 0; ensureOpen(); if (streamConnection != null) { throw new IOException("connection already open"); } /* * The request headers can not be changed once the output * stream has been opened. */ if (maxOStreams == 0) { return; } // Look to see if a hacker embedded any extra fields. for (; ; ) { index = value.indexOf("\r\n", index); if (index == -1) { break; } // Allow legal header value continuations. CRLF + (SP|HT) index += 2; if (index >= value.length() || (value.charAt(index) != ' ' && value.charAt(index) != '\t')) { // illegal values passed for properties - raise an exception throw new IllegalArgumentException("illegal value found"); } } setRequestField(key, value); } /** * Add the named field to the list of request fields. * This method is where a subclass should override properties. * * @param key key for the request header field. * @param value the value for the request header field. */ protected void setRequestField(String key, String value) { /* https handles the proxy fields in a different way */ if (key.startsWith("Proxy-")) { proxyHeaders.setProperty(key, value); return; } /* * if application setRequestProperties("Connection", "close") * then we need to know this & take appropriate default close action */ if ((key.equals("Connection")) && (value.equals("close"))) { ConnectionCloseFlag = true; } if ((key.equals("Transfer-Encoding")) && (value.equals("chunked"))) { chunkedOut = true; } reqProperties.setProperty(key, value); } /** * Get the response code of the current request. * * @return numeric value of the parsed response code * @exception IOException is thrown if a network error ocurrs */ public int getResponseCode() throws IOException { ensureOpen(); sendRequest(); return responseCode; } /** * Get the response message of the current request. * * @return message associated with the current response header * @exception IOException is thrown if a network error ocurrs */ public String getResponseMessage() throws IOException { ensureOpen(); sendRequest(); return responseMsg; } /** * Get the Content-Length for the current response. * * @return length of data to be transmitted after the response headers */ public long getLength() { try { ensureOpen(); sendRequest(); } catch (IOException ioe) { // Fall through to return -1 for length } return contentLength; } /** * Get the Content-Type for the current response. * * @return MIME type of data to be transmitted after the response header */ public String getType() { try { return getHeaderField("content-type"); } catch (IOException x) { return null; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -