Fixed flushing of empty responses.
This commit is contained in:
parent
18851ac786
commit
22e8fa9b70
|
@ -56,7 +56,13 @@ unittest {
|
|||
HttpRequestHandler handler = HttpRequestHandler.of(
|
||||
(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
||||
response.status = HttpStatus.OK;
|
||||
response.writeBodyString("Testing");
|
||||
});
|
||||
testHttp1Transport(new TaskPoolHttp1Transport(handler));
|
||||
|
||||
HttpRequestHandler handler2 = HttpRequestHandler.of(
|
||||
(ref ServerHttpRequest request, ref ServerHttpResponse response) {
|
||||
response.status = HttpStatus.OK;
|
||||
response.writeBodyString("Testing");
|
||||
});
|
||||
testHttp1Transport(new TaskPoolHttp1Transport(handler2));
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ version(unittest) {
|
|||
|
||||
string httpResponseContent = cast(string) buffer[0 .. totalBytesReceived];
|
||||
string[] parts = httpResponseContent.split("\r\n\r\n");
|
||||
assert(parts.length > 0, "HTTP 1.1 response is missing required status and headers section.");
|
||||
assert(parts.length > 0, "HTTP 1.1 response is missing required status and headers section:\n\n" ~ httpResponseContent);
|
||||
string[] headerLines = parts[0].split("\r\n");
|
||||
assert(headerLines.length > 0, "HTTP 1.1 response is missing required status line.");
|
||||
string statusLine = headerLines[0];
|
||||
|
@ -131,13 +131,22 @@ void handleClient(Socket clientSocket, HttpRequestHandler requestHandler) {
|
|||
scope ServerHttpRequest request = result.request;
|
||||
scope ServerHttpResponse response;
|
||||
SocketOutputStream* outputStream = new SocketOutputStream(clientSocket);
|
||||
response.outputStream = outputStreamObjectFor(HttpResponseOutputStream!(SocketOutputStream*)(
|
||||
outputStream,
|
||||
&response
|
||||
));
|
||||
HttpResponseOutputStream!(SocketOutputStream*) responseOutputStream
|
||||
= HttpResponseOutputStream!(SocketOutputStream*)(
|
||||
outputStream,
|
||||
&response
|
||||
);
|
||||
response.outputStream = outputStreamObjectFor(&responseOutputStream);
|
||||
try {
|
||||
requestHandler.handle(request, response);
|
||||
debugF!"%s %s -> %d %s"(request.method, request.url, response.status.code, response.status.text);
|
||||
// If the response's headers aren't flushed yet, write them now.
|
||||
if (!responseOutputStream.areHeadersFlushed()) {
|
||||
auto writeResult = responseOutputStream.writeHeaders();
|
||||
if (writeResult.hasError) {
|
||||
errorF!"Failed to write response headers: %s"(writeResult.error.message);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error("Exception thrown while handling request.", e);
|
||||
} catch (Throwable t) {
|
||||
|
|
|
@ -23,6 +23,15 @@ struct HttpResponseOutputStream(S) if (isByteOutputStream!S) {
|
|||
this.response = response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the HTTP response headers have been flushed to the
|
||||
* underlying output stream.
|
||||
* Returns: `true` if the headers have been flushed, `false` otherwise.
|
||||
*/
|
||||
bool areHeadersFlushed() const {
|
||||
return headersFlushed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given data to the stream. If the referenced HTTP response's
|
||||
* status and headers haven't yet been written, they will be written first.
|
||||
|
@ -37,7 +46,6 @@ struct HttpResponseOutputStream(S) if (isByteOutputStream!S) {
|
|||
auto result = writeHeaders();
|
||||
if (result.hasError) return result;
|
||||
bytesWritten += result.count;
|
||||
headersFlushed = true;
|
||||
}
|
||||
auto result = outputStream.writeToStream(buffer);
|
||||
if (result.hasError) return result;
|
||||
|
@ -50,6 +58,10 @@ struct HttpResponseOutputStream(S) if (isByteOutputStream!S) {
|
|||
* Returns: The stream result of writing.
|
||||
*/
|
||||
StreamResult writeHeaders() {
|
||||
if (headersFlushed) {
|
||||
return StreamResult(0); // No need to write again.
|
||||
}
|
||||
headersFlushed = true;
|
||||
size_t idx = 0;
|
||||
char[6] statusCodeBuffer; // Normal HTTP codes are 3 digits, but this leaves room for extensions.
|
||||
writeUIntToBuffer(response.status.code, statusCodeBuffer, idx);
|
||||
|
@ -111,13 +123,15 @@ unittest {
|
|||
resp.status = HttpStatus.OK;
|
||||
resp.headers.add("Content-Type", "text/plain");
|
||||
auto httpOut = HttpResponseOutputStream!(ArrayOutputStream!ubyte*)(&os, &resp);
|
||||
resp.outputStream = outputStreamObjectFor(httpOut);
|
||||
resp.outputStream = outputStreamObjectFor(&httpOut);
|
||||
assert(httpOut.areHeadersFlushed() == false);
|
||||
StreamResult r = resp.outputStream.writeToStream(cast(ubyte[]) "Hello world!");
|
||||
const expectedOutput =
|
||||
"HTTP/1.1 200 OK\r\n" ~
|
||||
"Content-Type: text/plain\r\n" ~
|
||||
"\r\n" ~
|
||||
"Hello world!";
|
||||
assert(httpOut.areHeadersFlushed() == true);
|
||||
assert(os.toArray() == expectedOutput);
|
||||
assert(r.hasCount);
|
||||
assert(r.count == os.toArray().length);
|
||||
|
|
Loading…
Reference in New Issue