0

I am currently using fasthttp for sending my requests my question is, is there a way to have a persistent session? I need the cookies and data to stick.

c := fasthttp.Client{ Name: "Add To Cart",}

store, err := session.Start() // ?????
args := fasthttp.AcquireArgs()
defer fasthttp.ReleaseArgs(args)

args.Add("pid", sizepid)
args.Add("options", "[]")
args.Add("quantity", "1")

statusCode, body, err := c.Post(nil, "URL", args)
if err != nil {
    panic(err)
}`
Tiya Jose
  • 1,359
  • 14
  • 24
  • Should I switch over to go-sessions? or can I continue to use fasthttp? – EmptyCarts Feb 06 '20 at 01:34
  • There's a session package for fasthttp: https://github.com/phachon/fasthttpsession . It's in the fasthttp readme and that package's readme has code examples. –  Feb 06 '20 at 01:38
  • How would I add it to something like this?? since I don't have the fasthttp.RequestCtx. I edited my question to include the code. – EmptyCarts Feb 06 '20 at 01:47
  • The `fasthttpsession` package seems to be intended for use with `fasthttp` as a server, not as a client. – Jory Geerts Feb 06 '20 at 10:33

1 Answers1

1

Based on your question I think this is already clear to you, but just in case: Sessions aren't started on the client, they are started on the server. The server checks to see if a specific cookie exists; if it does it resumes the session that the cookie identifies; if it doesn't it creates a new session and sends the identifier back to the client as a cookie. All the client needs to do is send the correct cookie to the server.

So, you need to read and write cookies. The fasthttp.Client.Post() interface doesn't allow you to do that. So instead of that nice interface, things become rather ugly.

You need to ask fasthttp for both a Request and Response object before you do the request. Once you've done the initial request, you need to either look all cookies, or read out a specific cookie. You can now use those values for your next request.

I've written a short example of how you would do this.

func main() {
    c := fasthttp.Client{}

    // Create a request
    req := fasthttp.AcquireRequest()
    defer fasthttp.ReleaseRequest(req)
    req.SetRequestURI(`https://www.google.com/`)

    // Create a response
    resp := fasthttp.AcquireResponse()
    defer fasthttp.ReleaseResponse(resp)

    // Execute the request, writing to the response object
    err := c.Do(req, resp)
    if err != nil {
        panic(err)
    }

    //  Loop over all cookies; usefull if you want to just send everything back on consecutive requests
    resp.Header.VisitAllCookie(func(key, value []byte) {
        log.Printf("Cookie %s: %s\n", key, value)
    })

    // Read a specific cookie
    nid := fasthttp.AcquireCookie()
    defer fasthttp.ReleaseCookie(nid)
    nid.SetKey(`NID`)
    if resp.Header.Cookie(nid) {
        log.Println("Value for NID Cookie: " + string(nid.Value()))

        // Create a second request and set the cookie from the first
        req2 := fasthttp.AcquireRequest()
        defer fasthttp.ReleaseRequest(req2)
        req2.SetRequestURI(`https://www.google.com/`)
        req2.Header.SetCookie(`NID`, string(nid.Value()))

        // Now you can execute this request again using c.Do() - don't forget to acquire a new Response!
    }
}

Note: you can chose to skip the fasthttp.AcquireXXX() and defer fasthttp.ReleaseXXX(yyy) steps - but that would negate much (maybe most) of the performance benefits over using standard net/http, so if you go that route maybe just ditch fasthttp all together.

Jory Geerts
  • 1,916
  • 15
  • 25
  • How do I add all cookies to future request which is in another func?? – EmptyCarts Feb 06 '20 at 22:36
  • Well, you could build a `map[string]string` that you fill inside `VisitAllCookie()` and pass that map to the other func (either explicitly as a parameter, or more implicitly by making the map a property on the struct that contains the func). – Jory Geerts Feb 07 '20 at 09:56