138494Sobrien/* Licensed to the Apache Software Foundation (ASF) under one or more
2174294Sobrien * contributor license agreements.  See the NOTICE file distributed with
338494Sobrien * this work for additional information regarding copyright ownership.
438494Sobrien * The ASF licenses this file to You under the Apache License, Version 2.0
538494Sobrien * (the "License"); you may not use this file except in compliance with
638494Sobrien * the License.  You may obtain a copy of the License at
738494Sobrien *
838494Sobrien *     http://www.apache.org/licenses/LICENSE-2.0
938494Sobrien *
1038494Sobrien * Unless required by applicable law or agreed to in writing, software
1138494Sobrien * distributed under the License is distributed on an "AS IS" BASIS,
1238494Sobrien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338494Sobrien * See the License for the specific language governing permissions and
1438494Sobrien * limitations under the License.
1538494Sobrien */
1638494Sobrien
1738494Sobrien#include "apr_buckets.h"
1838494Sobrien
1938494Sobrienstatic apr_status_t socket_bucket_read(apr_bucket *a, const char **str,
2042629Sobrien                                       apr_size_t *len, apr_read_type_e block)
2138494Sobrien{
2238494Sobrien    apr_socket_t *p = a->data;
2338494Sobrien    char *buf;
2438494Sobrien    apr_status_t rv;
2538494Sobrien    apr_interval_time_t timeout;
2638494Sobrien
2738494Sobrien    if (block == APR_NONBLOCK_READ) {
2838494Sobrien        apr_socket_timeout_get(p, &timeout);
2938494Sobrien        apr_socket_timeout_set(p, 0);
3038494Sobrien    }
3138494Sobrien
3238494Sobrien    *str = NULL;
3338494Sobrien    *len = APR_BUCKET_BUFF_SIZE;
3438494Sobrien    buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */
3538494Sobrien
3638494Sobrien    rv = apr_socket_recv(p, buf, len);
3738494Sobrien
3838494Sobrien    if (block == APR_NONBLOCK_READ) {
3938494Sobrien        apr_socket_timeout_set(p, timeout);
40174294Sobrien    }
4138494Sobrien
4238494Sobrien    if (rv != APR_SUCCESS && rv != APR_EOF) {
4338494Sobrien        apr_bucket_free(buf);
4438494Sobrien        return rv;
4538494Sobrien    }
4638494Sobrien    /*
4738494Sobrien     * If there's more to read we have to keep the rest of the socket
4838494Sobrien     * for later. XXX: Note that more complicated bucket types that
4938494Sobrien     * refer to data not in memory and must therefore have a read()
5038494Sobrien     * function similar to this one should be wary of copying this
5138494Sobrien     * code because if they have a destroy function they probably
5238494Sobrien     * want to migrate the bucket's subordinate structure from the
5338494Sobrien     * old bucket to a raw new one and adjust it as appropriate,
5438494Sobrien     * rather than destroying the old one and creating a completely
5538494Sobrien     * new bucket.
56174294Sobrien     *
57174294Sobrien     * Even if there is nothing more to read, don't close the socket here
5838494Sobrien     * as we have to use it to send any response :)  We could shut it
5938494Sobrien     * down for reading, but there is no benefit to doing so.
6038494Sobrien     */
6138494Sobrien    if (*len > 0) {
6238494Sobrien        apr_bucket_heap *h;
6338494Sobrien        /* Change the current bucket to refer to what we read */
6438494Sobrien        a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free);
6538494Sobrien        h = a->data;
6638494Sobrien        h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */
67174294Sobrien        *str = buf;
68174294Sobrien        APR_BUCKET_INSERT_AFTER(a, apr_bucket_socket_create(p, a->list));
69174294Sobrien    }
70174294Sobrien    else {
7138494Sobrien        apr_bucket_free(buf);
7238494Sobrien        a = apr_bucket_immortal_make(a, "", 0);
7338494Sobrien        *str = a->data;
7438494Sobrien    }
75174294Sobrien    return APR_SUCCESS;
76174294Sobrien}
77174294Sobrien
78174294SobrienAPU_DECLARE(apr_bucket *) apr_bucket_socket_make(apr_bucket *b, apr_socket_t *p)
79174294Sobrien{
80174294Sobrien    /*
8138494Sobrien     * XXX: We rely on a cleanup on some pool or other to actually
8238494Sobrien     * destroy the socket. We should probably explicitly call apr to
8338494Sobrien     * destroy it instead.
8438494Sobrien     *
8538494Sobrien     * Note that typically the socket is allocated from the connection pool
8638494Sobrien     * so it will disappear when the connection is finished.
8738494Sobrien     */
8838494Sobrien    b->type        = &apr_bucket_type_socket;
8938494Sobrien    b->length      = (apr_size_t)(-1);
9038494Sobrien    b->start       = -1;
9138494Sobrien    b->data        = p;
9238494Sobrien
9338494Sobrien    return b;
9438494Sobrien}
9538494Sobrien
9638494SobrienAPU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *p,
9738494Sobrien                                                   apr_bucket_alloc_t *list)
9838494Sobrien{
9938494Sobrien    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
10038494Sobrien
10138494Sobrien    APR_BUCKET_INIT(b);
10238494Sobrien    b->free = apr_bucket_free;
10338494Sobrien    b->list = list;
10438494Sobrien    return apr_bucket_socket_make(b, p);
10538494Sobrien}
106174294Sobrien
10738494SobrienAPU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_socket = {
10838494Sobrien    "SOCKET", 5, APR_BUCKET_DATA,
10938494Sobrien    apr_bucket_destroy_noop,
11038494Sobrien    socket_bucket_read,
11138494Sobrien    apr_bucket_setaside_notimpl,
11238494Sobrien    apr_bucket_split_notimpl,
11338494Sobrien    apr_bucket_copy_notimpl
11438494Sobrien};
11538494Sobrien