Node.js HTTP2服务器错误:套接字挂起

给定具有实验HTTP2支持的最新版本的Node.js

$ node -v

v9.2.0

HTTP2服务器:

var options = {

key: getKey(),

cert: getCert(),

allowHTTP1: true

}

var server = http2.createSecureServer(options)

server.on('stream', onstream)

server.on('error', onerror)

server.on('connect', onconnect)

server.on('socketError', onsocketerror)

server.on('frameError', onframeerror)

server.on('remoteSettings', onremotesettings)

server.listen(8443)

function onconnect() {

console.log('connect')

}

function onremotesettings(settings) {

console.log('remote settings', settings)

}

function onframeerror(error) {

console.log('frame error', error)

}

function onsocketerror(error) {

console.log('socket error', error)

}

function onerror(error) {

console.log(error)

}

function onstream(stream, headers) {

console.log('stream')

}

并对此提出了要求:

var https = require('https')

var options = {

method: 'GET',

hostname: 'localhost',

port: '8443',

path: '/',

protocol: 'https:',

rejectUnauthorized: false,

agent: false

}

var req = https.request(options, function(res){

var body = ''

res.setEncoding('utf8')

res.on('data', function(data){

body += data;

});

res.on('end', function(){

callback(null, body)

})

})

req.end()

它只是挂起并最终说:

Error: socket hang up

at createHangUpError (_http_client.js:330:15)

at TLSSocket.socketOnEnd (_http_client.js:423:23)

at TLSSocket.emit (events.js:164:20)

at endReadableNT (_stream_readable.js:1054:12)

at _combinedTickCallback (internal/process/next_tick.js:138:11)

at process._tickCallback (internal/process/next_tick.js:180:9)

如果rejectUnauthorized: true设置,则错误:

Error: self signed certificate

at TLSSocket.onConnectSecure (_tls_wrap.js:1036:34)

at TLSSocket.emit (events.js:159:13)

at TLSSocket._finishInit (_tls_wrap.js:637:8)

不知道出了什么问题以及为什么到了日志记录的地步stream

如果我进入浏览器并访问https://

localhost:8443,然后单击警告消息,则它实际上会记录stream并成功发出请求。但是尚未能够使节点发出请求。

我想将其视为HTTP1服务器,因此不想使用HTTP2客户端发出请求。但是尝试使用相同的东西。

回答:

HTTP / 1与HTTP / 2共享的请求语义不同,因此需要在HTTP / 2服务器中检测并处理HTTP /

1客户端。为了同时支持两者,您需要使用HTTP2兼容性API。

当HTTP1客户端连接到具有allowHTTP1: true设置的HTTP / 2服务器但不处理HTTP / 1请求时,将发生“挂起” 。

这些示例基于Node文档的示例代码。

回答:

const http2 = require('http2')

const fs = require('fs')

var options = {

key: fs.readFileSync('server-key.pem'),

cert: fs.readFileSync('server-crt.pem'),

//ca: fs.readFileSync('ca-crt.pem'),

allowHTTP1: true,

}

var server = http2.createSecureServer(options, (req, res) => {

// detects if it is a HTTPS request or HTTP/2

const { socket: { alpnProtocol } } = (req.httpVersion === '2.0')

? req.stream.session

: req

res.writeHead(200, { 'content-type': 'application/json' })

res.end(JSON.stringify({

alpnProtocol,

httpVersion: req.httpVersion

}))

})

server.listen(8443)

回答:

const http2 = require('http2')

const fs = require('fs')

const client = http2.connect('https://localhost:8443', {

ca: fs.readFileSync('ca-crt.pem'),

rejectUnauthorized: true,

})

client.on('socketError', (err) => console.error(err))

client.on('error', (err) => console.error(err))

const req = client.request({ ':path': '/' })

req.on('response', (headers, flags) => {

for (const name in headers) {

console.log('Header: "%s" "%s"', name, headers[name])

}

})

req.setEncoding('utf8')

let data = ''

req.on('data', chunk => data += chunk)

req.on('end', () => {

console.log('Data:', data)

client.destroy()

})

