服务器端自定义 headers,带有嵌入式码头和球衣

Server side custom headers with embedded jetty and jersey

我们有一个遗留应用程序,它使用嵌入式 Jetty 并通过客户端进行 HTTP 调用来提供功能。服务器所需的大部分 information/parameters 是由客户端通过 HTTP headers 发送的。我们现在正在使用 Jersey 对 REST API 调用的使用进行原型设计,其中提供与 JSON 输入相同的参数。要求之一是保持向后兼容性并且不干扰现有功能。

虽然我们能够使用 Jersey 并传入参数,但我们正在寻求以下方面的帮助:

Request base_request = request instanceof Request ? (Request)request : HttpConnection.getCurrentConnection().getHttpChannel().getRequest();
Response base_response = response instanceof Response ? (Response)response : HttpConnection.getCurrentConnection().getHttpChannel().getResponse();

这实际上没有使用我发送的 HttpServletRequestWrapper object。由于这行代码查找 org.eclipse.jetty.server.Request object,我尝试围绕此 [= 创建一个包装器56=],就像这样,但这没有用,因为这个实例似乎有大部分内容为 null,而且它不会提供 Request object 将提供的其余方法。

class MyRequestWrapper extends Request
{
   public MyRequestWrapper(HttpServletRequest request)
   {
      super( ((Request)request).getHttpChannel(), ((Request)request).getHttpInput());
   }

   @Override
   public String getHeader(String name)
   {
      if(name.equalsIgnoreCase("X-My-Test"))
      {
         return "MyName";
      }
      return super.getHeader(name);
   }
}

将 JSON 输入作为 headers 从 REST 处理方法发送到现有 Jetty 处理程序的最佳方法是什么,而不产生安全问题?我想我可以稍微调整一下对基本请求的检查,但我不确定最好的方法。

包装请求仅对创建包装请求的同一 ServletContextFilter 链有效,并且仅适用于从创建时开始执行的过滤器链的其余部分已创建。

包装请求永远不会应用于标准 Jetty Handler,因为它不参与 ServletContextFilter 链。

由于 context-less 在其中执行的环境的需要,也不可能包装核心 Jetty Request object。您无法更改此行为。

如果您正在包装请求和诸如此类的东西,而不仅仅是为了提供自定义请求 header,请停止执行您现在正在处理的 ALL 包装和废话。

Note: The minute you stop wrapping HttpServletRequest, HttpServletResponse, or the Servlet streams is the minute you will have the ability to use features introduced for Servlet 3.0 and newer, such as AsyncContext and Async I/O. The technique of wrapping these components is discouraged in modern usage because it limits your options for better performing webapps.

你有2个选择,都修改Request headers in-place.

  1. 在发送前 header 秒修改请求。
  2. 在调度期间通过低级别 Jetty 处理程序修改请求 headers。

如果您选择在发送前修改 headers,您可以在 2 个地方执行此操作。

  1. 作为 HttpConfiguration.Customizer
  2. 在 pre-dispatch HttpChannel.Listener 事件之一期间

如果您选择在调度期间修改 headers,则创建一个修改 Request headers 的 Jetty Handler,并将其放在早期的某个位置您的服务器处理程序层次结构。

修改Request header的代码都会做同样的事情,这里以Handler版本为例。

package jetty.demo;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerWrapper;

public class ModifyRequestHeadersHandler extends AbstractHandler
{
    @Override
    public void handle(String target, Request baseRequest, 
        HttpServletRequest request, HttpServletResponse response) 
        throws IOException, ServletException
    {
        // As fully fleshed out field
        final HttpField X_MY_TEST = new HttpField("X-My-Test", "MyName");
        baseRequest.getHttpFields().put(X_MY_TEST);

        // As predefined header and custom value
        baseRequest.getHttpFields().put(HttpHeader.X_POWERED_BY,
            "ModifiedRequestHeadersHandler");

        // As string header and string value
        baseRequest.getHttpFields().put("X-Foo-Test", "MyFooName");
    }
}