Skip to content

Commit

Permalink
fixed #272: supported a binary mode in HTTP.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kray-G committed Apr 15, 2021
1 parent e79585d commit b2ded31
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 9 deletions.
27 changes: 22 additions & 5 deletions lib/std/net/http.kx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ _namespace Net {
return this;
}

public binmode(tf) {
curl_.isContentTypeText = tf ? "0" : "1";
}

public textmode(tf) {
curl_.isContentTypeText = tf ? "1" : "0";
}

public sslVerifyPeer(tf) {
curl_.setOptionInt(Net.CURLOPT_SSL_VERIFYPEER, tf);
return this;
Expand Down Expand Up @@ -161,12 +169,21 @@ _namespace Net {
hdr_.append(curl_.header);
curl_.header = "";
}
if (curl_.received.length() > 0) {
if (body.isFunction) {
body(curl_.received);
if (curl_.isContentTypeText[0] == '1'[0]) {
if (curl_.received.length() > 0) {
if (body.isFunction) {
body(curl_.received);
}
buf_.append(curl_.received);
curl_.received = "";
}
} else {
if (curl_.receivedbin.length() > 0) {
if (body.isFunction) {
body(curl_.receivedbin);
}
curl_.receivedbin = <>;
}
buf_.append(curl_.received);
curl_.received = "";
}
curl_.wait(1000);
} while (curl_.isRunning);
Expand Down
63 changes: 59 additions & 4 deletions src/extlib/kxnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ if (obj) { \
} \
} \
/**/
#define KX_NET_GET_BIN_BUFFER(r, obj, name) \
kx_bin_t *r = 0; \
if (obj) { \
kx_val_t *val = NULL; \
KEX_GET_PROP(val, obj, name); \
if (val && val->type == KX_BIN_T) { \
r = val->value.bn; \
} \
} \
/**/
#define KX_NET_GET_BUFFER_AS_CSTR(r, obj, name) \
const char *r = 0; \
if (obj) { \
Expand Down Expand Up @@ -343,24 +353,66 @@ static size_t Net_headerCallback(void *ptr, size_t size, size_t nmemb, void *use
kx_obj_t *obj = (kx_obj_t *)userp;
size_t bufsz = size * nmemb;
KX_NET_GET_BUFFER(sv, obj, "header");
KX_NET_GET_BUFFER(ct, obj, "contentType");
if (!sv) {
return bufsz;
}

ks_append_n(sv, (char *)ptr, bufsz);
if (ks_string(ct)[0] == 0) {
const char *p = strstr(ks_string(sv), "Content-Type: ");
if (p) {
p += strlen("Content-Type: ");
const char *e = strchr(p, ';');
if (!e) {
e = strchr(p, '\r');
if (!e) {
e = strchr(p, '\n');
}
}
if (e) {
ks_append_n(ct, (char *)p, e - p);
KX_NET_GET_BUFFER(ctt, obj, "isContentTypeText");
// If a user sets it already, there's no change here.
// '-' means a user did no mode change at the moment.
if (ks_string(ctt)[0] == '-') {
if (strcmp(ks_string(ct), "application/json") == 0 || strncmp(ks_string(ct), "text/", 5) == 0) {
ks_string(ctt)[0] = '1';
}
}
}
}
}
return bufsz;
}

static size_t Net_writeCallback(void *ptr, size_t size, size_t nmemb, void *userp)
{
kx_obj_t *obj = (kx_obj_t *)userp;
size_t bufsz = size * nmemb;
KX_NET_GET_BUFFER(sv, obj, "received");
if (!sv) {
return bufsz;

int is_bin;
KX_NET_GET_BUFFER(ctt, obj, "isContentTypeText");
if (ks_string(ctt)[0] == '1') {
is_bin = 0;
} else {
is_bin = 1;
}
if (is_bin) {
KX_NET_GET_BIN_BUFFER(bin, obj, "receivedbin");
char *p = (char *)ptr;
int i = 0, sz = bufsz;
while (sz--) {
*kv_pushp(uint8_t, bin->bin) = *p++;
}
} else {
KX_NET_GET_BUFFER(sv, obj, "received");
if (!sv) {
return bufsz;
}
ks_append_n(sv, (char *)ptr, bufsz);
}

ks_append_n(sv, (char *)ptr, bufsz);
return bufsz;
}

Expand Down Expand Up @@ -486,7 +538,10 @@ int Net_createCurlHandler(int args, kx_frm_t *frmv, kx_frm_t *lexv, kx_context_t
KEX_SET_PROP_ANY(obj, "_curl", info);
KEX_SET_PROP_INT(obj, "isRunning", 0);
KEX_SET_PROP_CSTR(obj, "header", "");
KEX_SET_PROP_CSTR(obj, "contentType", "");
KEX_SET_PROP_CSTR(obj, "isContentTypeText", "-");
KEX_SET_PROP_CSTR(obj, "received", "");
KEX_SET_PROP_BIN(obj, "receivedbin", allocate_bin(ctx));
KEX_SET_PROP_CSTR(obj, "debugInfo", "");

curl_easy_setopt(ci->eh, CURLOPT_WRITEFUNCTION, Net_writeCallback);
Expand Down

0 comments on commit b2ded31

Please sign in to comment.