'gRPC file upload detect content type of file on server
I am trying to do a file upload on via client streaming gRPC. Sending a file via streaming from client to server.
I have implemented this code for server side which receives the files. I would like the server to only accept the files of a specific type lets say image files of the format .png ,.bmp,.jpeg and many more may be.
So the client shouldn't be able to upload any other type of file other than the ones listed above.
How do I achieve this in gRPC ?
For the file upload sample I have referred this link
Server side code to process the request,
public class FileUploadService extends FileServiceGrpc.FileServiceImplBase {
private static final Path SERVER_BASE_PATH = Paths.get("src/test/resources/output");
@Override
public StreamObserver<FileUploadRequest> upload(StreamObserver<FileUploadResponse> responseObserver) {
return new StreamObserver<FileUploadRequest>() {
// upload context variables
OutputStream writer;
Status status = Status.IN_PROGRESS;
@Override
public void onNext(FileUploadRequest fileUploadRequest) {
try{
if(fileUploadRequest.hasMetadata()){
writer = getFilePath(fileUploadRequest);
}else{
writeFile(writer, fileUploadRequest.getFile().getContent());
}
}catch (IOException e){
this.onError(e);
}
}
@Override
public void onError(Throwable throwable) {
status = Status.FAILED;
this.onCompleted();
}
@Override
public void onCompleted() {
closeFile(writer);
status = Status.IN_PROGRESS.equals(status) ? Status.SUCCESS : status;
FileUploadResponse response = FileUploadResponse.newBuilder()
.setStatus(status)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
};
}
private OutputStream getFilePath(FileUploadRequest request) throws IOException {
var fileName = request.getMetadata().getName() + "." + request.getMetadata().getType();
return Files.newOutputStream(SERVER_BASE_PATH.resolve(fileName), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
private void writeFile(OutputStream writer, ByteString content) throws IOException {
writer.write(content.toByteArray());
writer.flush();
}
private void closeFile(OutputStream writer){
try {
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Proto file
package file;
option java_package = "com.vinsguru.io";
option java_multiple_files = true;
message MetaData {
string name = 1;
string type = 2;
}
message File {
bytes content = 1;
}
enum Status {
PENDING = 0;
IN_PROGRESS = 1;
SUCCESS = 2;
FAILED = 3;
}
message FileUploadRequest {
oneof request {
MetaData metadata = 1;
File file = 2;
}
}
message FileUploadResponse {
string name = 1;
Status status = 2;
}
service FileService {
rpc upload(stream FileUploadRequest) returns(FileUploadResponse);
}
Solution 1:[1]
Assuming you don't want to just trust the file extension of the file, you will need to probe the file contents to determine its type. If you trust your client, you could consider just using FileTypeDetector.
If you don't trust your client, then your server must inspect the incoming file data and cancel the transfer if it detects an unsupported file type. To do this you could look at incorporating e.g. Apache Tika to your server.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Terry |