eXist-db / exist

eXist Native XML Database and Application Platform
https://exist-db.org
GNU Lesser General Public License v2.1
430 stars 180 forks source link

RESTXQ chokes on default Accept header of JDK HttpURLConnection #1698

Open adamretter opened 6 years ago

adamretter commented 6 years ago

The real issue is this: https://bugs.openjdk.java.net/browse/JDK-8163921

The RESTXQ end-point:

declare
    %rest:GET
    %rest:path("/{$api:repo}/api/geo/json")
    %rest:query-param("type", "{$type}", "")
    %rest:query-param("output", "{$output}", "json")
    %output:media-type("application/json")
    %output:method("json")
function api:get-geo-json($api:repo as xs:string?, $type as xs:string*, $output as xs:string*) {
(<rest:response> 
  <http:response status="200"> 
    <http:header name="Content-Type" value="application/json; charset=utf-8"/>
    <http:header name="Access-Control-Allow-Origin" value="application/json; charset=utf-8"/>
  </http:response> 
</rest:response>, 
     api:get-geojson-node($type,$output)
) 
};

The Java client code:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

import static java.nio.charset.StandardCharsets.UTF_8;

public class JdkReaderExample {

    private static String readAll(final Reader reader) throws IOException {
        final StringBuilder sb = new StringBuilder();
        final char[] buf = new char[64 * 1024]; // 64 KB

        int read;
        while ((read = reader.read(buf)) != -1) {
            sb.append(buf, 0, read);
        }

        return sb.toString();
    }

    public static String readJsonFromUrl(String url) throws IOException {
        final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();

        //connection.setRequestProperty("Accept", "application/json");
        connection.setDoInput(true);

        // make the request
        final int httpResponseCode = connection.getResponseCode();
        if (httpResponseCode == HttpURLConnection.HTTP_OK) {

            // all good

            try (final Reader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), UTF_8))) {
                final String jsonText = readAll(reader);
                return jsonText;
            }

        } else {
            // an error occurred
            System.err.println("Failed with HTTP Code: " + httpResponseCode);
            System.err.println(connection.getResponseMessage());
            try (final Reader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), UTF_8))) {
                final String errorBody = readAll(reader);
                System.err.println(errorBody);
            }
            return null;
        }
    }

    public static void main(final String[] args) throws IOException {
        final String json = readJsonFromUrl("http://syriaca.org/api/geo/json?type=church");
        if (json != null) {
            System.out.println(json.toString());
        }
    }

}

The resultant error:

HTTP/1.1 500 Server Error
Date: Wed, 17 Jan 2018 15:21:02 GMT
Server: Jetty(9.3.9.v20160517)
Content-Type: text/html;charset=iso-8859-1
Cache-Control: must-revalidate,no-cache,no-store
Content-Length: 10730
Set-Cookie: JSESSIONID=1i6o5rx2k7vgz10d5bfzzn86ud;Path=/exist
Connection: close

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 500 Server Error</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /exist/apps/srophe/api/geo/json. Reason:
<pre>    Server Error</pre></p><h3>Caused by:</h3><pre>javax.servlet.ServletException: An error occurred while processing request to /exist/apps/srophe/api/geo/json: Invalid Accept Header Value: &apos;text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2&apos; in respect to pattern: &apos;((?:(?:\*\/\*)|(?:[a-z0-9!#\$&amp;\.\+\-\^_]{1,127}\/\*)|(?:[a-z0-9!#\$&amp;\.\+\-\^_]{1,127}\/[a-z0-9!#\$&amp;\.\+\-\^_]{1,127}))(?:;\s?q=(?:0(?:\.[0-9]{1,3})?)|(?:1(?:\.[0]{1,3})?))?\s?(?:;\s?[a-z]+=[a-z]+|(?:&quot;[a-z0-9]+&quot;))?)(,\s?(?:(?:\*\/\*)|(?:[a-z0-9!#\$&amp;\.\+\-\^_]{1,127}\/\*)|(?:[a-z0-9!#\$&amp;\.\+\-\^_]{1,127}\/[a-z0-9!#\$&amp;\.\+\-\^_]{1,127}))(?:;\s?q=(?:0(?:\.[0-9]{1,3})?)|(?:1(?:\.[0]{1,3})?))?\s?(?:;\s?[a-z]+=[a-z]+|(?:&quot;[a-z0-9]+&quot;))?)*&apos;
.at org.exist.http.urlrewrite.XQueryURLRewrite.service(XQueryURLRewrite.java:378)
PietroLiuzzo commented 5 years ago

I am experiencing the same issue, getting the same error. only from some Chrome instances and only for requests sent to RESTXQ modules

https://betamasaheft.eu/manuscripts/BNFet45/main

is there any workaround?

PietroLiuzzo commented 5 years ago

sorry, I have managed to fix this (?) adding in nginx.conf proxy_set_header Accept '*/*' ;