ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/Search/HttpHandler.cpp
Revision: 14
Committed: 2002-12-07T00:19:03-08:00 (22 years, 6 months ago) by douglas
File size: 9011 byte(s)
Log Message:
Renamed HttpHandler.connect() to HttpHandler.handle().
Implemented client header sending.
Changed indexing output positions in code.

File Contents

# User Rev Content
1 douglas 1 /* ============================================================================
2     * Douglas Thrift's Search Engine License
3     *
4     * Copyright (C) 2002, Douglas Thrift. All Rights Reserved.
5     * Redistribution and use in source and binary forms, with or without
6     * modification, are permitted provided that the following conditions are met:
7     *
8     * 1. Redistributions of source code must retain the above copyright notice,
9     * this list of conditions and the following disclaimer.
10     *
11     * 2. Redistributions in binary form must reproduce the above copyright notice,
12     * this list of conditions and the following disclaimer in the documentation
13     * and/or other materials provided with the distribution.
14     *
15     * 3. The end-user documentation included with the redistribution, if any, must
16     * include the following acknowledgment:
17     *
18     * "This product includes software developed by Douglas Thrift
19     * (http://computers.douglasthrift.net/searchengine/)."
20     *
21     * Alternately, this acknowledgment may appear in the software itself, if
22     * and wherever such third-party acknowledgments normally appear.
23     *
24     * 4. The names "Douglas Thrift" and "Douglas Thrift's Search Engine" must not
25     * be used to endorse or promote products derived from this software without
26     * specific prior written permission. For written permission, please visit
27     * http://www.douglasthrift.net/contact.cgi for contact information.
28     *
29     * 5. Products derived from this software may not be called "Douglas Thrift's
30     * Search Engine", nor may "Douglas Thrift's Search Engine" appear in their
31     * name, without prior written permission.
32     *
33     * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
34     * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35     * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
36     * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
37     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
39     * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
40     * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41     * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
42     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43     * ============================================================================
44     */
45     // Douglas Thrift's Search Engine HTTP Handler
46     //
47     // Douglas Thrift
48     //
49     // HttpHandler.cpp
50    
51     #include "HttpHandler.h"
52    
53     HttpHandler::HttpHandler()
54     {
55 douglas 14 buffer = new char[BUFSIZ + 1];
56    
57 douglas 13 #ifdef _WIN32
58 douglas 14 if (WSAStartup(MAKEWORD(2, 0), &data) != 0)
59 douglas 13 {
60     error(program + ": WSAStartup()");
61     exit(1);
62     }
63     #endif // _WIN32
64 douglas 1
65     begin = 0;
66     }
67    
68     HttpHandler::~HttpHandler()
69     {
70 douglas 14 delete [] buffer;
71    
72 douglas 13 #ifdef _WIN32
73     WSACleanup();
74     #endif // _WIN32
75 douglas 1 }
76    
77 douglas 14 bool HttpHandler::handle(URL &url, bool head)
78 douglas 1 {
79     bool answer = false;
80    
81 douglas 14 if ((http = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
82     {
83     error(program + ": Socket");
84     exit(1);
85     }
86 douglas 1
87 douglas 14 sockaddr_in address;
88     hostent* host;
89 douglas 1
90 douglas 14 address.sin_family = AF_INET;
91 douglas 1
92 douglas 14 if ((host = gethostbyname(url.getAddress().c_str())) == NULL)
93     {
94     error(program + ": Host: " + url.getAddress(), true);
95     return answer;
96     }
97 douglas 1
98 douglas 14 address.sin_addr = *((in_addr*)*host->h_addr_list);
99     address.sin_port = htons(url.getPort());
100    
101     if (connect(http, (sockaddr*)&address, sizeof(sockaddr_in)) ==
102     SOCKET_ERROR)
103     {
104     error(program + ": Connect");
105     return answer;
106     }
107    
108     if (head)
109     {
110     putline("HEAD " + url.getPath() + " HTTP/1.1");
111     }
112     else
113     {
114     putline("GET " + url.getPath() + " HTTP/1.1");
115     }
116    
117     putline("Accept: text/html; text/plain");
118     putline("User-Agent: " + agent(true) + ' ' + platform());
119    
120     if (url.getPort() == 80)
121     {
122     putline("Host: " + url.getAddress());
123     }
124     else
125     {
126     char* port = new char[1024];
127     sprintf(port, "%u", url.getPort());
128    
129     putline("Host: " + url.getAddress() + ':' + port);
130    
131     delete [] port;
132     }
133    
134     putline();
135    
136 douglas 1 return answer;
137     }
138    
139     HttpHandler& HttpHandler::getline(string& line, char endline)
140     {
141     int end = page.find(endline, begin);
142     int newline = page.find('\n', begin);
143    
144     if (newline < end || end == string::npos)
145     {
146     end = newline;
147     }
148    
149     line = page.substr(begin, end - begin);
150    
151     if (end == string::npos)
152     {
153     begin = end;
154     }
155     else
156     {
157     begin = end + 1;
158     }
159    
160     return *this;
161     }
162    
163     bool HttpHandler::good()
164     {
165     bool answer = true;
166    
167     if (begin >= page.length())
168     {
169     answer = false;
170     }
171     else if (begin == string::npos)
172     {
173     answer = false;
174     }
175    
176     return answer;
177     }
178    
179     void HttpHandler::clear()
180     {
181     begin = 0;
182     page = "";
183     }
184    
185 douglas 14 void HttpHandler::putline(const string line)
186     {
187     sprintf(buffer, "%s\r\n", line.c_str());
188     if (send(http, buffer, strlen(buffer), 0) == SOCKET_ERROR)
189     {
190     error(program + ": Send");
191     exit(1);
192     }
193     }
194    
195 douglas 13 void HttpHandler::error(const string prefix, bool host)
196 douglas 1 {
197 douglas 13 #ifdef _WIN32
198     string error;
199 douglas 1
200 douglas 13 switch (WSAGetLastError())
201 douglas 1 {
202 douglas 13 case WSAEACCES:
203     error = "Permission denied.";
204     break;
205     case WSAEADDRINUSE:
206     error = "Address already in use.";
207     break;
208     case WSAEADDRNOTAVAIL:
209     error = "Cannot assign requested address.";
210     break;
211     case WSAEAFNOSUPPORT:
212     error = "Address family not supported by protocol family.";
213     break;
214     case WSAEALREADY:
215     error = "Operation already in progress.";
216     break;
217     case WSAECONNABORTED:
218     error = "Software caused connection abort.";
219     break;
220     case WSAECONNREFUSED:
221     error = "Connection refused.";
222     break;
223     case WSAECONNRESET:
224     error = "Connection reset by peer.";
225     break;
226     case WSAEDESTADDRREQ:
227     error = "Destination address required.";
228     break;
229     case WSAEFAULT:
230     error = "Bad address.";
231     break;
232     case WSAEHOSTDOWN:
233     error = "Host is down.";
234     break;
235     case WSAEHOSTUNREACH:
236     error = "No route to host.";
237     break;
238     case WSAEINPROGRESS:
239     error = "Operation now in progress.";
240     break;
241     case WSAEINTR:
242     error = "Interrupted function call.";
243     break;
244     case WSAEINVAL:
245     error = "Invalid argument.";
246     break;
247     case WSAEISCONN:
248     error = "Socket is already connected.";
249     break;
250     case WSAEMFILE:
251     error = "Too many open files.";
252     break;
253     case WSAEMSGSIZE:
254     error = "Message too long.";
255     break;
256     case WSAENETDOWN:
257     error = "Network is down.";
258     break;
259     case WSAENETRESET:
260     error = "Network dropped connection on reset.";
261     break;
262     case WSAENETUNREACH:
263     error = "Network is unreachable.";
264     break;
265     case WSAENOBUFS:
266     error = "No buffer space available.";
267     break;
268     case WSAENOPROTOOPT:
269     error = "Bad protocol option.";
270     break;
271     case WSAENOTCONN:
272     error = "Socket is not connected.";
273     break;
274     case WSAENOTSOCK:
275     error = "Socket operation on non-socket.";
276     break;
277     case WSAEOPNOTSUPP:
278     error = "Operation not supported.";
279     break;
280     case WSAEPFNOSUPPORT:
281     error = "Protocol family not supported.";
282     break;
283     case WSAEPROCLIM:
284     error = "Too many processes.";
285     break;
286     case WSAEPROTONOSUPPORT:
287     error = "Protocol not supported.";
288     break;
289     case WSAEPROTOTYPE:
290     error = "Protocol wrong type for socket.";
291     break;
292     case WSAESHUTDOWN:
293     error = "Cannot send after socket shutdown.";
294     break;
295     case WSAESOCKTNOSUPPORT:
296     error = "Socket type not supported.";
297     break;
298     case WSAETIMEDOUT:
299     error = "Connection timed out.";
300     break;
301     case WSATYPE_NOT_FOUND:
302     error = "Class type not found.";
303     break;
304     case WSAEWOULDBLOCK:
305     error = "Resource temporarily unavailable.";
306     break;
307     case WSAHOST_NOT_FOUND:
308     error = "Host not found.";
309     break;
310     case WSA_INVALID_HANDLE:
311     error = "Specified event object handle is invalid.";
312     break;
313     case WSA_INVALID_PARAMETER:
314     error = "One or more parameters are invalid.";
315     break;
316     // case WSAINVALIDPROCTABLE:
317     // error = "Invalid procedure table from service provider.";
318     // break;
319     // case WSAINVALIDPROVIDER:
320     // error = "Invalid service provider version number.";
321     // break;
322     case WSA_IO_INCOMPLETE:
323     error = "Overlapped I/O event object not in signaled state.";
324     break;
325     case WSA_IO_PENDING:
326     error = "Overlapped operations will complete later.";
327     break;
328     case WSA_NOT_ENOUGH_MEMORY:
329     error = "Insufficient memory available.";
330     break;
331     case WSANOTINITIALISED:
332     error = "Successful WSAStartup not yet performed.";
333     break;
334     case WSANO_DATA:
335     error = "Valid name, no data record of requested type.";
336     break;
337     case WSANO_RECOVERY:
338     error = "This is a non-recoverable error.";
339     break;
340     // case WSAPROVIDERFAILEDINIT:
341     // error = "Unable to initialize a service provider.";
342     // break;
343     case WSASYSCALLFAILURE:
344     error = "System call failure.";
345     break;
346     case WSASYSNOTREADY:
347     error = "Network subsystem is unavailable.";
348     break;
349     case WSATRY_AGAIN:
350     error = "Non-authoritative host not found.";
351     break;
352     case WSAVERNOTSUPPORTED:
353     error = "WINSOCK.DLL version out of range.";
354     break;
355     case WSAEDISCON:
356     error = "Graceful shutdown in progress.";
357     break;
358     case WSA_OPERATION_ABORTED:
359     error = "Overlapped operation aborted.";
360     break;
361     default:
362     error = "Unknown error.";
363     break;
364     }
365 douglas 1
366 douglas 13 cerr << prefix << ": " << error << "\n";
367     #else
368     if (host)
369     {
370     herror(prefix.c_str());
371 douglas 1 }
372     else
373     {
374 douglas 13 perror(prefix.c_str());
375 douglas 1 }
376 douglas 13 #endif // _WIN32
377     }