Arduino DLNA Server
Loading...
Searching...
No Matches
HttpClientHandler.h
Go to the documentation of this file.
1#pragma once
2
3#include <stddef.h>
4#include <string.h>
5
6#include "HttpChunkWriter.h"
7#include "HttpHeader.h"
8#include "IHttpServer.h"
9#include "basic/RetryPrint.h"
10#include "basic/StrPrint.h"
11
12namespace tiny_dlna {
13
29template <typename ClientT>
31 public:
32 // Default constructor for use in HttpServer
33 HttpClientHandler() = default;
34
37 virtual ~HttpClientHandler() = default;
38
39 void setClient(ClientT* client) { p_client = client; }
40
43 void setKeepAlive(bool active) { is_keep_alive = active; }
44 bool isKeepAlive() { return is_keep_alive; }
45
48 if (!p_client) return;
49 Client& client = *p_client;
50 int count = 50;
51 while (client.available() == 0) {
52 delay(20);
53 if (count-- <= 0) {
54 break;
55 }
56 }
58 // provide reply with empty header
60 }
61
62 // Helper for writing status and message to the reply (uses p_client)
63 void reply(int status, const char* msg) {
64 if (!p_client) return;
65 reply_header.setValues(status, msg);
67 endClient();
68 }
69
70 void replyChunked(const char* contentType, Stream& inputStream,
71 int status = 200, const char* msg = SUCCESS) override {
72 if (!p_client) return;
73 replyChunked(contentType, status, msg);
74 HttpChunkWriter chunk_writer;
75 uint8_t buffer[buffer_size];
76 while (inputStream.available()) {
77 int len = inputStream.readBytes(buffer, buffer_size);
78 chunk_writer.writeChunk(*p_client, (const char*)buffer, len);
79 }
80 chunk_writer.writeEnd(*p_client);
81 endClient();
82 }
83
84 void replyChunked(const char* contentType, int status = 200,
85 const char* msg = SUCCESS) override {
86 if (!p_client) return;
87 DlnaLogger.log(DlnaLogLevel::Info, "reply %s", "replyChunked");
88 reply_header.setValues(status, msg);
90 reply_header.put(CONTENT_TYPE, contentType);
93 }
94
95 void reply(const char* contentType, Stream& inputStream, int size,
96 int status = 200, const char* msg = SUCCESS) override {
97 if (!p_client) return;
98 DlnaLogger.log(DlnaLogLevel::Info, "reply %s", "stream");
99 reply_header.setValues(status, msg);
101 reply_header.put(CONTENT_TYPE, contentType);
104 uint8_t buffer[buffer_size];
105 while (inputStream.available()) {
106 int len = inputStream.readBytes(buffer, buffer_size);
107 p_client->write((const uint8_t*)buffer, len);
108 }
109 endClient();
110 }
111
112 void reply(const char* contentType, size_t (*callback)(Print& out, void* ref),
113 int status = 200, const char* msg = SUCCESS,
114 void* ref = nullptr) override {
115 if (!p_client) return;
116 DlnaLogger.log(DlnaLogLevel::Info, "reply %s", "via callback");
117 NullPrint nop;
118 size_t size = callback(nop, ref);
119 reply_header.setValues(status, msg);
120 reply_header.put(CONTENT_TYPE, contentType);
124 size_t size_eff = callback(*p_client, ref);
125 if (size_eff != size) {
126 DlnaLogger.log(DlnaLogLevel::Warning,
127 "HttpServer callback wrote %d bytes; expected %d",
128 size_eff, size);
129 }
130#if DLNA_LOG_XML
131 callback(Serial, ref);
132#endif
133
134 #if DLNA_CHECK_XML_LENGTH
135 StrPrint test;
136 size_t test_len = callback(test, ref);
137 if (strlen(test.c_str()) != size) {
138 DlnaLogger.log(DlnaLogLevel::Error,
139 "HttpServer wrote %d bytes: expected %d / strlen: %d",
140 test_len, size, strlen(test.c_str()));
141 }
142#endif
143 endClient();
144 }
145
146 void reply(const char* contentType, const char* str, int status = 200,
147 const char* msg = SUCCESS) override {
148 if (!p_client) return;
149 DlnaLogger.log(DlnaLogLevel::Info, "reply %s", str);
150 int len = strlen(str);
151 reply_header.setValues(status, msg);
153 reply_header.put(CONTENT_TYPE, contentType);
156 p_client->write((const uint8_t*)str, len);
157 endClient();
158 }
159
160 void reply(const char* contentType, const uint8_t* str, int len,
161 int status = 200, const char* msg = SUCCESS) override {
162 if (!p_client) return;
163 DlnaLogger.log(DlnaLogLevel::Info, "reply %s: %d bytes", contentType, len);
164 reply_header.setValues(status, msg);
166 reply_header.put(CONTENT_TYPE, contentType);
169 p_client->write((const uint8_t*)str, len);
170 endClient();
171 }
172
173 void replyOK() override { reply("text/plain", "SUCCESS", 200, SUCCESS); }
174
175 void replyNotFound() override {
176 DlnaLogger.log(DlnaLogLevel::Info, "reply %s", "404");
177 reply("text/plain", "Page Not Found", 404, "Page Not Found");
178 }
179
180 void replyError(int err, const char* msg = "Internal Server Error") override {
181 DlnaLogger.log(DlnaLogLevel::Info, "reply %s", "error");
182 reply("text/plain", msg, err, msg);
183 }
184
185 void endClient() override {
186 if (!p_client) return;
187 p_client->flush();
188 p_client->stop();
189 }
190
191 void crlf() override {
192 if (p_client) p_client->println();
193 }
194
195 Client* client() override { return p_client; }
196
198
200
201 // Allows resizing the internal buffer
202 void resize(size_t newSize) { buffer_size = newSize; }
203
204 protected:
205 ClientT* p_client = nullptr;
208 int buffer_size = 512;
209 bool is_keep_alive = true;
210};
211
212} // namespace tiny_dlna
Writes the data chunked to the actual client.
Definition: HttpChunkWriter.h:19
int writeChunk(Client &client, const char *str, int len, const char *str1=nullptr, int len1=0)
Definition: HttpChunkWriter.h:21
void writeEnd(Client &client)
Definition: HttpChunkWriter.h:38
Handles HTTP client connections and responses for the DLNA HTTP server.
Definition: HttpClientHandler.h:30
HttpReplyHeader reply_header
Definition: HttpClientHandler.h:207
virtual ~HttpClientHandler()=default
bool is_keep_alive
Definition: HttpClientHandler.h:209
void reply(const char *contentType, size_t(*callback)(Print &out, void *ref), int status=200, const char *msg=SUCCESS, void *ref=nullptr) override
Definition: HttpClientHandler.h:112
void replyChunked(const char *contentType, int status=200, const char *msg=SUCCESS) override
Definition: HttpClientHandler.h:84
void replyError(int err, const char *msg="Internal Server Error") override
Definition: HttpClientHandler.h:180
int buffer_size
Definition: HttpClientHandler.h:208
HttpRequestHeader & requestHeader()
Definition: HttpClientHandler.h:197
HttpClientHandler(ClientT *client)
Definition: HttpClientHandler.h:36
void reply(const char *contentType, Stream &inputStream, int size, int status=200, const char *msg=SUCCESS) override
Definition: HttpClientHandler.h:95
void reply(int status, const char *msg)
Definition: HttpClientHandler.h:63
void readHttpHeader()
Reads the http header info from the client.
Definition: HttpClientHandler.h:47
HttpReplyHeader & replyHeader()
Definition: HttpClientHandler.h:199
HttpClientHandler(ClientT &client)
Definition: HttpClientHandler.h:35
void setClient(ClientT *client)
Definition: HttpClientHandler.h:39
ClientT * p_client
Definition: HttpClientHandler.h:205
Client * client() override
Definition: HttpClientHandler.h:195
void replyOK() override
Definition: HttpClientHandler.h:173
void replyChunked(const char *contentType, Stream &inputStream, int status=200, const char *msg=SUCCESS) override
Definition: HttpClientHandler.h:70
void reply(const char *contentType, const uint8_t *str, int len, int status=200, const char *msg=SUCCESS) override
Definition: HttpClientHandler.h:160
void setKeepAlive(bool active)
Definition: HttpClientHandler.h:43
bool isKeepAlive()
Definition: HttpClientHandler.h:44
void replyNotFound() override
Definition: HttpClientHandler.h:175
HttpRequestHeader request_header
Definition: HttpClientHandler.h:206
void reply(const char *contentType, const char *str, int status=200, const char *msg=SUCCESS) override
Definition: HttpClientHandler.h:146
void resize(size_t newSize)
Definition: HttpClientHandler.h:202
void crlf() override
Definition: HttpClientHandler.h:191
void endClient() override
Definition: HttpClientHandler.h:185
void read(Client &in)
Definition: HttpHeader.h:233
HttpHeader & clear(bool activeFlag=true)
clears the data - usually we do not delete but we just set the active flag
Definition: HttpHeader.h:86
HttpHeader & put(const char *key, const char *value)
Definition: HttpHeader.h:105
void write(Client &out)
Definition: HttpHeader.h:267
Reading and Writing of Http Replys.
Definition: HttpHeader.h:409
void setValues(int statusCode, const char *msg="", const char *protocol=nullptr)
Definition: HttpHeader.h:412
Reading and writing of Http Requests.
Definition: HttpHeader.h:355
Definition: IHttpServer.h:19
Class with does not do any output: it can be used to determine the length of the output.
Definition: NullPrint.h:12
Print to a dynamic string.
Definition: StrPrint.h:13
const char * c_str()
Definition: StrPrint.h:39
Definition: Allocator.h:13
const char * CONTENT_TYPE
Definition: HttpHeader.h:16
const char * CON_KEEP_ALIVE
Definition: HttpHeader.h:20
const char * CONTENT_LENGTH
Definition: HttpHeader.h:17
const char * CON_CLOSE
Definition: HttpHeader.h:19
const char * TRANSFER_ENCODING
Definition: HttpHeader.h:21
const char * SUCCESS
Definition: HttpHeader.h:25
const char * CHUNKED
Definition: HttpHeader.h:22
const char * CONNECTION
Definition: HttpHeader.h:18