diff --git a/TODO b/TODO index 715430e256..14d69eea98 100644 --- a/TODO +++ b/TODO @@ -160,6 +160,8 @@ LOW-PRIORITY -------------------------- DONE (may need test) Please document these! +- Test HTTP redirect mechanism for all types of operations (POST, GET, HEAD, etc) + - mechanism for returning app stderr output to server? store in blob? - add size to FILE_INFO diff --git a/checkin_notes b/checkin_notes index 6ad8cf519b..4d366be442 100755 --- a/checkin_notes +++ b/checkin_notes @@ -1370,3 +1370,15 @@ David A. July 30, 2002 index.html lib/ parse.C + +Eric Heien August 2, 2002 + - Implemented HTTP 301 and 302 redirect commands. + - These still need to be fully tested. + + TODO + client/ + http.C + http.h + net_xfer.C + net_xfer.h + diff --git a/client/http.C b/client/http.C index f36ee534ab..ea54fc32b2 100644 --- a/client/http.C +++ b/client/http.C @@ -237,6 +237,18 @@ int read_http_reply_header(int socket, HTTP_REPLY_HEADER& header) { if (p) { header.content_length = atoi(p+strlen("Content-Length: ")); } + p = strstr(buf, "Location: "); + if (p) { + // TODO: Is there a better way to do this? + n = 0; + p += strlen( "Location: " ); + + while (p[n] != '\n' && p[n] != '\r') { + header.redirect_location[n] = p[n]; + n++; + } + p[n] = '\0'; + } return 0; } } @@ -427,7 +439,7 @@ HTTP_OP_SET::HTTP_OP_SET(NET_XFER_SET* p) { net_xfers = p; } -// Inserts an hTTP_OP into the set +// Inserts an HTTP_OP into the set // int HTTP_OP_SET::insert(HTTP_OP* ho) { int retval; @@ -534,6 +546,30 @@ bool HTTP_OP_SET::poll() { action = true; if (log_flags.http_debug) printf("got reply header\n"); read_http_reply_header(htp->socket, htp->hrh); + // TODO: handle all kinds of redirects here + if (htp->hrh.status == 301 || htp->hrh.status == 302) { + fprintf( stderr, "Redirect to %s\n", htp->hrh.redirect_location ); + // Close the old socket + htp->close_socket(); + switch (htp->http_op_type) { + case HTTP_OP_HEAD: + htp->init_head( htp->hrh.redirect_location ); + break; + case HTTP_OP_GET: + htp->init_get( htp->hrh.redirect_location, htp->outfile ); + break; + case HTTP_OP_POST: + htp->init_post( htp->hrh.redirect_location, htp->infile, htp->outfile ); + break; + case HTTP_OP_POST2: + // TODO: Change offset to correct value + htp->init_post2( htp->hrh.redirect_location, htp->req1, htp->infile,0 ); + break; + } + // Open connection to the redirected server + htp->open_server(); + break; + } if (htp->hrh.status/100 != 2) { htp->http_op_state = HTTP_STATE_DONE; htp->http_op_retval = htp->hrh.status; diff --git a/client/http.h b/client/http.h index f9ab81cd94..12afe1a608 100644 --- a/client/http.h +++ b/client/http.h @@ -29,6 +29,7 @@ struct HTTP_REPLY_HEADER { int status; int content_length; + char redirect_location[256]; }; #define HTTP_OP_NONE 0 diff --git a/client/net_xfer.C b/client/net_xfer.C index 839230a700..b1b217108c 100644 --- a/client/net_xfer.C +++ b/client/net_xfer.C @@ -123,6 +123,13 @@ int NET_XFER::open_server() { return 0; } +void NET_XFER::close_socket( void ) { +#ifdef _WIN32 + if (socket) closesocket(socket); +#else + if (socket) close(socket); +#endif +} void NET_XFER::init(char* host, int p, int b) { // net_xfer_state = ? @@ -154,11 +161,8 @@ int NET_XFER_SET::insert(NET_XFER* nxp) { int NET_XFER_SET::remove(NET_XFER* nxp) { vector::iterator iter; -#ifdef _WIN32 - if (nxp->socket) closesocket(nxp->socket); -#else - if (nxp->socket) close(nxp->socket); -#endif + // Close the socket + nxp->close_socket(); iter = net_xfers.begin(); while (iter != net_xfers.end()) { diff --git a/client/net_xfer.h b/client/net_xfer.h index 00909908e3..ce13bdf800 100644 --- a/client/net_xfer.h +++ b/client/net_xfer.h @@ -51,6 +51,7 @@ public: void init(char* host, int port, int blocksize); int open_server(); + void close_socket(); int do_xfer(int&); void got_error(); };