Skip to content

Commit a8d4cbd

Browse files
committed
Add C API to get HTTP responses
1 parent f68a2fc commit a8d4cbd

File tree

3 files changed

+147
-1
lines changed

3 files changed

+147
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Changes
66
- Add `get_http_response` JSON-RPC API.
7+
- Add C API to get HTTP responses.
78

89
## [1.112.7] - 2023-04-17
910

deltachat-ffi/deltachat.h

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef struct _dc_event dc_event_t;
2525
typedef struct _dc_event_emitter dc_event_emitter_t;
2626
typedef struct _dc_jsonrpc_instance dc_jsonrpc_instance_t;
2727
typedef struct _dc_backup_provider dc_backup_provider_t;
28+
typedef struct _dc_http_response dc_http_response_t;
2829

2930
// Alias for backwards compatibility, use dc_event_emitter_t instead.
3031
typedef struct _dc_event_emitter dc_accounts_event_emitter_t;
@@ -5057,6 +5058,63 @@ int dc_provider_get_status (const dc_provider_t* prov
50575058
void dc_provider_unref (dc_provider_t* provider);
50585059

50595060

5061+
/**
5062+
* Return an HTTP(S) GET response.
5063+
* This function can be used to download remote content for HTML emails.
5064+
*
5065+
* @memberof dc_context_t
5066+
* @param context The context object to take proxy settings from.
5067+
* @param url HTTP or HTTPS URL.
5068+
* @return The response must be released using dc_http_response_unref() after usage.
5069+
* NULL is returned on errors.
5070+
*/
5071+
dc_http_response_t* dc_get_http_response (const dc_context_t* context, const char* url);
5072+
5073+
/**
5074+
* Returns HTTP response MIME type as a string, e.g. "text/plain" or "text/html".
5075+
*
5076+
* @memberof dc_http_response_t
5077+
* @param response HTTP response as returned by dc_get_http_response().
5078+
* @return The string which must be released using dc_str_unref() after usage. May be NULL.
5079+
*/
5080+
char* dc_http_response_get_mimetype (const dc_http_response_t* response);
5081+
5082+
/**
5083+
* Returns HTTP response encoding, e.g. "utf-8".
5084+
*
5085+
* @memberof dc_http_response_t
5086+
* @param response HTTP response as returned by dc_get_http_response().
5087+
* @return The string which must be released using dc_str_unref() after usage. May be NULL.
5088+
*/
5089+
char* dc_http_response_get_encoding (const dc_http_response_t* response);
5090+
5091+
/**
5092+
* Returns HTTP response contents.
5093+
*
5094+
* @memberof dc_http_response_t
5095+
* @param response HTTP response as returned by dc_get_http_response().
5096+
* @return The blob which must be released using dc_str_unref() after usage. NULL is never returned.
5097+
*/
5098+
uint8_t* dc_http_response_get_blob (const dc_http_response_t* response);
5099+
5100+
/**
5101+
* Returns HTTP response content size.
5102+
*
5103+
* @memberof dc_http_response_t
5104+
* @param response HTTP response as returned by dc_get_http_response().
5105+
* @return The blob size.
5106+
*/
5107+
size_t dc_http_response_get_size (const dc_http_response_t* response);
5108+
5109+
/**
5110+
* Free an HTTP response object.
5111+
*
5112+
* @memberof dc_http_response_t
5113+
* @param response HTTP response as returned by dc_get_http_response().
5114+
*/
5115+
void dc_http_response_unref (const dc_http_response_t* response);
5116+
5117+
50605118
/**
50615119
* @class dc_lot_t
50625120
*
@@ -5534,7 +5592,6 @@ void dc_reactions_unref (dc_reactions_t* reactions);
55345592
*/
55355593

55365594

5537-
55385595
/**
55395596
* @class dc_jsonrpc_instance_t
55405597
*

deltachat-ffi/src/lib.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use deltachat::ephemeral::Timer as EphemeralTimer;
3131
use deltachat::imex::BackupProvider;
3232
use deltachat::key::DcKey;
3333
use deltachat::message::MsgId;
34+
use deltachat::net::read_url_blob;
3435
use deltachat::qr_code_generator::{generate_backup_qr, get_securejoin_qr_svg};
3536
use deltachat::reaction::{get_msg_reactions, send_reaction, Reactions};
3637
use deltachat::stock_str::StockMessage;
@@ -4467,6 +4468,93 @@ pub unsafe extern "C" fn dc_provider_unref(provider: *mut dc_provider_t) {
44674468
// this may change once we start localizing string.
44684469
}
44694470

4471+
// dc_http_response_t
4472+
4473+
pub type dc_http_response_t = net::HttpResponse;
4474+
4475+
#[no_mangle]
4476+
pub unsafe extern "C" fn dc_get_http_response(
4477+
context: *const dc_context_t,
4478+
url: *const libc::c_char,
4479+
) -> *mut dc_http_response_t {
4480+
if context.is_null() || url.is_null() {
4481+
eprintln!("ignoring careless call to dc_get_http_response()");
4482+
return ptr::null_mut();
4483+
}
4484+
4485+
let context = &*context;
4486+
let url = to_string_lossy(url);
4487+
if let Ok(response) = block_on(read_url_blob(context, &url)).log_err(context, "read_url_blob") {
4488+
Box::into_raw(Box::new(response))
4489+
} else {
4490+
ptr::null_mut()
4491+
}
4492+
}
4493+
4494+
#[no_mangle]
4495+
pub unsafe extern "C" fn dc_http_response_get_mimetype(
4496+
response: *const dc_http_response_t,
4497+
) -> *mut libc::c_char {
4498+
if response.is_null() {
4499+
eprintln!("ignoring careless call to dc_http_response_get_mimetype()");
4500+
return ptr::null_mut();
4501+
}
4502+
4503+
let response = &*response;
4504+
response.mimetype.strdup()
4505+
}
4506+
4507+
#[no_mangle]
4508+
pub unsafe extern "C" fn dc_http_response_get_encoding(
4509+
response: *const dc_http_response_t,
4510+
) -> *mut libc::c_char {
4511+
if response.is_null() {
4512+
eprintln!("ignoring careless call to dc_http_response_get_encoding()");
4513+
return ptr::null_mut();
4514+
}
4515+
4516+
let response = &*response;
4517+
response.encoding.strdup()
4518+
}
4519+
4520+
#[no_mangle]
4521+
pub unsafe extern "C" fn dc_http_response_get_blob(
4522+
response: *const dc_http_response_t,
4523+
) -> *mut libc::c_char {
4524+
if response.is_null() {
4525+
eprintln!("ignoring careless call to dc_http_response_get_blob()");
4526+
return ptr::null_mut();
4527+
}
4528+
4529+
let response = &*response;
4530+
let blob_len = response.blob.len();
4531+
let ptr = libc::malloc(blob_len);
4532+
libc::memcpy(ptr, response.blob.as_ptr() as *mut libc::c_void, blob_len);
4533+
ptr as *mut libc::c_char
4534+
}
4535+
4536+
#[no_mangle]
4537+
pub unsafe extern "C" fn dc_http_response_get_size(
4538+
response: *const dc_http_response_t,
4539+
) -> libc::size_t {
4540+
if response.is_null() {
4541+
eprintln!("ignoring careless call to dc_http_response_get_size()");
4542+
return 0;
4543+
}
4544+
4545+
let response = &*response;
4546+
response.blob.len()
4547+
}
4548+
4549+
#[no_mangle]
4550+
pub unsafe extern "C" fn dc_http_response_unref(response: *mut dc_http_response_t) {
4551+
if response.is_null() {
4552+
eprintln!("ignoring careless call to dc_http_response_unref()");
4553+
return;
4554+
}
4555+
drop(Box::from_raw(response));
4556+
}
4557+
44704558
// -- Accounts
44714559

44724560
/// Reader-writer lock wrapper for accounts manager to guarantee thread safety when using

0 commit comments

Comments
 (0)