Search in sources :

Example 1 with HttpEntity

use of org.opendatakit.httpclientandroidlib.HttpEntity in project collect by opendatakit.

the class WebUtils method getXmlDocument.

/**
 * Common method for returning a parsed xml document given a url and the
 * http context and client objects involved in the web connection.
 */
public static DocumentFetchResult getXmlDocument(String urlString, HttpContext localContext, HttpClient httpclient) {
    URI u;
    try {
        URL url = new URL(urlString);
        u = url.toURI();
    } catch (URISyntaxException | MalformedURLException e) {
        Timber.i(e, "Error converting URL %s to uri", urlString);
        return new DocumentFetchResult(e.getLocalizedMessage() + // + app.getString(R.string.while_accessing) + urlString);
        ("while accessing") + urlString, 0);
    }
    if (u.getHost() == null) {
        return new DocumentFetchResult("Invalid server URL (no hostname): " + urlString, 0);
    }
    // if https then enable preemptive basic auth...
    if (u.getScheme().equals("https")) {
        enablePreemptiveBasicAuth(localContext, u.getHost());
    }
    // set up request...
    HttpGet req = WebUtils.createOpenRosaHttpGet(u);
    req.addHeader(WebUtils.ACCEPT_ENCODING_HEADER, WebUtils.GZIP_CONTENT_ENCODING);
    HttpResponse response;
    try {
        response = httpclient.execute(req, localContext);
        int statusCode = response.getStatusLine().getStatusCode();
        HttpEntity entity = response.getEntity();
        if (statusCode != HttpStatus.SC_OK) {
            WebUtils.discardEntityBytes(response);
            if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
                // clear the cookies -- should not be necessary?
                Collect.getInstance().getCookieStore().clear();
            }
            String webError = response.getStatusLine().getReasonPhrase() + " (" + statusCode + ")";
            return new DocumentFetchResult(u.toString() + " responded with: " + webError, statusCode);
        }
        if (entity == null) {
            String error = "No entity body returned from: " + u.toString();
            Timber.e(error);
            return new DocumentFetchResult(error, 0);
        }
        if (!entity.getContentType().getValue().toLowerCase(Locale.ENGLISH).contains(WebUtils.HTTP_CONTENT_TYPE_TEXT_XML)) {
            WebUtils.discardEntityBytes(response);
            String error = "ContentType: " + entity.getContentType().getValue() + " returned from: " + u.toString() + " is not text/xml.  This is often caused a network proxy.  Do you need " + "to login to your network?";
            Timber.e(error);
            return new DocumentFetchResult(error, 0);
        }
        // parse response
        Document doc = null;
        try {
            InputStream is = null;
            InputStreamReader isr = null;
            try {
                is = entity.getContent();
                Header contentEncoding = entity.getContentEncoding();
                if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase(WebUtils.GZIP_CONTENT_ENCODING)) {
                    is = new GZIPInputStream(is);
                }
                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();
                isr = null;
            } finally {
                if (isr != null) {
                    try {
                        // ensure stream is consumed...
                        final long count = 1024L;
                        while (isr.skip(count) == count) {
                        // skipping to the end of the http entity
                        }
                    } catch (Exception e) {
                        // no-op
                        Timber.e(e);
                    }
                    try {
                        isr.close();
                    } catch (IOException e) {
                        // no-op
                        Timber.e(e, "Error closing input stream reader");
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        Timber.e(e, "Error closing inputstream");
                    // no-op
                    }
                }
            }
        } catch (Exception e) {
            String error = "Parsing failed with " + e.getMessage() + "while accessing " + u.toString();
            Timber.e(error);
            return new DocumentFetchResult(error, 0);
        }
        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) {
                Timber.w("%s unrecognized version(s): %s", WebUtils.OPEN_ROSA_VERSION_HEADER, b.toString());
            }
        }
        return new DocumentFetchResult(doc, isOR);
    } catch (Exception e) {
        String cause;
        Throwable c = e;
        while (c.getCause() != null) {
            c = c.getCause();
        }
        cause = c.toString();
        String error = "Error: " + cause + " while accessing " + u.toString();
        Timber.w(error);
        return new DocumentFetchResult(error, 0);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) HttpEntity(org.opendatakit.httpclientandroidlib.HttpEntity) InputStreamReader(java.io.InputStreamReader) GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) HttpGet(org.opendatakit.httpclientandroidlib.client.methods.HttpGet) HttpResponse(org.opendatakit.httpclientandroidlib.HttpResponse) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) Document(org.kxml2.kdom.Document) URI(java.net.URI) URL(java.net.URL) URISyntaxException(java.net.URISyntaxException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) GZIPInputStream(java.util.zip.GZIPInputStream) KXmlParser(org.kxml2.io.KXmlParser) Header(org.opendatakit.httpclientandroidlib.Header)

