第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 Node.js 通過代理發(fā)送 HTTP/2 請求?

如何使用 Node.js 通過代理發(fā)送 HTTP/2 請求?

呼喚遠(yuǎn)方 2022-11-11 10:49:47
我想使用 Node.js 的http2庫通過代理向服務(wù)器發(fā)送 HTTP/2 請求。出于測試目的,我使用 Charles v4.2.7 作為代理,但 Charles 無法代理該請求。Charles 顯示Malformed request URL "*"錯誤,因?yàn)樗盏降恼埱笫荘RI * HTTP/2.0(HTTP/2 連接前言)。我可以使用 cURL(例如)通過我的 Charles 代理成功發(fā)送 HTTP/2 請求curl --http2 -x localhost:8888 https://cypher.codes,所以我認(rèn)為這不是 Charles 的問題,而是我的 Node.js 實(shí)現(xiàn)的問題。這是我的 Node.js HTTP/2 客戶端實(shí)現(xiàn),它嘗試通過我在 http://localhost:8888 上監(jiān)聽的 Charles 代理向https://cypher.codes發(fā)送 GET 請求:const http2 = require('http2');const client = http2.connect('http://localhost:8888');client.on('error', (err) => console.error(err));const req = client.request({  ':scheme': 'https',  ':method': 'GET',  ':authority': 'cypher.codes',  ':path': '/',});req.on('response', (headers, flags) => {  for (const name in headers) {    console.log(`${name}: ${headers[name]}`);  }});req.setEncoding('utf8');let data = '';req.on('data', (chunk) => { data += chunk; });req.on('end', () => {  console.log(`\n${data}`);  client.close();});req.end();這是我在運(yùn)行時遇到的 Node.js 錯誤node proxy.js(proxy.js是包含上述代碼的文件):events.js:200      throw er; // Unhandled 'error' event      ^Error [ERR_HTTP2_ERROR]: Protocol error    at Http2Session.onSessionInternalError (internal/http2/core.js:746:26)Emitted 'error' event on ClientHttp2Stream instance at:    at emitErrorNT (internal/streams/destroy.js:92:8)    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)    at processTicksAndRejections (internal/process/task_queues.js:81:21) {  code: 'ERR_HTTP2_ERROR',  errno: -505}我使用詳細(xì)輸出重新運(yùn)行了上述 cURL 請求,看起來 cURL 首先使用 HTTP/1 向代理發(fā)送 CONNECT,然后使用 HTTP/2 發(fā)送 GET 請求。我想嘗試通過 Node.js 做同樣的事情(首先發(fā)送一個 HTTP/1 CONNECT 請求,然后在同一個 TCP 連接上發(fā)送我的 HTTP/2 請求),但我不知道該怎么做。創(chuàng)建 HTTP/2 客戶端(即http2.connect('http://localhost:8888');)的行為會發(fā)送 HTTP/2 連接前言。我考慮過首先使用 HTTP/1(例如使用http庫)創(chuàng)建連接,然后將其升級到 HTTP/2,但我找不到任何有關(guān)如何執(zhí)行此操作的示例。有人可以幫我使用 Node.js 通過代理發(fā)送 HTTP/2 請求嗎?
查看完整描述

3 回答

?
江戶川亂折騰

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超5個贊

要通過不理解它的代理來隧道 HTTP/2,您需要使用 HTTP/1.1 進(jìn)行初始連接,然后僅在隧道中使用 HTTP/2。您的代碼從一開始就使用 HTTP/2,這是行不通的。


要真正建立該隧道,您首先向目標(biāo)主機(jī)發(fā)送 HTTP CONNECT 請求,并收到 200 響應(yīng),然后將來連接上的所有其他內(nèi)容都會在您和目標(biāo)主機(jī)之間來回轉(zhuǎn)發(fā)。


一旦你的隧道工作了,你就可以發(fā)送 HTTP/2(或目標(biāo)服務(wù)器理解的任何其他內(nèi)容),它會直接到達(dá)你的目標(biāo)。


在節(jié)點(diǎn)中執(zhí)行此操作的代碼如下所示:


const http = require('http');

const http2 = require('http2');


// Build a HTTP/1.1 CONNECT request for a tunnel:

const req = http.request({

  method: 'CONNECT',

  host: '127.0.0.1',

  port: 8888,

  path: 'cypher.codes'

});

req.end(); // Send it


req.on('connect', (res, socket) => {

  // When you get a successful response, use the tunnelled socket

  // to make your new request.

  const client = http2.connect('https://cypher.codes', {

    // Use your existing socket, wrapped with TLS for HTTPS:

    createConnection: () => tls.connect({

      socket: socket,

      ALPNProtocols: ['h2']

    })

  });


  // From here, use 'client' to do HTTP/2 as normal through the tunnel

});

