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

# Content
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 buffer = new char[BUFSIZ + 1];
56
57 #ifdef _WIN32
58 if (WSAStartup(MAKEWORD(2, 0), &data) != 0)
59 {
60 error(program + ": WSAStartup()");
61 exit(1);
62 }
63 #endif // _WIN32
64
65 begin = 0;
66 }
67
68 HttpHandler::~HttpHandler()
69 {
70 delete [] buffer;
71
72 #ifdef _WIN32
73 WSACleanup();
74 #endif // _WIN32
75 }
76
77 bool HttpHandler::handle(URL &url, bool head)
78 {
79 bool answer = false;
80
81 if ((http = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
82 {
83 error(program + ": Socket");
84 exit(1);
85 }
86
87 sockaddr_in address;
88 hostent* host;
89
90 address.sin_family = AF_INET;
91
92 if ((host = gethostbyname(url.getAddress().c_str())) == NULL)
93 {
94 error(program + ": Host: " + url.getAddress(), true);
95 return answer;
96 }
97
98 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 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 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 void HttpHandler::error(const string prefix, bool host)
196 {
197 #ifdef _WIN32
198 string error;
199
200 switch (WSAGetLastError())
201 {
202 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
366 cerr << prefix << ": " << error << "\n";
367 #else
368 if (host)
369 {
370 herror(prefix.c_str());
371 }
372 else
373 {
374 perror(prefix.c_str());
375 }
376 #endif // _WIN32
377 }