From decbf0135cbc534d6cafd4e351eaa25588a9e1ee Mon Sep 17 00:00:00 2001 From: adevries Date: Fri, 5 Feb 1999 20:00:24 +0000 Subject: [PATCH] Made HTTP much better. CVS patchset: 2777 CVS date: 1999/02/05 20:00:24 --- http.c | 81 +++++++++++++++++++++++++++++++++++++++--------------------------- http.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- url.c | 3 ++- 3 files changed, 117 insertions(+), 39 deletions(-) diff --git a/http.c b/http.c index 6b5c9ef..7daa613 100644 --- a/http.c +++ b/http.c @@ -4,7 +4,6 @@ * Written by Alex deVries * * 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 --- 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 --- 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; -- 2.7.4