📄 http_handler.cpp
字号:
// $Id: http_handler.cpp 80826 2008-03-04 14:51:23Z wotte $
// ============================================================================
//
// = LIBRARY
// apps/JAWS/clients/Caching
//
// = FILENAME
// http_handler.cpp
//
// = AUTHOR
// James Hu
//
// ============================================================================
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_string.h"
#include "ace/Filecache.h"
#include "http_handler.h"
ACE_RCSID(Caching, http_handler, "$Id: http_handler.cpp 80826 2008-03-04 14:51:23Z wotte $")
HTTP_Handler::HTTP_Handler (void)
{
}
HTTP_Handler::HTTP_Handler (const char * path)
{
// How long is the request going to be?
this->request_[0] = '\0';
this->request_size_ =
ACE_OS::strlen ("GET ")
+ ACE_OS::strlen (path)
+ ACE_OS::strlen (" HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n");
// Make the request.
if ((u_int) this->request_size_ < sizeof (this->request_))
ACE_OS::sprintf (this->request_,
"GET %s HTTP/1.0\r\nAccept: HTTP/1.0\r\n\r\n",
path);
// Find the filename.
const char *last = ACE_OS::strrchr (path, '/');
if (last == 0)
last = path;
else if (last[1] == '\0')
last = "index.html";
else
last = last+1;
ACE_OS::sprintf (this->filename_, "%s", last);
}
int
HTTP_Handler::open (void *)
{
// If you want threads, use the activate stuff.
#if 0
if (this->activate () != 0)
{
ACE_ERROR_RETURN ((LM_ERROR, "HTTP_Handler::open, whups!\n"), -1);
}
return 0;
#else
return this->svc ();
#endif /* 0 */
}
int
HTTP_Handler::svc (void)
{
static char buf[BUFSIZ];
int count = 0;
ACE_DEBUG ((LM_DEBUG, "[%t] sending request --\n%s", this->request_));
this->peer ().send_n (this->request_, this->request_size_);
// Read in characters until encounter \r\n\r\n
int done = 0;
char *contentlength;
do
{
while (((count += this->peer ().recv_n (buf + count, 1)) > 0)
&& ((u_int) count < sizeof (buf)))
{
buf[count] = '\0';
if (count < 2)
continue;
done = ACE_OS::strcmp (buf + count - 4, "\n\n") == 0;
if (done)
break;
if (count < 4)
continue;
done = ACE_OS::strcmp (buf + count - 4, "\r\n\r\n") == 0;
if (done)
break;
}
if (!done)
{
char *last = ACE_OS::strrchr (buf, '\n');
last[0] = '\0';
if ((contentlength = ACE_OS::strstr (buf, "\nContent-length:"))
|| (contentlength = ACE_OS::strstr (buf, "\nContent-Length:")))
done = 1;
else
{
last[0] = '\n';
count = ACE_OS::strlen (last);
ACE_OS::memmove (buf, last, count + 1);
}
}
else
{
contentlength = ACE_OS::strstr (buf, "\nContent-length:");
if (!contentlength)
contentlength =
ACE_OS::strstr (buf, "\nContent-Length:");
}
}
while (!done);
// ASSERT (contentlength != 0)
int size = 0;
if (contentlength
&& (::sscanf (contentlength, "\nContent-%*[lL]ength: %d ",
&size) == 1))
{
this->response_size_ = size;
ACE_Filecache_Handle afh (ACE_TEXT_CHAR_TO_TCHAR (this->filename_),
this->response_size_);
this->peer ().recv_n (afh.address (), this->response_size_);
ACE_DEBUG ((LM_DEBUG,
" ``%s'' is now cached.\n",
this->filename_));
}
else
{
// Maybe we should do something more clever here, such as extend
// ACE_Filecache_Handle to allow the creation of cache objects
// whose size is unknown?
// Another possibility is to write the contents out to a file,
// and then cache it.
// Perhaps make ACE_Filecache_Handle more savvy, and allow a
// constructor which accepts a PEER as a parameter.
ACE_DEBUG ((LM_DEBUG,
"HTTP_Handler, no content-length header!\n"));
}
return 0;
}
const char *
HTTP_Handler::filename (void) const
{
return this->filename_;
}
int
HTTP_Connector::connect (const char * url)
{
char host[BUFSIZ];
u_short port;
char path[BUFSIZ];
if (this->parseurl (url, host, &port, path) == -1)
{
ACE_DEBUG ((LM_DEBUG,
"HTTP_Connector, error parsing url: %s\n",
url));
return -1;
}
HTTP_Handler hh (path);
HTTP_Handler *hhptr = &hh;
// First check the cache.
if (ACE_Filecache::instance ()->find (ACE_TEXT_CHAR_TO_TCHAR (hh.filename ())) == 0)
{
ACE_DEBUG ((LM_DEBUG, " ``%s'' is already cached.\n",
hh.filename ()));
return 0;
}
return this->connector_.connect (hhptr, ACE_INET_Addr (port, host));
}
#define DEFAULT_SERVER_PORT 80
// extract the main components of a URL
int
HTTP_Connector::parseurl (const char *url,
char *host,
u_short *port,
char *path)
{
int status = 0;
// hackish, but useful
if (3 != ::sscanf (url, "http://%[^:/]:%hu%s", host, port, path))
{
if (2 != ::sscanf (url, "http://%[^:/]:%hu", host, port))
{
if (2 != ::sscanf (url, "http://%[^:/]%s", host, path))
{
if (1 != ::sscanf (url, "http://%[^:/]", host))
status = -1;
else
{
*port = DEFAULT_SERVER_PORT;
ACE_OS::strcpy (path, "/");
}
}
else
*port = DEFAULT_SERVER_PORT;
}
else ACE_OS::strcpy (path, "/");
}
// 0 => success
// -1 => error
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -