use of sun.net.www.MeteredStream in project jdk8u_jdk by JetBrains.
the class FtpURLConnection method getInputStream.
/**
* Get the InputStream to retreive the remote file. It will issue the
* "get" (or "dir") command to the ftp server.
*
* @return the <code>InputStream</code> to the connection.
*
* @throws IOException if already opened for output
* @throws FtpProtocolException if errors occur during the transfert.
*/
@Override
public InputStream getInputStream() throws IOException {
if (!connected) {
connect();
}
if (http != null) {
return http.getInputStream();
}
if (os != null) {
throw new IOException("Already opened for output");
}
if (is != null) {
return is;
}
MessageHeader msgh = new MessageHeader();
boolean isAdir = false;
try {
decodePath(url.getPath());
if (filename == null || type == DIR) {
ftp.setAsciiType();
cd(pathname);
if (filename == null) {
is = new FtpInputStream(ftp, ftp.list(null));
} else {
is = new FtpInputStream(ftp, ftp.nameList(filename));
}
} else {
if (type == ASCII) {
ftp.setAsciiType();
} else {
ftp.setBinaryType();
}
cd(pathname);
is = new FtpInputStream(ftp, ftp.getFileStream(filename));
}
/* Try to get the size of the file in bytes. If that is
successful, then create a MeteredStream. */
try {
long l = ftp.getLastTransferSize();
msgh.add("content-length", Long.toString(l));
if (l > 0) {
// Wrap input stream with MeteredStream to ensure read() will always return -1
// at expected length.
// Check if URL should be metered
boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, "GET");
ProgressSource pi = null;
if (meteredInput) {
pi = new ProgressSource(url, "GET", l);
pi.beginTracking();
}
is = new MeteredStream(is, pi, l);
}
} catch (Exception e) {
e.printStackTrace();
/* do nothing, since all we were doing was trying to
get the size in bytes of the file */
}
if (isAdir) {
msgh.add("content-type", "text/plain");
msgh.add("access-type", "directory");
} else {
msgh.add("access-type", "file");
String ftype = guessContentTypeFromName(fullpath);
if (ftype == null && is.markSupported()) {
ftype = guessContentTypeFromStream(is);
}
if (ftype != null) {
msgh.add("content-type", ftype);
}
}
} catch (FileNotFoundException e) {
try {
cd(fullpath);
/* if that worked, then make a directory listing
and build an html stream with all the files in
the directory */
ftp.setAsciiType();
is = new FtpInputStream(ftp, ftp.list(null));
msgh.add("content-type", "text/plain");
msgh.add("access-type", "directory");
} catch (IOException ex) {
throw new FileNotFoundException(fullpath);
} catch (FtpProtocolException ex2) {
throw new FileNotFoundException(fullpath);
}
} catch (FtpProtocolException ftpe) {
throw new IOException(ftpe);
}
setProperties(msgh);
return is;
}
use of sun.net.www.MeteredStream in project jdk8u_jdk by JetBrains.
the class HttpClient method parseHTTPHeader.
private boolean parseHTTPHeader(MessageHeader responses, ProgressSource pi, HttpURLConnection httpuc) throws IOException {
/* If "HTTP/*" is found in the beginning, return true. Let
* HttpURLConnection parse the mime header itself.
*
* If this isn't valid HTTP, then we don't try to parse a header
* out of the beginning of the response into the responses,
* and instead just queue up the output stream to it's very beginning.
* This seems most reasonable, and is what the NN browser does.
*/
keepAliveConnections = -1;
keepAliveTimeout = 0;
boolean ret = false;
byte[] b = new byte[8];
try {
int nread = 0;
serverInput.mark(10);
while (nread < 8) {
int r = serverInput.read(b, nread, 8 - nread);
if (r < 0) {
break;
}
nread += r;
}
String keep = null;
ret = b[0] == 'H' && b[1] == 'T' && b[2] == 'T' && b[3] == 'P' && b[4] == '/' && b[5] == '1' && b[6] == '.';
serverInput.reset();
if (ret) {
// is valid HTTP - response started w/ "HTTP/1."
responses.parseHeader(serverInput);
// we've finished parsing http headers
// check if there are any applicable cookies to set (in cache)
CookieHandler cookieHandler = httpuc.getCookieHandler();
if (cookieHandler != null) {
URI uri = ParseUtil.toURI(url);
// it is resolved.
if (uri != null)
cookieHandler.put(uri, responses.getHeaders());
}
/* decide if we're keeping alive:
* This is a bit tricky. There's a spec, but most current
* servers (10/1/96) that support this differ in dialects.
* If the server/client misunderstand each other, the
* protocol should fall back onto HTTP/1.0, no keep-alive.
*/
if (usingProxy) {
// not likely a proxy will return this
keep = responses.findValue("Proxy-Connection");
}
if (keep == null) {
keep = responses.findValue("Connection");
}
if (keep != null && keep.toLowerCase(Locale.US).equals("keep-alive")) {
/* some servers, notably Apache1.1, send something like:
* "Keep-Alive: timeout=15, max=1" which we should respect.
*/
HeaderParser p = new HeaderParser(responses.findValue("Keep-Alive"));
if (p != null) {
/* default should be larger in case of proxy */
keepAliveConnections = p.findInt("max", usingProxy ? 50 : 5);
keepAliveTimeout = p.findInt("timeout", usingProxy ? 60 : 5);
}
} else if (b[7] != '0') {
/*
* We're talking 1.1 or later. Keep persistent until
* the server says to close.
*/
if (keep != null) {
/*
* The only Connection token we understand is close.
* Paranoia: if there is any Connection header then
* treat as non-persistent.
*/
keepAliveConnections = 1;
} else {
keepAliveConnections = 5;
}
}
} else if (nread != 8) {
if (!failedOnce && requests != null) {
failedOnce = true;
if (getRequestMethod().equals("CONNECT") || streaming || (httpuc.getRequestMethod().equals("POST") && !retryPostProp)) {
// do not retry the request
} else {
closeServer();
cachedHttpClient = false;
openServer();
if (needsTunneling()) {
MessageHeader origRequests = requests;
httpuc.doTunneling();
requests = origRequests;
}
afterConnect();
writeRequests(requests, poster);
return parseHTTP(responses, pi, httpuc);
}
}
throw new SocketException("Unexpected end of file from server");
} else {
// we can't vouche for what this is....
responses.set("Content-type", "unknown/unknown");
}
} catch (IOException e) {
throw e;
}
int code = -1;
try {
String resp;
resp = responses.getValue(0);
/* should have no leading/trailing LWS
* expedite the typical case by assuming it has
* form "HTTP/1.x <WS> 2XX <mumble>"
*/
int ind;
ind = resp.indexOf(' ');
while (resp.charAt(ind) == ' ') ind++;
code = Integer.parseInt(resp.substring(ind, ind + 3));
} catch (Exception e) {
}
if (code == HTTP_CONTINUE && ignoreContinue) {
responses.reset();
return parseHTTPHeader(responses, pi, httpuc);
}
long cl = -1;
/*
* Set things up to parse the entity body of the reply.
* We should be smarter about avoid pointless work when
* the HTTP method and response code indicate there will be
* no entity body to parse.
*/
String te = responses.findValue("Transfer-Encoding");
if (te != null && te.equalsIgnoreCase("chunked")) {
serverInput = new ChunkedInputStream(serverInput, this, responses);
/*
* If keep alive not specified then close after the stream
* has completed.
*/
if (keepAliveConnections <= 1) {
keepAliveConnections = 1;
keepingAlive = false;
} else {
keepingAlive = true;
}
failedOnce = false;
} else {
/*
* If it's a keep alive connection then we will keep
* (alive if :-
* 1. content-length is specified, or
* 2. "Not-Modified" or "No-Content" responses - RFC 2616 states that
* 204 or 304 response must not include a message body.
*/
String cls = responses.findValue("content-length");
if (cls != null) {
try {
cl = Long.parseLong(cls);
} catch (NumberFormatException e) {
cl = -1;
}
}
String requestLine = requests.getKey(0);
if ((requestLine != null && (requestLine.startsWith("HEAD"))) || code == HttpURLConnection.HTTP_NOT_MODIFIED || code == HttpURLConnection.HTTP_NO_CONTENT) {
cl = 0;
}
if (keepAliveConnections > 1 && (cl >= 0 || code == HttpURLConnection.HTTP_NOT_MODIFIED || code == HttpURLConnection.HTTP_NO_CONTENT)) {
keepingAlive = true;
failedOnce = false;
} else if (keepingAlive) {
/* Previously we were keeping alive, and now we're not. Remove
* this from the cache (but only here, once) - otherwise we get
* multiple removes and the cache count gets messed up.
*/
keepingAlive = false;
}
}
if (cl > 0) {
if (pi != null) {
// Progress monitor is enabled
pi.setContentType(responses.findValue("content-type"));
}
if (isKeepingAlive()) {
// Wrap KeepAliveStream if keep alive is enabled.
logFinest("KeepAlive stream used: " + url);
serverInput = new KeepAliveStream(serverInput, pi, cl, this);
failedOnce = false;
} else {
serverInput = new MeteredStream(serverInput, pi, cl);
}
} else if (cl == -1) {
if (pi != null) {
// Progress monitoring is enabled.
pi.setContentType(responses.findValue("content-type"));
// Wrap MeteredStream for tracking indeterministic
// progress, even if the input stream is ChunkedInputStream.
serverInput = new MeteredStream(serverInput, pi, cl);
} else {
// Progress monitoring is disabled, and there is no
// need to wrap an unknown length input stream.
// ** This is an no-op **
}
} else {
if (pi != null)
pi.finishTracking();
}
return ret;
}
Aggregations