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"
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"
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_
);
47 JAWS_Synch_IO::handle () const
53 JAWS_Synch_IO::handle (ACE_HANDLE handle
)
55 this->handle_
= handle
;
59 JAWS_Synch_IO::read (ACE_Message_Block
&mb
,
62 ACE_SOCK_Stream stream
;
63 stream
.set_handle (this->handle_
);
64 int result
= stream
.recv (mb
.wr_ptr (), size
);
67 this->handler_
->read_error ();
71 this->handler_
->read_complete (mb
);
76 JAWS_Synch_IO::receive_file (const char *filename
,
78 int initial_data_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
,
97 if (bytes
== bytes_to_read
)
98 this->handler_
->receive_file_complete ();
103 if (result
!= ACE_Filecache_Handle::ACE_SUCCESS
)
104 this->handler_
->receive_file_error (result
);
108 JAWS_Synch_IO::transmit_file (const char *filename
,
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 ())
127 && (stream
.send_n (trailer
, trailer_size
) == trailer_size
))
128 this->handler_
->transmit_file_complete ();
132 // Attempting to use writev
138 iov
[iovcnt
].iov_base
= const_cast<char*> (header
);
139 iov
[iovcnt
].iov_len
= header_size
;
142 if (handle
.size () > 0)
144 iov
[iovcnt
].iov_base
= reinterpret_cast<char*> (handle
.address ());
145 iov
[iovcnt
].iov_len
= handle
.size ();
148 if (trailer_size
> 0)
150 iov
[iovcnt
].iov_base
= const_cast<char*> (trailer
);
151 iov
[iovcnt
].iov_len
= trailer_size
;
154 if (ACE_OS::writev (this->handle_
, iov
, iovcnt
) < 0)
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
);
166 JAWS_Synch_IO::send_confirmation_message (const char *buffer
,
169 this->send_message (buffer
, length
);
170 this->handler_
->confirmation_message_complete ();
174 JAWS_Synch_IO::send_error_message (const char *buffer
,
177 this->send_message (buffer
, length
);
178 this->handler_
->error_message_complete ();
182 JAWS_Synch_IO::send_message (const char *buffer
,
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_
);
203 JAWS_Asynch_IO::read (ACE_Message_Block
& mb
,
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
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)
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
;
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)
242 if (code
== ACE_Filecache_Handle::ACE_SUCCESS
)
243 this->handler_
->receive_file_complete ();
245 this->handler_
->receive_file_error (code
);
247 delete &result
.message_block ();
248 delete (ACE_Filecache_Handle
*) result
.act ();
252 // This callback is for this->read()
253 if (result
.success ()
254 && result
.bytes_transferred () != 0)
255 this->handler_
->read_complete (result
.message_block ());
257 this->handler_
->read_error ();
262 JAWS_Asynch_IO::receive_file (const char *filename
,
264 int initial_data_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 (),
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
));
292 ACE_Asynch_Read_Stream ar
;
294 if (ar
.open (*this, this->handle_
) == -1
295 || ar
.read (*mb
, mb
->size () - mb
->length (), handle
) == -1)
300 if (result
!= ACE_Filecache_Handle::ACE_SUCCESS
)
302 this->handler_
->receive_file_error (result
);
309 JAWS_Asynch_IO::transmit_file (const char *filename
,
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
343 if (result
!= ACE_Filecache_Handle::ACE_SUCCESS
)
345 this->handler_
->transmit_file_error (result
);
346 delete header_and_trailer
;
352 // This method will be called when an asynchronous transmit file completes.
354 JAWS_Asynch_IO::handle_transmit_file (const ACE_Asynch_Transmit_File::Result
&result
)
356 if (result
.success ())
357 this->handler_
->transmit_file_complete ();
359 this->handler_
->transmit_file_error (-1);
361 delete result
.header_and_trailer ();
362 delete (ACE_Filecache_Handle
*) result
.act ();
366 JAWS_Asynch_IO::send_confirmation_message (const char *buffer
,
369 this->send_message (buffer
, length
, CONFORMATION
);
373 JAWS_Asynch_IO::send_error_message (const char *buffer
,
376 this->send_message (buffer
, length
, ERROR_MESSAGE
);
380 JAWS_Asynch_IO::send_message (const char *buffer
,
384 ACE_Message_Block
*mb
= 0;
385 ACE_NEW (mb
, ACE_Message_Block (buffer
, length
));
389 this->handler_
->error_message_complete ();
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)
399 if (act
== CONFORMATION
)
400 this->handler_
->confirmation_message_complete ();
402 this->handler_
->error_message_complete ();
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 ();
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_
);
432 JAWS_Synch_IO_No_Cache::handle () const
434 return this->handle_
;
438 JAWS_Synch_IO_No_Cache::handle (ACE_HANDLE handle
)
440 this->handle_
= handle
;
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
);
451 this->handler_
->read_error ();
455 this->handler_
->read_complete (mb
);
460 JAWS_Synch_IO_No_Cache::receive_file (const char *,
465 //ugly hack to send HTTP_Status_Code::STATUS_FORBIDDEN
466 this->handler_
->receive_file_error (5);
470 JAWS_Synch_IO_No_Cache::transmit_file (const char *filename
,
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
);
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
);
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
);
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 ();
526 //ugly hack to default to HTTP_Status_Code::STATUS_INTERNAL_SERVER_ERROR
528 this->handler_
->transmit_file_error (result
);
531 ACE_OS::close (handle
);
535 JAWS_Synch_IO_No_Cache::send_confirmation_message (const char *buffer
,
538 this->send_message (buffer
, length
);
539 this->handler_
->confirmation_message_complete ();
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 ();
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
);