fix tls connect

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-12-27 04:14:36 +01:00
padre c96859f7ac
commit 7574ffb16a

Ver fichero

@@ -32,65 +32,106 @@ class StreamParser extends EventEmitter {
} }
parse() { parse() {
// Find complete stanzas in buffer if (!this.buffer.length) return;
let startIdx = 0;
let inTag = false;
let tagDepth = 0;
for (let i = 0; i < this.buffer.length; i++) { // Handle stream start first (only once)
const char = this.buffer[i]; if (!this.streamStarted) {
// Look for stream:stream tag anywhere in buffer (skip XML declaration)
const streamMatch = this.buffer.match(/<stream:stream[^>]*>/);
if (!streamMatch) {
// Stream opening tag not complete yet
return;
}
const streamTag = streamMatch[0];
const streamIndex = this.buffer.indexOf(streamTag);
if (char === '<') {
if (this.buffer.substring(i, i + 2) === '</') {
// Closing tag
tagDepth--;
} else if (this.buffer[i + 1] !== '!' && this.buffer[i + 1] !== '?') {
// Opening tag
if (!this.streamStarted && this.buffer.substring(i).match(/^<stream:stream/)) {
// Parse stream start
const streamEndIdx = this.buffer.indexOf('>', i);
if (streamEndIdx !== -1) {
const streamTag = this.buffer.substring(i, streamEndIdx + 1);
try { try {
const attrs = this.parseAttributes(streamTag); const attrs = this.parseAttributes(streamTag);
this.streamStarted = true; this.streamStarted = true;
this.emit('streamStart', attrs); this.emit('streamStart', attrs);
this.buffer = this.buffer.substring(streamEndIdx + 1); // Keep everything after the stream tag
i = -1; this.buffer = this.buffer.substring(streamIndex + streamTag.length);
startIdx = 0; // Recursively parse any stanzas that follow
this.parse();
} catch (e) { } catch (e) {
this.emit('error', e); this.emit('error', new Error(`Stream parse error: ${e.message}`));
} }
return;
} }
} else {
tagDepth++; // Parse stanzas (after stream is started)
let index = 0;
while (index < this.buffer.length) {
// Skip whitespace
while (index < this.buffer.length && /\s/.test(this.buffer[index])) {
index++;
}
if (index >= this.buffer.length) break;
if (this.buffer[index] === '<') {
// Check for stream closing
if (this.buffer.substring(index).startsWith('</stream:stream>')) {
this.emit('streamEnd');
this.buffer = '';
return;
}
// Try to extract a complete stanza
let closeIndex = -1;
let depth = 0;
let inOpenTag = true;
for (let i = index; i < this.buffer.length; i++) {
const char = this.buffer[i];
if (char === '<') {
// Check if it's a closing tag
if (this.buffer[i + 1] === '/') {
depth--;
} else if (this.buffer[i + 1] !== '!' && this.buffer[i + 1] !== '?') {
depth++;
}
inOpenTag = true;
} else if (char === '>' && inOpenTag) {
// Check if self-closing
if (this.buffer[i - 1] === '/') {
depth--;
}
if (depth === 0 && this.buffer[index + 1] !== '/') {
// Found end of stanza
closeIndex = i;
break;
}
inOpenTag = false;
} }
} }
if (tagDepth > 0) { if (closeIndex === -1) {
inTag = true; // Stanza not complete, wait for more data
break;
} }
} else if (char === '>' && inTag) {
tagDepth--;
if (tagDepth === 0) { // Extract stanza
// Complete stanza const stanzaStr = this.buffer.substring(index, closeIndex + 1);
const stanzaStr = this.buffer.substring(startIdx, i + 1);
if (stanzaStr.trim()) {
try { try {
const stanza = ltx.parse(stanzaStr); const stanza = ltx.parse(stanzaStr);
this.emit('stanza', stanza); this.emit('stanza', stanza);
index = closeIndex + 1;
} catch (e) { } catch (e) {
this.emit('error', e); // Invalid stanza, skip this byte
} index++;
}
startIdx = i + 1;
inTag = false;
} }
} else {
index++;
} }
} }
this.buffer = this.buffer.substring(startIdx); // Keep unparsed data in buffer
this.buffer = this.buffer.substring(index);
} }
parseAttributes(tagStr) { parseAttributes(tagStr) {
@@ -190,7 +231,7 @@ class XMPPStream extends EventEmitter {
} }
handleStreamStart(attrs) { handleStreamStart(attrs) {
this.logger.debug('Stream start received:', attrs); this.logger.info('Stream start received:', attrs);
if (this.state === 'wait-for-stream') { if (this.state === 'wait-for-stream') {
// Send stream response // Send stream response