Compare commits
30 Commits
zxbu-patch
...
main
Author | SHA1 | Date |
---|---|---|
zxbu | d5b8f01e32 | |
zxbu | 6ade2dbfe8 | |
liuyonghui | f0bdb77674 | |
zxbu | c9e87bfcd7 | |
Delphi Lin | 2407802e5b | |
zxbu | 121ec196c9 | |
zxbu | ef3cb8540d | |
zhouxin | fa8b890e26 | |
zxbu | 08124d17e7 | |
kid101x | fef74ee99c | |
zxbu | ce08dc0566 | |
zuodajiang | b8f183be5e | |
zxbu | 04a97ea189 | |
zhouxin | da567fd6c2 | |
zhouxin | 044ec20f59 | |
zhouxin | 1718782b60 | |
zxbu | 62260137cb | |
zhouxin | 394eb7b6db | |
zxbu | eca5f7da36 | |
zxbu | f480c894f8 | |
zxbu | ccb7552422 | |
zhouxin | fec2079f5c | |
zxbu | 83283a2133 | |
zhouxin | 55dfacd3ee | |
zhouxin | 453e91f87c | |
zhouxin | ae620231fe | |
zhouxin | 410b742959 | |
zhouxin | cb9dc7e777 | |
zxbu | f52c1816eb | |
zxbu | 0e9cce633d |
|
@ -66,7 +66,7 @@ jobs:
|
|||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
FROM maven:3-jdk-8-alpine AS maven
|
||||
FROM maven:3.6.3-jdk-11 AS maven
|
||||
USER root
|
||||
COPY ./ /tmp/code
|
||||
RUN cd /tmp/code && mvn clean package -Dmaven.test.skip=true -Dmaven.javadoc.skip=true
|
||||
|
||||
|
||||
FROM openjdk:8-jdk-alpine
|
||||
FROM openjdk:11-jdk-oracle
|
||||
COPY --from=maven /tmp/code/target/*.jar /webdav.jar
|
||||
EXPOSE 8080
|
||||
ENV JAVA_OPTS="-Xmx1g"
|
||||
|
|
76
README.md
76
README.md
|
@ -1,4 +1,27 @@
|
|||
|
||||
说明:[1.1.0版本](https://github.com/zxbu/webdav-aliyundriver/releases/tag/v1.1.0)支持阿里Teambition网盘的webdav协议,后续的2.x版本仅支持阿里云盘,不再维护Teambition网盘版本
|
||||
|
||||
- [webdav-aliyundriver](#webdav-aliyundriver)
|
||||
- [如何使用](#如何使用)
|
||||
- [Jar包运行](#jar包运行)
|
||||
- [容器运行](#容器运行)
|
||||
- [Docker-Compose](#docker-compose)
|
||||
- [参数说明](#参数说明)
|
||||
- [QQ群](#qq群)
|
||||
- [新手教程](#新手教程)
|
||||
- [群晖](#群晖)
|
||||
- [Windows10](#windows10)
|
||||
- [Linux](#linux)
|
||||
- [Mac](#mac)
|
||||
- [客户端兼容性](#客户端兼容性)
|
||||
- [浏览器获取refreshToken方式](#浏览器获取refreshtoken方式)
|
||||
- [功能说明](#功能说明)
|
||||
- [支持的功能](#支持的功能)
|
||||
- [暂不支持的功能](#暂不支持的功能)
|
||||
- [已知问题](#已知问题)
|
||||
- [TODO](#todo)
|
||||
- [免责声明](#免责声明)
|
||||
|
||||
# webdav-aliyundriver
|
||||
本项目实现了阿里云盘的webdav协议,只需要简单的配置一下,就可以让阿里云盘变身为webdav协议的文件服务器。
|
||||
基于此,你可以把阿里云盘挂载为Windows、Linux、Mac系统的磁盘,可以通过NAS系统做文件管理或文件同步,更多玩法等你挖掘
|
||||
|
@ -21,6 +44,32 @@ docker run -d --name=webdav-aliyundriver --restart=always -p 8080:8080 -v /etc/
|
|||
# JAVA_OPTS 可修改最大内存占用,比如 -e JAVA_OPTS="-Xmx512m" 表示最大内存限制为512m
|
||||
```
|
||||
|
||||
## Docker-Compose
|
||||
```yml
|
||||
version: "3.0"
|
||||
services:
|
||||
webdav-aliyundriver:
|
||||
image: zx5253/webdav-aliyundriver
|
||||
container_name: aliyundriver
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
- ALIYUNDRIVE_REFRESH_TOKEN=refreshToken
|
||||
- ALIYUNDRIVE_AUTH_USER_NAME=admin
|
||||
- ALIYUNDRIVE_AUTH_PASSWORD=admin
|
||||
- JAVA_OPTS=-Xmx1g
|
||||
volumes:
|
||||
- /etc/aliyun-driver/:/etc/aliyun-driver/
|
||||
ports:
|
||||
- 6666:8080
|
||||
restart: always
|
||||
|
||||
# “refreshToken”请根据下文说明自行获取。
|
||||
# “ALIYUNDRIVE_AUTH_USER-NAME”和“ALIYUNDRIVE_AUTH_PASSWORD”为连接用户名和密码,建议更改。
|
||||
# “/etc/aliyun-driver/:/etc/aliyun-driver/”,可以把冒号前改为指定目录,比如“/homes/USER/docker/alidriver/:/etc/aliyun-driver/”。
|
||||
# 删除了“/etc/localtime:/etc/localtime”,如有需要同步时间请自行添加在environment下。
|
||||
# 端口6666可自行按需更改,此端口为WebDAV连接端口,8080为容器内配置端口,修改请量力而为。
|
||||
# 建议不要保留这些中文注释,以防报错,比如QNAP。
|
||||
```
|
||||
|
||||
# 参数说明
|
||||
```bash
|
||||
|
@ -34,10 +83,20 @@ docker run -d --name=webdav-aliyundriver --restart=always -p 8080:8080 -v /etc/
|
|||
WebDav账户,默认admin
|
||||
--aliyundrive.auth.password=admin
|
||||
WebDav密码,默认admin
|
||||
--aliyundrive.work-dir=/etc/aliyun-driver/
|
||||
token挂载路径(如果多开的话,需修改此配置)
|
||||
|
||||
```
|
||||
# QQ群
|
||||
> 群号:789738128
|
||||
> 群号(已满):789738128
|
||||
|
||||
> 二群群号(已满):979024890
|
||||
|
||||
> 三群群号(已满):212673498
|
||||
|
||||
> 四群群号(已满):752067171
|
||||
|
||||
> 五群群号:555954095
|
||||
|
||||
# 新手教程
|
||||
## 群晖
|
||||
|
@ -59,6 +118,7 @@ TODO
|
|||
| Rclone | 可用 | 可用 | 推荐,支持各个系统 |
|
||||
| Mac原生 | 可用 | 可用 | |
|
||||
| Windows原生 | 可用 | 有点小问题 | 不建议,适配有点问题,上传报错 |
|
||||
| RaiDrive | 可用 | 可用 | Windows平台下建议用这个 |
|
||||
|
||||
|
||||
# 浏览器获取refreshToken方式
|
||||
|
@ -77,13 +137,25 @@ TODO
|
|||
6. 文件上传(支持大文件自动分批上传)
|
||||
7. 支持超大文件上传(官方限制30G)
|
||||
8. 支持WebDav权限校验(默认账户密码:admin/admin)
|
||||
9. 文件下载断点续传
|
||||
10. Webdav下的流媒体播放等功能
|
||||
## 暂不支持的功能
|
||||
1. 移动文件到其他目录的同时,修改文件名。比如 /a.zip 移动到 /b/a1.zip,是不支持的
|
||||
2. 文件上传断点续传
|
||||
3. 文件下载断点续传
|
||||
3. 部分客户端兼容性不好
|
||||
## 已知问题
|
||||
1. 没有做文件sha1校验,不保证上传文件的100%准确性(一般场景下,是没问题的)
|
||||
2. 通过文件名和文件大小判断是否重复。也就是说如果一个文件即使发生了更新,但其大小没有任何改变,是不会自动上传的
|
||||
3. 不支持文件名包含 `/` 字符
|
||||
|
||||
## TODO
|
||||
1. 支持更多登录方式(验证码、账号密码等)
|
||||
|
||||
|
||||
# 免责声明
|
||||
1. 本软件为免费开源项目,无任何形式的盈利行为。
|
||||
2. 本软件服务于阿里云盘,旨在让阿里云盘功能更强大。如有侵权,请与我联系,会及时处理。
|
||||
3. 本软件皆调用官方接口实现,无任何“Hack”行为,无破坏官方接口行为。
|
||||
5. 本软件仅做流量转发,不拦截、存储、篡改任何用户数据。
|
||||
6. 严禁使用本软件进行盈利、损坏官方、散落任何违法信息等行为。
|
||||
7. 本软件不作任何稳定性的承诺,如因使用本软件导致的文件丢失、文件破坏等意外情况,均与本软件无关。
|
||||
|
|
8
pom.xml
8
pom.xml
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
<groupId>com.github.zxbu</groupId>
|
||||
<artifactId>webdav-aliyundriver</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<version>2.4.0</version>
|
||||
<name>webdav</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
|
@ -30,6 +30,12 @@
|
|||
<version>3.14.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
@ -8,11 +8,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
public class WebdavTeambitionApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
|
|
@ -7,7 +7,9 @@ import okhttp3.*;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -42,7 +44,14 @@ public class AliYunDriverClient {
|
|||
@Override
|
||||
public Request authenticate(Route route, Response response) throws IOException {
|
||||
if (response.code() == 401 && response.body() != null && response.body().string().contains("AccessToken")) {
|
||||
String refreshTokenResult = post("https://websv.aliyundrive.com/token/refresh", Collections.singletonMap("refresh_token", readRefreshToken()));
|
||||
String refreshTokenResult;
|
||||
try {
|
||||
refreshTokenResult = post("https://websv.aliyundrive.com/token/refresh", Collections.singletonMap("refresh_token", readRefreshToken()));
|
||||
} catch (Exception e) {
|
||||
// 如果置换token失败,先清空原token文件,再尝试一次
|
||||
deleteRefreshTokenFile();
|
||||
refreshTokenResult = post("https://websv.aliyundrive.com/token/refresh", Collections.singletonMap("refresh_token", readRefreshToken()));
|
||||
}
|
||||
String accessToken = (String) JsonUtil.getJsonNodeValue(refreshTokenResult, "access_token");
|
||||
String refreshToken = (String) JsonUtil.getJsonNodeValue(refreshTokenResult, "refresh_token");
|
||||
Assert.hasLength(accessToken, "获取accessToken失败");
|
||||
|
@ -85,12 +94,32 @@ public class AliYunDriverClient {
|
|||
}
|
||||
|
||||
|
||||
public InputStream download(String url) {
|
||||
Request request = new Request.Builder().header("referer", "https://www.aliyundrive.com/").url(url).build();
|
||||
public Response download(String url, HttpServletRequest httpServletRequest, long size ) {
|
||||
Request.Builder builder = new Request.Builder().header("referer", "https://www.aliyundrive.com/");
|
||||
String range = httpServletRequest.getHeader("range");
|
||||
if (range != null) {
|
||||
// 如果range最后 >= size, 则去掉
|
||||
String[] split = range.split("-");
|
||||
if (split.length == 2) {
|
||||
String end = split[1];
|
||||
if (Long.parseLong(end) >= size) {
|
||||
range = range.substring(0, range.lastIndexOf('-') + 1);
|
||||
}
|
||||
}
|
||||
builder.header("range", range);
|
||||
}
|
||||
|
||||
String ifRange = httpServletRequest.getHeader("if-range");
|
||||
if (ifRange != null) {
|
||||
builder.header("if-range", ifRange);
|
||||
}
|
||||
|
||||
|
||||
Request request = builder.url(url).build();
|
||||
Response response = null;
|
||||
try {
|
||||
response = okHttpClient.newCall(request).execute();
|
||||
return response.body().byteStream();
|
||||
return response;
|
||||
} catch (IOException e) {
|
||||
throw new WebdavException(e);
|
||||
}
|
||||
|
@ -178,6 +207,16 @@ public class AliYunDriverClient {
|
|||
return aliYunDriveProperties.getUrl() + url;
|
||||
}
|
||||
|
||||
private void deleteRefreshTokenFile() {
|
||||
String refreshTokenPath = aliYunDriveProperties.getWorkDir() + "refresh-token";
|
||||
Path path = Paths.get(refreshTokenPath);
|
||||
try {
|
||||
Files.delete(path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private String readRefreshToken() {
|
||||
String refreshTokenPath = aliYunDriveProperties.getWorkDir() + "refresh-token";
|
||||
Path path = Paths.get(refreshTokenPath);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package com.github.zxbu.webdavteambition.config;
|
||||
|
||||
import com.github.zxbu.webdavteambition.model.result.TFile;
|
||||
import com.github.zxbu.webdavteambition.store.AliYunDriverClientService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AliYunDriverCronTask {
|
||||
|
||||
@Autowired
|
||||
private AliYunDriverClientService aliYunDriverClientService;
|
||||
|
||||
/**
|
||||
* 每隔5分钟请求一下接口,保证token不过期
|
||||
*/
|
||||
@Scheduled(initialDelay = 30 * 1000, fixedDelay = 5 * 60 * 1000)
|
||||
public void refreshToken() {
|
||||
try {
|
||||
TFile root = aliYunDriverClientService.getTFileByPath("/");
|
||||
aliYunDriverClientService.getTFiles(root.getFile_id());
|
||||
} catch (Exception e) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.github.zxbu.webdavteambition.model;
|
|||
public class DownloadRequest {
|
||||
private String drive_id;
|
||||
private String file_id;
|
||||
private Integer expire_sec = 14400;
|
||||
|
||||
public String getDrive_id() {
|
||||
return drive_id;
|
||||
|
@ -19,4 +20,12 @@ public class DownloadRequest {
|
|||
public void setFile_id(String file_id) {
|
||||
this.file_id = file_id;
|
||||
}
|
||||
|
||||
public Integer getExpire_sec() {
|
||||
return expire_sec;
|
||||
}
|
||||
|
||||
public void setExpire_sec(Integer expire_sec) {
|
||||
this.expire_sec = expire_sec;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.github.zxbu.webdavteambition.store;
|
|||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.zxbu.webdavteambition.client.AliYunDriverClient;
|
||||
import com.github.zxbu.webdavteambition.model.*;
|
||||
import com.github.zxbu.webdavteambition.model.result.TFile;
|
||||
|
@ -10,6 +12,7 @@ import com.github.zxbu.webdavteambition.model.result.UploadPreResult;
|
|||
import com.github.zxbu.webdavteambition.util.JsonUtil;
|
||||
import net.sf.webdav.exceptions.WebdavException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Response;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -17,10 +20,12 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class AliYunDriverClientService {
|
||||
|
@ -29,7 +34,12 @@ public class AliYunDriverClientService {
|
|||
private static String rootPath = "/";
|
||||
private static int chunkSize = 10485760; // 10MB
|
||||
private TFile rootTFile = null;
|
||||
private final ThreadLocal<Map<String, Set<TFile>>> tFilesCache = new ThreadLocal<>();
|
||||
|
||||
private static Cache<String, Set<TFile>> tFilesCache = Caffeine.newBuilder()
|
||||
.initialCapacity(128)
|
||||
.maximumSize(1024)
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
private final AliYunDriverClient client;
|
||||
|
||||
|
@ -42,12 +52,7 @@ public class AliYunDriverClientService {
|
|||
}
|
||||
|
||||
public Set<TFile> getTFiles(String nodeId) {
|
||||
Map<String, Set<TFile>> map = tFilesCache.get();
|
||||
if (map == null) {
|
||||
map = new ConcurrentHashMap<>();
|
||||
tFilesCache.set(map);
|
||||
}
|
||||
Set<TFile> tFiles = map.computeIfAbsent(nodeId, key -> {
|
||||
Set<TFile> tFiles = tFilesCache.get(nodeId, key -> {
|
||||
// 获取真实的文件列表
|
||||
return getTFiles2(nodeId);
|
||||
});
|
||||
|
@ -276,14 +281,15 @@ public class AliYunDriverClientService {
|
|||
return getNodeIdByPath2(path);
|
||||
}
|
||||
|
||||
public InputStream download(String path) {
|
||||
public Response download(String path, HttpServletRequest request, long size ) {
|
||||
TFile file = getTFileByPath(path);
|
||||
DownloadRequest downloadRequest = new DownloadRequest();
|
||||
downloadRequest.setDrive_id(client.getDriveId());
|
||||
downloadRequest.setFile_id(file.getFile_id());
|
||||
String json = client.post("/file/get_download_url", downloadRequest);
|
||||
Object url = JsonUtil.getJsonNodeValue(json, "url");
|
||||
return client.download(url.toString());
|
||||
LOGGER.debug("{} url = {}", path, url);
|
||||
return client.download(url.toString(), request, size);
|
||||
}
|
||||
|
||||
private TFile getNodeIdByPath2(String path) {
|
||||
|
@ -357,11 +363,7 @@ public class AliYunDriverClientService {
|
|||
return path;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
Map<String, Set<TFile>> map = tFilesCache.get();
|
||||
if (map != null) {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
tFilesCache.invalidateAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.sf.webdav.IWebdavStore;
|
|||
import net.sf.webdav.StoredObject;
|
||||
import net.sf.webdav.Transaction;
|
||||
import net.sf.webdav.exceptions.WebdavException;
|
||||
import okhttp3.Response;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -17,6 +18,8 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.Principal;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class AliYunDriverFileSystemStore implements IWebdavStore {
|
||||
|
@ -36,14 +39,13 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
|
||||
@Override
|
||||
public void destroy() {
|
||||
LOGGER.debug("destroy");
|
||||
LOGGER.info("destroy");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITransaction begin(Principal principal, HttpServletRequest req, HttpServletResponse resp) {
|
||||
LOGGER.debug("begin");
|
||||
aliYunDriverClientService.clearCache();
|
||||
return new Transaction(principal, req, resp);
|
||||
}
|
||||
|
||||
|
@ -54,7 +56,6 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
|
||||
@Override
|
||||
public void commit(ITransaction transaction) {
|
||||
aliYunDriverClientService.clearCache();
|
||||
LOGGER.debug("commit");
|
||||
}
|
||||
|
||||
|
@ -79,8 +80,24 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
|
||||
@Override
|
||||
public InputStream getResourceContent(ITransaction transaction, String resourceUri) {
|
||||
LOGGER.debug("getResourceContent: {}", resourceUri);
|
||||
return aliYunDriverClientService.download(resourceUri);
|
||||
LOGGER.info("getResourceContent: {}", resourceUri);
|
||||
Enumeration<String> headerNames = transaction.getRequest().getHeaderNames();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String s = headerNames.nextElement();
|
||||
LOGGER.debug("{} request: {} = {}",resourceUri, s, transaction.getRequest().getHeader(s));
|
||||
}
|
||||
HttpServletResponse response = transaction.getResponse();
|
||||
long size = getResourceLength(transaction, resourceUri);
|
||||
Response downResponse = aliYunDriverClientService.download(resourceUri, transaction.getRequest(), size);
|
||||
response.setContentLengthLong(downResponse.body().contentLength());
|
||||
LOGGER.debug("{} code = {}", resourceUri, downResponse.code());
|
||||
for (String name : downResponse.headers().names()) {
|
||||
LOGGER.debug("{} downResponse: {} = {}", resourceUri, name, downResponse.header(name));
|
||||
response.addHeader(name, downResponse.header(name));
|
||||
}
|
||||
response.setStatus(downResponse.code());
|
||||
return downResponse.body().byteStream();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,7 +108,8 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
|
||||
long contentLength = request.getContentLength();
|
||||
if (contentLength < 0) {
|
||||
contentLength = Long.parseLong(request.getHeader("content-length"));
|
||||
contentLength = Long.parseLong(Optional.ofNullable(request.getHeader("content-length"))
|
||||
.orElse(request.getHeader("X-Expected-Entity-Length")));
|
||||
}
|
||||
aliYunDriverClientService.uploadPre(resourceUri, contentLength, content);
|
||||
|
||||
|
@ -113,7 +131,7 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
|
||||
@Override
|
||||
public String[] getChildrenNames(ITransaction transaction, String folderUri) {
|
||||
LOGGER.debug("getChildrenNames: {}", folderUri);
|
||||
LOGGER.info("getChildrenNames: {}", folderUri);
|
||||
TFile tFile = aliYunDriverClientService.getTFileByPath(folderUri);
|
||||
if (tFile.getType().equals(FileType.file.name())) {
|
||||
return new String[0];
|
||||
|
@ -126,7 +144,11 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
|
||||
@Override
|
||||
public long getResourceLength(ITransaction transaction, String path) {
|
||||
LOGGER.debug("getResourceLength: {}", path);
|
||||
return getResourceLength2(transaction, path);
|
||||
}
|
||||
|
||||
public long getResourceLength2(ITransaction transaction, String path) {
|
||||
LOGGER.info("getResourceLength: {}", path);
|
||||
TFile tFile = aliYunDriverClientService.getTFileByPath(path);
|
||||
if (tFile == null || tFile.getSize() == null) {
|
||||
return 384;
|
||||
|
@ -164,12 +186,12 @@ public class AliYunDriverFileSystemStore implements IWebdavStore {
|
|||
public StoredObject getStoredObject(ITransaction transaction, String uri) {
|
||||
|
||||
|
||||
LOGGER.debug("getStoredObject: {}", uri);
|
||||
LOGGER.info("getStoredObject: {}", uri);
|
||||
TFile tFile = aliYunDriverClientService.getTFileByPath(uri);
|
||||
if (tFile != null) {
|
||||
StoredObject so = new StoredObject();
|
||||
so.setFolder(tFile.getType().equalsIgnoreCase("folder"));
|
||||
so.setResourceLength(getResourceLength(transaction, uri));
|
||||
so.setResourceLength(getResourceLength2(transaction, uri));
|
||||
so.setCreationDate(tFile.getCreated_at());
|
||||
so.setLastModified(tFile.getUpdated_at());
|
||||
return so;
|
||||
|
|
|
@ -18,6 +18,7 @@ package net.sf.webdav.methods;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
|
@ -32,6 +33,8 @@ import net.sf.webdav.IWebdavStore;
|
|||
import net.sf.webdav.StoredObject;
|
||||
import net.sf.webdav.WebdavStatus;
|
||||
import net.sf.webdav.locking.ResourceLocks;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.springframework.web.util.UriUtils;
|
||||
|
||||
public class DoGet extends DoHead {
|
||||
|
||||
|
@ -61,30 +64,33 @@ public class DoGet extends DoHead {
|
|||
OutputStream out = resp.getOutputStream();
|
||||
InputStream in = _store.getResourceContent(transaction, path);
|
||||
try {
|
||||
int read = -1;
|
||||
byte[] copyBuffer = new byte[BUF_SIZE];
|
||||
|
||||
while ((read = in.read(copyBuffer, 0, copyBuffer.length)) != -1) {
|
||||
out.write(copyBuffer, 0, read);
|
||||
if (in != null) {
|
||||
LOG.debug("开始 {}, ", path);
|
||||
IOUtils.copyLarge(in, out);
|
||||
LOG.debug("结束 {}", path);
|
||||
}
|
||||
} finally {
|
||||
// flushing causes a IOE if a file is opened on the webserver
|
||||
// client disconnected before server finished sending response
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Closing InputStream causes Exception!\n"
|
||||
+ e.toString());
|
||||
LOG.warn("{} Closing InputStream causes Exception!\n", path
|
||||
,e);
|
||||
}
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Flushing OutputStream causes Exception!\n"
|
||||
+ e.toString());
|
||||
LOG.warn("{} Flushing OutputStream causes Exception!\n", path
|
||||
,e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("{} doBody causes Exception!\n", path
|
||||
,e);
|
||||
LOG.trace(e.toString());
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +147,7 @@ public class DoGet extends DoHead {
|
|||
childrenTemp.append("\">");
|
||||
childrenTemp.append("<td>");
|
||||
childrenTemp.append("<a href=\"");
|
||||
childrenTemp.append(child);
|
||||
childrenTemp.append(UriUtils.encode(child, "utf-8"));
|
||||
StoredObject obj= _store.getStoredObject(transaction, path+"/"+child);
|
||||
if (obj == null)
|
||||
{
|
||||
|
|
|
@ -209,6 +209,9 @@ public class DoLock extends AbstractMethod {
|
|||
return;
|
||||
}
|
||||
nullSo = _store.getStoredObject(transaction, _path);
|
||||
if (nullSo == null) {
|
||||
nullSo = new StoredObject();
|
||||
}
|
||||
// define the newly created resource as null-resource
|
||||
nullSo.setNullResource(true);
|
||||
|
||||
|
@ -416,8 +419,13 @@ public class DoLock extends AbstractMethod {
|
|||
|
||||
if (currentNode.getNodeType() == Node.ELEMENT_NODE
|
||||
|| currentNode.getNodeType() == Node.TEXT_NODE) {
|
||||
if (currentNode.getFirstChild() != null) {
|
||||
_lockOwner = currentNode.getFirstChild()
|
||||
.getNodeValue();
|
||||
} else {
|
||||
_lockOwner = currentNode.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,11 @@ public class DoUnlock extends DeterminableMethod {
|
|||
if (_resourceLocks.unlock(transaction, lockId, owner)) {
|
||||
StoredObject so = _store.getStoredObject(
|
||||
transaction, path);
|
||||
if (so == null) {
|
||||
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (so.isNullResource()) {
|
||||
_store.removeObject(transaction, path);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue