"Fossies" - the Fresh Open Source Software Archive

Member "sitecopy-0.16.6/lib/neon/ne_redirect.c" (2 Jul 2007, 3677 Bytes) of archive /linux/www/sitecopy-0.16.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ne_redirect.c" see the Fossies "Dox" file reference documentation.

    1 /* 
    2    HTTP-redirect support
    3    Copyright (C) 1999-2007, Joe Orton <joe@manyfish.co.uk>
    4 
    5    This library is free software; you can redistribute it and/or
    6    modify it under the terms of the GNU Library General Public
    7    License as published by the Free Software Foundation; either
    8    version 2 of the License, or (at your option) any later version.
    9    
   10    This library is distributed in the hope that it will be useful,
   11    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13    Library General Public License for more details.
   14 
   15    You should have received a copy of the GNU Library General Public
   16    License along with this library; if not, write to the Free
   17    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   18    MA 02111-1307, USA
   19 
   20 */
   21 
   22 #include "config.h"
   23 
   24 #ifdef HAVE_STDLIB_H
   25 #include <stdlib.h>
   26 #endif
   27 #ifdef HAVE_STRING_H
   28 #include <string.h>
   29 #endif
   30 
   31 #include "ne_session.h"
   32 #include "ne_request.h"
   33 #include "ne_alloc.h"
   34 #include "ne_uri.h"
   35 #include "ne_redirect.h"
   36 #include "ne_internal.h"
   37 #include "ne_string.h"
   38 
   39 #define REDIRECT_ID "http://www.webdav.org/neon/hooks/http-redirect"
   40 
   41 struct redirect {
   42     char *requri;
   43     int valid; /* non-zero if .uri contains a redirect */
   44     ne_uri uri;
   45     ne_session *sess;
   46 };
   47 
   48 static void
   49 create(ne_request *req, void *session, const char *method, const char *uri)
   50 {
   51     struct redirect *red = session;
   52     if (red->requri) ne_free(red->requri);
   53     red->requri = ne_strdup(uri);
   54 }
   55 
   56 #define REDIR(n) ((n) == 301 || (n) == 302 || (n) == 303 || \
   57           (n) == 307)
   58 
   59 static int post_send(ne_request *req, void *private, const ne_status *status)
   60 {
   61     struct redirect *red = private;
   62     const char *location = ne_get_response_header(req, "Location");
   63     ne_buffer *path = NULL;
   64     int ret;
   65 
   66     /* Don't do anything for non-redirect status or no Location header. */
   67     if (!REDIR(status->code) || location == NULL)
   68     return NE_OK;
   69 
   70     if (strstr(location, "://") == NULL && location[0] != '/') {
   71     char *pnt;
   72 
   73     path = ne_buffer_create();
   74     ne_buffer_zappend(path, red->requri);
   75     pnt = strrchr(path->data, '/');
   76 
   77     if (pnt && pnt[1] != '\0') {
   78         /* Chop off last path segment. */
   79         pnt[1] = '\0';
   80         ne_buffer_altered(path);
   81     }
   82     ne_buffer_zappend(path, location);
   83     location = path->data;
   84     }
   85 
   86     /* free last uri. */
   87     ne_uri_free(&red->uri);
   88     
   89     /* Parse the Location header */
   90     if (ne_uri_parse(location, &red->uri) || red->uri.path == NULL) {
   91         red->valid = 0;
   92     ne_set_error(red->sess, _("Could not parse redirect destination URL"));
   93         ret = NE_ERROR;
   94     } else {
   95         /* got a valid redirect. */
   96         red->valid = 1;
   97         ret = NE_REDIRECT;
   98 
   99         if (!red->uri.host) {
  100             /* Not an absoluteURI: breaks 2616 but everybody does it. */
  101             ne_fill_server_uri(red->sess, &red->uri);
  102         }
  103     }
  104 
  105     if (path) ne_buffer_destroy(path);
  106 
  107     return ret;
  108 }
  109 
  110 static void free_redirect(void *cookie)
  111 {
  112     struct redirect *red = cookie;
  113     ne_uri_free(&red->uri);
  114     if (red->requri)
  115         ne_free(red->requri);
  116     ne_free(red);
  117 }
  118 
  119 void ne_redirect_register(ne_session *sess)
  120 {
  121     struct redirect *red = ne_calloc(sizeof *red);
  122     
  123     red->sess = sess;
  124 
  125     ne_hook_create_request(sess, create, red);
  126     ne_hook_post_send(sess, post_send, red);
  127     ne_hook_destroy_session(sess, free_redirect, red);
  128 
  129     ne_set_session_private(sess, REDIRECT_ID, red);
  130 }
  131 
  132 const ne_uri *ne_redirect_location(ne_session *sess)
  133 {
  134     struct redirect *red = ne_get_session_private(sess, REDIRECT_ID);
  135 
  136     if (red && red->valid)
  137         return &red->uri;
  138     else
  139         return NULL;
  140 }
  141