head	1.16;
access;
symbols
	tonic_4:1.16
	tonic_3:1.16
	tonic_2:1.16
	demo:1.16.0.2
	design_report:1.16
	dec2:1.1.1.1
	oral_presentation_freeze:1.3.0.2
	DAVEG_CDP:1.1.1.1.0.4
	template_integ:1.1.1.1.0.2
	v1_1:1.1.1.1
	nov19:1.1.1.1
	course_staff:1.1.1;
locks; strict;
comment	@ * @;


1.16
date	95.12.11.18.52.48;	author rgmisra;	state Exp;
branches;
next	1.15;

1.15
date	95.12.11.15.57.10;	author daveg;	state Exp;
branches;
next	1.14;

1.14
date	95.12.11.15.53.08;	author daveg;	state Exp;
branches;
next	1.13;

1.13
date	95.12.11.13.43.28;	author rgmisra;	state Exp;
branches;
next	1.12;

1.12
date	95.12.11.13.33.10;	author hartmans;	state Exp;
branches;
next	1.11;

1.11
date	95.12.11.13.28.28;	author hartmans;	state Exp;
branches;
next	1.10;

1.10
date	95.12.11.07.11.54;	author hartmans;	state Exp;
branches;
next	1.9;

1.9
date	95.12.10.07.31.37;	author jered;	state Exp;
branches;
next	1.8;

1.8
date	95.12.10.07.23.50;	author hartmans;	state Exp;
branches;
next	1.7;

1.7
date	95.12.07.22.36.57;	author hartmans;	state Exp;
branches;
next	1.6;

1.6
date	95.12.07.11.08.02;	author hartmans;	state Exp;
branches;
next	1.5;

1.5
date	95.12.04.05.28.22;	author hartmans;	state Exp;
branches;
next	1.4;

1.4
date	95.12.02.09.47.00;	author hartmans;	state Exp;
branches;
next	1.3;

1.3
date	95.11.28.06.43.30;	author hartmans;	state Exp;
branches;
next	1.2;

1.2
date	95.11.28.06.33.42;	author hartmans;	state Exp;
branches;
next	1.1;

1.1
date	95.11.19.05.50.04;	author hartmans;	state Exp;
branches
	1.1.1.1;
next	;

1.1.1.1
date	95.11.19.05.50.05;	author hartmans;	state Exp;
branches;
next	;


desc
@@


1.16
log
@finally, a working safeify_filename
@
text
@#include <6170.h>
#include "ps5/url_ops.h"
#include <ctype.h>

// $Header: /afs/athena.mit.edu/course/6/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.15 1995/12/11 15:57:10 daveg Exp $

string extract_pathname(string URL) {
    int index;
    if (!URL.find_char('?', 0, index)) {
	index = URL.length();
    }
    int start = 0;
    while (start < URL.length() && URL[start] == '/') start++;
    return URL.substring(start, index - start);
}

string extract_query(string URL) {
    int index;
    if (!URL.find_char('?', 0, index)) return string();
    return URL.substring(index + 1, URL.length() - (index + 1));
}

static void split_path(string URL, int &start, int &end) {
    // effects: the location of the first character of first component is
    // placed in "start", and the location of the last character of that
    // component, plus one, is placed in "end". If there is no first component,
    // 0 is placed in both.
    start = 0;
    while (start < URL.length() && URL[start] == '/') start++;
    if (start == URL.length()) {
	start = 0;
	end = 0;
	return;
    }
    end = start + 1;
    while (end < URL.length() && URL[end] != '/') end++;
}

string first_component(string URL) {
    int start, next;
    split_path(URL, start, next);
    return extract_pathname(URL.substring(start, next - start));
}

string rest_components(string URL) {
    int start, next;
    split_path(URL, start, next);
    while (next < URL.length() && URL[next] == '/') next++;
    return URL.substring(next, URL.length() - next);
}

string last_component(string URL) {
    int last = URL.length() - 1;
    while (last >= 0 && URL[last] == '/') last--;
    last++;
    int first = last-1;
    while (first >= 0 && URL[first] != '/') first--;
    first++;
    if (first < last) return URL.substring(first, last - first);
    else return "";
}

