DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
HttpResponse.cpp
Go to the documentation of this file.
1#include "pch.h"
3#include "System/Console.h"
4#include "System/Convert.h"
5#include <string>
6
7namespace DotNetDupe {
8 namespace WebAppCore {
9 namespace Http {
10
11 static void WriteRaw(System::SmartPointer<System::Net::Sockets::NetworkStream> pStream, const std::string& str) {
13 if (!pStream.IsNull() && !str.empty()) {
14 pStream->Write(str.data(), 0, static_cast<int>(str.length()));
15 }
16 }
17
18 static std::string GetHttpStatusMessage(int code) {
20 switch (code) {
21 case 201: return "Created";
22 case 204: return "No Content";
23 case 400: return "Bad Request";
24 case 401: return "Unauthorized";
25 case 404: return "Not Found";
26 case 500: return "Internal Server Error";
27 default: return "OK";
28 }
29 }
30
31 static std::string BuildResponseHeaderString(int statusCode, const System::String& contentType, bool bChunked, const System::Collections::Generic::Dictionary<System::String, System::String>& headers) {
33 std::string headerString = "HTTP/1.1 " + std::to_string(statusCode) + " " + GetHttpStatusMessage(statusCode) + "\r\n";
34 headerString += "Content-Type: " + std::string(contentType.GetRawString() ? contentType.GetRawString() : "") + "\r\n";
35 if (bChunked) headerString += "Transfer-Encoding: chunked\r\n";
36 headerString += "Connection: keep-alive\r\nServer: DotNetDupeWebApplication/1.0\r\n";
38 auto keys = headers.GetKeys(); auto values = headers.GetValues();
39 for (int i = 0; i < keys.GetLength(); ++i) {
40 headerString += std::string(keys[i].GetRawString() ? keys[i].GetRawString() : "") + ": " + std::string(values[i].GetRawString() ? values[i].GetRawString() : "") + "\r\n";
41 }
43 return headerString + "\r\n";
44 }
45
48 if (m_bHeadersSent) return;
49 m_bHeadersSent = true;
51 WriteRaw(m_pStream, BuildResponseHeaderString(m_nStatusCode, m_sContentType, m_bChunked, m_headers));
52 }
53
56 std::string rawData = std::string(data.GetRawString() ? data.GetRawString() : "");
57 if (rawData.empty()) return;
59 if (!m_bHeadersSent) {
60 m_bChunked = true;
62 }
63
65 char hexBuf[32] = { 0 };
66 snprintf(hexBuf, sizeof(hexBuf), "%zX\r\n", rawData.length());
67 std::string chunk = std::string(hexBuf) + rawData + "\r\n";
68 WriteRaw(m_pStream, chunk);
69 }
70
73 if (!m_bHeadersSent) {
75 }
77 if (m_bChunked) {
78 WriteRaw(m_pStream, "0\r\n\r\n");
79 } else {
80 std::string body = std::string(m_sBody.GetRawString() ? m_sBody.GetRawString() : "");
81 if (!body.empty()) {
82 WriteRaw(m_pStream, body);
83 }
84 }
85 }
86
87 }
88 }
89}
Represents standard input, output, and error streams for console applications.
Converts a base data type to another base data type, and encodes/decodes Base64 data.
HTTP request, response, and context abstractions for WebAppCore processing pipelines.
Represents a collection of keys and values.
Definition Dictionary.h:66
A unified smart pointer that supports both unique and shared ownership semantics.
bool IsNull() const noexcept
Checks if the SmartPointer is null.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
Definition String.h:74
const char * GetRawString() const
Definition String.cpp:230
void FlushHeaders()
Serializes and transmits the HTTP status line and response headers to the network stream.
void WriteChunk(const DotNetDupe::System::String &data)
Writes a chunk of data using HTTP/1.1 chunked transfer encoding.
void Flush()
Flushes any remaining response body or terminal chunk marker to the client stream.
static std::string BuildResponseHeaderString(int statusCode, const System::String &contentType, bool bChunked, const System::Collections::Generic::Dictionary< System::String, System::String > &headers)
static std::string GetHttpStatusMessage(int code)
static void WriteRaw(System::SmartPointer< System::Net::Sockets::NetworkStream > pStream, const std::string &str)