Changeset 330

Show
Ignore:
Timestamp:
03/08/08 03:02:55 (9 months ago)
Author:
jake
Message:

base64 encode the keys so that keys can have /&$ etc

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/thrudoc/src/DiskBackend.cpp

    r308 r330  
    4040 
    4141LoggerPtr DiskBackend::logger (Logger::getLogger ("DiskBackend")); 
     42 
     43 
     44static const std::string base64_chars = 
     45             "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
     46             "abcdefghijklmnopqrstuvwxyz" 
     47             "0123456789+_"; 
     48 
     49 
     50static inline bool is_base64(unsigned char c) { 
     51  return (isalnum(c) || (c == '+') || (c == '_')); 
     52} 
     53 
     54std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { 
     55  std::string ret; 
     56  int i = 0; 
     57  int j = 0; 
     58  unsigned char char_array_3[3]; 
     59  unsigned char char_array_4[4]; 
     60 
     61  while (in_len--) { 
     62    char_array_3[i++] = *(bytes_to_encode++); 
     63    if (i == 3) { 
     64      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; 
     65      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); 
     66      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); 
     67      char_array_4[3] = char_array_3[2] & 0x3f; 
     68 
     69      for(i = 0; (i <4) ; i++) 
     70        ret += base64_chars[char_array_4[i]]; 
     71      i = 0; 
     72    } 
     73  } 
     74 
     75  if (i) 
     76  { 
     77    for(j = i; j < 3; j++) 
     78      char_array_3[j] = '\0'; 
     79 
     80    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; 
     81    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); 
     82    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); 
     83    char_array_4[3] = char_array_3[2] & 0x3f; 
     84 
     85    for (j = 0; (j < i + 1); j++) 
     86      ret += base64_chars[char_array_4[j]]; 
     87 
     88    while((i++ < 3)) 
     89      ret += '='; 
     90 
     91  } 
     92 
     93  return ret; 
     94 
     95} 
     96 
     97std::string base64_decode(std::string const& encoded_string) { 
     98  int in_len = encoded_string.size(); 
     99  int i = 0; 
     100  int j = 0; 
     101  int in_ = 0; 
     102  unsigned char char_array_4[4], char_array_3[3]; 
     103  std::string ret; 
     104 
     105  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { 
     106    char_array_4[i++] = encoded_string[in_]; in_++; 
     107    if (i ==4) { 
     108      for (i = 0; i <4; i++) 
     109        char_array_4[i] = base64_chars.find(char_array_4[i]); 
     110 
     111      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); 
     112      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); 
     113      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; 
     114 
     115      for (i = 0; (i < 3); i++) 
     116        ret += char_array_3[i]; 
     117      i = 0; 
     118    } 
     119  } 
     120 
     121  if (i) { 
     122    for (j = i; j <4; j++) 
     123      char_array_4[j] = 0; 
     124 
     125    for (j = 0; j <4; j++) 
     126      char_array_4[j] = base64_chars.find(char_array_4[j]); 
     127 
     128    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); 
     129    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); 
     130    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; 
     131 
     132    for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; 
     133  } 
     134 
     135  return ret; 
     136} 
     137 
    42138 
    43139DiskBackend::DiskBackend (const string & doc_root) 
     
    264360            string ret = (*i)->path ().leaf (); 
    265361            Element e; 
    266             e.key    = ret; 
     362            e.key    = base64_decode(ret); 
    267363            e.value  = get (bucket, ret); 
    268364            e.bucket = bucket; 
     
    360456        throw e; 
    361457    } 
     458 
    362459    if (key) 
    363460    { 
     
    368465            throw e; 
    369466        } 
    370         // anything that's not legal in a file should be found and err'd on here 
    371         else if (key->find_first_of (";:/\\/~$") != string::npos) 
    372         { 
    373             ThrudocException e; 
    374             e.what = "invalid key"; 
    375             throw e; 
    376         } 
    377     } 
     467    } 
     468 
    378469    /* values can be whatever they want to be */ 
    379470} 
     
    412503                                   const string & key) 
    413504{ 
     505 
     506 
     507 
    414508    return 
    415509        doc_root + "/" + 
     
    418512        d2 + "/" + 
    419513        d3 + "/" + 
    420         key; 
     514        base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length()); 
    421515} 
    422516