Made HTTP much better.

CVS patchset: 2777
CVS date: 1999/02/05 20:00:24
This commit is contained in:
adevries 1999-02-05 20:00:24 +00:00
parent 6e22dccb47
commit decbf0135c
3 changed files with 117 additions and 39 deletions

81
http.c
View File

@ -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;
}

72
http.h
View File

@ -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

3
url.c
View File

@ -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;