반응형

Golang을 사용하다보면 임시 구조체를 사용하면 생각보다 유연하고 편하게 작업 할 수 있다.

 

함수 내에 스택에 할당됨으로 함수내에서만 사용가능하다. 일반적으로 사용하는 구조체와의 차이점이라고 할 수 있다.

 

type Test struct{
 TestId string
}

func Tt(){
 t := &Test{}
}

일반적으로는 위와같은 방법으로 구조체를 생성하고 사용하지만 다음과 같이 사용하면 구조체를 임시로 사용가능하다.

 

func Tt(){
 var Test struct{
    TestId String
 }
 
 t := &Test{}
 
}

위와 같이 함수내에 구조체를 정의 하여 사용할 수 있고, 슬라이스로도 사용이 가능하다.

 

활용방안은 데이터베이스를 사용할때 ORM 은 각 테이블에 관한 정보는 제대로 가져오나 (grom) join 과 같은 상황에선 제대로 결과 값을 가져오지 못하는 경우가 발생이 되는데 이럴때 임시 구조체를 사용한다면 원하는 결과 값을 보다 쉽게 가져 올 수 있다.

 

gorm은 다음 포스팅 부터 연재 하는걸로~

반응형

'개발 > Go' 카테고리의 다른 글

[문법] 임시 구조체  (0) 2022.05.13
[gRPC/gRPC GATEWAY] json 필드 이름 proto 타입이름과 다를때  (0) 2022.05.12
[gRPC] message oneof 사용  (0) 2022.05.11
반응형

사실상 gRPC를 사용한다면 필드이름이랑 json으로 변환할때 큰 신경을 안써도 된다. 적어도 내가 하는 프로젝트에선

 

하지만 gRPC를 HTTP 통신을 하고싶다면 요청은 큰 문제가 없지만 응답을 받을때 우리가 예상한 키 값으로 넘어 오지 않는다.

 

가령

 

message Test{
 string first_name = 1; ==> JSON firstName
 string last_name = 2;  ==> JSON lastName
}

위와 같이 _ 가 camelCase형식으로 바뀌디 때문에 예상한 응답이 아닐 경우가 있다.

 

이럴때는 gRPC gateway 의 ServeMux에 옵션을 추가해주면 해결된다.

 

gwMux := runtime.NewServeMux(
    runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
        MarshalOptions: protojson.MarshalOptions{
            UseProtoNames: true,
        },
    }))

 

WithMarshalerOption함수를 사용하여 옵션을 추가해 주면된다.

 

사용하려는 MIME에 runtime.JsonPB{} 구조체에 MarshalOptions 의 UseProtoNames를 true로 설정해 주면 proto에 정의된 필드 이름대로 JSON 키 값이 출력된다.

반응형

'개발 > Go' 카테고리의 다른 글

[문법] 임시 구조체  (0) 2022.05.13
[gRPC/gRPC GATEWAY] json 필드 이름 proto 타입이름과 다를때  (0) 2022.05.12
[gRPC] message oneof 사용  (0) 2022.05.11
반응형

gRPC 는 통신을 할때 protobuf 를 사용하는데 gRPC를 사용하기전 tcp 통신으로 protobuf를 파이썬에서 만 사용해봤었다.

 

이번 프로젝트에서 gRPC를 사용하게 되면서 gRPC Gateway 통신에도 oneof 를 사용해 보려고 한다.

 

아직 protobuf 자체를 Go에서 사용해 본것이 아니고 gRPC에서만 테스트한 예제이다.

 

message Test{
 int64 admin_id = 1;
 int64 user_id = 2;
}

만약 위와같은 필드를 사용하는데 둘중 하나의 필드만 사용한다면 oneof 키워드를 사용할 수 있다.

 

message Test{
 oneof id_oneof{
   int64 admin_id = 1;
   int64 user_id = 2;
 }
}

그렇다면 Go에서 위와 같은 oneof 처리를 어떻게 하면 좋을까?

 

Go에서 gRPC는 Get 함수를 자동으로 지원해 줌으로 GetAdminId() 와 GetUserId()를 사용하여 값을 가져 올 수 있는데 위 함수로 결과 값을 가져와 처리하기에는 oneof를 사용하는 의미가 없어진다. 

 

사실 oneof를 사용하는 이유가 여러 필드 중 1개만 사용함으로써 Serialize된 데이터 패킷의 수도 줄일 수 있는 장점이 있다. 그렇기에 사용 할 수 있는 부분은 사용하는 것이 이득이라 생각한다.

 

