Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize http server #5251

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 111 additions & 3 deletions ext-src/php_swoole_http.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,115 @@ struct Response {
zval _ztrailer;
};

struct ByteBuffer {
const char *protocol = nullptr;
const char *status = nullptr;
const char *reason = nullptr;

size_t http_status_length = 0;
size_t http_headers_length = 0;

int index = 0;
size_t *lengths;
const char **headers;

int free_num = 0;
zend_string **free_list;

ByteBuffer(size_t *_lengths, const char **_headers, zend_string **_free_list) {
lengths = _lengths;
headers = _headers;
free_list = _free_list;
}

~ByteBuffer() {
int i = 0;
while (i < free_num) {
zend_string_release(free_list[i++]);
}
}

inline void add_status(const char *_status, const char *_reason) {
protocol = "HTTP/1.1 ";
status = _status;
reason = _reason;
// calculate http status line length
if (!reason) {
http_status_length = strlen(protocol) + strlen(status) + SW_CRLF_LEN;
} else {
http_status_length = strlen(protocol) + strlen(status) + strlen(reason) + SW_CRLF_LEN + 1;
}
}

inline void add_header(zend_string *key, zend_string *value) {
zend_string_addref(key);
zend_string_addref(value);
free_list[free_num++] = key;
free_list[free_num++] = value;
add_header(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(value), ZSTR_LEN(value));
}

inline void add_header(const char *key, size_t key_length, const char *value, size_t value_length) {
headers[index] = key;
lengths[index] = key_length;
index++;

headers[index] = value;
lengths[index] = value_length;
index++;

if (value) {
http_headers_length += key_length + value_length + SW_CRLF_LEN + 2;
} else {
// When the value is a nullptr, it means that this response header has a fixed value.
http_headers_length += key_length;
}
}

inline size_t get_protocol_length(size_t length = 0) {
// calculate http protocol length
return http_status_length + http_headers_length + length + SW_CRLF_LEN;
}

void write_protocol(String *http_buffer, const char *data, size_t length) {
http_buffer->append(protocol, strlen(protocol));
http_buffer->append(status, strlen(status));
if (reason) {
http_buffer->append(" ", 1);
http_buffer->append(reason, strlen(reason));
}
http_buffer->append(SW_CRLF, SW_CRLF_LEN);

size_t key_length = 0;
size_t value_length = 0;
const char *key = nullptr;
const char *value = nullptr;
int i = 0;

while (i < index) {
key_length = lengths[i];
value_length = lengths[i + 1];
key = headers[i++];
value = headers[i++];

if (value == nullptr) {
http_buffer->append(key, key_length);
continue;
}

http_buffer->append(key, key_length);
http_buffer->append(ZEND_STRL(": "));
http_buffer->append(value, value_length);
http_buffer->append(SW_CRLF, SW_CRLF_LEN);
}

http_buffer->append(SW_CRLF, SW_CRLF_LEN);
if (data) {
http_buffer->append(data, length);
}
}
};

struct Context {
SessionId fd;
uchar completed : 1;
Expand Down Expand Up @@ -192,8 +301,8 @@ struct Context {
void end(zval *zdata, zval *return_value);
bool send_file(const char *file, uint32_t l_file, off_t offset, size_t length);
void send_trailer(zval *return_value);
String *get_write_buffer();
void build_header(String *http_buffer, const char *body, size_t length);
String *get_write_buffer(size_t capacity = SW_BUFFER_SIZE_STD);
void build_header(const char *body, size_t length);
ssize_t build_trailer(String *http_buffer);

size_t get_content_length() {
Expand All @@ -212,7 +321,6 @@ struct Context {
bool is_available();
void free();
};

} // namespace http

namespace http2 {
Expand Down
16 changes: 7 additions & 9 deletions ext-src/php_swoole_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,12 @@ static sw_inline void sw_zend_update_property_null_ex(zend_class_entry *scope, z
zend_update_property_ex(scope, SW_Z8_OBJ_P(object), s, &tmp);
}

static sw_inline zval *sw_zend_read_property_ex(zend_class_entry *ce, zval *obj, zend_string *s, int silent) {
zval rv, *property = zend_read_property_ex(ce, SW_Z8_OBJ_P(obj), s, silent, &rv);
static sw_inline zval *sw_zend_read_property_ex(zend_class_entry *ce, zval *zobject, zend_string *name, int silent) {
zval *zv = zend_hash_find(&ce->properties_info, name);
zend_property_info *property_info = (zend_property_info *) Z_PTR_P(zv);
zval *property = OBJ_PROP(SW_Z8_OBJ_P(zobject), property_info->offset);
if (UNEXPECTED(property == &EG(uninitialized_zval))) {
sw_zend_update_property_null_ex(ce, obj, s);
return zend_read_property_ex(ce, SW_Z8_OBJ_P(obj), s, silent, &rv);
ZVAL_NULL(property);
}
return property;
}
Expand Down Expand Up @@ -946,11 +947,8 @@ static sw_inline int php_swoole_check_reactor() {
}
}

static sw_inline char *php_swoole_format_date(char *format, size_t format_len, time_t ts, int localtime) {
zend_string *time = php_format_date(format, format_len, ts, localtime);
char *return_str = estrndup(ZSTR_VAL(time), ZSTR_LEN(time));
zend_string_release(time);
return return_str;
static sw_inline zend_string *php_swoole_format_date(char *format, size_t format_len, time_t ts, int localtime) {
return php_format_date(format, format_len, ts, localtime);
}

static sw_inline char *php_swoole_url_encode(const char *value, size_t value_len, size_t *exten) {
Expand Down
8 changes: 4 additions & 4 deletions ext-src/swoole_http2_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,11 @@ static void http2_server_set_date_header(Http2::HeaderSet *headers) {

time_t now = time(nullptr);
if (now != cache.time) {
char *date_str = php_swoole_format_date((char *) ZEND_STRL(SW_HTTP_DATE_FORMAT), now, 0);
cache.len = strlen(date_str);
memcpy(cache.buf, date_str, cache.len);
zend_string *date = php_swoole_format_date((char *) ZEND_STRL(SW_HTTP_DATE_FORMAT), now, 0);
memcpy(cache.buf, ZSTR_VAL(date), ZSTR_LEN(date));
cache.len = ZSTR_LEN(date);
cache.time = now;
efree(date_str);
zend_string_release(date);
}
headers->add(ZEND_STRL("date"), cache.buf, cache.len);
}
Expand Down
Loading
Loading