DEV Community

Cover image for An interesting process of solving an issue
Lorain
Lorain

Posted on

An interesting process of solving an issue

Foreword

This article focuses on the process of solving an issue for Hertz. The link to the issue is here.

Issue Analysis

The originator of this issue was a user who wanted to migrate from FastHTTP to Hertz, but for some reason couldn't get all of his code based on Hertz at once, so now he's trying to get Hertz to replace some of his previous FastHTTP code.

Now he had some problems with the FastHTTP Cookie docking with Hertz, so we can take a look at the core code he sent.

// FastHTTP code
cookie := FastHTTPCtx.Response.Header.Peek(fasthttp.HeaderCookie)
// Hertz code
cookieNew := protocol.AcquireCookie()
cookieNew.Parse(string(cookie))
HertzCtx.Response.Header.SetCookie(cookieNew)
Enter fullscreen mode Exit fullscreen mode

If we take a quick look, we can see that the user is trying to get the value of the cookie field (fasthttp.HeaderCookie) in the response header using FastHTTP's Peek function. Then use Hertz to get an empty cookie from the pool and use the Parse function to parse the FastHTTP cookie field and set it into the empty Cookie, and finally set it into the response header using Hertz's SetCookie function.

There are two bugs in this code. The first one is very easy to find. You can see the user Peek the HTTP response header. However, the cookie field is not in the response header. Only the HTTP request header has the cookie field. So you can't actually get the value here, the correct code would look like this:

  • Get the cookie field of the request header
cookie := FastHTTPCtx.Request.Header.Peek(fasthttp.HeaderCookie)
Enter fullscreen mode Exit fullscreen mode
  • Get the set-cookie field of the response header
cookie := FastHTTPCtx.Response.Header.Peek(fasthttp.HeaderSetCookie)
Enter fullscreen mode Exit fullscreen mode

The second bug, which is a little harder to spot, is that we Peek all the values in the cookie field, which contains many cookies, but the Parse function can't parse them all at once and set them to the empty allocated cookie.

To verify this bug, I took a snippet of the value of the cookie field that I brought when I visited github, and then parsed it with the Parse function. Finally, we printed the values set on the cookie, and we can see that the last cookie contains only the value of the first cookie.

package main

import "github.com/cloudwego/hertz/pkg/protocol"

func main() {
   cookie := protocol.AcquireCookie()
   defer protocol.ReleaseCookie(cookie)
   _ = cookie.Parse("_device_id=12ion3sbdfs6c06dde9f4oroiu5nd32dsfio9; _octo=GH1.1.199263436.16523146515; user_session=21tB__7-tTVwYCm0unrewjbSdX7Bp0UU59d9BWy-MQgFDUEJRN; __Host-user_session_same_site=21wR__7-tTVwYCm0uasdibqwyD7Bp0UU59d9BWy-MQgFDUEJRN; logged_in=yes; dotcom_user=justlorain; preferred_color_mode=light; has_recent_activity=1;")
   println(cookie.String()) //_device_id=12ion3sbdfs6c06dde9f4oroiu5nd32dsfio9
}
Enter fullscreen mode Exit fullscreen mode

Solution

We can Parse and SetCookie one by one using the VisitAllCookie function, as follows:

FastHttpctx.Response.Header.VisitAllCookie(func(key, value []byte) {
   cookie := protocol.AcquireCookie()
   defer protocol.ReleaseCookie(cookie)
   _ = cookie.ParseBytes(value)
   HertzCtx.Response.Header.SetCookie(cookie)
})
Enter fullscreen mode Exit fullscreen mode

Summary

That's it for analyzing and resolving this issue. I hope you found it helpful and I'm very welcome to try out the Hertz HTTP framework. You can find more information about Hertz in my previous posts. And welcome to some very valuable issues for Hertz, the CloudWeGo community members will do their best to answer.

Reference List

Top comments (0)