Main Page | Class List | File List | Class Members | File Members

url.c

Go to the documentation of this file.
00001 /*
00002  *  $Id: url.c,v 1.8 2006/04/17 22:45:19 ghost666 Exp $
00003  *
00004  *  rssbgr - RSS backgroud reader
00005  *  Copyright (C) 2005, 2006 Piotr 'GhosT' Wydrych
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #include "url.h"
00023 
00024 #define my_isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
00025 #define my_islower(c) (((c) >= 'a') && ((c) <= 'z'))
00026 #define my_isdigit(c) (((c) >= '0') && ((c) <= '9'))
00027 #define my_isalpha(c) (my_isupper(c) || my_islower(c))
00028 #define my_isalnum(c) (my_isalpha(c) || my_isdigit(c))
00029 #define my_isxdigit(c) (my_isdigit(c) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f')))
00030 
00031 int parse_url(char *url, char **out_host, uint16_t *port, char **out_request)
00032 {
00033  unsigned int i_url, i_host, i_request;
00034  char *host, *request;
00035 
00036  if (url == NULL) return -1;
00037  host = (char *)calloc(strlen(url)+1, sizeof(char));
00038  *port = 0;
00039  i_url = i_host = i_request = 0;
00040 
00041  if (!strncmp("http://", url, 7)) i_url = 7;
00042 
00043  for (; url[i_url] != '\0' && !i_request; ++i_url)
00044  {
00045   if (my_isalnum(url[i_url]) || url[i_url] == '-' || url[i_url] == '_' || url[i_url] == '.')
00046    host[i_host++] = tolower(url[i_url]);
00047   else if (url[i_url] == ':')
00048   {
00049    for(; my_isdigit(url[i_url+1]); ++i_url)
00050     *port = 10*(*port) + (uint16_t)(url[i_url+1] - '0');
00051    if (url[i_url+1] == '/' || url[i_url+1] == '\\' || url[i_url+1] == '\0')
00052     i_request = 5;
00053    else
00054     return -1;
00055    if (*port == 0)
00056     return -1;
00057    ++i_url;
00058   }
00059   else if (url[i_url] == '/' || url[i_url] == '\\')
00060    i_request = 5;
00061   else
00062    return -1;
00063  }
00064  if (*port == 0) *port = 80;
00065  host = (char *)realloc(host, i_host+1);
00066 
00067  request = (char *)calloc((strlen(url)-i_host)*3+7, sizeof(char)); /* calloc - very pessimistic version */
00068 
00069  strcat(request, "GET /");
00070 
00071  for (; url[i_url]; ++i_url)
00072   if (my_isalnum(url[i_url]) || url[i_url] == '/' || url[i_url] == '\\' || url[i_url] == '~' || url[i_url] == '-' || url[i_url] == '_' || url[i_url] == '.' || url[i_url] == '+' || url[i_url] == '=' || url[i_url] == '?' || url[i_url] == '&')
00073    request[i_request++] = url[i_url];
00074   else if (url[i_url] == '%')
00075   {
00076    if (my_isxdigit(url[i_url+1]) && my_isxdigit(url[i_url+2]))
00077    {
00078     request[i_request++] = url[i_url]; request[i_request++] = url[++i_url]; request[i_request++] = url[++i_url];
00079    }
00080    else
00081    {
00082     request[i_request++] = '%'; request[i_request++] = '2'; request[i_request++] = '5';
00083    }
00084   }
00085   else
00086   {
00087    request[i_request++] = '%'; sprintf(request+i_request, "%02X", (unsigned char)(url[i_url])); i_request+=2;
00088   }
00089 
00090  
00091  request = (char *)realloc(request, i_host+i_request+39);
00092  sprintf(request+i_request, " HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n", host);
00093 
00094  *out_host = host;
00095  *out_request = request;
00096  return i_host+i_request;
00097 }

Generated on Fri May 26 08:40:18 2006 for RSSbgr by doxygen 1.3.6