Example 2 with HttpEntity

use of org.opendatakit.httpclientandroidlib.HttpEntity in project collect by opendatakit.

the class DownloadFormsTask method downloadFile.

/**
 * Common routine to download a document from the downloadUrl and save the contents in the file
 * 'file'. Shared by media file download and form file download.
 * <p>
 * SurveyCTO: The file is saved into a temp folder and is moved to the final place if everything
 * is okay, so that garbage is not left over on cancel.
 *
 * @param file        the final file
 * @param downloadUrl the url to get the contents from.
 */
private void downloadFile(File file, String downloadUrl) throws IOException, TaskCancelledException, URISyntaxException, Exception {
    File tempFile = File.createTempFile(file.getName(), TEMP_DOWNLOAD_EXTENSION, new File(Collect.CACHE_PATH));
    URI uri;
    try {
        // assume the downloadUrl is escaped properly
        URL url = new URL(downloadUrl);
        uri = url.toURI();
    } catch (MalformedURLException | URISyntaxException e) {
        Timber.e(e, "Unable to get a URI for download URL : %s  due to %s : ", downloadUrl, e.getMessage());
        throw e;
    }
    // WiFi network connections can be renegotiated during a large form download sequence.
    // This will cause intermittent download failures.  Silently retry once after each
    // failure.  Only if there are two consecutive failures do we abort.
    boolean success = false;
    int attemptCount = 0;
    final int MAX_ATTEMPT_COUNT = 2;
    while (!success && ++attemptCount <= MAX_ATTEMPT_COUNT) {
        if (isCancelled()) {
            throw new TaskCancelledException(tempFile);
        }
        Timber.i("Started downloading to %s from %s", tempFile.getAbsolutePath(), downloadUrl);
        // get shared HttpContext so that authentication and cookies are retained.
        HttpContext localContext = Collect.getInstance().getHttpContext();
        HttpClient httpclient = WebUtils.createHttpClient(WebUtils.CONNECTION_TIMEOUT);
        // set up request...
        HttpGet req = WebUtils.createOpenRosaHttpGet(uri);
        req.addHeader(WebUtils.ACCEPT_ENCODING_HEADER, WebUtils.GZIP_CONTENT_ENCODING);
        HttpResponse response;
        try {
            response = httpclient.execute(req, localContext);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                WebUtils.discardEntityBytes(response);
                if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
                    // clear the cookies -- should not be necessary?
                    Collect.getInstance().getCookieStore().clear();
                }
                String errMsg = Collect.getInstance().getString(R.string.file_fetch_failed, downloadUrl, response.getStatusLine().getReasonPhrase(), String.valueOf(statusCode));
                Timber.e(errMsg);
                throw new Exception(errMsg);
            }
            // write connection to file
            InputStream is = null;
            OutputStream os = null;
            try {
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
                Header contentEncoding = entity.getContentEncoding();
                if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase(WebUtils.GZIP_CONTENT_ENCODING)) {
                    is = new GZIPInputStream(is);
                }
                os = new FileOutputStream(tempFile);
                byte[] buf = new byte[4096];
                int len;
                while ((len = is.read(buf)) > 0 && !isCancelled()) {
                    os.write(buf, 0, len);
                }
                os.flush();
                success = true;
            } finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (Exception e) {
                        Timber.e(e);
                    }
                }
                if (is != null) {
                    try {
                        // ensure stream is consumed...
                        final long count = 1024L;
                        while (is.skip(count) == count) {
                        // skipping to the end of the http entity
                        }
                    } catch (Exception e) {
                    // no-op
                    }
                    try {
                        is.close();
                    } catch (Exception e) {
                        Timber.e(e);
                    }
                }
            }
        } catch (Exception e) {
            Timber.e(e.toString());
            // silently retry unless this is the last attempt,
            // in which case we rethrow the exception.
            FileUtils.deleteAndReport(tempFile);
            if (attemptCount == MAX_ATTEMPT_COUNT) {
                throw e;
            }
        }
        if (isCancelled()) {
            FileUtils.deleteAndReport(tempFile);
            throw new TaskCancelledException(tempFile);
        }
    }
    Timber.d("Completed downloading of %s. It will be moved to the proper path...", tempFile.getAbsolutePath());
    FileUtils.deleteAndReport(file);
    String errorMessage = FileUtils.copyFile(tempFile, file);
    if (file.exists()) {
        Timber.w("Copied %s over %s", tempFile.getAbsolutePath(), file.getAbsolutePath());
        FileUtils.deleteAndReport(tempFile);
    } else {
        String msg = Collect.getInstance().getString(R.string.fs_file_copy_error, tempFile.getAbsolutePath(), file.getAbsolutePath(), errorMessage);
        Timber.w(msg);
        throw new RuntimeException(msg);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) HttpEntity(org.opendatakit.httpclientandroidlib.HttpEntity) GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) HttpGet(org.opendatakit.httpclientandroidlib.client.methods.HttpGet) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) HttpContext(org.opendatakit.httpclientandroidlib.protocol.HttpContext) HttpResponse(org.opendatakit.httpclientandroidlib.HttpResponse) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) URL(java.net.URL) URISyntaxException(java.net.URISyntaxException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) GZIPInputStream(java.util.zip.GZIPInputStream) Header(org.opendatakit.httpclientandroidlib.Header) HttpClient(org.opendatakit.httpclientandroidlib.client.HttpClient) FileOutputStream(java.io.FileOutputStream) MediaFile(org.odk.collect.android.logic.MediaFile) File(java.io.File)

