private void uploadPing(final TelemetryPing ping, final ResultDelegate delegate) {
    final BaseResource resource;
    try {
      resource = new BaseResource(ping.getURL());
    } catch (final URISyntaxException e) {
      Log.w(LOGTAG, "URISyntaxException for server URL when creating BaseResource: returning.");
      return;
    }

    delegate.setResource(resource);
    resource.delegate = delegate;
    resource.setShouldCompressUploadedEntity(true);
    resource.setShouldChunkUploadsHint(false); // Telemetry servers don't support chunking.

    // We're in a background thread so we don't have any reason to do this asynchronously.
    // If we tried, onStartCommand would return and IntentService might stop itself before we
    // finish.
    resource.postBlocking(ping.getPayload());
  }
Beispiel #2
0
 /** Stop observing HttpResponses for backoff requests. */
 protected void uninstallAsHttpResponseObserver() {
   Logger.debug(LOG_TAG, "Uninstalling " + this + " as BaseResource HttpResponseObserver.");
   BaseResource.setHttpResponseObserver(null);
 }
Beispiel #3
0
 /** Reset any observed backoff and start observing HTTP responses for backoff requests. */
 protected void installAsHttpResponseObserver() {
   Logger.debug(LOG_TAG, "Installing " + this + " as BaseResource HttpResponseObserver.");
   BaseResource.setHttpResponseObserver(this);
   largestBackoffObserved.set(-1);
 }
  private Resource createGetRequest(
      final GetRequestStageDelegate callbackDelegate, final JPakeClient jpakeClient)
      throws URISyntaxException {
    BaseResource httpResource = new BaseResource(jpakeClient.channelUrl);
    httpResource.delegate =
        new SyncResourceDelegate(httpResource) {

          @Override
          public void addHeaders(HttpRequestBase request, DefaultHttpClient client) {
            request.setHeader(new BasicHeader("X-KeyExchange-Id", jpakeClient.clientId));
            if (jpakeClient.myEtag != null) {
              request.setHeader(new BasicHeader("If-None-Match", jpakeClient.myEtag));
            }
          }

          @Override
          public void handleHttpResponse(HttpResponse response) {
            int statusCode = response.getStatusLine().getStatusCode();
            switch (statusCode) {
              case 200:
                jpakeClient.pollTries = 0; // Reset pollTries for next GET.
                callbackDelegate.handleSuccess(response);
                break;
              case 304:
                Logger.debug(LOG_TAG, "Channel hasn't been updated yet. Will try again later");
                if (pollTries >= jpakeClient.jpakeMaxTries) {
                  Logger.error(
                      LOG_TAG,
                      "Tried for "
                          + pollTries
                          + " times, maxTries "
                          + jpakeClient.jpakeMaxTries
                          + ", aborting");
                  callbackDelegate.handleFailure(Constants.JPAKE_ERROR_TIMEOUT);
                  break;
                }
                jpakeClient.pollTries += 1;
                if (!jpakeClient.finished) {
                  Logger.debug(LOG_TAG, "Scheduling next GET request.");
                  scheduleGetRequest(jpakeClient.jpakePollInterval, jpakeClient);
                } else {
                  Logger.debug(LOG_TAG, "Resetting pollTries");
                  jpakeClient.pollTries = 0;
                }
                break;
              case 404:
                Logger.error(LOG_TAG, "No data found in channel.");
                callbackDelegate.handleFailure(Constants.JPAKE_ERROR_NODATA);
                break;
              case 412: // "Precondition failed"
                Logger.debug(LOG_TAG, "Message already replaced on server by other party.");
                callbackDelegate.handleSuccess(response);
                break;
              default:
                Logger.error(
                    LOG_TAG, "Could not retrieve data. Server responded with HTTP " + statusCode);
                callbackDelegate.handleFailure(Constants.JPAKE_ERROR_SERVER);
                break;
            }
            // Clean up.
            SyncResourceDelegate.consumeEntity(response.getEntity());
          }

          @Override
          public void handleHttpProtocolException(ClientProtocolException e) {
            callbackDelegate.handleError(e);
          }

          @Override
          public void handleHttpIOException(IOException e) {
            callbackDelegate.handleError(e);
          }

          @Override
          public void handleTransportException(GeneralSecurityException e) {
            callbackDelegate.handleError(e);
          }

          @Override
          public int connectionTimeout() {
            return JPakeClient.REQUEST_TIMEOUT;
          }
        };
    return httpResource;
  }
  @Override
  public void execute(final AccountAuthenticator aa)
      throws URISyntaxException, UnsupportedEncodingException {
    final EnsureUserExistenceStageDelegate callbackDelegate =
        new EnsureUserExistenceStageDelegate() {

          @Override
          public void handleSuccess() {
            // User exists; now determine auth node.
            Log.d(LOG_TAG, "handleSuccess()");
            aa.runNextStage();
          }

          @Override
          public void handleFailure(AuthenticationResult result) {
            aa.abort(result, new Exception("Failure in EnsureUser"));
          }

          @Override
          public void handleError(Exception e) {
            Logger.info(LOG_TAG, "Error checking for user existence.");
            aa.abort(AuthenticationResult.FAILURE_SERVER, e);
          }
        };

    String userRequestUrl =
        aa.nodeServer + Constants.AUTH_NODE_PATHNAME + Constants.AUTH_NODE_VERSION + aa.username;
    final BaseResource httpResource = new BaseResource(userRequestUrl);
    httpResource.delegate =
        new SyncResourceDelegate(httpResource) {

          @Override
          public void handleHttpResponse(HttpResponse response) {
            int statusCode = response.getStatusLine().getStatusCode();
            switch (statusCode) {
              case 200:
                try {
                  InputStream content = response.getEntity().getContent();
                  BufferedReader reader =
                      new BufferedReader(new InputStreamReader(content, "UTF-8"), 1024);
                  String inUse = reader.readLine();
                  BaseResource.consumeReader(reader);
                  reader.close();
                  // Removed Logger.debug inUse, because stalling.
                  if (inUse.equals("1")) { // Username exists.
                    callbackDelegate.handleSuccess();
                  } else { // User does not exist.
                    Logger.info(LOG_TAG, "No such user.");
                    callbackDelegate.handleFailure(AuthenticationResult.FAILURE_USERNAME);
                  }
                } catch (Exception e) {
                  Logger.error(LOG_TAG, "Failure in content parsing.", e);
                  callbackDelegate.handleFailure(AuthenticationResult.FAILURE_OTHER);
                }
                break;
              default: // No other response is acceptable.
                callbackDelegate.handleFailure(AuthenticationResult.FAILURE_OTHER);
            }
            Logger.debug(LOG_TAG, "Consuming entity.");
            BaseResource.consumeEntity(response.getEntity());
          }

          @Override
          public void handleHttpProtocolException(ClientProtocolException e) {
            callbackDelegate.handleError(e);
          }

          @Override
          public void handleHttpIOException(IOException e) {
            callbackDelegate.handleError(e);
          }

          @Override
          public void handleTransportException(GeneralSecurityException e) {
            callbackDelegate.handleError(e);
          }
        };
    // Make request.
    AccountAuthenticator.runOnThread(
        new Runnable() {

          @Override
          public void run() {
            httpResource.get();
          }
        });
  }
  // TODO: if cluster URL has changed since last time, we need to ensure that we do
  // a fresh start. This takes place at the GlobalSession level. Verify!
  public static void fetchClusterURL(
      final GlobalSession session, final ClusterURLFetchDelegate delegate)
      throws URISyntaxException {
    Log.i(LOG_TAG, "In fetchClusterURL. Server URL is " + session.config.serverURL);
    String nodeWeaveURL = session.config.nodeWeaveURL();
    Log.d(LOG_TAG, "node/weave is " + nodeWeaveURL);

    BaseResource resource = new BaseResource(nodeWeaveURL);
    resource.delegate =
        new SyncResourceDelegate(resource) {

          @Override
          public void handleHttpResponse(HttpResponse response) {
            int status = response.getStatusLine().getStatusCode();
            switch (status) {
              case 200:
                Log.i(LOG_TAG, "Got 200 for node/weave fetch.");
                // Great!
                HttpEntity entity = response.getEntity();
                if (entity == null) {
                  delegate.handleSuccess(null);
                  return;
                }
                String output = null;
                try {
                  InputStream content = entity.getContent();
                  BufferedReader reader =
                      new BufferedReader(new InputStreamReader(content, "UTF-8"), 1024);
                  output = reader.readLine();
                  SyncResourceDelegate.consumeReader(reader);
                  reader.close();
                } catch (IllegalStateException e) {
                  delegate.handleError(e);
                } catch (IOException e) {
                  delegate.handleError(e);
                }

                if (output == null || output.equals("null")) {
                  delegate.handleSuccess(null);
                }
                delegate.handleSuccess(output);
                break;
              case 400:
              case 404:
                Log.i(LOG_TAG, "Got " + status + " for cluster URL request.");
                delegate.handleFailure(response);
                SyncResourceDelegate.consumeEntity(response.getEntity());
                break;
              default:
                Log.w(LOG_TAG, "Got " + status + " fetching node/weave. Returning failure.");
                delegate.handleFailure(response);
                SyncResourceDelegate.consumeEntity(response.getEntity());
            }
          }

          @Override
          public void handleHttpProtocolException(ClientProtocolException e) {
            delegate.handleError(e);
          }

          @Override
          public void handleHttpIOException(IOException e) {
            delegate.handleError(e);
          }

          @Override
          public void handleTransportException(GeneralSecurityException e) {
            delegate.handleError(e);
          }
        };

    resource.get();
  }
  public MockGlobalSessionCallback doTestSuccess(
      final boolean stageShouldBackoff, final boolean stageShouldAdvance)
      throws SyncConfigurationException, IllegalArgumentException, NonObjectJSONException,
          IOException, ParseException, CryptoException {
    MockServer server =
        new MockServer() {
          @Override
          public void handle(Request request, Response response) {
            if (stageShouldBackoff) {
              response.set("X-Weave-Backoff", Long.toString(TEST_BACKOFF_IN_SECONDS));
            }
            super.handle(request, response);
          }
        };

    final MockServerSyncStage stage =
        new MockServerSyncStage() {
          @Override
          public void execute() {
            // We should have installed our HTTP response observer before starting the sync.
            assertTrue(BaseResource.isHttpResponseObserver(session));

            doRequest();
            if (stageShouldAdvance) {
              session.advance();
              return;
            }
            session.abort(null, "Stage intentionally failed.");
          }
        };

    final MockGlobalSessionCallback callback = new MockGlobalSessionCallback(TEST_CLUSTER_URL);
    SyncConfiguration config =
        new SyncConfiguration(
            TEST_USERNAME,
            new BasicAuthHeaderProvider(TEST_USERNAME, TEST_PASSWORD),
            new MockSharedPreferences(),
            new KeyBundle(TEST_USERNAME, TEST_SYNC_KEY));
    final GlobalSession session =
        new MockGlobalSession(config, callback).withStage(Stage.syncBookmarks, stage);

    data.startHTTPServer(server);
    WaitHelper.getTestWaiter()
        .performWait(
            WaitHelper.onThreadRunnable(
                new Runnable() {
                  @Override
                  public void run() {
                    try {
                      session.start();
                    } catch (Exception e) {
                      final AssertionFailedError error = new AssertionFailedError();
                      error.initCause(e);
                      WaitHelper.getTestWaiter().performNotify(error);
                    }
                  }
                }));
    data.stopHTTPServer();

    // We should have uninstalled our HTTP response observer when the session is terminated.
    assertFalse(BaseResource.isHttpResponseObserver(session));

    return callback;
  }