Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / apps / JAWS / clients / Caching / http_handler.cpp
blob8f50f8340678f9013d22632ad9a1831d76796c4c
2 //=============================================================================
3 /**
4 * @file http_handler.cpp
6 * @author James Hu
7 */
8 //=============================================================================
11 #include "ace/OS_NS_stdio.h"
12 #include "ace/OS_NS_string.h"
13 #include "ace/Filecache.h"
14 #include "http_handler.h"
16 HTTP_Handler::HTTP_Handler ()
20 HTTP_Handler::HTTP_Handler (const char * path)
22 // How long is the request going to be?
23 this->request_[0] = '\0';
24 this->request_size_ =
25 ACE_OS::strlen ("GET ")
26 + ACE_OS::strlen (path)
27 + ACE_OS::strlen (" HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n");
29 // Make the request.
30 if ((u_int) this->request_size_ < sizeof (this->request_))
31 ACE_OS::sprintf (this->request_,
32 "GET %s HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n",
33 path);
35 // Find the filename.
36 const char *last = ACE_OS::strrchr (path, '/');
38 if (last == 0)
39 last = path;
40 else if (last[1] == '\0')
41 last = "index.html";
42 else
43 last = last+1;
45 ACE_OS::sprintf (this->filename_, "%s", last);
48 int
49 HTTP_Handler::open (void *)
51 // If you want threads, use the activate stuff.
52 #if 0
53 if (this->activate () != 0)
55 ACE_ERROR_RETURN ((LM_ERROR, "HTTP_Handler::open, whups!\n"), -1);
58 return 0;
59 #else
60 return this->svc ();
61 #endif /* 0 */
64 int
65 HTTP_Handler::svc ()
67 static char buf[BUFSIZ];
68 int count = 0;
70 ACE_DEBUG ((LM_DEBUG, "[%t] sending request --\n%s", this->request_));
72 this->peer ().send_n (this->request_, this->request_size_);
74 // Read in characters until encounter \r\n\r\n
75 int done = 0;
76 char *contentlength;
80 while (((count += this->peer ().recv_n (buf + count, 1)) > 0)
81 && ((u_int) count < sizeof (buf)))
83 buf[count] = '\0';
85 if (count < 2)
86 continue;
87 done = ACE_OS::strcmp (buf + count - 4, "\n\n") == 0;
89 if (done)
90 break;
92 if (count < 4)
93 continue;
95 done = ACE_OS::strcmp (buf + count - 4, "\r\n\r\n") == 0;
97 if (done)
98 break;
101 if (!done)
103 char *last = ACE_OS::strrchr (buf, '\n');
104 last[0] = '\0';
106 if ((contentlength = ACE_OS::strstr (buf, "\nContent-length:"))
107 || (contentlength = ACE_OS::strstr (buf, "\nContent-Length:")))
108 done = 1;
109 else
111 last[0] = '\n';
112 count = ACE_OS::strlen (last);
113 ACE_OS::memmove (buf, last, count + 1);
116 else
118 contentlength = ACE_OS::strstr (buf, "\nContent-length:");
120 if (!contentlength)
121 contentlength =
122 ACE_OS::strstr (buf, "\nContent-Length:");
126 while (!done);
128 // ASSERT (contentlength != 0)
129 int size = 0;
130 if (contentlength
131 && (::sscanf (contentlength, "\nContent-%*[lL]ength: %d ",
132 &size) == 1))
134 this->response_size_ = size;
135 ACE_Filecache_Handle afh (ACE_TEXT_CHAR_TO_TCHAR (this->filename_),
136 this->response_size_);
138 this->peer ().recv_n (afh.address (), this->response_size_);
140 ACE_DEBUG ((LM_DEBUG,
141 " ``%s'' is now cached.\n",
142 this->filename_));
144 else
146 // Maybe we should do something more clever here, such as extend
147 // ACE_Filecache_Handle to allow the creation of cache objects
148 // whose size is unknown?
150 // Another possibility is to write the contents out to a file,
151 // and then cache it.
153 // Perhaps make ACE_Filecache_Handle more savvy, and allow a
154 // constructor which accepts a PEER as a parameter.
155 ACE_DEBUG ((LM_DEBUG,
156 "HTTP_Handler, no content-length header!\n"));
159 return 0;
162 const char *
163 HTTP_Handler::filename () const
165 return this->filename_;
169 HTTP_Connector::connect (const char * url)
171 char host[BUFSIZ];
172 u_short port;
173 char path[BUFSIZ];
175 if (this->parseurl (url, host, &port, path) == -1)
177 ACE_DEBUG ((LM_DEBUG,
178 "HTTP_Connector, error parsing url: %s\n",
179 url));
180 return -1;
183 HTTP_Handler hh (path);
184 HTTP_Handler *hhptr = &hh;
186 // First check the cache.
187 if (ACE_Filecache::instance ()->find (ACE_TEXT_CHAR_TO_TCHAR (hh.filename ())) == 0)
189 ACE_DEBUG ((LM_DEBUG, " ``%s'' is already cached.\n",
190 hh.filename ()));
191 return 0;
194 return this->connector_.connect (hhptr, ACE_INET_Addr (port, host));
197 #define DEFAULT_SERVER_PORT 80
199 // extract the main components of a URL
201 HTTP_Connector::parseurl (const char *url,
202 char *host,
203 u_short *port,
204 char *path)
206 int status = 0;
208 // hackish, but useful
209 if (3 != ::sscanf (url, "http://%[^:/]:%hu%s", host, port, path))
211 if (2 != ::sscanf (url, "http://%[^:/]:%hu", host, port))
213 if (2 != ::sscanf (url, "http://%[^:/]%s", host, path))
215 if (1 != ::sscanf (url, "http://%[^:/]", host))
216 status = -1;
217 else
219 *port = DEFAULT_SERVER_PORT;
220 ACE_OS::strcpy (path, "/");
223 else
224 *port = DEFAULT_SERVER_PORT;
226 else ACE_OS::strcpy (path, "/");
229 // 0 => success
230 // -1 => error
231 return status;