📄 urlconnection.java
字号:
* the last one on the returned package list. */ private String getContentHandlerPkgPrefixes() { String packagePrefixList = (String) AccessController.doPrivileged( new sun.security.action.GetPropertyAction(contentPathProp, "")); if (packagePrefixList != "") { packagePrefixList += "|"; } return packagePrefixList + contentClassPrefix; } /** * Tries to determine the content type of an object, based * on the specified "file" component of a URL. * This is a convenience method that can be used by * subclasses that override the <code>getContentType</code> method. * * @param fname a filename. * @return a guess as to what the content type of the object is, * based upon its file name. * @see java.net.URLConnection#getContentType() */ public static String guessContentTypeFromName(String fname) { return getFileNameMap().getContentTypeFor(fname); } /** * Tries to determine the type of an input stream based on the * characters at the beginning of the input stream. This method can * be used by subclasses that override the * <code>getContentType</code> method. * <p> * Ideally, this routine would not be needed. But many * <code>http</code> servers return the incorrect content type; in * addition, there are many nonstandard extensions. Direct inspection * of the bytes to determine the content type is often more accurate * than believing the content type claimed by the <code>http</code> server. * * @param is an input stream that supports marks. * @return a guess at the content type, or <code>null</code> if none * can be determined. * @exception IOException if an I/O error occurs while reading the * input stream. * @see java.io.InputStream#mark(int) * @see java.io.InputStream#markSupported() * @see java.net.URLConnection#getContentType() */ static public String guessContentTypeFromStream(InputStream is) throws IOException { // If we can't read ahead safely, just give up on guessing if (!is.markSupported()) return null; is.mark(12); int c1 = is.read(); int c2 = is.read(); int c3 = is.read(); int c4 = is.read(); int c5 = is.read(); int c6 = is.read(); int c7 = is.read(); int c8 = is.read(); int c9 = is.read(); int c10 = is.read(); int c11 = is.read(); is.reset(); if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) { return "application/java-vm"; } if (c1 == 0xAC && c2 == 0xED) { // next two bytes are version number, currently 0x00 0x05 return "application/x-java-serialized-object"; } if (c1 == '<') { if (c2 == '!' || ((c2 == 'h' && (c3 == 't' && c4 == 'm' && c5 == 'l' || c3 == 'e' && c4 == 'a' && c5 == 'd') || (c2 == 'b' && c3 == 'o' && c4 == 'd' && c5 == 'y'))) || ((c2 == 'H' && (c3 == 'T' && c4 == 'M' && c5 == 'L' || c3 == 'E' && c4 == 'A' && c5 == 'D') || (c2 == 'B' && c3 == 'O' && c4 == 'D' && c5 == 'Y')))) { return "text/html"; } if (c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l' && c6 == ' ') { return "application/xml"; } } // big and little endian UTF-16 encodings, with byte order mark if (c1 == 0xfe && c2 == 0xff) { if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' && c7 == 0 && c8 == 'x') { return "application/xml"; } } if (c1 == 0xff && c2 == 0xfe) { if (c3 == '<' && c4 == 0 && c5 == '?' && c6 == 0 && c7 == 'x' && c8 == 0) { return "application/xml"; } } if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') { return "image/gif"; } if (c1 == '#' && c2 == 'd' && c3 == 'e' && c4 == 'f') { return "image/x-bitmap"; } if (c1 == '!' && c2 == ' ' && c3 == 'X' && c4 == 'P' && c5 == 'M' && c6 == '2') { return "image/x-pixmap"; } if (c1 == 137 && c2 == 80 && c3 == 78 && c4 == 71 && c5 == 13 && c6 == 10 && c7 == 26 && c8 == 10) { return "image/png"; } if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) { if (c4 == 0xE0) { return "image/jpeg"; } /** * File format used by digital cameras to store images. * Exif Format can be read by any application supporting * JPEG. Exif Spec can be found at: * http://www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF */ if ((c4 == 0xE1) && (c7 == 'E' && c8 == 'x' && c9 == 'i' && c10 =='f' && c11 == 0)) { return "image/jpeg"; } if (c4 == 0xEE) { return "image/jpg"; } } if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 && c5 == 0xA1 && c6 == 0xB1 && c7 == 0x1A && c8 == 0xE1) { /* Above is signature of Microsoft Structured Storage. * Below this, could have tests for various SS entities. * For now, just test for FlashPix. */ if (checkfpx(is)) { return "image/vnd.fpx"; } } if (c1 == 0x2E && c2 == 0x73 && c3 == 0x6E && c4 == 0x64) { return "audio/basic"; // .au format, big endian } if (c1 == 0x64 && c2 == 0x6E && c3 == 0x73 && c4 == 0x2E) { return "audio/basic"; // .au format, little endian } if (c1 == 'R' && c2 == 'I' && c3 == 'F' && c4 == 'F') { /* I don't know if this is official but evidence * suggests that .wav files start with "RIFF" - brown */ return "audio/x-wav"; } return null; } /** * Check for FlashPix image data in InputStream is. Return true if * the stream has FlashPix data, false otherwise. Before calling this * method, the stream should have already been checked to be sure it * contains Microsoft Structured Storage data. */ static private boolean checkfpx(InputStream is) throws IOException { /* Test for FlashPix image data in Microsoft Structured Storage format. * In general, should do this with calls to an SS implementation. * Lacking that, need to dig via offsets to get to the FlashPix * ClassID. Details: * * Offset to Fpx ClsID from beginning of stream should be: * * FpxClsidOffset = rootEntryOffset + clsidOffset * * where: clsidOffset = 0x50. * rootEntryOffset = headerSize + sectorSize*sectDirStart * + 128*rootEntryDirectory * * where: headerSize = 0x200 (always) * sectorSize = 2 raised to power of uSectorShift, * which is found in the header at * offset 0x1E. * sectDirStart = found in the header at offset 0x30. * rootEntryDirectory = in general, should search for * directory labelled as root. * We will assume value of 0 (i.e., * rootEntry is in first directory) */ // Mark the stream so we can reset it. 0x100 is enough for the first // few reads, but the mark will have to be reset and set again once // the offset to the root directory entry is computed. That offset // can be very large and isn't know until the stream has been read from is.mark(0x100); // Get the byte ordering located at 0x1E. 0xFE is little endian, // 0xFF is big endian. long toSkip = (long)0x1C; long posn; if ((posn = skipForward(is, toSkip)) < toSkip) { is.reset(); return false; } int c[] = new int[16]; if (readBytes(c, 2, is) < 0) { is.reset(); return false; } int byteOrder = c[0]; posn+=2; int uSectorShift; if (readBytes(c, 2, is) < 0) { is.reset(); return false; } if(byteOrder == 0xFE) { uSectorShift = c[0]; uSectorShift += c[1] << 8; } else { uSectorShift = c[0] << 8; uSectorShift += c[1]; } posn += 2; toSkip = (long)0x30 - posn; long skipped = 0; if ((skipped = skipForward(is, toSkip)) < toSkip) { is.reset(); return false; } posn += skipped; if (readBytes(c, 4, is) < 0) { is.reset(); return false; } int sectDirStart; if(byteOrder == 0xFE) { sectDirStart = c[0]; sectDirStart += c[1] << 8; sectDirStart += c[2] << 16; sectDirStart += c[3] << 24; } else { sectDirStart = c[0] << 24; sectDirStart += c[1] << 16; sectDirStart += c[2] << 8; sectDirStart += c[3]; } posn += 4; is.reset(); // Reset back to the beginning toSkip = (long)0x200 + (long)((int)1<<uSectorShift)*sectDirStart + (long)0x50; // Sanity check! if (toSkip < 0) { return false; } /* * How far can we skip? Is there any performance problem here? * This skip can be fairly long, at least 0x4c650 in at least * one case. Have to assume that the skip will fit in an int. * Leave room to read whole root dir */ is.mark((int)toSkip+0x30); if ((skipForward(is, toSkip)) < toSkip) { is.reset(); return false; } /* should be at beginning of ClassID, which is as follows * (in little-endian byte order): * 00 67 61 56 54 C1 CE 11 85 53 00 AA 00 A1 F9 5B * * This is stored from Windows as long,short,short,char[8] * so for byte order changes, the order only changes for * the first 8 bytes in the ClassID. * * Test against this, ignoring second byte (little-endian) since * this could change depending on part of Fpx file we have. */ if (readBytes(c, 16, is) < 0) { is.reset(); return false; } // little-endian byte order if (byteOrder == 0xFE && c[0] == 0x00 && c[2] == 0x61 && c[3] == 0x56 && c[4] == 0x54 && c[5] == 0xC1 && c[6] == 0xCE && c[7] == 0x11 && c[8] == 0x85 && c[9] == 0x53 && c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 && c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) { is.reset(); return true; } // big-endian byte order else if (c[3] == 0x00 && c[1] == 0x61 && c[0] == 0x56 && c[5] == 0x54 && c[4] == 0xC1 && c[7] == 0xCE && c[6] == 0x11 && c[8] == 0x85 && c[9] == 0x53 && c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 && c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) { is.reset(); return true; } is.reset(); return false; } /** * Tries to read the specified number of bytes from the stream * Returns -1, If EOF is reached before len bytes are read, returns 0 * otherwise */ static private int readBytes(int c[], int len, InputStream is) throws IOException { byte buf[] = new byte[len]; if (is.read(buf, 0, len) < len) { return -1; } // fill the passed in int array for (int i = 0; i < len; i++) { c[i] = buf[i] & 0xff; } return 0; } /** * Skips through the specified number of bytes from the stream * until either EOF is reached, or the specified * number of bytes have been skipped */ static private long skipForward(InputStream is, long toSkip) throws IOException { long eachSkip = 0; long skipped = 0; while (skipped != toSkip) { eachSkip = is.skip(toSkip - skipped); // check if EOF is reached if (eachSkip <= 0) { if (is.read() == -1) { return skipped ; } else { skipped++; } } skipped += eachSkip; } return skipped; }}class UnknownContentHandler extends ContentHandler { public Object getContent(URLConnection uc) throws IOException { return uc.getInputStream(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -