public URLFetchResponse fetch()

in api_dev/src/main/java/com/google/appengine/api/urlfetch/dev/LocalURLFetchService.java [347:458]


  public URLFetchResponse fetch(Status status, URLFetchRequest request) {
    if (status == null) {
      throw new NullPointerException("status cannot be null.");
    }

    if (request == null) {
      throw new NullPointerException("request cannot be null.");
    }

    if (!hasValidURL(request)) {
      throw new ApplicationException(
          ErrorCode.INVALID_URL.getNumber(), "Invalid URL: " + request.getUrl());
    }

    MethodFactory methodFactory = METHOD_FACTORY_MAP.get(request.getMethod());
    if (methodFactory == null) {
      throw new ApplicationException(
          ErrorCode.INVALID_URL.getNumber(), "Unsupported method: " + request.getMethod());
    }
    HttpRequestBase method = methodFactory.buildMethod(request);
    HttpParams params = new BasicHttpParams();
    HttpClientParams.setRedirecting(params, request.getFollowRedirects());

    // TODO set these timeouts according to the RPC deadline.
    // see http://b/1488459 for more info
    // how long we'll wait to establish a connection
    HttpConnectionParams.setConnectionTimeout(params, timeoutInMs);
    // how long we'll let the socket stay open
    HttpConnectionParams.setSoTimeout(params, timeoutInMs);
    method.setParams(params);

    boolean sawContentType = false;
    for (URLFetchRequest.Header pbHeader : request.getHeaderList()) {
      // Ignore user-set Content-Length header. It causes HttpClient to throw
      // an exception, and this behavior matches production.
      if (pbHeader.getKey().equalsIgnoreCase("Content-Length")) {
        continue;
      }

      method.addHeader(pbHeader.getKey(), pbHeader.getValue());

      if (pbHeader.getKey().equalsIgnoreCase("Content-Type")) {
        sawContentType = true;
      }
    }

    // See comment in apphosting/api/urlfetch/urlfetch_request_options.cc
    // TODO: Should we check on PUT/PATCH? What would the default be?
    if (!sawContentType && (request.getMethod() == RequestMethod.POST) && request.hasPayload()) {
      method.addHeader("Content-Type", "application/x-www-form-urlencoded");
    }

    URLFetchResponse.Builder response = URLFetchResponse.newBuilder();
    try {
      HttpResponse httpResponse = doPrivilegedExecute(request, method, response);
      int responseCode = httpResponse.getStatusLine().getStatusCode();
      if (responseCode < 100 || responseCode >= 600) {
        // Note, response codes in the range [100, 600) are valid.
        throw new ApplicationException(
            ErrorCode.FETCH_ERROR.getNumber(),
            "Status code "
                + responseCode
                + " unknown when making "
                + method.getMethod()
                + " request to URL: "
                + request.getUrl());
      }
      HttpEntity responseEntity = httpResponse.getEntity();
      if (responseEntity != null) {
        byte[] responseBuffer = responseToByteArray(responseEntity);
        if (responseBuffer.length > maxResponseLength) {
          responseBuffer = Arrays.copyOf(responseBuffer, maxResponseLength);
          response.setContentWasTruncated(true);
        }
        response.setContent(ByteString.copyFrom(responseBuffer));
      }
      httpclientHeadersToPbHeaders(httpResponse.getAllHeaders(), response);
    } catch (SocketTimeoutException ste) {
      throw new ApplicationException(
          ErrorCode.DEADLINE_EXCEEDED.getNumber(),
          "http method " + method.getMethod() + " against URL " + request.getUrl() + " timed out.");
    } catch (SSLException e) {
      throw new ApplicationException(
          ErrorCode.SSL_CERTIFICATE_ERROR.getNumber(),
          "Couldn't validate the server's SSL certificate for URL "
              + request.getUrl()
              + ": "
              + e.getMessage());
    } catch (IOException e) {
      if (e.getCause() != null
          && e.getCause().getMessage().matches("Maximum redirects \\([0-9]+\\) exceeded")) {
        throw new ApplicationException(
            ErrorCode.TOO_MANY_REDIRECTS.getNumber(),
            "Received exception executing http method "
                + method.getMethod()
                + " against URL "
                + request.getUrl()
                + ": "
                + e.getCause().getMessage());
      } else {
        throw new ApplicationException(
            ErrorCode.FETCH_ERROR.getNumber(),
            "Received exception executing http method "
                + method.getMethod()
                + " against URL "
                + request.getUrl()
                + ": "
                + e.getMessage());
      }
    }
    return response.build();
  }