ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/Search/HttpHandler.cpp
(Generate patch)

Comparing trunk/Search/HttpHandler.cpp (file contents):
Revision 13 by douglas, 2002-12-06T19:56:56-08:00 vs.
Revision 19 by douglas, 2002-12-10T00:02:22-08:00

# Line 52 | Line 52
52  
53   HttpHandler::HttpHandler()
54   {
55 +        buffer = new char[BUFSIZ + 1];
56 +
57   #ifdef _WIN32
58 <        WSADATA data;
57 <        if (WSAStartup(MAKEWORD(2, 0) != 0, &data))
58 >        if (WSAStartup(MAKEWORD(2, 0), &data) != 0)
59          {
60 <                error(program + ": WSAStartup()");
60 >                error(program + ": WSAStartup");
61                  exit(1);
62          }
63   #endif // _WIN32
64  
65          begin = 0;
66 +        length = 0;
67 +        chunked = false;
68   }
69  
70   HttpHandler::~HttpHandler()
71   {
72 +        delete [] buffer;
73 +
74   #ifdef _WIN32
75          WSACleanup();
76   #endif // _WIN32
77   }
78  
79 < bool HttpHandler::connect(URL &url, bool head)
79 > bool HttpHandler::handle(URL &url, bool head)
80   {
81          bool answer = false;
82  
83 < //      if (status != JNI_ERR)
84 < //      {
85 < //              if (cls != 0)
86 < //              {
87 < //                      if (mid != 0)
88 < //                      {
89 < //                              jstring addressJ = env->NewStringUTF(url.getAddress().c_str());
90 < //                              jint portJ = url.getPort();
91 < //                              jstring pathJ = env->NewStringUTF(url.getPath().c_str());
92 < //                              jstring programNameJ = env->NewStringUTF(programName.c_str());
93 < //                              jstring programVersionJ =
94 < //                                      env->NewStringUTF(programVersion.c_str());
95 <
96 < //                              jstring pageJ = (jstring)env->CallStaticObjectMethod(cls, mid,
97 < //                                      addressJ, portJ, pathJ, programNameJ, programVersionJ);
98 <
99 < //                              const char* pageC = env->GetStringUTFChars(pageJ, 0);
100 < //                              page = pageC;
101 < //                              env->ReleaseStringUTFChars(pageJ, pageC);
102 <
103 < //                              if (page != "unknown host\n" && page != "io exception\n" &&
104 < //                                      page != "bad headers\n") answer = true;
105 < //                      }
106 < //              }
107 < //      }
83 >        if ((http = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
84 >        {
85 >                error(program + ": Socket");
86 >                exit(1);
87 >        }
88 >
89 >        sockaddr_in address;
90 >        hostent* host;
91 >
92 >        address.sin_family = AF_INET;
93 >
94 >        if ((host = gethostbyname(url.getAddress().c_str())) == NULL)
95 >        {
96 >                error(program + ": Host: " + url.getAddress(), true);
97 >                return answer;
98 >        }
99 >
100 >        address.sin_addr = *((in_addr*)*host->h_addr_list);
101 >        address.sin_port = htons(url.getPort());
102 >
103 >        if (connect(http, (sockaddr*)&address, sizeof(sockaddr_in)) ==
104 >                SOCKET_ERROR)
105 >        {
106 >                error(program + ": Connect");
107 >                return answer;
108 >        }
109 >
110 >        if (head)
111 >        {
112 >                putline("HEAD " + url.getPath() + " HTTP/1.1");
113 >        }
114 >        else
115 >        {
116 >                putline("GET " + url.getPath() + " HTTP/1.1");
117 >        }
118 >
119 >        putline("Accept: text/html; text/plain");
120 >        putline("User-Agent: " + agent(true) + ' ' + platform());
121 >
122 >        if (url.getPort() == 80)
123 >        {
124 >                putline("Host: " + url.getAddress());
125 >        }
126 >        else
127 >        {
128 >                char* port = new char[1024];
129 >                sprintf(port, "%u", url.getPort());
130 >
131 >                putline("Host: " + url.getAddress() + ':' + port);
132 >
133 >                delete [] port;
134 >        }
135 >
136 > //      putline("Referer: " + ?referer?);
137 >        putline("Connection: close");
138 >        putline();
139 >
140 >        code response;
141 >        string line;
142 >
143 >        do
144 >        {
145 >                line = getline();
146 >
147 >                if (line.find("HTTP/") != 0)
148 >                {
149 >                        return answer;
150 >                }
151 >
152 >                unsigned dot = line.find('.');
153 >                unsigned space = line.find(' ');
154 >
155 >                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 10);
156 >                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(),
157 >                        0, 10);
158 >
159 >                if (major > 1 || minor < 1)
160 >                {
161 >                        cerr << program << ": Potentially Incompatible Server: HTTP/" <<
162 >                                major << "." << minor << "\n";
163 >
164 >                        return answer;
165 >                }
166 >
167 >                response = code(strtoul(line.substr(space + 1).c_str(), 0, 10));
168 >
169 >                if (response < ok) do line = getline(); while (line != "");
170 >        }
171 >        while (response < ok);
172 >
173 >        do
174 >        {
175 >                line = getline();
176 >
177 >                if (line != "")
178 >                {
179 >                        unsigned colon = line.find(':');
180 >
181 >                        string field = line.substr(0, colon);
182 >                        string value = line.substr(colon + 1);
183 >
184 >                        while (isspace(value[0])) value.erase(0, 1);
185 >
186 >                        if (field == "Content-Type")
187 >                        {
188 >                                type = value;
189 >                        }
190 >                        else if (field == "Content-Length")
191 >                        {
192 >                                length = strtoul(value.c_str(), 0, 10);
193 >                        }
194 >                        else if (field == "Location")
195 >                        {
196 >                                location = value;
197 >                        }
198 >                        else if (field == "Transfer-Encoding")
199 >                        {
200 >                                chunked = value == "chunked";
201 >                        }
202 >                }
203 >        }
204 >        while (line != "");
205 >
206 >        switch (response)
207 >        {
208 >        case ok:
209 >                if (debug) cerr << "response = " << response << "\n";
210 >                answer = true;
211 >                break;
212 >        case choices:
213 >        case moved:
214 >        case found:
215 >                if (debug) cerr << "response = " << response << "\n"
216 >                        << "location = " << location << "\n";
217 >                location = getLink(location, url);
218 >                break;
219 >        case notfound:
220 >        case internal:
221 >                if (debug) cerr << "response = " << response << "\n";
222 >                break;
223 >        default:
224 >                if (debug) cerr << "response = " << response << "\n";
225 >                if (response <= 299)
226 >                {
227 >                        answer = true;
228 >                }
229 >                else if (response <= 399)
230 >                {
231 >                        location = getLink(location, url);
232 >                }
233 >                break;
234 >        }
235 >
236 >        if (!head && answer) populate();
237  
238          return answer;
239   }
# Line 146 | Line 280 | bool HttpHandler::good()
280  
281   void HttpHandler::clear()
282   {
283 +        closesocket(http);
284 +
285 +        type = "";
286 +        length = 0;
287 +        location = "";
288          begin = 0;
289          page = "";
290 +        chunked = false;
291 + }
292 +
293 + void HttpHandler::populate()
294 + {
295 +        if (!chunked)
296 +        {
297 +                unsigned left = length;
298 +
299 +                while (left > 0)
300 +                {
301 +                        memset(buffer, 0, BUFSIZ + 1);
302 +
303 +                        unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
304 +
305 +                        if (recv(http, buffer, bytes, 0) == SOCKET_ERROR)
306 +                        {
307 +                                error(program + ": Revc");
308 +                                exit(1);
309 +                        }
310 +
311 +                        page += buffer;
312 +                        left -= bytes;
313 +                }
314 +        }
315 +        else
316 +        {
317 +                //
318 +        }
319 +
320 +        cerr << "\n[" << page << "]\n";
321 + }
322 +
323 + void HttpHandler::putline(const string line)
324 + {
325 +        sprintf(buffer, "%s\r\n", line.c_str());
326 +        if (send(http, buffer, strlen(buffer), 0) == SOCKET_ERROR)
327 +        {
328 +                error(program + ": Send");
329 +                exit(1);
330 +        }
331 + }
332 +
333 + string HttpHandler::getline()
334 + {
335 +        string line;
336 +        char byte;
337 +
338 +        do
339 +        {
340 +                if (recv(http, &byte, 1, 0) == SOCKET_ERROR)
341 +                {
342 +                        error(program + ": Recv");
343 +                }
344 +
345 +                if (byte != '\r' && byte != '\n')
346 +                {
347 +                        line += byte;
348 +                }
349 +        }
350 +        while (byte != '\n');
351 +
352 +        return line;
353   }
354  
355 < void HttpHandler::error(const string prefix, bool host)
355 > void HttpHandler::error(const string& prefix, bool host)
356   {
357   #ifdef _WIN32
358          string error;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines