📄 protocol.java
字号:
} hostAndPort = url.host + ":" + url.port; return this; } /** * Check if the required permission has been set to allowed. Allowed * is required because this method will not prompt the user. Only * trusted callers have the a permission set to the allowed level. * * @param token token with the HTTP permission set to the allowed level */ private void checkIfPermissionAllowed(SecurityToken token) { token.checkIfPermissionAllowed(HTTP_PERMISSION_NAME); ownerTrusted = true; permissionChecked = true; } /** * Check for the required permission. * * @param name name of resource to insert into the permission question * * @exception IOInterruptedException if another thread interrupts the * calling thread while this method is waiting to preempt the * display. */ private void checkForPermission(String name) throws InterruptedIOException { name = protocol + ":" + name; try { AccessController.checkPermission(HTTP_PERMISSION_NAME, name); permissionChecked = true; } catch (InterruptedSecurityException ise) { throw new InterruptedIOException( "Interrupted while trying to ask the user permission"); } try { AccessController. checkPermission(AccessController.TRUSTED_APP_PERMISSION_NAME); ownerTrusted = true; } catch (SecurityException se) { ownerTrusted = false; } } /** * Open the input stream if it has not already been opened. * * @exception IOException is thrown if it has already been opened. * @return input stream for the current connection */ public InputStream openInputStream() throws IOException { InputStream in; /* * Call into parent to create input stream passed back to the user */ in = super.openInputStream(); /* * Send a request to the web server if there wasn't one * sent already */ sendRequest(); return in; } /** * Open the output stream if it has not already been opened. * * @exception IOException is thrown if it has already been opened. * @return output stream for the current connection */ public OutputStream openOutputStream() throws IOException { OutputStream out; /* * call into parent to create output stream passed back to the user */ out = super.openOutputStream(); /* * Create a byte array output stream for output buffering * once the user calls flush() this gets written to stream */ writebuf = new byte[outputBufferSize]; return out; } /** * Reads up to <code>len</code> bytes of data from the input stream into * an array of bytes. * This method reads NonChunked http connection input streams. * This method can only be called after the InputStream setup is complete. * * @param b the buffer into which the data is read. * @param off the start offset in array <code>b</code> * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of * the stream has been reached. * @exception IOException if an I/O error occurs. */ protected int readBytes(byte b[], int off, int len) throws IOException { int rc; /* * Be consistent about returning EOF once encountered. */ if (eof) { return (-1); } /* * The InputStream close behavior will be different if close is called * from another thread when reading. */ synchronized (streamInput) { readInProgress = true; } try { /* * If the http connection is chunked, call the readBytesChunked * method */ if (chunkedIn || chunksize > 0) { /* * Non-chunked data of known length is treated as one big chunk */ return readBytesChunked(b, off, len); } /* * Non-chunked unknown length */ if (bytesleft == 0) { /* * the internal input stream buffer is empty, read from the * stream */ if (len >= inputBufferSize) { /* * No need to buffer, if the caller has given a big buffer. */ rc = streamInput.read(b, off, len); } else { rc = streamInput.read(readbuf, 0, inputBufferSize); bytesleft = rc; bytesread = 0; } if (rc == -1) { /* * The next call to this method should not read. */ eof = true; return -1; } totalbytesread += rc; if (bytesleft == 0) { /* * The data was read directly into the caller's buffer. */ return rc; } } rc = readFromBuffer(b, off, len); return rc; } finally { synchronized (streamInput) { readInProgress = false; } } } /** * Reads up to <code>len</code> bytes of data from the internal buffer into * an array of bytes. * * @param b the buffer into which the data is read. * @param off the start offset in array <code>b</code> * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of * the stream has been reached. * @exception IOException if an I/O error occurs. */ private int readFromBuffer(byte b[], int off, int len) throws IOException { /* * copy http buffer data into user buffer, then * increment and decrement counters */ int rc; if (len > bytesleft) { rc = bytesleft; } else { rc = len; } System.arraycopy(readbuf, bytesread, b, off, rc); bytesleft -= rc; bytesread += rc; return rc; } /** * Returns the number of bytes that can be read (or skipped over) from * this input stream without blocking by the next caller of a method for * this input stream. The next caller might be the same thread or * another thread. * * @return the number of bytes that can be read from this input stream * without blocking. * @exception IOException if an I/O error occurs. */ public int available() throws IOException { int bytesAvailable; /* * Only after all the headers have been processed can * an accurate available count be provided. */ if (!requestFinished || eof) { return 0; } /* * Regardless of chunked or non-chunked transfers - * if data is already buffered return the amount * buffered. */ if (bytesleft > 0) { return bytesleft; } if (chunkedIn && totalbytesread == chunksize) { /* * Check if a new chunk size header is available. */ return readChunkSizeNonBlocking(); } /* * Otherwise rely on the lower level stream available * count for the nonchunked input stream. */ bytesAvailable = streamInput.available(); if (chunksize <= bytesAvailable) { return chunksize; } return bytesAvailable; } /** * Read a chunk size header into the readLine buffer * without blocking. The stringbuffer is populated * with characters one at a time. This routine is design * so that a partial chunk size header could be read * and then completed by a blocking read of the chunk * or a subsequent call to available. * * @return available data that can be read */ int readChunkSizeNonBlocking() throws IOException { /* * Check the underlying stream to see how many bytes are * available. Do not read beyond the available characters, * because that would block. */ int len = streamInput.available(); /* Reset the last character from the current readLine buffer. */ int sblen = stringbuffer.length(); char lastchar = '\0'; if (sblen > 0) { lastchar = stringbuffer.charAt(sblen - 1); } int size = -1; /* * Loop through the available characters until a full * chunk size header is in the readLine buffer. */ for (; len > 0; len--) { char c = (char) streamInput.read(); if (lastchar == '\r' && c == '\n') { // remove the '\r' from the buffer stringbuffer.setLength(stringbuffer.length() - 1); if (stringbuffer.length() > 0) { // this is a size, not the CRLF at the end of a chunk try { String temp = stringbuffer.toString(); int semi = temp.indexOf(';'); // skip extensions if (semi > 0) { temp = temp.substring(0, semi); } /* * Reset the string buffer length so readline() will * not parse this line. */ stringbuffer.setLength(0); size = Integer.parseInt(temp, 16); } catch (NumberFormatException nfe) { throw new IOException( "invalid chunk size number format"); } break; } } else { stringbuffer.append(c); lastchar = c; } } if (size < 0) { // did not get the size return 0; } /* * Update the chunksize and the total bytes that have been * read from the chunk. This will trigger the next call to * readBytes to refill the buffers as needed. */ chunksize = size; if (size == 0) { eof = true; return 0; } totalbytesread = 0; /* * If the full chunk is available, return chunksize, * otherwise return the remainder of the available * bytes (e.g. partial chunk). */ return (chunksize < len ? chunksize : len); } /** * Reads up to <code>len</code> bytes of data from the input stream into * an array of bytes. * This method reads Chunked and known length non-chunked http connection * input streams. For non-chunked set the field <code>chunkedIn</code> * should be false. * * @param b the buffer into which the data is read. * @param off the start offset in array <code>b</code> * at which the data is written. * @param len the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of * the stream has been reached. * @exception IOException if an I/O error occurs. */ protected int readBytesChunked(byte b[], int off, int len) throws IOException { int rc; if (bytesleft == 0) { /* * the internal input stream buffer is empty, read from the stream */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -