/*******************************************************************************
 * FILENAME: Headers.c
 *
 * PROJECT:
 *    Bitty HTTP
 *
 * FILE DESCRIPTION:
 *    
 *
 * COPYRIGHT:
 *    Copyright (c) 2019 Paul Hutchinson
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a copy
 *    of this software and associated documentation files (the "Software"), to deal
 *    in the Software without restriction, including without limitation the rights
 *    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *    copies of the Software, and to permit persons to whom the Software is
 *    furnished to do so, subject to the following conditions:
 *    
 *    The above copyright notice and this permission notice shall be included in all
 *    copies or substantial portions of the Software.
 *    
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *    SOFTWARE.
 *
 ******************************************************************************/

/*** HEADER FILES TO INCLUDE  ***/
#include "CodeExamples.h"
#include "Pages/Pages.h"
#include "Common/Headers.h"

/*** DEFINES                  ***/

/*** MACROS                   ***/

/*** TYPE DEFINITIONS         ***/

/*** FUNCTION PROTOTYPES      ***/

/*** VARIABLE DEFINITIONS     ***/

const char m_HeadersVarsHTML[]=
"<h1><span>1</span>Custom Headers</h1>\n"
"<p>This example will show how to add your own custom headers to\n"
"the http reply.</p>\n"
"\n"
"<p>"PRODUCTNAME" only provides a minimal set of headers.</p>\n"
"<p>The following headers are the ones that "PRODUCTNAME" will output:<br/>\n"
"<ul>\n"
"<li>Transfer-Encoding</li>\n"
"<li>Server</li>\n"
"<li>Content-Length</li>\n"
"<li>ETag</li>\n"
"<li>Location</li>\n"
"<li>Set-Cookie</li>\n"
"</ul>\n"
"</p>\n"
"<p>This example will also show changing the returned status code and\n"
"redirecting to another page.\n"
"</p>\n"
"<h2>AJAX</h2>\n"
"<p>This example uses some javascript ajax to display the headers.  What the\n"
"script will do is re-request the same page and then add the headers returned\n"
"to a div on the screen.</p>\n"
"\n"
"<h2>Files</h2>";

