Fixed gcc43 conversion warnings.
[privoxy.git] / parsers.c
index d56fde8..9060ea1 100644 (file)
--- a/parsers.c
+++ b/parsers.c
@@ -1,4 +1,4 @@
-const char parsers_rcs[] = "$Id: parsers.c,v 1.74 2006/10/02 16:59:12 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.78 2006/12/26 17:19:20 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/parsers.c,v $
@@ -10,10 +10,15 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.74 2006/10/02 16:59:12 fabiankeil
  *                   `client_uagent', `client_x_forwarded',
  *                   `client_x_forwarded_adder', `client_xtra_adder',
  *                   `content_type', `crumble', `destroy_list', `enlist',
- *                   `flush_socket', ``get_header', `sed',
- *                   and `server_set_cookie'.
- *
- * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
+ *                   `flush_socket', ``get_header', `sed', `filter_server_header'
+ *                   `filter_client_header', `filter_header', `crunch_server_header',
+ *                   `server_content_encoding', `server_content_disposition',
+ *                   `server_last_modified', `client_accept_language',
+ *                   `crunch_client_header', `client_if_modified_since',
+ *                   `client_if_none_match', `get_destination_from_headers',
+ *                   `parse_header_time' and `server_set_cookie'.
+ *
+ * Copyright   :  Written by and Copyright (C) 2001-2006 the SourceForge
  *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -40,6 +45,29 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.74 2006/10/02 16:59:12 fabiankeil
  *
  * Revisions   :
  *    $Log: parsers.c,v $
+ *    Revision 1.78  2006/12/26 17:19:20  fabiankeil
+ *    Bringing back the "useless" localtime() call
+ *    I removed in revision 1.67. On some platforms
+ *    it's necessary to prevent time zone offsets.
+ *
+ *    Revision 1.77  2006/12/07 18:44:26  fabiankeil
+ *    Rebuild request URL in get_destination_from_headers()
+ *    to make sure redirect{pcrs command} works as expected
+ *    for intercepted requests.
+ *
+ *    Revision 1.76  2006/12/06 19:52:25  fabiankeil
+ *    Added get_destination_from_headers().
+ *
+ *    Revision 1.75  2006/11/13 19:05:51  fabiankeil
+ *    Make pthread mutex locking more generic. Instead of
+ *    checking for OSX and OpenBSD, check for FEATURE_PTHREAD
+ *    and use mutex locking unless there is an _r function
+ *    available. Better safe than sorry.
+ *
+ *    Fixes "./configure --disable-pthread" and should result
+ *    in less threading-related problems on pthread-using platforms,
+ *    but it still doesn't fix BR#1122404.
+ *
  *    Revision 1.74  2006/10/02 16:59:12  fabiankeil
  *    The special header "X-Filter: No" now disables
  *    header filtering as well.
@@ -688,7 +716,7 @@ int flush_socket(jb_socket fd, struct client_state *csp)
  *                or buffer limit reached.
  *
  *********************************************************************/
