Support carriage returns on new lines

This commit is contained in:
John Starich 2019-06-14 00:40:22 -05:00 committed by Aaron Lindsay
parent f41286cac7
commit 67e527c855
8 changed files with 39 additions and 9 deletions

View File

@ -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")

View File

@ -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

View File

@ -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(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>` + "\n")
b.WriteString(`<?OFX OFXHEADER="200" VERSION="` + v.String() + `" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>` + "\n")
b.WriteString(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>`)
if carriageReturn {
b.WriteByte('\r')
}
b.WriteByte('\n')
b.WriteString(`<?OFX OFXHEADER="200" VERSION="` + v.String() + `" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>`)
if carriageReturn {
b.WriteByte('\r')
}
b.WriteByte('\n')
default:
return fmt.Errorf("%d is not a valid OFX version string", v)
}

2
go.mod
View File

@ -1,7 +1,7 @@
module github.com/aclindsa/ofxgo
require (
github.com/aclindsa/xml v0.0.0-20171002130543-5d4402bb4a20
github.com/aclindsa/xml v0.0.0-20190625094425-0aa7a3409cf4
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 // indirect
golang.org/x/sys v0.0.0-20180928133829-e4b3c5e90611 // indirect

2
go.sum
View File

@ -1,5 +1,7 @@
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-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=
github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 h1:Vk3wNqEZwyGyei9yq5ekj7frek2u7HUfffJ1/opblzc=

View File

@ -31,7 +31,8 @@ type Request struct {
Prof []Message //<PROFMSGSETV1>
Image []Message //<IMAGEMSGSETV1>
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,12 +81,15 @@ 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 {
encoder.Indent("", " ")
}
if oq.carriageReturn {
encoder.CarriageReturn(true)
}
ofxElement := xml.StartElement{Name: xml.Name{Local: "OFX"}}

View File

@ -10,6 +10,7 @@ import (
var ignoreSpacesRe = regexp.MustCompile(">[ \t\r\n]+<")
func marshalCheckRequest(t *testing.T, request *ofxgo.Request, expected string) {
t.Helper()
buf, err := request.Marshal()
if err != nil {
t.Fatalf("%s: Unexpected error marshalling request: %s\n", t.Name(), err)

View File

@ -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("", " ")