const char m_HeadersVarsHTML2[]=
"<h2>FileServer.c</h2>\n"
"<p>The file server is changed to provide 4 new pages.</p>\n"
"<h3>/Redirect1.html</h3>\n"
"<p>Redirect1.html is a simple page that just redirects to Redirect2.html.</p>\n"
"<h3>/Redirect2.html</h3>\n"
"<p>Redirect2.html is another simple page that just shows that it was\n"
"redirected from Redirect1.html by printing it's name</p>\n"
"<h3>/StatusCode.html</h3>\n"
"<p>StatusCode.html changes the status code returned and displays it.</p>\n"
"<h3>/GenericHeader.html</h3>\n"
"<p>GenericHeader.html adds a custom header to the reply.  The page will\n"
"display the headers that where sent with the page.</p>\n"
"\n"
"<div class='code'>"
"void File_Root(struct WebServer *Web);\n"
"void File_Redirect1(struct WebServer *Web);\n"
"void File_Redirect2(struct WebServer *Web);\n"
"void File_StatusCode(struct WebServer *Web);\n"
"void File_GenericHeader(struct WebServer *Web);\n"
"void File_Display(struct WebServer *Web);\n"
"void File_SomeStyle(struct WebServer *Web);\n"
"void File_Quit(struct WebServer *Web);\n"
"\n"
"struct FileInfo m_Files[]=\n"
"{\n"
"    /* Filename, Dynamic, Cookies, Gets, Posts, Callback */\n"
"    {\"/\",true,NULL,NULL,NULL,File_Root},\n"
"    {\"/Redirect1.html\",true,NULL,NULL,NULL,File_Redirect1},\n"
"    {\"/Redirect2.html\",true,NULL,NULL,NULL,File_Redirect2},\n"
"    {\"/StatusCode.html\",true,NULL,NULL,NULL,File_StatusCode},\n"
"    {\"/GenericHeader.html\",true,NULL,NULL,NULL,File_GenericHeader},\n"
"    {\"/SomeStyle.css\",false,NULL,NULL,NULL,File_SomeStyle},\n"
"    {\"/quit.html\",true,NULL,NULL,NULL,File_Quit},\n"
"};\n"
"</div>\n"
"\n"
"<p>The new pages Redirect1.html, Redirect2.html. StatusCode.html, and\n"
"GenericHeader.html have been added.</p>\n"
"\n"
"<div class='code'>"
"const char RootHTML[]=\n"
"\"&lt;!DOCTYPE html&gt;\"\n"
"\"&lt;html&gt;\"\n"
"\"&lt;head&gt;\"\n"
"    \"&lt;title&gt;Bitty HTTP - Root&lt;/title&gt;\"\n"
"    \"&lt;link rel='stylesheet' href='/SomeStyle.css'&gt;\"\n"
"\"&lt;/head&gt;\"\n"
"\"&lt;body&gt;\"\n"
"    \"&lt;div id='top'&gt;Bitty HTTP Example - Root&lt;/div&gt;\"\n"
"    \"&lt;div id='quitbttn'&gt;&lt;a href='/quit.html'&gt;QUIT&lt;/a&gt;&lt;/div&gt;\"\n"
"    \"&lt;div id='content'&gt;\"\n"
"        \"Headers example&lt;br/&gt;\"\n"
"        \"&lt;br/&gt;\"\n"
"        \"This is the main page.&lt;br/&gt;\"\n"
"        \"&lt;a href='/Redirect1.html'&gt;Redirect Test&lt;/a&gt;&lt;br/&gt;\"\n"
"        \"&lt;a href='/StatusCode.html'&gt;Status Code Test&lt;/a&gt;&lt;br/&gt;\"\n"
"        \"&lt;a href='/GenericHeader.html'&gt;Generic Header Test&lt;/a&gt;&lt;br/&gt;\"\n"
"    \"&lt;/div&gt;\"\n"
"\"&lt;div id='bottom'&gt;&lt;/div&gt;\"\n"
"\"&lt;/body&gt;\"\n"
"\"&lt;/html&gt;\";\n"
"</div>\n"
"\n"
"<p>The root page has been changed to a number of links to the new pages.</p>\n"
"\n"
"<div class='code'>"
"const char Redirect1HTML[]=\n"
"\"&lt;!DOCTYPE html&gt;\"\n"
"\"&lt;html&gt;\"\n"
"\"&lt;head&gt;\"\n"
"    \"&lt;title&gt;Bitty HTTP - Root&lt;/title&gt;\"\n"
"    \"&lt;link rel='stylesheet' href='/SomeStyle.css'&gt;\"\n"
"\"&lt;/head&gt;\"\n"
"\"&lt;body&gt;\"\n"
"    \"&lt;div id='top'&gt;Bitty HTTP Example - Root&lt;/div&gt;\"\n"
"    \"&lt;div id='quitbttn'&gt;&lt;a href='/quit.html'&gt;QUIT&lt;/a&gt;&lt;/div&gt;\"\n"
"    \"&lt;div id='content'&gt;\"\n"
"        \"Headers example.&lt;br/&gt;\"\n"
"        \"&lt;br/&gt;\"\n"
"        \"&lt;h1&gt;Redirect 1&lt;/h1&gt;\"\n"
"    \"&lt;/div&gt;\"\n"
"\"&lt;div id='bottom'&gt;&lt;/div&gt;\"\n"
"\"&lt;/body&gt;\"\n"
"\"&lt;/html&gt;\";\n"
"\n"
"void File_Redirect1(struct WebServer *Web)\n"
"{\n"
"    WS_Location(Web,\"/Redirect2.html\");\n"
"    WS_WriteWhole(Web,Redirect1HTML,sizeof(Redirect1HTML)-1);\n"
"}\n"
"</div>\n"
"\n"
"<p>This is the first page of the redirect example.  In the code for this\n"
"page we first call <span class='coderef'>WS_Location()</span> with\n"
"the URL we want to redirect to.  The\n"
"<span class='coderef'>WS_Location()</span> function adds a\n"
"<span class='coderef'>Location:</span> header to the output.  You must\n"
"add any headers before outputing any of the body of the page, so in this\n"
"case we call <span class='coderef'>WS_Location()</span> before using\n"
"<span class='coderef'>WS_WriteWhole()</span> to output our page.</p>\n"
"<p>The <span class='coderef'>WS_Location()</span> function will also change\n"
"the status code to 301 Moved Permanently</p>"
"<p>When we load this page the <span class='coderef'>Location:</span> header\n"
"will redirect us to the /Redirect2.html page</p>"
"<p>If you want to redirect using a different status code than 301 then you\n"
"need to output a custom header using <span class='coderef'>WS_Header()</span>\n"
"and <span class='coderef'>WS_SetHTTPStatusCode()</span> as follows:\n"
"<div class='code' style='margin-left:50px;width:94%;background-color:#FAEBD7'>"
"   WS_Header(Web,\"Location: /Redirect2.html\");\n"
"   WS_SetHTTPStatusCode(Web,e_ReplyStatus_TmpRedirect);\n"
"</div>"
"\n"
"<p>Continuing with FileServer.c:</p>\n"
"<div class='code'>"
"const char Redirect2HTML[]=\n"
"\"&lt;!DOCTYPE html&gt;\"\n"
"\"&lt;html&gt;\"\n"
"\"&lt;head&gt;\"\n"
"    \"&lt;title&gt;Bitty HTTP - Root&lt;/title&gt;\"\n"
"    \"&lt;link rel='stylesheet' href='/SomeStyle.css'&gt;\"\n"
"\"&lt;/head&gt;\"\n"
"\"&lt;body&gt;\"\n"
"    \"&lt;div id='top'&gt;Bitty HTTP Example - Root&lt;/div&gt;\"\n"
"    \"&lt;div id='quitbttn'&gt;&lt;a href='/quit.html'&gt;QUIT&lt;/a&gt;&lt;/div&gt;\"\n"
"    \"&lt;div id='content'&gt;\"\n"
"        \"Headers example.&lt;br/&gt;\"\n"
"        \"&lt;br/&gt;\"\n"
"        \"&lt;h1&gt;Redirect 2&lt;/h1&gt;\"\n"
"    \"&lt;/div&gt;\"\n"
"\"&lt;div id='bottom'&gt;&lt;/div&gt;\"\n"
"\"&lt;/body&gt;\"\n"
"\"&lt;/html&gt;\";\n"
"\n"
"void File_Redirect2(struct WebServer *Web)\n"
"{\n"
"    WS_WriteWhole(Web,Redirect2HTML,sizeof(Redirect2HTML)-1);\n"
"}\n"
"</div>\n"
"\n"
"<p>The next page is a simple page to display that we have been redirected.</p>"
"<div class='code'>"
"const char StatusCodeHTML[]=\n"
"\"&lt;!DOCTYPE html&gt;\"\n"
"\"&lt;html&gt;\"\n"
"\"&lt;head&gt;\"\n"
"    \"&lt;title&gt;Bitty HTTP - Status Code&lt;/title&gt;\"\n"
"    \"&lt;link rel='stylesheet' href='/SomeStyle.css'&gt;\"\n"
"\"&lt;/head&gt;\"\n"
"\"&lt;body&gt;\"\n"
"    \"&lt;div id='top'&gt;Bitty HTTP Example - Status Code&lt;/div&gt;\"\n"
"    \"&lt;div id='quitbttn'&gt;&lt;a href='/quit.html'&gt;QUIT&lt;/a&gt;&lt;/div&gt;\"\n"
"    \"&lt;div id='content'&gt;\"\n"
"        \"&lt;h1&gt;Status Code&lt;/h1&gt;\"\n"
"        \"Re-requesting page to get the headers (by ajax):&lt;br/&gt;\"\n"
"        \"&lt;div id='Headers' style='white-space: pre;border:1px solid black;margin:5px;padding:5px;font-family: monospace'&gt;&lt;/div&gt;\"\n"
"    \"&lt;/div&gt;\"\n"
"\"&lt;div id='bottom'&gt;&lt;/div&gt;\"\n"
"\"&lt;script&gt;\\n\"\n"
"\"   var req = new XMLHttpRequest();\\n\"\n"
"\"   req.open('GET', document.location, false);\\n\"\n"
"\"   req.send(null);\\n\"\n"
"\"   var headers = req.getAllResponseHeaders();\\n\"\n"
"\"   var outdiv=document.getElementById('Headers');\\n\"\n"
"\"   outdiv.innerHTML='Status:'+req.status+' '+req.statusText+'\\\\n\\\\n'+headers;\\n\"\n"
"\"&lt;/script&gt;\\n\"\n"
"\"&lt;/body&gt;\"\n"
"\"&lt;/html&gt;\";\n"
"\n"
"void File_StatusCode(struct WebServer *Web)\n"
"{\n"
"    WS_SetHTTPStatusCode(Web,e_ReplyStatus_Forbidden);\n"
"    WS_WriteWhole(Web,StatusCodeHTML,sizeof(StatusCodeHTML)-1);\n"
"}\n"
"</div>\n"
"<p>This is the set status code example.  It uses the\n"
"<span class='coderef'>WS_SetHTTPStatusCode()</span> function to set the\n"
"status code to one of the defined return codes.  This needs to be called\n"
"before any of the body is sent.</p>"
"<p>The system supports the following status codes:\n"
"<table>\n"
"<tr><td>e_ReplyStatus_Ok</td><td>200</td></tr>\n"
"<tr><td>e_ReplyStatus_MovedPerm</td><td>301</td></tr>\n"
"<tr><td>e_ReplyStatus_NotModified</td><td>304</td></tr>\n"
"<tr><td>e_ReplyStatus_TmpRedirect</td><td>307</td></tr>\n"
"<tr><td>e_ReplyStatus_PermRedirect</td><td>308</td></tr>\n"
"<tr><td>e_ReplyStatus_BadRequest</td><td>400</td></tr>\n"
"<tr><td>e_ReplyStatus_Forbidden</td><td>403</td></tr>\n"
"<tr><td>e_ReplyStatus_NotFound</td><td>404</td></tr>\n"
"<tr><td>e_ReplyStatus_MethodNotAllowed</td><td>405</td></tr>\n"
"<tr><td>e_ReplyStatus_URITooLong</td><td>414</td></tr>\n"
"<tr><td>e_ReplyStatus_RequestHeaderFieldsTooLarge</td><td>431</td></tr>\n"
"<tr><td>e_ReplyStatus_InternalServerError</td><td>500</td></tr>\n"
"<tr><td>e_ReplyStatus_NotImplemented</td><td>501</td></tr>\n"
"<tr><td>e_ReplyStatus_HTTPVersionNotSupported</td><td>505</td></tr>\n"
"<tr><td>e_ReplyStatus_InsufficientStorage</td><td>507</td></tr>\n"
"</table>"
"</p>"
"<p>It should be noted that the page works by including some javascript that\n"
"makes a second request to the server for the same page (using AJAX).\n"
"It does this because there is no way to the status code or headers from\n"
"javascript without using AJAX</p>"
"\n"

