message.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. package sip
  2. import (
  3. "bytes"
  4. "strings"
  5. "sync"
  6. uuid "github.com/satori/go.uuid"
  7. "github.com/ghettovoice/gosip/log"
  8. )
  9. // A representation of a SIP method.
  10. // This is syntactic sugar around the string type, so make sure to use
  11. // the Equals method rather than built-in equality, or you'll fall foul of case differences.
  12. // If you're defining your own Method, uppercase is preferred but not compulsory.
  13. type RequestMethod string
  14. // StatusCode - response status code: 1xx - 6xx
  15. type StatusCode uint16
  16. // Determine if the given method equals some other given method.
  17. // This is syntactic sugar for case insensitive equality checking.
  18. func (method *RequestMethod) Equals(other *RequestMethod) bool {
  19. if method != nil && other != nil {
  20. return strings.EqualFold(string(*method), string(*other))
  21. } else {
  22. return method == other
  23. }
  24. }
  25. // It's nicer to avoid using raw strings to represent methods, so the following standard
  26. // method names are defined here as constants for convenience.
  27. const (
  28. INVITE RequestMethod = "INVITE"
  29. ACK RequestMethod = "ACK"
  30. CANCEL RequestMethod = "CANCEL"
  31. BYE RequestMethod = "BYE"
  32. REGISTER RequestMethod = "REGISTER"
  33. OPTIONS RequestMethod = "OPTIONS"
  34. SUBSCRIBE RequestMethod = "SUBSCRIBE"
  35. NOTIFY RequestMethod = "NOTIFY"
  36. REFER RequestMethod = "REFER"
  37. INFO RequestMethod = "INFO"
  38. MESSAGE RequestMethod = "MESSAGE"
  39. PRACK RequestMethod = "PRACK"
  40. UPDATE RequestMethod = "UPDATE"
  41. PUBLISH RequestMethod = "PUBLISH"
  42. )
  43. type MessageID string
  44. func NextMessageID() MessageID {
  45. return MessageID(uuid.Must(uuid.NewV4()).String())
  46. }
  47. // Message introduces common SIP message RFC 3261 - 7.
  48. type Message interface {
  49. MessageID() MessageID
  50. Clone() Message
  51. // Start line returns message start line.
  52. StartLine() string
  53. // String returns string representation of SIP message in RFC 3261 form.
  54. String() string
  55. // Short returns short string info about message.
  56. Short() string
  57. // SipVersion returns SIP protocol version.
  58. SipVersion() string
  59. // SetSipVersion sets SIP protocol version.
  60. SetSipVersion(version string)
  61. // Headers returns all message headers.
  62. Headers() []Header
  63. // GetHeaders returns slice of headers of the given type.
  64. GetHeaders(name string) []Header
  65. // AppendHeader appends header to message.
  66. AppendHeader(header Header)
  67. // PrependHeader prepends header to message.
  68. PrependHeader(header Header)
  69. PrependHeaderAfter(header Header, afterName string)
  70. // RemoveHeader removes header from message.
  71. RemoveHeader(name string)
  72. ReplaceHeaders(name string, headers []Header)
  73. // Body returns message body.
  74. Body() string
  75. // SetBody sets message body.
  76. SetBody(body string, setContentLength bool)
  77. /* Helper getters for common headers */
  78. // CallID returns 'Call-ID' header.
  79. CallID() (*CallID, bool)
  80. // Via returns the top 'Via' header field.
  81. Via() (ViaHeader, bool)
  82. // ViaHop returns the first segment of the top 'Via' header.
  83. ViaHop() (*ViaHop, bool)
  84. // From returns 'From' header field.
  85. From() (*FromHeader, bool)
  86. // To returns 'To' header field.
  87. To() (*ToHeader, bool)
  88. // CSeq returns 'CSeq' header field.
  89. CSeq() (*CSeq, bool)
  90. ContentLength() (*ContentLength, bool)
  91. ContentType() (*ContentType, bool)
  92. Contact() (*ContactHeader, bool)
  93. Transport() string
  94. SetTransport(tp string)
  95. Source() string
  96. SetSource(src string)
  97. Destination() string
  98. SetDestination(dest string)
  99. IsCancel() bool
  100. IsAck() bool
  101. Fields() log.Fields
  102. WithFields(fields log.Fields) Message
  103. }
  104. // headers is a struct with methods to work with SIP headers.
  105. type headers struct {
  106. mu sync.RWMutex
  107. // The logical SIP headers attached to this message.
  108. headers map[string][]Header
  109. // The order the headers should be displayed in.
  110. headerOrder []string
  111. }
  112. func newHeaders(hdrs []Header) *headers {
  113. hs := new(headers)
  114. hs.headers = make(map[string][]Header)
  115. hs.headerOrder = make([]string, 0)
  116. for _, header := range hdrs {
  117. hs.AppendHeader(header)
  118. }
  119. return hs
  120. }
  121. func (hs *headers) String() string {
  122. buffer := bytes.Buffer{}
  123. hs.mu.RLock()
  124. // Construct each header in turn and add it to the message.
  125. for typeIdx, name := range hs.headerOrder {
  126. headers := hs.headers[name]
  127. for idx, header := range headers {
  128. buffer.WriteString(header.String())
  129. if typeIdx < len(hs.headerOrder) || idx < len(headers) {
  130. buffer.WriteString("\r\n")
  131. }
  132. }
  133. }
  134. hs.mu.RUnlock()
  135. return buffer.String()
  136. }
  137. // Add the given header.
  138. func (hs *headers) AppendHeader(header Header) {
  139. name := strings.ToLower(header.Name())
  140. hs.mu.Lock()
  141. if _, ok := hs.headers[name]; ok {
  142. hs.headers[name] = append(hs.headers[name], header)
  143. } else {
  144. hs.headers[name] = []Header{header}
  145. hs.headerOrder = append(hs.headerOrder, name)
  146. }
  147. hs.mu.Unlock()
  148. }
  149. // AddFrontHeader adds header to the front of header list
  150. // if there is no header has h's name, add h to the font of all headers
  151. // if there are some headers have h's name, add h to front of the sublist
  152. func (hs *headers) PrependHeader(header Header) {
  153. name := strings.ToLower(header.Name())
  154. hs.mu.Lock()
  155. if hdrs, ok := hs.headers[name]; ok {
  156. hs.headers[name] = append([]Header{header}, hdrs...)
  157. } else {
  158. hs.headers[name] = []Header{header}
  159. newOrder := make([]string, 1, len(hs.headerOrder)+1)
  160. newOrder[0] = name
  161. hs.headerOrder = append(newOrder, hs.headerOrder...)
  162. }
  163. hs.mu.Unlock()
  164. }
  165. func (hs *headers) PrependHeaderAfter(header Header, afterName string) {
  166. headerName := strings.ToLower(header.Name())
  167. afterName = strings.ToLower(afterName)
  168. hs.mu.Lock()
  169. if _, ok := hs.headers[afterName]; ok {
  170. afterIdx := -1
  171. headerIdx := -1
  172. for i, name := range hs.headerOrder {
  173. if name == afterName {
  174. afterIdx = i
  175. }
  176. if name == headerName {
  177. headerIdx = i
  178. }
  179. }
  180. if headerIdx == -1 {
  181. hs.headers[headerName] = []Header{header}
  182. newOrder := make([]string, 0)
  183. newOrder = append(newOrder, hs.headerOrder[:afterIdx+1]...)
  184. newOrder = append(newOrder, headerName)
  185. newOrder = append(newOrder, hs.headerOrder[afterIdx+1:]...)
  186. hs.headerOrder = newOrder
  187. } else {
  188. hs.headers[headerName] = append([]Header{header}, hs.headers[headerName]...)
  189. newOrder := make([]string, 0)
  190. if afterIdx < headerIdx {
  191. newOrder = append(newOrder, hs.headerOrder[:afterIdx+1]...)
  192. newOrder = append(newOrder, headerName)
  193. newOrder = append(newOrder, hs.headerOrder[afterIdx+1:headerIdx]...)
  194. newOrder = append(newOrder, hs.headerOrder[headerIdx+1:]...)
  195. } else {
  196. newOrder = append(newOrder, hs.headerOrder[:headerIdx]...)
  197. newOrder = append(newOrder, hs.headerOrder[headerIdx+1:afterIdx+1]...)
  198. newOrder = append(newOrder, headerName)
  199. newOrder = append(newOrder, hs.headerOrder[afterIdx+1:]...)
  200. }
  201. hs.headerOrder = newOrder
  202. }
  203. hs.mu.Unlock()
  204. } else {
  205. hs.mu.Unlock()
  206. hs.PrependHeader(header)
  207. }
  208. }
  209. func (hs *headers) ReplaceHeaders(name string, headers []Header) {
  210. name = strings.ToLower(name)
  211. hs.mu.Lock()
  212. if _, ok := hs.headers[name]; ok {
  213. hs.headers[name] = headers
  214. }
  215. hs.mu.Unlock()
  216. }
  217. // Gets some headers.
  218. func (hs *headers) Headers() []Header {
  219. hdrs := make([]Header, 0)
  220. hs.mu.RLock()
  221. for _, key := range hs.headerOrder {
  222. hdrs = append(hdrs, hs.headers[key]...)
  223. }
  224. hs.mu.RUnlock()
  225. return hdrs
  226. }
  227. func (hs *headers) GetHeaders(name string) []Header {
  228. name = strings.ToLower(name)
  229. hs.mu.RLock()
  230. defer hs.mu.RUnlock()
  231. if hs.headers == nil {
  232. hs.headers = map[string][]Header{}
  233. hs.headerOrder = []string{}
  234. }
  235. if headers, ok := hs.headers[name]; ok {
  236. return headers
  237. }
  238. return []Header{}
  239. }
  240. func (hs *headers) RemoveHeader(name string) {
  241. name = strings.ToLower(name)
  242. hs.mu.Lock()
  243. delete(hs.headers, name)
  244. // update order slice
  245. for idx, entry := range hs.headerOrder {
  246. if entry == name {
  247. hs.headerOrder = append(hs.headerOrder[:idx], hs.headerOrder[idx+1:]...)
  248. break
  249. }
  250. }
  251. hs.mu.Unlock()
  252. }
  253. // CloneHeaders returns all cloned headers in slice.
  254. func (hs *headers) CloneHeaders() []Header {
  255. return cloneHeaders(hs)
  256. }
  257. func cloneHeaders(msg interface{ Headers() []Header }) []Header {
  258. hdrs := make([]Header, 0)
  259. for _, header := range msg.Headers() {
  260. hdrs = append(hdrs, header.Clone())
  261. }
  262. return hdrs
  263. }
  264. func (hs *headers) CallID() (*CallID, bool) {
  265. hdrs := hs.GetHeaders("Call-ID")
  266. if len(hdrs) == 0 {
  267. return nil, false
  268. }
  269. callId, ok := hdrs[0].(*CallID)
  270. if !ok {
  271. return nil, false
  272. }
  273. return callId, true
  274. }
  275. func (hs *headers) Via() (ViaHeader, bool) {
  276. hdrs := hs.GetHeaders("Via")
  277. if len(hdrs) == 0 {
  278. return nil, false
  279. }
  280. via, ok := (hdrs[0]).(ViaHeader)
  281. if !ok {
  282. return nil, false
  283. }
  284. return via, true
  285. }
  286. func (hs *headers) ViaHop() (*ViaHop, bool) {
  287. via, ok := hs.Via()
  288. if !ok {
  289. return nil, false
  290. }
  291. hops := []*ViaHop(via)
  292. if len(hops) == 0 {
  293. return nil, false
  294. }
  295. return hops[0], true
  296. }
  297. func (hs *headers) From() (*FromHeader, bool) {
  298. hdrs := hs.GetHeaders("From")
  299. if len(hdrs) == 0 {
  300. return nil, false
  301. }
  302. from, ok := hdrs[0].(*FromHeader)
  303. if !ok {
  304. return nil, false
  305. }
  306. return from, true
  307. }
  308. func (hs *headers) To() (*ToHeader, bool) {
  309. hdrs := hs.GetHeaders("To")
  310. if len(hdrs) == 0 {
  311. return nil, false
  312. }
  313. to, ok := hdrs[0].(*ToHeader)
  314. if !ok {
  315. return nil, false
  316. }
  317. return to, true
  318. }
  319. func (hs *headers) CSeq() (*CSeq, bool) {
  320. hdrs := hs.GetHeaders("CSeq")
  321. if len(hdrs) == 0 {
  322. return nil, false
  323. }
  324. cseq, ok := hdrs[0].(*CSeq)
  325. if !ok {
  326. return nil, false
  327. }
  328. return cseq, true
  329. }
  330. func (hs *headers) ContentLength() (*ContentLength, bool) {
  331. hdrs := hs.GetHeaders("Content-Length")
  332. if len(hdrs) == 0 {
  333. return nil, false
  334. }
  335. contentLength, ok := hdrs[0].(*ContentLength)
  336. if !ok {
  337. return nil, false
  338. }
  339. return contentLength, true
  340. }
  341. func (hs *headers) ContentType() (*ContentType, bool) {
  342. hdrs := hs.GetHeaders("Content-Type")
  343. if len(hdrs) == 0 {
  344. return nil, false
  345. }
  346. contentType, ok := hdrs[0].(*ContentType)
  347. if !ok {
  348. return nil, false
  349. }
  350. return contentType, true
  351. }
  352. func (hs *headers) Contact() (*ContactHeader, bool) {
  353. hdrs := hs.GetHeaders("Contact")
  354. if len(hdrs) == 0 {
  355. return nil, false
  356. }
  357. contactHeader, ok := hdrs[0].(*ContactHeader)
  358. if !ok {
  359. return nil, false
  360. }
  361. return contactHeader, true
  362. }
  363. // basic message implementation
  364. type message struct {
  365. // message headers
  366. *headers
  367. mu sync.RWMutex
  368. messID MessageID
  369. sipVersion string
  370. body string
  371. startLine func() string
  372. tp string
  373. src string
  374. dest string
  375. fields log.Fields
  376. }
  377. func (msg *message) MessageID() MessageID {
  378. return msg.messID
  379. }
  380. func (msg *message) StartLine() string {
  381. return msg.startLine()
  382. }
  383. func (msg *message) Fields() log.Fields {
  384. msg.mu.RLock()
  385. defer msg.mu.RUnlock()
  386. return msg.fields.WithFields(log.Fields{
  387. "transport": msg.tp,
  388. "source": msg.src,
  389. "destination": msg.dest,
  390. })
  391. }
  392. func (msg *message) String() string {
  393. var buffer bytes.Buffer
  394. // write message start line
  395. buffer.WriteString(msg.StartLine() + "\r\n")
  396. // Write the headers.
  397. msg.mu.RLock()
  398. buffer.WriteString(msg.headers.String())
  399. msg.mu.RUnlock()
  400. // message body
  401. buffer.WriteString("\r\n" + msg.Body())
  402. return buffer.String()
  403. }
  404. func (msg *message) SipVersion() string {
  405. msg.mu.RLock()
  406. defer msg.mu.RUnlock()
  407. return msg.sipVersion
  408. }
  409. func (msg *message) SetSipVersion(version string) {
  410. msg.mu.Lock()
  411. msg.sipVersion = version
  412. msg.mu.Unlock()
  413. }
  414. func (msg *message) Body() string {
  415. msg.mu.RLock()
  416. defer msg.mu.RUnlock()
  417. return msg.body
  418. }
  419. // SetBody sets message body, calculates it length and add 'Content-Length' header.
  420. func (msg *message) SetBody(body string, setContentLength bool) {
  421. msg.mu.Lock()
  422. msg.body = body
  423. msg.mu.Unlock()
  424. if setContentLength {
  425. hdrs := msg.GetHeaders("Content-Length")
  426. if len(hdrs) == 0 {
  427. length := ContentLength(len(body))
  428. msg.AppendHeader(&length)
  429. } else {
  430. length := ContentLength(len(body))
  431. msg.ReplaceHeaders("Content-Length", []Header{&length})
  432. }
  433. }
  434. }
  435. func (msg *message) Transport() string {
  436. msg.mu.RLock()
  437. defer msg.mu.RUnlock()
  438. return msg.tp
  439. }
  440. func (msg *message) SetTransport(tp string) {
  441. msg.mu.Lock()
  442. msg.tp = strings.ToUpper(tp)
  443. msg.mu.Unlock()
  444. }
  445. func (msg *message) Source() string {
  446. msg.mu.RLock()
  447. defer msg.mu.RUnlock()
  448. return msg.src
  449. }
  450. func (msg *message) SetSource(src string) {
  451. msg.mu.Lock()
  452. msg.src = src
  453. msg.mu.Unlock()
  454. }
  455. func (msg *message) Destination() string {
  456. msg.mu.RLock()
  457. defer msg.mu.RUnlock()
  458. return msg.dest
  459. }
  460. func (msg *message) SetDestination(dest string) {
  461. msg.mu.Lock()
  462. msg.dest = dest
  463. msg.mu.Unlock()
  464. }
  465. // Copy all headers of one type from one message to another.
  466. // Appending to any headers that were already there.
  467. func CopyHeaders(name string, from, to Message) {
  468. name = strings.ToLower(name)
  469. for _, h := range from.GetHeaders(name) {
  470. to.AppendHeader(h.Clone())
  471. }
  472. }
  473. func PrependCopyHeaders(name string, from, to Message) {
  474. name = strings.ToLower(name)
  475. for _, h := range from.GetHeaders(name) {
  476. to.PrependHeader(h.Clone())
  477. }
  478. }
  479. type MessageMapper func(msg Message) Message