Skip to content

Commit

Permalink
moved default setting of content type on string POST body to when req…
Browse files Browse the repository at this point in the history
…uest is built, not when set with <<
  • Loading branch information
Fuquen, Edwin committed Jun 12, 2014
1 parent 267e0a3 commit 97efa0b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
49 changes: 33 additions & 16 deletions core/src/main/scala/requests.scala
Expand Up @@ -4,16 +4,39 @@ import com.ning.http.client.RequestBuilder

/** This wrapper provides referential transparency for the
underlying RequestBuilder. */
case class Req(run: RequestBuilder => RequestBuilder)
extends MethodVerbs with UrlVerbs with ParamVerbs
case class Req(
run: RequestBuilder => RequestBuilder,
state: Req.State = Req.State()
) extends MethodVerbs with UrlVerbs with ParamVerbs
with AuthVerbs with HeaderVerbs with RequestBuilderVerbs {
def subject = this
def underlying(next: RequestBuilder => RequestBuilder) =
Req(run andThen next)
def toRequestBuilder = run(new RequestBuilder)
Req(run andThen next, state)
def toState(next: Req.State => Req.State) =
Req(run, next(state))
def toRequestBuilder = {
val requestBuilder = run(new RequestBuilder)
//Body set from String and with no Content-Type will get a default of 'text/plain; charset=UTF-8'
if(state.bodyType == Req.StringBody && !requestBuilder.build.getHeaders.containsKey("Content-Type")) {

This comment has been minimized.

Copy link
@n8han

n8han Jun 20, 2014

I know this is moved from below, but is this case sensitive?

This comment has been minimized.

setContentType("text/plain", "UTF-8").run(new RequestBuilder)
} else {
requestBuilder
}
}
def toRequest = toRequestBuilder.build
}

object Req {
final case class State(bodyType: BodyType = NoBody)

trait BodyType
final case object NoBody extends BodyType
final case object StringBody extends BodyType
final case object ByteArrayBody extends BodyType
final case object EntityWriterBody extends BodyType
final case object FileBody extends BodyType
}

trait HostVerbs {
def apply(host: String) = {
val asciiSafeDomain = IDNDomainHelpers.safeConvert(host)
Expand Down Expand Up @@ -84,11 +107,6 @@ trait ParamVerbs extends RequestVerbs {
subject.setMethod(method)
else subject
}
protected def defaultContentType(mediaType: String, charset: String): Req = {
if (!subject.toRequest.getHeaders.containsKey("Content-Type"))
subject.setContentType(mediaType, charset)
else subject
}

/** Adds `params` to the request body. Sets request method
* to POST if it is currently GET. */
Expand All @@ -102,8 +120,7 @@ trait ParamVerbs extends RequestVerbs {
* - set method to POST if currently GET,
* - set HTTP Content-Type to "text/plain; charset=UTF-8" if unspecified. */
def << (body: String) = {
defaultMethod("POST").defaultContentType("text/plain", "UTF-8").
setBody(body)
defaultMethod("POST").setBody(body)
}
/** Set a file as the request body and set method to PUT if it's
* currently GET. */
Expand Down Expand Up @@ -156,15 +173,15 @@ trait RequestBuilderVerbs extends RequestVerbs {
params.mapValues{ _.asJava: Collection[String] }.asJava
)) }
def setBody(data: Array[Byte]) =
subject.underlying { _.setBody(data) }
subject.underlying { _.setBody(data) }.toState { _.copy(bodyType = Req.ByteArrayBody) }
def setBody(dataWriter: EntityWriter, length: Long) =
subject.underlying { _.setBody(dataWriter, length) }
subject.underlying { _.setBody(dataWriter, length) }.toState { _.copy(bodyType = Req.EntityWriterBody) }
def setBody(dataWriter: EntityWriter) =
subject.underlying { _.setBody(dataWriter) }
subject.underlying { _.setBody(dataWriter) }.toState { _.copy(bodyType = Req.EntityWriterBody) }
def setBody(data: String) =
subject.underlying { _.setBody(data) }
subject.underlying { _.setBody(data) }.toState { _.copy(bodyType = Req.StringBody) }
def setBody(file: java.io.File) =
subject.underlying { _.setBody(file) }
subject.underlying { _.setBody(file) }.toState { _.copy(bodyType = Req.FileBody) }
def setBodyEncoding(charset: String) =
subject.underlying { _.setBodyEncoding(charset) }
def setContentType(mediaType: String, charset: String) =
Expand Down
6 changes: 6 additions & 0 deletions core/src/test/scala/basic.scala
Expand Up @@ -127,4 +127,10 @@ with DispatchCleanup {
res() ?= (sample + "; charset=UTF-8")
}

property("Send a custom content type with <:< after <<") = forAll(Gen.oneOf("application/json", "application/foo")) { (sample: String) =>
val res: Future[String] = Http(
localhost / "contenttype" << "request body" <:< Map("Content-Type" -> sample) > as.String
)
res() ?= (sample)
}
}

0 comments on commit 97efa0b

Please sign in to comment.