2023-12-05-TIL
2023-12-05-TIL
Today I Learned
HTTP 11 Processor [] Character
Spring Boot(내장 Tomcat) 로그에 Http11Processor가 Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986이라는 오류를 남기는 경우가 있다. FusionAuth 이슈가 같은 메시지를 다룬다. 쿼리 스트링에 [, ], {, | 같은 문자를 퍼센트 인코딩하지 않고 그대로 보냈을 때 Tomcat이 요청을 거부한 것이다. ids[]=1처럼 배열 파라미터를 대괄호로 보내는 클라이언트에서 흔히 생긴다.
Tomcat HTTP 커넥터 문서는 relaxedQueryChars 속성을 설명하면서, HTTP/1.1 명세는 이런 문자를 쿼리 스트링에서 %nn으로 인코딩하도록 요구하지만 주요 브라우저를 포함한 많은 클라이언트가 이를 지키지 않는다고 적는다. 이 속성에 " < > [ \ ] ^ { | } 중 허용할 문자를 지정하면 Tomcat이 거부하지 않는다. 경로에는 relaxedPathChars`가 따로 있다. 다만 서버 설정을 푸는 것보다 클라이언트가 인코딩해서 보내게 하는 것이 근본적인 해결이다. |
비슷하게 보이는 Invalid character found in method name. HTTP method names must be tokens는 다른 문제다. Stack Overflow 질문의 답변처럼 HTTP 포트로 HTTPS 요청이 들어와 TLS 바이트를 HTTP 요청줄로 읽으려 할 때 주로 난다.
- https://github.com/FusionAuth/fusionauth-issues/issues/635
- https://community.f5.com/t5/technical-forum/error-processing-http-request-header/td-p/94509
- https://stackoverflow.com/questions/49273847/springboot-error-parsing-http-request-header
- https://stackoverflow.com/questions/40881080/handling-special-characters-in-rest-api
Encoding as Base64 in Java
Java 8부터는 표준 라이브러리의 java.util.Base64를 쓰면 된다. 인코더와 디코더가 세 종류다.
Base64.getEncoder(): RFC 4648의 기본 알파벳을 쓴다.Base64.getUrlEncoder():+,/대신-,_를 쓰는 URL·파일명 안전 알파벳이다.Base64.getMimeEncoder(): MIME 형식으로, 일정 길이마다 줄바꿈을 넣는다.
1
2
String encoded = Base64.getEncoder().encodeToString("hello".getBytes(StandardCharsets.UTF_8));
byte[] decoded = Base64.getDecoder().decode(encoded);
Spring의 Base64Utils도 같은 일을 했지만, Spring Framework 6.0 Javadoc에서 제거 예정(deprecated for removal)으로 표시되어 있다. 새 코드에서는 java.util.Base64를 쓰는 편이 맞다.
- https://stackoverflow.com/questions/13109588/encoding-as-base64-in-java
- https://www.baeldung.com/java-base64-encode-and-decode
- https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/util/Base64Utils.html
- https://stackoverflow.com/questions/10416493/base64-encoding-for-the-log-in-with-the-spring-mvc
Extracting Video Metadata using Lambda and Mediainfo
업로드된 영상의 길이, 코덱, 해상도 같은 기술 메타데이터를 뽑는 방법이다. AWS Compute 블로그는 오픈소스 도구 MediaInfo를 Lambda에서 돌리는 구성을 소개한다. 핵심은 파일 전체를 내려받지 않는다는 점이다.
- S3에 영상이 올라오면 이벤트로 Lambda가 실행된다.
- Lambda가 그 객체의 서명된 URL을 만들어 MediaInfo에 넘긴다.
- MediaInfo는 URL에서 메타데이터에 필요한 최소한의 바이트만 받아 분석하고, XML로 결과를 낸다.
글은 MediaInfo의 장점으로 URL 입력 지원, 풍부한 메타데이터, XML 출력, 그리고 의존성을 하나의 실행 파일에 넣는 정적 컴파일을 들고, 이 정적 바이너리를 Lambda에 넣기 위해 Amazon Linux용으로 컴파일하는 과정을 보여 준다. 실행 환경 선택은 Lambda 런타임 문서를 참고한다.
- https://aws.amazon.com/ko/blogs/compute/extracting-video-metadata-using-lambda-and-mediainfo/
- https://mediaarea.net/en/MediaInfo/Download/Source
- https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html
- https://www.youtube.com/watch?v=OJrxbr9ebDE
- https://www.youtube.com/watch?v=3Ar1ABlD_Vs
- https://www.youtube.com/watch?v=IgAE-ycnb94
- https://www.youtube.com/watch?v=UsaiOEFdfs0
Extract Duration from Mediainfo
S3 자체는 영상 길이를 알지 못한다. get-object-attributes는 HeadObject와 ListParts의 정보를 한 번에 돌려주는 API지만, 여기서 얻는 것은 크기, ETag, 체크섬, 파트 정보 같은 객체 수준의 속성이다. 그래서 길이는 위처럼 MediaInfo 같은 도구로 파일 내용을 읽어 구해야 한다. 한 번 구한 길이는 다시 계산하지 않도록 DB에 저장하거나, 업로드할 때 사용자 정의 메타데이터(x-amz-meta-*)로 객체에 붙여 둘 수 있다. 링크 중 aws s3 cp로 메타데이터를 붙이는 질문이 두 번째 방법을 다룬다.
목록 끝의 Cloudflare Radar 2023 연말 리뷰와 Lombok 상속 글은 이 주제와 직접 관련은 없는 참고 링크다.
- https://stackoverflow.com/questions/33433269/get-the-duration-of-videos-stored-in-a-s3-bucket
- https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object-attributes.html
- https://stackoverflow.com/questions/40626967/aws-s3-cli-cp-file-and-add-metadata
- https://stackoverflow.com/questions/7446266/get-video-duration-of-file-hosted-on-amazon-s3
- https://blog.cloudflare.com/radar-2023-year-in-review/
- https://medium.com/@sergio-sanchez/inheritance-with-lombok-annotations-in-java-springboot-f32a2d873fff
12factor app
The Twelve-Factor App은 서비스형 소프트웨어(SaaS)를 만들 때 따를 열두 가지 원칙을 정리한 방법론이다. 언어나 백엔드 서비스 종류와 상관없이 적용할 수 있다고 소개한다. 몇 가지만 추리면 이렇다.
- Codebase: 버전 관리되는 코드베이스 하나에서 여러 배포가 나온다.
- Config: 설정은 코드가 아니라 환경 변수에 둔다.
- Backing services: DB, 큐, 캐시 같은 지원 서비스를 연결된 자원으로 다뤄 설정만으로 교체할 수 있게 한다.
- Build, release, run: 빌드와 실행 단계를 엄격히 분리한다.
- Processes: 애플리케이션을 상태 없는 프로세스로 실행하고, 상태는 지원 서비스에 둔다.
- Concurrency: 프로세스 모델로 수평 확장한다.
컨테이너와 쿠버네티스 환경에서 당연하게 여기는 관행 대부분이 이 원칙들과 겹친다.
- https://12factor.net/
댓글
아직 댓글이 없습니다