我最近也一直在研究我自己的工具的內(nèi)部結(jié)構(gòu),為代理添加完整的 HTTP/2 支持,并將其寫在這里,這可能對你非常重要。https://github.com/httptoolkit/mockttp/blob/h2/test/integration/http2.spec.ts中的測試在這樣的節(jié)點(diǎn)中有更多和更大的隧道 HTTP/2 示例,所以這些絕對值得也看看。當(dāng)然,這一切仍在開發(fā)中,所以如果您有任何問題或發(fā)現(xiàn)任何錯誤,請告訴我。


查看完整回答
反對 回復(fù) 2022-11-11
?
www說

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超8個贊

身份驗(yàn)證以及如何避免 TLS 證書錯誤。


所以這是我的更新版本:


const http = require('http');

const http2 = require('http2');

const tls = require('tls');


// Build a HTTP/1.1 CONNECT request for a tunnel:

const username = '...';

const password = '...';

const req = http.request({

  method: 'CONNECT',

  host: '127.0.0.1',

  port: 8888,

  path: 'website.com', //the destination domain

  headers: { //this is how we authorize the proxy, skip it if you don't need it

    'Proxy-Authorization': 'Basic ' + Buffer.from(username + ':' + password).toString('base64')

  }

});

req.end(); // Send it


req.on('connect', (res, socket) => {

  // When you get a successful response, use the tunnelled socket to make your new request

  const client = http2.connect('https://website.com', {

    createConnection: () => tls.connect({

      host: 'website.com', //this is necessary to avoid certificate errors

      socket: socket,

      ALPNProtocols: ['h2']

    })

  });


  // From here, use 'client' to do HTTP/2 as normal through the tunnel

});


查看完整回答
反對 回復(fù) 2022-11-11
?
富國滬深

TA貢獻(xiàn)1790條經(jīng)驗(yàn) 獲得超9個贊

為了顯示我的解決方案,我們將向 API 發(fā)出請求,該 API 將您的 IP 作為 JSON 返回,然后您就可以適應(yīng)您的需求。


這是代碼:


/**

 * A URL without the path.

 */

const TARGET_AUTHOTIRY = 'https://api4.my-ip.io'


/**

 * You should use the host with the port equivalent to the protocol

 * HTTP => 80

 * HTTPS => 443

 */

const TARGET_HOST = 'api4.my-ip.io:443'


/**

 * Proxy configuration

 */

const PROXY_HOST = '<your_proxy_host>'

const PROXY_PORT = '<your_proxy_port>'

const PROXY_USERNAME = '<your_proxy_username>'

const PROXY_PASSWORD = '<your_proxy_password>'


/**

 * Establishes an connection to the target server throught the HTTP/1.0

 * proxy server.

 *

 * The CONNECT method tells the PROXY server where this connection should arive.

 *

 * After the connection is established you will be able to use the TCP socket to send data

 * to the TARGET server.

 */

const request = http.request({

  method: 'CONNECT',

  host: PROXY_HOST,

  port: PROXY_PORT,

  path: TARGET_HOST,

  headers: {

    'Host': TARGET_HOST,

    'Proxy-Authorization': `Basic ${Buffer.from(`${PROXY_USERNAME}:${PROXY_PASSWORD}`).toString('base64')}`

  }

})


/**

 * Wait the "connect" event and then uses the TCP socket to proxy the HTTP/2.0 connection throught.

 */

request.on('connect', (res, socket) => {

  /**

   * Check if it has successfully connected to the server

   */

  if (res.statusCode !== 200)

    throw new Error('Connection rejected by the proxy')


  /**

   * Use the TCP socket from the HTTP/1.0 as the socket for this new connection

   * without the need to establish the TLS connection manually and handle the errors

   * manually too.

   *

   * This method accepts all TCP and TLS options.

   */

  const client = http2.connect(TARGET_AUTHOTIRY, { socket })


  client.on('connect', () => {

    console.log('Connected to the page!')

  })


  /**

   * Request to check your IP

   */

  const req = client.request({

    ':path': '/ip.json',

  })


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

    console.log('Recieved a response')

  })


  /**

   * Stores the data recieved as a response

   */

  const buffers = []

  req.on('data', (buffer) => {

    buffers.push(buffer)

  })


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

    console.log(Buffer.concat(buffers).toString('utf-8'))


    // Closes the connection with the server

    client.close()

  })


  req.end()

})


request.end()

我沒有創(chuàng)建 TLS 套接字,而是將我的 TCP 套接字注入 HTTP/2.0 客戶端。


socket選項(xiàng)未在方法文檔中明確列出,但該方法接受所有net.connect ()和tls.connect()選項(xiàng)。


您可以在此處找到有關(guān)http2.connect方法的所有文檔:HTTP 2 Node JS Documentation


查看完整回答
反對 回復(fù) 2022-11-11
  • 3 回答
  • 0 關(guān)注
  • 350 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號