11package sip
22
33import (
4+ "bytes"
45 "fmt"
56 "strconv"
67 "strings"
@@ -10,9 +11,9 @@ import (
1011// Some of headers parsing are moved to different files for better maintance
1112
1213// A HeaderParser is any function that turns raw header data into one or more Header objects.
13- type HeaderParser func (headerName string , headerData string ) (Header , error )
14+ type HeaderParser func (headerName [] byte , headerData string ) (Header , error )
1415
15- type mapHeadersParser map [string ]HeaderParser
16+ type HeadersParser map [string ]HeaderParser
1617
1718type errComaDetected int
1819
@@ -37,7 +38,7 @@ func (e errComaDetected) Error() string {
3738// t To RFC 3261
3839// u Allow-Events -events- "understand"
3940// v Via RFC 3261
40- var headersParsers = mapHeadersParser {
41+ var headersParsers = HeadersParser {
4142 "c" : headerParserContentType ,
4243 "content-type" : headerParserContentType ,
4344 "f" : headerParserFrom ,
@@ -66,56 +67,49 @@ func DefaultHeadersParser() map[string]HeaderParser {
6667 return headersParsers
6768}
6869
69- // parseMsgHeader will append any parsed header
70- // In case comma seperated values it will add them as new in case comma is detected
71- func (headersParser mapHeadersParser ) parseMsgHeader (msg Message , headerText string ) (err error ) {
72- // p.log.Tracef("parsing header \"%s\"", headerText)
73-
74- colonIdx := strings .Index (headerText , ":" )
70+ // ParseHeader parses a SIP header from the line and appends it to out.
71+ func (headersParser HeadersParser ) ParseHeader (out []Header , line []byte ) ([]Header , error ) {
72+ colonIdx := bytes .IndexByte (line , ':' )
7573 if colonIdx == - 1 {
76- err = fmt .Errorf ("field name with no value in header: %s" , headerText )
77- return
74+ return out , fmt .Errorf ("field name with no value in header: %q" , line )
7875 }
7976
80- fieldName := strings .TrimSpace (headerText [:colonIdx ])
81- lowerFieldName := HeaderToLower (fieldName )
82- fieldText := strings .TrimSpace (headerText [colonIdx + 1 :])
77+ fieldName := bytes .TrimSpace (line [:colonIdx ])
78+ lowerFieldName := headerToLower (fieldName )
79+ fieldValue := bytes .TrimSpace (line [colonIdx + 1 :])
8380
84- headerParser , ok := headersParser [lowerFieldName ]
81+ headerParser , ok := headersParser [string ( lowerFieldName ) ]
8582 if ! ok {
8683 // We have no registered parser for this header type,
8784 // so we encapsulate the header data in a GenericHeader struct.
8885 // We do only forwarding on this with trimmed space. Validation and parsing is required by user
89-
90- header := NewHeader (fieldName , fieldText )
91- msg .AppendHeader (header )
92- return nil
86+ h := NewHeader (string (fieldName ), string (fieldValue ))
87+ out = append (out , h )
88+ return out , nil
9389 }
9490
95- // Support comma seperated value
91+ fieldText := string (fieldValue )
92+ // Support comma separated values
9693 for {
9794 // We have a registered parser for this header type - use it.
9895 // headerParser should detect comma (,) and return as error
99- header , err := headerParser (lowerFieldName , fieldText )
100-
101- // Mostly we will run with no error
96+ h , err := headerParser (lowerFieldName , fieldText )
10297 if err == nil {
103- msg . AppendHeader ( header )
104- return nil
98+ out = append ( out , h )
99+ return out , nil
105100 }
106101
107102 commaErr , ok := err .(errComaDetected )
108103 if ! ok {
109- return err
104+ return out , err
110105 }
111-
112106 // Ok we detected we have comma in header value
113- msg . AppendHeader ( header )
107+ out = append ( out , h )
114108 fieldText = fieldText [commaErr + 1 :]
115109 }
116110}
117111
118- func headerParserCallId (headerName string , headerText string ) (header Header , err error ) {
112+ func headerParserCallId (headerName [] byte , headerText string ) (header Header , err error ) {
119113 var callId CallIDHeader
120114 return & callId , parseCallIdHeader (headerText , & callId )
121115}
@@ -131,7 +125,7 @@ func parseCallIdHeader(headerText string, callId *CallIDHeader) error {
131125 return nil
132126}
133127
134- func headerParserMaxForwards (headerName string , headerText string ) (header Header , err error ) {
128+ func headerParserMaxForwards (headerName [] byte , headerText string ) (header Header , err error ) {
135129 var maxfwd MaxForwardsHeader
136130 return & maxfwd , parseMaxForwardsHeader (headerText , & maxfwd )
137131}
@@ -143,7 +137,7 @@ func parseMaxForwardsHeader(headerText string, maxfwd *MaxForwardsHeader) error
143137 return err
144138}
145139
146- func headerParserCSeq (headerName string , headerText string ) (headers Header , err error ) {
140+ func headerParserCSeq (headerName [] byte , headerText string ) (headers Header , err error ) {
147141 var cseq CSeqHeader
148142 return & cseq , parseCSeqHeader (headerText , & cseq )
149143}
@@ -169,7 +163,7 @@ func parseCSeqHeader(headerText string, cseq *CSeqHeader) error {
169163 return nil
170164}
171165
172- func headerParserContentLength (headerName string , headerText string ) (header Header , err error ) {
166+ func headerParserContentLength (headerName [] byte , headerText string ) (header Header , err error ) {
173167 var contentLength ContentLengthHeader
174168 return & contentLength , parseContentLengthHeader (headerText , & contentLength )
175169}
@@ -182,7 +176,7 @@ func parseContentLengthHeader(headerText string, contentLength *ContentLengthHea
182176}
183177
184178// headerParserContentType parses ContentType header
185- func headerParserContentType (headerName string , headerText string ) (headers Header , err error ) {
179+ func headerParserContentType (headerName [] byte , headerText string ) (headers Header , err error ) {
186180 var contentType ContentTypeHeader
187181 return & contentType , parseContentTypeHeader (headerText , & contentType )
188182}
0 commit comments