summaryrefslogtreecommitdiff
path: root/trunk/ACE/protocols/ace/HTBP/HTBP_Outside_Squid_Filter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ACE/protocols/ace/HTBP/HTBP_Outside_Squid_Filter.cpp')
-rw-r--r--trunk/ACE/protocols/ace/HTBP/HTBP_Outside_Squid_Filter.cpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/trunk/ACE/protocols/ace/HTBP/HTBP_Outside_Squid_Filter.cpp b/trunk/ACE/protocols/ace/HTBP/HTBP_Outside_Squid_Filter.cpp
new file mode 100644
index 00000000000..05e79083794
--- /dev/null
+++ b/trunk/ACE/protocols/ace/HTBP/HTBP_Outside_Squid_Filter.cpp
@@ -0,0 +1,196 @@
+// ACE_HTBP_Outside_Squid_Filter.cpp
+// $Id$
+
+#include "ace/Log_Msg.h"
+
+#include "HTBP_Session.h"
+#include "HTBP_Outside_Squid_Filter.h"
+
+#if !defined (__ACE_INLINE__)
+#include "HTBP_Outside_Squid_Filter.inl"
+#endif
+
+ACE_RCSID(HTBP,
+ ACE_HTBP_Outside_Squid_Filter,
+ "$Id$")
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ssize_t
+ACE::HTBP::Outside_Squid_Filter::recv_data_header (ACE::HTBP::Channel *ch)
+{
+ // on the outside of the firewall, this method must do the details
+ // necessary to call replace_session or whatever to migrate the sock
+ // stream to the appropriate ACE::HTBP::Channel, then to finally
+ // assign the right filter to that stream. That filter will an
+ // ACE::HTBP::Outside_[Send|Recv]_Filter.
+
+ // in the case of an ACE::HTBP::Outside_Recv_Filter, the assigned
+ // filter must be a null filter first, with a replacement.
+
+ // recv header details
+ 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;
+ }
+ return 0;
+ }
+
+ char *start = ch->leftovers().rd_ptr();
+
+ int is_inbound = 0;
+ ACE_CString token ("POST ");
+ if (ACE_OS::strncmp (start,token.c_str(),token.length()) == 0)
+ is_inbound = 1;
+ else
+ {
+ token = "GET ";
+ if (ACE_OS::strncmp (start,
+ token.c_str(),
+ token.length()) != 0)
+ {
+ ch->leftovers().length(0);
+ errno = EINVAL;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE::HTBP::Outside_Squid_Filter::recv_data_header "
+ "bad request header\n"),0);
+ }
+ }
+ start += token.length();
+ // "http://" is stripped by squid, leaving only "/"
+ start += (ACE_OS::strncmp (start,"http://",7) == 0) ? 7 : 1;
+
+ // set up the actual session and stream
+ ACE::HTBP::Session_Id_t session_id;
+ char * slash = ACE_OS::strchr(start,'/');
+ char * nl = ACE_OS::strchr (start,'\n');
+ if (slash == 0)
+ {
+ ch->leftovers().length(0);
+ errno = EINVAL;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE::HTBP::Outside_Squid_Filter::recv_data_header "
+ "missing sender key\n"),0);
+ }
+ *slash = 0;
+ session_id.local_.string_to_addr (start);
+ start = slash+1;
+
+ slash = ACE_OS::strchr(start,'/');
+ if (slash == 0)
+ {
+ ch->leftovers().length(0);
+ errno = EINVAL;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE::HTBP::Outside_Squid_Filter::recv_data_header "
+ "missing sender key\n"),0);
+ }
+ *slash = 0;
+ session_id.peer_.string_to_addr (start);
+ start = slash + 1;
+
+ slash = ACE_OS::strchr(start,' ');
+ if (slash == 0)
+ {
+ ch->leftovers().length (0);
+ errno = EINVAL;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE::HTBP::Outside_Squid_Filter::recv_data_header "
+ "missing sender key"),0);
+ }
+ *slash = 0;
+ session_id.id_ = strtol(start,0,10);
+ start = slash + 1;
+
+ if (is_inbound)
+ {
+ token = "Content-Length: ";
+ char *tpos = ACE_OS::strstr(start,token.c_str());
+ if (tpos != 0)
+ {
+ nl = ACE_OS::strchr(tpos,'\n');
+ tpos += token.length();
+ *nl = 0;
+ ch->data_len(strtol(tpos,0,10));
+ start = nl+1;
+ }
+ }
+ ch->leftovers().rd_ptr(header_end);
+
+ ACE::HTBP::Session *session = 0;
+ if (ACE::HTBP::Session::find_session (session_id, session) == -1)
+ {
+ ACE_NEW_RETURN (session, ACE::HTBP::Session (session_id), 0);
+ if (ACE::HTBP::Session::add_session (session) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "ACE::HTBP::Outside_Squid_Filter::"
+ "recv_data_header %p",
+ "add_session"),0);
+ }
+ ch->session(session);
+
+ if (is_inbound)
+ {
+ ch->state(ACE::HTBP::Channel::Data_Queued);
+ session->inbound (ch);
+ }
+ else
+ {
+ ch->state(ACE::HTBP::Channel::Ready);
+ session->outbound (ch);
+ }
+ return 1;
+}
+
+ssize_t
+ACE::HTBP::Outside_Squid_Filter::recv_data_trailer (ACE::HTBP::Channel *ch)
+{
+ ch->state(ACE::HTBP::Channel::Send_Ack);
+ return 1;
+}
+
+int
+ACE::HTBP::Outside_Squid_Filter::send_ack (ACE::HTBP::Channel *ch)
+{
+ this->send_data_header (0,ch);
+ if (ch->state() == ACE::HTBP::Channel::Header_Sent)
+ ch->state(ACE::HTBP::Channel::Detached);
+ return 1;
+}
+
+ssize_t
+ACE::HTBP::Outside_Squid_Filter::send_data_header (ssize_t data_len,
+ ACE::HTBP::Channel *ch)
+{
+ ACE_CString header ("HTTP/1.1 200 OK\n"
+ "Content-Type: application/octet-stream\n"
+ "Content-Length: ");
+ char datalenstr[20];
+ ACE_OS::itoa (data_len,datalenstr,10);
+ header += datalenstr;
+ header += "\n\n";
+ ssize_t 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::Outside_Squid_Filter::send_data_trailer (ACE::HTBP::Channel *ch)
+{
+ ch->state(ACE::HTBP::Channel::Detached);
+ return 1;
+}
+
+int
+ACE::HTBP::Outside_Squid_Filter::recv_ack (ACE::HTBP::Channel *)
+{
+ return 1;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL