4 * Copyright (C) 2000, 2001, 2002 by
5 * Jeffrey Fulmer - <jdfulmer@armstrong.com>
6 * This file is distributed as part of Siege
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #endif/*HAVE_CONFIG_H*/
35 # define strrchr rindex
37 char *strchr (), *strrchr ();
39 # define memcpy(d, s, n) bcopy ((s), (d), (n))
40 # define memmove(d, s, n) bcopy ((s), (d), (n))
49 #define PLENGTH 84 /* length of the *prot[] array */
52 * ALERT: using hardcoded array lengths below,
53 * if you change this array, then redefine PLENGTH
55 * Currently http(prot[25]) and https(prot[26]) are
56 * the only supported protocols. But all w3c supported
57 * protocols are listed for URL evaluation.
59 static char *prot[] = {
60 "about:", "addrbook:", "acap:", "afp:",
61 "afs:", "callto:", "chttp:", "cid:",
62 "clsid:", "data:", "date:", "DAV:",
63 "dns:", "eid:", "fax:", "file:",
64 "finger:", "freenet:", "ftp:", "gopher:",
65 "gsm:", "h323:", "h324:", "hdl:",
66 "hnews:", "http:", "https:", "iioploc:",
67 "ilu:", "imap:", "IOR:", "irc:",
68 "isbn:", "java:", "JavaRMI:", "javascript:",
69 "jdbc:", "ldap:", "lid:", "lifn:",
70 "livescript:", "lrq:", "mailto:", "mailserver:",
71 "md5:", "mid:", "mocha:", "modem:",
72 "news:", "nfs:", "nntp:", "opaquelocktoken:"
73 "path:", "phone:", "pop:", "pop3:",
74 "printer:", "prospero:", "res:", "rtsp:",
75 "rvp:", "rwhois:", "rx:", "sdp:",
76 "sip:", "shttp:", "snews:", "STANF:",
77 "t120:", "tel:", "telephone:", "telnet:",
78 "tip:", "tn3270:", "tv:", "uuid:",
79 "urn:", "vemmi:", "videotex:", "view:",
80 "wais:", "whois++:", "whodp:", "z39.50r:",
86 * int value of the length of the protocol
87 * string passed to the function.
90 protocol_length( char *url )
94 * hardcoded protocol length!! see explanation above...
96 for( x = 0; x < PLENGTH; x ++ ){
97 if( strncasecmp( url, prot[x], strlen( prot[x] )) == 0 )
98 return strlen( prot[x] );
104 * If a person edits an html file on the
105 * Microsoft platform and copies it to a
106 * UNIX server, we are left to deal with
107 * ^M chars messing with our minds...
114 if( str == NULL ) return NULL;
116 /* advance the ptr */
119 /* chomp the white space */
120 while( str < s && isspace( *( s-1 )))
125 return str; /* UNIX friendly */
129 * boolean, returns true if the protocol is
130 * supported by siege, false if it is not.
133 is_supported( char* url )
135 if( strncasecmp( url, prot[25], strlen( prot[25] )) == 0 )
137 if( strncasecmp( url, prot[26], strlen( prot[26] )) == 0 )
142 #endif /* HAVE_SSL */
149 * returns protocol char*
152 get_protocol( const char *url )
154 if( strncasecmp( url, prot[25], strlen( prot[25] )) == 0 )
156 if( strncasecmp( url, prot[26], strlen( prot[26] )) == 0 )
161 #endif /* HAVE_SSL */
170 get_default_port( PROTOCOL p )
179 #endif /* HAVE_SSL */
185 url_encode( char *str )
190 static char unsafe[] = "<>{}#%|\"\\^~[]`@:\033";
191 static char char2hex[16] = "0123456789ABCDEF";
195 if( strchr( unsafe, *ch ))
200 buf = (char*)malloc( size +1 );
204 if( strchr( unsafe, *ch )){
207 *p++ = char2hex[(c >> 4) & 0xf];
208 *p++ = char2hex[c & 0xf];
222 * populates URL->postdata with POST information
226 process_post_data( char *datap )
228 for( ; isspace(*datap); datap++ ){
229 /* Advance past white space */
232 /* Get Data from file */
241 build_url( char *url )
243 URL U; /* defined in setup.h */
244 int one, two, thr, fou; /* placement counters. */
245 char *post_cmd=NULL; /* POST directive for server */
248 post_cmd = strstr( url, " POST" );
249 if( post_cmd != NULL ){
250 /* How do we deal with handling the multi-headed url_t arrays */
251 U.calltype = URL_POST;
254 U.postdata = (char*)strdup( process_post_data( post_cmd ));
255 U.postlen = strlen( U.postdata );
258 U.calltype = URL_GET;
263 if(( one = protocol_length( url )) > 0 && is_supported( url ) == TRUE ){
266 else if(( one = protocol_length( url )) > 0 && is_supported( url ) == FALSE ){
267 U.protocol = UNSPRTD;
269 perror( "unsupported protocol" );
272 /* we are dealing with who knows what */
273 tmp = (char*)strstr( url, "://" );
275 one = (strlen(url) - (strlen(tmp) - 3 ));
278 one = 0; /* no specified protocol, assuming http: */
283 while( url[two] && url[two] != ':' && url[two] != '/' ) two++;
285 if( url[two] == ':' ){
287 while( url[two] && url[two] != '/' ){
292 if( url[two] == '/' ){ thr = two; }
293 else { thr = strlen( url ); }
295 /* here we piece it all together */
300 U.protocol = get_protocol( url );
302 U.hostname = (char*)strdup(substring( url, one, ( fou - one )));
304 U.port = get_default_port( U.protocol );
307 U.port = atoi(substring( url, fou+1, (thr-(fou+1))));
309 if(( U.pathname = (char *)strdup(substring( url, thr, strlen( url )))) == NULL ){
310 U.pathname = (char *)strdup( "/" );
312 U.pathname = (strlen(U.pathname)==0)?strcpy(U.pathname, "/"):U.pathname;
321 * parses char * then populates and
322 * returns a URL with appropriate data.
328 return build_url( url );