~ubuntu-branches/ubuntu/karmic/dante/karmic

« back to all changes in this revision

Viewing changes to dlib/httpproxy.c

  • Committer: Bazaar Package Importer
  • Author(s): Thijs Kinkhorst
  • Date: 2006-10-19 12:09:39 UTC
  • mfrom: (3.1.1 dapper)
  • Revision ID: james.westby@ubuntu.com-20061019120939-t818x24e2tn8be5k
Tags: 1.1.18-2.1
* Non-maintainer upload for RC bug.
* Make sure changelogs are installed into all packages (Closes: #393568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003
3
 
 *      Inferno Nettverk A/S, Norway.  All rights reserved.
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions
7
 
 * are met:
8
 
 * 1. The above copyright notice, this list of conditions and the following
9
 
 *    disclaimer must appear in all copies of the software, derivative works
10
 
 *    or modified versions, and any portions thereof, aswell as in all
11
 
 *    supporting documentation.
12
 
 * 2. All advertising materials mentioning features or use of this software
13
 
 *    must display the following acknowledgement:
14
 
 *      This product includes software developed by
15
 
 *      Inferno Nettverk A/S, Norway.
16
 
 * 3. The name of the author may not be used to endorse or promote products
17
 
 *    derived from this software without specific prior written permission.
18
 
 *
19
 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20
 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21
 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23
 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24
 
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 
 *
30
 
 * Inferno Nettverk A/S requests users of this software to return to
31
 
 *
32
 
 *  Software Distribution Coordinator  or  sdc@inet.no
33
 
 *  Inferno Nettverk A/S
34
 
 *  Oslo Research Park
35
 
 *  Gaustadall�en 21
36
 
 *  NO-0349 Oslo
37
 
 *  Norway
38
 
 *
39
 
 * any improvements or extensions that they make and grant Inferno Nettverk A/S
40
 
 * the rights to redistribute these changes.
41
 
 *
42
 
 */
43
 
 
44
 
#include "common.h"
45
 
 
46
 
static const char rcsid[] =
47
 
"$Id: httpproxy.c,v 1.12 2003/07/01 13:21:29 michaels Exp $";
48
 
 
49
 
int
50
 
httpproxy_negotiate(s, packet)
51
 
        int s;
52
 
        struct socks_t *packet;
53
 
{
54
 
        const char *function = "httpproxy_negotiate()";
55
 
        char buf[MAXHOSTNAMELEN + 512]; /* +512 for httpbabble. */
56
 
        char host[MAXSOCKSHOSTSTRING];
57
 
        int checked, eof;
58
 
        ssize_t len, rc;
59
 
        struct sockaddr addr;
60
 
        socklen_t addrlen;
61
 
 
62
 
        slog(LOG_DEBUG, function);
63
 
 
64
 
        sockshost2string(&packet->req.host, host, sizeof(host));
65
 
 
66
 
        /*
67
 
         * replace the dot that sockshost2string uses to separate port from host
68
 
         * with http's ':'.
69
 
        */
70
 
        *strrchr(host, '.') = ':';
71
 
 
72
 
        len = snprintfn(buf, sizeof(buf),
73
 
        "CONNECT %s HTTP/1.0\r\n"
74
 
        "User-agent: %s/client v%s\r\n"
75
 
        "\r\n",
76
 
        host, PACKAGE, VERSION);
77
 
 
78
 
        if ((rc = writen(s, buf, (size_t)len, NULL)) != len) {
79
 
                swarn("%s: wrote %d/%d bytes", function, rc, len);
80
 
                return -1;
81
 
        }
82
 
 
83
 
        slog(LOG_DEBUG, "%s: sending: %s", function, buf);
84
 
 
85
 
        eof = checked = len = 0;
86
 
        /* CONSTCOND */
87
 
        do {
88
 
                char *eol, *terminator = "\r\n";
89
 
 
90
 
                /* -1 so we can always NUL-terminate. */
91
 
                if (!eof) {
92
 
                        switch(rc = read(s, &buf[len], sizeof(buf) - len - 1)) {
93
 
                                case -1:
94
 
                                        swarn("%s: read()", function);
95
 
                                        return -1;
96
 
 
97
 
                                case 0:
98
 
                                        eof = 1;
99
 
                                        break;
100
 
                        }
101
 
                        len += rc;
102
 
                        SASSERTX((size_t)len < sizeof(buf));
103
 
                        buf[len] = NUL;
104
 
                }
105
 
 
106
 
                while ((eol = strstr(buf, terminator)) != NULL) { /* new line. */
107
 
                        *eol = NUL;
108
 
                        slog(LOG_DEBUG, "%s: read: %s", function, buf);
109
 
 
110
 
                        if (!checked) {
111
 
                                int error = 0;
112
 
 
113
 
                                switch (packet->req.version) {
114
 
                                        case HTTP_V1_0: {
115
 
                                                const char *offset = "HTTP/1.0 ";
116
 
 
117
 
                                                if (strncmp(buf, offset, strlen(offset)) != 0) {
118
 
                                                        error = 1;
119
 
                                                        break;
120
 
                                                }
121
 
 
122
 
                                                if (!isdigit(buf[strlen(offset)])) {
123
 
                                                        error = 1;
124
 
                                                        break;
125
 
                                                }
126
 
 
127
 
                                                packet->res.version = packet->req.version;
128
 
 
129
 
                                                /*
130
 
                                                 * XXX we've assumed that a reply is the size of a socks
131
 
                                                 * reply, http replies can however be bigger. :-/
132
 
                                                */
133
 
 
134
 
                                                /* CONSTCOND */
135
 
                                                packet->res.reply = (unsigned char)(atoi(&buf[strlen(offset)])
136
 
                                                == HTTP_SUCCESS ? HTTP_SUCCESS : !HTTP_SUCCESS);
137
 
 
138
 
 
139
 
                                                /*
140
 
                                                 * we don't know what address the server will use on
141
 
                                                 * our behalf, set it to what we use, better than nothing.
142
 
                                                */
143
 
                                                addrlen = sizeof(addr);
144
 
                                                if (getsockname(s, &addr, &addrlen) != 0)
145
 
                                                        SWARN(s);
146
 
                                                sockaddr2sockshost(&addr, &packet->res.host);
147
 
 
148
 
                                                checked = 1;
149
 
                                                break;
150
 
                                        }
151
 
 
152
 
                                        default:
153
 
                                                SERRX(packet->req.version);
154
 
                                }
155
 
 
156
 
                                if (error) {
157
 
                                        swarnx("%s: unknown response: \"%s\"", function, buf);
158
 
                                        return -1;
159
 
                                }
160
 
                        }
161
 
 
162
 
                        len -= (eol + strlen(terminator)) - buf;
163
 
                        SASSERTX(len >= 0);
164
 
                        SASSERTX((size_t)len < sizeof(buf));
165
 
                        memmove(buf, eol + strlen(terminator), (size_t)len);
166
 
                        buf[len] = NUL;
167
 
 
168
 
                        if (strncmp(buf, terminator, strlen(terminator)) == 0)
169
 
                                eof = 1;        /* empty line, all done. */
170
 
                }
171
 
 
172
 
                if (eof && !checked) { /* won't get any new line, dump what we have. */
173
 
                        slog(LOG_DEBUG, "%s: read: %s", function, buf);
174
 
                        len = 0;
175
 
                        buf[len] = 0;
176
 
                }
177
 
        } while (len > 0 || !eof);
178
 
 
179
 
        if (checked)
180
 
                return 0;
181
 
 
182
 
        slog(LOG_DEBUG, "%s: not checked?", function);
183
 
        return -1;      /* proxyserver doing something strange/unknown. */
184
 
}