Made HTTP much better.
authoradevries <devnull@localhost>
Fri, 5 Feb 1999 20:00:24 +0000 (20:00 +0000)
committeradevries <devnull@localhost>
Fri, 5 Feb 1999 20:00:24 +0000 (20:00 +0000)
CVS patchset: 2777
CVS date: 1999/02/05 20:00:24

http.c
http.h
url.c

diff --git a/http.c b/http.c
index 6b5c9ef..7daa613 100644 (file)
--- a/http.c
+++ b/http.c
@@ -4,7 +4,6 @@
  * Written by Alex deVries <puffin@redhat.com>
  * 
  * To do:
- *  - better HTTP response code handling
  *  - HTTP proxy authentication
  *  - non-peek parsing of the header so that querying works
  */
@@ -18,8 +17,6 @@
 #include "ftp.h"
 #include "http.h"
 
-static int httpDebug = 0;
-
 int httpProxySetup(const char * url, urlinfo ** uret)
 {
     urlinfo *u;
@@ -32,19 +29,20 @@ int httpProxySetup(const char * url, urlinfo ** uret)
        char *proxy;
        char *proxyport;
 
-       rpmMessage(RPMMESS_DEBUG, _("logging into %s as %s, pw %s\n"),
+       rpmMessage(RPMMESS_DEBUG, _("logging into %s as pw %s\n"),
                u->host,
-               u->user ? u->user : "ftp",
-               u->password ? u->password : "(username)");
+               u->user ? u->user : "(none)",
+               u->password ? u->password : "(none)");
 
        if ((proxy = rpmGetVar(RPMVAR_HTTPPROXY)) != NULL) {
-            newpath = malloc(strlen((*uret)->host)+
-                             strlen((*uret)->path) + 7 + 6 + 1 );
+            if ((newpath = malloc(strlen((*uret)->host)+
+                             strlen((*uret)->path) + 7 + 6 + 1 )) == NULL)
+               return HTTPERR_UNKNOWN_ERROR;
 
             sprintf(newpath,"http://%s:%i%s",
                  (*uret)->host,(*uret)->port,(*uret)->path);
            u->host = strdup(proxy);
-            free(u->path);
+            free(u->path);   /* Get rid of the old one */
             u->path = newpath;
        }
 
@@ -54,15 +52,18 @@ int httpProxySetup(const char * url, urlinfo ** uret)
            port = strtol(proxyport, &end, 0);
            if (*end) {
                fprintf(stderr, _("error: httport must be a number\n"));
-               return -1;
+               return HTTPERR_INVALID_PORT;
            }
             u->port=port;
        }
+    } else {
+      *uret = NULL;
+      return HTTPERR_UNSUPPORTED_PROTOCOL;
     }
 
     if (uret != NULL)
        *uret = u;
-    return 0;
+    return HTTPERR_OKAY;
 }
 
 int httpOpen(urlinfo *u)
@@ -84,19 +85,24 @@ int httpOpen(urlinfo *u)
 
     len = strlen(u->path) + sizeof("GET  HTTP 1.0\r\n\r\n"); 
     buf = alloca(len);
+    sprintf(buf,"GET %s HTTP 1.0\r\n\r\n",u->path);
+/*
     strcpy(buf, "GET ");
     strcat(buf, u->path);
     strcat(buf, " HTTP 1.0\r\n"); 
     strcat(buf,"\r\n");
+*/
 
-    sockfile = fdopen(sock,"r+");
+    if(!(sockfile = fdopen(sock,"r+"))) {
+        return HTTPERR_SERVER_IO_ERROR;
+    }
 
     if (write(sock, buf, len) != len) {
         close(sock);
         return HTTPERR_SERVER_IO_ERROR;
     }
-    
-    if (httpDebug) fprintf(stderr, "-> %s", buf);
+
+    rpmMessage(RPMMESS_DEBUG, _("Buffer: %s\n"), buf);
 
     return sock;
 }
