1 #include "JAWS/Parse_Headers.h"
2 #include "HTTPU/http_base.h"
3 #include "HTTPU/http_headers.h"
6 HTTP_Base::receive (ACE_Message_Block
&mb
)
8 if (this->line () == 0)
10 if (this->extract_line (mb
) == 0)
12 if (this->status () != STATUS_OK
)
15 // Call into the receive hook.
17 if (this->status_
== STATUS_INTERNAL_SERVER_ERROR
|| this->no_headers_
)
22 JAWS_Parse_Headers
*parser
= JAWS_Parse_Headers_Singleton::instance ();
23 int ret
= parser
->parse_headers (&(this->info_
), mb
);
25 switch (this->info_
.status ())
27 case JAWS_Header_Info::STATUS_CODE_OK
:
30 case JAWS_Header_Info::STATUS_CODE_NO_MEMORY
:
31 case JAWS_Header_Info::STATUS_CODE_TOO_LONG
:
33 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
41 HTTP_Base::deliver (ACE_Message_Block
&mb
)
43 JAWS_Header_Data
*data
= 0;
45 // Deliver this outgoing request.
46 // We do this by building the request up and writing it into the
50 // Make our Message Block big enough to hold a header name and
52 this->mb_
= new ACE_Message_Block (16384); // MAGIC! 2 x 8192
55 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
59 // Call into the deliver hook
60 int r
= this->espouse_line ();
65 this->deliver_state_
= 2;
70 while (this->deliver_state_
< 3)
72 // Deliver whatever is currently held in this->mb_.
73 size_t sz
= (mb
.space () < this->mb_
->length ()
75 : this->mb_
->length ());
79 mb
.copy (this->mb_
->rd_ptr (), sz
);
80 this->mb_
->rd_ptr (sz
);
86 // Arriving here means this->mb_ has been emptied.
89 switch (this->deliver_state_
)
91 case 0: // Obtain the next header data // Deliver a header name
92 this->deliver_state_
= this->deliver_header_name (data
);
95 case 1: // Deliver a header value
96 this->deliver_state_
= this->deliver_header_value (data
);
102 this->deliver_state_
= 3;
110 HTTP_Base::receive_payload (ACE_Message_Block
&mb
)
114 if (this->payload_
.space () < mb
.length ())
115 result
= this->payload_
.size (this->payload_
.size () +
116 mb
.length () - this->payload_
.space ());
120 this->payload_
.copy (mb
.rd_ptr (), mb
.length ());
121 mb
.rd_ptr (mb
.wr_ptr ());
125 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
131 HTTP_Base::receive_payload (ACE_Message_Block
&mb
, long length
)
136 return this->receive_payload (mb
);
138 if (this->payload_
.size () < (unsigned long) length
)
139 result
= this->payload_
.size (length
);
143 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
147 if (this->payload_
.space () >= mb
.length ())
149 this->payload_
.copy (mb
.rd_ptr (), mb
.length ());
150 mb
.rd_ptr (mb
.wr_ptr ());
155 size_t space
= this->payload_
.space ();
156 this->payload_
.copy (mb
.rd_ptr (), space
);
160 return this->payload_
.length () == (unsigned long) length
;
164 HTTP_Base::payload ()
166 return this->payload_
.rd_ptr ();
170 HTTP_Base::payload_size ()
172 return this->payload_
.length ();
176 HTTP_Base::build_headers (JAWS_Headers
*new_headers
)
178 JAWS_Header_Data
*data
= 0;
179 JAWS_Header_Data
*data2
= 0;
180 JAWS_Header_Table_Iterator
iter (*new_headers
);
183 while (! iter
.done ())
192 if (data
->header_type () == HTTP_HCodes::REPLACE_HEADER
)
193 this->headers ()->remove_all (data
->header_name ());
194 else if (data
->header_type () == HTTP_HCodes::INSERT_HEADER
195 || data
->header_type () == HTTP_HCodes::APPENDTO_HEADER
)
197 data2
= this->headers ()->find (data
->header_name ());
200 if (data
->header_type () == HTTP_HCodes::APPENDTO_HEADER
)
202 // Append to existing header
204 = ACE_OS::strlen (data
->header_value ())
205 + ACE_OS::strlen (data2
->header_value ())
206 + 3; /* for comma, space, and nul */
207 char *buf
= new char [len
];
210 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
213 ACE_OS::sprintf (buf
, "%s, %s",
214 data2
->header_value (),
215 data
->header_value ());
216 data2
->header_value (buf
);
220 // Only insert if it isn't already present
226 data2
= new JAWS_Header_Data (data
->header_name (),
227 data
->header_value ());
228 if (data2
== 0 || data2
->header_name () == 0
229 || data2
->header_value () == 0)
231 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
234 this->headers ()->insert (data2
);
243 HTTP_Base::deliver_header_name (JAWS_Header_Data
*&data
)
249 if ((data
= this->iter_
.next ()) == 0)
251 // No more headers, deliver final "\r\n"
252 this->mb_
->copy ("\r\n", 2);
256 if (data
->header_name ())
259 this->iter_
.advance ();
262 // Assume the following lines will always succeed.
263 this->mb_
->copy (data
->header_name ());
264 this->mb_
->wr_ptr (this->mb_
->wr_ptr () - 1);
265 this->mb_
->copy (": ", 2);
271 HTTP_Base::deliver_header_value (JAWS_Header_Data
*&data
)
273 // Assume the following line will always succeed.
274 if (data
->header_value ())
276 this->mb_
->copy (data
->header_value ());
277 this->mb_
->wr_ptr (this->mb_
->wr_ptr () - 1);
279 this->mb_
->copy ("\r\n", 2);
281 this->iter_
.advance ();
287 HTTP_Base::extract_line (ACE_Message_Block
&mb
)
289 JAWS_Parse_Headers
*parser
= JAWS_Parse_Headers_Singleton::instance ();
290 char *p
= parser
->skipset ("\n", mb
.rd_ptr (), mb
.wr_ptr ());
291 if (p
== mb
.wr_ptr ())
294 this->status_
= STATUS_OK
;
300 this->line_
= ACE_OS::strdup (mb
.rd_ptr ());
301 if (this->line_
== 0)
302 this->status_
= STATUS_INTERNAL_SERVER_ERROR
;
305 this->info_
.end_of_line (1);
312 ACE_DEBUG ((LM_DEBUG
, "%s\n", this->line ()));
314 ACE_DEBUG ((LM_DEBUG
, "STATUS IS %d %s\n",
316 (*HTTP_SCode::instance ())[this->status ()]));
319 #if !defined (ACE_HAS_INLINED_OSCALLS)
320 # include "HTTPU/http_base.inl"
321 # endif /* ACE_HAS_INLINED_OSCALLS */