diff --git a/jabber-core.el b/jabber-core.el index 8b558a8..eae787b 100644 --- a/jabber-core.el +++ b/jabber-core.el @@ -64,6 +64,10 @@ (defvar jabber-choked-timer nil) +(defvar jabber-namespace-prefixes nil + "XML namespace prefixes used for the current connection.") +(make-variable-buffer-local 'jabber-namespace-prefixes) + (defgroup jabber-core nil "customize core functionality" :group 'jabber) @@ -440,7 +444,7 @@ With double prefix argument, specify more connection details." (let ((stanza (cadr event))) (cond ;; At this stage, we only expect a stream:features stanza. - ((not (eq (jabber-xml-node-name stanza) 'stream:features)) + ((not (eq (jabber-xml-node-name stanza) 'features)) (list nil (plist-put state-data :disconnection-reason (format "Unexpected stanza %s" stanza)))) @@ -632,7 +636,7 @@ With double prefix argument, specify more connection details." (:stanza (let ((stanza (cadr event))) (cond - ((eq (jabber-xml-node-name stanza) 'stream:features) + ((eq (jabber-xml-node-name stanza) 'features) (if (and (jabber-xml-get-children stanza 'bind) (jabber-xml-get-children stanza 'session)) (labels @@ -862,7 +866,14 @@ DATA is any sexp." (stream-header (car (xml-parse-region (point-min) ending-at))) (session-id (jabber-xml-get-attribute stream-header 'id)) (stream-version (jabber-xml-get-attribute stream-header 'version))) - + + ;; Need to keep any namespace attributes on the stream + ;; header, as they can affect any stanza in the + ;; stream... + (setq jabber-namespace-prefixes + (jabber-xml-merge-namespace-declarations + (jabber-xml-node-attributes stream-header) + nil)) (jabber-log-xml fsm "receive" stream-header) (fsm-send fsm (list :stream-start session-id stream-version)) (delete-region (point-min) ending-at))) @@ -898,7 +909,9 @@ DATA is any sexp." (sit-for 2))) (delete-region (point-min) (point)) - (fsm-send fsm (list :stanza (jabber-xml-resolve-namespace-prefixes (car xml-data)))) + (fsm-send fsm (list :stanza + (jabber-xml-resolve-namespace-prefixes + (car xml-data) nil jabber-namespace-prefixes))) ;; XXX: move this logic elsewhere ;; We explicitly don't catch errors in jabber-process-input, ;; to facilitate debugging. diff --git a/jabber-xml.el b/jabber-xml.el index 88878fe..46762ed 100644 --- a/jabber-xml.el +++ b/jabber-xml.el @@ -226,22 +226,8 @@ any string character data of this node" (defun jabber-xml-resolve-namespace-prefixes (xml-data &optional default-ns prefixes) (let ((node-name (jabber-xml-node-name xml-data)) (attrs (jabber-xml-node-attributes xml-data))) - ;; First find any foo:xmlns attributes.. - (dolist (attr attrs) - (let ((attr-name (symbol-name (car attr)))) - (when (string-match "xmlns:" attr-name) - (let ((prefix (substring attr-name (match-end 0))) - (ns-uri (cdr attr))) - ;; A slightly complicated dance to never change the - ;; original value of prefixes (since the caller depends on - ;; it), but also to avoid excessive copying (which remove - ;; always does). Might need to profile and tweak this for - ;; performance. - (setq prefixes - (cons (cons prefix ns-uri) - (if (assoc prefix prefixes) - (remove (assoc prefix prefixes) prefixes) - prefixes))))))) + (setq prefixes (jabber-xml-merge-namespace-declarations attrs prefixes)) + ;; If there is an xmlns attribute, it is the new default ;; namespace. (let ((xmlns (jabber-xml-get-xmlns xml-data))) @@ -267,6 +253,25 @@ any string character data of this node" (jabber-xml-node-children xml-data)) xml-data)) +(defun jabber-xml-merge-namespace-declarations (attrs prefixes) + ;; First find any xmlns:foo attributes.. + (dolist (attr attrs) + (let ((attr-name (symbol-name (car attr)))) + (when (string-match "xmlns:" attr-name) + (let ((prefix (substring attr-name (match-end 0))) + (ns-uri (cdr attr))) + ;; A slightly complicated dance to never change the + ;; original value of prefixes (since the caller depends on + ;; it), but also to avoid excessive copying (which remove + ;; always does). Might need to profile and tweak this for + ;; performance. + (setq prefixes + (cons (cons prefix ns-uri) + (if (assoc prefix prefixes) + (remove (assoc prefix prefixes) prefixes) + prefixes))))))) + prefixes) + (provide 'jabber-xml) ;;; arch-tag: ca206e65-7026-4ee8-9af2-ff6a9c5af98a