@@ -114,6 +120,7 @@ int httpSkipHeader(FD_t sfd, char *buf,int * bytesRead, char ** start) {
     struct timeval timeout;
     int rc = 0;
     int bufLength = 0;
+    unsigned int response;
 
     errorCode[0] = '\0';
 
@@ -129,15 +136,19 @@ int httpSkipHeader(FD_t sfd, char *buf,int * bytesRead, char ** start) {
        rc = select(sfd->fd_fd+1, &readSet, &emptySet, &emptySet, &timeout);
        if (rc < 1) {
            if (rc==0) 
-               return HTTPERR_BAD_SERVER_RESPONSE;
+               return HTTPERR_SERVER_TIMEOUT;
            else
-               rc = HTTPERR_UNKNOWN;
+                return HTTPERR_SERVER_IO_ERROR;
        } else
            rc = 0;
 
        *bytesRead = read(sfd->fd_fd, buf + bufLength, 
              *bytesRead - bufLength - 1);
 
+        if (*bytesRead == -1) {
+                return HTTPERR_SERVER_IO_ERROR;
+        }
+
        bufLength += (*bytesRead);
 
        buf[bufLength] = '\0';
@@ -155,12 +166,14 @@ int httpSkipHeader(FD_t sfd, char *buf,int * bytesRead, char ** start) {
                   *chptr = '\0';
                if (*(chptr - 1) == '\r') *(chptr - 1) = '\0';
 
-                if ((!strncmp(*start,"HTTP",4)) && 
-                    (strchr(*start,' '))) {
-                   *start = strchr(*start,' ')+1;
-                   if (!strncmp(*start,"200",3))  {
-                       doesContinue = 1;
+                if ((!strncmp(*start,"HTTP",4))) {
+                   char *end;
+                   *start = strchr(*start,' ');
+                   response = strtol (*start,&end,0);
+                   if ((*end != '\0') && (*end != ' ')) {
+                      return HTTPERR_INVALID_SERVER_RESPONSE;
                    }
+                   doesContinue = 1;
                } else {
                     if (**start == '\0')  {
                        dataHere = 1;
@@ -174,32 +187,34 @@ int httpSkipHeader(FD_t sfd, char *buf,int * bytesRead, char ** start) {
          } while (chptr && !dataHere);
         }
     } while (doesContinue && !rc && !dataHere);
-    return 0;
+
+    switch (response) {
+      case HTTP_OK:
+          return 0;
+      default:
+          return HTTPERR_FILE_UNAVAILABLE;
+    }
 }
 
 int httpGetFile(FD_t sfd, FD_t tfd) {
 
     static char buf[BUFFER_SIZE + 1];
-    int bufLength = 0; 
     int bytesRead = BUFFER_SIZE, rc = 0;
     char * start;
 
-    httpSkipHeader(sfd,buf,&bytesRead,&start); 
+    if ((rc = httpSkipHeader(sfd,buf,&bytesRead,&start)) != HTTPERR_OKAY)
+            return rc;
     
     /* Write the buffer out to tfd */
 
-    if (write (tfd->fd_fd,start,bytesRead-(start-buf))<0) {
+    if (write (tfd->fd_fd,start,bytesRead-(start-buf))<0) 
         return HTTPERR_SERVER_IO_ERROR;
-    }
-
-    while (1) {
+    do {
        bytesRead = read(sfd->fd_fd, buf, 
              sizeof(buf)-1);
-        if (!bytesRead)  return 0;
-        if (write (tfd->fd_fd,buf,bytesRead)<0) {
+        if (write (tfd->fd_fd,buf,bytesRead)<0) 
            return HTTPERR_SERVER_IO_ERROR;
-         }
-    }    
-    return 0;
+    } while (bytesRead);
+    return HTTPERR_OKAY;
 }
 
diff --git a/http.h b/http.h
index bfe3b63..75038e1 100644 (file)
--- a/http.h
+++ b/http.h
@@ -1,16 +1,31 @@
+/*
+ * Portions 
+ * Copyright (c) 1995-1998 The Apache Group.  All rights reserved.
+ */
+
 #ifndef H_HTTP
 #define H_HTTP
 
+
+
+
 int httpProxySetup(const char * url, urlinfo ** uret);
 int httpCheckResponse(int fd, char ** str);
 int httpSkipHeader(FD_t sfd, char *buf,int * bytesRead, char ** start);
 
 
+#define HTTPERR_OKAY                        0
+#define HTTPERR_BAD_SERVER_RESPONSE     -1
+#define HTTPERR_SERVER_IO_ERROR         -2
+#define HTTPERR_SERVER_TIMEOUT          -3
+#define HTTPERR_BAD_HOSTNAME            -4
+#define HTTPERR_UNSUPPORTED_PROTOCOL    -5
+#define HTTPERR_INVALID_PORT            -6
+#define HTTPERR_INVALID_SERVER_RESPONSE -7
+#define HTTPERR_UNKNOWN_ERROR           -8
+#define HTTPERR_FILE_UNAVAILABLE        -9
+
 
-#define HTTPERR_BAD_SERVER_RESPONSE   -1
-#define HTTPERR_SERVER_IO_ERROR       -2
-#define HTTPERR_SERVER_TIMEOUT        -3
-#define HTTPERR_BAD_HOSTNAME          -5
 /*
 #define FTPERR_BAD_HOST_ADDR         -4
 #define FTPERR_FAILED_CONNECT        -6
@@ -20,6 +35,53 @@ int httpSkipHeader(FD_t sfd, char *buf,int * bytesRead, char ** start);
 #define FTPERR_FILE_NOT_FOUND        -10
 #define FTPERR_NIC_ABORT_IN_PROGRESS -11
 */
-#define HTTPERR_UNKNOWN               -100
+
+#define HTTP_CONTINUE                      100
+#define HTTP_SWITCHING_PROTOCOLS           101
+#define HTTP_PROCESSING                    102
+#define HTTP_OK                            200
+#define HTTP_CREATED                       201
+#define HTTP_ACCEPTED                      202
+#define HTTP_NON_AUTHORITATIVE             203
+#define HTTP_NO_CONTENT                    204
+#define HTTP_RESET_CONTENT                 205
+#define HTTP_PARTIAL_CONTENT               206
+#define HTTP_MULTI_STATUS                  207
+#define HTTP_MULTIPLE_CHOICES              300
+#define HTTP_MOVED_PERMANENTLY             301
+#define HTTP_MOVED_TEMPORARILY             302
+#define HTTP_SEE_OTHER                     303
+#define HTTP_NOT_MODIFIED                  304
+#define HTTP_USE_PROXY                     305
+#define HTTP_TEMPORARY_REDIRECT            307
+#define HTTP_BAD_REQUEST                   400
+#define HTTP_UNAUTHORIZED                  401
+#define HTTP_PAYMENT_REQUIRED              402
+#define HTTP_FORBIDDEN                     403
+#define HTTP_NOT_FOUND                     404
+#define HTTP_METHOD_NOT_ALLOWED            405
+#define HTTP_NOT_ACCEPTABLE                406
+#define HTTP_PROXY_AUTHENTICATION_REQUIRED 407
+#define HTTP_REQUEST_TIME_OUT              408
+#define HTTP_CONFLICT                      409
+#define HTTP_GONE                          410
+#define HTTP_LENGTH_REQUIRED               411
+#define HTTP_PRECONDITION_FAILED           412
+#define HTTP_REQUEST_ENTITY_TOO_LARGE      413
+#define HTTP_REQUEST_URI_TOO_LARGE         414
+#define HTTP_UNSUPPORTED_MEDIA_TYPE        415
+#define HTTP_RANGE_NOT_SATISFIABLE         416
+#define HTTP_EXPECTATION_FAILED            417
+#define HTTP_UNPROCESSABLE_ENTITY          422
+#define HTTP_LOCKED                        423
+#define HTTP_INTERNAL_SERVER_ERROR         500
+#define HTTP_NOT_IMPLEMENTED               501
+#define HTTP_BAD_GATEWAY                   502
+#define HTTP_SERVICE_UNAVAILABLE           503
+#define HTTP_GATEWAY_TIME_OUT              504
+#define HTTP_VERSION_NOT_SUPPORTED         505
+#define HTTP_VARIANT_ALSO_VARIES           506
+#define HTTP_NOT_EXTENDED                  510
 
 #endif
+
diff --git a/url.c b/url.c
index 817bbe3..92a6964 100644 (file)
--- a/url.c
+++ b/url.c
@@ -300,7 +300,8 @@ FD_t ufdOpen(const char *url, int flags, mode_t mode)
            break;
        if ((fd = fdNew()) == NULL)
            break;
-        httpProxySetup(url,&u);
+        if (httpProxySetup(url,&u)) 
+           break;
        fd->fd_url = u;
        fd->fd_fd = httpOpen(u);
        break;