source: trunk/third/libghttp/http_uri.c @ 15592

Revision 15592, 5.5 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15591, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * http_uri.c --- Contains functions to parse uri's
3 * Created: Christopher Blizzard <blizzard@appliedtheory.com>, 4-Jul-98
4 *
5 * Copyright (C) 1998 Free Software Foundation
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <string.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include "http_uri.h"
26
27typedef enum uri_parse_state_tag
28{
29  parse_state_read_host = 0,
30  parse_state_read_port,
31  parse_state_read_resource
32} uri_parse_state;
33   
34
35int
36http_uri_parse(char *a_string,
37               http_uri *a_uri)
38{
39  /* Everyone chant... "we love state machines..." */
40  uri_parse_state l_state = parse_state_read_host;
41  char *l_start_string = NULL;
42  char *l_end_string = NULL;
43  char  l_temp_port[6];
44
45  /* init the array */
46  memset(l_temp_port, 0, 6);
47  /* check the parameters */
48  if (a_string == NULL)
49    goto ec;
50  if (a_uri) {
51    a_uri->full = strdup(a_string);
52  }
53  l_start_string = strchr(a_string, ':');
54  /* check to make sure that there was a : in the string */
55  if (!l_start_string)
56    goto ec;
57  if (a_uri) {
58    a_uri->proto = (char *)malloc(l_start_string - a_string + 1);
59    memcpy(a_uri->proto, a_string, (l_start_string - a_string));
60    a_uri->proto[l_start_string - a_string] = '\0';
61  }
62  /* check to make sure it starts with "http://" */
63  if (strncmp(l_start_string, "://", 3) != 0)
64    goto ec;
65  /* start at the beginning of the string */
66  l_start_string = l_end_string = &l_start_string[3];
67  while(*l_end_string)
68    {
69      if (l_state == parse_state_read_host)
70        {
71          if (*l_end_string == ':')
72            {
73              l_state = parse_state_read_port;
74              if ((l_end_string - l_start_string) == 0)
75                goto ec;
76              /* allocate space */
77              if ((l_end_string - l_start_string) == 0)
78                goto ec;
79              /* only do this if a uri was passed in */
80              if (a_uri)
81                {
82                  a_uri->host = (char *)malloc(l_end_string - l_start_string + 1);
83                  /* copy the data */
84                  memcpy(a_uri->host, l_start_string, (l_end_string - l_start_string));
85                  /* terminate */
86                  a_uri->host[l_end_string - l_start_string] = '\0';
87                }
88              /* reset the counters */
89              l_end_string++;
90              l_start_string = l_end_string;
91              continue;
92            }
93          else if (*l_end_string == '/')
94            {
95              l_state = parse_state_read_resource;
96              if ((l_end_string - l_start_string) == 0)
97                goto ec;
98              if (a_uri)
99                {
100                  a_uri->host = (char *)malloc(l_end_string - l_start_string + 1);
101                  memcpy(a_uri->host, l_start_string, (l_end_string - l_start_string));
102                  a_uri->host[l_end_string - l_start_string] = '\0';
103                }
104              l_start_string = l_end_string;
105              continue;
106            }
107        }
108      else if (l_state == parse_state_read_port)
109        {
110          if (*l_end_string == '/')
111            {
112              l_state = parse_state_read_resource;
113              /* check to make sure we're not going to overflow */
114              if (l_end_string - l_start_string > 5)
115                goto ec;
116              /* check to make sure there was a port */
117              if ((l_end_string - l_start_string) == 0)
118                goto ec;
119              /* copy the port into a temp buffer */
120              memcpy(l_temp_port, l_start_string, l_end_string - l_start_string);
121              /* convert it. */
122              if (a_uri)
123                a_uri->port = atoi(l_temp_port);
124              l_start_string = l_end_string;
125              continue;
126            }
127          else if (isdigit(*l_end_string) == 0)
128            {
129              /* check to make sure they are just digits */
130              goto ec;
131            }
132        }
133      /* next.. */
134      l_end_string++;
135      continue;
136    }
137 
138  if (l_state == parse_state_read_host)
139    {
140      if ((l_end_string - l_start_string) == 0)
141        goto ec;
142      if (a_uri)
143        {
144          a_uri->host = (char *)malloc(l_end_string - l_start_string + 1);
145          memcpy(a_uri->host, l_start_string, (l_end_string - l_start_string));
146          a_uri->host[l_end_string - l_start_string] = '\0';
147          /* for a "/" */
148          a_uri->resource = strdup("/");
149        }
150    }
151  else if (l_state == parse_state_read_port)
152    {
153      if (strlen(l_start_string) == 0)
154        /* oops.  that's not a valid number */
155        goto ec;
156      if (a_uri)
157        {
158          a_uri->port = atoi(l_start_string);
159          a_uri->resource = strdup("/");
160        }
161    }
162  else if (l_state == parse_state_read_resource)
163    {
164      if (strlen(l_start_string) == 0)
165        {
166          if (a_uri)
167            a_uri->resource = strdup("/");
168        }
169      else
170        {
171          if (a_uri)
172            a_uri->resource = strdup(l_start_string);
173        }
174    }
175  else
176    {
177      /* uhh...how did we get here? */
178      goto ec;
179    }
180  return 0;
181         
182 ec:
183  return -1;
184}
185
186http_uri *
187http_uri_new(void)
188{
189  http_uri *l_return = NULL;
190
191  l_return = (http_uri *)malloc(sizeof(http_uri));
192  l_return->full = NULL;
193  l_return->proto = NULL;
194  l_return->host = NULL;
195  l_return->port = 80;
196  l_return->resource = NULL;
197  return l_return;
198}
199
200void
201http_uri_destroy(http_uri *a_uri)
202{
203  if (a_uri->full) {
204    free(a_uri->full);
205    a_uri->full = NULL;
206  }
207  if (a_uri->proto) {
208    free(a_uri->proto);
209    a_uri->proto = NULL;
210  }
211  if (a_uri->host) {
212    free(a_uri->host);
213    a_uri->host = NULL;
214  }
215  if (a_uri->resource) {
216    free(a_uri->resource);
217    a_uri->resource = NULL;
218  }
219  free(a_uri);
220}
221
222
Note: See TracBrowser for help on using the repository browser.