Files
hls-proxy/src/main/java/com/backend/hls/proxy/service/FetchService.java

116 lines
3.6 KiB
Java

package com.backend.hls.proxy.service;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.backend.hls.proxy.exception.FetchFailException;
import com.backend.hls.proxy.model.SimpleResponse;
@Service
public class FetchService {
private final HttpClient httpClient;
public FetchService(HttpClient httpClient) {
this.httpClient = httpClient;
}
/**
* Fetch text content from URL
*
* @throws FetchFailException
*/
@Cacheable("hlsPlaylistContent")
public String fetchTextContent(String url) throws FetchFailException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.build();
try {
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new FetchFailException(
"Failed to fetch content from " + url + ", status: " + response.statusCode(),
response);
}
return response.body();
} catch (IOException | InterruptedException e) {
throw new FetchFailException("Failed to fetch content from " + url, e);
}
}
/**
* Fetch binary content from URL
*
* @throws FetchFailException
*/
@Cacheable("playlistSegmentContent")
public SimpleResponse<byte[]> fetchBinaryContent(String url) throws FetchFailException {
return fetchBinaryContent(url, null);
}
/**
* Fetch binary content from URL
*
* @throws FetchFailException
*/
@Cacheable("playlistSegmentContent")
public SimpleResponse<byte[]> fetchBinaryContent(String url, String rangeHeader)
throws FetchFailException {
HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(URI.create(url));
if (rangeHeader != null && !rangeHeader.isEmpty()) {
builder.header("Range", rangeHeader);
}
try {
HttpResponse<byte[]> response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofByteArray());
if (response.statusCode() >= 400) {
throw new FetchFailException(
"Failed to fetch content from " + url + ", status: " + response.statusCode(),
response);
}
return new SimpleResponse<byte[]>(response.body(), response.headers());
} catch (IOException | InterruptedException e) {
throw new FetchFailException("Failed to fetch content from " + url, e);
}
}
/**
* Fetch content length
*
* @throws FetchFailException
*/
public long getContentLength(String url)
throws IOException, InterruptedException, FetchFailException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.method("HEAD", HttpRequest.BodyPublishers.noBody())
.timeout(Duration.ofSeconds(10))
.build();
HttpResponse<Void> response = httpClient.send(request,
HttpResponse.BodyHandlers.discarding());
if (response.statusCode() >= 400) {
throw new FetchFailException("HTTP " + response.statusCode(), response);
}
return response.headers()
.firstValueAsLong("Content-Length")
.orElse(-1L);
}
}