Java tutorial
/******************************************************************************* * Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH . * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * s IT Solutions AT Spardat GmbH - initial API and implementation *******************************************************************************/ /* * Created on 16.05.2003 */ package at.spardat.xma.boot.transport; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.Set; import java.util.SimpleTimeZone; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.cookie.CookieSpec; import org.apache.commons.httpclient.cookie.CookieSpecBase; import org.apache.commons.httpclient.cookie.MalformedCookieException; import at.spardat.xma.boot.BootRuntime; import at.spardat.xma.boot.Statics; import at.spardat.xma.boot.comp.CCLoader; import at.spardat.xma.boot.component.IRtXMASessionClient; import at.spardat.xma.boot.logger.LogLevel; import at.spardat.xma.boot.logger.Logger; /** * This class implements low level transport on http transport using suns UrlConnection implementation. * * @author s2877, s3595 * @version $Id: HTTPTransport.java 10852 2013-06-28 10:34:13Z dschwarz $ * */ public class HTTPTransport extends Transport { /** used to format if-modified-since correctly */ private static DateFormat httpdate_; private static Logger log_; private static HostnameVerifier hostnameVerifier; private static CookieSpec cookieSpec; private static HttpState httpState = new HttpState(); private HashMap<String, String> redirectCache = new HashMap<String, String>(); { httpdate_ = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); //$NON-NLS-1$ httpdate_.setTimeZone(new SimpleTimeZone(0, "GMT")); //$NON-NLS-1$ } /** * Initializes the underlaying http-protocol-provider from the given Propterties. * This sets the tcp-timeouts, the proxy-settings and ssl-settings. * @param prop containing properties for http and https protocol */ public static void init(Properties prop) { log_ = Logger.getLogger("boot.transport.http"); //$NON-NLS-1$ // proxy properties String strProxyEnable = prop.getProperty(Statics.CFG_PROP_PROXYENABLE); if (strProxyEnable != null && Boolean.valueOf(strProxyEnable).booleanValue()) { String strProxyServer = prop.getProperty(Statics.CFG_PROP_PROXYSERVER); String strProxyPort = prop.getProperty(Statics.CFG_PROP_PROXYPORT); if (strProxyServer != null && strProxyPort != null) { System.setProperty("proxySet", "true"); System.setProperty("http.proxyHost", strProxyServer); System.setProperty("http.proxyPort", strProxyPort); log_.log(LogLevel.FINE, "transport proxy is: {0}:{1}", new Object[] { strProxyServer, strProxyPort }); } String strSecureProxyServer = prop.getProperty(Statics.CFG_PROP_SECUREPROXYSERVER); String strSecureProxyPort = prop.getProperty(Statics.CFG_PROP_SECUREPROXYPORT); if (strSecureProxyPort != null && strSecureProxyServer != null) { System.setProperty("https.proxyHost", strSecureProxyServer); System.setProperty("https.proxyPort", strSecureProxyPort); log_.log(LogLevel.FINE, "secure transport proxy is: {0}:{1}", new Object[] { strSecureProxyServer, strSecureProxyPort }); } String strProxyOverride = prop.getProperty(Statics.CFG_PROP_PROXYOVERRIDE); if (strProxyOverride != null) { strProxyOverride = strProxyOverride.replace(';', '|'); // documented delimiter for IE strProxyOverride = strProxyOverride.replace(',', '|'); // IE supports ',' as delimiter, too strProxyOverride = strProxyOverride.replace(' ', '|'); // IE supports blank as delimiter, too strProxyOverride = strProxyOverride.replace('\t', '|'); // IE supports tab as delimiter, too strProxyOverride = strProxyOverride.replace('\r', '|'); // IE supports carriage return as delimiter, too strProxyOverride = strProxyOverride.replace('\n', '|'); // IE supports newline as delimiter, too strProxyOverride = strProxyOverride.replaceAll("<local>", "localhost|127.0.0.1"); System.setProperty("http.nonProxyHosts", strProxyOverride); log_.log(LogLevel.FINE, "proxy not used for: {0}", strProxyOverride); } } else { log_.log(LogLevel.FINE, "no transport proxy is used"); } // timeout properties String strConnectTimeout = prop.getProperty(Statics.CFG_PROP_CONNECTTIMEOUT); if (strConnectTimeout != null) { System.setProperty("sun.net.client.defaultConnectTimeout", strConnectTimeout); log_.log(LogLevel.FINE, "http connect timeout: " + strConnectTimeout + " milliseconds"); } String strReadTimeout = prop.getProperty(Statics.CFG_PROP_READTIMEOUT); if (strReadTimeout != null) { System.setProperty("sun.net.client.defaultReadTimeout", strReadTimeout); log_.log(LogLevel.FINE, "http read timeout: " + strReadTimeout + " milliseconds"); } // ssl properties String strTrustStore = prop.getProperty(Statics.CFG_PROP_SECURECERTS); if (strTrustStore != null) { log_.log(LogLevel.FINE, "using trusted certificates file " + strTrustStore); File trustFile = new File(strTrustStore); if (!trustFile.exists()) { log_.log(LogLevel.SEVERE, "trusted certificates file '" + trustFile.getAbsolutePath() + "' not found"); } System.setProperty("javax.net.ssl.trustStore", strTrustStore); } hostnameVerifier = new HostnameVerifierImpl(prop.getProperty(Statics.CFG_PROP_HOSTNAMEVERIFYIGNORE)); // cookie handling policy Class<?> cookiePolicyClass = null; String strCookiePolicy = prop.getProperty(Statics.CFG_PROP_COOKIEPOLICY); if (strCookiePolicy != null) { try { cookiePolicyClass = Class.forName(strCookiePolicy); } catch (ClassNotFoundException e) { log_.log(LogLevel.WARNING, "configured cookiePolicy '" + strCookiePolicy + "' not found, using default"); } } if (cookiePolicyClass == null) { cookiePolicyClass = CookieSpecBase.class; } log_.log(LogLevel.FINE, "using cookiePolicy " + cookiePolicyClass.getName()); CookiePolicy.registerCookieSpec(CookiePolicy.DEFAULT, cookiePolicyClass); cookieSpec = CookiePolicy.getDefaultSpec(); } /** * logs the proxy settings at the given level. */ public void logProxyInfo(LogLevel level) { StringBuffer result = new StringBuffer(); String proxyHost = System.getProperty("http.proxyHost"); if (proxyHost != null) { result.append("http proxy is: " + proxyHost); String proxyPort = System.getProperty("http.proxyPort"); if (proxyPort != null) { result.append(":" + proxyPort); } log_.log(level, result.toString()); } else { log_.log(level, "no http proxy used"); } result = new StringBuffer(); proxyHost = System.getProperty("https.proxyHost"); if (proxyHost != null) { result.append("https proxy is: " + proxyHost); String proxyPort = System.getProperty("https.proxyPort"); if (proxyPort != null) { result.append(":" + proxyPort); } log_.log(level, result.toString()); } else { log_.log(level, "no https proxy used"); } String nonProxyHosts = System.getProperty("http.nonProxyHosts"); if (nonProxyHosts != null) { log_.log(level, "no proxy used for: " + nonProxyHosts); } } /** * Constructs a <code>HTTPTransport</code>. * */ public HTTPTransport() { if (log_ == null) log_ = Logger.getLogger("boot.httpTransport"); //$NON-NLS-1$ } /** * Converts a <code>java.util.Date</code> to a String using the encoding specified by * the HTTP-Specification. We have to wrap this task, cause we may have to change it. <p> * see also SUN-Bug_ID: 4397096 <p> * * @param date the date to be formated * @return String the formated representation */ public static String httpDate(Date date) { return httpdate_.format(date); } /** * Converts a long containing a date to a String using the encoding specified by * the HTTP-Specification. We have to wrap this task, cause we may have to change it. <p> * see also SUN-Bug_ID: 4397096 <p> * * @param ldate the milliseconds since January 1, 1970, 00:00:00 GMT. * @return String the formated representation */ public static String httpDate(long ldate) { return httpdate_.format(new Date(ldate)); } /* (non-Javadoc) * @see at.spardat.xma.transport.Transport#getResource(at.spardat.xma.transport.XMA_URI, long) */ public Result getResource(final IRtXMASessionClient session, final XMA_URI resource, final long modifiedSince, final String etag) throws CommunicationException { CCLoader swtCLoader = BootRuntime.getInstance().getAppManager().getSWTClassLoader(); if (swtCLoader != null) { class Inner implements Runnable { Result result; CommunicationException exc; public void run() { try { result = getResourceImpl(session, resource, modifiedSince, etag); } catch (CommunicationException exc) { this.exc = exc; } } } Inner inner = new Inner(); try { // call BusyIndicator.showWhile over reflection from the SWT-Classloader Class<?> busyIndicatorClass = swtCLoader.loadClass("org.eclipse.swt.custom.BusyIndicator"); Class<?> displayClass = swtCLoader.loadClass("org.eclipse.swt.widgets.Display"); Method method = busyIndicatorClass.getMethod("showWhile", new Class[] { displayClass, Runnable.class }); method.invoke(null, new Object[] { null, inner }); } catch (Exception exc) { throw new RuntimeException(exc); } if (inner.exc != null) throw inner.exc; return inner.result; } else { return getResourceImpl(session, resource, modifiedSince, etag); } } /* (non-Javadoc) * @see at.spardat.xma.boot.transport.Transport#getRedirection(at.spardat.xma.boot.transport.XMA_URI) */ @Override public XMA_URI getRedirection(XMA_URI resource) { String resourceHostApp = resource.getHostApp(); String translated = redirectCache.get(resourceHostApp); if (translated != null) { String newUrl = resource.toString().replace(resourceHostApp, translated); try { return new XMA_URI(newUrl); } catch (MalformedURLException e) { log_.info("Can't translate URL: " + newUrl + ": " + e.toString()); } } return null; } private Object callRedirectAware(XMA_URI resource, RedirectCallback callback) throws CommunicationException { Set<URL> redirectLoopPreventionSet = new HashSet<URL>(); URL url = resource.getHTTP_URI(); String initialResourceHostApp = resource.getHostApp(); do { XMA_URI redirectedResource = getRedirection(resource); if (redirectedResource != null) { url = redirectedResource.getHTTP_URI(); log_.log(LogLevel.FINE, "Using redirect cache: " + resource + " -> " + redirectedResource); } redirectLoopPreventionSet.add(url); try { return callback.call(url); } catch (RedirectException re) { log_.log(LogLevel.WARNING, re.getMessage()); try { url = new URL(re.getLocation()); String resourceHostApp = resource.getHostApp(); resource = new XMA_URI(url); String newHostApp = resource.getHostApp(); if (!resourceHostApp.equals(newHostApp)) { redirectCache.put(resourceHostApp, newHostApp); // be aware of multiple redirects redirectCache.put(initialResourceHostApp, newHostApp); log_.log(LogLevel.FINE, "Adding redirect cache: " + resourceHostApp + " -> " + newHostApp); } } catch (MalformedURLException e) { throw new ServerException("Illegal HTTP redirect location: " + re.getLocation(), re, re.getReturnCode()); } } } while (!redirectLoopPreventionSet.contains(url) && redirectLoopPreventionSet.size() < 5); throw new ServerException("HTTP redirect loop detected at " + url); } public Result getResourceImpl(final IRtXMASessionClient session, XMA_URI resource, final long modifiedSince, final String etag) throws CommunicationException { RedirectCallback callback = new RedirectCallback() { public Object call(URL url) throws CommunicationException { return getResourceImpl(session, url, modifiedSince, etag); } }; return (Result) callRedirectAware(resource, callback); } private Result getResourceImpl(IRtXMASessionClient session, URL url, long modifiedSince, String etag) throws CommunicationException { /* locals ---------------------------------- */ Result result = new Result(); int code = 0; HttpURLConnection conn; /* locals ---------------------------------- */ try { conn = (HttpURLConnection) url.openConnection(); if (conn instanceof HttpsURLConnection) { ((HttpsURLConnection) conn).setHostnameVerifier(hostnameVerifier); } sendCookies(session, url, conn); if (etag != null) { conn.setRequestProperty("If-None-Match", etag); //$NON-NLS-1$ } String strUrl = url.toExternalForm(); if (url.getQuery() == null && (strUrl.endsWith(".jar") || strUrl.endsWith(".xml"))) { conn.setRequestProperty(Statics.HTTP_CACHE_CONTROL, Statics.HTTP_MAX_AGE + "=0"); //$NON-NLS-1$ } if (modifiedSince > 0) { // see sun bugid: 4397096 // if HTTP_Util library is used, the original method may also be used. // conn.setIfModifiedSince(modifiedSince); conn.setRequestProperty(Statics.strIfModifiedSince, HTTPTransport.httpDate(modifiedSince)); } conn.setRequestProperty(Statics.HTTP_ACCEPT, "*/*"); //$NON-NLS-1$ conn.setRequestProperty(Statics.HTTP_USER_AGENT, Statics.HTTP_USER_AGENT_NAME); } catch (IOException exc) { log_.log(LogLevel.WARNING, "error loading '" + url.toString() + "' form server:", exc); //$NON-NLS-1$ throw new ConnectException("error loading '" + url.toString() + "' form server:", exc); } try { code = conn.getResponseCode(); if (code == HttpURLConnection.HTTP_NOT_MODIFIED) { result.contentLength_ = 0; result.lastModified_ = conn.getLastModified(); if (result.lastModified_ <= 0) { result.lastModified_ = modifiedSince; } result.expirationDate_ = conn.getExpiration(); result.etag_ = conn.getHeaderField(Statics.strEtag); if (result.etag_ == null) { result.etag_ = etag; } log_.log(LogLevel.FINE, "resource not modified: {0}", url.toExternalForm()); //$NON-NLS-1$ } else if (code == HttpURLConnection.HTTP_OK) { result.contentLength_ = conn.getContentLength(); result.lastModified_ = conn.getLastModified(); result.expirationDate_ = conn.getExpiration(); result.etag_ = conn.getHeaderField(Statics.strEtag); result.transformations_ = conn.getHeaderField(Statics.TRANSFORM_HEADER); result.setBuffer(this.readOutput(conn)); if (result.contentLength_ < 0) { result.contentLength_ = result.buffer_.length; } } else if (code == HttpURLConnection.HTTP_MOVED_TEMP || code == HttpURLConnection.HTTP_MOVED_PERM) { String location = conn.getHeaderField(Statics.HTTP_LOCATION); throw new RedirectException("redirect received from " + url.toString() + " to " + location, code, location); } else { if (code < 500) throw new ConnectException("error loading '" + url.toString() + "' from the server:", code); else throw new ServerException("error loading '" + url.toString() + "' from the server:", code); } readCookies(session, url, conn); } catch (RedirectException re) { throw re; } catch (CommunicationException ce) { if (code != 0) log_.log(LogLevel.WARNING, "http returncode: {0}", Integer.toString(code)); //$NON-NLS-1$ log_.log(LogLevel.WARNING, "error loading '" + url.toString() + "' from the server:", ce); //$NON-NLS-1$ throw ce; } catch (Exception ex) { if (code != 0) log_.log(LogLevel.WARNING, "http returncode: {0}", Integer.toString(code)); //$NON-NLS-1$ log_.log(LogLevel.WARNING, "error loading '" + url.toString() + "' from the server:", ex); //$NON-NLS-1$ if (code < 500) throw new ConnectException("error loading '" + url.toString() + "' from the server:", ex); else throw new ServerException("error loading '" + url.toString() + "' from the server:", ex); } return result; } public byte[] callServerEvent(final IRtXMASessionClient session, final XMA_URI eventHandler, final byte[] input) throws CommunicationException { return callServerEvent(session, eventHandler, input, false); } /* (non-Javadoc) * @see at.spardat.xma.transport.Transport#callServerEvent(at.spardat.xma.session.XMASessionClient, at.spardat.xma.transport.XMA_URI, java.io.InputStream) */ public byte[] callServerEvent(final IRtXMASessionClient session, final XMA_URI eventHandler, final byte[] input, final boolean handleRedirect) throws CommunicationException { CCLoader swtCLoader = BootRuntime.getInstance().getAppManager().getSWTClassLoader(); if (swtCLoader != null) { class Inner implements Runnable { byte[] result; CommunicationException exc; public void run() { try { result = callServerEventImpl(session, eventHandler, input, handleRedirect); } catch (CommunicationException exc) { this.exc = exc; } } } Inner inner = new Inner(); try { // call BusyIndicator.showWhile over reflection from the SWT-Classloader Class<?> busyIndicatorClass = swtCLoader.loadClass("org.eclipse.swt.custom.BusyIndicator"); Class<?> displayClass = swtCLoader.loadClass("org.eclipse.swt.widgets.Display"); Method method = busyIndicatorClass.getMethod("showWhile", new Class[] { displayClass, Runnable.class }); method.invoke(null, new Object[] { null, inner }); } catch (Exception exc) { throw new RuntimeException(exc); } if (inner.exc != null) throw inner.exc; return inner.result; } else { return callServerEventImpl(session, eventHandler, input, handleRedirect); } } private byte[] callServerEventImpl(final IRtXMASessionClient session, XMA_URI eventHandler, final byte[] input, boolean handleRedirect) throws CommunicationException { if (handleRedirect) { RedirectCallback callback = new RedirectCallback() { public Object call(URL url) throws CommunicationException { return callServerEventImpl(session, url, input, true); } }; return (byte[]) callRedirectAware(eventHandler, callback); } else { return callServerEventImpl(session, eventHandler.getHTTP_URI(), input, false); } } private byte[] callServerEventImpl(IRtXMASessionClient session, URL url, byte[] input, boolean handleRedirect) throws CommunicationException { OutputStream serverIn; int code = 0; HttpURLConnection conn; byte[] buffer = null; try { conn = (HttpURLConnection) url.openConnection(); if (conn instanceof HttpsURLConnection) { ((HttpsURLConnection) conn).setHostnameVerifier(hostnameVerifier); } conn.setDoOutput(true); conn.setRequestMethod("POST"); //$NON-NLS-1$ sendCookies(session, url, conn); conn.setRequestProperty(Statics.HTTP_CONTENT_TYPE, "application/octet-stream"); //$NON-NLS-1$ conn.setRequestProperty(Statics.HTTP_ACCEPT, "application/octet-stream"); //$NON-NLS-1$ conn.setRequestProperty(Statics.HTTP_USER_AGENT, Statics.HTTP_USER_AGENT_NAME); serverIn = conn.getOutputStream(); } catch (IOException exc) { log_.log(LogLevel.WARNING, "error calling '" + url.toString() + "' at the server:", exc); //$NON-NLS-1$ throw new ConnectException("error calling '" + url.toString() + "' at the server:", exc); } try { serverIn.write(input); serverIn.close(); code = conn.getResponseCode(); // if requested, we allow redirect also on POST requests, therewith violating RFC 2616 section 10.3! if (handleRedirect && code == HttpURLConnection.HTTP_MOVED_TEMP || code == HttpURLConnection.HTTP_MOVED_PERM) { String location = conn.getHeaderField(Statics.HTTP_LOCATION); throw new RedirectException("redirect received from " + url.toString() + " to " + location, code, location); } buffer = this.readOutput(conn); readCookies(session, url, conn); return buffer; } catch (RedirectException re) { throw re; } catch (CommunicationException ce) { if (code != 0) log_.log(LogLevel.WARNING, "http returncode: {0}", Integer.toString(code)); //$NON-NLS-1$ log_.log(LogLevel.WARNING, "error calling '" + url.toString() + "' at the server:", ce); //$NON-NLS-1$ throw ce; } catch (Exception ex) { if (code != 0) log_.log(LogLevel.WARNING, "http returncode: {0}", Integer.toString(code)); //$NON-NLS-1$ log_.log(LogLevel.WARNING, "error calling '" + url.toString() + "' at the server:", ex); //$NON-NLS-1$ if (code < 500) throw new ConnectException("error calling '" + url.toString() + "' at the server:", ex); else throw new ServerException("error calling '" + url.toString() + "' at the server:", ex); } } /** * get server output into a buffer * * @param conn connection to read from * @return byte[] server output * @throws ServerException content lenght errro * @throws IOException for read erros */ private byte[] readOutput(HttpURLConnection conn) throws IOException { InputStream serverOut = null; byte[] buffer = null; try { serverOut = conn.getInputStream(); int len = conn.getContentLength(); int read = 0; int all = 0; if (len > -1) { buffer = new byte[len]; while (read > -1 && all < len) { read = serverOut.read(buffer, all, len - all); if (read > -1) all += read; } if (read < 0) { throw new ServerException( "Server reported contentLength " + len + " but send only " + all + " bytes of data"); } return buffer; } else { // if no content length was send, use default size and grow dynamically List<byte[]> bufferList = null; final int defLen = 1024 * 8; int lastLength = 0; bufferList = new ArrayList<byte[]>(); for (; read > -1; all += lastLength) { buffer = new byte[defLen]; for (lastLength = 0; read > -1 && lastLength < defLen;) { read = serverOut.read(buffer, lastLength, defLen - lastLength); if (read > -1) lastLength += read; } bufferList.add(buffer); } byte[] result = new byte[all]; for (int i = 0; i < bufferList.size() - 1; i++) { System.arraycopy(bufferList.get(i), 0, result, i * defLen, defLen); } System.arraycopy(bufferList.get(bufferList.size() - 1), 0, result, (bufferList.size() - 1) * defLen, lastLength); return result; } } finally { if (serverOut != null) serverOut.close(); } } /** * Get the used port of the url. If no port is defined in the url, * the default port of the protocol is returned. */ int getPort(URL url) { int port = url.getPort(); if (port == -1) { port = url.getDefaultPort(); } return port; } /** * Return the httpState for the session. * * To support multiple sessions override this method. */ protected HttpState getHttpState(IRtXMASessionClient session) { return httpState; } /** * Returns all cookies which are stored for the given url. * @deprecated Use getCookies(URL url, IRtXMASessionClient session) instead. */ public Cookie[] getCookies(URL url) { return getCookies(url, null); } /** * Returns all cookies which are stored for the given url and session. */ public Cookie[] getCookies(URL url, IRtXMASessionClient session) { Cookie[] cookies = getHttpState(session).getCookies(); if (cookies != null && cookies.length > 0) { cookies = cookieSpec.match(url.getHost(), getPort(url), url.getPath(), "https".equals(url.getProtocol()), cookies); } return cookies; } /** * Takes the cookies from the httpState which match the given url and creates the * corresponsing cookie-header on the given connection. */ private void sendCookies(IRtXMASessionClient session, URL url, HttpURLConnection conn) { Cookie[] cookies = getCookies(url, session); if (cookies != null && cookies.length > 0) { String cookieHeader = cookieSpec.formatCookies(cookies); conn.setRequestProperty(Statics.HTTP_COOKIE, cookieHeader); if (session != null && session.getId() == null) { // server side http session was established before client side session was created for (int j = 0; j < cookies.length; j++) { if ("JSESSIONID".equals(cookies[j].getName())) { session.setId(cookies[j].getName() + "=" + cookies[j].getValue()); } } } } } /** * Parses the cookies from the given connection and stores them in httpState. * Invalid cookies are ignored and logged. */ private void readCookies(IRtXMASessionClient session, URL url, HttpURLConnection conn) { String headerName = ""; for (int i = 1; headerName != null; i++) { headerName = conn.getHeaderFieldKey(i); if (Statics.HTTP_SET_COOKIE.equals(headerName)) { try { Cookie[] cookies = cookieSpec.parse(url.getHost(), getPort(url), url.getPath(), "https".equals(url.getProtocol()), conn.getHeaderField(i)); if (cookies != null) { for (int j = 0; j < cookies.length; j++) { try { cookieSpec.validate(url.getHost(), getPort(url), url.getPath(), "https".equals(url.getProtocol()), cookies[j]); getHttpState(session).addCookie(cookies[j]); if (session != null && "JSESSIONID".equals(cookies[j].getName())) { session.setId(cookies[j].getName() + "=" + cookies[j].getValue()); } } catch (MalformedCookieException e) { log_.log(LogLevel.WARNING, "cookie rejected: \"" + cookieSpec.formatCookie(cookies[j]) + "\". " + e.getMessage()); } } } } catch (MalformedCookieException e) { log_.log(LogLevel.WARNING, "Invalid cookie header: \"" + conn.getHeaderField(i) + "\". " + e.getMessage()); } } } } }