[Notice] Announcing the End of Demo Server [Read me]

doc/uploader: How uploader works in server.
@270b1629c0928609751df061fcfe45e129280d54
+++ docs/technical/uploader-server-internal.md
... | ... | @@ -0,0 +1,87 @@ |
1 | +이 문서는 파일 업로드 기능의 서버측 동작을 설명한다. | |
2 | + | |
3 | +개요 | |
4 | +---- | |
5 | + | |
6 | +Hive의 파일 업로드 및 다운로드 기능은 HTTP 요청과 응답을 통해 이루어진다. 요청은 `controller.AttachmentApp`이 `models.Attachment`를 이용하여 처리한다. | |
7 | + | |
8 | +파일을 업로드하거나 다운로드하는 요청은 conf/routes 파일에 다음과 같이 정의되어 있다. | |
9 | + | |
10 | + GET /files controllers.AttachmentApp.getFileList() | |
11 | + POST /files controllers.AttachmentApp.newFile() | |
12 | + GET /files/:id controllers.AttachmentApp.getFile(id: Long) | |
13 | + GET /files/:id/? controllers.AttachmentApp.getFile(id: Long) | |
14 | + POST /files/:id/? controllers.AttachmentApp.deleteFile(id: Long) | |
15 | + POST /files/:id controllers.AttachmentApp.deleteFile(id: Long) | |
16 | + | |
17 | +파일 업로드 | |
18 | +----------- | |
19 | + | |
20 | +/files로 POST 요청을 보내서 파일을 업로드 할 수 있다. 파일 업로드의 HTTP 요청은 인코딩이 `multipart/form-data`인 HTML form으로 파일을 `filePath`라는 이름의 file 타입 input element를 통해 submit하는 것과 같게 하면 된다. | |
21 | + | |
22 | +업로드된 파일은 사용자의 임시 저장공간에 보존되며, 그 사용자와 사이트 관리자를 제외한 다른 사용자의 접근은 금지된다. (일반적인 첨부파일의 경우, 첨부한 대상에 대한 읽기 권한이 있다면 첨부파일에도 읽기 권한이 있는 것으로 간주한다는 것을 생각하면 이 동작은 다소 예외적인 것이다. 실제 동작이 궁금하다면 `utils.AccessControl.isGlobalResourceAllowed` 메소드를 보라) | |
23 | + | |
24 | +임시 저장된 파일을 다른 리소스(이슈, 포스팅 등)에 첨부하려면, models.Attachment.attachFiles 메소드를 이용한다. 이 메소드는 사용자의 임시저장공간에 담겨있든 모든 파일을 특정 리소스에 첨부한다. | |
25 | + | |
26 | +사용자의 임시 저장공간을 거치는 것을 생략하고 바로 파일을 리소스에 첨부하는 것도 가능한데, 이를 위해서는 models.Attachment.store 메소드를 호출한다. 프로젝트의 로고를 설정하는 기능의 경우 이 방법을 사용한다. | |
27 | + | |
28 | +파일이 정상적으로 업로드되었다면, 서버는 업로드된 파일에 대한 메타데이터를 다음과 같이 json 형식으로 반환한다. | |
29 | + | |
30 | + { | |
31 | + "id":"193", | |
32 | + "name":"스크린샷, 2013-03-08 031557.png", | |
33 | + "url":"/files/193", | |
34 | + "mimeType":"image/png", | |
35 | + "size":"154440" | |
36 | + } | |
37 | + | |
38 | +주의: 위 응답은, 클라이언트의 유저에이전트가 인터넷 익스플로러인 경우, 실제로는 본문이 json 형식임에도 불구하고 Content-Type이 text/html로 설정되어 반환된다. 이유는 Content-Type을 application/json로 하여 응답하면, 인터넷 익스플로러는 무조건 다운로드 받으려 시도하기 때문에, 이 응답을 자바스크립트로 처리하게 할 수 없기 때문이다. | |
39 | + | |
40 | +예외처리 | |
41 | +* 사용자가 로그인을 하지 않은 경우, 403 Forbidden이 반환된다. | |
42 | + | |
43 | +파일 업로드에 대한 실제 코드는 models.AttachmentApp.newFile 메소드에서 확인할 수 있다. | |
44 | + | |
45 | +파일 다운로드 | |
46 | +------------- | |
47 | + | |
48 | +/files/:id로 GET 요청을 보내면 id가 :id인 파일을 다운로드 할 수 있다. | |
49 | + | |
50 | +주의: 파일명은 RFC 2231에 따라 인코딩된다. 따라서 인터넷 익스플로러 8 이하 버전, 사파리 5 이하 버전에서는 웹브라우저가 파일 이름을 올바르게 해석하지 못해 오동작이 발생할 수 있다. | |
51 | + | |
52 | +예외처리 | |
53 | +* 파일이 첨부된 리소스에 대한 읽기 권한이 없는 경우 403 Forbidden이 반환된다. | |
54 | +* :id에 해당하는 파일이 존재하지 않는 경우 404 Not Found가 반환된다. | |
55 | + | |
56 | +파일 다운로드에 대한 실제 코드는 models.AttachmentApp.getFile 에서 확인할 수 있다. | |
57 | + | |
58 | +파일 목록 | |
59 | +--------- | |
60 | + | |
61 | +/files로 GET 요청을 보내면 특정 리소스에 첨부된 파일들의 목록을 얻을 수 있다. 이 HTTP 요청은, 인코딩이 application/x-www-form-urlencoded 이고, 이름이 containerType과 containerId인 input element를 포함한 HTML form을 submit 했을 때의 요청과 같다. `containerType`의 값은 첨부파일을 얻을 리소스의 타입, `containerId`의 값은 첨부파일을 얻을 리소스의 아이디이다. | |
62 | + | |
63 | +첨부파일의 목록은 다음의 예와 같이 json 형식으로 반환된다. (요청의 Accept 헤더는 무시한다) | |
64 | + | |
65 | + { | |
66 | + "tempFiles":[], | |
67 | + "attachments":[ | |
68 | + { | |
69 | + "id":"201", | |
70 | + "name":"스크린샷, | |
71 | + 2013-03-09 012043.png", | |
72 | + "url":"/files/201", | |
73 | + "mimeType":"image/png", | |
74 | + "size":"267068" | |
75 | + }, | |
76 | + { | |
77 | + "id":"202", | |
78 | + "name":"스크린샷, | |
79 | + 2013-03-15 225249.png", | |
80 | + "url":"/files/202", | |
81 | + "mimeType":"image/png", | |
82 | + "size":"277671" | |
83 | + } | |
84 | + ] | |
85 | + } | |
86 | + | |
87 | +파일 목록에 대한 실제 코드는 models.AttachmentApp.getFileList 에서 확인할 수 있다. |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?