Skip to content
Snippets Groups Projects
transfer.c 41.2 KiB
Newer Older
  • Learn to ignore specific revisions
  •           /* we must make our own copy of the URL to play with, as it may
                 point to read-only data */
    
              char *url_clone=strdup(data->change.url);
    
              /* protsep points to the start of the host name */
    
              protsep=strstr(url_clone, "//");
    
                protsep+=2; /* pass the slashes */
    
    
                /* First we need to find out if there's a ?-letter in the URL,
                   and cut it and the right-side of that off */
                pathsep = strrchr(protsep, '?');
                if(pathsep)
                  *pathsep=0;
    
                /* we have a relative path to append to the last slash if
                   there's one available */
                pathsep = strrchr(protsep, '/');
                if(pathsep)
                  *pathsep=0;
              }
              else {
                /* We got a new absolute path for this server, cut off from the
                   first slash */
                pathsep = strchr(protsep, '/');
                if(pathsep)
                  *pathsep=0;
              }
    
    
              newest=(char *)malloc( strlen(url_clone) +
    
                                     1 + /* possible slash */
    
    
              if(!newest)
                return CURLE_OUT_OF_MEMORY;
    
              sprintf(newest, "%s%s%s", url_clone, ('/' == newurl[0])?"":"/",
                      newurl);
              free(newurl);
    
              /* This is an absolute URL, don't use the custom port number */
              port = FALSE;
    
            if(data->change.url_alloc)
              free(data->change.url);
            else
              data->change.url_alloc = TRUE; /* the URL is allocated */
    
          
            /* TBD: set the URL with curl_setopt() */
    
            newurl = NULL; /* don't free! */
    
            infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
    
            /*
             * We get here when the HTTP code is 300-399. We need to perform
             * differently based on exactly what return code there was.
             * Discussed on the curl mailing list and posted about on the 26th
             * of January 2001.
             */
    
            case 300: /* Multiple Choices */
            case 301: /* Moved Permanently */
            case 306: /* Not used */
            case 307: /* Temporary Redirect */
            default:  /* for all unknown ones */
              /* These are explicitly mention since I've checked RFC2616 and they
               * seem to be OK to POST to.
               */
              break;
    
            case 302: /* Found */
              /* (From 10.3.3)
    
                Note: RFC 1945 and RFC 2068 specify that the client is not allowed
                to change the method on the redirected request.  However, most
                existing user agent implementations treat 302 as if it were a 303
                response, performing a GET on the Location field-value regardless
                of the original request method. The status codes 303 and 307 have
                been added for servers that wish to make unambiguously clear which
                kind of reaction is expected of the client.
    
                (From 10.3.4)
    
                Note: Many pre-HTTP/1.1 user agents do not understand the 303
                status. When interoperability with such clients is a concern, the
                302 status code may be used instead, since most user agents react
                to a 302 response as described here for 303.             
              */
    
            case 303: /* See Other */
              /* Disable both types of POSTs, since doing a second POST when
               * following isn't what anyone would want! */
    
              data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
              infof(data, "Disables POST, goes with GET\n");
    
              break;
            case 304: /* Not Modified */
              /* 304 means we did a conditional request and it was "Not modified".
               * We shouldn't get any Location: header in this response!
               */
              break;
            case 305: /* Use Proxy */
              /* (quote from RFC2616, section 10.3.6):
               * "The requested resource MUST be accessed through the proxy given
               * by the Location field. The Location field gives the URI of the
               * proxy.  The recipient is expected to repeat this single request
               * via the proxy. 305 responses MUST only be generated by origin
               * servers."
               */
              break;
            }
    
            continue;
          }
        }
        break; /* it only reaches here when this shouldn't loop */
    
      } while(1); /* loop if Location: */
    
    
      /* make absolutely sure the alarm is switched off! */
    
      if(data->set.timeout || data->set.connecttimeout)
    
    CURLcode 
    Curl_Transfer(struct connectdata *c_conn, /* connection data */
                  int sockfd,	/* socket to read from or -1 */
                  int size,		/* -1 if unknown at this point */
                  bool getheader,	/* TRUE if header parsing is wanted */
                  long *bytecountp,	/* return number of bytes read or NULL */
                  int writesockfd,  /* socket to write to, it may very well be
                                       the same we read from. -1 disables */
                  long *writebytecountp /* return number of bytes written or
                                           NULL */
                  )
    {
      struct connectdata *conn = (struct connectdata *)c_conn;
      if(!conn)
        return CURLE_BAD_FUNCTION_ARGUMENT;
    
      /* now copy all input parameters */
      conn->sockfd = sockfd;
      conn->size = size;
      conn->getheader = getheader;
      conn->bytecountp = bytecountp;
      conn->writesockfd = writesockfd;
      conn->writebytecountp = writebytecountp;
    
      return CURLE_OK;
    
    }
              
    
    /*
     * local variables:
     * eval: (load-file "../curl-mode.el")
     * end:
    
     * vim600: fdm=marker
     * vim: et sw=2 ts=2 sts=2 tw=78