Skip to content

Commit b9bb9bf

Browse files
committed
OPTIONS and TRACE are now supported. Slight update to HTTPMessage addHeader to support integers as a value. Minor bug fixes
1 parent f6698d9 commit b9bb9bf

File tree

5 files changed

+84
-20
lines changed

5 files changed

+84
-20
lines changed

HTTPMessage.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,19 @@ void HTTPMessage::addHeader(string key, string value) {
282282
headers->insert(pair<string, string>(key, value));
283283
}
284284

285+
/**
286+
* Add header key-value pair to the map (Integer value)
287+
* Integer value is converted to a string
288+
*
289+
* @param key String representation of the Header Key
290+
* @param value Integer representation of the Header value
291+
*/
292+
void HTTPMessage::addHeader(string key, int value) {
293+
stringstream sz;
294+
sz << value;
295+
headers->insert(pair<string, string>(key, sz.str()));
296+
}
297+
285298
/**
286299
* Get Header Value
287300
* Given a header name (key), return the value associated with it in the headers map

HTTPMessage.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ enum Method {
4040
TRACE = 5,
4141
OPTIONS = 6,
4242
CONNECT = 7,
43-
PATH = 8
43+
PATCH = 8
4444
};
4545

4646
const static char* const requestMethodStr[NUM_METHODS] = {
@@ -52,7 +52,7 @@ const static char* const requestMethodStr[NUM_METHODS] = {
5252
"TRACE", // 5
5353
"OPTIONS", // 6
5454
"CONNECT", // 7
55-
"PATH" // 8
55+
"PATCH" // 8
5656
};
5757

5858

@@ -117,6 +117,7 @@ class HTTPMessage : public ByteBuffer {
117117
// Header Map manipulation
118118
void addHeader(string line);
119119
void addHeader(string key, string value);
120+
void addHeader(string key, int value);
120121
string getHeaderValue(string key);
121122
string getHeaderStr(int index);
122123
int getNumHeaders();

HTTPResponse.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void HTTPResponse::determineReasonStr() {
8282
reason = "Internal Server Error";
8383
break;
8484
case Status(NOT_IMPLEMENTED):
85-
reason = "Method not implemented";
85+
reason = "Not Implemented";
8686
break;
8787
default:
8888
break;

HTTPServer.cpp

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ void HTTPServer::handleRequest(Client *cl, HTTPRequest* req) {
303303
if(!req->parse()) {
304304
cout << "[" << cl->getClientIP() << "] There was an error processing the request of type: " << req->methodIntToStr(req->getMethod()) << endl;
305305
cout << req->getParseError() << endl;
306-
sendStatusResponse(cl, Status(SERVER_ERROR));
306+
sendStatusResponse(cl, Status(SERVER_ERROR), req->getParseError());
307307
return;
308308
}
309309

@@ -315,6 +315,12 @@ void HTTPServer::handleRequest(Client *cl, HTTPRequest* req) {
315315
case Method(GET):
316316
handleGet(cl, req);
317317
break;
318+
case Method(OPTIONS):
319+
handleOptions(cl, req);
320+
break;
321+
case Method(TRACE):
322+
handleTrace(cl, req);
323+
break;
318324
default:
319325
cout << cl->getClientIP() << ": Could not handle or determine request of type " << req->methodIntToStr(req->getMethod()) << endl;
320326
sendStatusResponse(cl, Status(NOT_IMPLEMENTED));
@@ -336,10 +342,8 @@ void HTTPServer::handleGet(Client *cl, HTTPRequest *req) {
336342
if(r != NULL) { // Exists
337343
HTTPResponse* res = new HTTPResponse();
338344
res->setStatus(Status(OK));
339-
std::stringstream sz;
340-
sz << r->getSize();
341345
res->addHeader("Content-Type", "text/html");
342-
res->addHeader("Content-Length", sz.str());
346+
res->addHeader("Content-Length", r->getSize());
343347
res->setData(r->getData(), r->getSize());
344348
sendResponse(cl, res, true);
345349
delete res;
@@ -350,7 +354,8 @@ void HTTPServer::handleGet(Client *cl, HTTPRequest *req) {
350354

351355
/**
352356
* Handle Head
353-
* Process a HEAD request to provide the client with an appropriate response
357+
* Process a HEAD request
358+
* HEAD: Return the corresponding headers for a resource, but not the acutal resource itself (in the body)
354359
*
355360
* @param cl Client requesting the resource
356361
* @param req State of the request
@@ -363,33 +368,76 @@ void HTTPServer::handleHead(Client *cl, HTTPRequest *req) {
363368
// Only include headers associated with the file. NEVER contains a body
364369
HTTPResponse* res = new HTTPResponse();
365370
res->setStatus(Status(OK));
366-
std::stringstream sz;
367-
sz << r->getSize();
368371
res->addHeader("Content-Type", "text/html");
369-
res->addHeader("Content-Length", sz.str());
372+
res->addHeader("Content-Length", r->getSize());
370373
sendResponse(cl, res, true);
371374
delete res;
372375
} else { // Not found
373376
sendStatusResponse(cl, Status(NOT_FOUND));
374377
}
375378
}
376379

380+
/**
381+
* Handle Options
382+
* Process a OPTIONS request
383+
* OPTIONS: Return allowed capabilties for the server (*) or a particular resource
384+
*
385+
* @param cl Client requesting the resource
386+
* @param req State of the request
387+
*/
388+
void HTTPServer::handleOptions(Client* cl, HTTPRequest* req) {
389+
// For now, we'll always return the capabilities of the server instead of figuring it out for each resource
390+
std::string allow = "HEAD GET OPTIONS TRACE";
391+
HTTPResponse* res = new HTTPResponse();
392+
res->setStatus(Status(OK));
393+
res->addHeader("Allow", allow.c_str());
394+
res->addHeader("Content-Length", "0"); // Required
395+
sendResponse(cl, res, true);
396+
delete res;
397+
}
398+
399+
/**
400+
* Handle Trace
401+
* Process a TRACE request
402+
* TRACE: send back the request as received by the server verbatim
403+
*
404+
* @param cl Client requesting the resource
405+
* @param req State of the request
406+
*/
407+
void HTTPServer::handleTrace(Client* cl, HTTPRequest *req) {
408+
// Get a byte array representation of the request
409+
unsigned int len = req->size();
410+
byte* buf = new byte[len];
411+
req->setReadPos(0); // Set the read position at the beginning since the request has already been read to the end
412+
req->getBytes(buf, len);
413+
414+
// Send a response with the entire request as the body
415+
HTTPResponse* res = new HTTPResponse();
416+
res->setStatus(Status(OK));
417+
res->addHeader("Content-Type", "text/plain");
418+
res->addHeader("Content-Length", len);
419+
res->setData(buf, len);
420+
sendResponse(cl, res, true);
421+
422+
delete res;
423+
delete buf;
424+
}
425+
377426
/**
378427
* Send Status Response
379428
* Send a predefined HTTP status code response to the client consisting of
380429
* only the status code and required headers, then disconnect the client
381430
*
382431
* @param cl Client to send the status code to
383432
* @param status Status code corresponding to the enum in HTTPMessage.h
433+
* @param msg An additional message to append to the body text
384434
*/
385-
void HTTPServer::sendStatusResponse(Client* cl, int status) {
435+
void HTTPServer::sendStatusResponse(Client* cl, int status, std::string msg) {
386436
HTTPResponse* res = new HTTPResponse();
387437
res->setStatus(Status(status));
388-
std::string body = res->getReason();
389-
std::stringstream sz;
390-
sz << body.size();
391-
res->addHeader("Content-Type", "text/html");
392-
res->addHeader("Content-Length", sz.str());
438+
std::string body = res->getReason() + " " + msg;
439+
res->addHeader("Content-Type", "text/plain");
440+
res->addHeader("Content-Length", body.size());
393441
res->setData((byte*)body.c_str(), body.size());
394442

395443
sendResponse(cl, res, true);

HTTPServer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ class HTTPServer {
6161
void closeSockets();
6262
void disconnectClient(Client* cl, bool mapErase = true);
6363
void handleClient(Client* cl);
64-
void sendStatusResponse(Client* cl, int status);
64+
void sendStatusResponse(Client* cl, int status, std::string msg = "");
6565
void sendResponse(Client* cl, HTTPResponse* res, bool disconnect = false);
6666

6767
// Request handlers
6868
void handleRequest(Client* cl, HTTPRequest* req);
69-
void handleHead(Client* cl, HTTPRequest *req);
70-
void handleGet(Client* cl, HTTPRequest *req);
69+
void handleGet(Client* cl, HTTPRequest* req);
70+
void handleHead(Client* cl, HTTPRequest* req);
71+
void handleOptions(Client* cl, HTTPRequest* req);
72+
void handleTrace(Client* cl, HTTPRequest* req);
7173

7274
public:
7375
HTTPServer();

0 commit comments

Comments
 (0)