Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Apache/modules/http2/   (Apache Software Stiftung Version 2.4.65©)  Datei vom 19.2.2024 mit Größe 6 kB image not shown  

Quelle  h2_headers.c   Sprache: C

 
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 
#include <assert.h>
#include <stdio.h>

#include <apr_strings.h>

#include <httpd.h>
#include <http_core.h>
#include <http_log.h>
#include <util_time.h>

#include <nghttp2/nghttp2.h>

#include "h2_private.h"
#include "h2_protocol.h"
#include "h2_config.h"
#include "h2_util.h"
#include "h2_request.h"
#include "h2_headers.h"

#if !AP_HAS_RESPONSE_BUCKETS

static int is_unsafe(server_rec *s) 
{
    core_server_config *conf = ap_get_core_module_config(s->module_config);
    return (conf->http_conformance == AP_HTTP_CONFORMANCE_UNSAFE);
}

typedef struct {
    apr_bucket_refcount refcount;
    h2_headers *headers;
} h2_bucket_headers;
 
static apr_status_t bucket_read(apr_bucket *b, const char **str,
                                apr_size_t *len, apr_read_type_e block)
{
    (void)b;
    (void)block;
    *str = NULL;
    *len = 0;
    return APR_SUCCESS;
}

apr_bucket * h2_bucket_headers_make(apr_bucket *b, h2_headers *r)
{
    h2_bucket_headers *br;

    br = apr_bucket_alloc(sizeof(*br), b->list);
    br->headers = r;

    b = apr_bucket_shared_make(b, br, 0, 0);
    b->type = &h2_bucket_type_headers;
    b->length = 0;
    
    return b;


apr_bucket * h2_bucket_headers_create(apr_bucket_alloc_t *list, 
                                       h2_headers *r)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    b = h2_bucket_headers_make(b, r);
    return b;
}
                                       
h2_headers *h2_bucket_headers_get(apr_bucket *b)
{
    if (H2_BUCKET_IS_HEADERS(b)) {
        return ((h2_bucket_headers *)b->data)->headers;
    }
    return NULL;
}

static void bucket_destroy(void *data)
{
    h2_bucket_headers *h = data;

    if (apr_bucket_shared_destroy(h)) {
        apr_bucket_free(h);
    }
}

const apr_bucket_type_t h2_bucket_type_headers = {
    "H2HEADERS", 5, APR_BUCKET_METADATA,
    bucket_destroy,
    bucket_read,
    apr_bucket_setaside_noop,
    apr_bucket_split_notimpl,
    apr_bucket_shared_copy
};

apr_bucket *h2_bucket_headers_clone(apr_bucket *b, apr_pool_t *pool,
                                    apr_bucket_alloc_t *list)
{
    h2_headers *hdrs = ((h2_bucket_headers *)b->data)->headers;
    return h2_bucket_headers_create(list, h2_headers_clone(pool, hdrs));
}


h2_headers *h2_headers_create(int status, const apr_table_t *headers_in, 
                              const apr_table_t *notes, apr_off_t raw_bytes,
                              apr_pool_t *pool)
{
    h2_headers *headers = apr_pcalloc(pool, sizeof(h2_headers));
    headers->status    = status;
    headers->headers   = (headers_in? apr_table_clone(pool, headers_in)
                           : apr_table_make(pool, 5));
    headers->notes     = (notes? apr_table_clone(pool, notes)
                           : apr_table_make(pool, 5));
    return headers;
}

static int add_header_lengths(void *ctx, const char *name, const char *value) 
{
    apr_size_t *plen = ctx;
    *plen += strlen(name) + strlen(value); 
    return 1;
}

apr_size_t h2_headers_length(h2_headers *headers)
{
    apr_size_t len = 0;
    apr_table_do(add_header_lengths, &len, headers->headers, NULL);
    return len;
}

apr_size_t h2_bucket_headers_headers_length(apr_bucket *b)
{
    h2_headers *h = h2_bucket_headers_get(b);
    return h? h2_headers_length(h) : 0;
}

h2_headers *h2_headers_rcreate(request_rec *r, int status,
                               const apr_table_t *header, apr_pool_t *pool)
{
    h2_headers *headers = h2_headers_create(status, header, r->notes, 0, pool);
    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, headers->status, r,
                  "h2_headers_rcreate(%ld): status=%d",
                  (long)r->connection->id, status);
    if (headers->status == HTTP_FORBIDDEN) {
        request_rec *r_prev;
        for (r_prev = r; r_prev != NULL; r_prev = r_prev->prev) {
            const char *cause = apr_table_get(r_prev->notes, "ssl-renegotiate-forbidden");
            if (cause) {
                /* This request triggered a TLS renegotiation that is not allowed
                 * in HTTP/2. Tell the client that it should use HTTP/1.1 for this.
                 */

                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, headers->status, r,
                              APLOGNO(10399)
                              "h2_headers(%ld): renegotiate forbidden, cause: %s",
                              (long)r->connection->id, cause);
                headers->status = H2_ERR_HTTP_1_1_REQUIRED;
                break;
            }
        }
    }
    if (is_unsafe(r->server)) {
        apr_table_setn(headers->notes, H2_HDR_CONFORMANCE, H2_HDR_CONFORMANCE_UNSAFE);
    }
    if (h2_config_rgeti(r, H2_CONF_PUSH) == 0 && h2_config_sgeti(r->server, H2_CONF_PUSH) != 0) {
        apr_table_setn(headers->notes, H2_PUSH_MODE_NOTE, "0");
    }
    return headers;
}

h2_headers *h2_headers_copy(apr_pool_t *pool, h2_headers *h)
{
    return h2_headers_create(h->status, h->headers, h->notes, h->raw_bytes, pool);
}

h2_headers *h2_headers_clone(apr_pool_t *pool, h2_headers *h)
{
    return h2_headers_create(h->status, h->headers, h->notes, h->raw_bytes, pool);
}

h2_headers *h2_headers_die(apr_status_t type,
                             const h2_request *req, apr_pool_t *pool)
{
    h2_headers *headers;
    char *date;
    
    headers = apr_pcalloc(pool, sizeof(h2_headers));
    headers->status    = (type >= 200 && type < 600)? type : 500;
    headers->headers        = apr_table_make(pool, 5);
    headers->notes          = apr_table_make(pool, 5);

    date = apr_palloc(pool, APR_RFC822_DATE_LEN);
    ap_recent_rfc822_date(date, req? req->request_time : apr_time_now());
    apr_table_setn(headers->headers, "Date", date);
    apr_table_setn(headers->headers, "Server", ap_get_server_banner());
    
    return headers;
}

int h2_headers_are_final_response(h2_headers *headers)
{
    return headers->status >= 200;
}

#endif /* !AP_HAS_RESPONSE_BUCKETS */

99%


¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.