string extension(string pathname) {
    int end = pathname.length() - 1;
    while (end > 0 && pathname[end] == '/') end--;
    int last = end - 1;
    while (last > 0 &&
	   pathname[last] != '/' &&
	   pathname[last] != '.') last--;
    if (last >= 0 && pathname[last] == '.') {
	return pathname.substring(last + 1, end - last);
    } else {
	return "";
    }
}

static int hex_to_nibble (char c)
// Effects: returns a nibble between 0 and 15
// Requires: c be in 0-9 a-f A-F
{
    switch (toupper(c))  {
    case '0':
	return 0;
    case '1': return 1;
    case '2': return 2;
    case '3': return 3;
    case '4': return 4;
    case '5': return 5;
    case '6': return 6;
    case '7': return 7;
    case '8': return 8;
    case '9': return 9;
    case 'A': return 10;
    case 'B': return 11;
    case 'C': return 12;
    case 'D': return 13;
    case 'E': return 14;
    case 'F': return 15;
    default: check(false, "hex_to_nibble passed non hex digit");
    }
    return 0; // Never ever reached.
}

bool unescape_uri(string in, string &out) {
    

    class unescaping_generator : public generator <char> {
    public:
	// Overview: Returns the characters of the string given to the
	// constructor replacing %xx (where xx is two hex digits) with the
	// appropriate unescaped character as per RFC 1738.


	unescaping_generator (string in ) {
	    s = in;
	    l = in.length();
	    broken_string = false;
	    i = 0;
    }

	bool get (char &c) {
	    if (i == l)
		return false;
	    if ( s[i] == '%') {
		if ((i+2  < l)&& (isxdigit(s[i+1]))&&(isxdigit(s[i+2]))) {
		    unsigned char ch = 16*hex_to_nibble(s[i+1])+hex_to_nibble(s[i+2]);
		    c = ch;
		    i += 3;
		    return true;
		}
		broken_string = true;
		i = l;
		    return false;
	    }
	    else {
		c = s[i++];
		return true;
	    }
	}

	bool broken() {return broken_string;
	}

    private:
	bool broken_string;
	int i,l;
	string s;
    } gen(in);
    string newstr(&gen);
    if ( gen.broken())
	return false;
    out = newstr;
    return true;
}

string escape_uri (string s) {
    return s; // Not quite long-term solution
}


map <string,string> *parse_query (string q) {
    map <string, string> *m = new map <string,string>;
    bool finding_value = false;		// If true, we are finding a value else a name.
    string fname;		// Generic string for field names
    int start = 0;			// 

    int lc;
    
    for ( lc = 0; lc < q.length(); lc++) {
	if (q[lc] == '='){
	    if (finding_value)
		return 0;		// We have an = in the middle of a field name.
	    finding_value = true;
	    if (!unescape_uri(q.substring(start,lc-start),fname))
		return 0;			//won't unescape
	    start = lc+1;
	}
	else if ((q[lc] == '&') || (lc == q.length())) {
	    if (!finding_value)
		return 0;	//  bogus: & in a field name.
	    string value;
	    if (!unescape_uri(q.substring(start,lc-start), value))
		return 0;	// unable to unescape value
	    if (value.length() != 0)
m->add(fname,value);
	    start = lc+1;
finding_value = false;
	}
    }
    if (finding_value) {
	    string value;
	    if (!unescape_uri(q.substring(start,lc-start), value))
		return 0;	// unable to unescape value
	    if (value.length() != 0)
m->add(fname,value);
}      
return m;
}

// string safeify_filename(string s) {
// int i;
// if (s.find_char('/',0,i))
// return "invalid_fil";
// return s;
// }

	
// string safeify_filename(string s) {
//    int i;
//    string fixed_name;
//  
//    for (i = 0; i < s.length(); i++)
//	if (s[i] != '/')
//	    fixed_name.append(s[i]);
//    return fixed_name;
//}

string safeify_filename(string s) {
  int curr, last = 0;
  string fixed_name = s;

  while (fixed_name.find_char('/', last, curr)) {
    fixed_name = fixed_name.substring(0, curr) + fixed_name.substring(curr+1, fixed_name.length()-curr-1);
  }
  return fixed_name;
}
@


