@@ -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 );
0 commit comments