Contiki 3.x
urlconv.c
1 /*
2  * Copyright (c) 2010, Kajtar Zsolt <soci@c64.rulez.org>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * Author: Kajtar Zsolt <soci@c64.rulez.org>
32  *
33  */
34 
35 #include <string.h>
36 
37 #include "cfs/cfs.h"
38 #include "http-strings.h"
39 
40 #define ISO_number 0x23
41 #define ISO_percent 0x25
42 #define ISO_period 0x2e
43 #define ISO_slash 0x2f
44 #define ISO_question 0x3f
45 
46 static char wwwroot[40];
47 static unsigned char wwwrootlen;
48 
49 void
50 urlconv_init(void)
51 {
52  int fd = cfs_open("wwwroot.cfg", CFS_READ);
53  int rd = cfs_read(fd, wwwroot, sizeof(wwwroot));
54  cfs_close(fd);
55  if(rd != -1) wwwrootlen = rd;
56 }
57 
58 /*---------------------------------------------------------------------------*/
59 /* URL to filename conversion
60  *
61  * prepends wwwroot prefix
62  * normalizes path by removing "/./"
63  * interprets "/../" and calculates path accordingly
64  * resulting path is always absolute
65  * replaces "%AB" notation with characters
66  * strips "#fragment" and "?query" from end
67  * replaces multiple slashes with a single one
68  * rejects non-ASCII characters
69  *
70  * MAXLEN is including trailing zero!
71  * input and output is ASCII
72  */
73 void
74 urlconv_tofilename(char *dest, char *source, unsigned char maxlen)
75 {
76  static unsigned char len;
77  static unsigned char c, hex1;
78  static unsigned char *from, *to;
79 
80  *dest = ISO_slash;
81  strncpy(dest + 1, wwwroot, wwwrootlen);
82  len = 0;
83  from = source; to = dest + wwwrootlen;
84  maxlen -= 2 + wwwrootlen;
85  do {
86  c = *(from++);
87  switch(c) {
88  case ISO_number:
89  case ISO_question:
90  c = 0;
91  break;
92  case ISO_percent:
93  c = 0;
94  hex1 = (*(from++) | 0x20) ^ 0x30; // ascii only!
95  if(hex1 > 0x50 && hex1 < 0x57)
96  hex1 -= 0x47;
97  else
98  if(hex1 > 9)
99  break; // invalid hex
100  c = (*(from++) | 0x20) ^ 0x30; // ascii only!
101  if(c > 0x50 && c < 0x57)
102  c -= 0x47;
103  else
104  if(c > 9)
105  break; // invalid hex
106  c |= hex1 << 4;
107  }
108 
109  if(c < 0x20 || c > 0x7e)
110  c = 0; // non ascii?!
111  if(len >= maxlen)
112  c = 0; // too long?
113 
114  if(c == ISO_slash || !c) {
115  switch(*to) {
116  case ISO_slash:
117  continue; // no repeated slash
118  case ISO_period:
119  switch(to[-1]) {
120  case ISO_slash: // handle "./"
121  --to; --len;
122  continue;
123  case ISO_period:
124  if(to[-2] == ISO_slash) {
125  to -= 2; len -= 2;
126  if(len) {
127  do {
128  --to; --len;
129  } while(*to != ISO_slash);
130  }
131  continue;
132  }
133  }
134  }
135  }
136  if(c) {
137  ++to; ++len;
138  *to = c;
139  }
140  } while(c);
141  if(*to == ISO_slash && (len + sizeof(http_index_htm) - 3) < maxlen) {
142  strcpy(to, http_index_htm); // add index.htm
143  } else {
144  ++to;
145  *to = 0;
146  }
147 }
148 /*---------------------------------------------------------------------------*/
int cfs_open(const char *name, int flags)
Open a file.
Definition: cfs-coffee.c:996
#define CFS_READ
Specify that cfs_open() should open a file for reading.
Definition: cfs.h:90
void cfs_close(int fd)
Close an open file.
Definition: cfs-coffee.c:1032
CFS header file.