Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

非滴链图床上传的临时文件目录权限问题导致上传失败 #246

Open
jianhong-li opened this issue Nov 26, 2023 · 0 comments

Comments

@jianhong-li
Copy link

版本: bolo 2.6

问题描述:

使用了七牛云的图床功能. 在测试时发现上传时会报错. 具体的报错内容如下:

[INFO 11-26 17:20:16 c.PicUploadProcessor 104] Uploading image [temp=/home/xxx/www/bolo-web/webapps/ROOT/image.png]
java.io.FileNotFoundException: /home/xxx/www/bolo-web/webapps/ROOT/image.png (Permission denied)
	at java.io.FileOutputStream.open0(Native Method)
	at java.io.FileOutputStream.open(FileOutputStream.java:270)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
	at org.apache.commons.fileupload.disk.DiskFileItem.write(DiskFileItem.java:423)
	at org.b3log.solo.bolo.pic.PicUploadProcessor.uploadPicture(PicUploadProcessor.java:106)
	at org.b3log.solo.bolo.pic.PicUploadProcessor_$$_jvstbc2_51._d10uploadPicture(PicUploadProcessor_$$_jvstbc2_51.java)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.b3log.latke.ioc.JavassistMethodHandler.invoke(JavassistMethodHandler.java:116)
	at org.b3log.solo.bolo.pic.PicUploadProcessor_$$_jvstbc2_51.uploadPicture(PicUploadProcessor_$$_jvstbc2_51.java)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

查看现在的源代码发现这个上传时会先把文件保存到本地.再使用UploadUtils上传到对应的目标地址:

            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setRepository(new File("temp/"));
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            Map okPic = new HashMap();
            List<String> errFiles = new ArrayList<>();
            try {
                List<FileItem> itemList = upload.parseRequest(context.getRequest());
                for (FileItem item : itemList) {
                    String name = item.getName();
                    String config;
                    try {
                        config = optionRepository.get(Option.ID_C_TUCHUANG_CONFIG).optString(Option.OPTION_VALUE);
                    } catch (Exception e) {
                        config = "hacpai";
                    }
                    final ServletContext servletContext = SoloServletListener.getServletContext();
                    final String assets = "/"; //  这里应该是直接使用了webapp的目录
                    String path = servletContext.getResource(assets).getPath();
                    path = URLDecoder.decode(path);
                    LOGGER.info("Uploading image [temp=" + path + name + "]");
                    File file = new File(path + name);
                    item.write(file);
                    item.delete();
                    try {
                        String url = UploadUtil.upload(config, file);
                        if (url.isEmpty()) {
                            url = "接口调用错误,请检查偏好设置-自定义图床配置,清除浏览器缓存并重启服务端。";
                        }
                        okPic.put(name, url);
                    } catch (Exception e) {
                        errFiles.add(name);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

出于安全考虑一般部署的webapp目录是不可写的. 我看原来是写到的是temp目录,不知为何后面修改为了webapp?

修改建议:

  1. 使用temp目录进行缓存.
  2. 如果后续的上传不是异步.(看代码确实不是) 建议直接使用apache的upload的fileItem 直接获取inputstream进行上传. 这样则少一次本地缓存.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant