w.flush();
return false;
}
try {
FetchResult result = client.fetch(uri);
ClientMetadata cm = result.getMetadata();
outsb.append("Content MIME type: ").append(cm.getMIMEType());
Bucket data = result.asBucket();
// FIXME limit it above
if(data.size() > 32*1024) {
System.err.println("Data is more than 32K: "+data.size());
outsb.append("Data is more than 32K: ").append(data.size());
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
byte[] dataBytes = BucketTools.toByteArray(data);
boolean evil = false;
for(byte b: dataBytes) {
// Look for escape codes
if(b == '\n') continue;
if(b == '\r') continue;
if(b < 32) evil = true;
}
if(evil) {
System.err.println("Data may contain escape codes which could cause the terminal to run arbitrary commands! Save it to a file if you must with GETFILE:");
outsb.append("Data may contain escape codes which could cause the terminal to run arbitrary commands! Save it to a file if you must with GETFILE:");
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
outsb.append("Data:\r\n");
outsb.append(new String(dataBytes, ENCODING));
} catch (FetchException e) {
outsb.append("Error: ").append(e.getMessage()).append("\r\n");
if((e.getMode() == FetchExceptionMode.SPLITFILE_ERROR) && (e.errorCodes != null)) {
outsb.append(e.errorCodes.toVerboseString());
}
if(e.newURI != null)
outsb.append("Permanent redirect: ").append(e.newURI).append("\r\n");
}
} else if(uline.startsWith("DUMP:")) {
// Should have a key next
String key = line.substring("DUMP:".length()).trim();
Logger.normal(this, "Key: "+key);
FreenetURI uri;
try {
uri = new FreenetURI(key);
Logger.normal(this, "Key: "+uri);
} catch (MalformedURLException e2) {
outsb.append("Malformed URI: ").append(key).append(" : ").append(e2);
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
try {
FetchContext context = client.getFetchContext();
FetchWaiter fw = new FetchWaiter((RequestClient)client);
ClientGetter get = new ClientGetter(fw, uri, context, RequestStarter.INTERACTIVE_PRIORITY_CLASS, null, null, null);
get.setMetaSnoop(new DumperSnoopMetadata());
get.start(n.clientCore.clientContext);
FetchResult result = fw.waitForCompletion();
ClientMetadata cm = result.getMetadata();
outsb.append("Content MIME type: ").append(cm.getMIMEType());
Bucket data = result.asBucket();
// FIXME limit it above
if(data.size() > 32*1024) {
System.err.println("Data is more than 32K: "+data.size());
outsb.append("Data is more than 32K: ").append(data.size());
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
byte[] dataBytes = BucketTools.toByteArray(data);
boolean evil = false;
for(byte b: dataBytes) {
// Look for escape codes
if(b == '\n') continue;
if(b == '\r') continue;
if(b < 32) evil = true;
}
if(evil) {
System.err.println("Data may contain escape codes which could cause the terminal to run arbitrary commands! Save it to a file if you must with GETFILE:");
outsb.append("Data may contain escape codes which could cause the terminal to run arbitrary commands! Save it to a file if you must with GETFILE:");
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
outsb.append("Data:\r\n");
outsb.append(new String(dataBytes, ENCODING));
} catch (FetchException e) {
outsb.append("Error: ").append(e.getMessage()).append("\r\n");
if((e.getMode() == FetchExceptionMode.SPLITFILE_ERROR) && (e.errorCodes != null)) {
outsb.append(e.errorCodes.toVerboseString());
}
if(e.newURI != null)
outsb.append("Permanent redirect: ").append(e.newURI).append("\r\n");
}
} else if(uline.startsWith("GETFILE:")) {
// Should have a key next
String key = line.substring("GETFILE:".length()).trim();
Logger.normal(this, "Key: "+key);
FreenetURI uri;
try {
uri = new FreenetURI(key);
} catch (MalformedURLException e2) {
outsb.append("Malformed URI: ").append(key).append(" : ").append(e2);
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
try {
long startTime = System.currentTimeMillis();
FetchResult result = client.fetch(uri);
ClientMetadata cm = result.getMetadata();
outsb.append("Content MIME type: ").append(cm.getMIMEType());
Bucket data = result.asBucket();
// Now calculate filename
String fnam = uri.getDocName();
fnam = sanitize(fnam);
if(fnam.length() == 0) {
fnam = "freenet-download-"+HexUtil.bytesToHex(BucketTools.hash(data), 0, 10);
String ext = DefaultMIMETypes.getExtension(cm.getMIMEType());
if((ext != null) && !ext.equals(""))
fnam += '.' + ext;
}
File f = new File(downloadsDir, fnam);
if(f.exists()) {
outsb.append("File exists already: ").append(fnam);
fnam = "freenet-"+System.currentTimeMillis()+ '-' +fnam;
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
BucketTools.copyTo(data, fos, Long.MAX_VALUE);
fos.close();
outsb.append("Written to ").append(fnam);
} catch (IOException e) {
outsb.append("Could not write file: caught ").append(e);
e.printStackTrace();
} finally {
if(fos != null) try {
fos.close();
} catch (IOException e1) {
// Ignore
}
}
long endTime = System.currentTimeMillis();
long sz = data.size();
double rate = 1000.0 * sz / (endTime-startTime);
outsb.append("Download rate: ").append(rate).append(" bytes / second");
} catch (FetchException e) {
outsb.append("Error: ").append(e.getMessage());
if((e.getMode() == FetchExceptionMode.SPLITFILE_ERROR) && (e.errorCodes != null)) {
outsb.append(e.errorCodes.toVerboseString());
}
if(e.newURI != null)
outsb.append("Permanent redirect: ").append(e.newURI).append("\r\n");
}
} else if(uline.startsWith("UPDATE")) {
outsb.append("starting the update process");
// FIXME run on separate thread
n.ticker.queueTimedJob(new Runnable() {
@Override
public void run() {
freenet.support.Logger.OSThread.logPID(this);
n.getNodeUpdater().arm();
}
}, 0);
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}else if(uline.startsWith("FILTER:")) {
line = line.substring("FILTER:".length()).trim();
outsb.append("Here is the result:\r\n");
final String content = readLines(reader, false);
final Bucket input = new ArrayBucket(content.getBytes("UTF-8"));
final Bucket output = new ArrayBucket();
InputStream inputStream = null;
OutputStream outputStream = null;
InputStream bis = null;
try {
inputStream = input.getInputStream();
outputStream = output.getOutputStream();
ContentFilter.filter(inputStream, outputStream, "text/html", new URI("http://127.0.0.1:8888/"), null, null, null, core.getLinkFilterExceptionProvider());
inputStream.close();
inputStream = null;
outputStream.close();
outputStream = null;
bis = output.getInputStream();
while(bis.available() > 0){
outsb.append((char)bis.read());
}
} catch (IOException e) {
outsb.append("Bucket error?: " + e.getMessage());
Logger.error(this, "Bucket error?: " + e, e);
} catch (URISyntaxException e) {
outsb.append("Internal error: " + e.getMessage());
Logger.error(this, "Internal error: " + e, e);
} finally {
Closer.close(inputStream);
Closer.close(outputStream);
Closer.close(bis);
input.free();
output.free();
}
outsb.append("\r\n");
}else if(uline.startsWith("BLOW")) {
n.getNodeUpdater().blow("caught an IOException : (Incompetent Operator) :p", true);
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
} else if(uline.startsWith("SHUTDOWN")) {
StringBuilder sb = new StringBuilder();
sb.append("Shutting node down.\r\n");
w.write(sb.toString());
w.flush();
n.exit("Shutdown from console");
} else if(uline.startsWith("RESTART")) {
StringBuilder sb = new StringBuilder();
sb.append("Restarting the node.\r\n");
w.write(sb.toString());
w.flush();
n.getNodeStarter().restart();
} else if(uline.startsWith("QUIT") && (core.directTMCI == this)) {
StringBuilder sb = new StringBuilder();
sb.append("QUIT command not available in console mode.\r\n");
w.write(sb.toString());
w.flush();
return false;
} else if(uline.startsWith("QUIT")) {
StringBuilder sb = new StringBuilder();
sb.append("Closing connection.\r\n");
w.write(sb.toString());
w.flush();
return true;
} else if(uline.startsWith("MEMSTAT")) {
Runtime rt = Runtime.getRuntime();
float freeMemory = rt.freeMemory();
float totalMemory = rt.totalMemory();
float maxMemory = rt.maxMemory();
long usedJavaMem = (long)(totalMemory - freeMemory);
long allocatedJavaMem = (long)totalMemory;
long maxJavaMem = (long)maxMemory;
int availableCpus = rt.availableProcessors();
NumberFormat thousendPoint = NumberFormat.getInstance();
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while(tg.getParent() != null) tg = tg.getParent();
int threadCount = tg.activeCount();
StringBuilder sb = new StringBuilder();
sb.append("Used Java memory:\u00a0" + SizeUtil.formatSize(usedJavaMem, true)+"\r\n");
sb.append("Allocated Java memory:\u00a0" + SizeUtil.formatSize(allocatedJavaMem, true)+"\r\n");
sb.append("Maximum Java memory:\u00a0" + SizeUtil.formatSize(maxJavaMem, true)+"\r\n");
sb.append("Running threads:\u00a0" + thousendPoint.format(threadCount)+"\r\n");
sb.append("Available CPUs:\u00a0" + availableCpus+"\r\n");
sb.append("Java Version:\u00a0" + System.getProperty("java.version")+"\r\n");
sb.append("JVM Vendor:\u00a0" + System.getProperty("java.vendor")+"\r\n");
sb.append("JVM Version:\u00a0" + System.getProperty("java.version")+"\r\n");
sb.append("OS Name:\u00a0" + System.getProperty("os.name")+"\r\n");
sb.append("OS Version:\u00a0" + System.getProperty("os.version")+"\r\n");
sb.append("OS Architecture:\u00a0" + System.getProperty("os.arch")+"\r\n");
w.write(sb.toString());
w.flush();
return false;
} else if(uline.startsWith("HELP")) {
printHeader(w);
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
} else if(uline.startsWith("PUT:") || (getCHKOnly = uline.startsWith("GETCHK:"))) {
if(getCHKOnly)
line = line.substring(("GETCHK:").length()).trim();
else
line = line.substring("PUT:".length()).trim();
String content;
if(line.length() > 0) {
// Single line insert
content = line;
} else {
// Multiple line insert
content = readLines(reader, false);
}
// Insert
byte[] data = content.getBytes(ENCODING);
InsertBlock block = new InsertBlock(new ArrayBucket(data), null, FreenetURI.EMPTY_CHK_URI);
FreenetURI uri;
try {
uri = client.insert(block, getCHKOnly, null);
} catch (InsertException e) {
outsb.append("Error: ").append(e.getMessage());
if(e.uri != null)
outsb.append("URI would have been: ").append(e.uri);
InsertExceptionMode mode = e.getMode();
if((mode == InsertExceptionMode.FATAL_ERRORS_IN_BLOCKS) || (mode == InsertExceptionMode.TOO_MANY_RETRIES_IN_BLOCKS)) {
outsb.append("Splitfile-specific error:\n").append(e.errorCodes.toVerboseString());
}
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
outsb.append("URI: ").append(uri);
////////////////////////////////////////////////////////////////////////////////
} else if(uline.startsWith("PUTDIR:") || (uline.startsWith("PUTSSKDIR")) || (getCHKOnly = uline.startsWith("GETCHKDIR:"))) {
// TODO: Check for errors?
boolean ssk = false;
if(uline.startsWith("PUTDIR:"))
line = line.substring("PUTDIR:".length());
else if(uline.startsWith("PUTSSKDIR:")) {
line = line.substring("PUTSSKDIR:".length());
ssk = true;
} else if(uline.startsWith("GETCHKDIR:"))
line = line.substring(("GETCHKDIR:").length());
else {
System.err.println("Impossible");
outsb.append("Impossible");
}
line = line.trim();
if(line.length() < 1) {
printHeader(w);
outsb.append("\r\n");
w.write(outsb.toString());
w.flush();
return false;
}
String defaultFile = null;
FreenetURI insertURI = FreenetURI.EMPTY_CHK_URI;
// set default file?
if (line.matches("^.*#.*$")) {
String[] split = line.split("#");
if(ssk) {
insertURI = new FreenetURI(split[0]);
line = split[1];
if(split.length > 2)
defaultFile = split[2];
} else {
defaultFile = split[1];
line = split[0];
}
}
HashMap<String, Object> bucketsByName =
makeBucketsByName(line);
if(defaultFile == null) {
String[] defaultFiles =
new String[] { "index.html", "index.htm", "default.html", "default.htm" };
for(String file: defaultFiles) {
if(bucketsByName.containsKey(file)) {
defaultFile = file;
break;
}
}
}
FreenetURI uri;
try {
uri = client.insertManifest(insertURI, bucketsByName, defaultFile);
uri = uri.addMetaStrings(new String[] { "" });
outsb.append("=======================================================");
outsb.append("URI: ").append(uri);
outsb.append("=======================================================");
} catch (InsertException e) {
outsb.append("Finished insert but: ").append(e.getMessage());
if(e.uri != null) {
uri = e.uri;
uri = uri.addMetaStrings(new String[] { "" });
outsb.append("URI would have been: ").append(uri);
}
if(e.errorCodes != null) {
outsb.append("Splitfile errors breakdown:");
outsb.append(e.errorCodes.toVerboseString());
}
Logger.error(this, "Caught "+e, e);
}
} else if(uline.startsWith("PUTFILE:") || (getCHKOnly = uline.startsWith("GETCHKFILE:"))) {
// Just insert to local store
if(getCHKOnly) {
line = line.substring(("GETCHKFILE:").length()).trim();
} else {
line = line.substring("PUTFILE:".length()).trim();
}
String mimeType = DefaultMIMETypes.guessMIMEType(line, false);
if (line.indexOf('#') > -1) {
String[] splittedLine = line.split("#");
line = splittedLine[0];
mimeType = splittedLine[1];
}
File f = new File(line);
outsb.append("Attempting to read file ").append(line);
long startTime = System.currentTimeMillis();
try {
if(!(f.exists() && f.canRead())) {
throw new FileNotFoundException();
}
// Guess MIME type
outsb.append(" using MIME type: ").append(mimeType).append("\r\n");
if(mimeType.equals(DefaultMIMETypes.DEFAULT_MIME_TYPE))
mimeType = ""; // don't need to override it
FileBucket fb = new FileBucket(f, true, false, false, false);
InsertBlock block = new InsertBlock(fb, new ClientMetadata(mimeType), FreenetURI.EMPTY_CHK_URI);
startTime = System.currentTimeMillis();
FreenetURI uri = client.insert(block, getCHKOnly, f.getName());
// FIXME depends on CHK's still being renamable