package com.imyeyu.network; import com.imyeyu.io.IO; import org.apache.hc.client5.http.fluent.Request; import org.apache.hc.client5.http.fluent.Response; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.io.HttpClientResponseHandler; import org.apache.hc.core5.http.io.entity.EntityUtils; import javax.naming.NoPermissionException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.file.Path; /** * 封装 {@link org.apache.hc.client5.http.fluent.Request} 计算返回进度 * * @author 夜雨 * @since 2025-06-26 13:03 */ public class ProgressiveRequest { private final Request request; private final ProgressiveCallback callback; private ProgressiveRequest(Request request, ProgressiveCallback callback) { this.request = request; this.callback = callback; } public static ProgressiveRequest wrap(Request request, ProgressiveCallback callback) { return new ProgressiveRequest(request, callback); } public void toFile(Path outputPath) throws IOException, NoPermissionException { processResponse(request.execute(), IO.getOutputStream(outputPath.toFile())); } public byte[] asBytes() throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); processResponse(request.execute(), os); return os.toByteArray(); } private void processResponse(Response response, OutputStream os) throws IOException { response.handleResponse((HttpClientResponseHandler) resp -> { HttpEntity entity = resp.getEntity(); if (entity == null) { throw new IOException("not found response entity"); } int code = resp.getCode(); if (400 <= code) { throw new IOException("response error: %s".formatted(code)); } long length = entity.getContentLength(); IO.toOutputStream(entity.getContent(), os, new IO.OnWriteCallback() { @Override public boolean handler(long total, long now) { return callback.handler(length, total, now); } }); EntityUtils.consume(entity); return null; }); } /** * * * @author 夜雨 * @since 2025-06-26 15:18 */ public interface ProgressiveCallback { boolean handler(long total, long read, long now); } }