plantuml / plantuml-server

PlantUML Online Server
https://plantuml.com/
GNU General Public License v3.0
1.59k stars 463 forks source link

CORS issues - Solution proposal #315

Open spassignat opened 9 months ago

spassignat commented 9 months ago

Is your feature request related to a problem? Please describe. Actually when using plantuml as a service server to convert plantuml to image, several kind of CORS error are raised.

Describe the solution you'd like We should be able to setup CORS during the deployment wihtout rebuilding entirely the application, or modifying the deployment directory content.

Proposal I only consider a deployment in tomcat as a war file. It's really JEE so I can be transposed to jetty. I hope this helps. At least it works as I "like", but maybe not as everybody like.

How to setup CORS Use a .xml file in the conf/Catalina/localhost add variables to the JNDI which is accessible from Servlets.

<Context>
    <Environment type="java.lang.String" name="Access-Control-Allow-Origin" value="http://localhost:5173" />
    <Environment type="java.lang.String" name="Access-Control-Allow-Headers" value="Authorization" />
    <Environment type="java.lang.String" name="Access-Control-Allow-Methods" value="PUT, HEAD, POST, GET, DELETE, OPTIONS" />
    <Environment type="java.lang.String" name="Access-Control-Allow-Credentials" value="true" />
</Context>

Where to implement

  1. I would add a Filter in the web.xml, before all other servlets.
    <filter>
        <filter-name>Cors</filter-name>
        <filter-class>net.sourceforge.plantuml.servlet.CorsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Cors</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
  2. Implements the filter

In the following code the default values need to be changed to match the desired default behaviour.

    protected void doFilter(HttpServletRequest req, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletContext context = getServletContext();
        String origin = context.getInitParameter("Access-Control-Allow-Origin");
        response.setHeader("Access-Control-Allow-Origin", origin != null ? origin : "http://localhost:5173");
        String headers = context.getInitParameter("Access-Control-Allow-Headers");
        response.setHeader("Access-Control-Allow-Headers", headers != null ? headers : "Authorization");
        String cred = context.getInitParameter("Access-Control-Allow-Credentials");
        response.setHeader("Access-Control-Allow-Credentials", cred != null ? cred : "true");
        String methods = context.getInitParameter("Access-Control-Allow-Methods");
        response.setHeader("Access-Control-Allow-Methods", methods!=null?methods:"PUT, HEAD, POST, GET, DELETE, OPTIONS");
        super.doFilter(req, response, chain);
    }
  1. Remove old code Remove all previous code in DiagramResponse and servlets : response.addHeader("Access-Control-Allow-Origin", "*");
  2. Add doOptions methods in servlets It does nothing but Parent servlet do introspection to know which methods are implemented and add them in the header.
    protected void doOptions(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
        super.doOptions(req, response);
    }