1/* 2 Tests for 3xx redirect interface (ne_redirect.h) 3 Copyright (C) 2002-2003, Joe Orton <joe@manyfish.co.uk> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) 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., 675 Mass Ave, Cambridge, MA 02139, USA. 18 19*/ 20 21#include "config.h" 22 23#include <sys/types.h> 24 25#ifdef HAVE_STDLIB_H 26#include <stdlib.h> 27#endif 28#ifdef HAVE_UNISTD_H 29#include <unistd.h> 30#endif 31 32#include "ne_redirect.h" 33 34#include "tests.h" 35#include "child.h" 36#include "utils.h" 37 38struct redir_args { 39 int code; 40 const char *dest; 41 const char *path; 42}; 43 44static int serve_redir(ne_socket *sock, void *ud) 45{ 46 struct redir_args *args = ud; 47 char buf[BUFSIZ]; 48 49 CALL(discard_request(sock)); 50 51 ne_snprintf(buf, BUFSIZ, 52 "HTTP/1.0 %d Get Ye Away\r\n" 53 "Content-Length: 0\r\n" 54 "Location: %s\r\n\n", 55 args->code, args->dest); 56 57 SEND_STRING(sock, buf); 58 59 return OK; 60} 61 62/* Run a request to 'path' and retrieve the redirect destination to 63 * *redir. */ 64static int process_redir(ne_session *sess, const char *path, 65 const ne_uri **redir) 66{ 67 ONN("did not get NE_REDIRECT", any_request(sess, path) != NE_REDIRECT); 68 *redir = ne_redirect_location(sess); 69 return OK; 70} 71 72static int check_redir(struct redir_args *args, const char *expect) 73{ 74 ne_session *sess; 75 const ne_uri *loc; 76 char *unp; 77 78 CALL(make_session(&sess, serve_redir, args)); 79 ne_redirect_register(sess); 80 81 CALL(process_redir(sess, args->path, &loc)); 82 ONN("redirect location was NULL", loc == NULL); 83 84 unp = ne_uri_unparse(loc); 85 ONV(strcmp(unp, expect), ("redirected to `%s' not `%s'", unp, expect)); 86 ne_free(unp); 87 88 ne_session_destroy(sess); 89 CALL(await_server()); 90 91 return OK; 92} 93 94#define DEST "http://foo.com/blah/blah/bar" 95#define PATH "/redir/me" 96 97static int simple(void) 98{ 99 struct redir_args args[] = { 100 {301, DEST, PATH}, 101 {302, DEST, PATH}, 102 {303, DEST, PATH}, 103 {307, DEST, PATH}, 104 {0, NULL, NULL} 105 }; 106 int n; 107 108 for (n = 0; args[n].code; n++) 109 CALL(check_redir(&args[n], DEST)); 110 111 return OK; 112} 113 114/* check that a non-absoluteURI is qualified properly */ 115static int non_absolute(void) 116{ 117 struct redir_args args = {302, "/foo/bar/blah", PATH}; 118 return check_redir(&args, "http://localhost:7777/foo/bar/blah"); 119} 120 121static int relative_1(void) 122{ 123 struct redir_args args = {302, "norman", "/foo/bar"}; 124 return check_redir(&args, "http://localhost:7777/foo/norman"); 125} 126 127static int relative_2(void) 128{ 129 struct redir_args args = {302, "wishbone", "/foo/bar/"}; 130 return check_redir(&args, "http://localhost:7777/foo/bar/wishbone"); 131} 132 133#if 0 134/* could implement failure on self-referential redirects, but 135 * realistically, the application must implement a max-redirs count 136 * check, so it's kind of redundant. Mozilla takes this approach. */ 137static int fail_loop(void) 138{ 139 ne_session *sess; 140 141 CALL(make_session(&sess, serve_redir, "http://localhost:7777/foo/bar")); 142 143 ne_redirect_register(sess); 144 145 ONN("followed looping redirect", 146 any_request(sess, "/foo/bar") != NE_ERROR); 147 148 ne_session_destroy(sess); 149 return OK; 150} 151#endif 152 153/* ensure that ne_redirect_location returns NULL when no redirect has 154 * been encountered, or redirect hooks aren't registered. */ 155static int no_redirect(void) 156{ 157 ne_session *sess = ne_session_create("http", "localhost", 7777); 158 const ne_uri *loc; 159 160 ONN("redirect non-NULL before register", ne_redirect_location(sess)); 161 ne_redirect_register(sess); 162 ONN("initial redirect non-NULL", ne_redirect_location(sess)); 163 164 CALL(spawn_server(7777, single_serve_string, 165 "HTTP/1.0 200 OK\r\n\r\n\r\n")); 166 ONREQ(any_request(sess, "/noredir")); 167 CALL(await_server()); 168 169 ONN("redirect non-NULL after non-redir req", ne_redirect_location(sess)); 170 171 CALL(spawn_server(7777, single_serve_string, "HTTP/1.0 302 Get Ye Away\r\n" 172 "Location: /blah\r\n" "\r\n")); 173 CALL(process_redir(sess, "/foo", &loc)); 174 CALL(await_server()); 175 176 ne_session_destroy(sess); 177 return OK; 178} 179 180ne_test tests[] = { 181 T(lookup_localhost), 182 T(simple), 183 T(non_absolute), 184 T(relative_1), 185 T(relative_2), 186 T(no_redirect), 187 T(NULL) 188}; 189 190