파일 업로드/다운로드 서버 (HttpServer)
7. 정리
multipart/form-data는 경계 문자열로 파트를 나눈 바이트열이다. 길이 필드가 없으므로 파서는\r\n--boundary를 스트림에서 찾아야 하고, 버퍼 끝의delimiter.length - 1바이트는 판정을 보류해야 경계를 놓치지 않는다.- 업로드 본문은 절대 통째로 메모리에 올리지 않는다. 파트
InputStream을 디스크나 파서로 바로 흘려보내고, 크기 제한은 헤더(1차)와 읽는 도중 카운트(2차) 두 곳에서 건다. - 사용자 입력은 전부 의심한다. 파일명은 경로 제거 후 표시용으로만, 저장명은 UUID. 확장자는 화이트리스트, 내용은 매직 넘버, 응답 MIME 은 서버가 결정. 다운로드 id 는 형식 검사.
- 저장은
.part임시 파일 → 검증 통과 →ATOMIC_MOVE. 실패하면 임시 파일을 지운다. - 다운로드는
Content-Type+Content-Length+Content-Disposition(filename과filename*=UTF-8''둘 다) +Accept-Ranges. 단일 Range 는skipNBytes+ 길이 제한 복사로 206. HttpServer는 실행기를 반드시 지정(JDK 21 은 가상 스레드). 거절 응답 전에는 남은 본문을 소비한다. 응답 본문은 길이를 맞추고 닫는다.- Spring 의
MultipartFile,max-file-size,ContentDisposition.attachment().filename(name, UTF_8)은 이 레슨의 파서·크기 검사·헤더 조립을 그대로 감싼 것이다. 이제 설정값이 어느 단계에서 동작하는지 알고 쓸 수 있다.
다음 레슨 04. JDBC 기초와 트랜잭션 에서는 업로드해서 검증한 회원 명단을 실제 DB(H2)에 넣습니다. PreparedStatement 배치 insert 와 트랜잭션으로 "1,000건 중 1건 실패 시 전체 롤백" 을 구현하고, SQL 인젝션이 왜 파라미터 바인딩으로 막히는지 봅니다.