Line data Source code
1 : /* 2 : * lwan - web server 3 : * Copyright (c) 2014 L. A. F. Pereira <l@tia.mat.br> 4 : * 5 : * This program is free software; you can redistribute it and/or 6 : * modify it under the terms of the GNU General Public License 7 : * as published by the Free Software Foundation; either version 2 8 : * of the License, or any later version. 9 : * 10 : * This program is distributed in the hope that it will be useful, 11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : * GNU General Public License for more details. 14 : * 15 : * You should have received a copy of the GNU General Public License 16 : * along with this program; if not, write to the Free Software 17 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 18 : * USA. 19 : */ 20 : 21 : #include <stdlib.h> 22 : #include <string.h> 23 : 24 : #include "lwan-private.h" 25 : #include "lwan-mod-redirect.h" 26 : 27 : struct redirect_priv { 28 : char *to; 29 : enum lwan_http_status code; 30 : }; 31 : 32 : static enum lwan_http_status 33 2 : redirect_handle_request(struct lwan_request *request, 34 : struct lwan_response *response, 35 : void *instance) 36 : { 37 2 : struct redirect_priv *priv = instance; 38 2 : struct lwan_key_value headers[] = {{"Location", priv->to}, {}}; 39 : 40 2 : response->headers = 41 2 : coro_memdup(request->conn->coro, headers, sizeof(headers)); 42 : 43 2 : return response->headers ? priv->code : HTTP_INTERNAL_ERROR; 44 : } 45 : 46 174 : static void *redirect_create(const char *prefix __attribute__((unused)), 47 : void *instance) 48 : { 49 174 : struct lwan_redirect_settings *settings = instance; 50 174 : struct redirect_priv *priv = malloc(sizeof(*priv)); 51 : 52 174 : if (!priv) 53 0 : return NULL; 54 : 55 174 : priv->to = strdup(settings->to); 56 174 : if (!priv->to) { 57 0 : free(priv); 58 0 : return NULL; 59 : } 60 : 61 174 : priv->code = settings->code; 62 : 63 174 : return priv; 64 : } 65 : 66 0 : static void redirect_destroy(void *data) 67 : { 68 0 : struct redirect_priv *priv = data; 69 : 70 0 : if (priv) { 71 0 : free(priv->to); 72 0 : free(priv); 73 : } 74 0 : } 75 : 76 174 : static enum lwan_http_status parse_http_code(const char *code, 77 : enum lwan_http_status fallback) 78 : { 79 : const char *known; 80 : int as_int; 81 : 82 174 : if (!code) 83 87 : return fallback; 84 : 85 87 : as_int = parse_int(code, 999); 86 87 : if (as_int == 999) 87 0 : return fallback; 88 : 89 87 : known = lwan_http_status_as_string_with_code((enum lwan_http_status)as_int); 90 87 : if (!strncmp(known, "999", 3)) 91 0 : return fallback; 92 : 93 87 : return (enum lwan_http_status)as_int; 94 : } 95 : 96 174 : static void *redirect_create_from_hash(const char *prefix, 97 : const struct hash *hash) 98 : { 99 348 : struct lwan_redirect_settings settings = { 100 174 : .to = hash_find(hash, "to"), 101 : .code = 102 174 : parse_http_code(hash_find(hash, "code"), HTTP_MOVED_PERMANENTLY), 103 : }; 104 : 105 174 : return redirect_create(prefix, &settings); 106 : } 107 : 108 : static const struct lwan_module module = { 109 : .create = redirect_create, 110 : .create_from_hash = redirect_create_from_hash, 111 : .destroy = redirect_destroy, 112 : .handle_request = redirect_handle_request, 113 : }; 114 : 115 : LWAN_REGISTER_MODULE(redirect, &module);