implement #4982
This commit is contained in:
parent
0b3abbd304
commit
5a321621f4
@ -1,3 +1,6 @@
|
||||
Mon Apr 17 01:29:07 CEST 2017
|
||||
Add support for HTTP body compression (#4982). -CG
|
||||
|
||||
Mon Mar 20 04:37:46 CET 2017
|
||||
Implemented first working version of taler-auditor. -CG
|
||||
|
||||
|
@ -55,6 +55,7 @@ taler_exchange_httpd_LDADD = \
|
||||
-lgnunetutil \
|
||||
-lgnunetjson \
|
||||
-ljansson \
|
||||
-lz \
|
||||
-lpthread
|
||||
|
||||
if HAVE_DEVELOPER
|
||||
|
@ -71,6 +71,16 @@ struct TEH_KS_StateHandle
|
||||
*/
|
||||
char *keys_json;
|
||||
|
||||
/**
|
||||
* deflate-compressed version of @e keys_json, or NULL if not available.
|
||||
*/
|
||||
void *keys_jsonz;
|
||||
|
||||
/**
|
||||
* Number of bytes in @e keys_jsonz.
|
||||
*/
|
||||
size_t keys_jsonz_size;
|
||||
|
||||
/**
|
||||
* Mapping from denomination keys to denomination key issue struct.
|
||||
* Used to lookup the key by hash.
|
||||
@ -709,6 +719,7 @@ ks_release_ (struct TEH_KS_StateHandle *key_state)
|
||||
key_state->revoked_map = NULL;
|
||||
}
|
||||
GNUNET_free_non_null (key_state->keys_json);
|
||||
GNUNET_free_non_null (key_state->keys_jsonz);
|
||||
GNUNET_free (key_state);
|
||||
}
|
||||
}
|
||||
@ -851,6 +862,17 @@ TEH_KS_acquire_ (const char *location)
|
||||
JSON_INDENT (2));
|
||||
GNUNET_assert (NULL != key_state->keys_json);
|
||||
json_decref (keys);
|
||||
/* also compute compressed version of /keys */
|
||||
key_state->keys_jsonz = GNUNET_strdup (key_state->keys_json);
|
||||
key_state->keys_jsonz_size = strlen (key_state->keys_json);
|
||||
if (MHD_YES !=
|
||||
TEH_RESPONSE_body_compress (&key_state->keys_jsonz,
|
||||
&key_state->keys_jsonz_size))
|
||||
{
|
||||
GNUNET_free (key_state->keys_jsonz);
|
||||
key_state->keys_jsonz = NULL;
|
||||
key_state->keys_jsonz_size = 0;
|
||||
}
|
||||
internal_key_state = key_state;
|
||||
}
|
||||
key_state = internal_key_state;
|
||||
@ -1225,10 +1247,26 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
|
||||
struct MHD_Response *response;
|
||||
int ret;
|
||||
char dat[128];
|
||||
char *json;
|
||||
size_t json_len;
|
||||
int comp;
|
||||
|
||||
key_state = TEH_KS_acquire ();
|
||||
response = MHD_create_response_from_buffer (strlen (key_state->keys_json),
|
||||
key_state->keys_json,
|
||||
comp = MHD_NO;
|
||||
if (NULL != key_state->keys_jsonz)
|
||||
comp = TEH_RESPONSE_can_compress (connection);
|
||||
if (MHD_YES == comp)
|
||||
{
|
||||
json = key_state->keys_jsonz;
|
||||
json_len = key_state->keys_jsonz_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
json = key_state->keys_json;
|
||||
json_len = strlen (key_state->keys_json);
|
||||
}
|
||||
response = MHD_create_response_from_buffer (json_len,
|
||||
json,
|
||||
MHD_RESPMEM_MUST_COPY);
|
||||
TEH_KS_release (key_state);
|
||||
if (NULL == response)
|
||||
@ -1241,6 +1279,15 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
|
||||
MHD_add_response_header (response,
|
||||
MHD_HTTP_HEADER_CONTENT_TYPE,
|
||||
rh->mime_type));
|
||||
if (MHD_YES !=
|
||||
MHD_add_response_header (response,
|
||||
MHD_HTTP_HEADER_CONTENT_ENCODING,
|
||||
"deflate"))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MHD_destroy_response (response);
|
||||
return MHD_NO;
|
||||
}
|
||||
get_date_string (key_state->reload_time,
|
||||
dat);
|
||||
GNUNET_break (MHD_YES ==
|
||||
|
@ -23,6 +23,7 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <zlib.h>
|
||||
#include "taler-exchange-httpd_responses.h"
|
||||
#include "taler_util.h"
|
||||
#include "taler_json_lib.h"
|
||||
@ -47,6 +48,74 @@ TEH_RESPONSE_add_global_headers (struct MHD_Response *response)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is HTTP body deflate compression supported by the client?
|
||||
*
|
||||
* @param connection connection to check
|
||||
* @return #MHD_YES if 'deflate' compression is allowed
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_can_compress (struct MHD_Connection *connection)
|
||||
{
|
||||
const char *ae;
|
||||
const char *de;
|
||||
|
||||
ae = MHD_lookup_connection_value (connection,
|
||||
MHD_HEADER_KIND,
|
||||
MHD_HTTP_HEADER_ACCEPT_ENCODING);
|
||||
if (NULL == ae)
|
||||
return MHD_NO;
|
||||
de = strstr (ae,
|
||||
"deflate");
|
||||
if (NULL == de)
|
||||
return MHD_NO;
|
||||
if ( ( (de == ae) ||
|
||||
( de[-1] == ',') ||
|
||||
(de[-1] == ' ') ) &&
|
||||
( (de[strlen ("deflate")] == '\0') ||
|
||||
(de[strlen ("deflate")] == ',') ) )
|
||||
return MHD_YES;
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to compress a response body. Updates @a buf and @buf_size.
|
||||
*
|
||||
* @param[in,out] buf pointer to body to compress
|
||||
* @param[in,out] buf_size pointer to initial size of @a buf
|
||||
* @return #MHD_TES if @a buf was compressed
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_body_compress (void **buf,
|
||||
size_t *buf_size)
|
||||
{
|
||||
Bytef *cbuf;
|
||||
uLongf cbuf_size;
|
||||
int ret;
|
||||
|
||||
cbuf_size = compressBound (*buf_size);
|
||||
cbuf = malloc (cbuf_size);
|
||||
if (NULL == cbuf)
|
||||
return MHD_NO;
|
||||
ret = compress (cbuf,
|
||||
&cbuf_size,
|
||||
(const Bytef *) *buf,
|
||||
*buf_size);
|
||||
if ( (Z_OK != ret) ||
|
||||
(cbuf_size >= *buf_size) )
|
||||
{
|
||||
/* compression failed */
|
||||
free (cbuf);
|
||||
return MHD_NO;
|
||||
}
|
||||
free (*buf);
|
||||
*buf = (void *) cbuf;
|
||||
*buf_size = (size_t) cbuf_size;
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send JSON object as response.
|
||||
*
|
||||
@ -61,12 +130,26 @@ TEH_RESPONSE_reply_json (struct MHD_Connection *connection,
|
||||
unsigned int response_code)
|
||||
{
|
||||
struct MHD_Response *resp;
|
||||
char *json_str;
|
||||
void *json_str;
|
||||
size_t json_len;
|
||||
int ret;
|
||||
int comp;
|
||||
|
||||
json_str = json_dumps (json, JSON_INDENT(2));
|
||||
GNUNET_assert (NULL != json_str);
|
||||
resp = MHD_create_response_from_buffer (strlen (json_str),
|
||||
json_str = json_dumps (json,
|
||||
JSON_INDENT(2));
|
||||
if (NULL == json_str)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return MHD_NO;
|
||||
}
|
||||
json_len = strlen (json_str);
|
||||
/* try to compress the body */
|
||||
comp = MHD_NO;
|
||||
if (MHD_YES ==
|
||||
TEH_RESPONSE_can_compress (connection))
|
||||
comp = TEH_RESPONSE_body_compress (&json_str,
|
||||
&json_len);
|
||||
resp = MHD_create_response_from_buffer (json_len,
|
||||
json_str,
|
||||
MHD_RESPMEM_MUST_FREE);
|
||||
if (NULL == resp)
|
||||
@ -79,6 +162,19 @@ TEH_RESPONSE_reply_json (struct MHD_Connection *connection,
|
||||
(void) MHD_add_response_header (resp,
|
||||
MHD_HTTP_HEADER_CONTENT_TYPE,
|
||||
"application/json");
|
||||
if (MHD_YES == comp)
|
||||
{
|
||||
/* Need to indicate to client that body is compressed */
|
||||
if (MHD_NO ==
|
||||
MHD_add_response_header (resp,
|
||||
MHD_HTTP_HEADER_CONTENT_ENCODING,
|
||||
"deflate"))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MHD_destroy_response (resp);
|
||||
return MHD_NO;
|
||||
}
|
||||
}
|
||||
ret = MHD_queue_response (connection,
|
||||
response_code,
|
||||
resp);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "taler-exchange-httpd.h"
|
||||
#include "taler-exchange-httpd_db.h"
|
||||
|
||||
|
||||
/**
|
||||
* Add headers we want to return in every response.
|
||||
* Useful for testing, like if we want to always close
|
||||
@ -44,6 +45,28 @@ void
|
||||
TEH_RESPONSE_add_global_headers (struct MHD_Response *response);
|
||||
|
||||
|
||||
/**
|
||||
* Try to compress a response body. Updates @a buf and @buf_size.
|
||||
*
|
||||
* @param[in,out] buf pointer to body to compress
|
||||
* @param[in,out] buf_size pointer to initial size of @a buf
|
||||
* @return #MHD_TES if @a buf was compressed
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_body_compress (void **buf,
|
||||
size_t *buf_size);
|
||||
|
||||
|
||||
/**
|
||||
* Is HTTP body deflate compression supported by the client?
|
||||
*
|
||||
* @param connection connection to check
|
||||
* @return #MHD_YES if 'deflate' compression is allowed
|
||||
*/
|
||||
int
|
||||
TEH_RESPONSE_can_compress (struct MHD_Connection *connection);
|
||||
|
||||
|
||||
/**
|
||||
* Send JSON object as response.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user