1 /* 2 * Copyright 2020 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.binder; 18 19 import com.google.common.base.Preconditions; 20 import io.grpc.ExperimentalApi; 21 22 /** 23 * Contains the policy for accepting inbound parcelable objects. 24 * 25 * <p>Since parcelables are generally error prone and parsing a parcelable can have unspecified 26 * side-effects, their use is generally discouraged. Some use cases require them though (E.g. when 27 * dealing with some platform-defined objects), so this policy allows them to be supported. 28 * 29 * <p>Parcelables can arrive as RPC messages, or as metadata values (in headers or footers). The 30 * default is to reject both cases, failing the RPC with a PERMISSION_DENED status code. This policy 31 * can be updated to accept one or both cases. 32 */ 33 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022") 34 public final class InboundParcelablePolicy { 35 36 /** The maximum allowed total size of Parcelables in metadata. */ 37 public static final int MAX_PARCELABLE_METADATA_SIZE = 32 * 1024; 38 39 public static final InboundParcelablePolicy DEFAULT = 40 new InboundParcelablePolicy(false, false, MAX_PARCELABLE_METADATA_SIZE); 41 42 private final boolean acceptParcelableMetadataValues; 43 private final boolean acceptParcelableMessages; 44 private final int maxParcelableMetadataSize; 45 InboundParcelablePolicy( boolean acceptParcelableMetadataValues, boolean acceptParcelableMessages, int maxParcelableMetadataSize)46 private InboundParcelablePolicy( 47 boolean acceptParcelableMetadataValues, 48 boolean acceptParcelableMessages, 49 int maxParcelableMetadataSize) { 50 this.acceptParcelableMetadataValues = acceptParcelableMetadataValues; 51 this.acceptParcelableMessages = acceptParcelableMessages; 52 this.maxParcelableMetadataSize = maxParcelableMetadataSize; 53 } 54 shouldAcceptParcelableMetadataValues()55 public boolean shouldAcceptParcelableMetadataValues() { 56 return acceptParcelableMetadataValues; 57 } 58 shouldAcceptParcelableMessages()59 public boolean shouldAcceptParcelableMessages() { 60 return acceptParcelableMessages; 61 } 62 getMaxParcelableMetadataSize()63 public int getMaxParcelableMetadataSize() { 64 return maxParcelableMetadataSize; 65 } 66 newBuilder()67 public static Builder newBuilder() { 68 return new Builder(); 69 } 70 71 /** A builder for InboundParcelablePolicy. */ 72 public static final class Builder { 73 private boolean acceptParcelableMetadataValues = DEFAULT.acceptParcelableMetadataValues; 74 private boolean acceptParcelableMessages = DEFAULT.acceptParcelableMessages; 75 private int maxParcelableMetadataSize = DEFAULT.maxParcelableMetadataSize; 76 77 /** Sets whether the policy should accept parcelable metadata values. */ setAcceptParcelableMetadataValues(boolean acceptParcelableMetadataValues)78 public Builder setAcceptParcelableMetadataValues(boolean acceptParcelableMetadataValues) { 79 this.acceptParcelableMetadataValues = acceptParcelableMetadataValues; 80 return this; 81 } 82 83 /** Sets whether the policy should accept parcelable messages. */ setAcceptParcelableMessages(boolean acceptParcelableMessages)84 public Builder setAcceptParcelableMessages(boolean acceptParcelableMessages) { 85 this.acceptParcelableMessages = acceptParcelableMessages; 86 return this; 87 } 88 89 /** 90 * Sets the maximum allowed total size of parcelables in metadata. 91 * 92 * @param maxParcelableMetadataSize must not exceed {@link #MAX_PARCELABLE_METADATA_SIZE} 93 */ setMaxParcelableMetadataSize(int maxParcelableMetadataSize)94 public Builder setMaxParcelableMetadataSize(int maxParcelableMetadataSize) { 95 Preconditions.checkArgument( 96 maxParcelableMetadataSize <= MAX_PARCELABLE_METADATA_SIZE, 97 "Parcelable metadata size can't exceed MAX_PARCELABLE_METADATA_SIZE."); 98 this.maxParcelableMetadataSize = maxParcelableMetadataSize; 99 return this; 100 } 101 build()102 public InboundParcelablePolicy build() { 103 return new InboundParcelablePolicy( 104 acceptParcelableMetadataValues, acceptParcelableMessages, maxParcelableMetadataSize); 105 } 106 } 107 } 108