Skip to content

Commit

Permalink
Switch away from using http.Header.Write() due to it stripping \n
Browse files Browse the repository at this point in the history
This is needed for some header strings that need to be sent to FreeSWITCH. For example the `extra-headers` header used in `sendevent NOTIFY` when providing a contact URI or the to/from URIs.

This change makes the following header possible:
extra-headers: Messages-Waiting: yes\r\nMessage-Account: example@1.1.1.1\r\nVoice-Message: 1/0\r\n

The main tradeoff here may be an increase of time building the header string. However when testing this out the difference was within microseconds and within error margins.
  • Loading branch information
winsock committed May 18, 2021
1 parent 8a4ed26 commit cf79155
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ eslgo was written from the ground up in idiomatic Go for use in our production p
go get github.com/percipia/eslgo
```
```
github.com/percipia/eslgo v1.4.0
github.com/percipia/eslgo v1.4.1
```

## Overview
Expand Down
34 changes: 34 additions & 0 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,41 @@
*/
package command

import (
"net/textproto"
"sort"
"strings"
)

// Command - A basic interface for FreeSWITCH ESL commands. Implement this if you want to send your own raw data to FreeSIWTCH over the ESL connection. Do not add the eslgo.EndOfMessage(\r\n\r\n) marker, eslgo does that for you.
type Command interface {
BuildMessage() string
}

var crlfToLF = strings.NewReplacer("\r\n", "\n")

// FormatHeaderString - Writes headers in a FreeSWITCH ESL friendly format. Converts headers containing \r\n to \n
func FormatHeaderString(headers textproto.MIMEHeader) string {
var ws strings.Builder

keys := make([]string, len(headers))
i := 0
for key := range headers {
keys[i] = key
i++
}
sort.Strings(keys)

for _, key := range keys {
for _, value := range headers[key] {
value = crlfToLF.Replace(value)
value = textproto.TrimString(value)
ws.WriteString(key)
ws.WriteString(": ")
ws.WriteString(value)
ws.WriteString("\r\n")
}
}
// Remove the extra \r\n
return ws.String()[:ws.Len()-2]
}
9 changes: 1 addition & 8 deletions command/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ package command

import (
"fmt"
"net/http"
"net/textproto"
"strconv"
"strings"
Expand Down Expand Up @@ -78,13 +77,7 @@ func (s *SendEvent) BuildMessage() string {
}

// Format the headers
var headers strings.Builder
err := http.Header(s.Headers).Write(&headers)
if err != nil || headers.Len() < 3 {
return ""
}
// -2 to remove the trailing \r\n added by http.Header.Write
headerString := headers.String()[:headers.Len()-2]
headerString := FormatHeaderString(s.Headers)
if _, ok := s.Headers["Content-Length"]; ok {
return fmt.Sprintf("sendevent %s\r\n%s\r\n\r\n%s", s.Name, headerString, s.Body)
}
Expand Down
10 changes: 1 addition & 9 deletions command/sendmsg.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ package command

import (
"fmt"
"net/http"
"net/textproto"
"strconv"
"strings"
)

type SendMessage struct {
Expand Down Expand Up @@ -47,13 +45,7 @@ func (s *SendMessage) BuildMessage() string {
}

// Format the headers
var headers strings.Builder
err := http.Header(s.Headers).Write(&headers)
if err != nil || headers.Len() < 3 {
return ""
}
// -2 to remove the trailing \r\n added by http.Header.Write
headerString := headers.String()[:headers.Len()-2]
headerString := FormatHeaderString(s.Headers)
if _, ok := s.Headers["Content-Length"]; ok {
return fmt.Sprintf("sendmsg %s\r\n%s\r\n\r\n%s", s.UUID, headerString, s.Body)
}
Expand Down

0 comments on commit cf79155

Please sign in to comment.