대게 많이 사용하는 방법이 무엇이 있을까 찾아봤는데 마땅히 없어 생각해본 처리 방법이다.

 

더 나은 방법이 있다면 답글 부탁 드리겠습니다.

func (x *XX) XXXX(ctx context.Context, request *pb.Test) (*pb.Test, error){
 switch v := request.GetIdOneOf().(type){
 case *pb.Test_AdminId:
  fmt.Println(v)
 case *pb.Test_UserId:
  fmt.Println(v)
 
 }
 
 ... 중간 생략
 
}

내가 생각한것은 oneof를 가져와서 직접 타입 체크를 한다면 oneof를 효과적으로 사용 할 수 있는 것 같다.

반응형

'개발 > Go' 카테고리의 다른 글

[문법] 임시 구조체  (0) 2022.05.13
[gRPC/gRPC GATEWAY] json 필드 이름 proto 타입이름과 다를때  (0) 2022.05.12
[gRPC] message oneof 사용  (0) 2022.05.11
반응형

react 개발 블로그 테스트

반응형

'개발 > React' 카테고리의 다른 글

react  (0) 2020.09.25
반응형

C 개발 블로그 테스트

반응형

'개발 > C' 카테고리의 다른 글

C  (0) 2020.09.25
반응형

제나름 대로 사용하기 위해서 만들어 본것입니다. 오역이 많습니다. 참고하거나 틀린점이 있으면 댓글 부탁 드립니다.

원본은 다음과 같습니다.


Using process

Overview

인터넷을 통해 서버로 접속하는 것처럼 Twisted 는 로컬 프로세스에 같은 API로 접속 할수 있다. API 는 다음과 같다

Running Another Process

reacotr를 통해 프로세스를 실행하려면 reactor.spawnProcess를 사용해야한다. Pipe는 child process에 만들어 지고, reactor 에 추가된 어플레키에션은 블록되지 않은 상태로 데이터를 새로운 프로세스에 주고 받을 수 있다. reactor.spawnProcesss는 두개의 인자값인 processProtocol executable 이 필요하다. 추가적으로 arg, enviroment, path, userID, groupID, usePTY, and childFDS를 사용 할수 있다. 이 모든것이 Windows에서 사용 할수 있는건 아니다.

from twisted.internet import reactor

processProtocol = MyProcessProtocol()
reactor.spawnProcess(processProtocol, executable, args=[program, arg1, arg2],
 env={'HOME': os.environ['HOME']}, path,
 uid, gid, usePTY, childFDs)
  • processProtocol : tiwsted.internet.protocol.ProcessProtocol 의 하위 클래스 여야 하며 인터페이스는 하단에 설명 한다.
  • executable : 프로그램이 실행 할 절대경로 이것은 processProtocol 이 접속 될것이다.
  • args : 프로세스를 실행하기 위하여 넘겨지는 argument 이고 arg[0]은 항상 프로레스 이름이 되어야 한다.
  • env : 프로세스에게 넘겨줄 환경변수 type은 dictinaory 이다.
  • path : 프로세스가 실행될 위치. 프로세스는 현재 디렉토리로 주어지기 전까지 사용하고 path를 사용한다면 디렉토리는 변경 될 것이다.
  • uid, gid : 유저 ID와 그룹 ID 이며 기입시 해당 유저와 그룹 ID 로 실행된다.
  • userPTY : 프로세스가 pty 를 사용할 것인지 아니면 pipe의 쌍을 사용할건지 명시한다. Python PTY
  • childFDs : 하위 프로세스의 descriptor 를 사용할지 정한다. 각 키는 file descriptor 의 숫자(Integer)이며 하위 프로세스에서 보여질 것이다. 0, 1, 2 FD는 stdin, stdout, stderror 이지면 몇 프로그램은 추가적인 fds를 커맨드 라인이나 환경 변수로 설정한다. 각 integer 값은 부모의 file descriptor 이고 r 은 부모로가 읽을 수 있고 w는 부모가 쓸수 있는 파이프를 만드는 문자열이다. 만약 childFDS가 제공되어 지지 않는 다면 기본적으로 stdin-write, stdout-reader, stderr-reader 파이프로 기본적으로 생성 된다.

