Files
ciimsproxy/internal/http.go
T

98 lines
2.0 KiB
Go

package internal
import (
"fmt"
"io"
"net/http"
"strings"
"time"
)
const (
defaultContentType string = "text/xml; charset=UTF-8"
defaultAgent string = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; XFire Client +http://xfire.codehaus.org)"
)
type Client struct {
httpClient *http.Client
}
type CIIMSResponse struct {
RawXML string
}
type HTTPStatusError struct {
StatusCode int
Status string
Body string
}
func (e *HTTPStatusError) Error() string {
body := e.Body
if len(body) > 512 {
body = body[:512] + "..."
}
if body == "" {
return fmt.Sprintf("ciims returned %s", e.Status)
}
return fmt.Sprintf("ciims returned %s: %s", e.Status, body)
}
func NewClient(timeoutSec int) (*Client, error) {
if timeoutSec <= 0 {
return nil, fmt.Errorf("timeout must be positive")
}
return &Client{
httpClient: &http.Client{
Timeout: time.Duration(timeoutSec) * time.Second,
},
}, nil
}
func (r *CIIMSResponse) IsFault() bool {
return r != nil && r.ErrorMessage() != ""
}
func (r *CIIMSResponse) ErrorMessage() string {
if r == nil {
return ""
}
return GetErrMsg(r.RawXML)
}
func (r *CIIMSResponse) Messages() []string {
if r == nil {
return nil
}
return GetMsgs(r.RawXML)
}
func (c *Client) Send(url string, msg string) (*CIIMSResponse, error) {
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(msg))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", defaultContentType)
req.Header.Set("User-Agent", defaultAgent)
req.Header.Set("SOAPAction", "")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
body := string(respBytes)
ciimsResp := &CIIMSResponse{RawXML: body}
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
return ciimsResp, &HTTPStatusError{
StatusCode: resp.StatusCode,
Status: resp.Status,
Body: body,
}
}
return ciimsResp, nil
}