static int http2_build_header(http_context *ctx, uchar *buffer, int body_length TSRMLS_DC) { assert(ctx->send_header == 0); char buf[SW_HTTP_HEADER_MAX_SIZE]; char *date_str = NULL; char intbuf[2][16]; int ret; /** * http header */ zval *zheader = ctx->response.zheader; int index = 0; nghttp2_nv nv[128]; /** * http status code */ if (ctx->response.status == 0) { ctx->response.status = 200; } ret = swoole_itoa(intbuf[0], ctx->response.status); http2_add_header(&nv[index++], ZEND_STRL(":status"), intbuf[0], ret); if (zheader) { int flag = 0x0; char *key_server = "server"; char *key_content_length = "content-length"; char *key_content_type = "content-type"; char *key_date = "date"; HashTable *ht = Z_ARRVAL_P(zheader); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (strcmp(key, key_server) == 0) { flag |= HTTP_RESPONSE_SERVER; } else if (strcmp(key, key_content_length) == 0) { flag |= HTTP_RESPONSE_CONTENT_LENGTH; } else if (strcmp(key, key_date) == 0) { flag |= HTTP_RESPONSE_DATE; } else if (strcmp(key, key_content_type) == 0) { flag |= HTTP_RESPONSE_CONTENT_TYPE; } http2_add_header(&nv[index++], key, keylen - 1, Z_STRVAL_P(value), Z_STRLEN_P(value)); } SW_HASHTABLE_FOREACH_END(); if (!(flag & HTTP_RESPONSE_SERVER)) { http2_add_header(&nv[index++], ZEND_STRL("server"), ZEND_STRL(SW_HTTP_SERVER_SOFTWARE)); } if (ctx->request.method == PHP_HTTP_OPTIONS) { http2_add_header(&nv[index++], ZEND_STRL("allow"), ZEND_STRL("GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS")); } else { if (!(flag & HTTP_RESPONSE_CONTENT_LENGTH) && body_length >= 0) { #ifdef SW_HAVE_ZLIB if (ctx->gzip_enable) { body_length = swoole_zlib_buffer->length; } #endif ret = swoole_itoa(intbuf[1], body_length); http2_add_header(&nv[index++], ZEND_STRL("content-length"), intbuf[1], ret); } } if (!(flag & HTTP_RESPONSE_DATE)) { date_str = sw_php_format_date(ZEND_STRL(SW_HTTP_DATE_FORMAT), SwooleGS->now, 0 TSRMLS_CC); http2_add_header(&nv[index++], ZEND_STRL("date"), date_str, strlen(date_str)); } if (!(flag & HTTP_RESPONSE_CONTENT_TYPE)) { http2_add_header(&nv[index++], ZEND_STRL("content-type"), ZEND_STRL("text/html")); } } else {
static int http2_client_build_header(zval *zobject, http2_client_request *req, char *buffer, int buffer_len TSRMLS_DC) { char *date_str = NULL; int ret; zval *zheader = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); int index = 0; int find_host = 0; nghttp2_nv nv[1024]; http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); if (req->type == HTTP_GET) { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); } else { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("POST")); } http2_add_header(&nv[index++], ZEND_STRL(":path"), req->uri, req->uri_len); if (hcc->ssl) { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); } else { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); } //Host index++; if (zheader && !ZVAL_IS_NULL(zheader)) { HashTable *ht = Z_ARRVAL_P(zheader); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (*key == ':') { continue; } if (strncasecmp("Host", key, keylen) == 0) { http2_add_header(&nv[3], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); find_host = 1; } else { http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); } } SW_HASHTABLE_FOREACH_END(); (void)type; }
static int http2_client_build_header(zval *zobject, zval *req, char *buffer, int buffer_len TSRMLS_DC) { char *date_str = NULL; int ret; int index = 0; int find_host = 0; zval *cookies = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("cookies"), 1 TSRMLS_CC); zval *method = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("method"), 1 TSRMLS_CC); zval *path = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("path"), 1 TSRMLS_CC); zval *headers = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("headers"), 1 TSRMLS_CC); nghttp2_nv nv[1024]; http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); if (ZVAL_IS_NULL(method) || Z_TYPE_P(method) != IS_STRING || Z_STRLEN_P(method) == 0) { http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); } else { http2_add_header(&nv[index++], ZEND_STRL(":method"), Z_STRVAL_P(method), Z_STRLEN_P(method)); } if (ZVAL_IS_NULL(path) || Z_TYPE_P(path) != IS_STRING || Z_STRLEN_P(path) == 0) { http2_add_header(&nv[index++], ZEND_STRL(":path"), "/", 1); } else { http2_add_header(&nv[index++], ZEND_STRL(":path"), Z_STRVAL_P(path), Z_STRLEN_P(path)); } if (hcc->ssl) { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); } else { http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); } //Host index++; if (headers && !ZVAL_IS_NULL(headers)) { HashTable *ht = Z_ARRVAL_P(headers); zval *value = NULL; char *key = NULL; uint32_t keylen = 0; int type; SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) { if (!key) { break; } if (*key == ':') { continue; } if (strncasecmp("Host", key, keylen) == 0) { http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); find_host = 1; } else { http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); } } SW_HASHTABLE_FOREACH_END(); (void)type; }