AWS Lambda HTTPs POST请求超时但在本地工作

时间:2020-05-23 01:36:08

标签: java aws-lambda httpurlconnection

我创建了一个AWS Lambda函数,该函数调用FredMeyers商店位置API。在我的IDE中本地发送POST请求可以正常工作,但是在lambda中运行时,POST请求会超时。我可以在本地和其他Lambda函数中成功向不同的杂货店API发送其他GET请求。 Lambda不在VPC中运行。

我在想以下其中一项:

1)我的sendPost方法设置错误,因为它仅在本地工作

2)API网关和Lambda某种程度上阻止了我的POST请求,因此urlConnection仍在等待(HttpUrlConnection)

3)从AWS Lambda进行呼叫时,目标URL目标有所不同

在运行lambda期间,代码挂起:

 int responseCode = urlConnection.getResponseCode();

HttpHelper:

public class HttpsClient{

    private final String urlPath;

    public HttpsClient(final String urlPath) {
        this.urlPath = urlPath;
    }

    public String sendPost(final Map<String, String> requestPropertiesMap, final String requestBodyJson) throws IOException {
        URL obj = new URL(urlPath);
        HttpURLConnection urlConnection = (HttpURLConnection) obj.openConnection();
        urlConnection.setRequestMethod("POST");

        if (true) {
            SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            ((HttpsURLConnection) urlConnection).setSSLSocketFactory(socketFactory);
        }

        requestPropertiesMap.entrySet().stream().forEach(entry ->
                urlConnection.addRequestProperty(entry.getKey(), entry.getValue()));

        final byte[] bodyRequest = requestBodyJson.getBytes(StandardCharsets.UTF_8);
        urlConnection.setDoOutput(true);
        DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());
        outputStream.write(bodyRequest);
        outputStream.flush();
        outputStream.close();

        int responseCode = urlConnection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) { // success

            try {
                final String encoding = urlConnection.getContentEncoding();
                final InputStream in;
                if ("gzip".equals(encoding)) {
                    in = new GZIPInputStream(urlConnection.getInputStream());
                } else {
                    in = urlConnection.getInputStream();
                }
                return textFromInputStream(in);
            } finally {
                urlConnection.getInputStream().close();
            }
        } else {
            throw new RuntimeException("Something went wrong... :( status code: " +
                    responseCode + " " + urlConnection.getResponseMessage());
        }
    }

    private String textFromInputStream(final InputStream inputStream) {
        return new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)).lines()
                .collect(Collectors.joining("\n"));
    }
} 

Fred Meyer商店搜索

public class FredMeyerStoreSearch implements StoreSearchClient {

    private final String apiURLFormat = "https://www.fredmeyer.com/atlas/v1/modality/options";

    @Override
    public List<Store> searchStores(final String zipCode) {
        final String requestBodyJson  = new Gson().toJson(StoreOptionsRequest.builder()
                .address(StoreAddress.builder().postalCode(zipCode).build())
                .build());
        try {
            final String fullUrl = apiURLFormat;
            final HttpsClient httpsClient = new HttpsClient(fullUrl);
            final String response = httpsClient.sendPost(getRequestParameters(), requestBodyJson);
            return new FredMeyerStoreTransformer(response).createStores();
        } catch (IOException e) {
            throw new RuntimeException("Something wrong with search call", e);
        }
    }

    private Map<String, String> getRequestParameters() {
        return new HashMap<String, String>() {{
            put("cookie", Constant.EMPTY_COOKIE);
            put("accept", "application/json, text/plain, */*");
            put("accept-encoding", "gzip, deflate, br");
            put("accept-language", "en-US,en;q=0.9");
            put("sec-fetch-dest", "empty");
            put("sec-fetch-mode", "cors");
            put("sec-fetch-site", "same-origin");
            put("user-agent", Constant.USER_AGENT);
            put("content-type", "application/json");
        }};
    }

    @Builder
    @Data
    private static class StoreOptionsRequest {
        private StoreAddress address;
    }

    @Builder
    @Data
    private static class StoreAddress {
        private String postalCode;
    }
}

编辑:太平洋标准时间05/23 @ 3:30 AM

  • 我重构为使用OkHttp3 HttpClient代替HttpUrlConnection,并且行为相同
  • 我引入了网络拦截器(OkHttp3)来记录请求/响应
  • 本地和lambda GET / POST请求都是相同的。
  • 本地POST请求命中nginx负载均衡器并正常工作
  • lambda POST请求命中了AkamaiGHost缓存服务器,该服务器似乎已配置为拒绝POST请求

有人对此行为和潜在的解决方法有洞见吗?

本地:

Received response for https://www.fredmeyer.com/atlas/v1/modality/options in 329.7ms
Server: nginx
Content-Type: application/json; charset=utf-8
Vary: Accept-Encoding
Access-Control-Allow-Origin: https://www.fredmeyer.com
Surrogate-Control: no-store
Vary: Origin
X-Content-Type-Options: nosniff
X-Dns-Prefetch-Control: off
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Vcap-Request-Id: c19c969d-0b1d-47c7-5784-c035a800c9c6
X-Xss-Protection: 1; mode=block
Content-Encoding: gzip
Content-Length: 3457
Expires: Sat, 23 May 2020 10:02:41 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Sat, 23 May 2020 10:02:41 GMT
Connection: keep-alive
Server-Timing: cdn-cache; desc=MISS
Server-Timing: edge; dur=58
Server-Timing: origin; dur=143
X-KT-ACR-LMA-CT: true
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Set-Cookie:<hiding>
Set-Cookie:<hiding>

Lambda:

Received response for https://www.fredmeyer.com/atlas/v1/modality/options in 201.3ms
Server: AkamaiGHost
Mime-Version: 1.0
Content-Type: text/html
Content-Length: 304
Expires: Sat, 23 May 2020 Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Sat, 23 May 2020 Connection: close
Server-Timing: cdn-cache; desc=HIT
Server-Timing: edge; dur=1
X-KT-ACR-LMA-CT: true
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Decoded Response: <HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
You don't have permission to access "http&#58;&#47;&#47;www&#46;fredmeyer&#46;com&#47;atlas&#47;v1&#47;modality&#47;options" on this server.<P>
Reference&#32;&#35;18&#46;1e032417&#46;1590228331&#46;1335abc8
</BODY>
</HTML>

0 个答案:

没有答案