@Override public void setContentType(String type) { if (isCommitted()) { return; } if (hasWriter()) { return; } if (null == type) { contentType = null; return; } MediaType mediaType = MediaType.parse(type); Optional<Charset> charset = mediaType.charset(); if (charset.isPresent()) { setCharacterEncoding(charset.get().name()); } contentType = mediaType.type() + '/' + mediaType.subtype(); }
private boolean requestAccessToken(Map<String, Object> queryMap) { Url tokenUri = Url.url("https://streamlabs.com/api/v1.0", "token"); String formData = Url.createQueryString(queryMap); HttpFields headers = new HttpFields(); headers.put(WebClient.NO_CACHE_HEADER, "true"); try { Response<StreamLabsToken> response = webClient.post(tokenUri, headers, formData, MediaType.FORM_DATA, StreamLabsToken.class); //noinspection Duplicates if (response.isOK()) { accessToken = response.getData().getAccessToken(); refreshToken = response.getData().getRefreshToken(); timeToLive = response.getData().getExpiresIn(); } else { authenticationError = "Failed exchanging authorization code for access token: " + response.getRawData(); } } catch (Exception e) { authenticationError = e.getMessage(); } return authenticationError == null; }
private static <T> T getMapper(List<MediaType> contentTypes, Map<MediaType, T> contentTypeMap, String errorMessage) throws LambdaException { List<MediaType> contentTypesWithoutParameters = contentTypes.stream() .map(MediaType::withoutParameters) .collect(toList()); return contentTypesWithoutParameters.stream() .map(contentTypeMap::get) .filter(Objects::nonNull) .findFirst() .orElseThrow(() -> { ApiGatewayProxyResponse unsupportedContentType = new ApiGatewayProxyResponseBuilder() .withStatusCode(UNSUPPORTED_MEDIA_TYPE.getStatusCode()) .withBody(String.format(errorMessage, contentTypes)) .build(); return new LambdaException(unsupportedContentType); }); }
@Test public void shouldIgnoreParametersWhenMatchingContentTypeAndAccept() throws Exception { sampleMethodHandler.registerPerContentType(CONTENT_TYPE_1, contentTypeMapper1); sampleMethodHandler.registerPerAccept(ACCEPT_TYPE_1, acceptMapper1); int output = 0; when(contentTypeMapper1.toInput(request, context)).thenReturn(output); when(acceptMapper1.outputToResponse(output)).thenReturn(new ApiGatewayProxyResponse.ApiGatewayProxyResponseBuilder() .withStatusCode(OK.getStatusCode()) .build()); MediaType contentTypeWithParameter = CONTENT_TYPE_1.withParameter("attribute", "value"); MediaType acceptTypeWithParameter = ACCEPT_TYPE_1.withParameter("attribute", "value"); ApiGatewayProxyResponse response = sampleMethodHandler.handle(request, singletonList(contentTypeWithParameter), singletonList(acceptTypeWithParameter), context); assertThat(response.getStatusCode()).isEqualTo(OK.getStatusCode()); }
@Test public void shouldIgnoreParametersWhenRegisteringContentTypeAndAccept() throws Exception { MediaType contentTypeWithParameter = CONTENT_TYPE_1.withParameter("attribute", "value"); MediaType acceptTypeWithParameter = ACCEPT_TYPE_1.withParameter("attribute", "value"); sampleMethodHandler.registerPerContentType(contentTypeWithParameter, contentTypeMapper1); sampleMethodHandler.registerPerAccept(acceptTypeWithParameter, acceptMapper1); int output = 0; when(contentTypeMapper1.toInput(request, context)).thenReturn(output); when(acceptMapper1.outputToResponse(output)).thenReturn(new ApiGatewayProxyResponse.ApiGatewayProxyResponseBuilder() .withStatusCode(OK.getStatusCode()) .build()); ApiGatewayProxyResponse response = sampleMethodHandler.handle(request, singletonList(CONTENT_TYPE_1), singletonList(ACCEPT_TYPE_1), context); assertThat(response.getStatusCode()).isEqualTo(OK.getStatusCode()); }
MediaTypeClassifierImpl(Iterable<? extends MediaType> mts) { Table<String, String, Set<MediaType>> typeTable = HashBasedTable.<String, String, Set<MediaType>>create(); for (MediaType mt : mts) { String type = mt.type(); String subtype = mt.subtype(); Set<MediaType> typeSet = typeTable.get(type, subtype); if (typeSet == null) { typeSet = Sets.newLinkedHashSet(); typeTable.put(type, subtype, typeSet); } typeSet.add(mt); } ImmutableTable.Builder<String, String, ImmutableSet<MediaType>> b = ImmutableTable.builder(); for (Table.Cell<String, String, Set<MediaType>> cell : typeTable.cellSet()) { b.put(cell.getRowKey(), cell.getColumnKey(), ImmutableSet.copyOf(cell.getValue())); } this.types = b.build(); }
@Override public Classification apply( UrlValue x, Diagnostic.Receiver<? super UrlValue> r) { MediaType t = x.getContentMediaType(); if (t == null) { r.note(Diagnostics.MISSING_MEDIA_TYPE, x); return Classification.INVALID; } String type = t.type(); String subtype = t.subtype(); if ("*".equals(type) || "*".equals(subtype)) { r.note(Diagnostics.WILDCARD, x); return Classification.INVALID; } if (anyRangeMatches(t, types.get(type, subtype)) || anyRangeMatches(t, types.get(type, "*")) || anyRangeMatches(t, types.get("*", "*"))) { return Classification.MATCH; } r.note(Diagnostics.WITHIN_NO_RANGES, x); return Classification.NOT_A_MATCH; }
/** * Extracts a JSON object from a servlet request. * * @return JSON object or {@code null} on error, in which case servlet should return. * @throws IOException if we failed to read from {@code req}. */ @Nullable @SuppressWarnings("unchecked") public static Map<String, ?> read(HttpServletRequest req) throws IOException { if (!"POST".equals(req.getMethod()) && !"PUT".equals(req.getMethod())) { logger.warning("JSON request payload only allowed for POST/PUT"); return null; } if (!JSON_UTF_8.is(MediaType.parse(req.getContentType()))) { logger.warningfmt("Invalid JSON Content-Type: %s", req.getContentType()); return null; } try (Reader jsonReader = req.getReader()) { try { return checkNotNull((Map<String, ?>) JSONValue.parseWithException(jsonReader)); } catch (ParseException | NullPointerException | ClassCastException e) { logger.warning(e, "Malformed JSON"); return null; } } }
@Override public void setContentType(String type) { if (isCommitted()) { return; } // if (hasWriter()) { // return; // } if (null == type) { contentType = null; return; } MediaType mediaType = MediaType.parse(type); Optional<Charset> charset = mediaType.charset(); if (charset.isPresent()) { setCharacterEncoding(charset.get().name()); } contentType = mediaType.type() + '/' + mediaType.subtype(); }
/** * Creates a file with the given parent or updates the existing one if a file already exists with * that same title and parent. * * @throws IllegalStateException if multiple files with that name exist in the given folder. * @throws IOException if communication with Google Drive fails for any reason. * @returns the file id. */ public String createOrUpdateFile( String title, MediaType mimeType, String parentFolderId, byte[] bytes) throws IOException { List<String> existingFiles = listFiles(parentFolderId, String.format("title = '%s'", title)); if (existingFiles.size() > 1) { throw new IllegalStateException(String.format( "Could not update file '%s' in Drive folder id '%s' because multiple files with that " + "name already exist.", title, parentFolderId)); } return existingFiles.isEmpty() ? createFile(title, mimeType, parentFolderId, bytes) : updateFile(existingFiles.get(0), title, mimeType, bytes); }
@Test public void testCreateOrUpdateFile_succeedsForNewFile() throws Exception { when(files.insert( eq(new File() .setTitle("title") .setMimeType("video/webm") .setParents(ImmutableList.of(new ParentReference().setId("driveFolderId")))), argThat(hasByteArrayContent(DATA)))) .thenReturn(insert); ChildList emptyChildList = new ChildList().setItems(ImmutableList.of()).setNextPageToken(null); when(childrenList.execute()).thenReturn(emptyChildList); assertThat(driveConnection.createOrUpdateFile( "title", MediaType.WEBM_VIDEO, "driveFolderId", DATA)) .isEqualTo("id"); }
@Before public void init() throws Exception { command.setConnection(connection); premiumTermsPath = writeToNamedTmpFile( "example_premium_terms.csv", readResourceUtf8( CreatePremiumListCommandTest.class, "testdata/example_premium_terms.csv")); servletPath = "/_dr/admin/createPremiumList"; when(connection.send( eq(CreatePremiumListAction.PATH), anyMapOf(String.class, String.class), any(MediaType.class), any(byte[].class))) .thenReturn(JSON_SAFETY_PREFIX + "{\"status\":\"success\",\"lines\":[]}"); }
@SuppressWarnings("unchecked") @Test public void test_deleteTwoEntities() throws Exception { String firstKey = "alphaNumericKey1"; String secondKey = "alphaNumericKey2"; String rawKeys = String.format("%s,%s", firstKey, secondKey); when(connection.send(anyString(), anyMap(), any(MediaType.class), any(byte[].class))) .thenReturn("Deleted 1 raw entities and 1 registered entities."); runCommandForced(firstKey, secondKey); verify(connection).send( eq("/_dr/admin/deleteEntity"), eq(ImmutableMap.of("rawKeys", rawKeys)), eq(MediaType.PLAIN_TEXT_UTF_8), eq(new byte[0])); assertInStdout("Deleted 1 raw entities and 1 registered entities."); }
/** * Helper method that connects to the given URL and returns the response as * a String * * @param url * the URL to connect to * @return the response content as a String */ protected String getMetadata(String url) throws MCRPersistenceException { try { URLConnection connection = getConnection(url); connection.setConnectTimeout(getConnectTimeout()); String contentType = connection.getContentType(); Charset charset = StandardCharsets.ISO_8859_1; //defined by RFC 2616 (sec 3.7.1) if (contentType != null) { MediaType mediaType = MediaType.parse(contentType); mediaType.charset().or(StandardCharsets.ISO_8859_1); } ByteArrayOutputStream out = new ByteArrayOutputStream(1024); forwardData(connection, out); return new String(out.toByteArray(), charset); } catch (IOException exc) { String msg = "Could not get metadata from Audio/Video Store URL: " + url; throw new MCRPersistenceException(msg, exc); } }
private boolean isAcceptableMediaType(KatharsisInvokerContext invokerContext) { String acceptHeader = invokerContext.getRequestHeader("Accept"); if (acceptHeader != null) { String[] accepts = acceptHeader.split(","); MediaType acceptableType; for (String mediaTypeItem : accepts) { acceptableType = MediaType.parse(mediaTypeItem.trim()); if (JsonApiMediaType.isCompatibleMediaType(acceptableType)) { return true; } } } return false; }
@Test public void testRun_errorResponse() throws Exception { reset(connection); command.setConnection(connection); when(connection.send( eq(CreatePremiumListAction.PATH), anyMapOf(String.class, String.class), any(MediaType.class), any(byte[].class))) .thenReturn( JSON_SAFETY_PREFIX + "{\"status\":\"error\",\"error\":\"foo already exists\"}"); VerifyException thrown = expectThrows( VerifyException.class, () -> runCommandForced("-i=" + premiumTermsPath, "-n=foo")); assertThat(thrown).hasMessageThat().contains("Server error:"); }
public final T setHeader(String name, @Nullable String value) { checkArgument(CharMatcher.whitespace().matchesNoneOf(name)); name = Ascii.toLowerCase(name); value = emptyToNull(value); switch (name) { case "content-type": setContentType(value == null ? null : MediaType.parse(value)); break; case "content-length": setContentLength(value == null ? -1 : Long.parseLong(value)); break; default: if (value == null) { headers.remove(name); } else { checkArgument(CRLF.matchesNoneOf(value)); headers.put(name, checkNotNull(value)); } } return castThis(); }
@Test public void testFailure_driveApiThrowsException() throws Exception { when(driveConnection.createFile( anyString(), any(MediaType.class), anyString(), any(byte[].class))) .thenThrow(new IOException("Drive is down")); InternalServerErrorException thrown = expectThrows( InternalServerErrorException.class, () -> action.handleJsonRequest( ImmutableMap.of( REGISTRAR_ID_PARAM, "TheRegistrar", GCS_BUCKET_PARAM, "mah-buckit", GCS_FOLDER_PREFIX_PARAM, "some/folder/", DETAIL_REPORT_NAME_PARAM, "detail_report.csv"))); assertThat(thrown).hasMessageThat().contains("Drive is down"); }
private boolean isAcceptableMediaType(HttpServletRequest servletRequest) { String acceptHeader = servletRequest.getHeader(HttpHeaders.ACCEPT); if (acceptHeader != null) { String[] accepts = acceptHeader.split(","); MediaType acceptableType; for (String mediaTypeItem : accepts) { try { acceptableType = MediaType.parse(mediaTypeItem.trim()); if (JsonApiMediaType.isCompatibleMediaType(acceptableType)) { return true; } } catch (Exception e) { continue; } } } return false; }
@Test public void testSuccess() throws Exception { // Create a dummy file in the local GCS service to read in the servlet. gcsService.createOrReplace( new GcsFilename("mah-buckit", "some/folder/detail_report.csv"), GcsFileOptions.getDefaultInstance(), ByteBuffer.wrap("one,two,three\n".getBytes(UTF_8))); Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of( REGISTRAR_ID_PARAM, "TheRegistrar", GCS_BUCKET_PARAM, "mah-buckit", GCS_FOLDER_PREFIX_PARAM, "some/folder/", DETAIL_REPORT_NAME_PARAM, "detail_report.csv")); verify(driveConnection).createFile( "detail_report.csv", MediaType.CSV_UTF_8, "0B-12345", "one,two,three\n".getBytes(UTF_8)); assertThat(response).containsEntry("driveId", "drive-id-123"); }
@Test public void testSuccess_transientIOException_retries() throws IOException { writeGcsFile( gcsService, new GcsFilename("test-bucket", "results/invoice_details_2017-10_TheRegistrar_hello.csv"), "hola,mundo\n3,4".getBytes(UTF_8)); when(driveConnection.createFile(any(), any(), any(), any())) .thenThrow(new IOException("expected")) .thenReturn("success"); action.run(); verify(driveConnection, times(2)) .createFile( "invoice_details_2017-10_TheRegistrar_hello.csv", MediaType.CSV_UTF_8, "0B-12345", "hola,mundo\n3,4".getBytes(UTF_8)); assertThat(response.getStatus()).isEqualTo(SC_OK); assertThat(response.getContentType()).isEqualTo(MediaType.PLAIN_TEXT_UTF_8); assertThat(response.getPayload()).isEqualTo("Copied detail reports."); }
protected JSONObject queryApi() { String baseUrl = apiAccess.getApiUrl() + requestUrl; log.info("Sending API request [ Method: " + requestMethod + " ] [ URL: " + baseUrl + " ] [ Arguments: " + requiredArgs + " ]"); JSONObject responseJson = null; Stopwatch timer = Stopwatch.createStarted(); try { HttpResponse response = null; if(requestMethod == ERequestMethod.GET) { String url = HttpHelpers.appendUrlParameters(baseUrl, requiredArgs); response = httpClient.doGet(url); } else if(requestMethod == ERequestMethod.POST) { JSONObject postBody = new JSONObject(requiredArgs); response = httpClient.doPost(baseUrl, MediaType.JSON_UTF_8, postBody.toString(), null); } responseJson = HttpClient.getResponseAsJson(response); } catch (HttpClientRequestFailedException e) { log.error("Failed to send request! Error - " + e.getMessage(), e); responseJson = new JSONObject() .put("success", false) .put("exception", e.getMessage()); } log.info("API response received [ Method: " + requestMethod + " ] [ URL: " + baseUrl + " ] [ In Flight: " + timer.stop() + " ]"); return responseJson; }
public static Body getBody(final BodyContainer container, final String contentType) { final MediaType parsedContentType = MediaType.parse(contentType); return container.getBodies().stream() .filter(body -> body.getContentTypes().stream().filter(mediaType -> parsedContentType.is(mediaType)).findFirst().isPresent()) .findFirst() .orElse(null); }
@Nullable public TypeGenModel getReturnType() { Response response = method.getResponses().stream().filter(response1 -> response1.getStatusCode().matches("^2[0-9]{2}$")).findFirst().orElse(null); if (response != null) { Body bodyType = response.getBodies().stream() .filter(bodyType1 -> bodyType1.getContentTypes().size() == 0 || bodyType1.getContentTypes().contains(MediaType.parse("application/json"))) .findFirst().orElse(null); if (bodyType != null && !BuiltinType.of(bodyType.getName()).isPresent()) { return new TypeGenModel(bodyType.getType()); } } return null; }
@Override public Response<SpotifySnapshot> addToTracksPlaylist(String playlistId, String... trackIds) throws Exception { String userId = executeTokenPreflight(); SpotifyTrackUriList trackUriList = new SpotifyTrackUriList(); trackUriList.getUris().addAll(Arrays.asList(trackIds)); String trackUriListMarshal = JacksonMarshaller.marshal(trackUriList); Url url = Url.url(API_BASE_URI, "users", userId, "playlists", playlistId, "tracks"); return webClient.post(url, headers, trackUriListMarshal, MediaType.JSON_UTF_8, SpotifySnapshot.class); }
private boolean requestAccessToken(Map<String, Object> requestFormData) { Url tokenUri = Url.url("https://accounts.spotify.com", "api", "token"); String clientCode = getConsumerKey() + ':' + consumerSecret; String base64ClientCode = Base64.getEncoder().encodeToString(clientCode.getBytes()); HttpFields headers = new HttpFields(); headers.put(HttpHeader.AUTHORIZATION, "Basic " + base64ClientCode); headers.put(WebClient.NO_CACHE_HEADER, "true"); String formDataString = Url.createQueryString(requestFormData); try { Response<OAuthAccessTokenResponse> response = webClient.post(tokenUri, headers, formDataString, MediaType.FORM_DATA, OAuthAccessTokenResponse.class); //noinspection Duplicates if (response.isOK()) { accessToken = response.getData().getAccessToken(); refreshToken = response.getData().getRefreshToken(); timeToLive = response.getData().getExpiresIn(); } else { authenticationError = "Failed exchanging authorization code for access token: " + response.getRawData(); } } catch (Exception e) { authenticationError = e.getMessage(); } return authenticationError == null; }
@Override public <T> Response<T> post(String uri, HttpFields headers, String body, MediaType bodyMediaType, Class<T> expectedModel) throws Exception { Request request = newRequest(uri); request.method(HttpMethod.POST); request.content(new StringContentProvider(body, mediaTypeToCharset(bodyMediaType))); headers = appendDefaultPostHeaders(headers, body, bodyMediaType); return execute(request, headers, expectedModel); }
@Override public <T> Response<T> put(String uri, HttpFields headers, String body, MediaType bodyMediaType, Class<T> expectedModel) throws Exception { Request request = newRequest(uri); request.method(HttpMethod.PUT); request.content(new StringContentProvider(body, mediaTypeToCharset(bodyMediaType))); headers = appendDefaultPostHeaders(headers, body, bodyMediaType); return execute(request, headers, expectedModel); }
@Override public Response<TwitchChannel> updateChannel(long twitchId, String game, String status) throws Exception { TwitchChannelUpdate updateWrapper = new TwitchChannelUpdate(); TwitchChannel updateData = new TwitchChannel(); updateData.setGame(game); updateData.setStatus(status); updateWrapper.setChannel(updateData); String updateDataJson = JacksonMarshaller.marshal(updateWrapper); return webClient.put(Url.url(API_BASE_URI, "channels", twitchId), headers, updateDataJson, MediaType.JSON_UTF_8, TwitchChannel.class); }
@Override public Response<Void> updateChannelCommunities(long twitchId, Set<Community> communities) throws Exception { TwitchCommunitiesUpdate update = new TwitchCommunitiesUpdate(); communities.stream() .limit(3) .map(Community::getTwitchId) .forEach(id -> update.getCommunityIds().add(id)); String body = JacksonMarshaller.marshal(update); return webClient.put(Url.url(API_BASE_URI, "channels", twitchId, "communities"), headers, body, MediaType.JSON_UTF_8, Void.class); }
@Override public Response<Void> subscribeToStreamsWebhookTopic(String localEndpoint, long leaseDurationSeconds, String targetChannelId) throws Exception { HashMap<String, Object> topicQuery = new HashMap<>(); topicQuery.put("user_id", targetChannelId); HashMap<String, Object> query = new HashMap<>(); query.put("hub.callback", webhookCallbackUrl + localEndpoint); query.put("hub.mode", "subscribe"); query.put("hub.topic", Url.url(API_BASE_URI, "streams").withQuery(topicQuery)); query.put("hub.lease_seconds", leaseDurationSeconds); return webClient.post(Url.url(API_BASE_URI, "webhooks", "hub").withQuery(query), headers, "", MediaType.PLAIN_TEXT_UTF_8, Void.class); }
@Override public Response<Void> subscribeToFollowersWebhookTopic(String localEndpoint, long leaseDurationSeconds, String targetChannelId) throws Exception { HashMap<String, Object> topicQuery = new HashMap<>(); topicQuery.put("to_id", targetChannelId); HashMap<String, Object> query = new HashMap<>(); query.put("hub.callback", webhookCallbackUrl + localEndpoint); query.put("hub.mode", "subscribe"); query.put("hub.topic", Url.url(API_BASE_URI, "users", "follows").withQuery(topicQuery)); query.put("hub.lease_seconds", leaseDurationSeconds); return webClient.post(Url.url(API_BASE_URI, "webhooks", "hub").withQuery(query), headers, "", MediaType.PLAIN_TEXT_UTF_8, Void.class); }
private List<MediaType> getContentTypes(String contentTypeString) { return Stream.of(contentTypeString.split(MEDIA_TYPE_LIST_SEPARATOR)) .filter(Objects::nonNull) .map(mediaType -> mediaType.replaceAll("\\s+","")) .map(MediaType::parse) .collect(toList()); }
public ApiGatewayProxyResponse handle(ApiGatewayProxyRequest request, List<MediaType> contentTypes, List<MediaType> acceptTypes, Context context) throws Exception { ApiGatewayProxyResponse response; try { ContentTypeMapper<Input> contentTypeMapper = getMapper(contentTypes, perContentTypeMap, "Content-Types %s are not supported"); logger.debug("Content-Type mapper found."); AcceptMapper<Output> acceptMapper = getMapper(acceptTypes, perAcceptMap, "Accept types %s are not supported"); logger.debug("Accept mapper found."); Map<String, String> headers = request.getHeaders().entrySet().stream() .collect(toMap( entry -> entry.getKey().toLowerCase(), entry -> entry.getValue().toLowerCase() )); if (!headers.keySet().containsAll(requiredHeaders)) { Collection<String> missingHeaders = new HashSet<>(requiredHeaders); missingHeaders.removeAll(headers.keySet()); ApiGatewayProxyResponse missingRequiredHeaders = new ApiGatewayProxyResponseBuilder() .withStatusCode(BAD_REQUEST.getStatusCode()) .withBody(String.format("The following required headers are not present: %s", String.join(", ", missingHeaders))) .build(); throw new LambdaException(missingRequiredHeaders); } logger.debug(String.format("Mapping input (%s): %s", contentTypeMapper.getClass(), request)); Input input = requireNonNull(contentTypeMapper.toInput(request, context)); logger.debug(String.format("Handling input (%s): %s", this.getClass(), input)); Output output = requireNonNull(handle(input)); logger.debug(String.format("Mapping output (%s): %s", acceptMapper.getClass(), output)); response = requireNonNull(acceptMapper.outputToResponse(output)); logger.debug("Successfully created response: " + response); } catch(Exception e) { response = handleException(e); } return response; }
@Test public void shouldReturnUnsupportedMediaTypeIfNoContentTypeMapperRegistered() throws Exception { List<MediaType> contentTypes = asList(CONTENT_TYPE_1, CONTENT_TYPE_2); ApiGatewayProxyResponse response = sampleMethodHandler.handle(request, contentTypes, singletonList(ACCEPT_TYPE_1), context); assertThat(response.getStatusCode()).isEqualTo(UNSUPPORTED_MEDIA_TYPE.getStatusCode()); assertThat(response.getBody()).contains(String.format("Content-Types %s are not supported", contentTypes)); }
@Test public void shouldReturnUnsupportedMediaTypeIfNoAcceptMapperRegistered() throws Exception { sampleMethodHandler.registerPerContentType(CONTENT_TYPE_1, contentTypeMapper1); List<MediaType> acceptTypes = asList(ACCEPT_TYPE_1, ACCEPT_TYPE_2); ApiGatewayProxyResponse response = sampleMethodHandler.handle(request, singletonList(CONTENT_TYPE_1), acceptTypes, context); assertThat(response.getStatusCode()).isEqualTo(UNSUPPORTED_MEDIA_TYPE.getStatusCode()); assertThat(response.getBody()).contains(String.format("Accept types %s are not supported", acceptTypes)); }
@Test public void shouldParseSeparatedContentTypes() throws Exception { String someHeader = "someHeader"; String someValue = "someValue"; Map<String, String> requestHeaders = new ConcurrentHashMap<>(); requestHeaders.put(CONTENT_TYPE, CONTENT_TYPE_1.toString() + ", " + CONTENT_TYPE_2.toString()); requestHeaders.put(ACCEPT, ACCEPT_TYPE_1.toString() + ", " + ACCEPT_TYPE_2.toString()); requestHeaders.put(someHeader, someValue); ApiGatewayProxyRequest request = new ApiGatewayProxyRequestBuilder() .withHttpMethod(METHOD) .withHeaders(requestHeaders) .withContext(context) .build(); Map<String, String> responseHeaders = new ConcurrentHashMap<>(); responseHeaders.put(someHeader, someValue); List<MediaType> contentTypes = asList(CONTENT_TYPE_1, CONTENT_TYPE_2); List<MediaType> acceptTypes = asList(ACCEPT_TYPE_1, ACCEPT_TYPE_2); when(methodHandler.handle(eq(request), eq(contentTypes), eq(acceptTypes), eq(context))) .thenReturn(new ApiGatewayProxyResponse.ApiGatewayProxyResponseBuilder() .withStatusCode(OK.getStatusCode()) .withHeaders(responseHeaders) .build()); handler.registerMethodHandler(METHOD, c -> methodHandler); handler.handleRequest(request, context); verify(methodHandler).handle(request, contentTypes, acceptTypes, context); }
@Test public void shouldMapContentTypeParameters() throws Exception { String someHeader = "someHeader"; String someValue = "someValue"; Map<String, String> requestHeaders = new ConcurrentHashMap<>(); MediaType contentType = CONTENT_TYPE_1.withParameter("q", "0.9"); contentType = contentType.withParameter("b", "hello"); String mediaTypeParametersString = contentType.parameters().asMap().entrySet().stream() .map(entry -> ";" + entry.getKey() + "=" + entry.getValue().iterator().next()) .collect(joining("")); requestHeaders.put(CONTENT_TYPE, CONTENT_TYPE_1.toString() + mediaTypeParametersString + ", " + CONTENT_TYPE_2.toString()); requestHeaders.put(ACCEPT, ACCEPT_TYPE_1.toString() + ", " + ACCEPT_TYPE_2.toString()); requestHeaders.put(someHeader, someValue); ApiGatewayProxyRequest request = new ApiGatewayProxyRequestBuilder() .withHttpMethod(METHOD) .withHeaders(requestHeaders) .withContext(context) .build(); Map<String, String> responseHeaders = new ConcurrentHashMap<>(); responseHeaders.put(someHeader, someValue); List<MediaType> contentTypes = asList(contentType, CONTENT_TYPE_2); List<MediaType> acceptTypes = asList(ACCEPT_TYPE_1, ACCEPT_TYPE_2); when(methodHandler.handle(request, contentTypes, acceptTypes, context) ) .thenReturn(new ApiGatewayProxyResponse.ApiGatewayProxyResponseBuilder() .withStatusCode(OK.getStatusCode()) .withHeaders(responseHeaders) .build()); handler.registerMethodHandler(METHOD, c -> methodHandler); handler.handleRequest(request, context); verify(methodHandler).handle(request, contentTypes, acceptTypes, context); }
@Test public void corsSupportShouldReturnBadRequestWhenRequestDoesNotSpecifyMethod() { LambdaProxyHandler<Configuration> handlerWithCorsSupport = new TestLambdaProxyHandler(true); Collection<String> supportedMethods = singletonList("POST"); MediaType mediaType1 = MediaType.create("application", "type1"); MediaType mediaType2 = MediaType.create("application", "type2"); MediaType mediaType3 = MediaType.create("application", "type3"); MediaType mediaType4 = MediaType.create("application", "type4"); Collection<String> requiredHeaders = Stream.of("header1", "header2") .map(Util::randomizeCase) .collect(toList()); SampleMethodHandler sampleMethodHandler = new SampleMethodHandler(requiredHeaders); sampleMethodHandler.registerPerAccept(mediaType1, mock(AcceptMapper.class)); sampleMethodHandler.registerPerAccept(mediaType2, mock(AcceptMapper.class)); sampleMethodHandler.registerPerAccept(mediaType3, mock(AcceptMapper.class)); sampleMethodHandler.registerPerContentType(mediaType4, mock(ContentTypeMapper.class)); supportedMethods.forEach(method -> handlerWithCorsSupport.registerMethodHandler( method, c -> sampleMethodHandler )); Map<String, String> headers = new ConcurrentHashMap<>(); Collection<String> requestHeaders = requiredHeaders.stream() .map(Util::randomizeCase) .collect(toSet()); requestHeaders.add("header3"); headers.put(ACCESS_CONTROL_REQUEST_HEADERS, String.join(", ", requestHeaders)); headers.put("Content-Type", mediaType4.toString()); headers.put("Origin", "http://127.0.0.1:8888"); randomiseKeyValues(headers); ApiGatewayProxyRequest request = new ApiGatewayProxyRequestBuilder() .withHttpMethod("OPTIONS") .withHeaders(headers) .withContext(context) .build(); ApiGatewayProxyResponse response = handlerWithCorsSupport.handleRequest(request, context); assertThat(response.getStatusCode()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(response.getBody()).contains(String.format("Options method should include the %s header", ACCESS_CONTROL_REQUEST_METHOD.toLowerCase())); }