Пример #1
0
  /**
   * Initialize the source for this response. It may be corrected later if the request headers
   * forbids network use.
   */
  private void initResponseSource() throws IOException {
    responseSource = ResponseSource.NETWORK;
    if (!policy.getUseCaches()) return;

    OkResponseCache responseCache = client.getOkResponseCache();
    if (responseCache == null) return;

    CacheResponse candidate =
        responseCache.get(uri, method, requestHeaders.getHeaders().toMultimap(false));
    if (candidate == null) return;

    Map<String, List<String>> responseHeadersMap = candidate.getHeaders();
    cachedResponseBody = candidate.getBody();
    if (!acceptCacheResponseType(candidate)
        || responseHeadersMap == null
        || cachedResponseBody == null) {
      Util.closeQuietly(cachedResponseBody);
      return;
    }

    RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap, true);
    cachedResponseHeaders = new ResponseHeaders(uri, rawResponseHeaders);
    long now = System.currentTimeMillis();
    this.responseSource = cachedResponseHeaders.chooseResponseSource(now, requestHeaders);
    if (responseSource == ResponseSource.CACHE) {
      this.cacheResponse = candidate;
      setResponse(cachedResponseHeaders, cachedResponseBody);
    } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
      this.cacheResponse = candidate;
    } else if (responseSource == ResponseSource.NETWORK) {
      Util.closeQuietly(cachedResponseBody);
    } else {
      throw new AssertionError();
    }
  }
Пример #2
0
  /**
   * Figures out what the response source will be, and opens a socket to that source if necessary.
   * Prepares the request headers and gets ready to start writing the request body if it exists.
   */
  public final void sendRequest() throws IOException {
    if (responseSource != null) {
      return;
    }

    prepareRawRequestHeaders();
    initResponseSource();
    OkResponseCache responseCache = client.getOkResponseCache();
    if (responseCache != null) {
      responseCache.trackResponse(responseSource);
    }

    // The raw response source may require the network, but the request
    // headers may forbid network use. In that case, dispose of the network
    // response and use a GATEWAY_TIMEOUT response instead, as specified
    // by http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4.
    if (requestHeaders.isOnlyIfCached() && responseSource.requiresConnection()) {
      if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
        Util.closeQuietly(cachedResponseBody);
      }
      this.responseSource = ResponseSource.CACHE;
      this.cacheResponse = GATEWAY_TIMEOUT_RESPONSE;
      RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(cacheResponse.getHeaders(), true);
      setResponse(new ResponseHeaders(uri, rawResponseHeaders), cacheResponse.getBody());
    }

    if (responseSource.requiresConnection()) {
      sendSocketRequest();
    } else if (connection != null) {
      client.getConnectionPool().recycle(connection);
      connection = null;
    }
  }
    void spewInternal() {
      if (pending.remaining() > 0) {
        com.koushikdutta.async.Util.emitAllData(BodySpewer.this, pending);
        if (pending.remaining() > 0) return;
      }

      // fill pending
      try {
        while (pending.remaining() == 0) {
          ByteBuffer buffer = ByteBuffer.allocate(8192);
          int read = cacheResponse.getBody().read(buffer.array());
          if (read == -1) {
            allowEnd = true;
            report(null);
            return;
          }
          buffer.limit(read);
          pending.add(buffer);
          com.koushikdutta.async.Util.emitAllData(BodySpewer.this, pending);
        }
      } catch (IOException e) {
        allowEnd = true;
        report(e);
      }
    }
