2012-02-16 2 views
5

비표준 HTTP 메소드 (동사)를 사용하여 요청에 응답하는 HTTP 서버를 작성하고 싶습니다. 예를 들어 클라이언트는 FOO/HTTP/.1.1과 같은 요청을합니다. 내가 ExpressJS의 lib/router/methods.js에서 내 보낸 배열 내 표준이 아닌 방법을 추가 ExpressJS로 비표준 HTTP 메소드 제공

var express = require('express'); 

var app = express.createServer(); 

app.configure(function(){ 
    app.use(express.logger({ format: ':method :url' })); 
    app.use(express.methodOverride()); 
}); 

app.foo('/', function(req, res){ 
    res.send('Hello World'); 
}); 

app.listen(3000); 

: 그리고 서버 측에서,이 요청은 같은 의해 처리 될 것이다. 이를 통해 예상대로 서버 코드를 작성할 수 있습니다. express.methodOverride()POST 요청을 _method=foo과 함께 사용하면 작동합니다. 그러나 실제 FOO 요청이 작동하지 않습니다. 내가 ExpressJS와 핵심 파일에 해킹을 피하지 않고이를 구현 할 수 있도록하고 싶습니다

$telnet localhost 3000 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
FOO/HTTP/1.1 
Connection closed by foreign host. 

: 즉시 클라이언트로 연결이 서버에 의해 폐쇄 요청의 첫 번째 줄을 보낼 수 있습니다.

이것이 가능한지 및 어떤 생각이 있으십니까?

답변

4

짧은 대답 : 아니요, 불가능합니다. 자신의 HTTP 모듈을 구현하지 않아도됩니다. 테스트하려면

는 ... 베어 HTTP 서버를 시작 그런

$ node 
> require('http').createServer(function(req, res) { 
... console.log(req.method); 
... res.end(); 
... }).listen(8080); 

그것에 텔넷과 GET 및 FOO 요청을 발행 (이미 수행 한 것처럼)

$ telnet localhost 8080 
Trying ::1... 
telnet: connect to address ::1: Connection refused 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
GET/HTTP/1.1 

HTTP/1.1 200 OK 
Connection: keep-alive 
Transfer-Encoding: chunked 

0 

FOO/HTTP/1.1 
Connection closed by foreign host. 

$ 

노드 콘솔에

GET 

...하지만 FOO는 표시되지 않습니다. 따라서 Express가 사용하는 노드의 기본 HTTP 모듈은 이러한 요청을 사용할 수 없게 만듭니다.

+3

업데이트를 게시하려면 현재 노드 (4.6)와 express (4) 버전에서 사용자 정의 HTTP 동사를 처리 할 수 ​​있습니다. 'app.all'을 듣고 콜백에서'req.method'를 체크하면 작동합니다. – MatsLindh

-1

정말 중요한 목적이 있습니까? 자신의 HTTP 서버와 클라이언트 만이 서로 대화 할 수 있으며 아주 작은 이득을 위해 많은 노력이 필요합니다. 어떤면에서 standard HTTP verbs이 실패합니까?

익스프레스 해킹이 필요한지 여부에 대한 질문에 대답하려면 : 에 파고가 필요합니다. requirehttp 모듈을 익스프레스하고 적어도 자신의 모듈로 오버라이드해야합니다. Node.js는 내장 된 core modules are always checked first이므로 모듈에 동일한 이름을 부여 할 수는 없습니다.

+0

구현하고자하는 비표준 동사는 캐시에서 객체를 제거하기 위해 Squid와 Varnish가 지원하는 PURGE 메소드입니다 (http://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache 참조). .3F 및 https://www.varnish-cache.org/docs/trunk/tutorial/purging.html) –

+3

글쎄, 난 그냥 기본 HTTP 서버 개체에 대한 테스트를했고 당신이 설명하는 동작은 확실히 노드에 의해 발생합니다. js 'http 서버이며 express로 추가되지 않았습니다. Joyent와 함께 버그를 수정해야한다. (표준은 비표준 동사를 허용하지 않는 것에 대해 아무 것도 말하지 않는다. 따라서 사용자가 기능을 구현하고자한다면 이해할 수있다.) - 자신을 패치 한 후에는 패치를 승인 할 가능성이 더 높습니다. 그래도 작동하지 않는다면 원하는 것을하기 위해 http 라이브러리와 express를 포크해야 할 것입니다. –

0

다른 사람들처럼 Node.js의 HTTP 서버 라이브러리는 특정 동사 만 허용하도록 구성되어 있습니다. Ben Noordius의 제안 인 Parsley도 작동하지 않습니다. 그 라이브러리는 동사의 더 작은 허용 목록이기 때문에 작동하지 않습니다. (꽤 오랜 시간 동안 유지되지도 않았습니다.)

이 단계에서 홀수 요청을 지원하려면 더 과감한 조치를 취해야합니다. 약간의 내부 행동을 펀칭하는 오리와 관련된 멋진 못생긴 해킹이 있습니다. 이것은 Node.js의 v0.10.x에서 작동하지만 새로운 버전이 출시되면 신중하게 테스트합니다.

SOURCE /live ICE/1.0 

을 다음 : 내 경우

, 나는 표준이 아닌 동사하지만, 비표준 프로토콜 버전 식별자뿐만 아니라, 그리고 아이스 캐스트 소스 스트림 누락 Content-Length 헤더뿐만 아니라 지원하는 데 필요한 시작해야합니다 :

server.on('connection', function (socket) { 
    var originalOnDataFunction = socket.ondata; 
    var newLineOffset; 
    var receiveBuffer = new Buffer(0); 
    socket.ondata = function (d, start, end) { 
     receiveBuffer = Buffer.concat([receiveBuffer, d.slice(start, end)]); 
     if ((newLineOffset = receiveBuffer.toString('ascii').indexOf('\n')) > -1) { 
      var firstLineParts = receiveBuffer.slice(0, newLineOffset).toString().split(' '); 
      firstLineParts[0] = firstLineParts[0].replace(/^SOURCE$/ig, 'PUT'); 
      firstLineParts[2] = firstLineParts[2].replace(/^ICE\//ig, 'HTTP/'); 
      receiveBuffer = Buffer.concat([ 
       new Buffer(
        firstLineParts.join(' ') + '\r\n' + 
        'Content-Length: 9007199254740992\r\n' 
       ), 
       receiveBuffer.slice(newLineOffset +1) 
      ]); 

      socket.ondata = originalOnDataFunction; 
      socket.ondata.apply(this, [receiveBuffer, 0, receiveBuffer.length]); 
     } 
    }; 
} 

끔찍하지만 작동합니다. 특별히 만족스럽지는 않지만, HTTP 퍼서 작성기 나 기존의 HTTP 파서를 선택하는 경우이 인스턴스를 조정해야합니다.