Nodejs: преобразовать строку в буфер - PullRequest
13 голосов
/ 17 августа 2011

Я пытаюсь записать строку в сокет (сокет называется «ответ»).Вот код, который у меня есть (я пытаюсь реализовать прокси кэширования байтов ...):

var http = require('http');
var sys=require('sys');

var localHash={};

http.createServer(function(request, response) {
    var proxy = http.createClient(80, request.headers['host'])
    var proxy_request = proxy.request(request.method, request.url, request.headers);
    proxy_request.addListener('response', function (proxy_response) {
    proxy_response.addListener('data', function(x) {
        var responseData=x.toString();
        var f=50;
        var toTransmit="";
        var p=0;        

        var N=responseData.length;
        if(N>f){
            p=Math.floor(N/f);

            var hash="";
            var chunk="";
            for(var i=0;i<p;i++){
                chunk=responseData.substr(f*i,f);
                hash=DJBHash(chunk);
                if(localHash[hash]==undefined){
                    localHash[hash]=chunk;
                    toTransmit=toTransmit+chunk;
                }else{
                    sys.puts("***hit"+chunk);
                    toTransmit=toTransmit+chunk;//"***EOH"+hash;
                }
            }
            //remainder:
            chunk=responseData.substr(f*p);
            hash=DJBHash(chunk);
            if(localHash[hash]==undefined){
                localHash[hash]=chunk;
                toTransmit=toTransmit+chunk;
            }else{
                toTransmit=toTransmit+chunk;//"***EOH"+hash;
            }
        }else{
            toTransmit=responseData;
        }
        response.write(new Buffer(toTransmit));   /*error occurs here */
    });
    proxy_response.addListener('end', function() {
        response.end();
    });
    response.writeHead(proxy_response.statusCode, proxy_response.headers);
    });
    request.addListener('data', function(chunk) {
        sys.puts(chunk);
        proxy_request.write(chunk, 'binary');
    });
    request.addListener('end', function() {
        proxy_request.end();
    });
}).listen(8080);



function DJBHash(str) {
    var hash = 5381;
    for(var i = 0; i < str.length; i++) {
        hash = (((hash << 5) + hash) + str.charCodeAt(i)) & 0xffffffff;
    }
    if(hash<-1){
        hash=hash*-1;
    }
    return hash;
}

Проблема в том, что в Firefox я продолжаю получать «ошибку кодирования контента».Это как если бы взломанный контент не передавался должным образом.Я гарантировал, что «toTransmit» - это то же самое, что и «x» через console.log (x) и console.log (toTransmit).

Стоит отметить, что если я заменю response.write(new Buffer(toTransmit)) на просто response.write(x), прокси работает, как и ожидалось, но мне нужно провести некоторый анализ полезной нагрузки и затем передать «toTransmit», а не «x».

Я также пытался response.write(toTransmit) (т.е. без преобразования в буфер) и я продолжаю получать ту же ошибку кодирования содержимого.

Я действительно застрял.Я думал, что эту проблему исправили, преобразовав строку в буфер согласно другому потоку (/8020140/nodejs-oshibka-kodirovki-kontenta),, но я заново открыл новый поток, чтобы обсудить эту новую проблему, с которой я столкнулся.

Я должендобавьте, что если я открываю страницу через прокси в Opera, я получаю gobblydeegook - это как если бы gzipped данные были повреждены.

Любое понимание очень ценится.

Большое спасибо заранее,

Ответы [ 3 ]

22 голосов
/ 10 декабря 2016

Как насчет этого?

var responseData= Buffer.from( x, 'utf8' )

из: Преобразовать строку в буферный узел

19 голосов
/ 17 августа 2011

Не углубляясь в ваш код, мне кажется, что вы, возможно, захотите изменить

var responseData=x.toString();

до

var responseData=x.toString("binary");

и, наконец,

response.write(new Buffer(toTransmit, "binary"));
5 голосов
/ 17 августа 2011

Из документов :

Чистый Javascript дружествен к Юникоду, но не подходит для двоичных данных.При работе с потоками TCP или файловой системой необходимо обрабатывать потоки октетов.В Node есть несколько стратегий для манипулирования, создания и потребления потоков октетов.

Необработанные данные хранятся в экземплярах класса Buffer.Буфер похож на массив целых чисел, но соответствует необработанному выделению памяти вне кучи V8.Размер буфера не может быть изменен.

Поэтому не используйте строки для обработки двоичных данных.

Измените proxy_request.write(chunk, 'binary'); на proxy_request.write(chunk);.

Пропустить var responseData=x.toString();, это плохая идея.

Вместо выполнения substr для строки, используйте slice для буфера.

Вместо выполнения + со строками, используйте "метод concat из buffertools .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...