/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.clients.fcp;
import java.io.File;
import java.net.MalformedURLException;
import freenet.keys.FreenetURI;
import freenet.node.Node;
import freenet.pluginmanager.PluginInfoWrapper;
import freenet.support.Logger;
import freenet.support.SimpleFieldSet;
/**
* load a plugin
*
*/
public class LoadPlugin extends FCPMessage {
static final String NAME = "LoadPlugin";
static final String TYPENAME_FILE = "file";
static final String TYPENAME_FREENET = "freenet";
static final String TYPENAME_OFFICIAL = "official";
static final String TYPENAME_URL = "url";
private final String identifier;
private final String pluginURL;
private final String urlType;
private final boolean store;
private final boolean force;
private final boolean forceHTTPS;
public LoadPlugin(SimpleFieldSet fs) throws MessageInvalidException {
identifier = fs.get("Identifier");
if(identifier == null)
throw new MessageInvalidException(ProtocolErrorMessage.MISSING_FIELD, "Must contain an Identifier field", null, false);
pluginURL = fs.get("PluginURL");
if(pluginURL == null)
throw new MessageInvalidException(ProtocolErrorMessage.MISSING_FIELD, "Must contain a PluginURL field", identifier, false);
String type = fs.get("URLType");
if ((type != null) && (type.trim().length() > 0))
urlType = type.trim();
else
urlType = null;
if (urlType != null) {
if (!(TYPENAME_FILE.equalsIgnoreCase(urlType) ||
TYPENAME_FREENET.equalsIgnoreCase(urlType) ||
TYPENAME_OFFICIAL.equalsIgnoreCase(urlType) ||
TYPENAME_URL.equalsIgnoreCase(urlType)))
throw new MessageInvalidException(ProtocolErrorMessage.INVALID_FIELD, "Unknown URL type: '"+urlType+"'", identifier, false);
}
String officialSource = fs.get("OfficialSource");
if(officialSource != null) {
if(officialSource.equalsIgnoreCase("https")) {
force = true;
forceHTTPS = true;
} else if(officialSource.equalsIgnoreCase("freenet")) {
force = true;
forceHTTPS = false;
} else {
throw new MessageInvalidException(ProtocolErrorMessage.INVALID_FIELD, "Unknown OfficialSource '"+officialSource+"'", identifier, false);
}
} else {
force = false;
forceHTTPS = false;
}
store = fs.getBoolean("Store", false);
}
@Override
public SimpleFieldSet getFieldSet() {
return new SimpleFieldSet(true);
}
@Override
public String getName() {
return NAME;
}
@Override
public void run(final FCPConnectionHandler handler, final Node node) throws MessageInvalidException {
if(!handler.hasFullAccess()) {
throw new MessageInvalidException(ProtocolErrorMessage.ACCESS_DENIED, "LoadPlugin requires full access", identifier, false);
}
node.executor.execute(new Runnable() {
@Override
public void run() {
String type = null;
if (urlType == null) {
if (node.pluginManager.isOfficialPlugin(pluginURL) != null) {
type = TYPENAME_OFFICIAL;
} else if (new File(pluginURL).exists()) {
type = TYPENAME_FILE;
} else {
try {
new FreenetURI(pluginURL);
type = TYPENAME_FREENET;
} catch (MalformedURLException e) {
// FIXME currently i have no idea how to auto detect a proper url,
// especially distinguish it from typos/mistakes.
// so it is disabled for now. saces.
// try {
// URL url = new URL(pluginURL);
// url.getProtocol();
// TODO: sanitize checks for proper protocols
// } catch (MalformedURLException e1) {
// }
}
}
if (type == null) {
handler.outputHandler.queue(new ProtocolErrorMessage(ProtocolErrorMessage.INVALID_FIELD, false, "Was not able to guess the URL type from URL, check the URL or add a 'URLType' field", identifier, false));
return;
}
} else {
type = urlType.toLowerCase();
}
PluginInfoWrapper pi;
if (TYPENAME_OFFICIAL.equals(type)) {
pi = node.pluginManager.startPluginOfficial(pluginURL, store, force, forceHTTPS);
} else if (TYPENAME_FILE.equals(type)) {
pi = node.pluginManager.startPluginFile(pluginURL, store);
} else if (TYPENAME_FREENET.equals(type)) {
pi = node.pluginManager.startPluginFreenet(pluginURL, store);
} else if (TYPENAME_URL.equals(type)) {
pi = node.pluginManager.startPluginURL(pluginURL, store);
} else {
Logger.error(this, "This should really not happen!", new Exception("FIXME"));
handler.outputHandler.queue(new ProtocolErrorMessage(ProtocolErrorMessage.INTERNAL_ERROR, false, "This should really not happen! See logs for details.", identifier, false));
return;
}
if (pi == null) {
handler.outputHandler.queue(new ProtocolErrorMessage(ProtocolErrorMessage.NO_SUCH_PLUGIN, false, "Plugin '"+ pluginURL + "' does not exist or is not a FCP plugin", identifier, false));
} else {
handler.outputHandler.queue(new PluginInfoMessage(pi, identifier, true));
}
}
}, "Load Plugin");
}
}