~ubuntu-branches/ubuntu/precise/tidy/precise-updates

« back to all changes in this revision

Viewing changes to experimental/httpio.c

  • Committer: Bazaar Package Importer
  • Author(s): Jason Thomas
  • Date: 2008-01-20 21:46:03 UTC
  • mfrom: (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080120214603-poklofici9og61tx
Tags: 20080116cvs-2
* debian/control: build depends on xsltproc
  (closes: #461608)
* debian/tidy.preinst,postinst: add code to move old config file
  (closes: #461623)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "tmbstr.h"
 
2
 
 
3
#include "httpio.h"
 
4
 
 
5
int
 
6
makeConnection ( HTTPInputSource *pHttp )
 
7
{
 
8
    struct sockaddr_in sock;
 
9
    struct hostent *pHost;
 
10
 
 
11
    /* Get internet address of the host. */
 
12
    if (!(pHost = gethostbyname ( pHttp->pHostName )))
 
13
    {
 
14
        return -1;
 
15
    }
 
16
    /* Copy the address of the host to socket description.  */
 
17
    memcpy (&sock.sin_addr, pHost->h_addr, pHost->h_length);
 
18
 
 
19
    /* Set port and protocol */
 
20
    sock.sin_family = AF_INET;
 
21
    sock.sin_port = htons( pHttp->nPort );
 
22
 
 
23
    /* Make an internet socket, stream type.  */
 
24
    if ((pHttp->s = socket (AF_INET, SOCK_STREAM, 0)) == -1)
 
25
        return -1;
 
26
 
 
27
    /* Connect the socket to the remote host.  */
 
28
    if (connect (pHttp->s, (struct sockaddr *) &sock, sizeof( sock )))
 
29
    {
 
30
        if (errno == ECONNREFUSED)
 
31
            return ECONNREFUSED;
 
32
        else
 
33
            return -1;
 
34
    }
 
35
    return 0;
 
36
}
 
37
 
 
38
 
 
39
int parseURL( HTTPInputSource *pHttp, tmbstr url )
 
40
{
 
41
  int i, j = 0;
 
42
  ctmbstr pStr;
 
43
 
 
44
    pStr = tmbsubstr( url, "://" );
 
45
 
 
46
    /* If protocol is there, but not http, bail out, else assume http.  */
 
47
    if (NULL != pStr)
 
48
    {
 
49
        if (tmbstrncasecmp( url, "http://", 7 ))
 
50
            return -1;
 
51
    }
 
52
 
 
53
    if (NULL != pStr)
 
54
        j = pStr - url + 3;
 
55
    for (i = j; url[i] && url[i] != ':' && url[i] != '/'; i++) {}
 
56
    if (i == j)
 
57
        return -1;
 
58
 
 
59
    /* Get the hostname.  */
 
60
    pHttp->pHostName = tmbstrndup (&url[j], i - j );
 
61
 
 
62
    if (url[i] == ':')
 
63
    {
 
64
        /* We have a colon delimiting the hostname.  It should mean that
 
65
        a port number is following it */
 
66
        pHttp->nPort = 0;
 
67
        if (isdigit( url[++i] ))    /* A port number */
 
68
        {
 
69
            for (; url[i] && url[i] != '/'; i++)
 
70
            {
 
71
                if (isdigit( url[i] ))
 
72
                    pHttp->nPort = 10 * pHttp->nPort + (url[i] - '0');
 
73
                else
 
74
                    return -1;
 
75
            }
 
76
            if (!pHttp->nPort)
 
77
                return -1;
 
78
        }
 
79
        else                      /* or just a misformed port number */
 
80
            return -1;
 
81
    }
 
82
    else
 
83
        /* Assume default port.  */
 
84
        pHttp->nPort = 80;
 
85
 
 
86
    /* skip past the delimiting slash (we'll add it later )  */
 
87
    while (url[i] && url[i] == '/')
 
88
        i++;
 
89
    pHttp->pResource = tmbstrdup (url + i );
 
90
    return 0;
 
91
}
 
92
 
 
93
 
 
94
int fillBuffer( HTTPInputSource *in )
 
95
{
 
96
    if (0 < in->s)
 
97
    {
 
98
        in->nBufSize = recv( in->s, in->buffer, sizeof( in->buffer ), 0);
 
99
        in->nextBytePos = 0;
 
100
        if (in->nBufSize < sizeof( in->buffer ))
 
101
            in->buffer[in->nBufSize] = '\0';
 
102
    }
 
103
    else
 
104
        in->nBufSize = 0;
 
105
    return in->nBufSize;
 
106
}
 
107
 
 
108
 
 
109
int openURL( HTTPInputSource *in, tmbstr pUrl )
 
110
{
 
111
    int rc = -1;
 
112
#ifdef WIN32    
 
113
    WSADATA wsaData;
 
114
 
 
115
    rc = WSAStartup( 514, &wsaData );
 
116
#endif
 
117
 
 
118
    in->tis.getByte = (TidyGetByteFunc) HTTPGetByte; 
 
119
    in->tis.ungetByte = (TidyUngetByteFunc) HTTPUngetByte;
 
120
    in->tis.eof = (TidyEOFFunc) HTTPIsEOF;
 
121
    in->tis.sourceData = (uint) in;
 
122
    in->nextBytePos = in->nextUnGotBytePos = in->nBufSize = 0;
 
123
    parseURL( in, pUrl );
 
124
    if (0 == (rc = makeConnection( in )))
 
125
    {
 
126
        char ch, lastCh = '\0';
 
127
        int blanks = 0;
 
128
 
 
129
        char *getCmd = MemAlloc( 48 + strlen( in->pResource ));
 
130
        sprintf( getCmd, "GET /%s HTTP/1.0\r\nAccept: text/html\r\n\r\n", in->pResource );
 
131
        send( in->s, getCmd, strlen( getCmd ), 0 );
 
132
        MemFree( getCmd );
 
133
 
 
134
        /*  skip past the header information  */
 
135
        while (   in->nextBytePos >= in->nBufSize
 
136
               && 0 < (rc = fillBuffer( in )))
 
137
        {
 
138
            if (1 < blanks)
 
139
                break;
 
140
            for (; in->nextBytePos < sizeof( in->buffer ) 
 
141
                   && 0 != in->buffer[ in->nextBytePos ]; 
 
142
                 in->nextBytePos++ )
 
143
            {
 
144
                ch = in->buffer[ in->nextBytePos ];
 
145
                if (ch == '\r' || ch == '\n')
 
146
                {
 
147
                    if (ch == lastCh)
 
148
                    {
 
149
                        /*  Two carriage returns or two newlines in a row,
 
150
                            that's good enough */
 
151
                        blanks++;
 
152
                    }
 
153
                    if (lastCh == '\r' || lastCh == '\n')
 
154
                    {
 
155
                        blanks++;
 
156
                    }
 
157
                }
 
158
                else
 
159
                    blanks = 0;
 
160
                lastCh = ch;
 
161
                if (1 < blanks)
 
162
                {
 
163
                    /* end of header, scan to first non-white and return */
 
164
                    while ('\0' != ch && isspace( ch ))
 
165
                        ch = in->buffer[ ++in->nextBytePos ];
 
166
                    break;
 
167
                }
 
168
            }
 
169
        }
 
170
    }
 
171
    return rc;
 
172
}
 
173
 
 
174
 
 
175
void closeURL( HTTPInputSource *source )
 
176
{
 
177
    if (0 < source->s)
 
178
        closesocket( source->s );
 
179
    source->s = -1;
 
180
    source->tis.sourceData = 0;
 
181
#ifdef WIN32
 
182
    WSACleanup();
 
183
#endif
 
184
}
 
185
 
 
186
 
 
187
int HTTPGetByte( HTTPInputSource *source )
 
188
{
 
189
    if (source->nextUnGotBytePos)
 
190
        return source->unGetBuffer[ --source->nextUnGotBytePos ];
 
191
    if (0 != source->nBufSize && source->nextBytePos >= source->nBufSize)
 
192
    {
 
193
        fillBuffer( source );
 
194
    }
 
195
    if (0 == source->nBufSize)
 
196
        return EndOfStream;
 
197
    return source->buffer[ source->nextBytePos++ ];
 
198
}
 
199
 
 
200
void HTTPUngetByte( HTTPInputSource *source, uint byteValue )
 
201
{
 
202
    if (source->nextUnGotBytePos < 16 )  /* Only you can prevent buffer overflows */
 
203
        source->unGetBuffer[ source->nextUnGotBytePos++ ] = (char) byteValue;
 
204
}
 
205
 
 
206
Bool HTTPIsEOF( HTTPInputSource *source )
 
207
{
 
208
    if (source->nextUnGotBytePos)
 
209
        /* pending ungot bytes, not done */
 
210
        return no;
 
211
 
 
212
    if (   0 != source->nBufSize 
 
213
        && source->nextBytePos >= source->nBufSize)
 
214
        /* We've consumed the existing buffer, get another */
 
215
        fillBuffer( source );
 
216
 
 
217
    if (source->nextBytePos < source->nBufSize)
 
218
        /*  we have stuff in the buffer, must not be done. */
 
219
        return no;
 
220
 
 
221
    /* Nothing in the buffer, and the last receive failed, must be done.  */
 
222
    return yes;
 
223
}
 
224