Search in sources :

Example 6 with XmlDocumentFetchException

use of org.opendatakit.briefcase.model.XmlDocumentFetchException in project briefcase by opendatakit.

the class AggregateUtils method httpRetrieveXmlDocument.

/**
 * Common method for returning a parsed xml document given a url and the http
 * context and client objects involved in the web connection. The document is
 * the body of the response entity and should be xml.
 *
 * @return
 */
private static final DocumentFetchResult httpRetrieveXmlDocument(HttpUriRequest request, int[] validStatusList, ServerConnectionInfo serverInfo, boolean alwaysResetCredentials, DocumentDescription description, ResponseAction action) throws XmlDocumentFetchException {
    HttpClient httpClient = WebUtils.createHttpClient();
    // get shared HttpContext so that authentication and cookies are retained.
    HttpClientContext localContext = WebUtils.getHttpContext();
    URI uri = request.getURI();
    log.info("Attempting URI {}", uri);
    WebUtils.setCredentials(localContext, serverInfo, uri, alwaysResetCredentials);
    if (description.isCancelled()) {
        throw new XmlDocumentFetchException("Transfer of " + description.getDocumentDescriptionType() + " aborted.");
    }
    HttpResponse response = null;
    try {
        response = httpClient.execute(request, localContext);
        int statusCode = response.getStatusLine().getStatusCode();
        HttpEntity entity = response.getEntity();
        String lcContentType = (entity == null) ? null : entity.getContentType().getValue().toLowerCase();
        XmlDocumentFetchException ex = null;
        boolean statusCodeValid = false;
        for (int i : validStatusList) {
            if (i == statusCode) {
                statusCodeValid = true;
                break;
            }
        }
        if (!statusCodeValid) {
            String webError = response.getStatusLine().getReasonPhrase() + " (" + statusCode + ")";
            if (statusCode == 401) {
                // We reset the Http context to force next request to authenticate itself
                WebUtils.resetHttpContext();
                ex = new XmlDocumentFetchException("Authentication failure");
            } else if (statusCode == 400) {
                ex = new XmlDocumentFetchException(description.getFetchDocFailed() + webError + " while accessing: " + uri.toString() + "\nPlease verify that the " + description.getDocumentDescriptionType() + " that is being uploaded is well-formed.");
            } else {
                ex = new XmlDocumentFetchException(description.getFetchDocFailed() + webError + " while accessing: " + uri.toString() + "\nPlease verify that the URL, your user credentials and your permissions are all correct.");
            }
        } else if (entity == null) {
            log.warn("No entity body returned");
            ex = new XmlDocumentFetchException(description.getFetchDocFailed() + " Server unexpectedly returned no content");
        } else if (!(lcContentType.contains(HTTP_CONTENT_TYPE_TEXT_XML) || lcContentType.contains(HTTP_CONTENT_TYPE_APPLICATION_XML))) {
            log.warn("Wrong ContentType: " + entity.getContentType().getValue() + "returned");
            ex = new XmlDocumentFetchException(description.getFetchDocFailed() + "A non-XML document was returned. A network login screen may be interfering with the transmission to the server.");
        }
        if (ex != null) {
            flushEntityBytes(entity);
            // and throw the exception...
            throw ex;
        }
        // parse the xml document...
        Document doc = null;
        try {
            InputStream is = null;
            InputStreamReader isr = null;
            try {
                is = entity.getContent();
                isr = new InputStreamReader(is, "UTF-8");
                doc = new Document();
                KXmlParser parser = new KXmlParser();
                parser.setInput(isr);
                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                doc.parse(parser);
                isr.close();
            } finally {
                if (isr != null) {
                    try {
                        isr.close();
                    } catch (Exception e) {
                    // no-op
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (Exception e) {
                    // no-op
                    }
                }
            }
        } catch (Exception e) {
            log.warn("Parsing failed with " + e.getMessage(), e);
            throw new XmlDocumentFetchException(description.getFetchDocFailed());
        }
        // examine header fields...
        // is it an OpenRosa server?
        boolean isOR = false;
        Header[] fields = response.getHeaders(WebUtils.OPEN_ROSA_VERSION_HEADER);
        if (fields != null && fields.length >= 1) {
            isOR = true;
            boolean versionMatch = false;
            boolean first = true;
            StringBuilder b = new StringBuilder();
            for (Header h : fields) {
                if (WebUtils.OPEN_ROSA_VERSION.equals(h.getValue())) {
                    versionMatch = true;
                    break;
                }
                if (!first) {
                    b.append("; ");
                }
                first = false;
                b.append(h.getValue());
            }
            if (!versionMatch) {
                log.warn(WebUtils.OPEN_ROSA_VERSION_HEADER + " unrecognized version(s): " + b);
            }
        }
        // what about location?
        Header[] locations = response.getHeaders("Location");
        if (locations != null && locations.length == 1) {
            try {
                URL url = new URL(locations[0].getValue());
                URI uNew = url.toURI();
                log.info("Redirection to URI {}", uNew);
                if (uri.getHost().equalsIgnoreCase(uNew.getHost())) {
                    // trust the server to tell us a new location
                    // ... and possibly to use https instead.
                    String fullUrl = url.toExternalForm();
                    int idx = fullUrl.lastIndexOf("/");
                    serverInfo.setUrl(fullUrl.substring(0, idx));
                } else {
                    // Don't follow a redirection attempt to a different host.
                    // We can't tell if this is a spoof or not.
                    String msg = description.getFetchDocFailed() + "Unexpected redirection attempt";
                    log.warn(msg);
                    throw new XmlDocumentFetchException(msg);
                }
            } catch (MalformedURLException | URISyntaxException e) {
                String msg = description.getFetchDocFailed() + "Unexpected exception: " + e.getMessage();
                log.warn(msg, e);
                throw new XmlDocumentFetchException(msg);
            }
        }
        DocumentFetchResult result = new DocumentFetchResult(doc, isOR);
        if (action != null) {
            action.doAction(result);
        }
        return result;
    } catch (UnknownHostException e) {
        String msg = description.getFetchDocFailed() + "Unknown host";
        log.warn(msg, e);
        throw new XmlDocumentFetchException(msg);
    } catch (IOException | MetadataUpdateException e) {
        String msg = description.getFetchDocFailed() + "Unexpected exception: " + e;
        log.warn(msg, e);
        throw new XmlDocumentFetchException(msg);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) HttpEntity(org.apache.http.HttpEntity) URISyntaxException(java.net.URISyntaxException) Document(org.kxml2.kdom.Document) URI(java.net.URI) URL(java.net.URL) XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) KXmlParser(org.kxml2.io.KXmlParser) InputStreamReader(java.io.InputStreamReader) UnknownHostException(java.net.UnknownHostException) InputStream(java.io.InputStream) HttpResponse(org.apache.http.HttpResponse) MetadataUpdateException(org.opendatakit.briefcase.model.MetadataUpdateException) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) IOException(java.io.IOException) ClientProtocolException(org.apache.http.client.ClientProtocolException) URISyntaxException(java.net.URISyntaxException) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) MalformedURLException(java.net.MalformedURLException) XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) IOException(java.io.IOException) MetadataUpdateException(org.opendatakit.briefcase.model.MetadataUpdateException) UnknownHostException(java.net.UnknownHostException) Header(org.apache.http.Header) HttpClient(org.apache.http.client.HttpClient)

Aggregations

XmlDocumentFetchException (org.opendatakit.briefcase.model.XmlDocumentFetchException)6 URISyntaxException (java.net.URISyntaxException)4 FormStatusEvent (org.opendatakit.briefcase.model.FormStatusEvent)4 File (java.io.File)3 IOException (java.io.IOException)3 MalformedURLException (java.net.MalformedURLException)3 DocumentDescription (org.opendatakit.briefcase.model.DocumentDescription)3 ParsingException (org.opendatakit.briefcase.model.ParsingException)3 TransmissionException (org.opendatakit.briefcase.model.TransmissionException)3 URI (java.net.URI)2 URL (java.net.URL)2 UnknownHostException (java.net.UnknownHostException)2 HashMap (java.util.HashMap)2 ClientProtocolException (org.apache.http.client.ClientProtocolException)2 MetadataUpdateException (org.opendatakit.briefcase.model.MetadataUpdateException)2 FileOutputStream (java.io.FileOutputStream)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 OutputStreamWriter (java.io.OutputStreamWriter)1 SocketTimeoutException (java.net.SocketTimeoutException)1