]> granicus.if.org Git - apache/blob - modules/http2/h2_bucket_eos.c
Backport
[apache] / modules / http2 / h2_bucket_eos.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <assert.h>
18 #include <stddef.h>
19
20 #include <httpd.h>
21 #include <http_core.h>
22 #include <http_connection.h>
23 #include <http_log.h>
24
25 #include "h2_private.h"
26 #include "h2.h"
27 #include "h2_mplx.h"
28 #include "h2_stream.h"
29 #include "h2_bucket_eos.h"
30
31 typedef struct {
32     apr_bucket_refcount refcount;
33     h2_stream *stream;
34 } h2_bucket_eos;
35
36 static apr_status_t bucket_cleanup(void *data)
37 {
38     h2_stream **pstream = data;
39
40     if (*pstream) {
41         /* If bucket_destroy is called after us, this prevents
42          * bucket_destroy from trying to destroy the stream again. */
43         *pstream = NULL;
44     }
45     return APR_SUCCESS;
46 }
47
48 static apr_status_t bucket_read(apr_bucket *b, const char **str,
49                                 apr_size_t *len, apr_read_type_e block)
50 {
51     (void)b;
52     (void)block;
53     *str = NULL;
54     *len = 0;
55     return APR_SUCCESS;
56 }
57
58 apr_bucket *h2_bucket_eos_make(apr_bucket *b, h2_stream *stream)
59 {
60     h2_bucket_eos *h;
61
62     h = apr_bucket_alloc(sizeof(*h), b->list);
63     h->stream = stream;
64
65     b = apr_bucket_shared_make(b, h, 0, 0);
66     b->type = &h2_bucket_type_eos;
67     
68     return b;
69 }
70
71 apr_bucket *h2_bucket_eos_create(apr_bucket_alloc_t *list,
72                                  h2_stream *stream)
73 {
74     apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);
75
76     APR_BUCKET_INIT(b);
77     b->free = apr_bucket_free;
78     b->list = list;
79     b = h2_bucket_eos_make(b, stream);
80     if (stream) {
81         h2_bucket_eos *h = b->data;
82         apr_pool_pre_cleanup_register(stream->pool, &h->stream, bucket_cleanup);
83     }
84     return b;
85 }
86
87 static void bucket_destroy(void *data)
88 {
89     h2_bucket_eos *h = data;
90
91     if (apr_bucket_shared_destroy(h)) {
92         h2_stream *stream = h->stream;
93         if (stream && stream->pool) {
94             apr_pool_cleanup_kill(stream->pool, &h->stream, bucket_cleanup);
95         }
96         apr_bucket_free(h);
97         if (stream) {
98             h2_stream_eos_destroy(stream);
99         }
100     }
101 }
102
103 const apr_bucket_type_t h2_bucket_type_eos = {
104     "H2EOS", 5, APR_BUCKET_METADATA,
105     bucket_destroy,
106     bucket_read,
107     apr_bucket_setaside_noop,
108     apr_bucket_split_notimpl,
109     apr_bucket_shared_copy
110 };
111