| 91 | |
| 92 | |
| 93 | static apr_status_t bucket_socket_ex_read(apr_bucket *a, const char **str, |
| 94 | apr_size_t *len, |
| 95 | apr_read_type_e block) |
| 96 | { |
| 97 | socket_ex_data *data = a->data; |
| 98 | apr_socket_t *p = data->sock; |
| 99 | char *buf; |
| 100 | apr_status_t rv; |
| 101 | apr_interval_time_t timeout; |
| 102 | |
| 103 | if (block == APR_NONBLOCK_READ) { |
| 104 | apr_socket_timeout_get(p, &timeout); |
| 105 | apr_socket_timeout_set(p, 0); |
| 106 | } |
| 107 | |
| 108 | *str = NULL; |
| 109 | *len = APR_BUCKET_BUFF_SIZE; |
| 110 | buf = apr_bucket_alloc(*len, a->list); |
| 111 | |
| 112 | rv = apr_socket_recv(p, buf, len); |
| 113 | |
| 114 | if (block == APR_NONBLOCK_READ) { |
| 115 | apr_socket_timeout_set(p, timeout); |
| 116 | } |
| 117 | |
| 118 | if (rv != APR_SUCCESS && rv != APR_EOF) { |
| 119 | apr_bucket_free(buf); |
| 120 | return rv; |
| 121 | } |
| 122 | |
| 123 | if (*len > 0) { |
| 124 | apr_bucket_heap *h; |
| 125 | |
| 126 | /* count for stats */ |
| 127 | *data->counter += *len; |
| 128 | |
| 129 | /* Change the current bucket to refer to what we read */ |
| 130 | a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); |
| 131 | h = a->data; |
| 132 | h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ |
| 133 | *str = buf; |
| 134 | APR_BUCKET_INSERT_AFTER(a, bucket_socket_ex_create(data, a->list)); |
| 135 | } |
| 136 | else { |
| 137 | apr_bucket_free(buf); |
| 138 | a = apr_bucket_immortal_make(a, "", 0); |
| 139 | *str = a->data; |
| 140 | } |
| 141 | return APR_SUCCESS; |
| 142 | } |
| 143 | |
| 144 | static const apr_bucket_type_t bucket_type_socket_ex = { |
| 145 | "SOCKET_EX", 5, APR_BUCKET_DATA, |
nothing calls this directly
no test coverage detected