using web::WebUtil** The HTTP response.class ButterResponse {** The HTTP status code. Int statusCode** The HTTP status message. Str statusMsg** The HTTP repsonse headers. HttpResponseHeaders headers** HTTP version of the response. Version version := Butter.http11** The request body. Buf body** A temporary store for request data, use to pass data between middleware. Str:Obj data := [:]** it-block ctor.new make(|This| in){ in(this)}** Creates a response reading real HTTP values from an 'InStream'.** The whole response body is read in. new makeFromInStream(InStream in){ res := Str.defValtry{ resVer := (Version?)null res = in.readLineif(res.startsWith("HTTP/1.0")) resVer = Butter.http10elseif(res.startsWith("HTTP/1.1")) resVer = Butter.http11elsethrow IOErr("Unknown HTTP version: ${res}") statusCode = res[9..11].toInt statusMsg = res[13..-1] headers = HttpResponseHeaders(WebUtil.parseHeaders(in))// ChunkInStream throws NullErr if the response has no body, e.g. HEAD requests// see http://fantom.org/sidewalk/topic/2365// I could check the Content-Length header, but why should I trust it!? instream := WebUtil.makeContentInStream(headers.map, in)try body = instream.readAllBufcatch body = Buf() instream.close}catch(IOErr e)throw e catch(Err err)throw IOErr("Invalid HTTP response: $res", err)}** Create a response from a 'Str' body.new makeFromStr(Int statusCode, Str statusMsg, Str:Str headers, Str body, |This|? f := null){this.statusCode = statusCodethis.statusMsg = statusMsgthis.headers = HttpResponseHeaders(headers)this.body = Buf(){ charset = this.headers.contentType?.charset ?: Charset.utf8 }.writeChars(body).flip f?.call(this)}** Reads the response stream and converts it to a 'Str' using the charset defined in the 'Content-Type' header.** ** This method closes the response stream. Str asStr(){ body.seek(0).charset = headers.contentType?.charset ?: Charset.utf8return body.readAllStr}** Return the response stream as a 'Buf'.** ** Convenience for `in.readAllBuf`. ** This method closes the response stream. Buf asBuf(){ body.seek(0)}** Returns the body as an 'InStream'. InStream asInStream(){ body.seek(0).in} @NoDocoverride Str toStr(){"$statusCode - $statusMsg"}}