args 와 env 는 기본적으로 비어 있는 값이다. args[0]은 executable과 같아야 한다. 만약 env에 os.environ 이 주어진다면 하위 프로세스는 현재 프로세스로부터 상속 받는다. reactor.spawnProcess IProcessTransport를 상속받아 구현된다.

Writing a ProcessProtocol

ProcessProtocol 은 spawnProcess와 상호작용을 한다. 일반 프로토콜과 비슷 하지만 몇가지 특정 이벤트를 처리를 추가하는 방법이 있다. 우리의 예제는 wc를 사용하여 예제를 구현한다. 첫번째로는 ProcessProtocol을 초기화 한다.

from twisted.internet import protocol
class WCProcessProtocol(protocol.ProcessProtocol):

    def __init__(self, text):
        self.text = text

ProcessProtocol이 연결이 되었을대 connectionMade 메소드를 호출한다. 우리의 프로토콜에선 텍스트를 표준 입력으로 쓰고 표준 입력을 닫아서 프로세스가 우리가 표준 입력을 마쳤다는것을 알릴것이다.

...
def connectionMade(self):
    self.transport.write(self.text)
    self.transport.closeStdin()

이 시점에서 프로세는 데이터를 받고 결과를 읽을 시간이다. dataReceived 로 데이터가 수신되는 대신에 표준 출력데이터는 outReceived로 수신되어진다. 이것은 표준 오류에 대한 데이터와 구별하기 위한 것이다.

...
def outReceived(self, data):
    fieldLength = len(data) / 3
    lines = int(data[:fieldLength])
    words = int(data[fieldLength:fieldLength*2])
    chars = int(data[fieldLength*2:])
    self.transport.loseConnection()
    self.receiveCounts(lines, words, chars)

이제 프로세스가 출력을 파싱하여 프로세스 연결을 종료 하였다. 그런 다음 결과를 마지막 메서드로 결과를 보낸다. 이것은 클래스의 사용자가 데이터를 사용하여 다른 작업을 수행하도록 재지정 할 수 있다. 이 예제에서는 단지 결과를 출력 하는것 뿐이다.

...
def receiveCounts(self, lines, words, chars):
    print('Received counts from wc.')
    print('Lines:', lines)
    print('Words:', words)
    print('Characters:', chars)

작업을 다하였다 WCProcessProtocol을 사용하기 위해서 우리는 spawnProcess를 사용하여 인스턴서를 넘겨 준다.

from twisted.internet import reactor
wcProcess = WCProcessProtocol("accessing protocols through Twisted is fun!\n")
reactor.spawnProcess(wcProcess, 'wc', ['wc'])
reactor.run()

Things that can happen to your ProcessProtocol

ProcessProtocol 을 상속 받아서 오버라이드 해야하는 함수에 대해 설명

  • connectionMade() : 프로그램이 시작될때 호출 되어지고 stdin pipe 를 통해 데이터를 쓰기 가장 좋은 위치다. (using self.transport.write)
  • outReceived(data) : 하위 프로세스 에서 데이터를 받을때 호출 되어진다. 파이프는 socket보다 큰(보통 1kb) 사이즈를 제공하려는 경향이 있어서 네트워크 소켓의 전형적인 랜덤 드립과 드랍 행동을 경험하지 않을 수 있다 하지만 한번에 데이터를 어지 못한다면 대처할 준비가 되어 있어야 한다. 제대로 수행하려면 수신자가 데이터를 축적하고 프로세스가 완료 될때까지 모든 작업을 연기해야 한다.
  • errReceived(data) : outReceived 처럼 동작하며 프로세스의 stderr pipe 로부터 호출 되어진다.
  • inConnectionLost : 프로세스의 stdin pipe가 닫힘을 reactor 로부터 통지 받는다. 프로그램은 일반적으로 자신의 stdin을 닫지 않으며self.transport.loseConnection을 ProcessProtocol 에서 닫을때 호출 될 것이다.
  • outConnectionLost : 프로그램이 stdout pipe를 닫을때 호출 되어진다. 대게 프로그램이 종료 될때 호출되어진다.
  • processExited(status) : 이 호출은 하위 프로세스가 회수 되거나 프로세스의 종료 정보를 받으면 호출 되어진다. 이 상태는 프로세스가 정상적으로 종료된 경우 (signal을 수신하지 않고 자연적인 원인으로 사망하고 종료 코드가 0인 경우), ProcessTerminated (.exitCode 속성을 가진경우) 를 보유하는 .value 로 생선된 Failure인스턴스의 형태로 전달된다.
  • processEnded(status) : file desciptor와 연관된 하위 프로세스가 닫히거나 프로세스가 회수 되어질때 호출 되어진다. 이것은 ProcessProtocol의 마지막으로 콜백할것을 의미한다. status 파라메터는 processExited 와 같은 의미이다.

