Annotation of libwww/Library/src/HTTP.c, revision 1.1
1.1 ! timbl 1: /* HyperText Tranfer Protocol - Client implementation HTTP.c
! 2: ** ==========================
! 3: */
! 4:
! 5: /* Module parameters:
! 6: ** -----------------
! 7: **
! 8: ** These may be undefined and redefined by syspec.h
! 9: */
! 10: #include "HTParse.h"
! 11: #include "HTUtils.h"
! 12: #include "tcp.h"
! 13: #include "HTTCP.h"
! 14: #include "HTFormat.h"
! 15:
! 16:
! 17: /* Load Document from HTTP Server HTLoadHTTP()
! 18: ** ==============================
! 19: **
! 20: ** Given a hypertext address, this routine loads a document.
! 21: **
! 22: **
! 23: ** On entry,
! 24: ** arg is the hypertext reference of the article to be loaded.
! 25: ** gate is nill if no gateway, else the gateway address.
! 26: **
! 27: ** On exit,
! 28: ** returns >=0 If no error, a good socket number
! 29: ** <0 Error.
! 30: **
! 31: ** The socket must be closed by the caller after the document has been
! 32: ** read.
! 33: **
! 34: */
! 35: PUBLIC int HTLoadHTTP ARGS3 (CONST char *, arg,
! 36: /* CONST char *, gate, */
! 37: HTAnchor *, anAnchor,
! 38: int, diag)
! 39: {
! 40: int s; /* Socket number for returned data */
! 41: char *command; /* The whole command */
! 42: int status; /* tcp return */
! 43: int gateway = 0; /* disable this feature */
! 44:
! 45: SockA soc_address; /* Binary network address */
! 46: SockA * sin = &soc_address;
! 47:
! 48: if (!arg) return -3; /* Bad if no name sepcified */
! 49: if (!*arg) return -2; /* Bad if name had zero length */
! 50:
! 51: /* Set up defaults:
! 52: */
! 53: #ifdef DECNET
! 54: sin->sdn_family = AF_DECnet; /* Family = DECnet, host order */
! 55: sin->sdn_objnum = DNP_OBJ; /* Default: http object number */
! 56: #else /* Internet */
! 57: sin->sin_family = AF_INET; /* Family = internet, host order */
! 58: sin->sin_port = htons(TCP_PORT); /* Default: http port */
! 59: #endif
! 60:
! 61: if (TRACE) {
! 62: if (gate) fprintf(stderr,
! 63: "HTTPAccess: Using gateway %s for %s\n", gate, arg);
! 64: else fprintf(stderr, "HTTPAccess: Direct access for %s\n", arg);
! 65: }
! 66:
! 67: /* Get node name and optional port number:
! 68: */
! 69: {
! 70: char *p1 = HTParse(gate ? gate : arg, "", PARSE_HOST);
! 71: int status = HTParseInet(sin, p1); /* TBL 920622 */
! 72: free(p1);
! 73: if (status) return status; /* No such host for example */
! 74: }
! 75:
! 76:
! 77: /* Now, let's get a socket set up from the server for the sgml data:
! 78: */
! 79: #ifdef DECNET
! 80: s = socket(AF_DECnet, SOCK_STREAM, 0);
! 81: #else
! 82: s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
! 83: #endif
! 84: status = connect(s, (struct sockaddr*)&soc_address, sizeof(soc_address));
! 85: if (status < 0) {
! 86: #ifndef DECNET
! 87: /* This code is temporary backward-compatibility. It should
! 88: go away when no server runs on port 2784 alone */
! 89: if (sin->sin_port == htons(TCP_PORT)) { /* Try the old one */
! 90: if (TRACE) printf (
! 91: "HTTP: Port %d doesn't answer (errno = %d). Trying good old port %d...\n",
! 92: TCP_PORT, errno, OLD_TCP_PORT);
! 93: sin->sin_port = htons(OLD_TCP_PORT);
! 94: /* First close current socket and open a clean one */
! 95: status = NETCLOSE (s);
! 96: s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
! 97: status = connect(s, (struct sockaddr*)&soc_address,
! 98: sizeof(soc_address));
! 99: }
! 100: if (status < 0)
! 101: #endif
! 102: {
! 103: if (TRACE) fprintf(stderr,
! 104: "HTTP: Unable to connect to remote host for `%s' (errno = %d).\n", arg, errno);
! 105: /* free(command); BUG OUT TBL 921121 */
! 106: return HTInetStatus("connect");
! 107: }
! 108: }
! 109:
! 110: if (TRACE) fprintf(stderr, "HTTP connected, socket %d\n", s);
! 111:
! 112: /* Ask that node for the document,
! 113: ** omitting the host name & anchor if not gatewayed.
! 114: */
! 115: if (gate) {
! 116: command = malloc(4 + strlen(arg)+ 2 + 1);
! 117: if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
! 118: strcpy(command, "GET ");
! 119: strcat(command, arg);
! 120: } else { /* not gatewayed */
! 121: char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
! 122: command = malloc(4 + strlen(p1)+ 2 + 1);
! 123: if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
! 124: strcpy(command, "GET ");
! 125: strcat(command, p1);
! 126: free(p1);
! 127: }
! 128: strcat(command, "\r\n"); /* Include CR for telnet compat. */
! 129:
! 130:
! 131: if (TRACE) fprintf(stderr, "HTTP writing command `%s' to socket %d\n", command, s);
! 132:
! 133: #ifdef NOT_ASCII
! 134: {
! 135: char * p;
! 136: for(p = command; *p; p++) {
! 137: *p = TOASCII(*p);
! 138: }
! 139: }
! 140: #endif
! 141:
! 142: status = NETWRITE(s, command, (int)strlen(command));
! 143: free(command);
! 144: if (status<0) {
! 145: if (TRACE) fprintf(stderr, "HTTPAccess: Unable to send command.\n");
! 146: return HTInetStatus("send");
! 147: }
! 148:
! 149: /* Now load the data
! 150: */
! 151: HTParseFormat(diag ? WWW_PLAINTEXT : WWW_HTML,
! 152: (HTParentAnchor *) anAnchor, s);
! 153:
! 154: if (TRACE) fprintf(stderr, "HTTP: close socket %d.\n", s);
! 155: status = NETCLOSE(s);
! 156:
! 157: return HT_LOADED; /* Good return */
! 158: }
! 159:
! 160: /* Protocol descriptor
! 161: */
! 162:
! 163: PUBLIC HTProtocol = { "http", HTLoadHTTP, 0 };
Webmaster