-jb_err add_to_iob(struct client_state *csp, char *buf, int n)
+jb_err add_to_iob(struct client_state *csp, char *buf, size_t n)
 {
    struct iob *iob = csp->iob;
    size_t used, offset, need, want;
@@ -696,8 +724,8 @@ jb_err add_to_iob(struct client_state *csp, char *buf, int n)
 
    if (n <= 0) return JB_ERR_OK;
 
-   used   = iob->eod - iob->buf;
-   offset = iob->cur - iob->buf;
+   used   = (size_t)(iob->eod - iob->buf);
+   offset = (size_t)(iob->cur - iob->buf);
    need   = used + n + 1;
 
    /*
@@ -1593,7 +1621,7 @@ jb_err server_last_modified(struct client_state *csp, char **header)
       }
       else
       {
-         rtime = difftime(now, last_modified);
+         rtime = (long int)difftime(now, last_modified);
          if (rtime)
          {
             rtime = pick_from_range(rtime);
@@ -2887,9 +2915,12 @@ jb_err server_set_cookie(struct client_state *csp, char **header)
  *********************************************************************/
 int strclean(const char *string, const char *substring)
 {
-   int hits = 0, len = strlen(substring);
+   int hits = 0;
+   size_t len;
    char *pos, *p;
 
+   len = strlen(substring);
+
    while((pos = strstr(string, substring)) != NULL)
    {
       p = pos + len;
@@ -2918,7 +2949,7 @@ int strclean(const char *string, const char *substring)
  *          2  :  tm = storage for the resulting time in seconds 
  *
  * Returns     :  Time struct containing the header time, or
- *                NULL in case of a parsing problem.
+ *                NULL in case of a parsing problems.
  *
  *********************************************************************/
 struct tm *parse_header_time(char *header, time_t *tm) {
@@ -2927,6 +2958,25 @@ struct tm *parse_header_time(char *header, time_t *tm) {
    struct tm gmt;
    struct tm * timeptr;
 
+   /*
+    * Initializing gmt to prevent time zone offsets.
+    *
+    * While this is only necessary on some platforms
+    * (mingw32 for example), I don't know how to
+    * detect these automatically and doing it everywhere
+    * shouldn't hurt.
+    */
+   time(tm); 
+#ifdef HAVE_LOCALTIME_R
+   gmt = *localtime_r(tm, &gmt);
+#elif FEATURE_PTHREAD
+   pthread_mutex_lock(&localtime_mutex);
+   gmt = *localtime(tm); 
+   pthread_mutex_unlock(&localtime_mutex);
+#else
+   gmt = *localtime(tm); 
+#endif
+
    /* Skipping header name */
    timestring = strstr(header, ": ");
    if (strptime(timestring, ": %a, %d %b %Y %H:%M:%S", &gmt) == NULL)
@@ -2936,9 +2986,91 @@ struct tm *parse_header_time(char *header, time_t *tm) {
    else
    {
       *tm = timegm(&gmt);
-      timeptr=&gmt;
+      timeptr = &gmt;
    }
    return(timeptr);
+
+}
+
+/*********************************************************************
+ *
+ * Function    :  get_destination_from_headers
+ *
+ * Description :  Parse the "Host:" header to get the request's destination.
+ *                Only needed if the client's request was forcefully
+ *                redirected into Privoxy.
+ *
+ *                Code mainly copied from client_host() which is currently
+ *                run too late for this purpose.
+ *
+ * Parameters  :
+ *          1  :  headers = List of headers (one of them hopefully being
+ *                the "Host:" header)
+ *          2  :  http = storage for the result (host, port and hostport). 
+ *
+ * Returns     :  JB_ERR_MEMORY in case of memory problems,
+ *                JB_ERR_PARSE if the host header couldn't be found,
+ *                JB_ERR_OK otherwise.
+ *
+ *********************************************************************/
+jb_err get_destination_from_headers(const struct list *headers, struct http_request *http)
+{
+   char *q;
+   char *p;
+   char *host;
+
+   host = get_header_value(headers, "Host:");
+
+   if (NULL == host)
+   {
+      log_error(LOG_LEVEL_ERROR, "No \"Host:\" header found.");
+      return JB_ERR_PARSE;
+   }
+
+   if (NULL == (p = strdup((host))))
+   {
+      log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header");
+      return JB_ERR_MEMORY;
+   }
+   chomp(p);
+   if (NULL == (q = strdup(p)))
+   {
+      freez(p);
+      log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header");
+      return JB_ERR_MEMORY;
+   }
+
+   freez(http->hostport);
+   http->hostport = p;
+   freez(http->host);
+   http->host = q;
+   q = strchr(http->host, ':');
+   if (q != NULL)
+   {
+      /* Terminate hostname and evaluate port string */
+      *q++ = '\0';
+      http->port = atoi(q);
+   }
+   else
+   {
+      http->port = http->ssl ? 443 : 80;
+   }
+
+   /* Rebuild request URL */
+   freez(http->url);
+   http->url = strdup(http->ssl ? "https://" : "http://");
+   string_append(&http->url, http->hostport);
+   string_append(&http->url, http->path);
+   if (http->url == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   log_error(LOG_LEVEL_HEADER, "Destination extracted from \"Host:\" header. New request URL: %s",
+      http->url);
+
+   return JB_ERR_OK;
+
 }