コード例 #1
0
ファイル: cookie.go プロジェクト: niltonkummer/web.go
// writeCookies writes the wire representation of the cookies
// to w. Each cookie is written on a separate "Cookie: " line.
// This choice is made because HTTP parsers tend to have a limit on
// line-length, so it seems safer to place cookies on separate lines.
func writeCookies(w io.Writer, kk []*http.Cookie) os.Error {
	lines := make([]string, 0, len(kk))
	var b bytes.Buffer
	for _, c := range kk {
		b.Reset()
		n := c.Name
		// TODO(petar): c.Value (below) should be unquoted if it is recognized as quoted
		fmt.Fprintf(&b, "%s=%s", http.CanonicalHeaderKey(n), c.Value)
		if len(c.Path) > 0 {
			fmt.Fprintf(&b, "; $Path=%s", url.QueryEscape(c.Path))
		}
		if len(c.Domain) > 0 {
			fmt.Fprintf(&b, "; $Domain=%s", url.QueryEscape(c.Domain))
		}
		if c.HttpOnly {
			fmt.Fprintf(&b, "; $HttpOnly")
		}
		lines = append(lines, "Cookie: "+b.String()+"\r\n")
	}
	sort.Strings(lines)
	for _, l := range lines {
		if _, err := io.WriteString(w, l); err != nil {
			return err
		}
	}
	return nil
}
コード例 #2
0
func PostFacebookLink(text string, urls []string) {
	u := make(url.Values)
	u.Add("access_token", accessToken)
	u.Add("link", url.QueryEscape(urls[0]))
	u.Add("message", url.QueryEscape(text))
	http.PostForm(linkURL, u)
}
コード例 #3
0
ファイル: httplib.go プロジェクト: axel-b/httplib.go
func (b *HttpRequestBuilder) getResponse() (*http.Response, os.Error) {
	var paramBody string
	if b.params != nil && len(b.params) > 0 {
		var buf bytes.Buffer
		for k, v := range b.params {
			buf.WriteString(url.QueryEscape(k))
			buf.WriteByte('=')
			buf.WriteString(url.QueryEscape(v))
			buf.WriteByte('&')
		}
		paramBody = buf.String()
		paramBody = paramBody[0 : len(paramBody)-1]
	}
	if b.req.Method == "GET" && len(paramBody) > 0 {
		if strings.Index(b.url, "?") != -1 {
			b.url += "&" + paramBody
		} else {
			b.url = b.url + "?" + paramBody
		}
	} else if b.req.Method == "POST" && b.req.Body == nil && len(paramBody) > 0 {
		b.Header("Content-Type", "application/x-www-form-urlencoded")
		b.req.Body = nopCloser{bytes.NewBufferString(paramBody)}
		b.req.ContentLength = int64(len(paramBody))
	}

	conn, resp, err := getResponse(b.url, b.req)
	b.clientConn = conn
	return resp, err
}
コード例 #4
0
ファイル: authrequest.go プロジェクト: brianolson/go-openid
func CreateAuthenticationRequest(OPEndPoint, ClaimedID, Realm, ReturnTo string) string {
	var p = make(map[string]string)

	p["openid.ns"] = "http://specs.openid.net/auth/2.0"
	p["openid.mode"] = "checkid_setup"

	if len(ClaimedID) == 0 {
		p["openid.claimed_id"] = "http://specs.openid.net/auth/2.0/identifier_select"
		p["openid.identity"] = "http://specs.openid.net/auth/2.0/identifier_select"
	} else {
		p["openid.claimed_id"] = ClaimedID
		p["openid.identity"] = ClaimedID
	}

	p["openid.return_to"] = Realm + ReturnTo
	p["openid.realm"] = Realm

	var url_ string
	url_ = OPEndPoint + "?"

	for k, v := range p {
		url_ += url.QueryEscape(k) + "=" + url.QueryEscape(v) + "&"
	}
	return url_
}
コード例 #5
0
ファイル: web.go プロジェクト: andrewzeneski/web.go
func Urlencode(data map[string]string) string {
	var buf bytes.Buffer
	for k, v := range data {
		buf.WriteString(url.QueryEscape(k))
		buf.WriteByte('=')
		buf.WriteString(url.QueryEscape(v))
		buf.WriteByte('&')
	}
	s := buf.String()
	return s[0 : len(s)-1]
}
コード例 #6
0
ファイル: service.go プロジェクト: pombredanne/contacts.go
func RetrieveActivityList(client oauth2_client.OAuth2Client, userId, collection string, m url.Values) (*ActivityListResponse, os.Error) {
	if userId == "" {
		userId = "me"
	}
	if collection == "" {
		collection = "public"
	}
	p := new(ActivityListResponse)
	uri := ACTIVITY_LIST_ENDPOINT + url.QueryEscape(userId) + "/activities/" + url.QueryEscape(collection)
	err := retrieveInfo(client, uri, m, p)
	return p, err
}
コード例 #7
0
ファイル: signup.go プロジェクト: cmc333333/fragspace
func signupPost(w http.ResponseWriter, r *http.Request) {
	responseType, client, err := params(r)
	if err != nil {
		err.WriteTo(w)
		return
	}
	email, password := r.FormValue("email"), r.FormValue("password")
	emailRegexp := regexp.MustCompile(`^[a-z0-9._%\-+]+@[a-z0-9.\-]+\.[a-z]+$`)
	msgs := make([]string, 0, 5)
	if !emailRegexp.MatchString(email) {
		msgs = append(msgs, "Invalid email address")
	}
	if len(password) < 6 {
		msgs = append(msgs, "Password is too short")
	}
	//  Also check if email already exists
	user := model.NewUser(email)
	context := appengine.NewContext(r)
	countExists, e := datastore.NewQuery("User").Filter("EmailHash =", user.EmailHash).Count(context)
	if e != nil {
		context.Errorf("%v", e)
		http.Error(w, e.String(), http.StatusInternalServerError)
		return
	}
	if countExists > 0 {
		msgs = append(msgs, "Email already exists")
	}

	if msgsLen := len(msgs); msgsLen > 0 {
		http.RedirectHandler("/oauth2/signup?response_type="+url.QueryEscape(responseType)+"&client_id="+
			url.QueryEscape(client.Id)+"&msgs="+url.QueryEscape(strings.Join(msgs, "|")), 303).ServeHTTP(w, r)
	} else {
		userKey, err := datastore.Put(context, datastore.NewIncompleteKey(context, "User", nil), user)
		if err != nil {
			context.Errorf("Error saving: %v", err)
			w.Write([]byte("Error saving: " + err.String()))
			return
		}
		auth := model.NewPasswordAuth(userKey, password)
		if _, err = datastore.Put(context, datastore.NewIncompleteKey(context, "Authentication", nil), auth); err != nil {
			context.Errorf("Error saving: %v", err)
			w.Write([]byte("Error saving: " + err.String()))
			return
		}
		key := newCodeKey(userKey.StringID(), client.Id, context)
		http.RedirectHandler(client.redirectUrl(key), 303).ServeHTTP(w, r)
	}
}
コード例 #8
0
ファイル: userconfig.go プロジェクト: paul-lalonde/golibs
// Obtain a URL which will allow the current user to authorize access to their
// OAuth-protected data.
func (c *UserConfig) GetAuthorizeURL(service *Service) (string, os.Error) {
	if c.RequestTokenKey == "" || c.RequestTokenSecret == "" {
		return "", os.NewError("No configured request token")
	}
	token := url.QueryEscape(c.RequestTokenKey)
	return service.AuthorizeURL + "?oauth_token=" + token, nil
}
コード例 #9
0
ファイル: main.go プロジェクト: WXB506/golang
func remoteSearch(query string) (res *http.Response, err os.Error) {
	search := "/search?f=text&q=" + url.QueryEscape(query)

	// list of addresses to try
	var addrs []string
	if *serverAddr != "" {
		// explicit server address - only try this one
		addrs = []string{*serverAddr}
	} else {
		addrs = []string{
			defaultAddr,
			"golang.org",
		}
	}

	// remote search
	for _, addr := range addrs {
		url := "http://" + addr + search
		res, err = http.Get(url)
		if err == nil && res.StatusCode == http.StatusOK {
			break
		}
	}

	if err == nil && res.StatusCode != http.StatusOK {
		err = os.NewError(res.Status)
	}

	return
}
コード例 #10
0
ファイル: main.go プロジェクト: ngerakines/gobook
func renameTag(req *web.Request) {
	// oldTag := req.Param.Get("oldTag")
	newTag := req.Param.Get("newTag")
	// updateTag(oldTag, newTag)
	url := fmt.Sprintf("/tag/%s", url.QueryEscape(newTag))
	req.Redirect(url, false)
}
コード例 #11
0
ファイル: item.go プロジェクト: davelondon/twist
func (i *Item) getLinkUrl(handlerFunc interface{}, values interface{}) string {

	valueStubs, _, needsHash := makeStubs(values, false)

	stubs := allStubs{Func: getFunctionName(handlerFunc), Values: valueStubs}

	hashQuery := ""
	if needsHash {
		hash := getHash(stubs)
		stubs.Hash = hash
		hashQuery = "&_hash=" + hash
	}

	qstring := ""
	for _, v := range stubs.Values {
		if len(qstring) == 0 {
			qstring += "?"
		} else {
			qstring += "&"
		}

		qstring += v.N + "=" + url.QueryEscape(toString(v.V))
	}
	href := "/" + stubs.Func + qstring + hashQuery

	return href

}
コード例 #12
0
ファイル: bitly.go プロジェクト: thevermi/rbot
func shorten(long string) (short string) {
	key := "R_e659dbb5514e34edc3540a7c95b0041b"
	login := "******"

	long = url.QueryEscape(long)

	url_ := fmt.Sprintf("http://api.bit.ly/v3/shorten?login=%s&apiKey=%s&longUrl=%s&format=json", login, key, long)
	r, err := http.Get(url_)
	defer r.Body.Close()

	if err != nil {
		return "Error connecting to bit.ly"
	}

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return "Error reading bit.ly response"
	}

	var j map[string]interface{}

	err = json.Unmarshal(b, &j)
	if err != nil {
		return "Unable to shorten URL."
	}

	var data map[string]interface{} = j["data"].(map[string]interface{})

	return data["url"].(string)
}
コード例 #13
0
ファイル: oauth1a.go プロジェクト: paul-lalonde/golibs
// Returns a map of all of the oauth_* (including signature) parameters for the
// given request, and the signature base string used to generate the signature.
func (s *HmacSha1Signer) GetOAuthParams(request *http.Request, clientConfig *ClientConfig, userConfig *UserConfig, nonce string, timestamp string) (map[string]string, string) {
	request.ParseForm()
	oauthParams := map[string]string{
		"oauth_consumer_key":     clientConfig.ConsumerKey,
		"oauth_nonce":            nonce,
		"oauth_signature_method": "HMAC-SHA1",
		"oauth_timestamp":        timestamp,
		"oauth_version":          "1.0",
	}
	tokenKey, tokenSecret := userConfig.GetToken()
	if tokenKey != "" {
		oauthParams["oauth_token"] = tokenKey
	}
	signingParams := map[string]string{}
	for key, value := range oauthParams {
		signingParams[key] = value
	}
	for key, value := range request.URL.Query() {
		//TODO: Support multiple parameters with the same name.
		signingParams[key] = value[0]
	}
	for key, value := range request.Form {
		//TODO: Support multiple parameters with the same name.
		signingParams[key] = value[0]
	}
	signingUrl := fmt.Sprintf("%v://%v%v", request.URL.Scheme, request.URL.RawAuthority, request.URL.Path)
	signatureParts := []string{
		request.Method,
		url.QueryEscape(signingUrl),
		s.encodeParameters(signingParams)}
	signatureBase := strings.Join(signatureParts, "&")
	oauthParams["oauth_signature"] = s.GetSignature(clientConfig.ConsumerSecret, tokenSecret, signatureBase)
	return oauthParams, signatureBase
}
コード例 #14
0
func slurpURL(urlStr string) []byte {
	diskFile := filepath.Join(os.TempDir(), "google-api-cache-"+url.QueryEscape(urlStr))
	if *useCache {
		bs, err := ioutil.ReadFile(diskFile)
		if err == nil && len(bs) > 0 {
			return bs
		}
	}

	req, err := http.NewRequest("GET", urlStr, nil)
	if err != nil {
		log.Fatal(err)
	}
	if *publicOnly {
		req.Header.Add("X-User-IP", "0.0.0.0") // hack
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("Error fetching URL %s: %v", urlStr, err)
	}
	bs, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Error reading body of URL %s: %v", urlStr, err)
	}
	if *useCache {
		if err := ioutil.WriteFile(diskFile, bs, 0666); err != nil {
			log.Printf("Warning: failed to write JSON of %s to disk file %s: %v", urlStr, diskFile, err)
		}
	}
	return bs
}
コード例 #15
0
ファイル: util.go プロジェクト: paul-lalonde/twitter
func addQueryVariables(url_ string, variables map[string]string) string {
	var addition string
	newUrl := url_

	i := 0
	for key, value := range variables {
		if i == 0 {
			addition = fmt.Sprintf("?%s=%s", key, url.QueryEscape(value))
		} else {
			addition = fmt.Sprintf("&%s=%s", key, url.QueryEscape(value))
		}
		newUrl += addition
		i++
	}

	return newUrl
}
コード例 #16
0
ファイル: gowiki.go プロジェクト: hyb/gowiki
func loadPage(title string) (*Page, os.Error) {
	filename := viewRoot + url.QueryEscape(title) + ".txt"
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: body}, nil
}
コード例 #17
0
ファイル: service.go プロジェクト: pombredanne/contacts.go
func RetrieveActivity(client oauth2_client.OAuth2Client, activityId string, m url.Values) (*Activity, os.Error) {
	if activityId == "" {
		return nil, os.NewError("activityId cannot be empty")
	}
	p := new(Activity)
	uri := ACTIVITY_ENDPOINT + url.QueryEscape(activityId)
	err := retrieveInfo(client, uri, m, p)
	return p, err
}
コード例 #18
0
ファイル: main.go プロジェクト: steliomo/jQuery-File-Upload
func delayedDelete(c appengine.Context, fi *FileInfo) {
	if key := string(fi.Key); key != "" {
		task := &taskqueue.Task{
			Path:   "/" + url.QueryEscape(key) + "/-",
			Method: "DELETE", Delay: EXPIRATION_TIME * 1000000,
		}
		taskqueue.Add(c, task, "")
	}
}
コード例 #19
0
ファイル: main.go プロジェクト: steliomo/jQuery-File-Upload
func (fi *FileInfo) CreateUrls(r *http.Request, c appengine.Context) {
	u := &url.URL{
		Scheme: r.URL.Scheme,
		Host:   appengine.DefaultVersionHostname(c),
	}
	u.Path = "/" + url.QueryEscape(string(fi.Key)) + "/" +
		url.QueryEscape(string(fi.Name))
	fi.Url = u.String()
	fi.DeleteUrl = fi.Url
	fi.DeleteType = "DELETE"
	if fi.ThumbnailUrl != "" && -1 == strings.Index(
		r.Header.Get("Accept"),
		"application/json",
	) {
		u.Path = "/thumbnails/" + url.QueryEscape(string(fi.Key))
		fi.ThumbnailUrl = u.String()
	}
}
コード例 #20
0
ファイル: service.go プロジェクト: pombredanne/contacts.go
func RetrieveContact(client oauth2_client.OAuth2Client, userId string, m url.Values) (*Person, os.Error) {
	if userId == "" {
		userId = "me"
	}
	p := new(Person)
	uri := PERSON_ENDPOINT + url.QueryEscape(userId)
	err := retrieveInfo(client, uri, m, p)
	return p, err
}
コード例 #21
0
ファイル: parammap.go プロジェクト: adamsxu/twister
// FormEncodedBytes returns a buffer containing the URL form encoding of the
// map.
func (m Values) FormEncodedBytes() []byte {
	var b bytes.Buffer
	sep := false
	for key, values := range m {
		escapedKey := url.QueryEscape(key)
		for _, value := range values {
			if sep {
				b.WriteByte('&')
			} else {
				sep = true
			}
			b.WriteString(escapedKey)
			b.WriteByte('=')
			b.WriteString(url.QueryEscape(value))
		}
	}
	return b.Bytes()
}
コード例 #22
0
ファイル: service.go プロジェクト: pombredanne/contacts.go
func UpdateGroup(client oauth2_client.OAuth2Client, userId, projection string, original, value *ContactGroup) (response *GroupResponse, err os.Error) {
	var useUserId string
	if len(userId) <= 0 {
		useUserId = GOOGLE_DEFAULT_USER_ID
	} else {
		useUserId = url.QueryEscape(userId)
	}
	if len(projection) <= 0 {
		projection = GOOGLE_DEFAULT_PROJECTION
	}
	headers := make(http.Header)
	headers.Set("GData-Version", "3.0")
	headers.Set("If-Match", original.Etag)
	m := make(url.Values)
	if len(m.Get(CONTACTS_ALT_PARAM)) <= 0 {
		m.Set(CONTACTS_ALT_PARAM, "json")
	}
	uri := GOOGLE_GROUPS_API_ENDPOINT
	for _, s := range []string{useUserId, projection, original.GroupId()} {
		if len(s) > 0 {
			if uri[len(uri)-1] != '/' {
				uri += "/"
			}
			uri += s
		}
	}
	entry := &GroupEntryUpdateRequest{Entry: value}
	value.Xmlns = XMLNS_ATOM
	value.XmlnsGcontact = XMLNS_GCONTACT
	value.XmlnsBatch = XMLNS_GDATA_BATCH
	value.XmlnsGd = XMLNS_GD
	value.Etag = original.Etag
	value.Id = original.Id
	value.Updated.Value = time.UTC().Format(GOOGLE_DATETIME_FORMAT)
	value.Categories = make([]AtomCategory, 1)
	value.Categories[0].Scheme = ATOM_CATEGORY_SCHEME_KIND
	value.Categories[0].Term = ATOM_CATEGORY_TERM_GROUP
	buf, err := json.Marshal(entry)
	if err != nil {
		return
	}
	resp, _, err := oauth2_client.AuthorizedPutRequestBytes(client, headers, uri, m, buf)
	if err != nil {
		return
	}
	if resp != nil {
		if resp.StatusCode >= 400 {
			b, _ := ioutil.ReadAll(resp.Body)
			err = os.NewError(string(b))
		} else {
			response = new(GroupResponse)
			err = json.NewDecoder(resp.Body).Decode(response)
		}
	}
	return
}
コード例 #23
0
ファイル: funcs.go プロジェクト: WXB506/golang
// URLQueryEscaper returns the escaped value of the textual representation of
// its arguments in a form suitable for embedding in a URL query.
func URLQueryEscaper(args ...interface{}) string {
	s, ok := "", false
	if len(args) == 1 {
		s, ok = args[0].(string)
	}
	if !ok {
		s = fmt.Sprint(args...)
	}
	return url.QueryEscape(s)
}
コード例 #24
0
ファイル: flickr.go プロジェクト: ipeet/camlistore
func encodeQuery(args map[string]string) string {
	i := 0
	s := bytes.NewBuffer(nil)
	for k, v := range args {
		if i != 0 {
			s.WriteString("&")
		}
		i++
		s.WriteString(k + "=" + url.QueryEscape(v))
	}
	return s.String()
}
コード例 #25
0
ファイル: oppai2.go プロジェクト: kimikato/go_oppai
func get_request_uri(param map[string]string) string {
	post_body := ""
	cnt := 0

	for k, v := range param {
		post_body += k + "=" + url.QueryEscape(v)
		if cnt < len(param)-1 {
			post_body += "&"
		}
		cnt++
	}
	return string(query_uri + "?" + post_body)
}
コード例 #26
0
ファイル: cookie.go プロジェクト: niltonkummer/web.go
// writeSetCookies writes the wire representation of the set-cookies
// to w. Each cookie is written on a separate "Set-Cookie: " line.
// This choice is made because HTTP parsers tend to have a limit on
// line-length, so it seems safer to place cookies on separate lines.
func writeSetCookies(w io.Writer, kk []*http.Cookie) os.Error {
	if kk == nil {
		return nil
	}
	lines := make([]string, 0, len(kk))
	var b bytes.Buffer
	for _, c := range kk {
		b.Reset()
		// TODO(petar): c.Value (below) should be unquoted if it is recognized as quoted
		fmt.Fprintf(&b, "%s=%s", http.CanonicalHeaderKey(c.Name), c.Value)
		if len(c.Path) > 0 {
			fmt.Fprintf(&b, "; Path=%s", url.QueryEscape(c.Path))
		}
		if len(c.Domain) > 0 {
			fmt.Fprintf(&b, "; Domain=%s", url.QueryEscape(c.Domain))
		}
		if len(c.Expires.Zone) > 0 {
			fmt.Fprintf(&b, "; Expires=%s", c.Expires.Format(time.RFC1123))
		}
		if c.MaxAge >= 0 {
			fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge)
		}
		if c.HttpOnly {
			fmt.Fprintf(&b, "; HttpOnly")
		}
		if c.Secure {
			fmt.Fprintf(&b, "; Secure")
		}
		lines = append(lines, "Set-Cookie: "+b.String()+"\r\n")
	}
	sort.Strings(lines)
	for _, l := range lines {
		if _, err := io.WriteString(w, l); err != nil {
			return err
		}
	}
	return nil
}
コード例 #27
0
ファイル: bitly.go プロジェクト: thevermi/rbot
func expand(short string) (long string) {
	key := "R_e659dbb5514e34edc3540a7c95b0041b"
	login := "******"

	short = url.QueryEscape(short)

	url_ := fmt.Sprintf("http://api.bit.ly/v3/expand?login=%s&apiKey=%s&shortUrl=%s&format=xml", login, key, short)
	r, err := http.Get(url_)
	defer r.Body.Close()

	if err != nil {
		return "Unable to connect to bit.ly"
	}

	type (
		Entry struct {
			Error    string
			Long_url string
		}

		Data struct {
			Entry Entry
		}

		Response struct {
			XMLName xml.Name `xml:"response"`
			Data    Data
		}
	)

	var response Response

	err = xml.Unmarshal(r.Body, &response)
	if err != nil {
		return "Unable to process response from bit.ly"
	}

	if response.Data.Entry.Error == "NOT_FOUND" {
		return response.Data.Entry.Error
	}

	s := strings.TrimLeft(response.Data.Entry.Long_url, "http://")
	s = strings.SplitN(s, "/", 2)[0]
	if strings.Contains(s, "amazon.") {
		return "amazon.com product"
	} else if strings.Contains(s, "ebay.") {
		return "ebay.com listing"
	}
	return response.Data.Entry.Long_url
}
コード例 #28
0
ファイル: cmd-booru.go プロジェクト: thevermi/rbot
func booruLoli(conn *irc.Conn, nick *irc.Nick, tag string, channel string) {
	tag = "loli*"
	tag = url.QueryEscape(tag)
	site := fmt.Sprintf("http://ibsearch.i-forge.net/?action=randimage&randimage[phrase]=%s&format=xml", tag)

	status := booruDoSearch(conn, channel, site)

	switch {
	case status == "FAIL":
		say(conn, channel, "%s, you are a pervert! No loli for you! >:|", nick.Nick)
	case status == "DOWN":
		say(conn, channel, "booru search is down. If this keeps happening, please inform the owner.")
	}
}
コード例 #29
0
ファイル: cmd-booru.go プロジェクト: thevermi/rbot
func booruSafeLoli(conn *irc.Conn, nick *irc.Nick, tag string, channel string) {
	tag = "+loli* rating:s"
	tag = url.QueryEscape(tag)
	site := fmt.Sprintf("http://ibsearch.i-forge.net/?action=randimage&randimage[phrase]=%s&format=xml", tag)

	status := booruDoSearch(conn, channel, site)

	switch {
	case status == "FAIL":
		say(conn, channel, "Aww, I couldn't find anything this time... ;-;")
	case status == "DOWN":
		say(conn, channel, "booru search is down. If this keeps happening, please inform the owner.")
	}
}
コード例 #30
0
ファイル: service.go プロジェクト: pombredanne/contacts.go
func CreateGroup(client oauth2_client.OAuth2Client, userId, projection string, value *ContactGroup) (response *GroupResponse, err os.Error) {
	var useUserId string
	if len(userId) <= 0 {
		useUserId = GOOGLE_DEFAULT_USER_ID
	} else {
		useUserId = url.QueryEscape(userId)
	}
	if len(projection) <= 0 {
		projection = GOOGLE_DEFAULT_PROJECTION
	}
	headers := make(http.Header)
	headers.Set("GData-Version", "3.0")
	m := make(url.Values)
	if len(m.Get(CONTACTS_ALT_PARAM)) <= 0 {
		m.Set(CONTACTS_ALT_PARAM, "json")
	}
	uri := GOOGLE_GROUPS_API_ENDPOINT
	for _, s := range []string{useUserId, projection} {
		if len(s) > 0 {
			if uri[len(uri)-1] != '/' {
				uri += "/"
			}
			uri += s
		}
	}
	entry := &GroupEntryInsertRequest{Version: "1.0", Encoding: "UTF-8", Entry: value}
	value.Xmlns = XMLNS_ATOM
	value.XmlnsGcontact = XMLNS_GCONTACT
	value.XmlnsBatch = XMLNS_GDATA_BATCH
	value.XmlnsGd = XMLNS_GD
	buf, err := json.Marshal(entry)
	if err != nil {
		return
	}
	resp, _, err := oauth2_client.AuthorizedPostRequestBytes(client, headers, uri, m, buf)
	if err != nil {
		return
	}
	if resp != nil {
		if resp.StatusCode >= 400 {
			b, _ := ioutil.ReadAll(resp.Body)
			err = os.NewError(string(b))
		} else {
			response = new(GroupResponse)
			err = json.NewDecoder(resp.Body).Decode(response)
		}
	}
	return
}