이러한 함수의 대부분에 대한 기본 클래스 정의는 no-ops입니다. 이것은 모든 튼튼하고 찌르레기가 버려지게 할 것이다. 파이프를 읽지 않으면 전체 파이프에 쓰기 위해 어린이 프로세스가 결국 차단됩니다. 즉, 파이프를 읽지 않아도됩니다.

Things you can do from your ProcessProtocol

하위 프로세스를 다루는 기본적인 방법 입니다.

  • self.transport.write(data) : data는 stdin pipe 입니다. write 메소드는 즉시 작성할 수 없는 데이터는 queue가 될것이다. 파이프가 다시쓰게 된다면 쓰기가 다시 시작될 것이다.
  • self.transport.closeStdin : stdin 파이프를 닫는다. 프로그램은 필터 역할을 한다 ( stdin 으로부터 읽기, data 수정, stdout 으로 데이터 쓰기) 보통 해당 작업이나 프로세스 종료 하는것으로 받아 들인다. 프로그램들이 다끝나면 stdin 을 닫는것이 중요하다. 그렇지 않으면 하위 프로세스는 절대로 끝나지 않을 것이다.
  • self.transport.closeStdout : 대게 호출 되어지지 않는다. stdout 에 쓰려고 하면 SIGPIPE 오류가 발생될 것이다.이 과정은 훌륭한 과정은 아니다.
  • self.transport.closeStderr : 대게 호출 되어지지 않는다. self.transport.closeStdout 과 같은 이유로
  • self.transport.loseConnection : 3개의 모든 파이프를 닫는다.
  • self.transport.signalProcess('KILL') : 하위 프로세스를 죽인다. 보통 processEnded가 호출 될 것이다.

Verbose Example

wc 프로그렘 작성

process.py
---
#!/usr/bin/env python

# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

from __future__ import print_function

from twisted.internet import protocol
from twisted.internet import reactor
import re

class MyPP(protocol.ProcessProtocol):
    def __init__(self, verses):
        self.verses = verses
        self.data = ""

    def connectionMade(self):
        print("connectionMade!")
        for i in range(self.verses):
        self.transport.write("Aleph-null bottles of beer on the wall,\n" +
         "Aleph-null bottles of beer,\n" +
         "Take one down and pass it around,\n" +
         "Aleph-null bottles of beer on the wall.\n")
        self.transport.closeStdin() # tell them we're done

    def outReceived(self, data):
        print("outReceived! with %d bytes!" % len(data))
        self.data = self.data + data

    def errReceived(self, data):
        print("errReceived! with %d bytes!" % len(data))

    def inConnectionLost(self):
        print("inConnectionLost! stdin is closed! (we probably did it)")

    def outConnectionLost(self):
        print("outConnectionLost! The child closed their stdout!")
# now is the time to examine what they wrote
#print("I saw them write:", self.data)
        (dummy, lines, words, chars, file) = re.split(r'\s+', self.data)
        print("I saw %s lines" % lines)

    def errConnectionLost(self):
        print("errConnectionLost! The child closed their stderr.")

    def processExited(self, reason):
        print("processExited, status %d" % (reason.value.exitCode,))

    def processEnded(self, reason):
        print("processEnded, status %d" % (reason.value.exitCode,))
        print("quitting")
        reactor.stop()

pp = MyPP(10)
reactor.spawnProcess(pp, "wc", ["wc"], {})
reactor.run()

이 프로그램의 정확한 출력은 비동기 이벤트 타이밍에 따라 다릅니다. 특히 프로그램은 하위 프로세스가 stderr 파이프가 닫히기 전이나 stdout 파이프로부터 읽은 후를 관찬 할 수 있다. 가능한 아래와 같을 것이다.

% ./process.py
connectionMade!
inConnectionLost! stdin is closed! (we probably did it)
errConnectionLost! The child closed their stderr.
outReceived! with 24 bytes!
outConnectionLost! The child closed their stdout!
I saw 40 lines
processEnded, status 0
quitting
Main loop terminated. 

Mapping File Descripotrs

stdin, stdout, stderr 은 단지 컨벤션이다. 프로그램은 일반적으로 input 은 fd0, 외부로 출력인 fd1, 에러를 발생하는 fd2 이다. 이것은 표준 C 라이브러리 매크로와 같다. stdin은 fd0 을 의미한다 그리고 쉘에선 파이프는 |을 의미하고 fd1으로 부터 명령을 다음 커맨드의 fd0 으로 리다이렉션 과 같다. 그러나 이것은 단지 컨벤션이며 프로그램은 자유롭게 file descriptors 를 추가 할수 있으며 표준 3개의 fd 를 무시 할 수도있다. childFDsargument는 자식 프로세스를 제공해야 하는 file descripotrs 를 정확히 지정 할 수 잇다.

각 childFD 는 3개중에 한개만 넣을 수 있다.

  • 부모 FD를 매핑 : 부모와 같은 읽기 쓰기와 같은 것을 할 수 있다
  • 부모로 부터 읽을 수 있는 파이프를 넣는다.
  • 파이프로 부터 부모에게 쓸수 있도록 넣는다.

childFDs를 매핑하는 것은 대게 하위 프로세스의 stderr 를 부모와 같은 곳에 출력 하기 위해 사용된다. shell 로부터 프로그램을 실행 시킬때 대게 fds 0, 1, 2는 쉘의 0,1,2와 매핑 되어 진 상태로 하위 프로그램의 출력을 같은 터미널에서 볼수 있도록 한다. 마찬가지로, inetd는 일반적으로 stdin 과 stdout 을 네트워크 소켓에 매핑하고 stderr를 동일한 소켓 또는 일종의 로깅 메커니즘에 매핑 할 수 있다. 이는 하위 프로그램이 네트워크에 대한 지식 없이 실행될수 있도록 한다.

부모의 읽기 파이프는 child의 output을 가지기 위해 사용되어지고 하위 프로세스와 interactive 를 하기위한 공통 공통된 방법이다.

부모의 쓰기 파이프를 하위 프로세스에 주면 하위 프로세스를 통제 할 수 있다. FTP와 BC 같은 프로그램은 명령을 stdin 스트림에 작성하여 이러한 방식으로 제어 할 수 있다.

childFDs dictionary는 file descriptor 숫자를 위의 조건 3가지의 상태중 1개를 할 수있다. 부모의 fd들중 한개를 맵핑하고 싶다면 간단하게 fd의 숫자를 값처럼 넣어주면 된다. read 파이프를 매핑 하려면 r을 값처럼 사용하면 된다. write 파이프를 매핑 하고 싶다면 w를 사용하면 된다.

아래 예제는 기본적으로 stdin/stdout/stderr 파이프를 매핑하는 것이다. 이것은 dictionary 타입으로 되어있다.

childFDs = {0: "w", 1: "r", 2: "r"}

부모의 파이썬 프로그램이 하는 것과 동일한 장소에 읽고 쓰는 프로세스를 시작하려면 다음을 사용한다.

childFDs = {0: 0, 1: 1, 2: 2}

fd를 추가하려면 다음과 같이 한다.

childFDs = {0: "w", 1: "r", 2: "r", 4: "w"}

ProcessProtocol with extra file descriptors

childFDs dictionary 를 보통 3개의 fd보다 더 제공 되어질때 이런 파이프를 접근 하기위해 추가적인 메소드가 필요하다. 이러한 방법은 위에서 설명한 outReceived 방법보다 더 일반적이다. 사실 이런 메소드(outReceived and errReceived) 는 오래된 코드를 호환하기위해 래핑되어있다. 새로운 ProcessProtocol 은 다음을 따르고 있다.

  • connectionMaded : 프로그램이 시작되어질때 호출 되어진다.
  • childDataReceived(childFD, data) :프로세스의 output pipe 들중 데이터를 받을때 호출되어진다 (예를 들어 childFDs 값이 r 이면 실질적인 숫자는(하위 프로세스의 관점에서) childFD에 있다. 호환을 위해 childFD가 1또는 2일때 childDataReceived outReceived errReceived로 디스패치하게 되어있다.)
  • childConnectionLost(childFD) : 이것은 reactor 로부터 프로세스의 파이프가 닫힐때 통지 도이ㅓ진다. 이것은 단지 부모의 파이프가 닫힌것인지( self.transport.closeChildFD과 같은), 하위 프로세스에서 명시적으로 파이프로 닫을때(때때로 EOF를 가르킴), 하위 프로세스가 종료 되거나 커널이 모든 파이프를 닫을때를 의미한다. childFD argument는 파이프가 닫혔다고 말한다. 파이프에 매핑된 파일 설명자에 대해서만 알수있다 기존 FD에 매핑 될때 부모는 그들이 언제 닫혔는지 알 수 있는 방법이 없습니다. 호환을 위해 기본적으로 inConnectonLost,outConnectionLost, errConnectionLost 디스패치 되어있다.
  • processEnded(status) : 하위 프로세스가 종료되어질때 나 파이프가 종료 되어질때 호출 되어진다. 이것은 종료 되기전에 모든 데이터들이processEnded가 실행되기 전에 쓰여진다.

