Git Product home page Git Product logo

form's People

Contributors

ajg avatar bitdeli-chef avatar cezarsa avatar godblesshugh avatar golint-fixer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

form's Issues

Proposal: Produce efficient errors instead raw panic message

I always like to check my form fields to see if their values are convertible to needed types and if not then inform the user about invalid fields. form produces *errors.errorString and this is not useful when generating error responses for this purpose.

What about defining a new error type such as below to give more control over them

e.g.

type Error []Field

func (e Error) Error() string {
  return "todo"
}

type Field struct {
  Name string // tag name e.g. time from form:"time"
  Message string // original error message 
  Type reflect.Type // point out the expected type so we can generate even more graceful error messages by checking this e.g. "time must be a UTC date"
  SliceIndex int // point out the index if an invalid Type placed in a slice except []byte
}

A dummy usage:

type Post struct {
  Time time.Time `form:"time"`
}

var p Post
err := form.DecodeValues(&p, url.Values{"time", []string{"AnInvalidDate"}})
if (err.(form.Error))[0].Type == form.TimeType {
 // so I can response a nice error message to user like:
 // HTTP 400
 // {"message": "Invalid Form Data", fields: {"time": "must be UTC formatted"}}
}

I'd like to implement this if you'll consider accepting the PR

Anonimous fields without prefix

Is possible parse anonimous fields without prefix if it's tag ommited or empty string (like json)?

Example:

package main

import (
	"encoding/json"
	"fmt"

	"github.com/ajg/form"
)

type T1 struct {
	X int `json:"x,omitempty" form:"x,omitempty"`
	Y int `json:"y,omitempty" form:"y,omitempty"`
}

type T2 struct {
	*T1 `json:"" form:""`
	A   int `json:"a,omitempty" form:"a,omitempty"`
	B   int `json:"b,omitempty" form:"b,omitempty"`
}

type T3 struct {
	*T1 `json:"t1" form:"t1"`
	A   int `json:"a,omitempty" form:"a,omitempty"`
	B   int `json:"b,omitempty" form:"b,omitempty"`
}

func main() {
	x := T2{&T1{1, 2}, 3, 4}
	s, _ := json.Marshal(x)
	s2, _ := form.EncodeToString(x)
	fmt.Println(string(s), s2)

	x2 := T3{&T1{1, 2}, 3, 4}
	s, _ = json.Marshal(x2)
	s2, _ = form.EncodeToString(x2)
	fmt.Println(string(s), s2)
}

Output:

{"x":1,"y":2,"a":3,"b":4} T1.x=1&T1.y=2&a=3&b=4
{"t1":{"x":1,"y":2},"a":3,"b":4} a=3&b=4&t1.x=1&t1.y=2

Second result is ok, but in first best result is "x=1&y=2&a=3&b=4"

Possibility of not indicate the index in the form html

Hi,
I have this:
type Film struct {
Genres []string
Topics []string
}

I am obliged to indicate the index of slice in the input form:



Is possible NOT indicate the index and only leave "Topics"? With gorilla/schema it is possible, but gorilla/schema, in general, is much more limited...

Thanks!

Best,
Emilio

Feature Request: File uploads

It would be nice to have the ability to encode files in the form data.

For example, we could have a special struct tag that indicates this field represents a file path.

Can decode/encode anonymous fields

Hi!
In the app that I created found a problem. I use a lot of this library, it allow so much fields but not anonymous fields. For example, i have in my project a two structs:

type Length struct {
    Title        map[string]string `json:"title"`
    Release  map[string]string `json:"release,omitempty"`
    Genres   Genre                  `json:"genres"`
    Topics    []string                 `json:"genres"`
}

type FilmBasedEpisodes struct {
    Length
    Channel  Channel
    Seasons  []Season
}

But when I want do this:

....
r.ParseMultipartForm(maxMemory)
dataFormHTML := r.Form
film := FilmBasedEpisodes{}
err := form.DecodeValues(&film, dataFormHTML)
....

The content of dataFormHTML is, for example, like this:

"Title.US":"Six Feet Under", "Title.ES": "A dos metros bajo tierra", "Channel.Original":"HBO"

The error from ajg.form in go compiler is : Title doesn't exist in struct main.FilmBasedEpisodes

I understand that the library not is compatible with anonymous fields, right? If I wrong, then, how I do it?

Best,
Emilio

keys with periods in them

A particular third-party API I wish to contact used periods in the key names. I have the keys in my structs labelled as such:

type whatever struct {
CleanupReturnCleaned bool form:"cleanup.returnCleaned"
}

but when I run form.EncodeToString() I get:
cleanup%5C.returnCleaned=true

I've read the documentation in the Readme and have tried escaping the period with a back slash but that doesnt seem to have the desired effect. Am I misreading the readme, or is this not possible using ajg/form?

Cheers!

Intentional special casing of periods in form keys limits real-world usage

Due to the intentional special casing of periods within form, any API which uses periods in a form field cannot be interacted with without some hacks. For example, the fastly API utilizes periods in their form fields: https://docs.fastly.com/api/config#settings_9740ff4ac0c1777f455274c4850ece23

The go-fastly library attempted to work around this by manually ripping out the generated escapes, but that leads to other things being unintentionally ripped out, as noted in this case: fastly/go-fastly#11

