* 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
*/
#include "ftp.h"
#include "http.h"
-static int httpDebug = 0;
-
int httpProxySetup(const char * url, urlinfo ** uret)
{
urlinfo *u;
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;
}
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)
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;
}
struct timeval timeout;
int rc = 0;
int bufLength = 0;
+ unsigned int response;
errorCode[0] = '\0';
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';
*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;
} 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;
}
+/*
+ * 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
#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
+