?? request.java
字號:
switch (code) { case 100: case 204: case 205: case 304: break; default: body = createResponseBodyStream(responseHeaders, majorVersion, minorVersion, in); } // Construct response Response ret = new Response(majorVersion, minorVersion, code, message, responseHeaders, body); return ret; } void notifyHeaderHandlers(Headers headers) { for (Iterator i = headers.entrySet().iterator(); i.hasNext(); ) { Map.Entry entry = (Map.Entry) i.next(); String name =(String) entry.getKey(); // Handle Set-Cookie if ("Set-Cookie".equalsIgnoreCase(name)) { String value = (String) entry.getValue(); handleSetCookie(value); } ResponseHeaderHandler handler = (ResponseHeaderHandler) responseHeaderHandlers.get(name); if (handler != null) { String value = (String) entry.getValue(); handler.setValue(value); } } } private InputStream createResponseBodyStream(Headers responseHeaders, int majorVersion, int minorVersion, InputStream in) throws IOException { long contentLength = -1; Headers trailer = null; // Persistent connections are the default in HTTP/1.1 boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) || "close".equalsIgnoreCase(responseHeaders.getValue("Connection")) || (connection.majorVersion == 1 && connection.minorVersion == 0) || (majorVersion == 1 && minorVersion == 0); String transferCoding = responseHeaders.getValue("Transfer-Encoding"); if ("chunked".equalsIgnoreCase(transferCoding)) { in = new LimitedLengthInputStream(in, -1, false, connection, doClose); in = new ChunkedInputStream(in, responseHeaders); } else { contentLength = responseHeaders.getLongValue("Content-Length"); if (contentLength < 0) doClose = true; // No Content-Length, must close. in = new LimitedLengthInputStream(in, contentLength, contentLength >= 0, connection, doClose); } String contentCoding = responseHeaders.getValue("Content-Encoding"); if (contentCoding != null && !"identity".equals(contentCoding)) { if ("gzip".equals(contentCoding)) { in = new GZIPInputStream(in); } else if ("deflate".equals(contentCoding)) { in = new InflaterInputStream(in); } else { throw new ProtocolException("Unsupported Content-Encoding: " + contentCoding); } // Remove the Content-Encoding header because the content is // no longer compressed. responseHeaders.remove("Content-Encoding"); } return in; } boolean authenticate(Response response, int attempts) throws IOException { String challenge = response.getHeader("WWW-Authenticate"); if (challenge == null) { challenge = response.getHeader("Proxy-Authenticate"); } int si = challenge.indexOf(' '); String scheme = (si == -1) ? challenge : challenge.substring(0, si); if ("Basic".equalsIgnoreCase(scheme)) { Properties params = parseAuthParams(challenge.substring(si + 1)); String realm = params.getProperty("realm"); Credentials creds = authenticator.getCredentials(realm, attempts); String userPass = creds.getUsername() + ':' + creds.getPassword(); byte[] b_userPass = userPass.getBytes("US-ASCII"); byte[] b_encoded = BASE64.encode(b_userPass); String authorization = scheme + " " + new String(b_encoded, "US-ASCII"); setHeader("Authorization", authorization); return true; } else if ("Digest".equalsIgnoreCase(scheme)) { Properties params = parseAuthParams(challenge.substring(si + 1)); String realm = params.getProperty("realm"); String nonce = params.getProperty("nonce"); String qop = params.getProperty("qop"); String algorithm = params.getProperty("algorithm"); String digestUri = getRequestURI(); Credentials creds = authenticator.getCredentials(realm, attempts); String username = creds.getUsername(); String password = creds.getPassword(); connection.incrementNonce(nonce); try { MessageDigest md5 = MessageDigest.getInstance("MD5"); final byte[] COLON = { 0x3a }; // Calculate H(A1) md5.reset(); md5.update(username.getBytes("US-ASCII")); md5.update(COLON); md5.update(realm.getBytes("US-ASCII")); md5.update(COLON); md5.update(password.getBytes("US-ASCII")); byte[] ha1 = md5.digest(); if ("md5-sess".equals(algorithm)) { byte[] cnonce = generateNonce(); md5.reset(); md5.update(ha1); md5.update(COLON); md5.update(nonce.getBytes("US-ASCII")); md5.update(COLON); md5.update(cnonce); ha1 = md5.digest(); } String ha1Hex = toHexString(ha1); // Calculate H(A2) md5.reset(); md5.update(method.getBytes("US-ASCII")); md5.update(COLON); md5.update(digestUri.getBytes("US-ASCII")); if ("auth-int".equals(qop)) { byte[] hEntity = null; // TODO hash of entity body md5.update(COLON); md5.update(hEntity); } byte[] ha2 = md5.digest(); String ha2Hex = toHexString(ha2); // Calculate response md5.reset(); md5.update(ha1Hex.getBytes("US-ASCII")); md5.update(COLON); md5.update(nonce.getBytes("US-ASCII")); if ("auth".equals(qop) || "auth-int".equals(qop)) { String nc = getNonceCount(nonce); byte[] cnonce = generateNonce(); md5.update(COLON); md5.update(nc.getBytes("US-ASCII")); md5.update(COLON); md5.update(cnonce); md5.update(COLON); md5.update(qop.getBytes("US-ASCII")); } md5.update(COLON); md5.update(ha2Hex.getBytes("US-ASCII")); String digestResponse = toHexString(md5.digest()); String authorization = scheme + " username=\"" + username + "\"" + " realm=\"" + realm + "\"" + " nonce=\"" + nonce + "\"" + " uri=\"" + digestUri + "\"" + " response=\"" + digestResponse + "\""; setHeader("Authorization", authorization); return true; } catch (NoSuchAlgorithmException e) { return false; } } // Scheme not recognised return false; } Properties parseAuthParams(String text) { int len = text.length(); String key = null; StringBuilder buf = new StringBuilder(); Properties ret = new Properties(); boolean inQuote = false; for (int i = 0; i < len; i++) { char c = text.charAt(i); if (c == '"') { inQuote = !inQuote; } else if (c == '=' && key == null) { key = buf.toString().trim(); buf.setLength(0); } else if (c == ' ' && !inQuote) { String value = unquote(buf.toString().trim()); ret.put(key, value); key = null; buf.setLength(0); } else if (c != ',' || (i <(len - 1) && text.charAt(i + 1) != ' ')) { buf.append(c); } } if (key != null) { String value = unquote(buf.toString().trim()); ret.put(key, value); } return ret; } String unquote(String text) { int len = text.length(); if (len > 0 && text.charAt(0) == '"' && text.charAt(len - 1) == '"') { return text.substring(1, len - 1); } return text; } /** * Returns the number of times the specified nonce value has been seen. * This always returns an 8-byte 0-padded hexadecimal string. */ String getNonceCount(String nonce) { int nc = connection.getNonceCount(nonce); String hex = Integer.toHexString(nc); StringBuilder buf = new StringBuilder(); for (int i = 8 - hex.length(); i > 0; i--) { buf.append('0'); } buf.append(hex); return buf.toString(); } /** * Client nonce value. */ byte[] nonce; /** * Generates a new client nonce value. */ byte[] generateNonce() throws IOException, NoSuchAlgorithmException { if (nonce == null) { long time = System.currentTimeMillis(); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(Long.toString(time).getBytes("US-ASCII")); nonce = md5.digest(); } return nonce; } String toHexString(byte[] bytes) { char[] ret = new char[bytes.length * 2]; for (int i = 0, j = 0; i < bytes.length; i++) { int c =(int) bytes[i]; if (c < 0) { c += 0x100; } ret[j++] = Character.forDigit(c / 0x10, 0x10); ret[j++] = Character.forDigit(c % 0x10, 0x10); } return new String(ret); } /** * Parse the specified cookie list and notify the cookie manager. */ void handleSetCookie(String text) { CookieManager cookieManager = connection.getCookieManager(); if (cookieManager == null) { return; } String name = null; String value = null; String comment = null; String domain = connection.getHostName(); String path = this.path; int lsi = path.lastIndexOf('/'); if (lsi != -1) { path = path.substring(0, lsi); } boolean secure = false; Date expires = null; int len = text.length(); String attr = null; StringBuilder buf = new StringBuilder(); boolean inQuote = false; for (int i = 0; i <= len; i++) { char c =(i == len) ? '\u0000' : text.charAt(i); if (c == '"') { inQuote = !inQuote; } else if (!inQuote) { if (c == '=' && attr == null) { attr = buf.toString().trim(); buf.setLength(0); } else if (c == ';' || i == len || c == ',') { String val = unquote(buf.toString().trim()); if (name == null) { name = attr; value = val; } else if ("Comment".equalsIgnoreCase(attr)) { comment = val; } else if ("Domain".equalsIgnoreCase(attr)) { domain = val; } else if ("Path".equalsIgnoreCase(attr)) { path = val; } else if ("Secure".equalsIgnoreCase(val)) { secure = true; } else if ("Max-Age".equalsIgnoreCase(attr)) { int delta = Integer.parseInt(val); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(System.currentTimeMillis()); cal.add(Calendar.SECOND, delta); expires = cal.getTime(); } else if ("Expires".equalsIgnoreCase(attr)) { DateFormat dateFormat = new HTTPDateFormat(); try { expires = dateFormat.parse(val); } catch (ParseException e) { // if this isn't a valid date, it may be that // the value was returned unquoted; in that case, we // want to continue buffering the value buf.append(c); continue; } } attr = null; buf.setLength(0); // case EOL if (i == len || c == ',') { Cookie cookie = new Cookie(name, value, comment, domain, path, secure, expires); cookieManager.setCookie(cookie); } if (c == ',') { // Reset cookie fields name = null; value = null; comment = null; domain = connection.getHostName(); path = this.path; if (lsi != -1) { path = path.substring(0, lsi); } secure = false; expires = null; } } else { buf.append(c); } } else { buf.append(c); } } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -