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