홈 › 실무 확장 › 03 / 22

파일 업로드/다운로드 서버 (HttpServer)

섹션 7진행 0 / 22

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 인젝션이 왜 파라미터 바인딩으로 막히는지 봅니다.