]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - buckets/socket_buckets.c
Vendor import serf-1.3.9 (now Apache serf)
[FreeBSD/FreeBSD.git] / buckets / socket_buckets.c
1 /* ====================================================================
2  *    Licensed to the Apache Software Foundation (ASF) under one
3  *    or more contributor license agreements.  See the NOTICE file
4  *    distributed with this work for additional information
5  *    regarding copyright ownership.  The ASF licenses this file
6  *    to you under the Apache License, Version 2.0 (the
7  *    "License"); you may not use this file except in compliance
8  *    with the License.  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing,
13  *    software distributed under the License is distributed on an
14  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  *    KIND, either express or implied.  See the License for the
16  *    specific language governing permissions and limitations
17  *    under the License.
18  * ====================================================================
19  */
20
21 #include <apr_pools.h>
22 #include <apr_network_io.h>
23
24 #include "serf.h"
25 #include "serf_private.h"
26 #include "serf_bucket_util.h"
27
28
29 typedef struct {
30     apr_socket_t *skt;
31
32     serf_databuf_t databuf;
33
34     /* Progress callback */
35     serf_progress_t progress_func;
36     void *progress_baton;
37 } socket_context_t;
38
39
40 static apr_status_t socket_reader(void *baton, apr_size_t bufsize,
41                                   char *buf, apr_size_t *len)
42 {
43     socket_context_t *ctx = baton;
44     apr_status_t status;
45
46     *len = bufsize;
47     status = apr_socket_recv(ctx->skt, buf, len);
48
49     if (status && !APR_STATUS_IS_EAGAIN(status))
50         serf__log_skt(SOCK_VERBOSE, __FILE__, ctx->skt,
51                       "socket_recv error %d\n", status);
52
53     if (*len)
54         serf__log_skt(SOCK_MSG_VERBOSE, __FILE__, ctx->skt,
55                       "--- socket_recv:\n%.*s\n-(%d)-\n",
56                       *len, buf, *len);
57
58     if (ctx->progress_func && *len)
59         ctx->progress_func(ctx->progress_baton, *len, 0);
60
61     return status;
62 }
63
64 serf_bucket_t *serf_bucket_socket_create(
65     apr_socket_t *skt,
66     serf_bucket_alloc_t *allocator)
67 {
68     socket_context_t *ctx;
69
70     /* Oh, well. */
71     ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx));
72     ctx->skt = skt;
73
74     serf_databuf_init(&ctx->databuf);
75     ctx->databuf.read = socket_reader;
76     ctx->databuf.read_baton = ctx;
77
78     ctx->progress_func = NULL;
79     ctx->progress_baton = NULL;
80     return serf_bucket_create(&serf_bucket_type_socket, allocator, ctx);
81 }
82
83 void serf_bucket_socket_set_read_progress_cb(
84     serf_bucket_t *bucket,
85     const serf_progress_t progress_func,
86     void *progress_baton)
87 {
88     socket_context_t *ctx = bucket->data;
89
90     ctx->progress_func = progress_func;
91     ctx->progress_baton = progress_baton;
92 }
93
94 static apr_status_t serf_socket_read(serf_bucket_t *bucket,
95                                      apr_size_t requested,
96                                      const char **data, apr_size_t *len)
97 {
98     socket_context_t *ctx = bucket->data;
99
100     return serf_databuf_read(&ctx->databuf, requested, data, len);
101 }
102
103 static apr_status_t serf_socket_readline(serf_bucket_t *bucket,
104                                          int acceptable, int *found,
105                                          const char **data, apr_size_t *len)
106 {
107     socket_context_t *ctx = bucket->data;
108
109     return serf_databuf_readline(&ctx->databuf, acceptable, found, data, len);
110 }
111
112 static apr_status_t serf_socket_peek(serf_bucket_t *bucket,
113                                      const char **data,
114                                      apr_size_t *len)
115 {
116     socket_context_t *ctx = bucket->data;
117
118     return serf_databuf_peek(&ctx->databuf, data, len);
119 }
120
121 const serf_bucket_type_t serf_bucket_type_socket = {
122     "SOCKET",
123     serf_socket_read,
124     serf_socket_readline,
125     serf_default_read_iovec,
126     serf_default_read_for_sendfile,
127     serf_default_read_bucket,
128     serf_socket_peek,
129     serf_default_destroy_and_data,
130 };