Skip to content

Instantly share code, notes, and snippets.

@rjeczalik
Created October 13, 2014 09:10
Show Gist options
  • Save rjeczalik/bf66e2996ce74f940ee9 to your computer and use it in GitHub Desktop.
Save rjeczalik/bf66e2996ce74f940ee9 to your computer and use it in GitHub Desktop.
Socollab - CodeCollaborator client (abandoned, got stuck at encoding GWT-RPC structs in its requests)
package main
import (
"fmt"
"os"
"socollab"
)
const usage = `usage: socollab COMMAND [ARG...]`
var user = os.Getenv("SOCOLLAB_USER")
var pass = os.Getenv("SOCOLLAB_PASS")
var bot socollab.Bot
func die(v interface{}) {
fmt.Fprintln(os.Stderr, v)
os.Exit(1)
}
func main() {
if len(os.Args) != 2 {
die(usage)
}
if user == "" {
die("SOCOLLAB_USER env is not exported")
}
if pass == "" {
die("SOCOLLAB_PASS env is not exported")
}
if err := run(); err != nil {
die(err)
}
}
func run() error {
if err := bot.Login(user, pass); err != nil {
return err
}
return nil
}
package socollab
import (
"errors"
"fmt"
"io"
"net/http"
"strings"
)
// TODO(rjeczalik): GWT-RPC?
var errTodo = errors.New("TODO(rjeczalik): Not implemented yet.")
const endpoint = "http://review"
const loginReqBodyFmt = "7|0|7|http://review/script/com.smartbear.ccollab.Ccol" +
"labWebclient/|939B8141586EA1033A18C480784C9D71|com.smartbear.ccollab.datamo" +
"del.client.unversioned.IUnversionedClientApi|login|java.lang.String/2004016" +
"611|%s|%s|1|2|3|4|2|5|5|6|7|"
var defaultClient = &http.Client{}
var cookieHeader = map[string][]string{
"Accept": {"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"},
"Accept-Language": {"en-US,en;q=0.8,pl;q=0.6"},
"Accept-Encoding": {"gzip,deflate,sdch"},
"Connection": {"keep-alive"},
"Host": {"review"},
"User-Agent": {"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36"},
}
func reqHeader(jsessionid string) http.Header {
return map[string][]string{
"Accept": {"*/*"},
"Accept-Language": {"en-US,en;q=0.8,pl;q=0.6"},
"Accept-Encoding": {"gzip,deflate,sdch"},
"Connection": {"keep-alive"},
"Host": {"review"},
"User-Agent": {"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36"},
"Origin": {endpoint},
"X-SmartBear-WindowId": {"20790441520512104"},
"Content-Type": {"text/x-gwt-rpc; charset=UTF-8"},
"X-GWT-Module-Base": {endpoint + "/script/com.smartbear.ccollab.CcollabWebclient/"},
"X-GWT-Permutation": {jsessionid},
}
}
type Bot struct {
Client *http.Client
cookie *http.Cookie
}
func (b *Bot) client() *http.Client {
if b.Client != nil {
return b.Client
}
return defaultClient
}
func jsessionid(res *http.Response) (cookie *http.Cookie, err error) {
for _, c := range res.Cookies() {
if strings.ToLower(c.Name) == "jsessionid" && len(c.Value) != 0 {
cookie = c
break
}
}
if cookie == nil {
err = fmt.Errorf("no JSESSIONID cookie in: %+v", res)
}
return
}
func (b *Bot) initcookie() error {
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return err
}
req.Header = cookieHeader
res, err := b.client().Do(req)
if err != nil {
return err
}
cookie, err := jsessionid(res)
if err != nil {
return err
}
b.cookie = cookie
return nil
}
func (b *Bot) do(method string, path string, body string) (*http.Response, error) {
r := (io.Reader)(nil)
if body != "" {
r = strings.NewReader(body)
}
req, err := http.NewRequest(method, endpoint+path, r)
if err != nil {
return nil, err
}
req.AddCookie(b.cookie)
req.Header = reqHeader(b.cookie.Value)
res, err := b.client().Do(req)
if err != nil {
return nil, err
}
return res, nil
}
func (b *Bot) Login(user, pass string) error {
if err := b.initcookie(); err != nil {
return err
}
res, err := b.do("POST", "/gwt", fmt.Sprintf(loginReqBodyFmt, user, pass))
if err != nil {
return err
}
cookie, err := jsessionid(res)
if err != nil {
return err
}
b.cookie = cookie
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment