README.md
Rendering markdown...
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
)
var (
ErrorInvalidSession = fmt.Errorf("session invalid/expired")
)
type XCConfig struct {
Root string
Username string
Password string
}
type XCClient struct {
config XCConfig
client *http.Client
store XCStore
}
func NewXCClient(config XCConfig) *XCClient {
jar, err := cookiejar.New(nil)
AssertOk(err)
return &XCClient{
config: config,
client: &http.Client{Jar: jar},
store: NewInMemoryXCStore(),
}
}
func (x *XCClient) TriggerNegativeCache(name string) error {
reqUrl := "http://" + name + "/image.png"
_, err := x.DocAddFile(reqUrl)
if err == ErrorInvalidSession {
if err := x.Login(); err != nil {
return err
}
_, err = x.DocAddFile(reqUrl)
}
if err == nil {
return fmt.Errorf("negative cache trigger expected error, got nothing")
}
if strings.Contains(err.Error(), "GENERAL_ARGUMENTS_ERROR") {
return nil
}
return err
}
func (x *XCClient) Login() error {
form := url.Values{}
form.Set("action", "login")
form.Set("name", x.config.Username)
form.Set("password", x.config.Password)
form.Set("staySignedIn", "true")
resp, err := x.client.Post(x.config.Root+"/appsuite/api/login",
"application/x-www-form-urlencoded", bytes.NewBuffer([]byte(form.Encode())))
if err != nil {
return fmt.Errorf("cannot load cookies, error %v", err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("cannot read response body, error %v", err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("cannot login, status %s, error %s", resp.Status, string(body))
}
data := XCLoginResult{}
if err := json.Unmarshal(body, &data); err != nil || data.Session == "" {
return fmt.Errorf("login failed, error %s", string(body))
}
x.store.SetSession(data)
return nil
}
type DocAddFileResponse struct {
FileName string `json:"added_filename"`
FileId string `json:"added_fileid"`
}
func (x *XCClient) DocAddFile(imageUrl string) (*DocAddFileResponse, error) {
form := url.Values{}
form.Set("action", "addfile")
form.Set("requestdata", "{\"add_imageurl\":\""+imageUrl+"\"}")
form.Set("version", "1")
form.Set("filename", "unnamed.docx")
form.Set("app", "text")
session, err := x.store.GetSession()
if err != nil {
return nil, err
}
resp, err := x.client.Post(
x.config.Root+"/appsuite/api/oxodocumentfilter?session="+session.Session,
"application/x-www-form-urlencoded", bytes.NewBuffer([]byte(form.Encode())))
if err != nil {
return nil, fmt.Errorf("cannot execute addfile request, error %v", err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("cannot read response body, error %v", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("addfile request failed, status: %s, error: %s", resp.Status, string(body))
}
if strings.Contains(string(body), "added_filename") {
responseData := struct {
Data DocAddFileResponse `json:"data"`
}{}
if err := json.Unmarshal(body, &responseData); err != nil {
return nil, fmt.Errorf("cannot unmarshal response data, error %+v", err)
}
return &responseData.Data, nil
}
if strings.Contains(string(body), "Your session expired") {
return nil, ErrorInvalidSession
}
return nil, fmt.Errorf("add failed, error %s", string(body))
}
func (x *XCClient) Logout() error {
form := url.Values{}
form.Set("action", "logout")
session, err := x.store.GetSession()
if err != nil {
return err
}
resp, err := x.client.Post(x.config.Root+"/appsuite/api/login?session="+session.Session,
"application/x-www-form-urlencoded", bytes.NewBuffer([]byte(form.Encode())))
if err != nil {
return fmt.Errorf("cannot logout, error %v", err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("cannot read response body, error %v", err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("cannot logout, status %s, error %s", resp.Status, string(body))
}
return nil
}