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