1362181Sdim/* ==================================================================== 2362181Sdim * Licensed to the Apache Software Foundation (ASF) under one 3362181Sdim * or more contributor license agreements. See the NOTICE file 4362181Sdim * distributed with this work for additional information 5362181Sdim * regarding copyright ownership. The ASF licenses this file 6362181Sdim * to you under the Apache License, Version 2.0 (the 7362181Sdim * "License"); you may not use this file except in compliance 8362181Sdim * with the License. You may obtain a copy of the License at 9251877Speter * 10362181Sdim * http://www.apache.org/licenses/LICENSE-2.0 11251877Speter * 12362181Sdim * Unless required by applicable law or agreed to in writing, 13362181Sdim * software distributed under the License is distributed on an 14362181Sdim * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15362181Sdim * KIND, either express or implied. See the License for the 16362181Sdim * specific language governing permissions and limitations 17362181Sdim * under the License. 18362181Sdim * ==================================================================== 19251877Speter */ 20251877Speter 21251877Speter#include <apr_pools.h> 22251877Speter#include <apr_network_io.h> 23251877Speter 24251877Speter#include "serf.h" 25251877Speter#include "serf_private.h" 26251877Speter#include "serf_bucket_util.h" 27251877Speter 28251877Speter 29251877Spetertypedef struct { 30251877Speter apr_socket_t *skt; 31251877Speter 32251877Speter serf_databuf_t databuf; 33251877Speter 34251877Speter /* Progress callback */ 35251877Speter serf_progress_t progress_func; 36251877Speter void *progress_baton; 37251877Speter} socket_context_t; 38251877Speter 39251877Speter 40251877Speterstatic apr_status_t socket_reader(void *baton, apr_size_t bufsize, 41251877Speter char *buf, apr_size_t *len) 42251877Speter{ 43251877Speter socket_context_t *ctx = baton; 44251877Speter apr_status_t status; 45251877Speter 46251877Speter *len = bufsize; 47251877Speter status = apr_socket_recv(ctx->skt, buf, len); 48251877Speter 49251877Speter if (status && !APR_STATUS_IS_EAGAIN(status)) 50251877Speter serf__log_skt(SOCK_VERBOSE, __FILE__, ctx->skt, 51251877Speter "socket_recv error %d\n", status); 52251877Speter 53251877Speter if (*len) 54251877Speter serf__log_skt(SOCK_MSG_VERBOSE, __FILE__, ctx->skt, 55251877Speter "--- socket_recv:\n%.*s\n-(%d)-\n", 56251877Speter *len, buf, *len); 57251877Speter 58262324Speter if (ctx->progress_func && *len) 59251877Speter ctx->progress_func(ctx->progress_baton, *len, 0); 60251877Speter 61251877Speter return status; 62251877Speter} 63251877Speter 64251877Speterserf_bucket_t *serf_bucket_socket_create( 65251877Speter apr_socket_t *skt, 66251877Speter serf_bucket_alloc_t *allocator) 67251877Speter{ 68251877Speter socket_context_t *ctx; 69251877Speter 70251877Speter /* Oh, well. */ 71251877Speter ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx)); 72251877Speter ctx->skt = skt; 73251877Speter 74251877Speter serf_databuf_init(&ctx->databuf); 75251877Speter ctx->databuf.read = socket_reader; 76251877Speter ctx->databuf.read_baton = ctx; 77251877Speter 78251877Speter ctx->progress_func = NULL; 79251877Speter ctx->progress_baton = NULL; 80251877Speter return serf_bucket_create(&serf_bucket_type_socket, allocator, ctx); 81251877Speter} 82251877Speter 83251877Spetervoid serf_bucket_socket_set_read_progress_cb( 84251877Speter serf_bucket_t *bucket, 85251877Speter const serf_progress_t progress_func, 86251877Speter void *progress_baton) 87251877Speter{ 88251877Speter socket_context_t *ctx = bucket->data; 89251877Speter 90251877Speter ctx->progress_func = progress_func; 91251877Speter ctx->progress_baton = progress_baton; 92251877Speter} 93251877Speter 94251877Speterstatic apr_status_t serf_socket_read(serf_bucket_t *bucket, 95251877Speter apr_size_t requested, 96251877Speter const char **data, apr_size_t *len) 97251877Speter{ 98251877Speter socket_context_t *ctx = bucket->data; 99251877Speter 100251877Speter return serf_databuf_read(&ctx->databuf, requested, data, len); 101251877Speter} 102251877Speter 103251877Speterstatic apr_status_t serf_socket_readline(serf_bucket_t *bucket, 104251877Speter int acceptable, int *found, 105251877Speter const char **data, apr_size_t *len) 106251877Speter{ 107251877Speter socket_context_t *ctx = bucket->data; 108251877Speter 109251877Speter return serf_databuf_readline(&ctx->databuf, acceptable, found, data, len); 110251877Speter} 111251877Speter 112251877Speterstatic apr_status_t serf_socket_peek(serf_bucket_t *bucket, 113251877Speter const char **data, 114251877Speter apr_size_t *len) 115251877Speter{ 116251877Speter socket_context_t *ctx = bucket->data; 117251877Speter 118251877Speter return serf_databuf_peek(&ctx->databuf, data, len); 119251877Speter} 120251877Speter 121251877Speterconst serf_bucket_type_t serf_bucket_type_socket = { 122251877Speter "SOCKET", 123251877Speter serf_socket_read, 124251877Speter serf_socket_readline, 125251877Speter serf_default_read_iovec, 126251877Speter serf_default_read_for_sendfile, 127251877Speter serf_default_read_bucket, 128251877Speter serf_socket_peek, 129251877Speter serf_default_destroy_and_data, 130251877Speter}; 131