"<div class='code'>"
"const char GenericHeaderHTML[]=\n"
"\"&lt;!DOCTYPE html&gt;\"\n"
"\"&lt;html&gt;\"\n"
"\"&lt;head&gt;\"\n"
"    \"&lt;title&gt;Bitty HTTP - Generic Header&lt;/title&gt;\"\n"
"    \"&lt;link rel='stylesheet' href='/SomeStyle.css'&gt;\"\n"
"\"&lt;/head&gt;\"\n"
"\"&lt;body&gt;\"\n"
"    \"&lt;div id='top'&gt;Bitty HTTP Example - Generic Header&lt;/div&gt;\"\n"
"    \"&lt;div id='quitbttn'&gt;&lt;a href='/quit.html'&gt;QUIT&lt;/a&gt;&lt;/div&gt;\"\n"
"    \"&lt;div id='content'&gt;\"\n"
"        \"&lt;h1&gt;Generic Header&lt;/h1&gt;\"\n"
"        \"Re-requesting page to get the headers (by ajax):&lt;br/&gt;\"\n"
"        \"&lt;div id='Headers' style='white-space: pre;border:1px solid black;margin:5px;padding:5px;font-family: monospace'&gt;&lt;/div&gt;\"\n"
"    \"&lt;/div&gt;\"\n"
"\"&lt;div id='bottom'&gt;&lt;/div&gt;\"\n"
"\"&lt;script&gt;\\n\"\n"
"\"   var req = new XMLHttpRequest();\\n\"\n"
"\"   req.open('GET', document.location, false);\\n\"\n"
"\"   req.send(null);\\n\"\n"
"\"   var headers = req.getAllResponseHeaders();\\n\"\n"
"\"   var outdiv=document.getElementById('Headers');\\n\"\n"
"\"   outdiv.innerHTML='Status:'+req.status+' '+req.statusText+'\\\\n\\\\n'+headers;\\n\"\n"
"\"&lt;/script&gt;\\n\"\n"
"\"&lt;/body&gt;\"\n"
"\"&lt;/html&gt;\";\n"
"\n"
"void File_GenericHeader(struct WebServer *Web)\n"
"{\n"
"    WS_Header(Web,\"X-Powered-By: Imagination\");\n"
"    WS_WriteWhole(Web,GenericHeaderHTML,sizeof(GenericHeaderHTML)-1);\n"
"}\n"
"</div>\n"
"<p>This example shows adding a generic header string.  The\n"
"<span class='coderef'>WS_Header()</span> function takes the string to output\n"
"this string it output in the HTTP headers with a newline appended to the\n"
"end of the string.  This must be called before any body is output.</p>"
"";

void File_Doc_HeadersVars(struct WebServer *Web)
{
    WS_WriteChunk(Web,m_HeadersVarsHTML,sizeof(m_HeadersVarsHTML)-1);
    OutputListOfExampleFiles(Web,e_ExampleCode_ManualHeaders);
    WS_WriteChunk(Web,m_HeadersVarsHTML2,sizeof(m_HeadersVarsHTML2)-1);
}
