viewer: move JFJochHttpReader to the viewer and switch it to libcurl
JFJochHttpReader (the viewer's live-broker HTTP client) is the only HTTP client
in the reader library and the only piece that needs TLS + Kerberos. Moving it out
of the always-built JFJochReader keeps the broker/writer free of a TLS/Kerberos
stack; switching it from cpp-httplib to libcurl gives the viewer HTTPS and, later,
GSSAPI/Bearer auth.
- Move reader/JFJochHttpReader.{cpp,h} -> viewer/, compiled into jfjoch_viewer.
- Rewrite the 10 httplib call sites onto one libcurl easy-handle Request() helper
(GET + PUT, binary/JSON bodies; status/transport handling preserved).
- CMake: FetchContent libcurl, STATIC, HTTP(S)-only, only for viewer builds.
OS-native backends keep Windows self-contained (Schannel+SSPI); Linux uses
system OpenSSL + GSSAPI (krb5). Drop httplib from JFJochReader.
- Block httplib OpenSSL auto-link (HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF) so the
broker stops pulling in libssl/libcrypto for HTTPS it never serves.
- docker: add krb5 dev headers (libkrb5-dev / krb5-devel) for CURL_USE_GSSAPI.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -161,6 +161,11 @@ FetchContent_Declare(
|
||||
# (gzip/zlib is enough for the broker), so disable it to avoid linking libbrotli.
|
||||
SET(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# httplib auto-enables HTTPS by linking system OpenSSL whenever it finds it. The broker serves
|
||||
# plain HTTP only (TLS, if ever wanted, is terminated by a front reverse proxy), so disable it --
|
||||
# otherwise jfjoch_broker would pull in libssl/libcrypto for no reason.
|
||||
SET(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# ZeroMQ (libzmq): fetch it here, at the top level, so that THIS project - not
|
||||
# slsDetectorPackage - controls the version. slsDetectorPackage bundles its own libzmq
|
||||
# archive, but only populates it behind `if(NOT libzmq_POPULATED)`; by making libzmq
|
||||
@@ -264,6 +269,35 @@ IF (WIN32)
|
||||
TARGET_INCLUDE_DIRECTORIES(wingetopt PUBLIC tools/wingetopt)
|
||||
ENDIF()
|
||||
|
||||
# libcurl: the jfjoch_viewer HTTP client (viewer/JFJochHttpReader). Fetched and STATICALLY linked
|
||||
# ONLY for viewer builds, so the broker/writer never pull in a TLS/Kerberos stack. Backends are
|
||||
# OS-native per platform to keep the Windows build self-contained: Schannel (TLS) + SSPI
|
||||
# (Negotiate/Kerberos) on Windows -- no external OpenSSL/krb5 -- and system OpenSSL + GSSAPI (krb5)
|
||||
# on Linux. Trimmed to HTTP(S) only, mirroring the libtiff codec pruning above.
|
||||
IF (JFJOCH_VIEWER_BUILD OR JFJOCH_VIEWER_ONLY)
|
||||
SET(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE)
|
||||
SET(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) # static libcurl only, never a shared lib
|
||||
SET(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
||||
SET(BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||
SET(CURL_DISABLE_INSTALL ON CACHE BOOL "" FORCE)
|
||||
SET(HTTP_ONLY ON CACHE BOOL "" FORCE) # HTTP/HTTPS only; drop FTP/LDAP/SMTP/...
|
||||
SET(CURL_USE_LIBPSL OFF CACHE BOOL "" FORCE) # avoid the libpsl dependency
|
||||
SET(CURL_USE_LIBSSH2 OFF CACHE BOOL "" FORCE)
|
||||
SET(CURL_ZLIB ON CACHE BOOL "" FORCE) # reuse the project's ZLIB
|
||||
IF (WIN32)
|
||||
SET(CURL_USE_SCHANNEL ON CACHE BOOL "" FORCE) # native Windows TLS (no OpenSSL)
|
||||
SET(CURL_USE_SSPI ON CACHE BOOL "" FORCE) # native Negotiate/Kerberos (no krb5)
|
||||
ELSE()
|
||||
SET(CURL_USE_OPENSSL ON CACHE BOOL "" FORCE)
|
||||
SET(CURL_USE_GSSAPI ON CACHE BOOL "" FORCE) # Kerberos via system krb5 (needs krb5-dev)
|
||||
ENDIF()
|
||||
FetchContent_Declare(curl
|
||||
GIT_REPOSITORY https://github.com/curl/curl.git
|
||||
GIT_TAG curl-8_11_1
|
||||
EXCLUDE_FROM_ALL)
|
||||
FetchContent_MakeAvailable(curl)
|
||||
ENDIF()
|
||||
|
||||
IF (JFJOCH_VIEWER_ONLY)
|
||||
# Minimal subtree: jfjoch_viewer and only the libraries it transitively links.
|
||||
# (broker here provides JFJochAPI only; its service targets are gated out.)
|
||||
|
||||
@@ -51,6 +51,7 @@ RUN dnf -y update && \
|
||||
mesa-libGL-devel \
|
||||
mesa-libEGL-devel \
|
||||
dbus-devel \
|
||||
krb5-devel \
|
||||
zlib-devel \
|
||||
zlib-static \
|
||||
glib2-devel \
|
||||
|
||||
@@ -58,6 +58,7 @@ RUN dnf -y update && \
|
||||
mesa-libGL-devel \
|
||||
mesa-libEGL-devel \
|
||||
dbus-devel \
|
||||
krb5-devel \
|
||||
zlib-devel \
|
||||
zlib-static \
|
||||
glib2-devel \
|
||||
|
||||
@@ -41,6 +41,7 @@ RUN set -eux; \
|
||||
dpkg-dev \
|
||||
fakeroot \
|
||||
libnuma-dev \
|
||||
libkrb5-dev \
|
||||
libxcb1-dev \
|
||||
libx11-dev \
|
||||
libxext-dev \
|
||||
|
||||
@@ -41,6 +41,7 @@ RUN set -eux; \
|
||||
dpkg-dev \
|
||||
fakeroot \
|
||||
libnuma-dev \
|
||||
libkrb5-dev \
|
||||
libxcb1-dev \
|
||||
libx11-dev \
|
||||
libxext-dev \
|
||||
|
||||
@@ -12,11 +12,12 @@ ADD_LIBRARY(JFJochReader STATIC
|
||||
JFJochReaderImage.h
|
||||
JFJochReaderDataset.cpp
|
||||
JFJochReaderDataset.h
|
||||
JFJochHttpReader.cpp
|
||||
JFJochHttpReader.h
|
||||
JFJochReaderSpots.h
|
||||
)
|
||||
|
||||
# NB: JFJochHttpReader (the viewer's live-broker HTTP client) lives in viewer/ and links libcurl;
|
||||
# it is deliberately NOT part of this always-built library, so the broker/writer never pull in a
|
||||
# TLS/Kerberos stack.
|
||||
TARGET_LINK_LIBRARIES(JFJochReader JFJochImageAnalysis JFJochAPI JFJochCommon JFJochZMQ JFJochLogger
|
||||
JFJochHDF5Wrappers CBORStream2FrameSerialize
|
||||
httplib::httplib ${CMAKE_DL_LIBS})
|
||||
${CMAKE_DL_LIBS})
|
||||
|
||||
@@ -29,6 +29,8 @@ ADD_EXECUTABLE(jfjoch_viewer jfjoch_viewer.cpp JFJochViewerWindow.cpp JFJochView
|
||||
image_viewer/JFJochSimpleImage.h
|
||||
JFJochImageReadingWorker.cpp
|
||||
JFJochImageReadingWorker.h
|
||||
JFJochHttpReader.cpp
|
||||
JFJochHttpReader.h
|
||||
RunData.h
|
||||
JFJochProcessController.cpp
|
||||
JFJochProcessController.h
|
||||
@@ -111,7 +113,7 @@ ADD_EXECUTABLE(jfjoch_viewer jfjoch_viewer.cpp JFJochViewerWindow.cpp JFJochView
|
||||
TARGET_LINK_LIBRARIES(jfjoch_viewer Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Charts Qt6::Concurrent
|
||||
Qt6::OpenGL Qt6::OpenGLWidgets
|
||||
JFJochReader JFJochLogger JFJochCommon JFJochWriter JFJochImageAnalysis Rugnux
|
||||
fftw3f)
|
||||
fftw3f CURL::libcurl)
|
||||
|
||||
# Native GUI app per platform: a .app bundle on macOS, GUI subsystem (no console window) on
|
||||
# Windows. Each property is ignored on the platforms it does not apply to, so set both always.
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
#include "JFJochHttpReader.h"
|
||||
|
||||
#include <httplib.h>
|
||||
#include <curl/curl.h>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "../frame_serialize/CBORStream2Deserializer.h"
|
||||
#include "../broker/gen/model/Image_buffer_status.h"
|
||||
@@ -13,6 +15,60 @@
|
||||
#include "../common/JFJochMath.h"
|
||||
#include "../image_analysis/bragg_integration/CalcISigma.h"
|
||||
|
||||
namespace {
|
||||
// libcurl write callback: append the received bytes to a std::string (which holds binary fine).
|
||||
size_t AppendToString(char *ptr, size_t size, size_t nmemb, void *userdata) {
|
||||
auto *out = static_cast<std::string *>(userdata);
|
||||
out->append(ptr, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
// libcurl needs a one-time global init before any easy handle is used; do it once and
|
||||
// thread-safely, as the viewer drives the reader from a worker thread.
|
||||
void EnsureCurlGlobalInit() {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [] { curl_global_init(CURL_GLOBAL_DEFAULT); });
|
||||
}
|
||||
}
|
||||
|
||||
JFJochHttpReader::HttpResult JFJochHttpReader::Request(const std::string &method, const std::string &path,
|
||||
const std::string &body,
|
||||
const std::string &content_type) const {
|
||||
EnsureCurlGlobalInit();
|
||||
|
||||
CURL *curl = curl_easy_init();
|
||||
if (curl == nullptr)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Could not initialize CURL");
|
||||
|
||||
HttpResult result;
|
||||
const std::string url = addr + path;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, AppendToString);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result.body);
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); // safe to use from worker threads
|
||||
|
||||
curl_slist *headers = nullptr;
|
||||
if (method == "PUT") {
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.data());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
|
||||
if (!content_type.empty())
|
||||
headers = curl_slist_append(headers, ("Content-Type: " + content_type).c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
}
|
||||
|
||||
if (curl_easy_perform(curl) == CURLE_OK) {
|
||||
result.ok = true;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &result.status);
|
||||
}
|
||||
|
||||
if (headers != nullptr)
|
||||
curl_slist_free_all(headers);
|
||||
curl_easy_cleanup(curl);
|
||||
return result;
|
||||
}
|
||||
|
||||
void JFJochHttpReader::Close() {
|
||||
std::unique_lock ul(http_mutex);
|
||||
addr = "";
|
||||
@@ -24,15 +80,13 @@ void JFJochHttpReader::Close() {
|
||||
}
|
||||
|
||||
ImageBufferStatus JFJochHttpReader::GetImageBufferStatus() const {
|
||||
httplib::Client cli_cmd(addr);
|
||||
|
||||
auto res = cli_cmd.Get("/image_buffer/status");
|
||||
if (!res || res->status != httplib::StatusCode::OK_200)
|
||||
auto res = Request("GET", "/image_buffer/status");
|
||||
if (!res.ok || res.status != 200)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Could not get image buffer status");
|
||||
|
||||
try {
|
||||
org::openapitools::server::model::Image_buffer_status status = nlohmann::json::parse(res->body);
|
||||
org::openapitools::server::model::Image_buffer_status status = nlohmann::json::parse(res.body);
|
||||
ImageBufferStatus ret{};
|
||||
ret.max_image_number = status.getMaxImageNumber();
|
||||
ret.min_image_number = status.getMinImageNumber();
|
||||
@@ -49,15 +103,13 @@ ImageBufferStatus JFJochHttpReader::GetImageBufferStatus() const {
|
||||
}
|
||||
|
||||
BrokerStatus JFJochHttpReader::GetBrokerStatus() const {
|
||||
httplib::Client cli_cmd(addr);
|
||||
|
||||
auto res = cli_cmd.Get("/status");
|
||||
if (!res || res->status != httplib::StatusCode::OK_200)
|
||||
auto res = Request("GET", "/status");
|
||||
if (!res.ok || res.status != 200)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Could not get broker status");
|
||||
|
||||
try {
|
||||
org::openapitools::server::model::Broker_status input = nlohmann::json::parse(res->body);
|
||||
org::openapitools::server::model::Broker_status input = nlohmann::json::parse(res.body);
|
||||
BrokerStatus ret{};
|
||||
ret.broker_version = input.getBrokerVersion();
|
||||
ret.gpu_count = input.getGpuCount();
|
||||
@@ -107,22 +159,19 @@ uint64_t JFJochHttpReader::GetNumberOfImages() const {
|
||||
}
|
||||
|
||||
std::shared_ptr<JFJochReaderDataset> JFJochHttpReader::UpdateDataset_i() {
|
||||
httplib::Client cli_cmd(addr);
|
||||
auto res = Request("GET", "/image_buffer/start.cbor");
|
||||
|
||||
auto res = cli_cmd.Get("/image_buffer/start.cbor");
|
||||
|
||||
if (!res || (res->status != httplib::StatusCode::OK_200
|
||||
&& res->status != httplib::StatusCode::NotFound_404))
|
||||
if (!res.ok || (res.status != 200 && res.status != 404))
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Could not get image buffer status");
|
||||
|
||||
if (res->status == httplib::StatusCode::NotFound_404)
|
||||
if (res.status == 404)
|
||||
return {};
|
||||
if (res->body.empty())
|
||||
if (res.body.empty())
|
||||
return {};
|
||||
|
||||
try {
|
||||
auto msg = CBORStream2Deserialize(res->body);
|
||||
auto msg = CBORStream2Deserialize(res.body);
|
||||
|
||||
if (msg->msg_type != CBORImageType::START)
|
||||
return {};
|
||||
@@ -259,8 +308,6 @@ bool JFJochHttpReader::LoadImage_i(std::shared_ptr<JFJochReaderDataset> &dataset
|
||||
if (addr.empty())
|
||||
return false;
|
||||
|
||||
httplib::Client cli_cmd(addr);
|
||||
|
||||
bool buffer_changed = false;
|
||||
|
||||
// For autoupdate - if buffer didn't change don't update dataset
|
||||
@@ -285,18 +332,18 @@ bool JFJochHttpReader::LoadImage_i(std::shared_ptr<JFJochReaderDataset> &dataset
|
||||
if (!dataset)
|
||||
return false;
|
||||
|
||||
auto res = cli_cmd.Get("/image_buffer/image.cbor?id=" + std::to_string(image_number));
|
||||
auto res = Request("GET", "/image_buffer/image.cbor?id=" + std::to_string(image_number));
|
||||
|
||||
if (!res || res->status != httplib::StatusCode::OK_200)
|
||||
if (!res.ok || res.status != 200)
|
||||
return false;
|
||||
|
||||
if (res->body.empty()) {
|
||||
if (res.body.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
buffer.resize(res->body.size());
|
||||
memcpy(buffer.data(), res->body.data(), res->body.size());
|
||||
buffer.resize(res.body.size());
|
||||
memcpy(buffer.data(), res.body.data(), res.body.size());
|
||||
|
||||
auto msg = CBORStream2Deserialize(buffer);
|
||||
|
||||
@@ -318,15 +365,14 @@ std::shared_ptr<JFJochReaderRawImage> JFJochHttpReader::GetRawImage(int64_t imag
|
||||
if (addr.empty())
|
||||
return {};
|
||||
|
||||
httplib::Client cli_cmd(addr);
|
||||
auto res = cli_cmd.Get("/image_buffer/image.cbor?id=" + std::to_string(image_number));
|
||||
auto res = Request("GET", "/image_buffer/image.cbor?id=" + std::to_string(image_number));
|
||||
|
||||
if (!res || res->status != httplib::StatusCode::OK_200 || res->body.empty())
|
||||
if (!res.ok || res.status != 200 || res.body.empty())
|
||||
return {};
|
||||
|
||||
try {
|
||||
auto msg =
|
||||
CBORStream2Deserialize(reinterpret_cast<uint8_t *>(res->body.data()), res->body.size());
|
||||
CBORStream2Deserialize(reinterpret_cast<uint8_t *>(res.body.data()), res.body.size());
|
||||
|
||||
if (msg->msg_type != CBORImageType::IMAGE)
|
||||
return {};
|
||||
@@ -355,26 +401,24 @@ std::vector<float> JFJochHttpReader::GetPlot_i(const std::string &plot_type, flo
|
||||
if (addr.empty())
|
||||
return {};
|
||||
|
||||
httplib::Client cli_cmd(addr);
|
||||
|
||||
auto res_bin = cli_cmd.Get("/preview/plot.bin?type=" + plot_type);
|
||||
if (res_bin && res_bin->status == httplib::StatusCode::OK_200) {
|
||||
if (res_bin->body.size() % sizeof(float) != 0) {
|
||||
auto res_bin = Request("GET", "/preview/plot.bin?type=" + plot_type);
|
||||
if (res_bin.ok && res_bin.status == 200) {
|
||||
if (res_bin.body.size() % sizeof(float) != 0) {
|
||||
throw std::runtime_error("Input size is not a multiple of sizeof(float)");
|
||||
}
|
||||
std::vector<float> v(res_bin->body.size() / sizeof(float));
|
||||
std::memcpy(v.data(), res_bin->body.data(), res_bin->body.size());
|
||||
std::vector<float> v(res_bin.body.size() / sizeof(float));
|
||||
std::memcpy(v.data(), res_bin.body.data(), res_bin.body.size());
|
||||
return v;
|
||||
}
|
||||
|
||||
auto res = cli_cmd.Get("/preview/plot?binning=1&experimental_coord=false&fill="
|
||||
+ std::to_string(fill_value) + "&type=" + plot_type);
|
||||
auto res = Request("GET", "/preview/plot?binning=1&experimental_coord=false&fill="
|
||||
+ std::to_string(fill_value) + "&type=" + plot_type);
|
||||
|
||||
if (!res || res->status != httplib::StatusCode::OK_200)
|
||||
if (!res.ok || res.status != 200)
|
||||
return {};
|
||||
|
||||
try {
|
||||
org::openapitools::server::model::Plots plots = nlohmann::json::parse(res->body);
|
||||
org::openapitools::server::model::Plots plots = nlohmann::json::parse(res.body);
|
||||
auto plot_v = plots.getPlot();
|
||||
if (plot_v.size() == 1)
|
||||
return plot_v[0].getY();
|
||||
@@ -397,21 +441,18 @@ void JFJochHttpReader::UploadUserMask(const std::vector<uint32_t>& mask) {
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"User mask is empty.");
|
||||
|
||||
httplib::Client cli_cmd(addr);
|
||||
|
||||
const char* data_ptr = reinterpret_cast<const char*>(mask.data());
|
||||
const size_t byte_size = mask.size() * sizeof(uint32_t);
|
||||
|
||||
auto res = cli_cmd.Put("/config/user_mask",
|
||||
data_ptr,
|
||||
byte_size,
|
||||
"application/octet-stream");
|
||||
auto res = Request("PUT", "/config/user_mask",
|
||||
std::string(data_ptr, byte_size),
|
||||
"application/octet-stream");
|
||||
|
||||
if (!res)
|
||||
if (!res.ok)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Failed to connect to server to upload user mask");
|
||||
|
||||
if (res->status != httplib::StatusCode::OK_200)
|
||||
if (res.status != 200)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Server rejected user mask upload");
|
||||
}
|
||||
@@ -421,12 +462,11 @@ ROIDefinition JFJochHttpReader::GetROIDefinitions() const {
|
||||
if (addr.empty())
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "HTTP address not set");
|
||||
|
||||
httplib::Client cli_cmd(addr);
|
||||
auto res = cli_cmd.Get("/config/roi");
|
||||
if (!res || res->status != httplib::StatusCode::OK_200)
|
||||
auto res = Request("GET", "/config/roi");
|
||||
if (!res.ok || res.status != 200)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Could not get ROI definitions");
|
||||
|
||||
org::openapitools::server::model::Roi_definitions input = nlohmann::json::parse(res->body);
|
||||
org::openapitools::server::model::Roi_definitions input = nlohmann::json::parse(res.body);
|
||||
ROIDefinition out;
|
||||
for (const auto &i : input.getBox().getRois())
|
||||
out.boxes.emplace_back(i.getName(), i.getMinXPxl(), i.getMaxXPxl(), i.getMinYPxl(), i.getMaxYPxl());
|
||||
@@ -494,12 +534,11 @@ void JFJochHttpReader::UploadROIDefinitions(const ROIDefinition &rois) const {
|
||||
out.setAzim(al);
|
||||
|
||||
nlohmann::json j = out;
|
||||
httplib::Client cli_cmd(addr);
|
||||
auto res = cli_cmd.Put("/config/roi", j.dump(), "application/json");
|
||||
if (!res)
|
||||
auto res = Request("PUT", "/config/roi", j.dump(), "application/json");
|
||||
if (!res.ok)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Failed to connect to server to upload ROIs");
|
||||
if (res->status != httplib::StatusCode::OK_200)
|
||||
if (res.status != 200)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Server rejected ROI upload");
|
||||
}
|
||||
|
||||
@@ -513,14 +552,13 @@ std::vector<SpotToSave> JFJochHttpReader::ReadSpots(int64_t image) const {
|
||||
if (addr.empty())
|
||||
return {};
|
||||
|
||||
httplib::Client cli_cmd(addr);
|
||||
auto res = cli_cmd.Get("/image_buffer/image.cbor?id=" + std::to_string(image));
|
||||
auto res = Request("GET", "/image_buffer/image.cbor?id=" + std::to_string(image));
|
||||
|
||||
if (!res || res->status != httplib::StatusCode::OK_200 || res->body.empty())
|
||||
if (!res.ok || res.status != 200 || res.body.empty())
|
||||
return {};
|
||||
|
||||
try {
|
||||
auto msg = CBORStream2Deserialize(res->body);
|
||||
auto msg = CBORStream2Deserialize(res.body);
|
||||
|
||||
if (msg->msg_type != CBORImageType::IMAGE)
|
||||
return {};
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JFJochReader.h"
|
||||
#include "../reader/JFJochReader.h"
|
||||
#include "../common/BrokerStatus.h"
|
||||
#include "../common/ImageBuffer.h"
|
||||
#include "../common/ROIDefinition.h"
|
||||
@@ -20,6 +20,18 @@ class JFJochHttpReader : public JFJochReader {
|
||||
std::shared_ptr<const PixelMask> cached_pixel_mask;
|
||||
std::string cached_pixel_mask_arm_date;
|
||||
|
||||
// Minimal HTTP result: whether a response arrived (transport-level success), the HTTP status
|
||||
// code, and the (possibly binary) response body.
|
||||
struct HttpResult {
|
||||
bool ok = false;
|
||||
long status = 0;
|
||||
std::string body;
|
||||
};
|
||||
// Single libcurl request helper behind every endpoint call. method is "GET" or "PUT"; for PUT
|
||||
// the body is sent with the given content_type.
|
||||
HttpResult Request(const std::string &method, const std::string &path,
|
||||
const std::string &body = {}, const std::string &content_type = {}) const;
|
||||
|
||||
ImageBufferStatus GetImageBufferStatus() const;
|
||||
|
||||
bool LoadImage_i(std::shared_ptr<JFJochReaderDataset> &dataset,
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "../reader/JFJochHDF5Reader.h"
|
||||
#include "../common/Logger.h"
|
||||
#include "../reader/JFJochHttpReader.h"
|
||||
#include "JFJochHttpReader.h"
|
||||
#include "../image_analysis/MXAnalysisWithoutFPGA.h"
|
||||
#include "../common/BraggIntegrationSettings.h"
|
||||
#include "../common/ScalingSettings.h"
|
||||
|
||||
Reference in New Issue
Block a user