📄 htbp_inside_squid_filter.cpp
字号:
// ACE_HTBP_Filter.cpp
// $Id: HTBP_Inside_Squid_Filter.cpp 80826 2008-03-04 14:51:23Z wotte $
#include "ace/Log_Msg.h"
//#include <sstream>
#include "HTBP_Session.h"
#include "HTBP_Inside_Squid_Filter.h"
#if !defined (__ACE_INLINE__)
#include "HTBP_Inside_Squid_Filter.inl"
#endif
ACE_RCSID(HTBP,ACE_HTBP_Inside_Squid_Filter,"$Id: HTBP_Inside_Squid_Filter.cpp 80826 2008-03-04 14:51:23Z wotte $")
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ssize_t
ACE::HTBP::Inside_Squid_Filter::send_data_trailer (ACE::HTBP::Channel *ch)
{
ch->state(ACE::HTBP::Channel::Wait_For_Ack);
return 0;
}
int
ACE::HTBP::Inside_Squid_Filter::make_request_header (ACE::HTBP::Channel *ch,
const char *cmd,
char *buffer,
size_t buffer_size)
{
// the string is formatted as:
// command http://host:port/htid/sessionId/request<requestId>.html HTTP/1.1\n
// host:port is the remote host and port from the channel,
// htid is the local endpoint identifier
// sessionId is the discreet session counter between these peers
// requestId is the discreet request sent for this session.
ACE::HTBP::Session *session = ch->session();
const char * format = "%shttp://%s:%d/%s/%d/request%d.html HTTP/1.1\n";
char remote_host[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
unsigned remote_port = session->peer_addr().get_port_number();
const char *local_htid = session->local_addr().get_htid();
ACE_UINT32 tempId = session->session_id().id_;
size_t sid_size = 1;
size_t rid_size = 1;
while (tempId /= 10) sid_size++;
tempId = ch->request_count();
while (tempId /= 10) rid_size++;
// This test was originally get_host_name() == -1, but this is
// problematic if the address doesn't resolve to a name. I think
// that it should be configurable, or maybe the hostname needs to
// be carried independent of the address to work with hosts that may
// have dynamic IP addresses. For now that isn't a problem.
if (session->peer_addr().get_host_addr(remote_host,
sizeof remote_host) == 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("HTBP::Inside_Squid_Filter:could not get ")
ACE_TEXT("peer_addr hostname\n")),
-1);
size_t size =
ACE_OS::strlen(format)
- 12 // subtract out the size of the format specifiers
+ ACE_OS::strlen (cmd)
+ ACE_OS::strlen (remote_host)
+ 5 // maximum size for a the remote port number
+ ACE_OS::strlen (local_htid)
+ sid_size // size of session id
+ rid_size; // size of request id
if (size > buffer_size)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("HTBP::Inside_Squid_Filter: insufficient ")
ACE_TEXT("buffer space for request header, need %d ")
ACE_TEXT("got %d\n"),
size, buffer_size),
-1);
ACE_OS::sprintf (buffer,format,
cmd,remote_host,remote_port,
local_htid, session->session_id().id_,
ch->request_count());
return ACE_OS::strlen(buffer);
}
ssize_t
ACE::HTBP::Inside_Squid_Filter::send_data_header (ssize_t data_len,
ACE::HTBP::Channel *ch)
{
char *buffer = new char[BUFSIZ];
ssize_t result = -1;
if (this->make_request_header (ch,"POST ",buffer,BUFSIZ) != -1)
{
ACE_CString header (buffer);
header += "Content-Type: application/octet-stream\nContent-Length: ";
char datalenstr[20];
ACE_OS::itoa (data_len,datalenstr,10);
header += datalenstr;
header += "\n\n";
result = ch->ace_stream().send(header.c_str(),header.length());
}
ch->state(result == -1 ? ACE::HTBP::Channel::Closed :
ACE::HTBP::Channel::Header_Sent);
this->reset_http_code();
return 1;
}
ssize_t
ACE::HTBP::Inside_Squid_Filter::recv_data_header (ACE::HTBP::Channel *ch)
{
if (this->http_code() != 200 && this->http_code() != 0)
{
if (ACE::debug())
ACE_ERROR ((LM_ERROR,
ACE_TEXT("HTBP::Inside_Squid_Filter::recv_data_header, ")
ACE_TEXT("non-OK result code %d recvd\n"),
this->http_code()));
errno = ch->consume_error () ? EINVAL : EWOULDBLOCK;
return 0;
}
char *header_end = this->header_complete(ch);
if (header_end == 0)
{
if (ch->state() != ACE::HTBP::Channel::Closed)
{
ch->state (ACE::HTBP::Channel::Header_Pending);
errno = EWOULDBLOCK;
}
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("HTBP::Inside_Squid_Filter::")
ACE_TEXT("recv_data_header, ")
ACE_TEXT("header not complete\n")),
0);
}
char *start = ch->leftovers().rd_ptr();
ACE_CString token = "Content-Length: ";
char *tpos = ACE_OS::strstr(start,token.c_str());
char *nl = ACE_OS::strchr (start,'\n');
if (tpos != 0)
{
tpos += token.length();
*nl = 0;
ch->data_len (ACE_OS::strtol(tpos,0,10));
start = nl+1;
}
ch->leftovers().rd_ptr(header_end);
if (this->http_code() != 200)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT("HTBP::Inside_Squid_Filter::recv_data_header, ")
ACE_TEXT("non-OK result code %d recvd\n"),
this->http_code()));
errno = ch->consume_error () ? EINVAL : EWOULDBLOCK;
return 0;
}
ch->state(ACE::HTBP::Channel::Data_Queued);
return 1;
}
ssize_t
ACE::HTBP::Inside_Squid_Filter::recv_data_trailer (ACE::HTBP::Channel *ch)
{
ch->state(ACE::HTBP::Channel::Send_Ack);
return 0;
}
int
ACE::HTBP::Inside_Squid_Filter::send_ack (ACE::HTBP::Channel *ch)
{
char *buffer = new char[BUFSIZ];
ssize_t result = -1;
if (ch->state() == ACE::HTBP::Channel::Ack_Sent)
{
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("HTBP::Inside Filter::send_ack: ")
ACE_TEXT("state is already ACK_SENT\n")),
1);
}
if (this->make_request_header (ch,"GET ",buffer,BUFSIZ) != -1)
{
ACE_CString header (buffer);
header += "\n";
result = ch->ace_stream().send(header.c_str(),header.length());
}
ch->state(result == -1 ?
ACE::HTBP::Channel::Closed : ACE::HTBP::Channel::Ack_Sent);
this->reset_http_code();
return 1;
}
int
ACE::HTBP::Inside_Squid_Filter::recv_ack (ACE::HTBP::Channel *ch)
{
char *header_end = this->header_complete(ch);
if (header_end == 0)
{
if (ch->state() != ACE::HTBP::Channel::Closed)
errno = EWOULDBLOCK;
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT("HTBP::Inside_Squid_Filter::")
ACE_TEXT("recv_data_header, ")
ACE_TEXT("header not complete\n")),0);
}
if (this->http_code() == 200)
{
ch->leftovers().length(0);
ch->state(ACE::HTBP::Channel::Ready);
return 1;
}
char *start = ch->leftovers().rd_ptr();
ACE_CString token = "Content-Length: ";
char *tpos = ACE_OS::strstr(start,token.c_str());
char *nl = ACE_OS::strchr (start,'\n');
if (tpos != 0)
{
tpos += token.length();
*nl = 0;
ch->data_len (ACE_OS::strtol(tpos,0,10));
start = nl+1;
}
ch->leftovers().rd_ptr(header_end);
errno = ch->consume_error () ? EINVAL : EWOULDBLOCK;
return 0;
}
ACE_END_VERSIONED_NAMESPACE_DECL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -