diff --git a/basic_client.go b/basic_client.go index 435a6a0..0c4489a 100644 --- a/basic_client.go +++ b/basic_client.go @@ -19,6 +19,8 @@ type BasicClient struct { // Don't insert newlines or indentation when marshalling to SGML/XML NoIndent bool + // Use carriage returns on new lines + CarriageReturn bool } // OfxVersion returns the OFX specification version this BasicClient will marshal @@ -54,6 +56,11 @@ func (c *BasicClient) IndentRequests() bool { return !c.NoIndent } +// CarriageReturnNewLines returns true if carriage returns should be used on new lines, false otherwise +func (c *BasicClient) CarriageReturnNewLines() bool { + return c.CarriageReturn +} + func (c *BasicClient) RawRequest(URL string, r io.Reader) (*http.Response, error) { if !strings.HasPrefix(URL, "https://") { return nil, errors.New("Refusing to send OFX request with possible plain-text password over non-https protocol") diff --git a/client.go b/client.go index 3690952..a9d43dd 100644 --- a/client.go +++ b/client.go @@ -16,6 +16,7 @@ type Client interface { ID() String Version() String IndentRequests() bool + CarriageReturnNewLines() bool // Request marshals a Request object into XML, makes an HTTP request // against it's URL, and then unmarshals the response into a Response diff --git a/common.go b/common.go index 62cf58c..bfbaeb3 100644 --- a/common.go +++ b/common.go @@ -6,14 +6,16 @@ import ( "bytes" "errors" "fmt" + "strings" + "github.com/aclindsa/xml" ) -func writeHeader(b *bytes.Buffer, v ofxVersion) error { +func writeHeader(b *bytes.Buffer, v ofxVersion, carriageReturn bool) error { // Write the header appropriate to our version switch v { case OfxVersion102, OfxVersion103, OfxVersion151, OfxVersion160: - b.WriteString(`OFXHEADER:100 + header := `OFXHEADER:100 DATA:OFXSGML VERSION:` + v.String() + ` SECURITY:NONE @@ -23,10 +25,22 @@ COMPRESSION:NONE OLDFILEUID:NONE NEWFILEUID:NONE -`) +` + if carriageReturn { + header = strings.Replace(header, "\n", "\r\n", -1) + } + b.WriteString(header) case OfxVersion200, OfxVersion201, OfxVersion202, OfxVersion203, OfxVersion210, OfxVersion211, OfxVersion220: - b.WriteString(`` + "\n") - b.WriteString(`` + "\n") + b.WriteString(``) + if carriageReturn { + b.WriteByte('\r') + } + b.WriteByte('\n') + b.WriteString(``) + if carriageReturn { + b.WriteByte('\r') + } + b.WriteByte('\n') default: return fmt.Errorf("%d is not a valid OFX version string", v) } diff --git a/go.sum b/go.sum index d6f3069..baa5649 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/aclindsa/xml v0.0.0-20171002130543-5d4402bb4a20 h1:wN3KlzWq56AIgOqFzYLYVih4zVyPDViCUeG5uZxJHq4= github.com/aclindsa/xml v0.0.0-20171002130543-5d4402bb4a20/go.mod h1:DiEHtTD+e6zS3+R95F05Bfbcsfv13wZTi2M4LfAFLBE= -github.com/aclindsa/xml v0.0.0-20190614100215-564dc705a222 h1:KF5DYtOrl6QZ/vlVZPzHGRr7xLakO8Ye0I+JoiV3PNg= -github.com/aclindsa/xml v0.0.0-20190614100215-564dc705a222/go.mod h1:GjqOUT8xlg5+T19lFv6yAGNrtMKkZ839Gt4e16mBXlY= github.com/aclindsa/xml v0.0.0-20190625094425-0aa7a3409cf4 h1:STo5wlCItpgL9LFBui17kZ/N1iKQk+UztLRj2cVkSXQ= github.com/aclindsa/xml v0.0.0-20190625094425-0aa7a3409cf4/go.mod h1:GjqOUT8xlg5+T19lFv6yAGNrtMKkZ839Gt4e16mBXlY= github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c h1:kQWxfPIHVLbgLzphqk3QUflDy9QdksZR4ygR807bpy0= diff --git a/request.go b/request.go index 91987a3..825064e 100644 --- a/request.go +++ b/request.go @@ -31,7 +31,8 @@ type Request struct { Prof []Message // Image []Message // - indent bool // Whether to indent the marshaled XML + indent bool // Whether to indent the marshaled XML + carriageReturn bool // Whether to user carriage returns in new lines for marshaled XML } func encodeMessageSet(e *xml.Encoder, requests []Message, set messageType, version ofxVersion) error { @@ -70,6 +71,7 @@ func (oq *Request) SetClientFields(c Client) { oq.Signon.AppID = c.ID() oq.Signon.AppVer = c.Version() oq.indent = c.IndentRequests() + oq.carriageReturn = c.CarriageReturnNewLines() } // Marshal this Request into its SGML/XML representation held in a bytes.Buffer @@ -79,7 +81,7 @@ func (oq *Request) Marshal() (*bytes.Buffer, error) { var b bytes.Buffer // Write the header appropriate to our version - writeHeader(&b, oq.Version) + writeHeader(&b, oq.Version, oq.carriageReturn) encoder := xml.NewEncoder(&b) if oq.indent { @@ -89,6 +91,9 @@ func (oq *Request) Marshal() (*bytes.Buffer, error) { // OFX 100 series versions should avoid element close tags for compatibility encoder.SetDisableAutoClose(ofxLeafElements...) } + if oq.carriageReturn { + encoder.CarriageReturn(true) + } ofxElement := xml.StartElement{Name: xml.Name{Local: "OFX"}} diff --git a/response.go b/response.go index 9ab4db7..00728e5 100644 --- a/response.go +++ b/response.go @@ -377,7 +377,7 @@ func (or *Response) Marshal() (*bytes.Buffer, error) { var b bytes.Buffer // Write the header appropriate to our version - writeHeader(&b, or.Version) + writeHeader(&b, or.Version, false) encoder := xml.NewEncoder(&b) encoder.Indent("", " ")