1.15
log
@another bug fix
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.14 1995/12/11 15:53:08 daveg Exp $
d208 10
d219 7
a225 7
    int i;
    string fixed_name;
  
    for (i = 0; i < s.length(); i++)
	if (s[i] != '/')
	    fixed_name.append(s[i]);
    return fixed_name;
@


1.14
log
@bug fix
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.13 1995/12/11 13:43:28 rgmisra Exp $
d209 2
a210 2
  int i;
  string fixed_name;
d212 4
a215 4
  for (i = 0; i < s.length(); i++)
    if (s[i] != '/')
      fixed_name->append(s[i]);
  return fixed_name;
@


1.13
log
@okay... safeify_filename should work...
@
text
@d5 1
a5 1
// $Header: /afs/athena.mit.edu/course/6/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.12 1995/12/11 13:33:10 hartmans Exp $
d212 1
a212 1
  for (i = 0; i < s->length(); i++)
@


1.12
log
@Sort of fix safeify_filename
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.11 1995/12/11 13:28:28 hartmans Exp $
d200 8
d209 7
a215 4
int i;
if (s.find_char('/',0,i))
return "invalid_fil";
return s;
a216 2

	
@


1.11
log
@Fix parse_query to deal with elements
that are blank.
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.10 1995/12/11 07:11:54 hartmans Exp $
d204 1
@


1.10
log
@Add safeify_filename.
Try to fix streams handling under rs6k one last time;
failed.
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.9 1995/12/10 07:31:37 jered Exp $
d184 2
a185 1
	    m->add(fname,value);
d194 2
a195 1
	    m->add(fname,value);
@


1.9
log
@Fixed a typo.
@
text
@d5 1
a5 1
// $Header: /afs/athena.mit.edu/course/6/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.8 1995/12/10 07:23:50 hartmans Exp $
d197 8
@


1.8
log
@oops
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.7 1995/12/07 22:36:57 hartmans Exp $
d191 1
a191 1
l	    if (!unescape_uri(q.substring(start,lc-start), value))
@


1.7
log
@* Add test_qparse a test driver for parse_query and unescape_uri
* Fix bugs in parse_query and unescape_uri
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.6 1995/12/07 11:08:02 hartmans Exp $
d167 1
d169 1
a169 1
    for (int lc = 0; lc < q.length(); lc++) {
d191 1
a191 1
	    if (!unescape_uri(q.substring(start,lc-start), value))
@


1.6
log
@Fix URI handling bugs:
unescape_uri forgot to initialize i,
several bugs with finding_value in parse_query
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.5 1995/12/04 05:28:22 hartmans Exp $
d82 1
a82 1
    case 0:
d84 9
a92 9
    case 1: return 1;
    case 2: return 2;
    case 3: return 3;
    case 4: return 4;
    case 5: return 5;
    case 6: return 6;
    case 7: return 7;
    case 8: return 8;
    case 9: return 9;
d188 6
@


1.5
log
@Parse a query string.
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.4 1995/12/02 09:47:00 hartmans Exp $
d42 1
a42 1
    return URL.substring(start, next - start);
d118 1
a118 1
	
d163 1
a163 1
    bool finding_value = true;		// If true, we are finding a value else a name.
d185 1
@


1.4
log
@Stub test added.
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.3 1995/11/28 06:43:30 hartmans Exp $
d161 27
a187 3
map <string,string> *parse_query (string) {
    // This doesn't actually work; this is a stub
    return new map <string,string>;
@


1.3
log
@Fix typos and bugs
@
text
@d5 1
a5 1
// $Header: /mit/6.170/groups/se01/.cvsroot/src/ps5/url_ops.C,v 1.2 1995/11/28 06:33:42 hartmans Exp $
d159 6
@


1.2
log
@Add escape_uri and unescape_uri
@
text
@d3 1
a3 1
// $Header$
d5 2
d101 1
d130 3
a132 2
		}broken_string = true;
		i = l
d151 1
a151 1
	returrn false;
@


1.1
log
@Initial revision
@
text
@d1 1
d3 1
d74 81
@


1.1.1.1
log
@Bring web_server code into our tree
@
text
@@
