@@ -72,70 +72,82 @@ class StaticRequestHandler : public RequestHandler<ServerType> {
72
72
, _path(path)
73
73
, _cache_header(cache_header)
74
74
{
75
- if (fs.exists (path)) {
76
- File file = fs.open (path, " r" );
77
- _isFile = file && file.isFile ();
78
- file.close ();
79
- }
80
- else {
81
- _isFile = false ;
82
- }
83
-
84
75
DEBUGV (" StaticRequestHandler: path=%s uri=%s isFile=%d, cache_header=%s\r\n " , path, uri, _isFile, cache_header == __null ? " " : cache_header);
85
- _baseUriLength = _uri.length ();
86
76
}
87
77
88
- bool canHandle (HTTPMethod requestMethod, const String& requestUri) override {
89
- if (( requestMethod != HTTP_GET) && (requestMethod != HTTP_HEAD))
90
- return false ;
78
+ bool validMethod (HTTPMethod requestMethod) {
79
+ return ( requestMethod == HTTP_GET) || (requestMethod == HTTP_HEAD);
80
+ }
91
81
92
- if ((_isFile && requestUri != _uri) || !requestUri.startsWith (_uri))
93
- return false ;
82
+ /* Deprecated version. Please use mime::getContentType instead */
83
+ static String getContentType (const String& path) __attribute__((deprecated)) {
84
+ return mime::getContentType (path);
85
+ }
94
86
95
- return true ;
87
+ protected:
88
+ FS _fs;
89
+ String _uri;
90
+ String _path;
91
+ String _cache_header;
92
+ };
93
+
94
+
95
+ template <typename ServerType>
96
+ class StaticDirectoryRequestHandler : public StaticRequestHandler <ServerType> {
97
+
98
+ using SRH = StaticRequestHandler<ServerType>;
99
+ using WebServerType = ESP8266WebServerTemplate<ServerType>;
100
+
101
+ public:
102
+ StaticDirectoryRequestHandler (FS& fs, const char * path, const char * uri, const char * cache_header)
103
+ :
104
+ SRH (fs, path, uri, cache_header),
105
+ _baseUriLength{SRH::_uri.length ()}
106
+ {}
107
+
108
+ bool canHandle (HTTPMethod requestMethod, const String& requestUri) override {
109
+ return SRH::validMethod (requestMethod) && requestUri.startsWith (SRH::_uri);
96
110
}
97
111
98
112
bool handle (WebServerType& server, HTTPMethod requestMethod, const String& requestUri) override {
99
113
100
114
if (!canHandle (requestMethod, requestUri))
101
115
return false ;
102
116
103
- DEBUGV (" StaticRequestHandler ::handle: request=%s _uri=%s\r\n " , requestUri.c_str (), _uri.c_str ());
117
+ DEBUGV (" DirectoryRequestHandler ::handle: request=%s _uri=%s\r\n " , requestUri.c_str (), SRH:: _uri.c_str ());
104
118
105
119
String path;
106
- path.reserve (_path.length () + requestUri.length () + 32 );
107
- path = _path;
108
-
109
- if (!_isFile) {
120
+ path.reserve (SRH::_path.length () + requestUri.length () + 32 );
121
+ path = SRH::_path;
110
122
111
- // Append whatever follows this URI in request to get the file path.
112
- path += requestUri.substring (_baseUriLength);
123
+ // Append whatever follows this URI in request to get the file path.
124
+ path += requestUri.substring (_baseUriLength);
113
125
114
- // Base URI doesn't point to a file.
115
- // If a directory is requested, look for index file.
116
- if (path.endsWith (" /" ))
117
- path += F (" index.htm" );
126
+ // Base URI doesn't point to a file.
127
+ // If a directory is requested, look for index file.
128
+ if (path.endsWith (" /" ))
129
+ path += F (" index.htm" );
118
130
119
- // If neither <blah> nor <blah>.gz exist, and <blah> is a file.htm, try it with file.html instead
120
- // For the normal case this will give a search order of index.htm, index.htm.gz, index.html, index.html.gz
121
- if (!_fs.exists (path) && !_fs.exists (path + " .gz" ) && path.endsWith (" .htm" )) {
122
- path += ' l' ;
123
- }
131
+ // If neither <blah> nor <blah>.gz exist, and <blah> is a file.htm, try it with file.html instead
132
+ // For the normal case this will give a search order of index.htm, index.htm.gz, index.html, index.html.gz
133
+ if (!SRH::_fs.exists (path) && !SRH::_fs.exists (path + " .gz" ) && path.endsWith (" .htm" )) {
134
+ path += ' l' ;
124
135
}
125
- DEBUGV (" StaticRequestHandler::handle: path=%s, isFile=%d\r\n " , path.c_str (), _isFile);
136
+
137
+ DEBUGV (" DirectoryRequestHandler::handle: path=%s\r\n " , path.c_str ());
126
138
127
139
String contentType = mime::getContentType (path);
128
140
129
141
using namespace mime ;
130
142
// look for gz file, only if the original specified path is not a gz. So part only works to send gzip via content encoding when a non compressed is asked for
131
143
// if you point the the path to gzip you will serve the gzip as content type "application/x-gzip", not text or javascript etc...
132
- if (!path.endsWith (FPSTR (mimeTable[gz].endsWith )) && !_fs.exists (path)) {
144
+ if (!path.endsWith (FPSTR (mimeTable[gz].endsWith )) && !SRH:: _fs.exists (path)) {
133
145
String pathWithGz = path + FPSTR (mimeTable[gz].endsWith );
134
- if (_fs.exists (pathWithGz))
146
+ if (SRH:: _fs.exists (pathWithGz))
135
147
path += FPSTR (mimeTable[gz].endsWith );
136
148
}
137
149
138
- File f = _fs.open (path, " r" );
150
+ File f = SRH:: _fs.open (path, " r" );
139
151
if (!f)
140
152
return false ;
141
153
@@ -144,70 +156,75 @@ class StaticRequestHandler : public RequestHandler<ServerType> {
144
156
return false ;
145
157
}
146
158
147
- if (_cache_header.length () != 0 )
148
- server.sendHeader (" Cache-Control" , _cache_header);
159
+ if (SRH:: _cache_header.length () != 0 )
160
+ server.sendHeader (" Cache-Control" , SRH:: _cache_header);
149
161
150
162
server.streamFile (f, contentType, requestMethod);
151
163
return true ;
152
164
}
153
165
154
- /* Deprecated version. Please use mime::getContentType instead */
155
- static String getContentType (const String& path) __attribute__((deprecated)) {
156
- return mime::getContentType (path);
157
- }
158
-
159
166
protected:
160
- FS _fs;
161
- String _uri;
162
- String _path;
163
- String _cache_header;
164
- bool _isFile;
165
167
size_t _baseUriLength;
166
168
};
167
169
168
170
template <typename ServerType>
169
- class StaticRequestETagHandler
171
+ class StaticFileRequestHandler
170
172
:
171
173
public StaticRequestHandler<ServerType> {
172
174
173
175
using SRH = StaticRequestHandler<ServerType>;
176
+ using WebServerType = ESP8266WebServerTemplate<ServerType>;
174
177
175
- using SRH::SRH;
178
+ public:
179
+ StaticFileRequestHandler (FS& fs, const char * path, const char * uri, const char * cache_header)
180
+ :
181
+ StaticRequestHandler<ServerType>{fs, path, uri, cache_header}
182
+ {
183
+ File f = SRH::_fs.open (path, " r" );
184
+ MD5Builder calcMD5;
185
+ calcMD5.begin ();
186
+ calcMD5.addStream (f, f.size ());
187
+ calcMD5.calculate ();
188
+ calcMD5.getBytes (_ETag_md5);
189
+ f.close ();
190
+ }
176
191
177
- using WebServerType = ESP8266WebServerTemplate<ServerType>;
192
+ bool canHandle (HTTPMethod requestMethod, const String& requestUri) override {
193
+ return SRH::validMethod (requestMethod) && requestUri == SRH::_uri;
194
+ }
178
195
179
- public:
180
196
bool handle (WebServerType& server, HTTPMethod requestMethod, const String & requestUri) override {
181
- if (!SRH:: canHandle (requestMethod, requestUri)){
197
+ if (!canHandle (requestMethod, requestUri))
182
198
return false ;
183
- }
184
199
185
- if (server.header (" If-None-Match" ) == SRH::_cache_header){
186
- // Serial.println("Sending 304!!!");
200
+ const String etag = " \" " + base64::encode (_ETag_md5, 16 , false ) + " \" " ;
201
+
202
+ if (server.header (" If-None-Match" ) == etag){
187
203
server.send (304 );
188
204
return true ;
189
205
}
190
206
191
-
192
207
File f = SRH::_fs.open (SRH::_path, " r" );
193
208
194
- if (!f){
209
+ if (!f)
195
210
return false ;
196
- }
197
211
198
212
if (!f.isFile ()) {
199
213
f.close ();
200
214
return false ;
201
215
}
202
216
203
- if (SRH::_cache_header.length () != 0 ){
204
- server.sendHeader (" ETag" , SRH::_cache_header);
205
- }
217
+ if (SRH::_cache_header.length () != 0 )
218
+ server.sendHeader (" Cache-Control" , SRH::_cache_header);
206
219
207
- server.streamFile (f, SRH::getContentType (SRH::_path), requestMethod);
220
+ server.sendHeader (" ETag" , etag);
221
+
222
+ server.streamFile (f, mime::getContentType (SRH::_path), requestMethod);
208
223
return true ;
209
224
}
210
-
225
+
226
+ protected:
227
+ uint8_t _ETag_md5[16 ];
211
228
};
212
229
213
230
} // namespace
0 commit comments