Skip to content

Commit

Permalink
Make Recorder correctly record binary bodies, backport #1203
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephane Landelle committed May 27, 2013
1 parent 4d11d50 commit b493fd8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
8 changes: 4 additions & 4 deletions gatling-recorder/src/main/resources/templates/request.ssp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<%@ val method: String %>
<%@ val printedUrl: String %>
<%@ val queryParams: List[(String, String)] %>
<%@ val requestBodyOrParams: Option[Either[String, List[(String, String)]]] %>
<%@ val body: Option[com.excilys.ebi.gatling.recorder.scenario.RequestBody] %>
<%@ val statusCode: Int %>
<%@ val id: Int %>
<%@ val credentials: Option[(String,String)] %>
Expand All @@ -15,10 +15,10 @@ exec(http("request_<%= id %>")
<% for (queryParam <- queryParams) { %>
.queryParam("""<%= queryParam._1 %>""", """<%= queryParam._2 %>""")
<% } %>
<% requestBodyOrParams.map { _ match {
case Left(_) => %>
<% body.map { _ match {
case com.excilys.ebi.gatling.recorder.scenario.RequestBodyBytes(_) => %>
.fileBody("<%= simulationClass %>_request_<%= id %>.txt")
<% case Right(params) => params.foreach { case(key, value) => %>
<% case com.excilys.ebi.gatling.recorder.scenario.RequestBodyParams(params) => params.foreach { case (key, value) => %>
.param("""<%= key %>""", """<%= value %>""")
<% } %>
<% } %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ import com.ning.http.util.Base64

import grizzled.slf4j.Logging

sealed trait RequestBody
case class RequestBodyParams(params: List[(String, String)]) extends RequestBody
case class RequestBodyBytes(bytes: Array[Byte]) extends RequestBody

object RequestElement {
def apply(r: RequestElement, newStatusCode: Int) = {
new RequestElement(r.request, newStatusCode, r.simulationClass)
Expand All @@ -41,8 +45,6 @@ object RequestElement {
class RequestElement(val request: HttpRequest, val statusCode: Int, val simulationClass: Option[String]) extends ScenarioElement with Logging {
val method = request.getMethod.toString

private val containsFormParams: Boolean = Option(request.getHeader(CONTENT_TYPE)).map(_.contains("application/x-www-form-urlencoded")).getOrElse(false)

private val uriParts = request.getUri.split("/", 4)
val baseUrl = uriParts.take(3).mkString("/")
val path = "/" + uriParts.lift(3).getOrElse("").split("\\?")(0)
Expand All @@ -54,22 +56,19 @@ class RequestElement(val request: HttpRequest, val statusCode: Int, val simulati

val queryParams = convertParamsFromJavaToScala(new QueryStringDecoder(request.getUri, Charset.forName(configuration.encoding)).getParameters)

val requestBodyOrParams: Option[Either[String, List[(String, String)]]] = if (request.getContent.readableBytes > 0) {

val bufferBytes = new Array[Byte](request.getContent.readableBytes)
val body: Option[RequestBody] = {

request.getContent.getBytes(request.getContent.readerIndex, bufferBytes);
val content = if (request.getContent.readableBytes > 0) {
val bufferBytes = new Array[Byte](request.getContent.readableBytes)
request.getContent.getBytes(request.getContent.readerIndex, bufferBytes)
Some(bufferBytes)
} else None

val bodyString = new String(bufferBytes, configuration.encoding)

if (containsFormParams) {
Some(Right(parseFormBody(bodyString)))
} else {
(Some(Left(bodyString)))
content.map { bytes =>
val containsFormParams = Option(request.getHeader(CONTENT_TYPE)).map(_.contains("application/x-www-form-urlencoded")).getOrElse(false)
if (containsFormParams) RequestBodyParams(parseFormBody(new String(bytes, configuration.encoding)))
else RequestBodyBytes(bytes)
}

} else {
None
}

var id: Int = 0
Expand Down Expand Up @@ -106,7 +105,7 @@ class RequestElement(val request: HttpRequest, val statusCode: Int, val simulati
"method" -> method,
"printedUrl" -> printedUrl,
"queryParams" -> queryParams,
"requestBodyOrParams" -> requestBodyOrParams,
"body" -> body,
"statusCode" -> statusCode,
"id" -> id,
"credentials" -> basicAuthCredentials,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ object ScenarioExporter extends Logging {
case e: RequestElement =>
i = i + 1
e.updateUrl(baseUrl).setId(i)
e.requestBodyOrParams.map(_.left.map(dumpRequestBody(i, _, configuration.simulationClassName)))
e.body.map {
_ match {
case RequestBodyBytes(bytes) => dumpRequestBody(i, bytes, configuration.simulationClassName)
case _ =>
}
}

case _ =>
}
Expand Down Expand Up @@ -175,11 +180,11 @@ object ScenarioExporter extends Logging {
Left(scenarioElements)
}

private def dumpRequestBody(idEvent: Int, content: String, simulationClass: String) {
private def dumpRequestBody(idEvent: Int, bytes: Array[Byte], simulationClass: String) {
use(new FileOutputStream(File(getFolder(configuration.requestBodiesFolder) / simulationClass + "_request_" + idEvent + ".txt").jfile)) {
fw =>
try {
fw.write(content.getBytes(configuration.encoding))
fw.write(bytes)
} catch {
case e: IOException => error("Error, while dumping request body...", e)
}
Expand Down

0 comments on commit b493fd8

Please sign in to comment.