request.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. package sip
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. "github.com/ghettovoice/gosip/log"
  8. )
  9. // Request RFC 3261 - 7.1.
  10. type Request interface {
  11. Message
  12. Method() RequestMethod
  13. SetMethod(method RequestMethod)
  14. Recipient() Uri
  15. SetRecipient(recipient Uri)
  16. /* Common Helpers */
  17. IsInvite() bool
  18. }
  19. type request struct {
  20. message
  21. method RequestMethod
  22. recipient Uri
  23. }
  24. func NewRequest(
  25. messID MessageID,
  26. method RequestMethod,
  27. recipient Uri,
  28. sipVersion string,
  29. hdrs []Header,
  30. body string,
  31. fields log.Fields,
  32. ) Request {
  33. req := new(request)
  34. if messID == "" {
  35. req.messID = NextMessageID()
  36. } else {
  37. req.messID = messID
  38. }
  39. req.startLine = req.StartLine
  40. req.sipVersion = sipVersion
  41. req.headers = newHeaders(hdrs)
  42. req.method = method
  43. req.recipient = recipient
  44. req.body = body
  45. req.fields = fields.WithFields(log.Fields{
  46. "request_id": req.messID,
  47. })
  48. return req
  49. }
  50. func (req *request) Short() string {
  51. if req == nil {
  52. return "<nil>"
  53. }
  54. fields := log.Fields{
  55. "method": req.Method(),
  56. "recipient": req.Recipient(),
  57. "transport": req.Transport(),
  58. "source": req.Source(),
  59. "destination": req.Destination(),
  60. }
  61. if cseq, ok := req.CSeq(); ok {
  62. fields["sequence"] = cseq.SeqNo
  63. }
  64. fields = req.Fields().WithFields(fields)
  65. return fmt.Sprintf("sip.Request<%s>", fields)
  66. }
  67. func (req *request) Method() RequestMethod {
  68. req.mu.RLock()
  69. defer req.mu.RUnlock()
  70. return req.method
  71. }
  72. func (req *request) SetMethod(method RequestMethod) {
  73. req.mu.Lock()
  74. req.method = method
  75. req.mu.Unlock()
  76. }
  77. func (req *request) Recipient() Uri {
  78. req.mu.RLock()
  79. defer req.mu.RUnlock()
  80. return req.recipient
  81. }
  82. func (req *request) SetRecipient(recipient Uri) {
  83. req.mu.Lock()
  84. req.recipient = recipient
  85. req.mu.Unlock()
  86. }
  87. // StartLine returns Request Line - RFC 2361 7.1.
  88. func (req *request) StartLine() string {
  89. var buffer bytes.Buffer
  90. // Every SIP request starts with a Request Line - RFC 2361 7.1.
  91. buffer.WriteString(
  92. fmt.Sprintf(
  93. "%s %s %s",
  94. string(req.Method()),
  95. req.Recipient(),
  96. req.SipVersion(),
  97. ),
  98. )
  99. return buffer.String()
  100. }
  101. func (req *request) Clone() Message {
  102. return cloneRequest(req, "", nil)
  103. }
  104. func (req *request) Fields() log.Fields {
  105. return req.fields.WithFields(log.Fields{
  106. "transport": req.Transport(),
  107. "source": req.Source(),
  108. "destination": req.Destination(),
  109. })
  110. }
  111. func (req *request) WithFields(fields log.Fields) Message {
  112. req.mu.Lock()
  113. req.fields = req.fields.WithFields(fields)
  114. req.mu.Unlock()
  115. return req
  116. }
  117. func (req *request) IsInvite() bool {
  118. return req.Method() == INVITE
  119. }
  120. func (req *request) IsAck() bool {
  121. return req.Method() == ACK
  122. }
  123. func (req *request) IsCancel() bool {
  124. return req.Method() == CANCEL
  125. }
  126. func (req *request) Transport() string {
  127. if tp := req.message.Transport(); tp != "" {
  128. return strings.ToUpper(tp)
  129. }
  130. var tp string
  131. if viaHop, ok := req.ViaHop(); ok && viaHop.Transport != "" {
  132. tp = viaHop.Transport
  133. } else {
  134. tp = DefaultProtocol
  135. }
  136. uri := req.Recipient()
  137. if hdrs := req.GetHeaders("Route"); len(hdrs) > 0 {
  138. routeHeader, ok := hdrs[0].(*RouteHeader)
  139. if ok && len(routeHeader.Addresses) > 0 {
  140. uri = routeHeader.Addresses[0]
  141. }
  142. }
  143. if uri != nil {
  144. if uri.UriParams() != nil {
  145. if val, ok := uri.UriParams().Get("transport"); ok && !val.Equals("") {
  146. tp = strings.ToUpper(val.String())
  147. }
  148. }
  149. if uri.IsEncrypted() {
  150. if tp == "TCP" {
  151. tp = "TLS"
  152. } else if tp == "WS" {
  153. tp = "WSS"
  154. }
  155. }
  156. }
  157. if tp == "UDP" && len(req.String()) > int(MTU)-200 {
  158. tp = "TCP"
  159. }
  160. return tp
  161. }
  162. func (req *request) Source() string {
  163. if src := req.message.Source(); src != "" {
  164. return src
  165. }
  166. viaHop, ok := req.ViaHop()
  167. if !ok {
  168. return ""
  169. }
  170. var (
  171. host string
  172. port Port
  173. )
  174. host = viaHop.Host
  175. if viaHop.Port != nil {
  176. port = *viaHop.Port
  177. } else {
  178. port = DefaultPort(req.Transport())
  179. }
  180. if viaHop.Params != nil {
  181. if received, ok := viaHop.Params.Get("received"); ok && received.String() != "" {
  182. host = received.String()
  183. }
  184. if rport, ok := viaHop.Params.Get("rport"); ok && rport != nil && rport.String() != "" {
  185. if p, err := strconv.Atoi(rport.String()); err == nil {
  186. port = Port(uint16(p))
  187. }
  188. }
  189. }
  190. return fmt.Sprintf("%v:%v", host, port)
  191. }
  192. func (req *request) Destination() string {
  193. if dest := req.message.Destination(); dest != "" {
  194. return dest
  195. }
  196. var uri *SipUri
  197. if hdrs := req.GetHeaders("Route"); len(hdrs) > 0 {
  198. routeHeader, ok := hdrs[0].(*RouteHeader)
  199. if ok && len(routeHeader.Addresses) > 0 {
  200. uri = routeHeader.Addresses[0].(*SipUri)
  201. }
  202. }
  203. if uri == nil {
  204. if u, ok := req.Recipient().(*SipUri); ok {
  205. uri = u
  206. } else {
  207. return ""
  208. }
  209. }
  210. host := uri.FHost
  211. var port Port
  212. if uri.FPort != nil {
  213. port = *uri.FPort
  214. } else {
  215. port = DefaultPort(req.Transport())
  216. }
  217. return fmt.Sprintf("%v:%v", host, port)
  218. }
  219. // NewAckRequest creates ACK request for 2xx INVITE
  220. // https://tools.ietf.org/html/rfc3261#section-13.2.2.4
  221. func NewAckRequest(ackID MessageID, inviteRequest Request, inviteResponse Response, body string, fields log.Fields) Request {
  222. recipient := inviteRequest.Recipient()
  223. if contact, ok := inviteResponse.Contact(); ok {
  224. // For ws and wss (like clients in browser), don't use Contact
  225. if strings.Index(strings.ToLower(recipient.String()), "transport=ws") == -1 {
  226. recipient = contact.Address
  227. }
  228. }
  229. ackRequest := NewRequest(
  230. ackID,
  231. ACK,
  232. recipient,
  233. inviteRequest.SipVersion(),
  234. []Header{},
  235. body,
  236. inviteRequest.Fields().
  237. WithFields(fields).
  238. WithFields(log.Fields{
  239. "invite_request_id": inviteRequest.MessageID(),
  240. "invite_response_id": inviteResponse.MessageID(),
  241. }),
  242. )
  243. CopyHeaders("Via", inviteRequest, ackRequest)
  244. if inviteResponse.IsSuccess() {
  245. // update branch, 2xx ACK is separate Tx
  246. viaHop, _ := ackRequest.ViaHop()
  247. viaHop.Params.Add("branch", String{Str: GenerateBranch()})
  248. }
  249. if len(inviteRequest.GetHeaders("Route")) > 0 {
  250. CopyHeaders("Route", inviteRequest, ackRequest)
  251. } else {
  252. hdrs := inviteResponse.GetHeaders("Record-Route")
  253. for i := len(hdrs) - 1; i >= 0; i-- {
  254. h := hdrs[i]
  255. uris := make([]Uri, 0)
  256. for j := len(h.(*RecordRouteHeader).Addresses) - 1; j >= 0; j-- {
  257. uris = append(uris, h.(*RecordRouteHeader).Addresses[j].Clone())
  258. }
  259. ackRequest.AppendHeader(&RouteHeader{
  260. Addresses: uris,
  261. })
  262. }
  263. }
  264. maxForwardsHeader := MaxForwards(70)
  265. ackRequest.AppendHeader(&maxForwardsHeader)
  266. CopyHeaders("From", inviteRequest, ackRequest)
  267. CopyHeaders("To", inviteResponse, ackRequest)
  268. CopyHeaders("Call-ID", inviteRequest, ackRequest)
  269. CopyHeaders("CSeq", inviteRequest, ackRequest)
  270. cseq, _ := ackRequest.CSeq()
  271. cseq.MethodName = ACK
  272. ackRequest.SetBody("", true)
  273. ackRequest.SetTransport(inviteRequest.Transport())
  274. ackRequest.SetSource(inviteRequest.Source())
  275. ackRequest.SetDestination(inviteRequest.Destination())
  276. return ackRequest
  277. }
  278. func NewCancelRequest(cancelID MessageID, requestForCancel Request, fields log.Fields) Request {
  279. cancelReq := NewRequest(
  280. cancelID,
  281. CANCEL,
  282. requestForCancel.Recipient(),
  283. requestForCancel.SipVersion(),
  284. []Header{},
  285. "",
  286. requestForCancel.Fields().
  287. WithFields(fields).
  288. WithFields(log.Fields{
  289. "cancelling_request_id": requestForCancel.MessageID(),
  290. }),
  291. )
  292. viaHop, _ := requestForCancel.ViaHop()
  293. cancelReq.AppendHeader(ViaHeader{viaHop.Clone()})
  294. CopyHeaders("Route", requestForCancel, cancelReq)
  295. maxForwardsHeader := MaxForwards(70)
  296. cancelReq.AppendHeader(&maxForwardsHeader)
  297. CopyHeaders("From", requestForCancel, cancelReq)
  298. CopyHeaders("To", requestForCancel, cancelReq)
  299. CopyHeaders("Call-ID", requestForCancel, cancelReq)
  300. CopyHeaders("CSeq", requestForCancel, cancelReq)
  301. cseq, _ := cancelReq.CSeq()
  302. cseq.MethodName = CANCEL
  303. cancelReq.SetBody("", true)
  304. cancelReq.SetTransport(requestForCancel.Transport())
  305. cancelReq.SetSource(requestForCancel.Source())
  306. cancelReq.SetDestination(requestForCancel.Destination())
  307. return cancelReq
  308. }
  309. func cloneRequest(req Request, id MessageID, fields log.Fields) Request {
  310. newFields := req.Fields()
  311. if fields != nil {
  312. newFields = newFields.WithFields(fields)
  313. }
  314. newReq := NewRequest(
  315. id,
  316. req.Method(),
  317. req.Recipient().Clone(),
  318. req.SipVersion(),
  319. cloneHeaders(req),
  320. req.Body(),
  321. newFields,
  322. )
  323. newReq.SetTransport(req.Transport())
  324. newReq.SetSource(req.Source())
  325. newReq.SetDestination(req.Destination())
  326. return newReq
  327. }
  328. func CopyRequest(req Request) Request {
  329. return cloneRequest(req, req.MessageID(), nil)
  330. }