req.end()

然后运行:

→ node http2_client.js 

(node:34542) ExperimentalWarning: The http2 module is an experimental API.

Header: ":status" "200"

Header: "content-type" "application/json"

Header: "date" "Sat, 02 Dec 2017 23:27:21 GMT"

Data: {"alpnProtocol":"h2","httpVersion":"2.0"}

回答:

const https = require('https')

const fs = require('fs')

var options = {

method: 'GET',

hostname: 'localhost',

port: '8443',

path: '/',

protocol: 'https:',

ca: fs.readFileSync('ca-crt.pem'),

rejectUnauthorized: true,

//agent: false

}

var req = https.request(options, function(res){

var body = ''

res.setEncoding('utf8')

res.on('data', data => body += data)

res.on('end', ()=> console.log('Body:', body))

})

req.on('response', response => {

for (const name in response.headers) {

console.log('Header: "%s" "%s"', name, response.headers[name])

}

})

req.end()

然后跑步

→ node http1_client.js 

Header: "content-type" "application/json"

Header: "date" "Sat, 02 Dec 2017 23:27:08 GMT"

Header: "connection" "close"

Header: "transfer-encoding" "chunked"

Body: {"alpnProtocol":false,"httpVersion":"1.1"}

回答:

使用纯HTTP / 2服务器可与一起使用,http2_client但将“挂起”用于http1_client。删除时,来自HTTP /

1客户端的TLS连接将关闭allowHTTP1: true

const http2 = require('http2')

const fs = require('fs')

var options = {

key: fs.readFileSync('server-key.pem'),

cert: fs.readFileSync('server-crt.pem'),

ca: fs.readFileSync('ca-crt.pem'),

allowHTTP1: true,

}

var server = http2.createSecureServer(options)

server.on('error', error => console.log(error))

server.on('connect', conn => console.log('connect', conn))

server.on('socketError', error => console.log('socketError', error))

server.on('frameError', error => console.log('frameError', error))

server.on('remoteSettings', settings => console.log('remote settings', settings))

server.on('stream', (stream, headers) => {

console.log('stream', headers)

stream.respond({

'content-type': 'application/html',

':status': 200

})

console.log(stream.session)

stream.end(JSON.stringify({

alpnProtocol: stream.session.socket.alpnProtocol,

httpVersion: "2"

}))

})

server.listen(8443)

回答:

根据要点中详细描述的扩展中间证书设置,需要将CA的完整证书链提供给客户端。

cat ca/x/certs/x.public.pem > caxy.pem

cat ca/y/certs/y.public.pem >> caxy.pem

然后在客户端中使用此ca选项。

{ 

ca: fs.readFileSync('caxy.pem'),

}

这些示例是使用来自circle.com的以下简单CA设置运行的:

为了简化配置,让我们获取以下CA配置文件。

wget https://raw.githubusercontent.com/anders94/https-authorized-

clients/master/keys/ca.cnf

接下来,我们将使用此配置创建一个新的证书颁发机构。

openssl req -new -x509 \

-days 9999 \

-config ca.cnf \

-keyout ca-key.pem \

-out ca-crt.pem

现在,我们已经在ca-key.pem和ca-crt.pem中拥有了证书颁发机构,现在让我们为服务器生成一个私钥。

openssl genrsa \

-out server-key.pem \

4096

我们的下一步是生成证书签名请求。再次简化配置,让我们使用server.cnf作为配置快捷方式。

wget https://raw.githubusercontent.com/anders94/https-authorized-

clients/master/keys/server.cnf

现在,我们将生成证书签名请求。

openssl req -new \

-config server.cnf \

-key server-key.pem \

-out server-csr.pem

现在让我们签署请求。

openssl x509 -req -extfile server.cnf \

-days 999 \

-passin "pass:password" \

-in server-csr.pem \

-CA ca-crt.pem \

-CAkey ca-key.pem \

-CAcreateserial \

-out server-crt.pem

以上是 Node.js HTTP2服务器错误:套接字挂起 的全部内容, 来源链接: utcz.com/qa/415698.html

回到顶部