/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/ package org.apache.catalina.session;
/** * Concrete implementation of the <b>Store</b> interface that utilizes a file per saved Session in a configured * directory. Sessions that are saved are still subject to being expired based on inactivity. * * @author Craig R. McClanahan
*/ publicfinalclass FileStore extends StoreBase {
privatestaticfinal Log log = LogFactory.getLog(FileStore.class); privatestaticfinal StringManager sm = StringManager.getManager(FileStore.class);
/** * The pathname of the directory in which Sessions are stored. This may be an absolute pathname, or a relative path * that is resolved against the temporary work directory for this application.
*/ private String directory = ".";
/** * A File representing the directory in which Sessions are stored.
*/ private File directoryFile = null;
/** * Name to register for this Store, used for logging.
*/ privatestaticfinal String storeName = "fileStore";
/** * Name to register for the background thread.
*/ privatestaticfinal String threadName = "FileStore";
/** * @return The directory path for this Store.
*/ public String getDirectory() { return directory;
}
/** * Set the directory path for this Store. * * @param path The new directory path
*/ publicvoid setDirectory(String path) {
String oldDirectory = this.directory; this.directory = path; this.directoryFile = null;
support.firePropertyChange("directory", oldDirectory, this.directory);
}
/** * @return The thread name for this Store.
*/ public String getThreadName() { return threadName;
}
/** * Return the name for this Store, used for logging.
*/
@Override public String getStoreName() { return storeName;
}
/** * Return the number of Sessions present in this Store. * * @exception IOException if an input/output error occurs
*/
@Override publicint getSize() throws IOException { // Acquire the list of files in our storage directory
File dir = directory(); if (dir == null) { return 0;
}
String files[] = dir.list();
// Figure out which files are sessions int keycount = 0; if (files != null) { for (String file : files) { if (file.endsWith(FILE_EXT)) {
keycount++;
}
}
} return keycount;
}
// --------------------------------------------------------- Public Methods
/** * Remove all of the Sessions in this Store. * * @exception IOException if an input/output error occurs
*/
@Override publicvoid clear() throws IOException {
String[] keys = keys(); for (String key : keys) {
remove(key);
}
}
/** * Return an array containing the session identifiers of all Sessions currently saved in this Store. If there are no * such Sessions, a zero-length array is returned. * * @exception IOException if an input/output error occurred
*/
@Override public String[] keys() throws IOException { // Acquire the list of files in our storage directory
File dir = directory(); if (dir == null) { returnnew String[0];
}
String files[] = dir.list();
// Build and return the list of session identifiers
List<String> list = new ArrayList<>(); int n = FILE_EXT.length(); for (String file : files) { if (file.endsWith(FILE_EXT)) {
list.add(file.substring(0, file.length() - n));
}
} return list.toArray(new String[0]);
}
/** * Load and return the Session associated with the specified session identifier from this Store, without removing * it. If there is no such stored Session, return <code>null</code>. * * @param id Session identifier of the session to load * * @exception ClassNotFoundException if a deserialization error occurs * @exception IOException if an input/output error occurs
*/
@Override public Session load(String id) throws ClassNotFoundException, IOException { // Open an input stream to the specified pathname, if any
File file = file(id); if (file == null || !file.exists()) { returnnull;
}
/** * Remove the Session with the specified session identifier from this Store, if present. If no such Session is * present, this method takes no action. * * @param id Session identifier of the Session to be removed * * @exception IOException if an input/output error occurs
*/
@Override publicvoid remove(String id) throws IOException {
File file = file(id); if (file == null) { return;
} if (manager.getContext().getLogger().isDebugEnabled()) {
manager.getContext().getLogger()
.debug(sm.getString(getStoreName() + ".removing", id, file.getAbsolutePath()));
}
if (file.exists() && !file.delete()) { thrownew IOException(sm.getString("fileStore.deleteSessionFailed", file));
}
}
/** * Save the specified Session into this Store. Any previously saved information for the associated session * identifier is replaced. * * @param session Session to be saved * * @exception IOException if an input/output error occurs
*/
@Override publicvoid save(Session session) throws IOException { // Open an output stream to the specified pathname, if any
File file = file(session.getIdInternal()); if (file == null) { return;
} if (manager.getContext().getLogger().isDebugEnabled()) {
manager.getContext().getLogger()
.debug(sm.getString(getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath()));
}
try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath());
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) {
((StandardSession) session).writeObjectData(oos);
}
}
/** * Return a File object representing the pathname to our session persistence directory, if any. The directory will * be created if it does not already exist.
*/ private File directory() throws IOException { if (this.directory == null) { returnnull;
} if (this.directoryFile != null) { // NOTE: Race condition is harmless, so do not synchronize returnthis.directoryFile;
}
File file = new File(this.directory); if (!file.isAbsolute()) {
Context context = manager.getContext();
ServletContext servletContext = context.getServletContext();
File work = (File) servletContext.getAttribute(ServletContext.TEMPDIR);
file = new File(work, this.directory);
} if (!file.exists() || !file.isDirectory()) { if (!file.delete() && file.exists()) { thrownew IOException(sm.getString("fileStore.deleteFailed", file));
} if (!file.mkdirs() && !file.isDirectory()) { thrownew IOException(sm.getString("fileStore.createFailed", file));
}
} this.directoryFile = file; return file;
}
/** * Return a File object representing the pathname to our session persistence file, if any. * * @param id The ID of the Session to be retrieved. This is used in the file naming.
*/ private File file(String id) throws IOException {
File storageDir = directory(); if (storageDir == null) { returnnull;
}
String filename = id + FILE_EXT;
File file = new File(storageDir, filename);
File canonicalFile = file.getCanonicalFile();
// Check the file is within the storage directory if (!canonicalFile.toPath().startsWith(storageDir.getCanonicalFile().toPath())) {
log.warn(sm.getString("fileStore.invalid", file.getPath(), id)); returnnull;
}
return canonicalFile;
}
}
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.