Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / apps / JAWS / server / JAWS_IO.cpp
blob9699073850bd02ef9fe430a55b025df93a42b316
1 #include "ace/OS_NS_string.h"
2 #include "ace/OS_NS_sys_uio.h"
3 #include "ace/OS_NS_sys_socket.h"
4 #include "ace/Message_Block.h"
5 #include "ace/Min_Max.h"
6 #include "ace/SOCK_Stream.h"
7 #include "ace/Filecache.h"
8 #include "JAWS_IO.h"
9 #include "HTTP_Helpers.h"
11 #include "ace/OS_NS_fcntl.h"
12 #include "ace/OS_NS_unistd.h"
13 #include "ace/OS_NS_sys_stat.h"
14 #include "ace/Basic_Types.h"
15 #include <memory>
17 JAWS_IO::JAWS_IO ()
18 : handler_ (0)
22 JAWS_IO::~JAWS_IO ()
26 void
27 JAWS_IO::handler (JAWS_IO_Handler *handler)
29 this->handler_ = handler;
32 JAWS_IO_Handler::~JAWS_IO_Handler ()
36 JAWS_Synch_IO::JAWS_Synch_IO ()
37 : handle_ (ACE_INVALID_HANDLE)
41 JAWS_Synch_IO::~JAWS_Synch_IO ()
43 ACE_OS::closesocket (this->handle_);
46 ACE_HANDLE
47 JAWS_Synch_IO::handle () const
49 return this->handle_;
52 void
53 JAWS_Synch_IO::handle (ACE_HANDLE handle)
55 this->handle_ = handle;
58 void
59 JAWS_Synch_IO::read (ACE_Message_Block &mb,
60 int size)
62 ACE_SOCK_Stream stream;
63 stream.set_handle (this->handle_);
64 int result = stream.recv (mb.wr_ptr (), size);
66 if (result <= 0)
67 this->handler_->read_error ();
68 else
70 mb.wr_ptr (result);
71 this->handler_->read_complete (mb);
75 void
76 JAWS_Synch_IO::receive_file (const char *filename,
77 void *initial_data,
78 int initial_data_length,
79 int entire_length)
81 ACE_Filecache_Handle handle (ACE_TEXT_CHAR_TO_TCHAR (filename), entire_length);
83 int result = handle.error ();
85 if (result == ACE_Filecache_Handle::ACE_SUCCESS)
87 ACE_SOCK_Stream stream;
88 stream.set_handle (this->handle_);
90 int bytes_to_memcpy = ACE_MIN (entire_length, initial_data_length);
91 ACE_OS::memcpy (handle.address (), initial_data, bytes_to_memcpy);
93 int bytes_to_read = entire_length - bytes_to_memcpy;
95 int bytes = stream.recv_n ((char *) handle.address () + initial_data_length,
96 bytes_to_read);
97 if (bytes == bytes_to_read)
98 this->handler_->receive_file_complete ();
99 else
100 result = -1;
103 if (result != ACE_Filecache_Handle::ACE_SUCCESS)
104 this->handler_->receive_file_error (result);
107 void
108 JAWS_Synch_IO::transmit_file (const char *filename,
109 const char *header,
110 int header_size,
111 const char *trailer,
112 int trailer_size)
114 ACE_Filecache_Handle handle (ACE_TEXT_CHAR_TO_TCHAR (filename));
116 int result = handle.error ();
118 if (result == ACE_Filecache_Handle::ACE_SUCCESS)
120 #if defined (ACE_JAWS_BASELINE) || defined (ACE_WIN32)
121 ACE_SOCK_Stream stream;
122 stream.set_handle (this->handle_);
124 if ((stream.send_n (header, header_size) == header_size)
125 && (stream.send_n (handle.address (), handle.size ())
126 == handle.size ())
127 && (stream.send_n (trailer, trailer_size) == trailer_size))
128 this->handler_->transmit_file_complete ();
129 else
130 result = -1;
131 #else
132 // Attempting to use writev
133 // Is this faster?
134 iovec iov[3];
135 int iovcnt = 0;
136 if (header_size > 0)
138 iov[iovcnt].iov_base = const_cast<char*> (header);
139 iov[iovcnt].iov_len = header_size;
140 iovcnt++;
142 if (handle.size () > 0)
144 iov[iovcnt].iov_base = reinterpret_cast<char*> (handle.address ());
145 iov[iovcnt].iov_len = handle.size ();
146 iovcnt++;
148 if (trailer_size > 0)
150 iov[iovcnt].iov_base = const_cast<char*> (trailer);
151 iov[iovcnt].iov_len = trailer_size;
152 iovcnt++;
154 if (ACE_OS::writev (this->handle_, iov, iovcnt) < 0)
155 result = -1;
156 else
157 this->handler_->transmit_file_complete ();
158 #endif /* ACE_JAWS_BASELINE */
161 if (result != ACE_Filecache_Handle::ACE_SUCCESS)
162 this->handler_->transmit_file_error (result);
165 void
166 JAWS_Synch_IO::send_confirmation_message (const char *buffer,
167 int length)
169 this->send_message (buffer, length);
170 this->handler_->confirmation_message_complete ();
173 void
174 JAWS_Synch_IO::send_error_message (const char *buffer,
175 int length)
177 this->send_message (buffer, length);
178 this->handler_->error_message_complete ();
181 void
182 JAWS_Synch_IO::send_message (const char *buffer,
183 int length)
185 ACE_SOCK_Stream stream;
186 stream.set_handle (this->handle_);
187 stream.send_n (buffer, length);
190 // This only works on Win32
191 #if defined (ACE_HAS_WIN32_OVERLAPPED_IO)
193 JAWS_Asynch_IO::JAWS_Asynch_IO ()
197 JAWS_Asynch_IO::~JAWS_Asynch_IO ()
199 ACE_OS::closesocket (this->handle_);
202 void
203 JAWS_Asynch_IO::read (ACE_Message_Block& mb,
204 int size)
206 ACE_Asynch_Read_Stream ar;
208 if (ar.open (*this, this->handle_) == -1
209 || ar.read (mb, size) == -1)
210 this->handler_->read_error ();
213 // This method will be called when an asynchronous read completes on a
214 // stream.
216 void
217 JAWS_Asynch_IO::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
219 // This callback is for this->receive_file()
220 if (result.act () != 0)
222 int code = 0;
223 if (result.success () && result.bytes_transferred () != 0)
225 if (result.message_block ().length () == result.message_block ().size ())
226 code = ACE_Filecache_Handle::ACE_SUCCESS;
227 else
229 ACE_Asynch_Read_Stream ar;
230 if (ar.open (*this, this->handle_) == -1
231 || ar.read (result.message_block (),
232 result.message_block ().size () - result.message_block ().length (),
233 result.act ()) == -1)
234 code = -1;
235 else
236 return;
239 else
240 code = -1;
242 if (code == ACE_Filecache_Handle::ACE_SUCCESS)
243 this->handler_->receive_file_complete ();
244 else
245 this->handler_->receive_file_error (code);
247 delete &result.message_block ();
248 delete (ACE_Filecache_Handle *) result.act ();
250 else
252 // This callback is for this->read()
253 if (result.success ()
254 && result.bytes_transferred () != 0)
255 this->handler_->read_complete (result.message_block ());
256 else
257 this->handler_->read_error ();
261 void
262 JAWS_Asynch_IO::receive_file (const char *filename,
263 void *initial_data,
264 int initial_data_length,
265 int entire_length)
267 ACE_Message_Block *mb = 0;
268 ACE_Filecache_Handle *handle;
270 ACE_NEW (handle, ACE_Filecache_Handle (filename, entire_length, ACE_NOMAP));
272 int result = handle->error ();
274 if (result == ACE_Filecache_Handle::ACE_SUCCESS)
276 ACE_OS::memcpy (handle->address (),
277 initial_data,
278 initial_data_length);
280 int bytes_to_read = entire_length - initial_data_length;
282 ACE_NEW (mb, ACE_Message_Block ((char *)handle->address ()
283 + initial_data_length, bytes_to_read));
285 if (mb == 0)
287 errno = ENOMEM;
288 result = -1;
290 else
292 ACE_Asynch_Read_Stream ar;
294 if (ar.open (*this, this->handle_) == -1
295 || ar.read (*mb, mb->size () - mb->length (), handle) == -1)
296 result = -1;
300 if (result != ACE_Filecache_Handle::ACE_SUCCESS)
302 this->handler_->receive_file_error (result);
303 delete mb;
304 delete handle;
308 void
309 JAWS_Asynch_IO::transmit_file (const char *filename,
310 const char *header,
311 int header_size,
312 const char *trailer,
313 int trailer_size)
315 ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer = 0;
316 ACE_Filecache_Handle *handle = new ACE_Filecache_Handle (filename, ACE_NOMAP);
318 int result = handle->error ();
320 if (result == ACE_Filecache_Handle::ACE_SUCCESS)
322 ACE_Message_Block header_mb (header, header_size);
323 ACE_Message_Block trailer_mb (trailer, trailer_size);
325 header_and_trailer = new ACE_Asynch_Transmit_File::Header_And_Trailer
326 (&header_mb, header_size, &trailer_mb, trailer_size);
328 ACE_Asynch_Transmit_File tf;
330 if (tf.open (*this, this->handle_) == -1
331 || tf.transmit_file (handle->handle (), // file handle
332 header_and_trailer, // header and trailer data
333 0, // bytes_to_write
334 0, // offset
335 0, // offset_high
336 0, // bytes_per_send
337 0, // flags
338 handle // act
339 ) == -1)
340 result = -1;
343 if (result != ACE_Filecache_Handle::ACE_SUCCESS)
345 this->handler_->transmit_file_error (result);
346 delete header_and_trailer;
347 delete handle;
352 // This method will be called when an asynchronous transmit file completes.
353 void
354 JAWS_Asynch_IO::handle_transmit_file (const ACE_Asynch_Transmit_File::Result &result)
356 if (result.success ())
357 this->handler_->transmit_file_complete ();
358 else
359 this->handler_->transmit_file_error (-1);
361 delete result.header_and_trailer ();
362 delete (ACE_Filecache_Handle *) result.act ();
365 void
366 JAWS_Asynch_IO::send_confirmation_message (const char *buffer,
367 int length)
369 this->send_message (buffer, length, CONFORMATION);
372 void
373 JAWS_Asynch_IO::send_error_message (const char *buffer,
374 int length)
376 this->send_message (buffer, length, ERROR_MESSAGE);
379 void
380 JAWS_Asynch_IO::send_message (const char *buffer,
381 int length,
382 int act)
384 ACE_Message_Block *mb = 0;
385 ACE_NEW (mb, ACE_Message_Block (buffer, length));
387 if (mb == 0)
389 this->handler_->error_message_complete ();
390 return;
393 ACE_Asynch_Write_Stream aw;
394 if (aw.open (*this, this->handle_) == -1
395 || aw.write (*mb, length, (void *) static_cast<intptr_t> (act)) == -1)
397 mb->release ();
399 if (act == CONFORMATION)
400 this->handler_->confirmation_message_complete ();
401 else
402 this->handler_->error_message_complete ();
406 void
407 JAWS_Asynch_IO::handle_write_stream (const ACE_Asynch_Write_Stream::Result &result)
409 result.message_block ().release ();
411 if (result.act () == (void *) CONFORMATION)
412 this->handler_->confirmation_message_complete ();
413 else
414 this->handler_->error_message_complete ();
417 #endif /* ACE_HAS_WIN32_OVERLAPPED_IO */
419 //-------------------Adding SYNCH IO no Caching
421 JAWS_Synch_IO_No_Cache::JAWS_Synch_IO_No_Cache ()
422 : handle_ (ACE_INVALID_HANDLE)
426 JAWS_Synch_IO_No_Cache::~JAWS_Synch_IO_No_Cache ()
428 ACE_OS::closesocket (this->handle_);
431 ACE_HANDLE
432 JAWS_Synch_IO_No_Cache::handle () const
434 return this->handle_;
437 void
438 JAWS_Synch_IO_No_Cache::handle (ACE_HANDLE handle)
440 this->handle_ = handle;
443 void
444 JAWS_Synch_IO_No_Cache::read (ACE_Message_Block &mb, int size)
446 ACE_SOCK_Stream stream;
447 stream.set_handle (this->handle_);
448 int result = stream.recv (mb.wr_ptr (), size);
450 if (result <= 0)
451 this->handler_->read_error ();
452 else
454 mb.wr_ptr (result);
455 this->handler_->read_complete (mb);
459 void
460 JAWS_Synch_IO_No_Cache::receive_file (const char *,
461 void *,
462 int,
463 int)
465 //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN
466 this->handler_->receive_file_error (5);
469 void
470 JAWS_Synch_IO_No_Cache::transmit_file (const char *filename,
471 const char *header,
472 int header_size,
473 const char *trailer,
474 int trailer_size)
476 int result = 0;
478 // Can we access the file?
479 if (ACE_OS::access (filename, R_OK) == -1)
481 //ugly hack to send in HTTP_Status_Code::STATUS_NOT_FOUND
482 result = ACE_Filecache_Handle::ACE_ACCESS_FAILED;
483 this->handler_->transmit_file_error (result);
484 return;
487 ACE_stat stat;
489 // Can we stat the file?
490 if (ACE_OS::stat (filename, &stat) == -1)
492 //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN
493 result = ACE_Filecache_Handle::ACE_STAT_FAILED;
494 this->handler_->transmit_file_error (result);
495 return;
498 ACE_OFF_T size = stat.st_size;
500 // Can we open the file?
501 ACE_HANDLE handle = ACE_OS::open (filename, O_RDONLY);
502 if (handle == ACE_INVALID_HANDLE)
504 //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN
505 result = ACE_Filecache_Handle::ACE_OPEN_FAILED;
506 this->handler_->transmit_file_error (result);
507 return;
510 char* f = new char[size];
511 std::unique_ptr<char[]> file (f);
513 ACE_OS::read_n (handle, f, size);
515 ACE_SOCK_Stream stream;
516 stream.set_handle (this->handle_);
518 if ((stream.send_n (header, header_size) == header_size)
519 && (stream.send_n (f, size) == size)
520 && (stream.send_n (trailer, trailer_size) == trailer_size))
522 this->handler_->transmit_file_complete ();
524 else
526 //ugly hack to default to HTTP_Status_Code::STATUS_INTERNAL_SERVER_ERROR
527 result = -1;
528 this->handler_->transmit_file_error (result);
531 ACE_OS::close (handle);
534 void
535 JAWS_Synch_IO_No_Cache::send_confirmation_message (const char *buffer,
536 int length)
538 this->send_message (buffer, length);
539 this->handler_->confirmation_message_complete ();
542 void
543 JAWS_Synch_IO_No_Cache::send_error_message (const char *buffer, int length)
545 this->send_message (buffer, length);
546 this->handler_->error_message_complete ();
549 void
550 JAWS_Synch_IO_No_Cache::send_message (const char *buffer, int length)
552 ACE_SOCK_Stream stream;
553 stream.set_handle (this->handle_);
554 stream.send_n (buffer, length);