Пример #4
0
 // Tries to get head and body from cache, return true if has got this time
 // or
 // already got before
 private boolean getFromCache() throws IOException {
   if (useCaches && null != responseCache && !hasTriedCache) {
     hasTriedCache = true;
     if (null == resHeader) {
       resHeader = new Header();
     }
     cacheResponse = responseCache.get(uri, method, resHeader.getFieldMap());
     if (null != cacheResponse) {
       Map<String, List<String>> headMap = cacheResponse.getHeaders();
       if (null != headMap) {
         resHeader = new Header(headMap);
       }
       is = cacheResponse.getBody();
       if (null != is) {
         return true;
       }
     }
   }
   if (hasTriedCache && null != is) {
     return true;
   }
   return false;
 }
  // step 1) see if we can serve request from the cache directly.
  // also see if this can be turned into a conditional cache request.
  @Override
  public Cancellable getSocket(final GetSocketData data) {
    if (cache == null) return null;

    if (!caching) return null;
    if (data.request.getHeaders().isNoCache()) return null;
    //        Log.i(LOGTAG, "getting cache socket: " + request.getUri().toString());

    String key = uriToKey(data.request.getUri());
    DiskLruCache.Snapshot snapshot;
    Entry entry;
    try {
      snapshot = cache.get(key);
      if (snapshot == null) {
        //                Log.i(LOGTAG, "snapshot fail");
        return null;
      }
      entry = new Entry(snapshot.getInputStream(ENTRY_METADATA));
    } catch (IOException e) {
      // Give up because the cache cannot be read.
      return null;
    }

    if (!entry.matches(
        data.request.getUri(),
        data.request.getMethod(),
        data.request.getHeaders().getHeaders().toMultimap())) {
      snapshot.close();
      return null;
    }

    ResponseSource responseSource = ResponseSource.NETWORK;

    CacheResponse candidate =
        entry.isHttps()
            ? new EntrySecureCacheResponse(entry, snapshot)
            : new EntryCacheResponse(entry, snapshot);

    Map<String, List<String>> responseHeadersMap;
    InputStream cachedResponseBody;
    try {
      responseHeadersMap = candidate.getHeaders();
      cachedResponseBody = candidate.getBody();
    } catch (Exception e) {
      return null;
    }
    if (responseHeadersMap == null || cachedResponseBody == null) {
      try {
        cachedResponseBody.close();
      } catch (Exception e) {
      }
      return null;
    }

    RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap);
    ResponseHeaders cachedResponseHeaders =
        new ResponseHeaders(data.request.getUri(), rawResponseHeaders);

    long now = System.currentTimeMillis();
    responseSource = cachedResponseHeaders.chooseResponseSource(now, data.request.getHeaders());

    if (responseSource == ResponseSource.CACHE) {
      cacheStoreCount++;
      final CachedSocket socket =
          entry.isHttps()
              ? new CachedSSLSocket((EntrySecureCacheResponse) candidate)
              : new CachedSocket((EntryCacheResponse) candidate);

      client
          .getServer()
          .post(
              new Runnable() {
                @Override
                public void run() {
                  data.connectCallback.onConnectCompleted(null, socket);
                  socket.spewInternal();
                }
              });
    } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
      CacheData cacheData = new CacheData();
      cacheData.cachedResponseHeaders = cachedResponseHeaders;
      cacheData.candidate = candidate;
      data.state.putParcelable("cache-data", cacheData);

      return null;
    } else {
      // NETWORK or other
      try {
        cachedResponseBody.close();
      } catch (Exception e) {
      }
      return null;
    }

    return new SimpleCancelable();
  }
Пример #6
0
  public static Record[] getRecords(String namestr, short type, short dclass, byte cred) {
    Message query;
    Message response;
    Record question;
    Record[] answers;
    int answerCount = 0, i = 0;
    Enumeration e;
    Name name = new Name(namestr);

    /*System.out.println("lookup of " + name + " " + Type.string(type));*/
    if (!Type.isRR(type) && type != Type.ANY) return null;

    if (res == null) {
      try {
        eres = new ExtendedResolver();
      } catch (UnknownHostException uhe) {
        System.out.println("Failed to initialize resolver");
        System.exit(-1);
      }
    }
    if (cache == null) cache = new Cache();

    CacheResponse cached = cache.lookupRecords(name, type, dclass, cred);
    /*System.out.println(cached);*/
    if (cached.isSuccessful()) {
      RRset rrset = cached.answer();
      answerCount = rrset.size();
      e = rrset.rrs();
    } else if (cached.isNegative()) {
      answerCount = 0;
      e = null;
    } else {
      question = Record.newRecord(name, type, dclass);
      query = Message.newQuery(question);

      if (res != null) response = res.send(query);
      else response = eres.send(query);

      short rcode = response.getHeader().getRcode();
      if (rcode == Rcode.NOERROR || rcode == Rcode.NXDOMAIN) cache.addMessage(response);

      if (rcode != Rcode.NOERROR) return null;

      e = response.getSection(Section.ANSWER);
      while (e.hasMoreElements()) {
        Record r = (Record) e.nextElement();
        if (matchType(r.getType(), type)) answerCount++;
      }

      e = response.getSection(Section.ANSWER);
    }

    if (answerCount == 0) return null;

    answers = new Record[answerCount];

    while (e.hasMoreElements()) {
      Record r = (Record) e.nextElement();
      if (matchType(r.getType(), type)) answers[i++] = r;
    }

    return answers;
  }