У нас есть VPN, который мы иногда используем для удаленного подключения к сайтам только для того, чтобы обнаружить, что tomcat, использующий фрагментированную кодировку, часто использует обрезанные файлы JavaScript.В попытке исправить это я хотел создать фильтр Tomcat для файлов JS, который отправляет их за один раз.
Прочитав статьи здесь и здесь IЯ попытался сделать это самостоятельно и попытался реализовать его следующим образом.
Я подключил фильтр к своему контексту с помощью пользовательской карты фильтров
new CustomFilterMap(
new String[]{"*.js"},
new String[]{"REQUEST"}
)
Эта часть на самом деле работала хорошо имой фильтр, кажется, применяется к файлам JS.Теперь часть, которую я не так хорошо работал, - это действительный фильтр.
public class NoChunkEncodedJSFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
val unversionedServletPath = request.getRequestURI().substring(request.getRequestURI().indexOf("/js"));
val requestFilePath = getServletContext().getRealPath(unversionedServletPath);
if (requestFilePath != null) {
File requestedFile = new File(requestFilePath);
if (requestedFile.exists()) {
val fileSize = Math.toIntExact(requestedFile.length());
val out = response.getWriter();
val wrappedResponse = new NonEncodedResponse(response, fileSize);
filterChain.doFilter(request, wrappedResponse);
out.write(wrappedResponse.toString(), "UTF-8");
out.close();
return;
}
}
filterChain.doFilter(request, response);
}
}
С моим NonEncodedResponse:
public class NonEncodedResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream baos;
public String toString() {
try {
return baos.toString("UTF-8");
} catch (UnsupportedEncodingException unsuportedEncodingException) {
return baos.toString();
}
}
/**
* Constructs a response adaptor wrapping the given response.
*
* @param response The response to be wrapped
* @throws IllegalArgumentException if the response is null
*/
public NonEncodedResponse(HttpServletResponse response, Integer fileSize) {
super(response);
this.setContentLength(fileSize);
this.setBufferSize(fileSize);
super.setContentLength(fileSize);
super.setBufferSize(fileSize);
baos = new ByteArrayOutputStream(fileSize);
}
@Override
public PrintWriter getWriter(){
return new PrintWriter(baos);
}
}
Итак, изначально я пытался вообще не оборачивать ответ ипросто вызывал response.setBufferSize(fileSize);
и response.setContentLength(fileSize);
, но это, казалось, имело 0 фактических эффектов на мой вывод, и когда я смотрел на заголовки, я все еще использовал кодирование передачи по частям без фиксированной длины содержимого.(Я также попытался установить собственный заголовок, подобный этому, и не увидел, чтобы он добавлялся к моему ответу. Я предполагаю, что ответ, который входит в фильтр в его базовой форме, является какой-то формой только для чтения.)
Я также попытался использовать свою оболочку и обойти ее выходной поток, читая и отправляя байты прямо из файла
val fileContents = Files.readAllBytes(Paths.get(requestFilePath));
out.write(new String(fileContents));
, потому что казалось, что, хотя мои попытки исправить длину содержимого потерпели неудачу, я все еще быля вижу только части файлов, которые отправляются как целое во вкладке сети моего браузера при попытке отладки.
В общем, теперь у меня есть такие файлы (возможно, не идеальные), и даже в идеале он по-прежнему говорит Transfer-Encoding: chunked
, несмотря на все мои усилия по установке фиксированной длины содержимого на мою оболочку и первоначальный ответ.Теперь я могу поместить свой заголовок в свой контент, чтобы знать, что он проходит через мой фильтр.Кажется, по какой-то причине он все еще просто закодирован.
Может кто-нибудь сказать мне, что я делаю неправильно, или, если для начала можно использовать фильтры, чтобы отключить чанкованное кодирование (я думаю, что я видел вещи, предполагающие, что они могут из поисков Google, но правда в том, что я простоне знаю)Я с радостью приветствую любые советы по этому вопросу, у меня больше нет идей, чтобы попробовать, и я, конечно, не знаю, что я делаю.