xmpp/layer2.go
changeset 163 3f891f7fe817
parent 147 d7679d991b17
equal deleted inserted replaced
162:7b5586a5e109 163:3f891f7fe817
     5 
     5 
     6 import (
     6 import (
     7 	"encoding/xml"
     7 	"encoding/xml"
     8 	"fmt"
     8 	"fmt"
     9 	"io"
     9 	"io"
       
    10 	"log"
    10 	"reflect"
    11 	"reflect"
    11 	"strings"
    12 	"strings"
    12 )
    13 )
    13 
    14 
    14 // Read bytes from a reader, unmarshal them as XML into structures of
    15 // Read bytes from a reader, unmarshal them as XML into structures of
    15 // the appropriate type, and send those structures on a channel.
    16 // the appropriate type, and send those structures on a channel.
    16 func recvXml(r io.Reader, ch chan<- interface{},
    17 func (cl *Client) recvXml(r io.Reader, ch chan<- interface{},
    17 	extStanza map[xml.Name]reflect.Type) {
    18 	extStanza map[xml.Name]reflect.Type) {
    18 	if _, ok := Debug.(*noLog); !ok {
    19 
    19 		pr, pw := io.Pipe()
       
    20 		go tee(r, pw, "S: ")
       
    21 		r = pr
       
    22 	}
       
    23 	defer close(ch)
    20 	defer close(ch)
    24 
    21 
    25 	// This trick loads our namespaces into the parser.
    22 	// This trick loads our namespaces into the parser.
    26 	nsstr := fmt.Sprintf(`<a xmlns="%s" xmlns:stream="%s">`,
    23 	nsstr := fmt.Sprintf(`<a xmlns="%s" xmlns:stream="%s">`,
    27 		NsClient, NsStream)
    24 		NsClient, NsStream)
    33 	for {
    30 	for {
    34 		// Sniff the next token on the stream.
    31 		// Sniff the next token on the stream.
    35 		t, err := p.Token()
    32 		t, err := p.Token()
    36 		if t == nil {
    33 		if t == nil {
    37 			if err != io.EOF {
    34 			if err != io.EOF {
    38 				Warn.Logf("read: %s", err)
    35 				cl.setError(fmt.Errorf("recv: %v", err))
    39 			}
    36 			}
    40 			break
    37 			break
    41 		}
    38 		}
    42 		var se xml.StartElement
    39 		var se xml.StartElement
    43 		var ok bool
    40 		var ok bool
    49 		var obj interface{}
    46 		var obj interface{}
    50 		switch se.Name.Space + " " + se.Name.Local {
    47 		switch se.Name.Space + " " + se.Name.Local {
    51 		case NsStream + " stream":
    48 		case NsStream + " stream":
    52 			st, err := parseStream(se)
    49 			st, err := parseStream(se)
    53 			if err != nil {
    50 			if err != nil {
    54 				Warn.Logf("unmarshal stream: %s", err)
    51 				cl.setError(fmt.Errorf("recv: %v", err))
    55 				break Loop
    52 				break Loop
    56 			}
    53 			}
    57 			ch <- st
    54 			ch <- st
    58 			continue
    55 			continue
    59 		case "stream error", NsStream + " error":
    56 		case "stream error", NsStream + " error":
    71 			obj = &Message{}
    68 			obj = &Message{}
    72 		case NsClient + " presence":
    69 		case NsClient + " presence":
    73 			obj = &Presence{}
    70 			obj = &Presence{}
    74 		default:
    71 		default:
    75 			obj = &Generic{}
    72 			obj = &Generic{}
    76 			Info.Logf("Ignoring unrecognized: %s %s", se.Name.Space,
    73 			if Debug {
    77 				se.Name.Local)
    74 				log.Printf("Ignoring unrecognized: %s %s",
       
    75 					se.Name.Space, se.Name.Local)
       
    76 			}
    78 		}
    77 		}
    79 
    78 
    80 		// Read the complete XML stanza.
    79 		// Read the complete XML stanza.
    81 		err = p.DecodeElement(obj, &se)
    80 		err = p.DecodeElement(obj, &se)
    82 		if err != nil {
    81 		if err != nil {
    83 			Warn.Logf("unmarshal: %s", err)
    82 			cl.setError(fmt.Errorf("recv: %v", err))
    84 			break Loop
    83 			break Loop
    85 		}
    84 		}
    86 
    85 
    87 		// If it's a Stanza, we try to unmarshal its innerxml
    86 		// If it's a Stanza, we try to unmarshal its innerxml
    88 		// into objects of the appropriate respective
    87 		// into objects of the appropriate respective
    89 		// types. This is specified by our extensions.
    88 		// types. This is specified by our extensions.
    90 		if st, ok := obj.(Stanza); ok {
    89 		if st, ok := obj.(Stanza); ok {
    91 			err = parseExtended(st.GetHeader(), extStanza)
    90 			err = parseExtended(st.GetHeader(), extStanza)
    92 			if err != nil {
    91 			if err != nil {
    93 				Warn.Logf("ext unmarshal: %s", err)
    92 				cl.setError(fmt.Errorf("recv: %v", err))
    94 				break Loop
    93 				break Loop
    95 			}
    94 			}
    96 		}
    95 		}
    97 
    96 
    98 		// Put it on the channel.
    97 		// Put it on the channel.
   131 	return nil
   130 	return nil
   132 }
   131 }
   133 
   132 
   134 // Receive structures on a channel, marshal them to XML, and send the
   133 // Receive structures on a channel, marshal them to XML, and send the
   135 // bytes on a writer.
   134 // bytes on a writer.
   136 func sendXml(w io.Writer, ch <-chan interface{}) {
   135 func (cl *Client) sendXml(w io.Writer, ch <-chan interface{}) {
   137 	if _, ok := Debug.(*noLog); !ok {
       
   138 		pr, pw := io.Pipe()
       
   139 		go tee(pr, w, "C: ")
       
   140 		w = pw
       
   141 	}
       
   142 	defer func(w io.Writer) {
   136 	defer func(w io.Writer) {
   143 		if c, ok := w.(io.Closer); ok {
   137 		if c, ok := w.(io.Closer); ok {
   144 			c.Close()
   138 			c.Close()
   145 		}
   139 		}
   146 	}(w)
   140 	}(w)
   149 
   143 
   150 	for obj := range ch {
   144 	for obj := range ch {
   151 		if st, ok := obj.(*stream); ok {
   145 		if st, ok := obj.(*stream); ok {
   152 			_, err := w.Write([]byte(st.String()))
   146 			_, err := w.Write([]byte(st.String()))
   153 			if err != nil {
   147 			if err != nil {
   154 				Warn.Logf("write: %s", err)
   148 				cl.setError(fmt.Errorf("send: %v", err))
       
   149 				break
   155 			}
   150 			}
   156 		} else {
   151 		} else {
   157 			err := enc.Encode(obj)
   152 			err := enc.Encode(obj)
   158 			if err != nil {
   153 			if err != nil {
   159 				Warn.Logf("marshal: %s", err)
   154 				cl.setError(fmt.Errorf("send: %v", err))
   160 				break
   155 				break
   161 			}
   156 			}
   162 		}
   157 		}
   163 	}
   158 	}
   164 }
   159 }