1 /**
2  * Copyright 2010 Christian Liesch
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * @file
19  *
20  * @Author christian liesch <liesch@gmx.ch>
21  *
22  * Implementation of the HTTP Test Tool transport.
23  */
24 
25 /************************************************************************
26  * Includes
27  ***********************************************************************/
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <apr.h>
33 #include <apr_lib.h>
34 #include <apr_errno.h>
35 #include <apr_strings.h>
36 #include <apr_network_io.h>
37 #include <apr_thread_proc.h>
38 #include <apr_thread_cond.h>
39 #include <apr_thread_mutex.h>
40 #include <apr_portable.h>
41 #include <apr_hash.h>
42 #include <apr_base64.h>
43 #include <apr_hooks.h>
44 
45 
46 #include "defines.h"
47 #include "transport.h"
48 
49 /************************************************************************
50  * Definitions
51  ***********************************************************************/
52 struct transport_s {
53   void *data;
54   transport_os_desc_get_f os_desc_get;
55   transport_set_timeout_f set_timeout;
56   transport_get_timeout_f get_timeout;
57   transport_read_f read;
58   transport_write_f write;
59 };
60 
61 /************************************************************************
62  * Globals
63  ***********************************************************************/
64 
65 /************************************************************************
66  * Implementation
67  ***********************************************************************/
68 /**
69  * create transport object
70  * @param data IN custom data
71  * @param read IN read method
72  * @param write IN write method
73  * @return transport object
74  */
transport_new(void * data,apr_pool_t * pool,transport_os_desc_get_f os_desc_get,transport_set_timeout_f set_timeout,transport_get_timeout_f get_timeout,transport_read_f read,transport_write_f write)75 transport_t *transport_new(void *data,
76                            apr_pool_t *pool,
77                            transport_os_desc_get_f os_desc_get,
78                            transport_set_timeout_f set_timeout,
79                            transport_get_timeout_f get_timeout,
80                            transport_read_f read,
81 			   transport_write_f write) {
82   transport_t *hook = apr_pcalloc(pool, sizeof(*hook));
83 
84   hook->data = data;
85   hook->os_desc_get = os_desc_get;
86   hook->set_timeout = set_timeout;
87   hook->get_timeout = get_timeout;
88   hook->read = read;
89   hook->write = write;
90 
91   return hook;
92 }
93 
94 /**
95  * set new user data
96  * @param hook IN transport hook
97  * @param data IN new user data
98  * @return APR_SUCCESS, APR_NOSOCK if no transport hook or any apr status
99  */
transport_set_data(transport_t * hook,void * data)100 apr_status_t transport_set_data(transport_t *hook, void *data) {
101   if (hook) {
102     hook->data = data;
103     return APR_SUCCESS;
104   }
105   else {
106     return APR_EGENERAL;
107   }
108 }
109 
110 /**
111  * get user data
112  * @param hook IN transport hook
113  * @return user data
114  */
transport_get_data(transport_t * hook)115 void *transport_get_data(transport_t *hook) {
116   return hook->data;
117 }
118 
119 /**
120  * Get socket descriptor of the transport protocol
121  * @param transport IN hook
122  * @param desc OUT os descriptor of this transport
123  * @return APR_SUCCESS, APR_NOSOCK if no transport hook or any apr status
124  */
transport_os_desc_get(transport_t * hook,int * desc)125 apr_status_t transport_os_desc_get(transport_t *hook, int *desc) {
126   if (hook && hook->os_desc_get) {
127     return hook->os_desc_get(hook->data, desc);
128   }
129   else {
130     *desc = -1;
131     return APR_EGENERAL;
132   }
133 
134 }
135 
136 /**
137  * set timeout for this transport
138  * @param transport IN hook
139  * @param t INOUT timeout in ns
140  * @return APR_SUCCESS, APR_NOSOCK if no transport hook or any apr status
141  */
transport_set_timeout(transport_t * hook,apr_interval_time_t t)142 apr_status_t transport_set_timeout(transport_t *hook, apr_interval_time_t t) {
143   if (hook && hook->set_timeout) {
144     return hook->set_timeout(hook->data, t);
145   }
146   else {
147     return APR_EGENERAL;
148   }
149 }
150 
151 /**
152  * get timeout for this transport
153  * @param transport IN hook
154  * @param t OUT timeout in ns
155  * @return APR_SUCCESS, APR_NOSOCK if no transport hook or any apr status
156  */
transport_get_timeout(transport_t * hook,apr_interval_time_t * t)157 apr_status_t transport_get_timeout(transport_t *hook, apr_interval_time_t *t) {
158   if (hook && hook->get_timeout) {
159     return hook->get_timeout(hook->data, t);
160   }
161   else {
162     return APR_EGENERAL;
163   }
164 }
165 
166 /**
167  * call registered transport method
168  * @param transport IN hook
169  * @param buf IN buffer which contains read bytes
170  * @param size INOUT size of buffer
171  * @return APR_SUCCESS, APR_NOSOCK if no transport hook or any apr status
172  */
transport_read(transport_t * hook,char * buf,apr_size_t * size)173 apr_status_t transport_read(transport_t *hook, char *buf, apr_size_t *size) {
174   if (hook && hook->read) {
175     return hook->read(hook->data, buf, size);
176   }
177   else {
178     *size = 0;
179     return APR_EGENERAL;
180   }
181 }
182 
183 /**
184  * call registered transport method
185  * @param transport IN hook
186  * @param buf IN buffer which contains read bytes
187  * @param size IN size of buffer
188  * @return APR_SUCCESS, APR_NOSOCK if no transport hook or any apr status
189  */
transport_write(transport_t * hook,const char * buf,apr_size_t size)190 apr_status_t transport_write(transport_t *hook, const char *buf, apr_size_t size) {
191   if (hook && hook->write) {
192     return hook->write(hook->data, buf, size);
193   }
194   else {
195     return APR_EGENERAL;
196   }
197 }
198 
199