이러한 것 이외에도 하위 프로세스에게 사용 할 수있는 메소드는 다음과 같다.

  • self.transport.writeToChild(childFD, data) : input 파이프로 데이터를 넣을때 간단하게 write는 childFD = 0 에쓰는 것과 같다.
  • self.transport.closeChildFD(childFD) : 하위 프로세스들중 하나를 닫아라. input 파이프를 다는것은 공통적으로 EOF 를 하위 프로세스에게 가르킨다. 출력 파이프를 다는것은 매우 유용하지도 않다.

반응형

'개발 > Python' 카테고리의 다른 글

Twisted/Using Process 번역  (0) 2019.03.07
Twisted/ Static File server file listing disable  (0) 2019.02.10
반응형

Twisted 를 사용하면서 웹의 static한 파일들을 사용하려면 Resource를 만들어서 serve해야 한다

위와 같이 serve할 path를 지정해주고 사용을 하면 되는 것인데, 이렇게 사용한다면 단점이 있다..

단점이라 함은 static.File Class가 자체적으로 해당 위치에 접속을 하게 되면 해당 파일 내용들이 나오게 되어 난감한 상황을 발생시키게 된다.

이것은 기본적으로 Twisted에서 directory listing을 off 하게 해주면 좋을듯 한데. 그것까진 지원이 되는것 같지 않아 아쉽다.

[기본적은 file serve하고 해당 폴더를 입력시 위와 같이 Directory Listing이 나온다]


해당 문제라기 보다는 Twisted의 기본적인 API문서를 보면 알게 되는데 해당 API는 아래와 같이 기술되어있다.


Twisted Static File API[링크]


위와같이 위치를 설정하면 해당 내용들이 자동적으로 HTML형식으로 리스팅 되어서 내온다는 말이다. 자 대충의 내용은 알았으니 실질적인 File Listing을 Disable을 해보자.


처리 방식은 다음과 같다.


해당 API문서를 보면 directoryListing이란 method 가 있는데 이 메소드의 반환값을보면 다음과 같다.



여기에서 DirecotryListeter라는 클래스가 반환이 되어 지는데 이는 위에 기본적으로 file serve direcotryListing 모습의 클래스를 반환한다 안에는 CSS/HTML 태그등 다양한 템플릿 형태로 저장 되어있다.


그렇다면 DirecotryLister는 무엇일까 이것도 또한 Resource의 일부임으로 DirecotryLister 대신에 다른 리소스를 리턴해 준다면 해당 파일 리스트는 생성되지 않을 것이다. 가장 해결하기 편한 방법은 간단히 해당 file Class를 상속받아서 direcotryListing을 오버라이딩해서 Resource만 return 해주면 된다.

그래서 나는 다음과 같이 해당 클래스를 생성해서 사용하기로 했다.

이렇게 정의 하고 이것을 Resource로 사용한다면 해당 디렉터리 목록은 나오지 않게 될 것이다.



[설정 적용된 모습]


이렇게 한다면 해당 디렉터리 목록은 나오지 않지만 해당 static 파일들은 내오게 된다. 이런식으로 사용한다면 조금이나마 보안 설정을 할 수 있게 되지 않을까? 선택은 개인의 몫이며 해당 관련된 내용중 틀린 내용이 있거나 좋은 내용이 있다면 답글 달아주면 감사 하겠습니다.





반응형

'개발 > Python' 카테고리의 다른 글

Twisted/Using Process 번역  (0) 2019.03.07
Twisted/ Static File server file listing disable  (0) 2019.02.10

+ Recent posts