Cleanup ACE_HAS_PTHREAD_SIGMASK_PROTOTYPE, all platforms support it so far as I can...
[ACE_TAO.git] / ACE / apps / JAWS2 / HTTPU / http_base.cpp
blob7af172025ad060d76ed23518fb51b17a1c580ae9
1 #include "JAWS/Parse_Headers.h"
2 #include "HTTPU/http_base.h"
3 #include "HTTPU/http_headers.h"
5 int
6 HTTP_Base::receive (ACE_Message_Block &mb)
8 if (this->line () == 0)
10 if (this->extract_line (mb) == 0)
11 return 0;
12 if (this->status () != STATUS_OK)
13 return 1;
15 // Call into the receive hook.
16 this->parse_line ();
17 if (this->status_ == STATUS_INTERNAL_SERVER_ERROR || this->no_headers_)
18 return 1;
21 // Parse 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:
28 break;
30 case JAWS_Header_Info::STATUS_CODE_NO_MEMORY:
31 case JAWS_Header_Info::STATUS_CODE_TOO_LONG:
32 default:
33 this->status_ = STATUS_INTERNAL_SERVER_ERROR;
34 break;
37 return ret;
40 int
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
47 // message block.
48 if (this->mb_ == 0)
50 // Make our Message Block big enough to hold a header name and
51 // header value
52 this->mb_ = new ACE_Message_Block (16384); // MAGIC! 2 x 8192
53 if (this->mb_ == 0)
55 this->status_ = STATUS_INTERNAL_SERVER_ERROR;
56 return -1;
59 // Call into the deliver hook
60 int r = this->espouse_line ();
61 if (r == -1)
62 return -1;
64 if (r == 1)
65 this->deliver_state_ = 2;
67 this->iter_.first ();
70 while (this->deliver_state_ < 3)
72 // Deliver whatever is currently held in this->mb_.
73 size_t sz = (mb.space () < this->mb_->length ()
74 ? mb.space ()
75 : this->mb_->length ());
77 if (sz > 0)
79 mb.copy (this->mb_->rd_ptr (), sz);
80 this->mb_->rd_ptr (sz);
83 if (mb.space () == 0)
84 return 0;
86 // Arriving here means this->mb_ has been emptied.
87 this->mb_->crunch ();
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);
93 break;
95 case 1: // Deliver a header value
96 this->deliver_state_ = this->deliver_header_value (data);
97 break;
99 case 2: // Finished!
100 delete this->mb_;
101 this->mb_ = 0;
102 this->deliver_state_ = 3;
106 return 1;
110 HTTP_Base::receive_payload (ACE_Message_Block &mb)
112 int result = 0;
114 if (this->payload_.space () < mb.length ())
115 result = this->payload_.size (this->payload_.size () +
116 mb.length () - this->payload_.space ());
118 if (result == 0)
120 this->payload_.copy (mb.rd_ptr (), mb.length ());
121 mb.rd_ptr (mb.wr_ptr ());
122 mb.crunch ();
124 else
125 this->status_ = STATUS_INTERNAL_SERVER_ERROR;
127 return result;
131 HTTP_Base::receive_payload (ACE_Message_Block &mb, long length)
133 int result = 0;
135 if (length == -1)
136 return this->receive_payload (mb);
138 if (this->payload_.size () < (unsigned long) length)
139 result = this->payload_.size (length);
141 if (result == -1)
143 this->status_ = STATUS_INTERNAL_SERVER_ERROR;
144 return -1;
147 if (this->payload_.space () >= mb.length ())
149 this->payload_.copy (mb.rd_ptr (), mb.length ());
150 mb.rd_ptr (mb.wr_ptr ());
151 mb.crunch ();
153 else
155 size_t space = this->payload_.space ();
156 this->payload_.copy (mb.rd_ptr (), space);
157 mb.rd_ptr (space);
160 return this->payload_.length () == (unsigned long) length;
163 const char *
164 HTTP_Base::payload ()
166 return this->payload_.rd_ptr ();
169 unsigned long
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);
182 iter.first ();
183 while (! iter.done ())
185 data = iter.next ();
186 if (data == 0)
188 iter.advance ();
189 continue;
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 ());
198 if (data2 != 0)
200 if (data->header_type () == HTTP_HCodes::APPENDTO_HEADER)
202 // Append to existing header
203 size_t len
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];
208 if (buf == 0)
210 this->status_ = STATUS_INTERNAL_SERVER_ERROR;
211 return -1;
213 ACE_OS::sprintf (buf, "%s, %s",
214 data2->header_value (),
215 data->header_value ());
216 data2->header_value (buf);
217 delete [] buf;
220 // Only insert if it isn't already present
221 iter.advance ();
222 continue;
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;
232 return -1;
234 this->headers ()->insert (data2);
236 iter.advance ();
239 return 0;
243 HTTP_Base::deliver_header_name (JAWS_Header_Data *&data)
245 data = 0;
247 for (;;)
249 if ((data = this->iter_.next ()) == 0)
251 // No more headers, deliver final "\r\n"
252 this->mb_->copy ("\r\n", 2);
253 return 2;
256 if (data->header_name ())
257 break;
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);
267 return 1;
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 ();
282 return 0;
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 ())
292 return 0;
294 this->status_ = STATUS_OK;
296 *p = '\0';
297 if (p[-1] == '\r')
298 p[-1] = '\0';
300 this->line_ = ACE_OS::strdup (mb.rd_ptr ());
301 if (this->line_ == 0)
302 this->status_ = STATUS_INTERNAL_SERVER_ERROR;
304 mb.rd_ptr (p+1);
305 this->info_.end_of_line (1);
306 return 1;
309 void
310 HTTP_Base::dump ()
312 ACE_DEBUG ((LM_DEBUG, "%s\n", this->line ()));
313 this->info_.dump ();
314 ACE_DEBUG ((LM_DEBUG, "STATUS IS %d %s\n",
315 this->status (),
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 */