Iris: Is there a way to get body as a string?

Created on 12 Aug 2018  路  7Comments  路  Source: kataras/iris

In docs iris have few body readers methods
UnmarshalBody
ReadJSON
ReadXML
ReadForm
and no method like
ReadText

I tryed to use ctx.Request().Body but it doesn't work however ctx.Request().ContentLength() return correct value of length that I try to send.
ctx.Request().GetBody() raise panic exception with no additional information

question

Most helpful comment

Hello @vadimptr this is a very easy to be answered question, it should be easy to solve but you don't have experience with net/http either if I am correct, right? No problem, let's go through it:

Learn for Free

The context#ReadJSON,ReadXML,ReadForm and all that functions are pointing to the context#UnmarshalBody, the source code is 100% open so you can just look how Iris is reading the request body(like any net/http-based framework does, we do nothing special at that point here except the note you'll read below): https://github.com/kataras/iris/blob/master/context/context.go#L2348

Note

In net/http and othe frameworks you can only read the body once by-default, you can't re-read it, so if you call ReadXXX and try to manual read the body as string it will fail because the body is already consumed, the go standard's io.Read func has this behavior. However in Iris we have the option WithoutBodyConsumptionOnUnmarshal which you can set on app.Run(..., iris.WithoutBodyConsumptionOnUnmarshal) if you really want to read the body manually even after the context's ReadXXX functions, the internal check is easy: https://github.com/kataras/iris/blob/master/context/context.go#L2353

Direct Answer to your Question:

import (
   "io/ioutil"

  "github.com/kataras/iris"
)

func(ctx iris.Context) {
  rawBodyAsBytes, err := ioutil.ReadAll(ctx.Request().Body)
  if err != nil { /* handle the error */ ctx.Writef("%v", err) }

  rawBodyAsString := string(rawBodyAsBytes)
  println(rawBodyAsString) /* do what ever you want, this is the answer you were looking for */
}

Thanks and have fun,
Gerasimos Maropoulos

All 7 comments

Founded solution
rawData, _ := ioutil.ReadAll(ctx.Request().Body)

Hello @vadimptr this is a very easy to be answered question, it should be easy to solve but you don't have experience with net/http either if I am correct, right? No problem, let's go through it:

Learn for Free

The context#ReadJSON,ReadXML,ReadForm and all that functions are pointing to the context#UnmarshalBody, the source code is 100% open so you can just look how Iris is reading the request body(like any net/http-based framework does, we do nothing special at that point here except the note you'll read below): https://github.com/kataras/iris/blob/master/context/context.go#L2348

Note

In net/http and othe frameworks you can only read the body once by-default, you can't re-read it, so if you call ReadXXX and try to manual read the body as string it will fail because the body is already consumed, the go standard's io.Read func has this behavior. However in Iris we have the option WithoutBodyConsumptionOnUnmarshal which you can set on app.Run(..., iris.WithoutBodyConsumptionOnUnmarshal) if you really want to read the body manually even after the context's ReadXXX functions, the internal check is easy: https://github.com/kataras/iris/blob/master/context/context.go#L2353

Direct Answer to your Question:

import (
   "io/ioutil"

  "github.com/kataras/iris"
)

func(ctx iris.Context) {
  rawBodyAsBytes, err := ioutil.ReadAll(ctx.Request().Body)
  if err != nil { /* handle the error */ ctx.Writef("%v", err) }

  rawBodyAsString := string(rawBodyAsBytes)
  println(rawBodyAsString) /* do what ever you want, this is the answer you were looking for */
}

Thanks and have fun,
Gerasimos Maropoulos

Yes I'm a newbie in golang and net/http
Sorry for the stupid question

No problem, you got more details now, it is good to ask and i am always open to answer and help you, although I noticed that when I pressed the submit button you had already found the solution almost a half second ago, we have good synchronization :)

Hello.

Do I need to do defer ctx.Request (). Body.Close ()?

thank you.

if you are handling request body in a middleware, make sure you've closed the body and assigned a new one

    ctx.Request().Body.Close()
    ctx.Request().Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

If app.Run(..., iris.WithoutBodyConsumptionOnUnmarshal) and ctx.GetBody/ctx.ReadJSON, XML... then you don't have to make it by yourself @wk1216123

https://github.com/kataras/iris/blob/36598ebb4518cad6628656241d1f4cdf6ac6b1f6/context/context.go#L2523-L2527

Was this page helpful?
0 / 5 - 0 ratings