Example 3 with HttpEntity

use of org.opendatakit.httpclientandroidlib.HttpEntity in project collect by opendatakit.

the class InstanceServerUploader method uploadOneSubmission.

/**
 * Uploads to urlString the submission identified by id with filepath of instance
 *
 * @param urlString    destination URL
 * @param toUpdate     - Instance URL for recording status update.
 * @param localContext - context (e.g., credentials, cookies) for client connection
 * @param uriRemap     - mapping of Uris to avoid redirects on subsequent invocations
 * @return false if credentials are required and we should terminate immediately.
 */
private boolean uploadOneSubmission(String urlString, String id, String instanceFilePath, Uri toUpdate, HttpContext localContext, Map<Uri, Uri> uriRemap, Outcome outcome) {
    Collect.getInstance().getActivityLogger().logAction(this, urlString, instanceFilePath);
    File instanceFile = new File(instanceFilePath);
    ContentValues cv = new ContentValues();
    Uri submissionUri = Uri.parse(urlString);
    HttpClient httpclient = WebUtils.createHttpClient(CONNECTION_TIMEOUT);
    ResponseMessageParser messageParser = null;
    boolean openRosaServer = false;
    if (uriRemap.containsKey(submissionUri)) {
        // we already issued a head request and got a response,
        // so we know the proper URL to send the submission to
        // and the proper scheme. We also know that it was an
        // OpenRosa compliant server.
        openRosaServer = true;
        submissionUri = uriRemap.get(submissionUri);
        // if https then enable preemptive basic auth...
        if (submissionUri.getScheme().equals("https")) {
            WebUtils.enablePreemptiveBasicAuth(localContext, submissionUri.getHost());
        }
        Timber.i("Using Uri remap for submission %s. Now: %s", id, submissionUri.toString());
    } else {
        if (submissionUri.getHost() == null) {
            Timber.i("Host name may not be null");
            outcome.messagesByInstanceId.put(id, fail + "Host name may not be null");
            cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
            Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
            return true;
        }
        // if https then enable preemptive basic auth...
        if (submissionUri.getScheme() != null && submissionUri.getScheme().equals("https")) {
            WebUtils.enablePreemptiveBasicAuth(localContext, submissionUri.getHost());
        }
        URI uri;
        try {
            uri = URI.create(submissionUri.toString());
        } catch (IllegalArgumentException e) {
            Timber.i(e);
            outcome.messagesByInstanceId.put(id, Collect.getInstance().getString(R.string.url_error));
            return false;
        }
        // Issue a head request to confirm the server is an OpenRosa server and see if auth
        // is required
        // http://docs.opendatakit.org/openrosa-form-submission/#extended-transmission-considerations
        HttpHead httpHead = WebUtils.createOpenRosaHttpHead(uri);
        // prepare response
        final HttpResponse response;
        try {
            Timber.i("Issuing HEAD request for %s to: %s", id, submissionUri.toString());
            response = httpclient.execute(httpHead, localContext);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
                // clear the cookies -- should not be necessary?
                Collect.getInstance().getCookieStore().clear();
                WebUtils.discardEntityBytes(response);
                // we need authentication, so stop and return what we've
                // done so far.
                outcome.authRequestingServer = submissionUri;
                return false;
            } else if (statusCode == 204) {
                Header[] locations = response.getHeaders("Location");
                WebUtils.discardEntityBytes(response);
                if (locations != null && locations.length == 1) {
                    try {
                        Uri newURI = Uri.parse(URLDecoder.decode(locations[0].getValue(), "utf-8"));
                        if (submissionUri.getHost().equalsIgnoreCase(newURI.getHost())) {
                            openRosaServer = true;
                            // Re-add params if server didn't respond with params
                            if (newURI.getQuery() == null) {
                                newURI = newURI.buildUpon().encodedQuery(submissionUri.getEncodedQuery()).build();
                            }
                            uriRemap.put(submissionUri, newURI);
                            submissionUri = newURI;
                        } else {
                            // Don't follow a redirection attempt to a different host.
                            // We can't tell if this is a spoof or not.
                            outcome.messagesByInstanceId.put(id, fail + "Unexpected redirection attempt to a different " + "host: " + newURI.toString());
                            cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
                            Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
                            return true;
                        }
                    } catch (Exception e) {
                        Timber.e(e, "Exception thrown parsing URI for url %s", urlString);
                        outcome.messagesByInstanceId.put(id, fail + urlString + " " + e.toString());
                        cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
                        Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
                        return true;
                    }
                }
            } else {
                // may be a server that does not handle
                WebUtils.discardEntityBytes(response);
                Timber.w("Status code on Head request: %d", statusCode);
                if (statusCode >= HttpStatus.SC_OK && statusCode < HttpStatus.SC_MULTIPLE_CHOICES) {
                    outcome.messagesByInstanceId.put(id, fail + "Invalid status code on Head request.  If you have a " + "web proxy, you may need to login to your network. ");
                    cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
                    Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
                    return true;
                }
            }
        } catch (ClientProtocolException | ConnectTimeoutException | UnknownHostException | SocketTimeoutException | NoHttpResponseException | SocketException e) {
            if (e instanceof ClientProtocolException) {
                outcome.messagesByInstanceId.put(id, fail + "Client Protocol Exception");
                Timber.i(e, "Client Protocol Exception");
            } else if (e instanceof ConnectTimeoutException) {
                outcome.messagesByInstanceId.put(id, fail + "Connection Timeout");
                Timber.i(e, "Connection Timeout");
            } else if (e instanceof UnknownHostException) {
                outcome.messagesByInstanceId.put(id, fail + e.toString() + " :: Network Connection Failed");
                Timber.i(e, "Network Connection Failed");
            } else if (e instanceof SocketTimeoutException) {
                outcome.messagesByInstanceId.put(id, fail + "Connection Timeout");
                Timber.i(e, "Connection timeout");
            } else {
                outcome.messagesByInstanceId.put(id, fail + "Network Connection Refused");
                Timber.i(e, "Network Connection Refused");
            }
            cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
            Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
            return true;
        } catch (Exception e) {
            String msg = e.getMessage();
            if (msg == null) {
                msg = e.toString();
            }
            outcome.messagesByInstanceId.put(id, fail + "Generic Exception: " + msg);
            Timber.e(e);
            cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
            Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
            return true;
        }
    }
    // At this point, we may have updated the uri to use https.
    // This occurs only if the Location header keeps the host name
    // the same. If it specifies a different host name, we error
    // out.
    // 
    // And we may have set authentication cookies in our
    // cookiestore (referenced by localContext) that will enable
    // authenticated publication to the server.
    // 
    // get instance file
    // Under normal operations, we upload the instanceFile to
    // the server.  However, during the save, there is a failure
    // window that may mark the submission as complete but leave
    // the file-to-be-uploaded with the name "submission.xml" and
    // the plaintext submission files on disk.  In this case,
    // upload the submission.xml and all the files in the directory.
    // This means the plaintext files and the encrypted files
    // will be sent to the server and the server will have to
    // figure out what to do with them.
    File submissionFile = new File(instanceFile.getParentFile(), "submission.xml");
    if (submissionFile.exists()) {
        Timber.w("submission.xml will be uploaded instead of %s", instanceFile.getAbsolutePath());
    } else {
        submissionFile = instanceFile;
    }
    if (!instanceFile.exists() && !submissionFile.exists()) {
        outcome.messagesByInstanceId.put(id, fail + "instance XML file does not exist!");
        cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
        Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
        return true;
    }
    // find all files in parent directory
    File[] allFiles = instanceFile.getParentFile().listFiles();
    // add media files
    List<File> files = new ArrayList<File>();
    if (allFiles != null) {
        for (File f : allFiles) {
            String fileName = f.getName();
            if (fileName.startsWith(".")) {
                // ignore invisible files
                continue;
            } else if (fileName.equals(instanceFile.getName())) {
                // the xml file has already been added
                continue;
            } else if (fileName.equals(submissionFile.getName())) {
                // the xml file has already been added
                continue;
            }
            String extension = getFileExtension(fileName);
            if (openRosaServer) {
                files.add(f);
            } else if (extension.equals("jpg")) {
                // legacy 0.9x
                files.add(f);
            } else if (extension.equals("3gpp")) {
                // legacy 0.9x
                files.add(f);
            } else if (extension.equals("3gp")) {
                // legacy 0.9x
                files.add(f);
            } else if (extension.equals("mp4")) {
                // legacy 0.9x
                files.add(f);
            } else if (extension.equals("osm")) {
                // legacy 0.9x
                files.add(f);
            } else {
                Timber.w("unrecognized file type %s", f.getName());
            }
        }
    } else {
        return false;
    }
    boolean first = true;
    int j = 0;
    int lastJ;
    while (j < files.size() || first) {
        lastJ = j;
        first = false;
        MimeTypeMap m = MimeTypeMap.getSingleton();
        long byteCount = 0L;
        // mime post
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        // add the submission file first...
        FileBody fb = new FileBody(submissionFile, ContentType.TEXT_XML);
        builder.addPart("xml_submission_file", fb);
        Timber.i("added xml_submission_file: %s", submissionFile.getName());
        byteCount += submissionFile.length();
        for (; j < files.size(); j++) {
            File f = files.get(j);
            // we will be processing every one of these, so
            // we only need to deal with the content type determination...
            ContentType contentType = ContentTypeMapping.of(f.getName());
            if (contentType == null) {
                String mime = m.getMimeTypeFromExtension(getFileExtension(f.getName()));
                if (mime != null) {
                    contentType = ContentType.create(mime);
                } else {
                    Timber.w("No specific MIME type found for file: %s", f.getName());
                    contentType = ContentType.APPLICATION_OCTET_STREAM;
                }
            }
            fb = new FileBody(f, contentType);
            builder.addPart(f.getName(), fb);
            byteCount += f.length();
            Timber.i("added file of type '%s' %s", contentType, f.getName());
            // we've added at least one attachment to the request...
            if (j + 1 < files.size()) {
                if ((j - lastJ + 1 > 100) || (byteCount + files.get(j + 1).length() > 10000000L)) {
                    // the next file would exceed the 10MB threshold...
                    Timber.i("Extremely long post is being split into multiple posts");
                    try {
                        StringBody sb = new StringBody("yes", ContentType.TEXT_PLAIN.withCharset(Charset.forName("UTF-8")));
                        builder.addPart("*isIncomplete*", sb);
                    } catch (Exception e) {
                        Timber.e(e);
                    }
                    // advance over the last attachment added...
                    ++j;
                    break;
                }
            }
        }
        HttpPost httppost = WebUtils.createOpenRosaHttpPost(submissionUri);
        httppost.setEntity(builder.build());
        // prepare response and return uploaded
        HttpResponse response;
        try {
            Timber.i("Issuing POST request for %s to: %s", id, submissionUri.toString());
            response = httpclient.execute(httppost, localContext);
            int responseCode = response.getStatusLine().getStatusCode();
            HttpEntity httpEntity = response.getEntity();
            messageParser = new ResponseMessageParser(httpEntity);
            WebUtils.discardEntityBytes(response);
            Timber.i("Response code:%d", responseCode);
            // If it wasn't, the submission has failed.
            if (responseCode != HttpStatus.SC_CREATED && responseCode != HttpStatus.SC_ACCEPTED) {
                if (responseCode == HttpStatus.SC_OK) {
                    outcome.messagesByInstanceId.put(id, fail + "Network login failure? Again?");
                } else if (responseCode == HttpStatus.SC_UNAUTHORIZED) {
                    // clear the cookies -- should not be necessary?
                    Collect.getInstance().getCookieStore().clear();
                    outcome.messagesByInstanceId.put(id, fail + response.getStatusLine().getReasonPhrase() + " (" + responseCode + ") at " + urlString);
                } else {
                    // If response from server is valid use that else use default messaging
                    if (messageParser.isValid()) {
                        outcome.messagesByInstanceId.put(id, fail + messageParser.getMessageResponse());
                    } else {
                        outcome.messagesByInstanceId.put(id, fail + response.getStatusLine().getReasonPhrase() + " (" + responseCode + ") at " + urlString);
                    }
                }
                cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
                Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
                return true;
            }
        } catch (IOException e) {
            if (e instanceof UnknownHostException || e instanceof HttpHostConnectException || e instanceof SocketException || e instanceof NoHttpResponseException || e instanceof SocketTimeoutException || e instanceof ConnectTimeoutException) {
                Timber.i(e);
            } else {
                Timber.e(e);
            }
            String msg = e.getMessage();
            if (msg == null) {
                msg = e.toString();
            }
            outcome.messagesByInstanceId.put(id, fail + "Generic Exception: " + msg);
            cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMISSION_FAILED);
            Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
            return true;
        }
    }
    // If response from server is valid use that else use default messaging
    if (messageParser.isValid()) {
        outcome.messagesByInstanceId.put(id, messageParser.getMessageResponse());
    } else {
        // Default messaging
        outcome.messagesByInstanceId.put(id, Collect.getInstance().getString(R.string.success));
    }
    cv.put(InstanceColumns.STATUS, InstanceProviderAPI.STATUS_SUBMITTED);
    Collect.getInstance().getContentResolver().update(toUpdate, cv, null, null);
    return true;
}
Also used : SocketException(java.net.SocketException) HttpPost(org.opendatakit.httpclientandroidlib.client.methods.HttpPost) MultipartEntityBuilder(org.opendatakit.httpclientandroidlib.entity.mime.MultipartEntityBuilder) ContentType(org.opendatakit.httpclientandroidlib.entity.ContentType) HttpEntity(org.opendatakit.httpclientandroidlib.HttpEntity) ArrayList(java.util.ArrayList) MimeTypeMap(android.webkit.MimeTypeMap) Uri(android.net.Uri) URI(java.net.URI) HttpHead(org.opendatakit.httpclientandroidlib.client.methods.HttpHead) ClientProtocolException(org.opendatakit.httpclientandroidlib.client.ClientProtocolException) HttpHostConnectException(org.opendatakit.httpclientandroidlib.conn.HttpHostConnectException) ContentValues(android.content.ContentValues) NoHttpResponseException(org.opendatakit.httpclientandroidlib.NoHttpResponseException) UnknownHostException(java.net.UnknownHostException) FileBody(org.opendatakit.httpclientandroidlib.entity.mime.content.FileBody) ResponseMessageParser(org.odk.collect.android.utilities.ResponseMessageParser) HttpResponse(org.opendatakit.httpclientandroidlib.HttpResponse) IOException(java.io.IOException) ConnectTimeoutException(org.opendatakit.httpclientandroidlib.conn.ConnectTimeoutException) SocketException(java.net.SocketException) SocketTimeoutException(java.net.SocketTimeoutException) NoHttpResponseException(org.opendatakit.httpclientandroidlib.NoHttpResponseException) HttpHostConnectException(org.opendatakit.httpclientandroidlib.conn.HttpHostConnectException) ClientProtocolException(org.opendatakit.httpclientandroidlib.client.ClientProtocolException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SocketTimeoutException(java.net.SocketTimeoutException) StringBody(org.opendatakit.httpclientandroidlib.entity.mime.content.StringBody) HttpClient(org.opendatakit.httpclientandroidlib.client.HttpClient) File(java.io.File) ConnectTimeoutException(org.opendatakit.httpclientandroidlib.conn.ConnectTimeoutException)

Aggregations

IOException (java.io.IOException)3 URI (java.net.URI)3 HttpEntity (org.opendatakit.httpclientandroidlib.HttpEntity)3 HttpResponse (org.opendatakit.httpclientandroidlib.HttpResponse)3 File (java.io.File)2 InputStream (java.io.InputStream)2 MalformedURLException (java.net.MalformedURLException)2 URISyntaxException (java.net.URISyntaxException)2 URL (java.net.URL)2 GZIPInputStream (java.util.zip.GZIPInputStream)2 Header (org.opendatakit.httpclientandroidlib.Header)2 HttpClient (org.opendatakit.httpclientandroidlib.client.HttpClient)2 HttpGet (org.opendatakit.httpclientandroidlib.client.methods.HttpGet)2 ContentValues (android.content.ContentValues)1 Uri (android.net.Uri)1 MimeTypeMap (android.webkit.MimeTypeMap)1 FileOutputStream (java.io.FileOutputStream)1 InputStreamReader (java.io.InputStreamReader)1 OutputStream (java.io.OutputStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1