1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
/* 
 * $Id: pathinfo.pike,v 1.4 1999/10/04 15:00:28 per Exp $ 
 * 
 * PATH_INFO support for Roxen. 
 * 
 * Henrik Grubbström 1998-10-01 
 */ 
 
#include <module.h> 
 
inherit "module"; 
 
constant cvs_version = "$Id: pathinfo.pike,v 1.4 1999/10/04 15:00:28 per Exp $"; 
constant thread_safe = 1; 
 
// #define PATHINFO_DEBUG 
 
array register_module() 
{ 
  return ({ MODULE_LAST, "PATH_INFO support", 
            "Support for PATH_INFO style URLs.", 
            0, 1 }); 
} 
 
mapping|int last_resort(object id) 
{ 
#ifdef PATHINFO_DEBUG 
  roxen_perror(sprintf("PATHINFO: Checking %O...\n", id->not_query)); 
#endif /* PATHINFO_DEBUG */ 
  if (id->misc->path_info) { 
    // Already been here... 
#ifdef PATHINFO_DEBUG 
    roxen_perror(sprintf("PATHINFO: Been here, done that.\n")); 
#endif /* PATHINFO_DEBUG */ 
    return 0; 
  } 
 
  string query = id->not_query; 
#if 0 
  array(int) offsets = Array.map(query/"/", sizeof); 
 
  int sum = 0; 
  int i; 
  for (i=0; i < sizeof(offsets); i++) { 
    sum = (offsets[i] += sum) + 1; 
  } 
 
  int lo = (offsets[0] != 0);       // Skip testing the empty string. 
  int hi = sizeof(offsets) - 1; 
 
  while(lo <= hi) {             // Don't let the beams cross. 
    int probe = (lo + hi)/2; 
    string file = query[..offsets[probe]-1]; 
 
#ifdef PATHINFO_DEBUG 
    roxen_perror(sprintf("PATHINFO: Trying %O...\n", file)); 
#endif /* PATHINFO_DEBUG */ 
 
    /* Note: Zapps id->not_query. */ 
    array st = id->conf->stat_file(file, id); 
    if (st) { 
      if (st[1] >= 0) { 
        // Found a file! 
        id->misc->path_info = query[offsets[probe]..]; 
        id->not_query = file; 
#ifdef PATHINFO_DEBUG 
      roxen_perror(sprintf("PATHINFO: Found: %O:%O\n", 
                             id->not_query, id->misc->path_info)); 
#endif /* PATHINFO_DEBUG */ 
      return 1;   // Go through id->handle_request() one more time... 
      } 
#ifdef PATHINFO_DEBUG 
      roxen_perror(sprintf("PATHINFO: Directory: %O\n", file)); 
#endif /* PATHINFO_DEBUG */ 
      /* Hm. Lets try this: */ 
      id->misc->path_info = query[offsets[probe]+1..]; 
      id->not_query = file+"/"; 
      return 1; 
      lo = probe + 1; 
    } else { 
      hi = probe - 1; 
    } 
  } 
#else /* Slower, but it works... */ 
  string pi = ""; 
  while( (search( query, "/" ) != -1) && strlen( query ) > 0 ) 
  { 
    query = reverse(query); 
    string add_path_info; 
    sscanf( query, "%[^/]/%s", add_path_info, query ); 
    query = reverse( query ); 
    if( strlen( pi ) ) 
      pi = "/"+reverse( add_path_info )+pi; 
    else 
      pi = "/"+add_path_info; 
    id->misc->path_info = pi; 
    array st = id->conf->stat_file( query, id ); 
    if( st ) 
    { 
      id->not_query = query; 
      return 1; 
    } 
  } 
#endif 
  return 0; 
}