Annotation of libwww/Library/src/HTTP.c, revision 1.1.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