Is there any workaround for interacting with forms which have periods in their form keys?

Behavior of isEmptyValue

The implementation of isEmptyValue makes encoding certain structs a bit non-intuitive. Similar to the discussion here, I am trying to encode a 0 in a request.

I would expect the following code to result in "num=0&name=test" but instead I end up with "num=&name=test" even though my value does "exist".

package main

import (
    "bytes"
    "github.com/ajg/form"
    "log"
)

type Thing struct {
    String  string `form:"name,omitempty"`
    Integer *uint  `form:"num,omitempty"`
}

func main() {

    a_num := uint(0)
    u := Thing{"test", &a_num}
    buf := new(bytes.Buffer)
    if err := form.NewEncoder(buf).DelimitWith('|').Encode(u); err != nil {
        log.Printf("[ERR] %s", err)
    }
    body := buf.String()
    log.Printf("[DEBUG] %s", body)

}

Fails to decode struct if field is missing

The library fails to decode a struct if field is missing.

E.g. I do have a struct

type TokenExchange struct {
  Type string `form:"grant_type"`
  Code string `form:"code"`
}

The input string to parse

grant_type=authorization_code&code=xxx&client_id=xxx

The library fails to decode string with an error

client_id doesn't exist in main.TokenExchange

I would expect that library skips client_id.

Tests are failing on Go 1.17: "invalid semicolon separator in query"

It looks like the tests are failing on Go 1.17 and up around parsing semicolons.

There are a couple ways to resolve - one of them is using the Go handler: https://pkg.go.dev/net/http#AllowQuerySemicolons

Other suggestions: https://golangshowcase.com/question/invalid-semicolon-separator-in-query-after-go-1-17

➜  form git:(master) ✗ go test ./...
--- FAIL: TestDecodeString (0.00s)
    decode_test.go:17: DecodeString(";C=42%2B6.6i;A.0=x;M.Bar=8;F=6.6;A.1=y;R=8734;A.2=z;Zs.0.Qp=33_44;B=true;M.Foo=7;T=2013-10-01T07:05:34.000000088Z;E.Bytes1=%00%01%02;Bytes2=%03%04%05;Zs.0.Q=11_22;Zs.0.Z=2006-12-01;M.Qux=9;life=42;S=Hello,+there.;P\\.D\\\\Q\\.B.A=P/D;P\\.D\\\\Q\\.B.B=Q-B;U=http%3A%2F%2Fexample.org%2Ffoo%23bar;"): invalid semicolon separator in query
    decode_test.go:17: DecodeString(";C=42%2B6.6i;A.0=x;M.Bar=8;F=6.6;A.1=y;R=8734;A.2=z;Zs.0.Qp=33_44;B=true;M.Foo=7;T=2013-10-01T07:05:34.000000088Z;E.Bytes1=%00%01%02;Bytes2=%03%04%05;Zs.0.Q=11_22;Zs.0.Z=2006-12-01;M.Qux=9;life=42;S=Hello,+there.;P\\.D\\\\Q\\.B.A=P/D;P\\.D\\\\Q\\.B.B=Q-B;U=http%3A%2F%2Fexample.org%2Ffoo%23bar;"): invalid semicolon separator in query
    decode_test.go:17: DecodeString(";C=42%2B6.6i;A.0=x;M.Bar=8;F=6.6;A.1=y;R=8734;A.2=z;Zs.0.Qp=33_44;B=true;M.Foo=7;T=2013-10-01T07:05:34.000000088Z;E.Bytes1=%00%01%02;Bytes2=%03%04%05;Zs.0.Q=11_22;Zs.0.Z=2006-12-01;M.Qux=9;life=42;S=Hello,+there.;P\\.D\\\\Q\\.B.A=P/D;P\\.D\\\\Q\\.B.B=Q-B;U=http%3A%2F%2Fexample.org%2Ffoo%23bar;"): invalid semicolon separator in query
--- FAIL: TestDecodeValues (0.00s)
panic: invalid semicolon separator in query [recovered]
        panic: invalid semicolon separator in query
FAIL

Proposal: Support for Reset

It would be useful for my use case if both the encoder and decoder structs exposed a Reset method which allowed changing the underlying io.Writer or io.Reader without having to create new instances. This makes it possible to use sync.Pool for example to manage a set of instances. The implementation would be trivial given that they don't have state other than the writer or reader. Would you consider a PR that added these? I'm thinking something like:

in decode.go:

func (d *decoder) Reset(r io.Reader) {
    d.r = r
}

in encode.go

func (e *encoder) Reset(w io.Writer) {
    e.w = w
}

Serialize composite []string with empty square brackets

👋🏻 I have an API that expects data to be sent like so:

services[]=A&services[]=B

How can I achieve this?

Currently the default behaviour appears to number each element within the slice.

I see there's a DelimitWith method but that doesn't quite achieve what I need (e.g. DelimitWith('|')):

services|0=A&services|1=B

Is there a custom unmarshal method I can define that might help encode the data how I need it?

Thanks!

tag v1.5.2

Please tag commit 9aeb3cf with v1.5.2. It simplify the lib usage with go mod and unlocks the latest.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.