add base64 command.

pull/1649/merge
hengyunabc
parent b2a069f89f
commit ffa536ed21

@ -1,5 +1,6 @@
package com.taobao.arthas.core.command;
import com.taobao.arthas.core.command.basic1000.Base64Command;
import com.taobao.arthas.core.command.basic1000.CatCommand;
import com.taobao.arthas.core.command.basic1000.ClsCommand;
import com.taobao.arthas.core.command.basic1000.EchoCommand;
@ -101,6 +102,7 @@ public class BuiltinCommandPack implements CommandResolver {
commands.add(Command.create(LoggerCommand.class));
commands.add(Command.create(HistoryCommand.class));
commands.add(Command.create(CatCommand.class));
commands.add(Command.create(Base64Command.class));
commands.add(Command.create(EchoCommand.class));
commands.add(Command.create(PwdCommand.class));
commands.add(Command.create(MBeanCommand.class));

@ -0,0 +1,170 @@
package com.taobao.arthas.core.command.basic1000;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.common.IOUtils;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.Base64Model;
import com.taobao.arthas.core.shell.cli.Completion;
import com.taobao.arthas.core.shell.cli.CompletionUtils;
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Name;
import com.taobao.middleware.cli.annotations.Option;
import com.taobao.middleware.cli.annotations.Summary;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.base64.Base64;
import io.netty.util.CharsetUtil;
/**
*
* @author hengyunabc 2021-01-05
*
*/
@Name("base64")
@Summary("Encode and decode using Base64 representation")
@Description(Constants.EXAMPLE +
" base64 /tmp/test.txt\n" +
" base64 --input /tmp/test.txt --output /tmp/result.txt\n" +
" base64 -d /tmp/result.txt\n"
+ Constants.WIKI + Constants.WIKI_HOME + "base64")
public class Base64Command extends AnnotatedCommand {
private static final Logger logger = LoggerFactory.getLogger(Base64Command.class);
private String file;
private Integer sizeLimit = 128 * 1024;
private int maxSizeLimit = 8 * 1024 * 1024;
private boolean decode;
private String input;
private String output;
@Argument(argName = "file", index = 0, required = false)
@Description("file")
public void setFiles(String file) {
this.file = file;
}
@Option(shortName = "d", longName = "decode", flag = true)
@Description("decodes input")
public void setDecode(boolean decode) {
this.decode = decode;
}
@Option(shortName = "i", longName = "input")
@Description("input file")
public void setInput(String input) {
this.input = input;
}
@Option(shortName = "o", longName = "output")
@Description("output file")
public void setOutput(String output) {
this.output = output;
}
@Option(shortName = "M", longName = "sizeLimit")
@Description("Upper size limit in bytes for the result (128 * 1024 by default, the maximum value is 8 * 1024 * 1024)")
public void setSizeLimit(Integer sizeLimit) {
this.sizeLimit = sizeLimit;
}
@Override
public void process(CommandProcess process) {
if (!verifyOptions(process)) {
return;
}
// 确认输入
if (file == null && this.input != null) {
file = input;
}
File f = new File(file);
if (!f.exists()) {
process.end(-1, file + ": No such file or directory");
return;
}
if (f.isDirectory()) {
process.end(-1, file + ": Is a directory");
return;
}
if (f.length() > sizeLimit) {
process.end(-1, file + ": Is too large, size: " + f.length());
return;
}
InputStream input = null;
try {
input = new FileInputStream(f);
byte[] bytes = IOUtils.getBytes(input);
ByteBuf convertResult = null;
if (this.decode) {
convertResult = Base64.decode(Unpooled.wrappedBuffer(bytes));
} else {
convertResult = Base64.encode(Unpooled.wrappedBuffer(bytes));
}
if (this.output != null) {
int readableBytes = convertResult.readableBytes();
OutputStream out = new FileOutputStream(this.output);
convertResult.readBytes(out, readableBytes);
process.appendResult(new Base64Model(null));
} else {
String base64Str = convertResult.toString(CharsetUtil.UTF_8);
process.appendResult(new Base64Model(base64Str));
}
} catch (IOException e) {
logger.error("read file error. name: " + file, e);
process.end(1, "read file error: " + e.getMessage());
return;
} finally {
IOUtils.close(input);
}
process.end();
}
private boolean verifyOptions(CommandProcess process) {
if(this.file == null && this.input == null) {
process.end(-1);
return false;
}
if (sizeLimit > maxSizeLimit) {
process.end(-1, "sizeLimit cannot be large than: " + maxSizeLimit);
return false;
}
// 目前不支持过滤限制http请求执行的文件大小
int maxSizeLimitOfNonTty = 128 * 1024;
if (!process.session().isTty() && sizeLimit > maxSizeLimitOfNonTty) {
process.end(-1,
"When executing in non-tty session, sizeLimit cannot be large than: " + maxSizeLimitOfNonTty);
return false;
}
return true;
}
@Override
public void complete(Completion completion) {
if (!CompletionUtils.completeFilePath(completion)) {
super.complete(completion);
}
}
}

@ -39,6 +39,7 @@ public class ResultViewResolver {
//registerView(HistoryView.class);
registerView(EchoView.class);
registerView(CatView.class);
registerView(Base64View.class);
registerView(OptionsView.class);
registerView(SystemPropertyView.class);
registerView(SystemEnvView.class);

@ -8,6 +8,7 @@
* [cat](cat.md)——打印文件内容和linux里的cat命令类似
* [echo](echo.md)--打印参数和linux里的echo命令类似
* [grep](grep.md)——匹配查找和linux里的grep命令类似
* [base64](base64.md)——base64编码转换和linux里的base64命令类似
* [tee](tee.md)——复制标准输入到标准输出和指定的文件和linux里的tee命令类似
* [pwd](pwd.md)——返回当前的工作目录和linux命令类似
* cls——清空当前屏幕区域

@ -35,6 +35,7 @@
* [cat](cat.md)
* [echo](echo.md)
* [grep](grep.md)
* [base64](base64.md)
* [tee](tee.md)
* [pwd](pwd.md)
* [options](options.md)

@ -8,6 +8,7 @@ Advanced Usage
* [cat](cat.md) - Concatenate and print files
* [echo](echo.md) - write arguments to the standard output
* [grep](grep.md) - Pattern searcher
* [base64](base64.md) - Encode and decode using Base64 representation.
* [tee](tee.md) - Copies standard input to standard output, making a copy in zero or more files.
* [pwd](pwd.md) - Return working directory name
* session - display current session information

@ -35,6 +35,7 @@ All Commands
* [cat](cat.md)
* [echo](echo.md)
* [grep](grep.md)
* [base64](base64.md)
* [tee](tee.md)
* [pwd](pwd.md)
* [options](options.md)

Loading…
Cancel
Save