UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "error.h" 30 31 #include <ucx/string.h> 32 #include "../util/pblock.h" 33 #include "../util/strbuf.h" 34 35 // macro for creating an error string (ucx sstr_t) 36 #define ERRMSG(s) { s, sizeof(s)-1 } 37 38 static sstr_t error_400 = ERRMSG("<html><body>bad request</body></html>"); 39 static sstr_t error_403 = ERRMSG("<html><body>forbidden</body></html>"); 40 static sstr_t error_404 = ERRMSG("<html><body>not found</body></html>"); 41 static sstr_t error_500 = ERRMSG("<html><body>server error</body></html>"); 42 static sstr_t error_503 = ERRMSG("<html><body>service unavailable</body></html>"); 43 44 static sstr_t error_std = ERRMSG("<html><body>error</body></html>"); 45 46 int nsapi_error_request(Session *sn, Request *rq) { 47 short status = rq->status_num; 48 sstr_t msg; 49 if(status < 400) { 50 msg.ptr = NULL; 51 msg.length = 0; 52 } else { 53 switch(status) { 54 default: msg = error_std; 55 case 403: { 56 msg = error_403; 57 break; 58 } 59 case 404: { 60 msg = error_404; 61 break; 62 } 63 case 500: { 64 msg = error_500; 65 break; 66 } 67 } 68 } 69 70 pblock_removekey(pb_key_content_type, rq->srvhdrs); 71 pblock_removekey(pb_key_content_length, rq->srvhdrs); 72 73 pblock_kninsert(pb_key_content_length, msg.length, rq->srvhdrs); 74 pblock_nvinsert("content-type", "text/html", rq->srvhdrs); 75 http_start_response(sn, rq); 76 77 if(msg.length > 0) { 78 net_write(sn->csd, msg.ptr, msg.length); 79 } 80 81 return REQ_PROCEED; 82 } 83 84 void fatal_error(HTTPRequest *req, int status) { 85 sstr_t msg = error_500; 86 char *statusmsg = "Internal Server Error"; 87 switch(status) { 88 case 400: { 89 msg = error_400; 90 statusmsg = "Bad request"; 91 break; 92 } 93 case 500: { 94 msg = error_500; 95 statusmsg = "Internal Server Error"; 96 break; 97 } 98 case 503: { 99 msg = error_503; 100 statusmsg = "Service Unavailable"; 101 break; 102 } 103 } 104 105 char buf[512]; 106 int len = snprintf(buf, 512, "HTTP/1.1 %d %s\r\nServer: webserver\r\nContent-type: text/html\r\nContent-length: %zd\r\n\r\n", status, statusmsg, msg.length); 107 108 // set socket blocking 109 int flags; 110 if (-1 == (flags = fcntl(req->connection->fd, F_GETFL, 0))) { 111 flags = 0; 112 } 113 if (fcntl(req->connection->fd, F_SETFL, flags & ~O_NONBLOCK) != 0) { 114 // error 115 } 116 117 req->connection->write(req->connection, buf, len); 118 req->connection->write(req->connection, msg.ptr, msg.length); 119 } 120