Search code examples
tomcatopenlayersgeoserver

WFS-T xmlhttp post length limits?


After a long time searching and trying I'm asking now for help:

My situation:

  • I've a jquery/openlayers-app which allows the user to create simple geoemtries with attributes over WFS-T...
  • I'm running on debian6 with tomcat6(:80-iptables) and geoserver 2.1.3(jetty:8181). All cross domain issues between tomcat and geoserver are solved with a simple jsp-proxy
  • The users can view all my wfs-layers without any problem and are able do create simple geometries

My problem:

  • Users creating more complex geometries are not able to save it over wfs-t. More complex means that the resulting XML-POST content length exceeds approx. 2100 characters. POST's with e.g. 2000 characters are inserted successfully.
  • I've digged into the tomcat-server settings and disabled all limits (maxHTTPHeaderSize,maxSavePostSize,...) and also elevated the maxpostsize in the geoserver-jetty webserver --> NO EFFECT
  • Following the response error message when a user creates more complex geometries:

org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0x0) was found in the element content of the document. An invalid XML character (Unicode: 0x0) was found in the element content of the document.


  • I've no idea why my XML POST request is causing an Unicode-error everytime i add one more vertex to a geometry which i successfully inserted before.
  • my request and response code:

successful POST request

successful response

successful POST request headers

not successful POST request

not successful response

not successful POST request headers

my jsp-proxy

I'm very happy for any hint how to solve my problem!

Thanks in advance,

Cheers Hubert


Solution

  • Better late than never :) Code below works for large geometries (at least for me)

    Oh YEAH this is code for simple jsp proxy

    <%@page session="false"%>
    <%@page import="java.net.*,java.io.*" %>
    <%@page trimDirectiveWhitespaces="true"%> 
    <%
    
    /**
     * This is a white list proxy that could be used the prevent an error due to 
     * JavaScript Same Origin Policy.
     * 
     * CAUTION: It might break some sites and it's a security risk because
     * people can use this proxy to browse the web and possibly do bad and/or illegal stuff
     * with it. 
     * It can load any content type.
     * This proxy implementation was inspired by the proxy.cgi script of OpenLayers
     * {@link http://openlayers.org}
     * To use this in OpenLayers you have to set OpenLayers.ProxyHost = "Url/To/This/Proxyfile/proxy.jsp?";
     * within your JavaScript code <br>
     * The base code of the proxy has been provided by SNIPPLR
     * {@link http://snipplr.com/view/17987/jsp-proxy-for-javascript-applications/}
     * 
     * @author terrestris GmbH & Co. KG
     * @author Christian Mayer
     * @author Marc Jansen
     * 
     * @license BSD see license.txt
     * 
     */
    String[] allowedHosts = {
        "www.openlayers.org", "openlayers.org", 
        "labs.metacarta.com", "world.freemap.in", 
        "prototype.openmnnd.org", "geo.openplans.org",
        "sigma.openplans.org", "demo.opengeo.org",
        "www.openstreetmap.org", "sample.azavea.com",
        "v-swe.uni-muenster.de:8080", 
        "vmap0.tiles.osgeo.org",
        "192.168.197.95:8080"
    };
    HttpURLConnection con = null;
    try {
        String reqUrl = request.getQueryString();
        String decodedUrl = "";
        if (reqUrl != null) {
            reqUrl = URLDecoder.decode(reqUrl, "UTF-8");
        }
        else {
            response.setStatus(400);
            out.println("ERROR 400: No target specified for proxy.");
        }
    
        // extract the host
        String host = "";
        host = reqUrl.split("\\/")[2];
        boolean allowed = false;
    
        // check if host (with port) is in white list
        for (String surl : allowedHosts) {
            if (host.equalsIgnoreCase(surl)) {
                allowed = true;
                break;
            }
        }
    
        // do the proxy action (load requested ressource and transport it to client)
        // if host is in white list
        if(allowed) {
            // replace the white spaces with plus in URL
            reqUrl = reqUrl.replaceAll(" ", "+"); 
    
            // call the requested ressource     
            URL url = new URL(reqUrl);
            con = (HttpURLConnection)url.openConnection();
            con.setDoOutput(true);
            con.setRequestMethod(request.getMethod());
            String reqContenType = request.getContentType();
            if(reqContenType != null) {
                con.setRequestProperty("Content-Type", reqContenType);
            }
            else {
                con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            }
    
            int clength = request.getContentLength();
            if(clength > 0) {
                /* NOT WORKING FOR LARGE POST BODY
                con.setDoInput(true);
                byte[] idata = new byte[clength];
                request.getInputStream().read(idata, 0, clength);
                con.getOutputStream().write(idata, 0, clength); 
                */
                con.setDoInput(true);
                InputStream istream = request.getInputStream();
                OutputStream os = con.getOutputStream();
                final int length = 5000;
                byte[] bytes = new byte[length];
                int bytesRead = 0;
                while ((bytesRead = istream.read(bytes, 0, length)) > 0) {
                    os.write(bytes, 0, bytesRead);
                }
            }
    
            // respond to client
            response.setContentType(con.getContentType());
    
            BufferedReader rd = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line;
            int i = 0;
            while ((line = rd.readLine()) != null) {
                out.println(line);  
            }
            rd.close();
        }
        else {
            // deny access via HTTP status code 502
            response.setStatus(502);
            out.println("ERROR 502: This proxy does not allow you to access that location.");
        }
    
    } catch(Exception e) {
    
        // resond an internal server error with the stacktrace
        // on exception
        response.setStatus(500);
        byte[] idata = new byte[5000];
    
        if(con.getErrorStream() != null) {
            con.getErrorStream().read(idata, 0, 5000);
        }
    
        out.println("ERROR 500: An internal server error occured. " + e.getMessage() + " " + new String(idata));    
    }
    %>