update include

main
HwangKC 2024-05-24 12:29:09 +08:00
parent 27cbb3875e
commit 7cf1e2f74c
241 changed files with 35469 additions and 1032 deletions

249
sdk/include/cgic.h 100644
View File

@ -0,0 +1,249 @@
/* The CGI_C library, by Thomas Boutell, version 2.01. CGI_C is intended
to be a high-quality API to simplify CGI programming tasks. */
/* Make sure this is only included once. */
#ifndef CGI_C
#define CGI_C 1
/* Ensure proper linkage to c++ programs. */
#ifdef __cplusplus
extern "C" {
#endif
/* Bring in standard I/O since some of the functions refer to
types defined by it, such as FILE *. */
#include <stdio.h>
/* The various CGI environment variables. Instead of using getenv(),
the programmer should refer to these, which are always
valid null-terminated strings (they may be empty, but they
will never be null). If these variables are used instead
of calling getenv(), then it will be possible to save
and restore CGI environments, which is highly convenient
for debugging. */
extern char *cgiServerSoftware;
extern char *cgiServerName;
extern char *cgiGatewayInterface;
extern char *cgiServerProtocol;
extern char *cgiServerPort;
extern char *cgiRequestMethod;
extern char *cgiPathInfo;
extern char *cgiPathTranslated;
extern char *cgiScriptName;
extern char *cgiQueryString;
extern char *cgiRemoteHost;
extern char *cgiRemoteAddr;
extern char *cgiAuthType;
extern char *cgiRemoteUser;
extern char *cgiRemoteIdent;
extern char *cgiContentType;
extern char *cgiAccept;
extern char *cgiUserAgent;
extern char *cgiReferrer;
/* Cookies as sent to the server. You can also get them
individually, or as a string array; see the documentation. */
extern char *cgiCookie;
/* A macro providing the same incorrect spelling that is
found in the HTTP/CGI specifications */
#define cgiReferer cgiReferrer
/* The number of bytes of data received.
Note that if the submission is a form submission
the library will read and parse all the information
directly from cgiIn; the programmer need not do so. */
extern int cgiContentLength;
/* Pointer to CGI output. The cgiHeader functions should be used
first to output the mime headers; the output HTML
page, GIF image or other web document should then be written
to cgiOut by the programmer. In the standard CGIC library,
cgiOut is always equivalent to stdout. */
extern FILE *cgiOut;
/* Pointer to CGI input. The programmer does not read from this.
We have continued to export it for backwards compatibility
so that cgic 1.x applications link properly. */
extern FILE *cgiIn;
/* Possible return codes from the cgiForm family of functions (see below). */
typedef enum {
cgiFormSuccess,
cgiFormTruncated,
cgiFormBadType,
cgiFormEmpty,
cgiFormNotFound,
cgiFormConstrained,
cgiFormNoSuchChoice,
cgiFormMemory,
cgiFormNoFileName,
cgiFormNoContentType,
cgiFormNotAFile,
cgiFormOpenFailed,
cgiFormIO,
cgiFormEOF
} cgiFormResultType;
/* These functions are used to retrieve form data. See
cgic.html for documentation. */
extern cgiFormResultType cgiFormString(
char *name, char *result, int max);
extern cgiFormResultType cgiFormStringNoNewlines(
char *name, char *result, int max);
extern cgiFormResultType cgiFormStringSpaceNeeded(
char *name, int *length);
extern cgiFormResultType cgiFormStringMultiple(
char *name, char ***ptrToStringArray);
extern void cgiStringArrayFree(char **stringArray);
extern cgiFormResultType cgiFormInteger(
char *name, int *result, int defaultV);
extern cgiFormResultType cgiFormIntegerBounded(
char *name, int *result, int min, int max, int defaultV);
extern cgiFormResultType cgiFormDouble(
char *name, double *result, double defaultV);
extern cgiFormResultType cgiFormDoubleBounded(
char *name, double *result, double min, double max, double defaultV);
extern cgiFormResultType cgiFormSelectSingle(
char *name, char **choicesText, int choicesTotal,
int *result, int defaultV);
extern cgiFormResultType cgiFormSelectMultiple(
char *name, char **choicesText, int choicesTotal,
int *result, int *invalid);
/* Just an alias; users have asked for this */
#define cgiFormSubmitClicked cgiFormCheckboxSingle
extern cgiFormResultType cgiFormCheckboxSingle(
char *name);
extern cgiFormResultType cgiFormCheckboxMultiple(
char *name, char **valuesText, int valuesTotal,
int *result, int *invalid);
extern cgiFormResultType cgiFormRadio(
char *name, char **valuesText, int valuesTotal,
int *result, int defaultV);
/* The paths returned by this function are the original names of files
as reported by the uploading web browser and shoult NOT be
blindly assumed to be "safe" names for server-side use! */
extern cgiFormResultType cgiFormFileName(
char *name, char *result, int max);
/* The content type of the uploaded file, as reported by the browser.
It should NOT be assumed that browsers will never falsify
such information. */
extern cgiFormResultType cgiFormFileContentType(
char *name, char *result, int max);
extern cgiFormResultType cgiFormFileSize(
char *name, int *sizeP);
typedef struct cgiFileStruct *cgiFilePtr;
extern cgiFormResultType cgiFormFileOpen(
char *name, cgiFilePtr *cfpp);
extern cgiFormResultType cgiFormFileRead(
cgiFilePtr cfp, char *buffer, int bufferSize, int *gotP);
extern cgiFormResultType cgiFormFileClose(
cgiFilePtr cfp);
extern cgiFormResultType cgiCookieString(
char *name, char *result, int max);
extern cgiFormResultType cgiCookieInteger(
char *name, int *result, int defaultV);
cgiFormResultType cgiCookies(
char ***ptrToStringArray);
typedef enum {
cgiCookieSecure = 1,
cgiCookieHttpOnly = 2,
cgiCookieSameSiteStrict = 4
} cgiCookieOption;
/* path can be null or empty in which case a path of / (entire site) is set.
domain can be a single web site; if it is an entire domain, such as
'boutell.dev', it should begin with a dot: '.boutell.dev' */
extern void cgiHeaderCookieSet(char *name, char *value,
int secondsToLive, char *path, char *domain, int options);
extern void cgiHeaderCookieSetString(char *name, char *value,
int secondsToLive, char *path, char *domain);
extern void cgiHeaderCookieSetInteger(char *name, int value,
int secondsToLive, char *path, char *domain);
extern void cgiHeaderLocation(char *redirectUrl);
extern void cgiHeaderStatus(int status, char *statusMessage);
extern void cgiHeaderContentType(char *mimeType);
typedef enum {
cgiEnvironmentIO,
cgiEnvironmentMemory,
cgiEnvironmentSuccess,
cgiEnvironmentWrongVersion
} cgiEnvironmentResultType;
extern cgiEnvironmentResultType cgiWriteEnvironment(char *filename);
extern cgiEnvironmentResultType cgiReadEnvironment(char *filename);
extern int cgiMain();
extern cgiFormResultType cgiFormEntries(
char ***ptrToStringArray);
/* Output string with the <, &, and > characters HTML-escaped.
's' is null-terminated. Returns cgiFormIO in the event
of error, cgiFormSuccess otherwise. */
cgiFormResultType cgiHtmlEscape(const char *s);
/* Output data with the <, &, and > characters HTML-escaped.
'data' is not null-terminated; 'len' is the number of
bytes in 'data'. Returns cgiFormIO in the event
of error, cgiFormSuccess otherwise. */
cgiFormResultType cgiHtmlEscapeData(const char *data, int len);
/* Output string with the " character HTML-escaped, and no
other characters escaped. This is useful when outputting
the contents of a tag attribute such as 'href' or 'src'.
's' is null-terminated. Returns cgiFormIO in the event
of error, cgiFormSuccess otherwise. */
cgiFormResultType cgiValueEscape(const char *s);
/* Output data with the " character HTML-escaped, and no
other characters escaped. This is useful when outputting
the contents of a tag attribute such as 'href' or 'src'.
'data' is not null-terminated; 'len' is the number of
bytes in 'data'. Returns cgiFormIO in the event
of error, cgiFormSuccess otherwise. */
cgiFormResultType cgiValueEscapeData(const char *data, int len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CGI_C */

View File

@ -24,26 +24,26 @@
#ifndef _CGIDEFS_H_ #ifndef _CGIDEFS_H_
#define _CGIDEFS_H_ 1 #define _CGIDEFS_H_ 1
/*! \file CgiDefs.h /*! \file CgiDefs.h
* \brief Platform and operating system specific macro definitions. * \brief Platform and operating system specific macro definitions.
* *
* Platform and operating system specific macro definitions that deal * Platform and operating system specific macro definitions that deal
* with namespace support and exporting of library functions. * with namespace support and exporting of library functions.
*/ */
/* /*
// Include information from configure // Include information from configure
#if HAVE_CONFIG_H #if HAVE_CONFIG_H
# include "config.h" # include "config.h"
#endif #endif
*/ */
/*! \namespace cgicc /*! \namespace cgicc
* \brief The namespace containing the cgicc library * \brief The namespace containing the cgicc library
* *
* The namespace containing all classes and functions of the * The namespace containing all classes and functions of the
* GNU cgicc library. * GNU cgicc library.
*/ */
// Win32-specific setup // Win32-specific setup
#ifdef WIN32 #ifdef WIN32
// export library symbols // export library symbols

View File

@ -4,6 +4,7 @@
#include <string> #include <string>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <atomic>
#include "hloop.h" #include "hloop.h"
#include "hsocket.h" #include "hsocket.h"
@ -41,7 +42,13 @@ public:
} }
virtual ~Channel() { virtual ~Channel() {
close(); if (isOpened()) {
close();
// NOTE: Detach after destructor to avoid triggering onclose
if (io_ && id_ == hio_id(io_)) {
hio_set_context(io_, NULL);
}
}
} }
hio_t* io() { return io_; } hio_t* io() { return io_; }
@ -73,6 +80,29 @@ public:
} }
} }
// contextPtr
std::shared_ptr<void> contextPtr() {
return contextPtr_;
}
void setContextPtr(const std::shared_ptr<void>& ctx) {
contextPtr_ = ctx;
}
void setContextPtr(std::shared_ptr<void>&& ctx) {
contextPtr_ = std::move(ctx);
}
template<class T>
std::shared_ptr<T> newContextPtr() {
contextPtr_ = std::make_shared<T>();
return std::static_pointer_cast<T>(contextPtr_);
}
template<class T>
std::shared_ptr<T> getContextPtr() {
return std::static_pointer_cast<T>(contextPtr_);
}
void deleteContextPtr() {
contextPtr_.reset();
}
bool isOpened() { bool isOpened() {
if (io_ == NULL || status >= DISCONNECTED) return false; if (io_ == NULL || status >= DISCONNECTED) return false;
return id_ == hio_id(io_) && hio_is_opened(io_); return id_ == hio_id(io_) && hio_is_opened(io_);
@ -126,13 +156,17 @@ public:
} }
// iobuf setting // iobuf setting
void setReadBuf(void* buf, size_t len) {
if (io_ == NULL) return;
hio_set_readbuf(io_, buf, len);
}
void setMaxReadBufsize(uint32_t size) { void setMaxReadBufsize(uint32_t size) {
if (io_ == NULL) return; if (io_ == NULL) return;
return hio_set_max_read_bufsize(io_, size); hio_set_max_read_bufsize(io_, size);
} }
void setMaxWriteBufsize(uint32_t size) { void setMaxWriteBufsize(uint32_t size) {
if (io_ == NULL) return; if (io_ == NULL) return;
return hio_set_max_write_bufsize(io_, size); hio_set_max_write_bufsize(io_, size);
} }
size_t writeBufsize() { size_t writeBufsize() {
if (io_ == NULL) return 0; if (io_ == NULL) return 0;
@ -144,11 +178,9 @@ public:
// close thread-safe // close thread-safe
int close(bool async = false) { int close(bool async = false) {
if (!isOpened()) return -1; if (isClosed()) return -1;
if (async) { status = CLOSED;
return hio_close_async(io_); return async ? hio_close_async(io_) : hio_close(io_);
}
return hio_close(io_);
} }
public: public:
@ -162,11 +194,13 @@ public:
CONNECTED, CONNECTED,
DISCONNECTED, DISCONNECTED,
CLOSED, CLOSED,
} status; };
std::atomic<Status> status;
std::function<void(Buffer*)> onread; std::function<void(Buffer*)> onread;
// NOTE: Use Channel::isWriteComplete in onwrite callback to determine whether all data has been written. // NOTE: Use Channel::isWriteComplete in onwrite callback to determine whether all data has been written.
std::function<void(Buffer*)> onwrite; std::function<void(Buffer*)> onwrite;
std::function<void()> onclose; std::function<void()> onclose;
std::shared_ptr<void> contextPtr_;
private: private:
static void on_read(hio_t* io, void* data, int readbytes) { static void on_read(hio_t* io, void* data, int readbytes) {
@ -255,13 +289,20 @@ public:
} }
// heartbeat // heartbeat
// NOTE: Beware of circular reference problems caused by passing SocketChannelPtr by value.
void setHeartbeat(int interval_ms, std::function<void()> fn) { void setHeartbeat(int interval_ms, std::function<void()> fn) {
if (io_ == NULL) return; if (io_ == NULL) return;
heartbeat = std::move(fn); heartbeat = std::move(fn);
hio_set_heartbeat(io_, interval_ms, send_heartbeat); hio_set_heartbeat(io_, interval_ms, send_heartbeat);
} }
// unpack /*
* unpack
*
* NOTE: unpack_setting_t of multiple IOs of the same function also are same,
* so only the pointer of unpack_setting_t is stored in hio_t,
* the life time of unpack_setting_t shoud be guaranteed by caller.
*/
void setUnpack(unpack_setting_t* setting) { void setUnpack(unpack_setting_t* setting) {
if (io_ == NULL) return; if (io_ == NULL) return;
hio_set_unpack(io_, setting); hio_set_unpack(io_, setting);

View File

@ -12,7 +12,7 @@ struct Event;
struct Timer; struct Timer;
typedef uint64_t TimerID; typedef uint64_t TimerID;
#define INVALID_TIMER_ID ((TimerID)-1) #define INVALID_TIMER_ID ((hv::TimerID)-1)
typedef std::function<void(Event*)> EventCallback; typedef std::function<void(Event*)> EventCallback;
typedef std::function<void(TimerID)> TimerCallback; typedef std::function<void(TimerID)> TimerCallback;

View File

@ -33,6 +33,7 @@ public:
is_loop_owner = true; is_loop_owner = true;
} }
connectionNum = 0; connectionNum = 0;
nextTimerID = 0;
setStatus(kInitialized); setStatus(kInitialized);
} }
@ -88,48 +89,60 @@ public:
// Timer interfaces: setTimer, killTimer, resetTimer // Timer interfaces: setTimer, killTimer, resetTimer
TimerID setTimer(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE, TimerID timerID = INVALID_TIMER_ID) { TimerID setTimer(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE, TimerID timerID = INVALID_TIMER_ID) {
if (loop_ == NULL) return INVALID_TIMER_ID; if (loop_ == NULL) return INVALID_TIMER_ID;
assertInLoopThread();
htimer_t* htimer = htimer_add(loop_, onTimer, timeout_ms, repeat); htimer_t* htimer = htimer_add(loop_, onTimer, timeout_ms, repeat);
assert(htimer != NULL);
if (timerID == INVALID_TIMER_ID) { if (timerID == INVALID_TIMER_ID) {
timerID = hevent_id(htimer); timerID = generateTimerID();
} else {
hevent_set_id(htimer, timerID);
} }
hevent_set_id(htimer, timerID);
TimerPtr timer = std::make_shared<Timer>(htimer, cb, repeat);
hevent_set_userdata(htimer, this); hevent_set_userdata(htimer, this);
mutex_.lock(); timers[timerID] = std::make_shared<Timer>(htimer, cb, repeat);
timers[timerID] = std::move(timer); return timerID;
mutex_.unlock(); }
// setTimerInLoop thread-safe
TimerID setTimerInLoop(int timeout_ms, TimerCallback cb, uint32_t repeat = INFINITE, TimerID timerID = INVALID_TIMER_ID) {
if (timerID == INVALID_TIMER_ID) {
timerID = generateTimerID();
}
runInLoop(std::bind(&EventLoop::setTimer, this, timeout_ms, cb, repeat, timerID));
return timerID; return timerID;
} }
// alias javascript setTimeout, setInterval // alias javascript setTimeout, setInterval
// setTimeout thread-safe
TimerID setTimeout(int timeout_ms, TimerCallback cb) { TimerID setTimeout(int timeout_ms, TimerCallback cb) {
return setTimer(timeout_ms, cb, 1); return setTimerInLoop(timeout_ms, cb, 1);
} }
// setInterval thread-safe
TimerID setInterval(int interval_ms, TimerCallback cb) { TimerID setInterval(int interval_ms, TimerCallback cb) {
return setTimer(interval_ms, cb, INFINITE); return setTimerInLoop(interval_ms, cb, INFINITE);
} }
// killTimer thread-safe
void killTimer(TimerID timerID) { void killTimer(TimerID timerID) {
std::lock_guard<std::mutex> locker(mutex_); runInLoop([timerID, this](){
auto iter = timers.find(timerID); auto iter = timers.find(timerID);
if (iter != timers.end()) { if (iter != timers.end()) {
htimer_del(iter->second->timer); htimer_del(iter->second->timer);
timers.erase(iter); timers.erase(iter);
} }
});
} }
void resetTimer(TimerID timerID) { // resetTimer thread-safe
std::lock_guard<std::mutex> locker(mutex_); void resetTimer(TimerID timerID, int timeout_ms = 0) {
auto iter = timers.find(timerID); runInLoop([timerID, timeout_ms, this](){
if (iter != timers.end()) { auto iter = timers.find(timerID);
htimer_reset(iter->second->timer); if (iter != timers.end()) {
if (iter->second->repeat == 0) { htimer_reset(iter->second->timer, timeout_ms);
iter->second->repeat = 1; if (iter->second->repeat == 0) {
iter->second->repeat = 1;
}
} }
} });
} }
long tid() { long tid() {
@ -163,7 +176,7 @@ public:
void postEvent(EventCallback cb) { void postEvent(EventCallback cb) {
if (loop_ == NULL) return; if (loop_ == NULL) return;
EventPtr ev(new Event(cb)); EventPtr ev = std::make_shared<Event>(cb);
hevent_set_userdata(&ev->event, this); hevent_set_userdata(&ev->event, this);
ev->event.cb = onCustomEvent; ev->event.cb = onCustomEvent;
@ -175,27 +188,27 @@ public:
} }
private: private:
TimerID generateTimerID() {
return (((TimerID)tid() & 0xFFFFFFFF) << 32) | ++nextTimerID;
}
static void onTimer(htimer_t* htimer) { static void onTimer(htimer_t* htimer) {
EventLoop* loop = (EventLoop*)hevent_userdata(htimer); EventLoop* loop = (EventLoop*)hevent_userdata(htimer);
TimerID timerID = hevent_id(htimer); TimerID timerID = hevent_id(htimer);
TimerPtr timer = NULL; TimerPtr timer = NULL;
loop->mutex_.lock();
auto iter = loop->timers.find(timerID); auto iter = loop->timers.find(timerID);
if (iter != loop->timers.end()) { if (iter != loop->timers.end()) {
timer = iter->second; timer = iter->second;
if (timer->repeat != INFINITE) --timer->repeat; if (timer->repeat != INFINITE) --timer->repeat;
} }
loop->mutex_.unlock();
if (timer) { if (timer) {
if (timer->cb) timer->cb(timerID); if (timer->cb) timer->cb(timerID);
if (timer->repeat == 0) { if (timer->repeat == 0) {
// htimer_t alloc and free by hloop, but timers[timerID] managed by EventLoop. // htimer_t alloc and free by hloop, but timers[timerID] managed by EventLoop.
loop->mutex_.lock();
loop->timers.erase(timerID); loop->timers.erase(timerID);
loop->mutex_.unlock();
} }
} }
} }
@ -218,7 +231,8 @@ private:
bool is_loop_owner; bool is_loop_owner;
std::mutex mutex_; std::mutex mutex_;
std::queue<EventPtr> customEvents; // GUAREDE_BY(mutex_) std::queue<EventPtr> customEvents; // GUAREDE_BY(mutex_)
std::map<TimerID, TimerPtr> timers; // GUAREDE_BY(mutex_) std::map<TimerID, TimerPtr> timers;
std::atomic<TimerID> nextTimerID;
}; };
typedef std::shared_ptr<EventLoop> EventLoopPtr; typedef std::shared_ptr<EventLoop> EventLoopPtr;
@ -243,11 +257,11 @@ static inline void killTimer(TimerID timerID) {
loop->killTimer(timerID); loop->killTimer(timerID);
} }
static inline void resetTimer(TimerID timerID) { static inline void resetTimer(TimerID timerID, int timeout_ms) {
EventLoop* loop = tlsEventLoop(); EventLoop* loop = tlsEventLoop();
assert(loop != NULL); assert(loop != NULL);
if (loop == NULL) return; if (loop == NULL) return;
loop->resetTimer(timerID); loop->resetTimer(timerID, timeout_ms);
} }
static inline TimerID setTimeout(int timeout_ms, TimerCallback cb) { static inline TimerID setTimeout(int timeout_ms, TimerCallback cb) {

View File

@ -16,11 +16,7 @@ public:
EventLoopThread(EventLoopPtr loop = NULL) { EventLoopThread(EventLoopPtr loop = NULL) {
setStatus(kInitializing); setStatus(kInitializing);
if (loop) { loop_ = loop ? loop : std::make_shared<EventLoop>();
loop_ = loop;
} else {
loop_.reset(new EventLoop);
}
setStatus(kInitialized); setStatus(kInitialized);
} }
@ -50,7 +46,7 @@ public:
if (status() >= kStarting && status() < kStopped) return; if (status() >= kStarting && status() < kStopped) return;
setStatus(kStarting); setStatus(kStarting);
thread_.reset(new std::thread(&EventLoopThread::loop_thread, this, pre, post)); thread_ = std::make_shared<std::thread>(&EventLoopThread::loop_thread, this, pre, post);
if (wait_thread_started) { if (wait_thread_started) {
while (loop_->status() < kRunning) { while (loop_->status() < kRunning) {
@ -70,9 +66,7 @@ public:
if (wait_thread_stopped) { if (wait_thread_stopped) {
if (hv_gettid() == loop_tid) return; if (hv_gettid() == loop_tid) return;
while (!isStopped()) { join();
hv_delay(1);
}
} }
} }

View File

@ -29,16 +29,16 @@ public:
} }
EventLoopPtr nextLoop(load_balance_e lb = LB_RoundRobin) { EventLoopPtr nextLoop(load_balance_e lb = LB_RoundRobin) {
int numLoops = loop_threads_.size(); size_t numLoops = loop_threads_.size();
if (numLoops == 0) return NULL; if (numLoops == 0) return NULL;
int idx = 0; size_t idx = 0;
if (lb == LB_RoundRobin) { if (lb == LB_RoundRobin) {
if (++next_loop_idx_ >= numLoops) next_loop_idx_ = 0; if (++next_loop_idx_ >= numLoops) next_loop_idx_ = 0;
idx = next_loop_idx_; idx = next_loop_idx_ % numLoops;
} else if (lb == LB_Random) { } else if (lb == LB_Random) {
idx = hv_rand(0, numLoops - 1); idx = hv_rand(0, numLoops - 1);
} else if (lb == LB_LeastConnections) { } else if (lb == LB_LeastConnections) {
for (int i = 1; i < numLoops; ++i) { for (size_t i = 1; i < numLoops; ++i) {
if (loop_threads_[i]->loop()->connectionNum < loop_threads_[idx]->loop()->connectionNum) { if (loop_threads_[i]->loop()->connectionNum < loop_threads_[idx]->loop()->connectionNum) {
idx = i; idx = i;
} }
@ -50,7 +50,7 @@ public:
} }
EventLoopPtr loop(int idx = -1) { EventLoopPtr loop(int idx = -1) {
if (idx >= 0 && idx < loop_threads_.size()) { if (idx >= 0 && idx < (int)loop_threads_.size()) {
return loop_threads_[idx]->loop(); return loop_threads_[idx]->loop();
} }
return nextLoop(); return nextLoop();
@ -71,12 +71,12 @@ public:
if (status() >= kStarting && status() < kStopped) return; if (status() >= kStarting && status() < kStopped) return;
setStatus(kStarting); setStatus(kStarting);
std::shared_ptr<std::atomic<int>> started_cnt(new std::atomic<int>(0)); auto started_cnt = std::make_shared<std::atomic<int>>(0);
std::shared_ptr<std::atomic<int>> exited_cnt(new std::atomic<int>(0)); auto exited_cnt = std::make_shared<std::atomic<int>>(0);
loop_threads_.clear(); loop_threads_.clear();
for (int i = 0; i < thread_num_; ++i) { for (int i = 0; i < thread_num_; ++i) {
EventLoopThreadPtr loop_thread(new EventLoopThread); auto loop_thread = std::make_shared<EventLoopThread>();
const EventLoopPtr& loop = loop_thread->loop(); const EventLoopPtr& loop = loop_thread->loop();
loop_thread->start(false, loop_thread->start(false,
[this, started_cnt, pre, &loop]() { [this, started_cnt, pre, &loop]() {
@ -115,9 +115,7 @@ public:
} }
if (wait_threads_stopped) { if (wait_threads_stopped) {
while (!isStopped()) { join();
hv_delay(1);
}
} }
} }

View File

@ -13,6 +13,12 @@ struct HV_EXPORT HttpContext {
HttpRequestPtr request; HttpRequestPtr request;
HttpResponsePtr response; HttpResponsePtr response;
HttpResponseWriterPtr writer; HttpResponseWriterPtr writer;
void* userdata;
HttpContext() {
service = NULL;
userdata = NULL;
}
// HttpRequest aliases // HttpRequest aliases
// return request->xxx // return request->xxx
@ -20,6 +26,10 @@ struct HV_EXPORT HttpContext {
return request->client_addr.ip; return request->client_addr.ip;
} }
int port() {
return request->client_addr.port;
}
http_method method() { http_method method() {
return request->method; return request->method;
} }
@ -127,7 +137,7 @@ struct HV_EXPORT HttpContext {
} }
void setHeader(const char* key, const std::string& value) { void setHeader(const char* key, const std::string& value) {
response->headers[key] = value; response->SetHeader(key, value);
if (stricmp(key, "Content-Type") == 0) { if (stricmp(key, "Content-Type") == 0) {
setContentType(value.c_str()); setContentType(value.c_str());
} }
@ -143,7 +153,9 @@ struct HV_EXPORT HttpContext {
// response->sendXxx // response->sendXxx
int send() { int send() {
writer->End(); if (writer) {
writer->End();
}
return response->status_code; return response->status_code;
} }
@ -184,6 +196,14 @@ struct HV_EXPORT HttpContext {
} }
#endif #endif
int redirect(const std::string& location, http_status status = HTTP_STATUS_FOUND) {
response->Redirect(location, status);
return send();
}
int close() {
return writer ? writer->close(true) : -1;
}
}; };
} // end namespace hv } // end namespace hv

View File

@ -76,13 +76,18 @@ struct HV_EXPORT HttpCookie {
Lax, Lax,
None None
} samesite; } samesite;
enum Priority {
NotSet,
Low,
Medium,
High,
} priority;
hv::KeyValue kv; // for multiple names
HttpCookie() { HttpCookie();
max_age = 0;
secure = false; void init();
httponly = false; void reset();
samesite = Default;
}
bool parse(const std::string& str); bool parse(const std::string& str);
std::string dump() const; std::string dump() const;
@ -211,7 +216,11 @@ public:
ParseBody(); ParseBody();
if (form.empty()) return HTTP_STATUS_BAD_REQUEST; if (form.empty()) return HTTP_STATUS_BAD_REQUEST;
} }
const hv::FormData& formdata = form[name]; auto iter = form.find(name);
if (iter == form.end()) {
return HTTP_STATUS_BAD_REQUEST;
}
const auto& formdata = iter->second;
if (formdata.content.empty()) { if (formdata.content.empty()) {
return HTTP_STATUS_BAD_REQUEST; return HTTP_STATUS_BAD_REQUEST;
} }
@ -247,57 +256,32 @@ public:
} }
#endif #endif
HttpMessage() { HttpMessage();
type = HTTP_BOTH; virtual ~HttpMessage();
Init();
}
virtual ~HttpMessage() {} void Init();
virtual void Reset();
void Init() { // structured-content -> content_type <-> headers["Content-Type"]
http_major = 1;
http_minor = 1;
content = NULL;
content_length = 0;
content_type = CONTENT_TYPE_NONE;
}
virtual void Reset() {
Init();
headers.clear();
cookies.clear();
body.clear();
#ifndef WITHOUT_HTTP_CONTENT
json.clear();
form.clear();
kv.clear();
#endif
}
// structured-content -> content_type <-> headers Content-Type
void FillContentType(); void FillContentType();
// body.size -> content_length <-> headers Content-Length // body.size -> content_length <-> headers["Content-Length"]
void FillContentLength(); void FillContentLength();
bool IsChunked(); bool IsChunked();
bool IsKeepAlive(); bool IsKeepAlive();
bool IsUpgrade();
// headers // headers
void SetHeader(const char* key, const std::string& value) { void SetHeader(const char* key, const std::string& value);
headers[key] = value; std::string GetHeader(const char* key, const std::string& defvalue = hv::empty_string);
}
std::string GetHeader(const char* key, const std::string& defvalue = hv::empty_string) { // cookies
auto iter = headers.find(key); void AddCookie(const HttpCookie& cookie);
return iter == headers.end() ? defvalue : iter->second; const HttpCookie& GetCookie(const std::string& name);
}
// body // body
void SetBody(const std::string& body) { void SetBody(const std::string& body);
this->body = body; const std::string& Body();
}
const std::string& Body() {
return this->body;
}
// headers -> string // headers -> string
void DumpHeaders(std::string& str); void DumpHeaders(std::string& str);
@ -330,6 +314,12 @@ public:
} }
return content_type; return content_type;
} }
void SetContentType(http_content_type type) {
content_type = type;
}
void SetContentType(const char* type) {
content_type = http_content_type_enum(type);
}
void SetContentTypeByFilename(const char* filepath) { void SetContentTypeByFilename(const char* filepath) {
const char* suffix = hv_suffixname(filepath); const char* suffix = hv_suffixname(filepath);
if (suffix) { if (suffix) {
@ -340,19 +330,6 @@ public:
} }
} }
void AddCookie(const HttpCookie& cookie) {
cookies.push_back(cookie);
}
const HttpCookie& GetCookie(const std::string& name) {
for (auto iter = cookies.begin(); iter != cookies.end(); ++iter) {
if (iter->name == name) {
return *iter;
}
}
return NoCookie;
}
int String(const std::string& str) { int String(const std::string& str) {
content_type = TEXT_PLAIN; content_type = TEXT_PLAIN;
body = str; body = str;
@ -415,38 +392,16 @@ public:
// for HttpClient // for HttpClient
uint16_t timeout; // unit: s uint16_t timeout; // unit: s
uint16_t connect_timeout;// unit: s uint16_t connect_timeout;// unit: s
uint32_t retry_count; // just for AsyncHttpClient fail retry uint32_t retry_count;
uint32_t retry_delay; // just for AsyncHttpClient fail retry uint32_t retry_delay; // unit: ms
unsigned redirect: 1; unsigned redirect: 1;
unsigned proxy : 1; unsigned proxy : 1;
unsigned cancel : 1;
HttpRequest() : HttpMessage() { HttpRequest();
type = HTTP_REQUEST;
Init();
}
void Init() { void Init();
headers["User-Agent"] = DEFAULT_HTTP_USER_AGENT; virtual void Reset();
headers["Accept"] = "*/*";
method = HTTP_GET;
scheme = "http";
host = "127.0.0.1";
port = DEFAULT_HTTP_PORT;
path = "/";
timeout = DEFAULT_HTTP_TIMEOUT;
connect_timeout = DEFAULT_HTTP_CONNECT_TIMEOUT;
retry_count = DEFAULT_HTTP_FAIL_RETRY_COUNT;
retry_delay = DEFAULT_HTTP_FAIL_RETRY_DELAY;
redirect = 1;
proxy = 0;
}
virtual void Reset() {
HttpMessage::Reset();
Init();
url.clear();
query_params.clear();
}
virtual std::string Dump(bool is_dump_headers = true, bool is_dump_body = false); virtual std::string Dump(bool is_dump_headers = true, bool is_dump_body = false);
@ -498,22 +453,32 @@ public:
} }
void FillHost(const char* host, int port = DEFAULT_HTTP_PORT); void FillHost(const char* host, int port = DEFAULT_HTTP_PORT);
void SetHost(const char* host, int port = DEFAULT_HTTP_PORT); void SetHost(const char* host, int port = DEFAULT_HTTP_PORT);
void SetProxy(const char* host, int port); void SetProxy(const char* host, int port);
bool IsProxy() { return proxy; } bool IsProxy() { return proxy; }
// Auth
void SetAuth(const std::string& auth);
void SetBasicAuth(const std::string& username, const std::string& password);
void SetBearerTokenAuth(const std::string& token);
void SetTimeout(int sec) { timeout = sec; }
void SetConnectTimeout(int sec) { connect_timeout = sec; }
void AllowRedirect(bool on = true) { redirect = on; }
// NOTE: SetRetry just for AsyncHttpClient
void SetRetry(int count = DEFAULT_HTTP_FAIL_RETRY_COUNT,
int delay = DEFAULT_HTTP_FAIL_RETRY_DELAY) {
retry_count = count;
retry_delay = delay;
}
void Cancel() { cancel = 1; }
bool IsCanceled() { return cancel == 1; }
// Range: bytes=0-4095 // Range: bytes=0-4095
void SetRange(long from = 0, long to = -1) { void SetRange(long from = 0, long to = -1);
headers["Range"] = hv::asprintf("bytes=%ld-%ld", from, to); bool GetRange(long& from, long& to);
}
bool GetRange(long& from, long& to) {
auto iter = headers.find("Range");
if (iter != headers.end()) {
sscanf(iter->second.c_str(), "bytes=%ld-%ld", &from, &to);
return true;
}
from = to = 0;
return false;
}
}; };
class HV_EXPORT HttpResponse : public HttpMessage { class HV_EXPORT HttpResponse : public HttpMessage {
@ -523,34 +488,21 @@ public:
return http_status_str(status_code); return http_status_str(status_code);
} }
HttpResponse() : HttpMessage() { HttpResponse();
type = HTTP_RESPONSE;
Init();
}
void Init() { void Init();
status_code = HTTP_STATUS_OK; virtual void Reset();
}
virtual void Reset() {
HttpMessage::Reset();
Init();
}
virtual std::string Dump(bool is_dump_headers = true, bool is_dump_body = false); virtual std::string Dump(bool is_dump_headers = true, bool is_dump_body = false);
// Content-Range: bytes 0-4095/10240000 // Content-Range: bytes 0-4095/10240000
void SetRange(long from, long to, long total) { void SetRange(long from, long to, long total);
headers["Content-Range"] = hv::asprintf("bytes %ld-%ld/%ld", from, to, total); bool GetRange(long& from, long& to, long& total);
}
bool GetRange(long& from, long& to, long& total) { int Redirect(const std::string& location, http_status status = HTTP_STATUS_FOUND) {
auto iter = headers.find("Content-Range"); status_code = status;
if (iter != headers.end()) { SetHeader("Location", location);
sscanf(iter->second.c_str(), "bytes %ld-%ld/%ld", &from, &to, &total); return status_code;
return true;
}
from = to = total = 0;
return false;
} }
}; };

View File

@ -32,6 +32,8 @@ public:
// Http2Parser: (state == H2_RECV_HEADERS || state == H2_RECV_DATA) && stream_closed // Http2Parser: (state == H2_RECV_HEADERS || state == H2_RECV_DATA) && stream_closed
virtual bool IsComplete() = 0; virtual bool IsComplete() = 0;
virtual bool IsEof() { return false; }
// client // client
// SubmitRequest -> while(GetSendData) {send} -> InitResponse -> do {recv -> FeedRecvData} while(WantRecv) // SubmitRequest -> while(GetSendData) {send} -> InitResponse -> do {recv -> FeedRecvData} while(WantRecv)
virtual int SubmitRequest(HttpRequest* req) = 0; virtual int SubmitRequest(HttpRequest* req) = 0;

View File

@ -6,21 +6,22 @@
namespace hv { namespace hv {
class HttpResponseWriter : public SocketChannel { class HV_EXPORT HttpResponseWriter : public SocketChannel {
public: public:
HttpResponsePtr response; HttpResponsePtr response;
enum State { enum State {
SEND_BEGIN, SEND_BEGIN = 0,
SEND_HEADER, SEND_HEADER,
SEND_BODY, SEND_BODY,
SEND_CHUNKED, SEND_CHUNKED,
SEND_CHUNKED_END, SEND_CHUNKED_END,
SEND_END, SEND_END,
} state; } state: 8, end: 8;
HttpResponseWriter(hio_t* io, const HttpResponsePtr& resp) HttpResponseWriter(hio_t* io, const HttpResponsePtr& resp)
: SocketChannel(io) : SocketChannel(io)
, response(resp) , response(resp)
, state(SEND_BEGIN) , state(SEND_BEGIN)
, end(SEND_BEGIN)
{} {}
~HttpResponseWriter() {} ~HttpResponseWriter() {}
@ -32,7 +33,7 @@ public:
// Begin -> EndHeaders("Transfer-Encoding", "chunked") -> WriteChunked -> WriteChunked -> ... -> End // Begin -> EndHeaders("Transfer-Encoding", "chunked") -> WriteChunked -> WriteChunked -> ... -> End
int Begin() { int Begin() {
state = SEND_BEGIN; state = end = SEND_BEGIN;
return 0; return 0;
} }
@ -42,50 +43,30 @@ public:
} }
int WriteHeader(const char* key, const char* value) { int WriteHeader(const char* key, const char* value) {
response->headers[key] = value; response->SetHeader(key, value);
return 0; return 0;
} }
template<typename T> template<typename T>
int WriteHeader(const char* key, T num) { int WriteHeader(const char* key, T num) {
response->headers[key] = hv::to_string(num); response->SetHeader(key, hv::to_string(num));
return 0; return 0;
} }
int EndHeaders(const char* key = NULL, const char* value = NULL) { int WriteCookie(const HttpCookie& cookie) {
if (state != SEND_BEGIN) return -1; response->cookies.push_back(cookie);
if (key && value) { return 0;
response->headers[key] = value;
}
std::string headers = response->Dump(true, false);
state = SEND_HEADER;
return write(headers);
} }
int EndHeaders(const char* key = NULL, const char* value = NULL);
template<typename T> template<typename T>
int EndHeaders(const char* key, T num) { int EndHeaders(const char* key, T num) {
std::string value = hv::to_string(num); std::string value = hv::to_string(num);
return EndHeaders(key, value.c_str()); return EndHeaders(key, value.c_str());
} }
int WriteChunked(const char* buf, int len = -1) { int WriteChunked(const char* buf, int len = -1);
int ret = 0;
if (len == -1) len = strlen(buf);
if (state == SEND_BEGIN) {
EndHeaders("Transfer-Encoding", "chunked");
}
char chunked_header[64];
int chunked_header_len = snprintf(chunked_header, sizeof(chunked_header), "%x\r\n", len);
write(chunked_header, chunked_header_len);
if (buf && len) {
ret = write(buf, len);
state = SEND_CHUNKED;
} else {
state = SEND_CHUNKED_END;
}
write("\r\n", 2);
return ret;
}
int WriteChunked(const std::string& str) { int WriteChunked(const std::string& str) {
return WriteChunked(str.c_str(), str.size()); return WriteChunked(str.c_str(), str.size());
@ -95,75 +76,17 @@ public:
return WriteChunked(NULL, 0); return WriteChunked(NULL, 0);
} }
int WriteBody(const char* buf, int len = -1) { int WriteBody(const char* buf, int len = -1);
if (response->IsChunked()) {
return WriteChunked(buf, len);
}
if (len == -1) len = strlen(buf);
if (state == SEND_BEGIN) {
response->body.append(buf, len);
return len;
} else {
state = SEND_BODY;
return write(buf, len);
}
}
int WriteBody(const std::string& str) { int WriteBody(const std::string& str) {
return WriteBody(str.c_str(), str.size()); return WriteBody(str.c_str(), str.size());
} }
int WriteResponse(HttpResponse* resp) { int WriteResponse(HttpResponse* resp);
if (resp == NULL) {
response->status_code = HTTP_STATUS_INTERNAL_SERVER_ERROR;
return 0;
}
bool is_dump_headers = state == SEND_BEGIN ? true : false;
std::string msg = resp->Dump(is_dump_headers, true);
state = SEND_BODY;
return write(msg);
}
int End(const char* buf = NULL, int len = -1) { int SSEvent(const std::string& data, const char* event = "message");
if (state == SEND_END) return 0;
if (!isConnected()) {
state = SEND_END;
return -1;
}
int ret = 0; int End(const char* buf = NULL, int len = -1);
if (state == SEND_CHUNKED) {
if (buf) {
ret = WriteChunked(buf, len);
}
if (state == SEND_CHUNKED) {
EndChunked();
}
} else {
if (buf) {
ret = WriteBody(buf, len);
}
bool is_dump_headers = true;
bool is_dump_body = true;
if (state == SEND_HEADER) {
is_dump_headers = false;
} else if (state == SEND_BODY) {
is_dump_headers = false;
is_dump_body = false;
}
if (is_dump_body) {
std::string msg = response->Dump(is_dump_headers, is_dump_body);
ret = write(msg);
}
}
state = SEND_END;
if (!response->IsKeepAlive()) {
close(true);
}
return ret;
}
int End(const std::string& str) { int End(const std::string& str) {
return End(str.c_str(), str.size()); return End(str.c_str(), str.size());

View File

@ -2,6 +2,7 @@
#define HV_HTTP_SERVER_H_ #define HV_HTTP_SERVER_H_
#include "hexport.h" #include "hexport.h"
#include "hssl.h"
#include "HttpService.h" #include "HttpService.h"
// #include "WebSocketServer.h" // #include "WebSocketServer.h"
namespace hv { namespace hv {
@ -17,12 +18,18 @@ typedef struct http_server_s {
int http_version; int http_version;
int worker_processes; int worker_processes;
int worker_threads; int worker_threads;
uint32_t worker_connections; // max_connections = workers * worker_connections
HttpService* service; // http service HttpService* service; // http service
WebSocketService* ws; // websocket service WebSocketService* ws; // websocket service
void* userdata; void* userdata;
//private:
int listenfd[2]; // 0: http, 1: https int listenfd[2]; // 0: http, 1: https
void* privdata; void* privdata;
// hooks
std::function<void()> onWorkerStart;
std::function<void()> onWorkerStop;
// SSL/TLS
hssl_ctx_t ssl_ctx;
unsigned alloced_ssl_ctx: 1;
#ifdef __cplusplus #ifdef __cplusplus
http_server_s() { http_server_s() {
@ -35,11 +42,15 @@ typedef struct http_server_s {
http_version = 1; http_version = 1;
worker_processes = 0; worker_processes = 0;
worker_threads = 0; worker_threads = 0;
worker_connections = 1024;
service = NULL; service = NULL;
ws = NULL; ws = NULL;
listenfd[0] = listenfd[1] = -1; listenfd[0] = listenfd[1] = -1;
userdata = NULL; userdata = NULL;
privdata = NULL; privdata = NULL;
// SSL/TLS
ssl_ctx = NULL;
alloced_ssl_ctx = 0;
} }
#endif #endif
} http_server_t; } http_server_t;
@ -74,7 +85,11 @@ namespace hv {
class HttpServer : public http_server_t { class HttpServer : public http_server_t {
public: public:
HttpServer() : http_server_t() {} HttpServer(HttpService* service = NULL)
: http_server_t()
{
this->service = service;
}
~HttpServer() { stop(); } ~HttpServer() { stop(); }
void registerHttpService(HttpService* service) { void registerHttpService(HttpService* service) {
@ -86,8 +101,12 @@ public:
} }
void setPort(int port = 0, int ssl_port = 0) { void setPort(int port = 0, int ssl_port = 0) {
if (port != 0) this->port = port; if (port >= 0) this->port = port;
if (ssl_port != 0) this->https_port = ssl_port; if (ssl_port >= 0) this->https_port = ssl_port;
}
void setListenFD(int fd = -1, int ssl_fd = -1) {
if (fd >= 0) this->listenfd[0] = fd;
if (ssl_fd >= 0) this->listenfd[1] = ssl_fd;
} }
void setProcessNum(int num) { void setProcessNum(int num) {
@ -98,6 +117,19 @@ public:
this->worker_threads = num; this->worker_threads = num;
} }
// SSL/TLS
int setSslCtx(hssl_ctx_t ssl_ctx) {
this->ssl_ctx = ssl_ctx;
return 0;
}
int newSslCtx(hssl_ctx_opt_t* opt) {
// NOTE: hssl_ctx_free in http_server_stop
hssl_ctx_t ssl_ctx = hssl_ctx_new(opt);
if (ssl_ctx == NULL) return -1;
this->alloced_ssl_ctx = 1;
return setSslCtx(ssl_ctx);
}
int run(bool wait = true) { int run(bool wait = true) {
return http_server_run(this, wait); return http_server_run(this, wait);
} }

View File

@ -4,6 +4,7 @@
#include <string> #include <string>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include <list> #include <list>
#include <memory> #include <memory>
#include <functional> #include <functional>
@ -28,9 +29,10 @@
/* /*
* @param[in] req: parsed structured http request * @param[in] req: parsed structured http request
* @param[out] resp: structured http response * @param[out] resp: structured http response
* @return 0: handle unfinished * @return 0: handle next
* http_status_code: handle done * http_status_code: handle done
*/ */
#define HTTP_STATUS_NEXT 0
#define HTTP_STATUS_UNFINISHED 0 #define HTTP_STATUS_UNFINISHED 0
// NOTE: http_sync_handler run on IO thread // NOTE: http_sync_handler run on IO thread
typedef std::function<int(HttpRequest* req, HttpResponse* resp)> http_sync_handler; typedef std::function<int(HttpRequest* req, HttpResponse* resp)> http_sync_handler;
@ -38,20 +40,25 @@ typedef std::function<int(HttpRequest* req, HttpResponse* resp)>
typedef std::function<void(const HttpRequestPtr& req, const HttpResponseWriterPtr& writer)> http_async_handler; typedef std::function<void(const HttpRequestPtr& req, const HttpResponseWriterPtr& writer)> http_async_handler;
// NOTE: http_ctx_handler run on IO thread, you can easily post HttpContextPtr to your consumer thread for processing. // NOTE: http_ctx_handler run on IO thread, you can easily post HttpContextPtr to your consumer thread for processing.
typedef std::function<int(const HttpContextPtr& ctx)> http_ctx_handler; typedef std::function<int(const HttpContextPtr& ctx)> http_ctx_handler;
// NOTE: http_state_handler run on IO thread
typedef std::function<int(const HttpContextPtr& ctx, http_parser_state state, const char* data, size_t size)> http_state_handler;
struct http_handler { struct http_handler {
http_sync_handler sync_handler; http_sync_handler sync_handler;
http_async_handler async_handler; http_async_handler async_handler;
http_ctx_handler ctx_handler; http_ctx_handler ctx_handler;
http_state_handler state_handler;
http_handler() {} http_handler() {}
http_handler(http_sync_handler fn) : sync_handler(std::move(fn)) {} http_handler(http_sync_handler fn) : sync_handler(std::move(fn)) {}
http_handler(http_async_handler fn) : async_handler(std::move(fn)) {} http_handler(http_async_handler fn) : async_handler(std::move(fn)) {}
http_handler(http_ctx_handler fn) : ctx_handler(std::move(fn)) {} http_handler(http_ctx_handler fn) : ctx_handler(std::move(fn)) {}
http_handler(http_state_handler fn) : state_handler(std::move(fn)) {}
http_handler(const http_handler& rhs) http_handler(const http_handler& rhs)
: sync_handler(std::move(rhs.sync_handler)) : sync_handler(std::move(const_cast<http_handler&>(rhs).sync_handler))
, async_handler(std::move(rhs.async_handler)) , async_handler(std::move(const_cast<http_handler&>(rhs).async_handler))
, ctx_handler(std::move(rhs.ctx_handler)) , ctx_handler(std::move(const_cast<http_handler&>(rhs).ctx_handler))
, state_handler(std::move(const_cast<http_handler&>(rhs).state_handler))
{} {}
const http_handler& operator=(http_sync_handler fn) { const http_handler& operator=(http_sync_handler fn) {
@ -66,6 +73,10 @@ struct http_handler {
ctx_handler = std::move(fn); ctx_handler = std::move(fn);
return *this; return *this;
} }
const http_handler& operator=(http_state_handler fn) {
state_handler = std::move(fn);
return *this;
}
bool isNull() { bool isNull() {
return sync_handler == NULL && return sync_handler == NULL &&
@ -78,6 +89,8 @@ struct http_handler {
} }
}; };
typedef std::vector<http_handler> http_handlers;
struct http_method_handler { struct http_method_handler {
http_method method; http_method method;
http_handler handler; http_handler handler;
@ -88,32 +101,47 @@ struct http_method_handler {
// method => http_method_handler // method => http_method_handler
typedef std::list<http_method_handler> http_method_handlers; typedef std::list<http_method_handler> http_method_handlers;
// path => http_method_handlers // path => http_method_handlers
typedef std::unordered_map<std::string, std::shared_ptr<http_method_handlers>> http_api_handlers; typedef std::unordered_map<std::string, std::shared_ptr<http_method_handlers>> http_path_handlers;
namespace hv { namespace hv {
struct HV_EXPORT HttpService { struct HV_EXPORT HttpService {
// preprocessor -> processor -> postprocessor /* handler chain */
// preprocessor -> middleware -> processor -> postprocessor
http_handler preprocessor; http_handler preprocessor;
// processor: api_handlers -> staticHandler -> errorHandler http_handlers middleware;
// processor: pathHandlers -> staticHandler -> errorHandler
http_handler processor; http_handler processor;
http_handler postprocessor; http_handler postprocessor;
// api service (that is http.APIServer) /* API handlers */
std::string base_url; std::string base_url;
http_api_handlers api_handlers; http_path_handlers pathHandlers;
// file service (that is http.FileServer) /* Static file service */
http_handler staticHandler; http_handler staticHandler;
http_handler largeFileHandler; http_handler largeFileHandler;
std::string document_root; std::string document_root;
std::string home_page; std::string home_page;
std::string error_page; std::string error_page;
// indexof service (that is http.DirectoryServer) // nginx: location => root
std::map<std::string, std::string, std::greater<std::string>> staticDirs;
/* Indexof directory service */
std::string index_of; std::string index_of;
http_handler errorHandler; http_handler errorHandler;
/* Proxy service */
/* Reverse proxy service */
// nginx: location => proxy_pass
std::map<std::string, std::string, std::greater<std::string>> proxies;
/* Forward proxy service */
StringList trustProxies;
StringList noProxies;
int proxy_connect_timeout;
int proxy_read_timeout;
int proxy_write_timeout;
// options // options
int keepalive_timeout; int keepalive_timeout;
int max_file_cache_size; // cache small file int max_file_cache_size; // cache small file
@ -127,6 +155,9 @@ struct HV_EXPORT HttpService {
*/ */
int limit_rate; // limit send rate, unit: KB/s int limit_rate; // limit send rate, unit: KB/s
unsigned enable_access_log :1;
unsigned enable_forward_proxy :1;
HttpService() { HttpService() {
// base_url = DEFAULT_BASE_URL; // base_url = DEFAULT_BASE_URL;
@ -135,123 +166,107 @@ struct HV_EXPORT HttpService {
// error_page = DEFAULT_ERROR_PAGE; // error_page = DEFAULT_ERROR_PAGE;
// index_of = DEFAULT_INDEXOF_DIR; // index_of = DEFAULT_INDEXOF_DIR;
proxy_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
proxy_read_timeout = 0;
proxy_write_timeout = 0;
keepalive_timeout = DEFAULT_KEEPALIVE_TIMEOUT; keepalive_timeout = DEFAULT_KEEPALIVE_TIMEOUT;
max_file_cache_size = MAX_FILE_CACHE_SIZE; max_file_cache_size = MAX_FILE_CACHE_SIZE;
file_cache_stat_interval = DEFAULT_FILE_CACHE_STAT_INTERVAL; file_cache_stat_interval = DEFAULT_FILE_CACHE_STAT_INTERVAL;
file_cache_expired_time = DEFAULT_FILE_CACHE_EXPIRED_TIME; file_cache_expired_time = DEFAULT_FILE_CACHE_EXPIRED_TIME;
limit_rate = -1; // unlimited limit_rate = -1; // unlimited
enable_access_log = 1;
enable_forward_proxy = 0;
} }
void AddApi(const char* path, http_method method, const http_handler& handler); void AddRoute(const char* path, http_method method, const http_handler& handler);
// @retval 0 OK, else HTTP_STATUS_NOT_FOUND, HTTP_STATUS_METHOD_NOT_ALLOWED // @retval 0 OK, else HTTP_STATUS_NOT_FOUND, HTTP_STATUS_METHOD_NOT_ALLOWED
int GetApi(const char* url, http_method method, http_handler** handler); int GetRoute(const char* url, http_method method, http_handler** handler);
// RESTful API /:field/ => req->query_params["field"] // RESTful API /:field/ => req->query_params["field"]
int GetApi(HttpRequest* req, http_handler** handler); int GetRoute(HttpRequest* req, http_handler** handler);
// Static("/", "/var/www/html")
void Static(const char* path, const char* dir);
// @retval / => /var/www/html/index.html
std::string GetStaticFilepath(const char* path);
// https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
void AllowCORS();
// proxy
// forward proxy
void EnableForwardProxy() { enable_forward_proxy = 1; }
void AddTrustProxy(const char* host);
void AddNoProxy(const char* host);
bool IsTrustProxy(const char* host);
// reverse proxy
// Proxy("/api/v1/", "http://www.httpbin.org/");
void Proxy(const char* path, const char* url);
// @retval /api/v1/test => http://www.httpbin.org/test
std::string GetProxyUrl(const char* path);
hv::StringList Paths() { hv::StringList Paths() {
hv::StringList paths; hv::StringList paths;
for (auto& pair : api_handlers) { for (auto& pair : pathHandlers) {
paths.emplace_back(pair.first); paths.emplace_back(pair.first);
} }
return paths; return paths;
} }
// github.com/gin-gonic/gin // Handler = [ http_sync_handler, http_ctx_handler ]
void Handle(const char* httpMethod, const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
AddApi(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc)); void Use(Handler handlerFunc) {
middleware.emplace_back(handlerFunc);
} }
void Handle(const char* httpMethod, const char* relativePath, http_async_handler handlerFunc) {
AddApi(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc)); // Inspired by github.com/gin-gonic/gin
} // Handler = [ http_sync_handler, http_async_handler, http_ctx_handler, http_state_handler ]
void Handle(const char* httpMethod, const char* relativePath, http_ctx_handler handlerFunc) { template<typename Handler>
AddApi(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc)); void Handle(const char* httpMethod, const char* relativePath, Handler handlerFunc) {
AddRoute(relativePath, http_method_enum(httpMethod), http_handler(handlerFunc));
} }
// HEAD // HEAD
void HEAD(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("HEAD", relativePath, handlerFunc); void HEAD(const char* relativePath, Handler handlerFunc) {
}
void HEAD(const char* relativePath, http_async_handler handlerFunc) {
Handle("HEAD", relativePath, handlerFunc);
}
void HEAD(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("HEAD", relativePath, handlerFunc); Handle("HEAD", relativePath, handlerFunc);
} }
// GET // GET
void GET(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("GET", relativePath, handlerFunc); void GET(const char* relativePath, Handler handlerFunc) {
}
void GET(const char* relativePath, http_async_handler handlerFunc) {
Handle("GET", relativePath, handlerFunc);
}
void GET(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("GET", relativePath, handlerFunc); Handle("GET", relativePath, handlerFunc);
} }
// POST // POST
void POST(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("POST", relativePath, handlerFunc); void POST(const char* relativePath, Handler handlerFunc) {
}
void POST(const char* relativePath, http_async_handler handlerFunc) {
Handle("POST", relativePath, handlerFunc);
}
void POST(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("POST", relativePath, handlerFunc); Handle("POST", relativePath, handlerFunc);
} }
// PUT // PUT
void PUT(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("PUT", relativePath, handlerFunc); void PUT(const char* relativePath, Handler handlerFunc) {
}
void PUT(const char* relativePath, http_async_handler handlerFunc) {
Handle("PUT", relativePath, handlerFunc);
}
void PUT(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("PUT", relativePath, handlerFunc); Handle("PUT", relativePath, handlerFunc);
} }
// DELETE // DELETE
// NOTE: Windows <winnt.h> #define DELETE as a macro, we have to replace DELETE with Delete. // NOTE: Windows <winnt.h> #define DELETE as a macro, we have to replace DELETE with Delete.
void Delete(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("DELETE", relativePath, handlerFunc); void Delete(const char* relativePath, Handler handlerFunc) {
}
void Delete(const char* relativePath, http_async_handler handlerFunc) {
Handle("DELETE", relativePath, handlerFunc);
}
void Delete(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("DELETE", relativePath, handlerFunc); Handle("DELETE", relativePath, handlerFunc);
} }
// PATCH // PATCH
void PATCH(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("PATCH", relativePath, handlerFunc); void PATCH(const char* relativePath, Handler handlerFunc) {
}
void PATCH(const char* relativePath, http_async_handler handlerFunc) {
Handle("PATCH", relativePath, handlerFunc);
}
void PATCH(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("PATCH", relativePath, handlerFunc); Handle("PATCH", relativePath, handlerFunc);
} }
// Any // Any
void Any(const char* relativePath, http_sync_handler handlerFunc) { template<typename Handler>
Handle("HEAD", relativePath, handlerFunc); void Any(const char* relativePath, Handler handlerFunc) {
Handle("GET", relativePath, handlerFunc);
Handle("POST", relativePath, handlerFunc);
Handle("PUT", relativePath, handlerFunc);
Handle("DELETE", relativePath, handlerFunc);
Handle("PATCH", relativePath, handlerFunc);
}
void Any(const char* relativePath, http_async_handler handlerFunc) {
Handle("HEAD", relativePath, handlerFunc);
Handle("GET", relativePath, handlerFunc);
Handle("POST", relativePath, handlerFunc);
Handle("PUT", relativePath, handlerFunc);
Handle("DELETE", relativePath, handlerFunc);
Handle("PATCH", relativePath, handlerFunc);
}
void Any(const char* relativePath, http_ctx_handler handlerFunc) {
Handle("HEAD", relativePath, handlerFunc); Handle("HEAD", relativePath, handlerFunc);
Handle("GET", relativePath, handlerFunc); Handle("GET", relativePath, handlerFunc);
Handle("POST", relativePath, handlerFunc); Handle("POST", relativePath, handlerFunc);

View File

@ -11,11 +11,13 @@
namespace hv { namespace hv {
template<class TSocketChannel = SocketChannel> template<class TSocketChannel = SocketChannel>
class TcpClientTmpl { class TcpClientEventLoopTmpl {
public: public:
typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr; typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr;
TcpClientTmpl() { TcpClientEventLoopTmpl(EventLoopPtr loop = NULL) {
loop_ = loop ? loop : std::make_shared<EventLoop>();
remote_port = 0;
connect_timeout = HIO_DEFAULT_CONNECT_TIMEOUT; connect_timeout = HIO_DEFAULT_CONNECT_TIMEOUT;
tls = false; tls = false;
tls_setting = NULL; tls_setting = NULL;
@ -23,59 +25,107 @@ public:
unpack_setting = NULL; unpack_setting = NULL;
} }
virtual ~TcpClientTmpl() { virtual ~TcpClientEventLoopTmpl() {
HV_FREE(tls_setting); HV_FREE(tls_setting);
HV_FREE(reconn_setting); HV_FREE(reconn_setting);
HV_FREE(unpack_setting); HV_FREE(unpack_setting);
} }
const EventLoopPtr& loop() { const EventLoopPtr& loop() {
return loop_thread.loop(); return loop_;
} }
//NOTE: By default, not bind local port. If necessary, you can call system api bind() after createsocket(). // delete thread-safe
//@retval >=0 connfd, <0 error void deleteInLoop() {
loop_->runInLoop([this](){
delete this;
});
}
// NOTE: By default, not bind local port. If necessary, you can call bind() after createsocket().
// @retval >=0 connfd, <0 error
int createsocket(int remote_port, const char* remote_host = "127.0.0.1") { int createsocket(int remote_port, const char* remote_host = "127.0.0.1") {
memset(&remote_addr, 0, sizeof(remote_addr)); memset(&remote_addr, 0, sizeof(remote_addr));
int ret = sockaddr_set_ipport(&remote_addr, remote_host, remote_port); int ret = sockaddr_set_ipport(&remote_addr, remote_host, remote_port);
if (ret != 0) { if (ret != 0) {
return -1; return NABS(ret);
} }
this->remote_host = remote_host; this->remote_host = remote_host;
this->remote_port = remote_port; this->remote_port = remote_port;
return createsocket(&remote_addr.sa); return createsocket(&remote_addr.sa);
} }
int createsocket(struct sockaddr* remote_addr) { int createsocket(struct sockaddr* remote_addr) {
int connfd = socket(remote_addr->sa_family, SOCK_STREAM, 0); int connfd = ::socket(remote_addr->sa_family, SOCK_STREAM, 0);
// SOCKADDR_PRINT(remote_addr); // SOCKADDR_PRINT(remote_addr);
if (connfd < 0) { if (connfd < 0) {
perror("socket"); perror("socket");
return -2; return -2;
} }
hio_t* io = hio_get(loop_thread.hloop(), connfd); hio_t* io = hio_get(loop_->loop(), connfd);
assert(io != NULL); assert(io != NULL);
hio_set_peeraddr(io, remote_addr, SOCKADDR_LEN(remote_addr)); hio_set_peeraddr(io, remote_addr, SOCKADDR_LEN(remote_addr));
channel.reset(new TSocketChannel(io)); channel = std::make_shared<TSocketChannel>(io);
return connfd; return connfd;
} }
int bind(int local_port, const char* local_host = "0.0.0.0") {
sockaddr_u local_addr;
memset(&local_addr, 0, sizeof(local_addr));
int ret = sockaddr_set_ipport(&local_addr, local_host, local_port);
if (ret != 0) {
return NABS(ret);
}
return bind(&local_addr.sa);
}
int bind(struct sockaddr* local_addr) {
if (channel == NULL || channel->isClosed()) {
return -1;
}
int ret = ::bind(channel->fd(), local_addr, SOCKADDR_LEN(local_addr));
if (ret != 0) {
perror("bind");
}
return ret;
}
// closesocket thread-safe // closesocket thread-safe
void closesocket() { void closesocket() {
setReconnect(NULL); if (channel && channel->status != SocketChannel::CLOSED) {
if (channel) { loop_->runInLoop([this](){
channel->close(true); if (channel) {
setReconnect(NULL);
channel->close();
}
});
} }
} }
int startConnect() { int startConnect() {
assert(channel != NULL); if (channel == NULL || channel->isClosed()) {
int connfd = createsocket(&remote_addr.sa);
if (connfd < 0) {
hloge("createsocket %s:%d return %d!\n", remote_host.c_str(), remote_port, connfd);
return connfd;
}
}
if (channel == NULL || channel->status >= SocketChannel::CONNECTING) {
return -1;
}
if (connect_timeout) { if (connect_timeout) {
channel->setConnectTimeout(connect_timeout); channel->setConnectTimeout(connect_timeout);
} }
if (tls) { if (tls) {
channel->enableSSL(); channel->enableSSL();
if (tls_setting) { if (tls_setting) {
channel->newSslCtx(tls_setting); int ret = channel->newSslCtx(tls_setting);
if (ret != 0) {
hloge("new SSL_CTX failed: %d", ret);
closesocket();
return ret;
}
} }
if (!is_ipaddr(remote_host.c_str())) { if (!is_ipaddr(remote_host.c_str())) {
channel->setHostname(remote_host); channel->setHostname(remote_host);
@ -104,16 +154,12 @@ public:
} }
}; };
channel->onclose = [this]() { channel->onclose = [this]() {
bool reconnect = reconn_setting != NULL;
if (onConnection) { if (onConnection) {
onConnection(channel); onConnection(channel);
} }
// reconnect if (reconnect) {
if (reconn_setting) {
startReconnect(); startReconnect();
} else {
channel = NULL;
// NOTE: channel should be destroyed,
// so in this lambda function, no code should be added below.
} }
}; };
return channel->startConnect(); return channel->startConnect();
@ -123,21 +169,16 @@ public:
if (!reconn_setting) return -1; if (!reconn_setting) return -1;
if (!reconn_setting_can_retry(reconn_setting)) return -2; if (!reconn_setting_can_retry(reconn_setting)) return -2;
uint32_t delay = reconn_setting_calc_delay(reconn_setting); uint32_t delay = reconn_setting_calc_delay(reconn_setting);
loop_thread.loop()->setTimeout(delay, [this](TimerID timerID){ hlogi("reconnect... cnt=%d, delay=%d", reconn_setting->cur_retry_cnt, reconn_setting->cur_delay);
hlogi("reconnect... cnt=%d, delay=%d", reconn_setting->cur_retry_cnt, reconn_setting->cur_delay); loop_->setTimeout(delay, [this](TimerID timerID){
if (createsocket(&remote_addr.sa) < 0) return;
startConnect(); startConnect();
}); });
return 0; return 0;
} }
void start(bool wait_threads_started = true) { // start thread-safe
loop_thread.start(wait_threads_started, std::bind(&TcpClientTmpl::startConnect, this)); void start() {
} loop_->runInLoop(std::bind(&TcpClientEventLoopTmpl::startConnect, this));
// stop thread-safe
void stop(bool wait_threads_stopped = true) {
setReconnect(NULL);
loop_thread.stop(wait_threads_stopped);
} }
bool isConnected() { bool isConnected() {
@ -217,7 +258,47 @@ public:
std::function<void(const TSocketChannelPtr&, Buffer*)> onWriteComplete; std::function<void(const TSocketChannelPtr&, Buffer*)> onWriteComplete;
private: private:
EventLoopThread loop_thread; EventLoopPtr loop_;
};
template<class TSocketChannel = SocketChannel>
class TcpClientTmpl : private EventLoopThread, public TcpClientEventLoopTmpl<TSocketChannel> {
public:
TcpClientTmpl(EventLoopPtr loop = NULL)
: EventLoopThread(loop)
, TcpClientEventLoopTmpl<TSocketChannel>(EventLoopThread::loop())
, is_loop_owner(loop == NULL)
{}
virtual ~TcpClientTmpl() {
stop(true);
}
const EventLoopPtr& loop() {
return EventLoopThread::loop();
}
// start thread-safe
void start(bool wait_threads_started = true) {
if (isRunning()) {
TcpClientEventLoopTmpl<TSocketChannel>::start();
} else {
EventLoopThread::start(wait_threads_started, [this]() {
TcpClientTmpl::startConnect();
return 0;
});
}
}
// stop thread-safe
void stop(bool wait_threads_stopped = true) {
TcpClientEventLoopTmpl<TSocketChannel>::closesocket();
if (is_loop_owner) {
EventLoopThread::stop(wait_threads_stopped);
}
}
private:
bool is_loop_owner;
}; };
typedef TcpClientTmpl<SocketChannel> TcpClient; typedef TcpClientTmpl<SocketChannel> TcpClient;

View File

@ -11,19 +11,24 @@
namespace hv { namespace hv {
template<class TSocketChannel = SocketChannel> template<class TSocketChannel = SocketChannel>
class TcpServerTmpl { class TcpServerEventLoopTmpl {
public: public:
typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr; typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr;
TcpServerTmpl() { TcpServerEventLoopTmpl(EventLoopPtr loop = NULL) {
acceptor_loop = loop ? loop : std::make_shared<EventLoop>();
port = 0;
listenfd = -1; listenfd = -1;
tls = false; tls = false;
unpack_setting.mode = UNPACK_MODE_NONE; tls_setting = NULL;
unpack_setting = NULL;
max_connections = 0xFFFFFFFF; max_connections = 0xFFFFFFFF;
load_balance = LB_RoundRobin; load_balance = LB_RoundRobin;
} }
virtual ~TcpServerTmpl() { virtual ~TcpServerEventLoopTmpl() {
HV_FREE(tls_setting);
HV_FREE(unpack_setting);
} }
EventLoopPtr loop(int idx = -1) { EventLoopPtr loop(int idx = -1) {
@ -33,12 +38,20 @@ public:
//@retval >=0 listenfd, <0 error //@retval >=0 listenfd, <0 error
int createsocket(int port, const char* host = "0.0.0.0") { int createsocket(int port, const char* host = "0.0.0.0") {
listenfd = Listen(port, host); listenfd = Listen(port, host);
if (listenfd < 0) return listenfd;
this->host = host;
this->port = port;
return listenfd; return listenfd;
} }
// closesocket thread-safe // closesocket thread-safe
void closesocket() { void closesocket() {
if (listenfd >= 0) { if (listenfd >= 0) {
hio_close_async(hio_get(acceptor_thread.hloop(), listenfd)); hloop_t* loop = acceptor_loop->loop();
if (loop) {
hio_t* listenio = hio_get(loop, listenfd);
assert(listenio != NULL);
hio_close_async(listenio);
}
listenfd = -1; listenfd = -1;
} }
} }
@ -57,24 +70,51 @@ public:
} }
int startAccept() { int startAccept() {
assert(listenfd >= 0); if (listenfd < 0) {
hio_t* listenio = haccept(acceptor_thread.hloop(), listenfd, onAccept); listenfd = createsocket(port, host.c_str());
if (listenfd < 0) {
hloge("createsocket %s:%d return %d!\n", host.c_str(), port, listenfd);
return listenfd;
}
}
hloop_t* loop = acceptor_loop->loop();
if (loop == NULL) return -2;
hio_t* listenio = haccept(loop, listenfd, onAccept);
assert(listenio != NULL);
hevent_set_userdata(listenio, this); hevent_set_userdata(listenio, this);
if (tls) { if (tls) {
hio_enable_ssl(listenio); hio_enable_ssl(listenio);
if (tls_setting) {
int ret = hio_new_ssl_ctx(listenio, tls_setting);
if (ret != 0) {
hloge("new SSL_CTX failed: %d", ret);
closesocket();
return ret;
}
}
} }
return 0; return 0;
} }
int stopAccept() {
if (listenfd < 0) return -1;
hloop_t* loop = acceptor_loop->loop();
if (loop == NULL) return -2;
hio_t* listenio = hio_get(loop, listenfd);
assert(listenio != NULL);
return hio_del(listenio, HV_READ);
}
// start thread-safe
void start(bool wait_threads_started = true) { void start(bool wait_threads_started = true) {
if (worker_threads.threadNum() > 0) { if (worker_threads.threadNum() > 0) {
worker_threads.start(wait_threads_started); worker_threads.start(wait_threads_started);
} }
acceptor_thread.start(wait_threads_started, std::bind(&TcpServerTmpl::startAccept, this)); acceptor_loop->runInLoop(std::bind(&TcpServerEventLoopTmpl::startAccept, this));
} }
// stop thread-safe // stop thread-safe
void stop(bool wait_threads_stopped = true) { void stop(bool wait_threads_stopped = true) {
acceptor_thread.stop(wait_threads_stopped); closesocket();
if (worker_threads.threadNum() > 0) { if (worker_threads.threadNum() > 0) {
worker_threads.stop(wait_threads_stopped); worker_threads.stop(wait_threads_stopped);
} }
@ -83,27 +123,30 @@ public:
int withTLS(hssl_ctx_opt_t* opt = NULL) { int withTLS(hssl_ctx_opt_t* opt = NULL) {
tls = true; tls = true;
if (opt) { if (opt) {
opt->endpoint = HSSL_SERVER; if (tls_setting == NULL) {
if (hssl_ctx_init(opt) == NULL) { HV_ALLOC_SIZEOF(tls_setting);
fprintf(stderr, "hssl_ctx_init failed!\n");
return -1;
} }
opt->endpoint = HSSL_SERVER;
*tls_setting = *opt;
} }
return 0; return 0;
} }
void setUnpack(unpack_setting_t* setting) { void setUnpack(unpack_setting_t* setting) {
if (setting) { if (setting == NULL) {
unpack_setting = *setting; HV_FREE(unpack_setting);
} else { return;
unpack_setting.mode = UNPACK_MODE_NONE;
} }
if (unpack_setting == NULL) {
HV_ALLOC_SIZEOF(unpack_setting);
}
*unpack_setting = *setting;
} }
// channel // channel
const TSocketChannelPtr& addChannel(hio_t* io) { const TSocketChannelPtr& addChannel(hio_t* io) {
uint32_t id = hio_id(io); uint32_t id = hio_id(io);
auto channel = TSocketChannelPtr(new TSocketChannel(io)); auto channel = std::make_shared<TSocketChannel>(io);
std::lock_guard<std::mutex> locker(mutex_); std::lock_guard<std::mutex> locker(mutex_);
channels[id] = channel; channels[id] = channel;
return channels[id]; return channels[id];
@ -147,7 +190,7 @@ public:
private: private:
static void newConnEvent(hio_t* connio) { static void newConnEvent(hio_t* connio) {
TcpServerTmpl* server = (TcpServerTmpl*)hevent_userdata(connio); TcpServerEventLoopTmpl* server = (TcpServerEventLoopTmpl*)hevent_userdata(connio);
if (server->connectionNum() >= server->max_connections) { if (server->connectionNum() >= server->max_connections) {
hlogw("over max_connections"); hlogw("over max_connections");
hio_close(connio); hio_close(connio);
@ -186,8 +229,8 @@ private:
// so in this lambda function, no code should be added below. // so in this lambda function, no code should be added below.
}; };
if (server->unpack_setting.mode != UNPACK_MODE_NONE) { if (server->unpack_setting) {
channel->setUnpack(&server->unpack_setting); channel->setUnpack(server->unpack_setting);
} }
channel->startRead(); channel->startRead();
if (server->onConnection) { if (server->onConnection) {
@ -196,21 +239,24 @@ private:
} }
static void onAccept(hio_t* connio) { static void onAccept(hio_t* connio) {
TcpServerTmpl* server = (TcpServerTmpl*)hevent_userdata(connio); TcpServerEventLoopTmpl* server = (TcpServerEventLoopTmpl*)hevent_userdata(connio);
// NOTE: detach from acceptor loop // NOTE: detach from acceptor loop
hio_detach(connio); hio_detach(connio);
EventLoopPtr worker_loop = server->worker_threads.nextLoop(server->load_balance); EventLoopPtr worker_loop = server->worker_threads.nextLoop(server->load_balance);
if (worker_loop == NULL) { if (worker_loop == NULL) {
worker_loop = server->acceptor_thread.loop(); worker_loop = server->acceptor_loop;
} }
++worker_loop->connectionNum; ++worker_loop->connectionNum;
worker_loop->runInLoop(std::bind(&TcpServerTmpl::newConnEvent, connio)); worker_loop->runInLoop(std::bind(&TcpServerEventLoopTmpl::newConnEvent, connio));
} }
public: public:
std::string host;
int port;
int listenfd; int listenfd;
bool tls; bool tls;
unpack_setting_t unpack_setting; hssl_ctx_opt_t* tls_setting;
unpack_setting_t* unpack_setting;
// Callback // Callback
std::function<void(const TSocketChannelPtr&)> onConnection; std::function<void(const TSocketChannelPtr&)> onConnection;
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage; std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
@ -225,8 +271,42 @@ private:
std::map<uint32_t, TSocketChannelPtr> channels; // GUAREDE_BY(mutex_) std::map<uint32_t, TSocketChannelPtr> channels; // GUAREDE_BY(mutex_)
std::mutex mutex_; std::mutex mutex_;
EventLoopThread acceptor_thread; EventLoopPtr acceptor_loop;
EventLoopThreadPool worker_threads; EventLoopThreadPool worker_threads;
};
template<class TSocketChannel = SocketChannel>
class TcpServerTmpl : private EventLoopThread, public TcpServerEventLoopTmpl<TSocketChannel> {
public:
TcpServerTmpl(EventLoopPtr loop = NULL)
: EventLoopThread(loop)
, TcpServerEventLoopTmpl<TSocketChannel>(EventLoopThread::loop())
, is_loop_owner(loop == NULL)
{}
virtual ~TcpServerTmpl() {
stop(true);
}
EventLoopPtr loop(int idx = -1) {
return TcpServerEventLoopTmpl<TSocketChannel>::loop(idx);
}
// start thread-safe
void start(bool wait_threads_started = true) {
TcpServerEventLoopTmpl<TSocketChannel>::start(wait_threads_started);
EventLoopThread::start(wait_threads_started);
}
// stop thread-safe
void stop(bool wait_threads_stopped = true) {
if (is_loop_owner) {
EventLoopThread::stop(wait_threads_stopped);
}
TcpServerEventLoopTmpl<TSocketChannel>::stop(wait_threads_stopped);
}
private:
bool is_loop_owner;
}; };
typedef TcpServerTmpl<SocketChannel> TcpServer; typedef TcpServerTmpl<SocketChannel> TcpServer;

View File

@ -9,31 +9,60 @@
namespace hv { namespace hv {
template<class TSocketChannel = SocketChannel> template<class TSocketChannel = SocketChannel>
class UdpClientTmpl { class UdpClientEventLoopTmpl {
public: public:
typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr; typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr;
UdpClientTmpl() { UdpClientEventLoopTmpl(EventLoopPtr loop = NULL) {
loop_ = loop ? loop : std::make_shared<EventLoop>();
remote_port = 0;
#if WITH_KCP #if WITH_KCP
enable_kcp = false; kcp_setting = NULL;
#endif #endif
} }
virtual ~UdpClientTmpl() { virtual ~UdpClientEventLoopTmpl() {
#if WITH_KCP
HV_FREE(kcp_setting);
#endif
} }
const EventLoopPtr& loop() { const EventLoopPtr& loop() {
return loop_thread.loop(); return loop_;
} }
//NOTE: By default, not bind local port. If necessary, you can call system api bind() after createsocket(). // NOTE: By default, not bind local port. If necessary, you can call bind() after createsocket().
//@retval >=0 sockfd, <0 error // @retval >=0 sockfd, <0 error
int createsocket(int remote_port, const char* remote_host = "127.0.0.1") { int createsocket(int remote_port, const char* remote_host = "127.0.0.1") {
hio_t* io = hloop_create_udp_client(loop_thread.hloop(), remote_host, remote_port); hio_t* io = hloop_create_udp_client(loop_->loop(), remote_host, remote_port);
if (io == NULL) return -1; if (io == NULL) return -1;
channel.reset(new TSocketChannel(io)); this->remote_host = remote_host;
return channel->fd(); this->remote_port = remote_port;
channel = std::make_shared<TSocketChannel>(io);
int sockfd = channel->fd();
if (hv_strendswith(remote_host, ".255")) {
udp_broadcast(sockfd, 1);
}
return sockfd;
} }
int bind(int local_port, const char* local_host = "0.0.0.0") {
if (channel == NULL || channel->isClosed()) {
return -1;
}
sockaddr_u local_addr;
memset(&local_addr, 0, sizeof(local_addr));
int ret = sockaddr_set_ipport(&local_addr, local_host, local_port);
if (ret != 0) {
return NABS(ret);
}
ret = ::bind(channel->fd(), &local_addr.sa, SOCKADDR_LEN(&local_addr));
if (ret != 0) {
perror("bind");
}
return ret;
}
// closesocket thread-safe // closesocket thread-safe
void closesocket() { void closesocket() {
if (channel) { if (channel) {
@ -42,7 +71,16 @@ public:
} }
int startRecv() { int startRecv() {
assert(channel != NULL); if (channel == NULL || channel->isClosed()) {
int sockfd = createsocket(remote_port, remote_host.c_str());
if (sockfd < 0) {
hloge("createsocket %s:%d return %d!\n", remote_host.c_str(), remote_port, sockfd);
return sockfd;
}
}
if (channel == NULL || channel->isClosed()) {
return -1;
}
channel->onread = [this](Buffer* buf) { channel->onread = [this](Buffer* buf) {
if (onMessage) { if (onMessage) {
onMessage(channel, buf); onMessage(channel, buf);
@ -54,19 +92,21 @@ public:
} }
}; };
#if WITH_KCP #if WITH_KCP
if (enable_kcp) { if (kcp_setting) {
hio_set_kcp(channel->io(), &kcp_setting); hio_set_kcp(channel->io(), kcp_setting);
} }
#endif #endif
return channel->startRead(); return channel->startRead();
} }
void start(bool wait_threads_started = true) { int stopRecv() {
loop_thread.start(wait_threads_started, std::bind(&UdpClientTmpl::startRecv, this)); if (channel == NULL) return -1;
return channel->stopRead();
} }
// stop thread-safe
void stop(bool wait_threads_stopped = true) { // start thread-safe
loop_thread.stop(wait_threads_stopped); void start() {
loop_->runInLoop(std::bind(&UdpClientEventLoopTmpl::startRecv, this));
} }
// sendto thread-safe // sendto thread-safe
@ -85,20 +125,25 @@ public:
#if WITH_KCP #if WITH_KCP
void setKcp(kcp_setting_t* setting) { void setKcp(kcp_setting_t* setting) {
if (setting) { if (setting == NULL) {
enable_kcp = true; HV_FREE(kcp_setting);
kcp_setting = *setting; return;
} else {
enable_kcp = false;
} }
if (kcp_setting == NULL) {
HV_ALLOC_SIZEOF(kcp_setting);
}
*kcp_setting = *setting;
} }
#endif #endif
public: public:
TSocketChannelPtr channel; TSocketChannelPtr channel;
std::string remote_host;
int remote_port;
#if WITH_KCP #if WITH_KCP
bool enable_kcp; kcp_setting_t* kcp_setting;
kcp_setting_t kcp_setting;
#endif #endif
// Callback // Callback
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage; std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
@ -107,7 +152,44 @@ public:
private: private:
std::mutex sendto_mutex; std::mutex sendto_mutex;
EventLoopThread loop_thread; EventLoopPtr loop_;
};
template<class TSocketChannel = SocketChannel>
class UdpClientTmpl : private EventLoopThread, public UdpClientEventLoopTmpl<TSocketChannel> {
public:
UdpClientTmpl(EventLoopPtr loop = NULL)
: EventLoopThread(loop)
, UdpClientEventLoopTmpl<TSocketChannel>(EventLoopThread::loop())
, is_loop_owner(loop == NULL)
{}
virtual ~UdpClientTmpl() {
stop(true);
}
const EventLoopPtr& loop() {
return EventLoopThread::loop();
}
// start thread-safe
void start(bool wait_threads_started = true) {
if (isRunning()) {
UdpClientEventLoopTmpl<TSocketChannel>::start();
} else {
EventLoopThread::start(wait_threads_started, std::bind(&UdpClientTmpl::startRecv, this));
}
}
// stop thread-safe
void stop(bool wait_threads_stopped = true) {
UdpClientEventLoopTmpl<TSocketChannel>::closesocket();
if (is_loop_owner) {
EventLoopThread::stop(wait_threads_stopped);
}
}
private:
bool is_loop_owner;
}; };
typedef UdpClientTmpl<SocketChannel> UdpClient; typedef UdpClientTmpl<SocketChannel> UdpClient;

View File

@ -9,28 +9,35 @@
namespace hv { namespace hv {
template<class TSocketChannel = SocketChannel> template<class TSocketChannel = SocketChannel>
class UdpServerTmpl { class UdpServerEventLoopTmpl {
public: public:
typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr; typedef std::shared_ptr<TSocketChannel> TSocketChannelPtr;
UdpServerTmpl() { UdpServerEventLoopTmpl(EventLoopPtr loop = NULL) {
loop_ = loop ? loop : std::make_shared<EventLoop>();
port = 0;
#if WITH_KCP #if WITH_KCP
enable_kcp = false; kcp_setting = NULL;
#endif #endif
} }
virtual ~UdpServerTmpl() { virtual ~UdpServerEventLoopTmpl() {
#if WITH_KCP
HV_FREE(kcp_setting);
#endif
} }
const EventLoopPtr& loop() { const EventLoopPtr& loop() {
return loop_thread.loop(); return loop_;
} }
//@retval >=0 bindfd, <0 error //@retval >=0 bindfd, <0 error
int createsocket(int port, const char* host = "0.0.0.0") { int createsocket(int port, const char* host = "0.0.0.0") {
hio_t* io = hloop_create_udp_server(loop_thread.hloop(), host, port); hio_t* io = hloop_create_udp_server(loop_->loop(), host, port);
if (io == NULL) return -1; if (io == NULL) return -1;
channel.reset(new TSocketChannel(io)); this->host = host;
this->port = port;
channel = std::make_shared<TSocketChannel>(io);
return channel->fd(); return channel->fd();
} }
// closesocket thread-safe // closesocket thread-safe
@ -41,7 +48,16 @@ public:
} }
int startRecv() { int startRecv() {
assert(channel != NULL); if (channel == NULL || channel->isClosed()) {
int bindfd = createsocket(port, host.c_str());
if (bindfd < 0) {
hloge("createsocket %s:%d return %d!\n", host.c_str(), port, bindfd);
return bindfd;
}
}
if (channel == NULL || channel->isClosed()) {
return -1;
}
channel->onread = [this](Buffer* buf) { channel->onread = [this](Buffer* buf) {
if (onMessage) { if (onMessage) {
onMessage(channel, buf); onMessage(channel, buf);
@ -53,19 +69,21 @@ public:
} }
}; };
#if WITH_KCP #if WITH_KCP
if (enable_kcp) { if (kcp_setting) {
hio_set_kcp(channel->io(), &kcp_setting); hio_set_kcp(channel->io(), kcp_setting);
} }
#endif #endif
return channel->startRead(); return channel->startRead();
} }
void start(bool wait_threads_started = true) { int stopRecv() {
loop_thread.start(wait_threads_started, std::bind(&UdpServerTmpl::startRecv, this)); if (channel == NULL) return -1;
return channel->stopRead();
} }
// stop thread-safe
void stop(bool wait_threads_stopped = true) { // start thread-safe
loop_thread.stop(wait_threads_stopped); void start() {
loop_->runInLoop(std::bind(&UdpServerEventLoopTmpl::startRecv, this));
} }
// sendto thread-safe // sendto thread-safe
@ -82,11 +100,25 @@ public:
return sendto(str.data(), str.size(), peeraddr); return sendto(str.data(), str.size(), peeraddr);
} }
#if WITH_KCP
void setKcp(kcp_setting_t* setting) {
if (setting == NULL) {
HV_FREE(kcp_setting);
return;
}
if (kcp_setting == NULL) {
HV_ALLOC_SIZEOF(kcp_setting);
}
*kcp_setting = *setting;
}
#endif
public: public:
std::string host;
int port;
TSocketChannelPtr channel; TSocketChannelPtr channel;
#if WITH_KCP #if WITH_KCP
bool enable_kcp; kcp_setting_t* kcp_setting;
kcp_setting_t kcp_setting;
#endif #endif
// Callback // Callback
std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage; std::function<void(const TSocketChannelPtr&, Buffer*)> onMessage;
@ -95,7 +127,44 @@ public:
private: private:
std::mutex sendto_mutex; std::mutex sendto_mutex;
EventLoopThread loop_thread; EventLoopPtr loop_;
};
template<class TSocketChannel = SocketChannel>
class UdpServerTmpl : private EventLoopThread, public UdpServerEventLoopTmpl<TSocketChannel> {
public:
UdpServerTmpl(EventLoopPtr loop = NULL)
: EventLoopThread(loop)
, UdpServerEventLoopTmpl<TSocketChannel>(EventLoopThread::loop())
, is_loop_owner(loop == NULL)
{}
virtual ~UdpServerTmpl() {
stop(true);
}
const EventLoopPtr& loop() {
return EventLoopThread::loop();
}
// start thread-safe
void start(bool wait_threads_started = true) {
if (isRunning()) {
UdpServerEventLoopTmpl<TSocketChannel>::start();
} else {
EventLoopThread::start(wait_threads_started, std::bind(&UdpServerTmpl::startRecv, this));
}
}
// stop thread-safe
void stop(bool wait_threads_stopped = true) {
UdpServerEventLoopTmpl<TSocketChannel>::closesocket();
if (is_loop_owner) {
EventLoopThread::stop(wait_threads_stopped);
}
}
private:
bool is_loop_owner;
}; };
typedef UdpServerTmpl<SocketChannel> UdpServer; typedef UdpServerTmpl<SocketChannel> UdpServer;

View File

@ -10,12 +10,13 @@
namespace hv { namespace hv {
class WebSocketChannel : public SocketChannel { class HV_EXPORT WebSocketChannel : public SocketChannel {
public: public:
ws_session_type type; ws_session_type type;
WebSocketChannel(hio_t* io, ws_session_type type = WS_CLIENT) WebSocketChannel(hio_t* io, ws_session_type type = WS_CLIENT)
: SocketChannel(io) : SocketChannel(io)
, type(type) , type(type)
, opcode(WS_OPCODE_CLOSE)
{} {}
~WebSocketChannel() {} ~WebSocketChannel() {}
@ -25,80 +26,23 @@ public:
return send(msg.c_str(), msg.size(), opcode, fin); return send(msg.c_str(), msg.size(), opcode, fin);
} }
int send(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY, bool fin = true) { int send(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY, bool fin = true);
int fragment = 0xFFFF; // 65535
if (len > fragment) {
return send(buf, len, fragment, opcode);
}
std::lock_guard<std::mutex> locker(mutex_);
return sendFrame(buf, len, opcode, fin);
}
// websocket fragment // websocket fragment
// lock -> int send(const char* buf, int len, int fragment, enum ws_opcode opcode = WS_OPCODE_BINARY);
// send(p, fragment, opcode, false) ->
// send(p, fragment, WS_OPCODE_CONTINUE, false) ->
// ... ->
// send(p, remain, WS_OPCODE_CONTINUE, true)
// unlock
int send(const char* buf, int len, int fragment, enum ws_opcode opcode = WS_OPCODE_BINARY) {
std::lock_guard<std::mutex> locker(mutex_);
if (len <= fragment) {
return sendFrame(buf, len, opcode, true);
}
// first fragment int sendPing();
int nsend = sendFrame(buf, fragment, opcode, false); int sendPong();
if (nsend < 0) return nsend;
const char* p = buf + fragment; int close() {
int remain = len - fragment; return SocketChannel::close(type == WS_SERVER);
while (remain > fragment) {
nsend = sendFrame(p, fragment, WS_OPCODE_CONTINUE, false);
if (nsend < 0) return nsend;
p += fragment;
remain -= fragment;
}
// last fragment
nsend = sendFrame(p, remain, WS_OPCODE_CONTINUE, true);
if (nsend < 0) return nsend;
return len;
}
int sendPing() {
std::lock_guard<std::mutex> locker(mutex_);
if (type == WS_CLIENT) {
return write(WS_CLIENT_PING_FRAME, WS_CLIENT_MIN_FRAME_SIZE);
}
return write(WS_SERVER_PING_FRAME, WS_SERVER_MIN_FRAME_SIZE);
}
int sendPong() {
std::lock_guard<std::mutex> locker(mutex_);
if (type == WS_CLIENT) {
return write(WS_CLIENT_PONG_FRAME, WS_CLIENT_MIN_FRAME_SIZE);
}
return write(WS_SERVER_PONG_FRAME, WS_SERVER_MIN_FRAME_SIZE);
} }
protected: protected:
int sendFrame(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY, bool fin = true) { int sendFrame(const char* buf, int len, enum ws_opcode opcode = WS_OPCODE_BINARY, bool fin = true);
bool has_mask = false;
char mask[4] = {0};
if (type == WS_CLIENT) {
*(int*)mask = rand();
has_mask = true;
}
int frame_size = ws_calc_frame_size(len, has_mask);
if (sendbuf_.len < frame_size) {
sendbuf_.resize(ceil2e(frame_size));
}
ws_build_frame(sendbuf_.base, buf, len, mask, has_mask, opcode, fin);
return write(sendbuf_.base, frame_size);
}
public:
enum ws_opcode opcode;
private: private:
Buffer sendbuf_; Buffer sendbuf_;
std::mutex mutex_; std::mutex mutex_;

View File

@ -21,9 +21,11 @@ public:
std::function<void()> onopen; std::function<void()> onopen;
std::function<void()> onclose; std::function<void()> onclose;
std::function<void(const std::string& msg)> onmessage; std::function<void(const std::string& msg)> onmessage;
// PATCH: onmessage not given opcode
enum ws_opcode opcode() { return channel ? channel->opcode : WS_OPCODE_CLOSE; }
WebSocketClient(); WebSocketClient(EventLoopPtr loop = NULL);
~WebSocketClient(); virtual ~WebSocketClient();
// url = ws://ip:port/path // url = ws://ip:port/path
// url = wss://ip:port/path // url = wss://ip:port/path
@ -37,6 +39,16 @@ public:
ping_interval = ms; ping_interval = ms;
} }
// NOTE: call before open
void setHttpRequest(const HttpRequestPtr& req) {
http_req_ = req;
}
// NOTE: call when onopen
const HttpResponsePtr& getHttpResponse() {
return http_resp_;
}
private: private:
enum State { enum State {
CONNECTING, CONNECTING,

View File

@ -15,18 +15,27 @@
namespace hv { namespace hv {
struct WebSocketService { struct WebSocketService {
std::function<void(const WebSocketChannelPtr&, const std::string&)> onopen; std::function<void(const WebSocketChannelPtr&, const HttpRequestPtr&)> onopen;
std::function<void(const WebSocketChannelPtr&, const std::string&)> onmessage; std::function<void(const WebSocketChannelPtr&, const std::string&)> onmessage;
std::function<void(const WebSocketChannelPtr&)> onclose; std::function<void(const WebSocketChannelPtr&)> onclose;
int ping_interval; int ping_interval;
WebSocketService() { WebSocketService() : ping_interval(0) {}
ping_interval = 10000; // ms
void setPingInterval(int ms) {
ping_interval = ms;
} }
}; };
class WebSocketServer : public HttpServer { class WebSocketServer : public HttpServer {
public: public:
WebSocketServer(WebSocketService* service = NULL)
: HttpServer()
{
this->ws = service;
}
~WebSocketServer() { stop(); }
void registerWebSocketService(WebSocketService* service) { void registerWebSocketService(WebSocketService* service) {
this->ws = service; this->ws = service;
} }

View File

@ -1,4 +1,5 @@
#ifndef HV_AXIOS_H_ #ifndef HV_AXIOS_H_
#define HV_AXIOS_H_
#include "json.hpp" #include "json.hpp"
#include "requests.h" #include "requests.h"
@ -64,7 +65,7 @@ using requests::ResponseCallback;
namespace axios { namespace axios {
HV_INLINE Request newRequestFromJson(const json& jreq) { HV_INLINE Request newRequestFromJson(const json& jreq) {
Request req(new HttpRequest); auto req = std::make_shared<HttpRequest>();
// url // url
if (jreq.contains("url")) { if (jreq.contains("url")) {
req->url = jreq["url"]; req->url = jreq["url"];

View File

@ -46,6 +46,12 @@ typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
#ifdef _WIN32 #ifdef _WIN32
#define ATOMIC_FLAG_TEST_AND_SET atomic_flag_test_and_set
static inline bool atomic_flag_test_and_set(atomic_flag* p) {
// return InterlockedIncrement((LONG*)&p->_Value, 1);
return InterlockedCompareExchange((LONG*)&p->_Value, 1, 0);
}
#define ATOMIC_ADD InterlockedAdd #define ATOMIC_ADD InterlockedAdd
#define ATOMIC_SUB(p, n) InterlockedAdd(p, -n) #define ATOMIC_SUB(p, n) InterlockedAdd(p, -n)
#define ATOMIC_INC InterlockedIncrement #define ATOMIC_INC InterlockedIncrement

View File

@ -50,7 +50,7 @@ HV_EXPORT void hv_free(void* ptr);
HV_EXPORT long hv_alloc_cnt(); HV_EXPORT long hv_alloc_cnt();
HV_EXPORT long hv_free_cnt(); HV_EXPORT long hv_free_cnt();
HV_INLINE void hv_memcheck() { HV_INLINE void hv_memcheck(void) {
printf("Memcheck => alloc:%ld free:%ld\n", hv_alloc_cnt(), hv_free_cnt()); printf("Memcheck => alloc:%ld free:%ld\n", hv_alloc_cnt(), hv_free_cnt());
} }
#define HV_MEMCHECK atexit(hv_memcheck); #define HV_MEMCHECK atexit(hv_memcheck);
@ -63,6 +63,7 @@ HV_EXPORT char* hv_strreverse(char* str);
HV_EXPORT bool hv_strstartswith(const char* str, const char* start); HV_EXPORT bool hv_strstartswith(const char* str, const char* start);
HV_EXPORT bool hv_strendswith(const char* str, const char* end); HV_EXPORT bool hv_strendswith(const char* str, const char* end);
HV_EXPORT bool hv_strcontains(const char* str, const char* sub); HV_EXPORT bool hv_strcontains(const char* str, const char* sub);
HV_EXPORT bool hv_wildcard_match(const char* str, const char* pattern);
// strncpy n = sizeof(dest_buf)-1 // strncpy n = sizeof(dest_buf)-1
// hv_strncpy n = sizeof(dest_buf) // hv_strncpy n = sizeof(dest_buf)

View File

@ -10,7 +10,7 @@
#endif #endif
#ifndef HAVE_STDATOMIC_H #ifndef HAVE_STDATOMIC_H
#define HAVE_STDATOMIC_H 0 #define HAVE_STDATOMIC_H 1
#endif #endif
#ifndef HAVE_SYS_TYPES_H #ifndef HAVE_SYS_TYPES_H
@ -22,7 +22,7 @@
#endif #endif
#ifndef HAVE_SYS_TIME_H #ifndef HAVE_SYS_TIME_H
#define HAVE_SYS_TIME_H 0 #define HAVE_SYS_TIME_H 1
#endif #endif
#ifndef HAVE_FCNTL_H #ifndef HAVE_FCNTL_H
@ -30,11 +30,11 @@
#endif #endif
#ifndef HAVE_PTHREAD_H #ifndef HAVE_PTHREAD_H
#define HAVE_PTHREAD_H 0 #define HAVE_PTHREAD_H 1
#endif #endif
#ifndef HAVE_ENDIAN_H #ifndef HAVE_ENDIAN_H
#define HAVE_ENDIAN_H 0 #define HAVE_ENDIAN_H 1
#endif #endif
#ifndef HAVE_SYS_ENDIAN_H #ifndef HAVE_SYS_ENDIAN_H
@ -54,48 +54,46 @@
#endif #endif
#ifndef HAVE_CLOCK_GETTIME #ifndef HAVE_CLOCK_GETTIME
#define HAVE_CLOCK_GETTIME 0 #define HAVE_CLOCK_GETTIME 1
#endif #endif
#ifndef HAVE_GETTIMEOFDAY #ifndef HAVE_GETTIMEOFDAY
#define HAVE_GETTIMEOFDAY 0 #define HAVE_GETTIMEOFDAY 1
#endif #endif
#ifndef HAVE_PTHREAD_SPIN_LOCK #ifndef HAVE_PTHREAD_SPIN_LOCK
#define HAVE_PTHREAD_SPIN_LOCK 0 #define HAVE_PTHREAD_SPIN_LOCK 1
#endif #endif
#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
#define HAVE_PTHREAD_MUTEX_TIMEDLOCK 0 #define HAVE_PTHREAD_MUTEX_TIMEDLOCK 1
#endif #endif
#ifndef HAVE_SEM_TIMEDWAIT #ifndef HAVE_SEM_TIMEDWAIT
#define HAVE_SEM_TIMEDWAIT 0 #define HAVE_SEM_TIMEDWAIT 1
#endif #endif
#ifndef HAVE_PIPE #ifndef HAVE_PIPE
#define HAVE_PIPE 0 #define HAVE_PIPE 1
#endif #endif
#ifndef HAVE_SOCKETPAIR #ifndef HAVE_SOCKETPAIR
#define HAVE_SOCKETPAIR 0 #define HAVE_SOCKETPAIR 1
#endif #endif
#ifndef HAVE_EVENTFD #ifndef HAVE_EVENTFD
#define HAVE_EVENTFD 0 #define HAVE_EVENTFD 1
#endif #endif
#ifndef HAVE_SETPROCTITLE #ifndef HAVE_SETPROCTITLE
#define HAVE_SETPROCTITLE 0 #define HAVE_SETPROCTITLE 0
#endif #endif
#define WITH_OPENSSL 1 /* #undef WITH_OPENSSL */
/* #undef WITH_GNUTLS */ /* #undef WITH_GNUTLS */
/* #undef WITH_MBEDTLS */ /* #undef WITH_MBEDTLS */
/* #undef ENABLE_UDS */ /* #undef ENABLE_UDS */
/* #undef USE_MULTIMAP */ /* #undef USE_MULTIMAP */
/* #undef WITH_KCP */ /* #undef WITH_KCP */
#endif // HV_CONFIG_H_ #endif // HV_CONFIG_H_

View File

@ -68,12 +68,13 @@ ASCII:
#define IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) #define IS_ALPHA(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
#endif #endif
#ifndef IS_NUM // NOTE: IS_NUM conflicts with mysql.h
#define IS_NUM(c) ((c) >= '0' && (c) <= '9') #ifndef IS_DIGIT
#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
#endif #endif
#ifndef IS_ALPHANUM #ifndef IS_ALPHANUM
#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_DIGIT(c))
#endif #endif
#ifndef IS_CNTRL #ifndef IS_CNTRL
@ -85,7 +86,7 @@ ASCII:
#endif #endif
#ifndef IS_HEX #ifndef IS_HEX
#define IS_HEX(c) (IS_NUM(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) #define IS_HEX(c) (IS_DIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif #endif
#ifndef IS_LOWER #ifndef IS_LOWER

View File

@ -18,6 +18,89 @@
#define le32toh(v) OSSwapLittleToHostInt32(v) #define le32toh(v) OSSwapLittleToHostInt32(v)
#define le64toh(v) OSSwapLittleToHostInt64(v) #define le64toh(v) OSSwapLittleToHostInt64(v)
#elif defined(OS_WIN) #elif defined(OS_WIN)
#if _WIN32_WINNT < _WIN32_WINNT_WIN8
/*
* Byte order conversion functions for 64-bit integers and 32 + 64 bit
* floating-point numbers. IEEE big-endian format is used for the
* network floating point format.
*/
#define _WS2_32_WINSOCK_SWAP_LONG(l) \
( ( ((l) >> 24) & 0x000000FFL ) | \
( ((l) >> 8) & 0x0000FF00L ) | \
( ((l) << 8) & 0x00FF0000L ) | \
( ((l) << 24) & 0xFF000000L ) )
#define _WS2_32_WINSOCK_SWAP_LONGLONG(l) \
( ( ((l) >> 56) & 0x00000000000000FFLL ) | \
( ((l) >> 40) & 0x000000000000FF00LL ) | \
( ((l) >> 24) & 0x0000000000FF0000LL ) | \
( ((l) >> 8) & 0x00000000FF000000LL ) | \
( ((l) << 8) & 0x000000FF00000000LL ) | \
( ((l) << 24) & 0x0000FF0000000000LL ) | \
( ((l) << 40) & 0x00FF000000000000LL ) | \
( ((l) << 56) & 0xFF00000000000000LL ) )
#ifndef htonll
__inline unsigned __int64 htonll ( unsigned __int64 Value )
{
const unsigned __int64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value);
return Retval;
}
#endif /* htonll */
#ifndef ntohll
__inline unsigned __int64 ntohll ( unsigned __int64 Value )
{
const unsigned __int64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value);
return Retval;
}
#endif /* ntohll */
#ifndef htonf
__inline unsigned __int32 htonf ( float Value )
{
unsigned __int32 Tempval;
unsigned __int32 Retval;
Tempval = *(unsigned __int32*)(&Value);
Retval = _WS2_32_WINSOCK_SWAP_LONG (Tempval);
return Retval;
}
#endif /* htonf */
#ifndef ntohf
__inline float ntohf ( unsigned __int32 Value )
{
const unsigned __int32 Tempval = _WS2_32_WINSOCK_SWAP_LONG (Value);
float Retval;
*((unsigned __int32*)&Retval) = Tempval;
return Retval;
}
#endif /* ntohf */
#ifndef htond
__inline unsigned __int64 htond ( double Value )
{
unsigned __int64 Tempval;
unsigned __int64 Retval;
Tempval = *(unsigned __int64*)(&Value);
Retval = _WS2_32_WINSOCK_SWAP_LONGLONG (Tempval);
return Retval;
}
#endif /* htond */
#ifndef ntohd
__inline double ntohd ( unsigned __int64 Value )
{
const unsigned __int64 Tempval = _WS2_32_WINSOCK_SWAP_LONGLONG (Value);
double Retval;
*((unsigned __int64*)&Retval) = Tempval;
return Retval;
}
#endif /* ntohd */
#endif
#define htobe16(v) htons(v) #define htobe16(v) htons(v)
#define htobe32(v) htonl(v) #define htobe32(v) htonl(v)
#define htobe64(v) htonll(v) #define htobe64(v) htonll(v)

View File

@ -135,6 +135,10 @@ struct s
// MSVC ports // MSVC ports
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning (disable: 4251) // STL dll
#pragma warning (disable: 4275) // dll-interface
#if _MSC_VER < 1900 // < VS2015 #if _MSC_VER < 1900 // < VS2015
#ifndef __cplusplus #ifndef __cplusplus

View File

@ -9,6 +9,7 @@
class HFile { class HFile {
public: public:
HFile() { HFile() {
filepath[0] = '\0';
fp = NULL; fp = NULL;
} }
@ -18,7 +19,7 @@ public:
int open(const char* filepath, const char* mode) { int open(const char* filepath, const char* mode) {
close(); close();
strncpy(this->filepath, filepath, MAX_PATH); strncpy(this->filepath, filepath, MAX_PATH - 1);
fp = fopen(filepath, mode); fp = fopen(filepath, mode);
return fp ? 0 : errno; return fp ? 0 : errno;
} }
@ -34,6 +35,16 @@ public:
return fp != NULL; return fp != NULL;
} }
int remove() {
close();
return ::remove(filepath);
}
int rename(const char* newpath) {
close();
return ::rename(filepath, newpath);
}
size_t read(void* ptr, size_t len) { size_t read(void* ptr, size_t len) {
return fread(ptr, 1, len, fp); return fread(ptr, 1, len, fp);
} }

View File

@ -119,7 +119,7 @@ HV_EXPORT const char* logger_get_cur_file(logger_t* logger);
// hlog: default logger instance // hlog: default logger instance
HV_EXPORT logger_t* hv_default_logger(); HV_EXPORT logger_t* hv_default_logger();
HV_EXPORT void hv_destroy_default_logger(); HV_EXPORT void hv_destroy_default_logger(void);
// macro hlog* // macro hlog*
#define hlog hv_default_logger() #define hlog hv_default_logger()
@ -138,11 +138,11 @@ HV_EXPORT void hv_destroy_default_logger();
#define hlog_fsync() logger_fsync(hlog) #define hlog_fsync() logger_fsync(hlog)
#define hlog_get_cur_file() logger_get_cur_file(hlog) #define hlog_get_cur_file() logger_get_cur_file(hlog)
#define hlogd(fmt, ...) logger_print(hlog, LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogd(fmt, ...) logger_print(hlog, LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
#define hlogi(fmt, ...) logger_print(hlog, LOG_LEVEL_INFO, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogi(fmt, ...) logger_print(hlog, LOG_LEVEL_INFO, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
#define hlogw(fmt, ...) logger_print(hlog, LOG_LEVEL_WARN, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogw(fmt, ...) logger_print(hlog, LOG_LEVEL_WARN, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
#define hloge(fmt, ...) logger_print(hlog, LOG_LEVEL_ERROR, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hloge(fmt, ...) logger_print(hlog, LOG_LEVEL_ERROR, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
#define hlogf(fmt, ...) logger_print(hlog, LOG_LEVEL_FATAL, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__) #define hlogf(fmt, ...) logger_print(hlog, LOG_LEVEL_FATAL, fmt " [%s:%d:%s]", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
// below for android // below for android
#if defined(ANDROID) || defined(__ANDROID__) #if defined(ANDROID) || defined(__ANDROID__)

View File

@ -131,6 +131,8 @@ HV_EXPORT hloop_t* hloop_new(int flags DEFAULT(HLOOP_FLAG_AUTO_FREE));
// WARN: Forbid to call hloop_free if HLOOP_FLAG_AUTO_FREE set. // WARN: Forbid to call hloop_free if HLOOP_FLAG_AUTO_FREE set.
HV_EXPORT void hloop_free(hloop_t** pp); HV_EXPORT void hloop_free(hloop_t** pp);
HV_EXPORT int hloop_process_events(hloop_t* loop, int timeout_ms DEFAULT(0));
// NOTE: when no active events, loop will quit if HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS set. // NOTE: when no active events, loop will quit if HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS set.
HV_EXPORT int hloop_run(hloop_t* loop); HV_EXPORT int hloop_run(hloop_t* loop);
// NOTE: hloop_stop called in loop-thread just set flag to quit in next loop, // NOTE: hloop_stop called in loop-thread just set flag to quit in next loop,
@ -185,8 +187,7 @@ HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT
HV_EXPORT void hidle_del(hidle_t* idle); HV_EXPORT void hidle_del(hidle_t* idle);
// timer // timer
// @param timeout: unit(ms) HV_EXPORT htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout_ms, uint32_t repeat DEFAULT(INFINITE));
HV_EXPORT htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t repeat DEFAULT(INFINITE));
/* /*
* minute hour day week month cb * minute hour day week month cb
* 0~59 0~23 1~31 0~6 1~12 * 0~59 0~23 1~31 0~6 1~12
@ -202,7 +203,7 @@ HV_EXPORT htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE)); int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
HV_EXPORT void htimer_del(htimer_t* timer); HV_EXPORT void htimer_del(htimer_t* timer);
HV_EXPORT void htimer_reset(htimer_t* timer); HV_EXPORT void htimer_reset(htimer_t* timer, uint32_t timeout_ms DEFAULT(0));
// io // io
//-----------------------low-level apis--------------------------------------- //-----------------------low-level apis---------------------------------------
@ -271,6 +272,7 @@ HV_EXPORT struct sockaddr* hio_peeraddr (hio_t* io);
HV_EXPORT void hio_set_context(hio_t* io, void* ctx); HV_EXPORT void hio_set_context(hio_t* io, void* ctx);
HV_EXPORT void* hio_context(hio_t* io); HV_EXPORT void* hio_context(hio_t* io);
HV_EXPORT bool hio_is_opened(hio_t* io); HV_EXPORT bool hio_is_opened(hio_t* io);
HV_EXPORT bool hio_is_connected(hio_t* io);
HV_EXPORT bool hio_is_closed(hio_t* io); HV_EXPORT bool hio_is_closed(hio_t* io);
// iobuf // iobuf
@ -437,6 +439,8 @@ HV_EXPORT hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int p
// hio_read(io) // hio_read(io)
// hio_read(io->upstream_io) // hio_read(io->upstream_io)
HV_EXPORT void hio_read_upstream(hio_t* io); HV_EXPORT void hio_read_upstream(hio_t* io);
// on_write(io) -> hio_write_is_complete(io) -> hio_read(io->upstream_io)
HV_EXPORT void hio_read_upstream_on_write_complete(hio_t* io, const void* buf, int writebytes);
// hio_write(io->upstream_io, buf, bytes) // hio_write(io->upstream_io, buf, bytes)
HV_EXPORT void hio_write_upstream(hio_t* io, void* buf, int bytes); HV_EXPORT void hio_write_upstream(hio_t* io, void* buf, int bytes);
// hio_close(io->upstream_io) // hio_close(io->upstream_io)
@ -494,17 +498,20 @@ typedef struct unpack_setting_s {
unsigned char delimiter[PACKAGE_MAX_DELIMITER_BYTES]; unsigned char delimiter[PACKAGE_MAX_DELIMITER_BYTES];
unsigned short delimiter_bytes; unsigned short delimiter_bytes;
}; };
// UNPACK_BY_LENGTH_FIELD /*
/* package_len = head_len + body_len + length_adjustment * UNPACK_BY_LENGTH_FIELD
*
* package_len = head_len + body_len + length_adjustment
* *
* if (length_field_coding == ENCODE_BY_VARINT) head_len = body_offset + varint_bytes - length_field_bytes; * if (length_field_coding == ENCODE_BY_VARINT) head_len = body_offset + varint_bytes - length_field_bytes;
* else head_len = body_offset; * else head_len = body_offset;
* *
* body_len calc by length_field * length_field stores body length, exclude head length,
* if length_field = head_len + body_len, then length_adjustment should be set to -head_len.
* *
*/ */
struct { struct {
unsigned short body_offset; unsigned short body_offset; // Equal to head length usually
unsigned short length_field_offset; unsigned short length_field_offset;
unsigned short length_field_bytes; unsigned short length_field_bytes;
short length_adjustment; short length_adjustment;
@ -528,7 +535,13 @@ typedef struct unpack_setting_s {
#endif #endif
} unpack_setting_t; } unpack_setting_t;
// @see examples/jsonrpc examples/protorpc /*
* @see examples/jsonrpc examples/protorpc
*
* NOTE: unpack_setting_t of multiple IOs of the same function also are same,
* so only the pointer of unpack_setting_t is stored in hio_t,
* the life time of unpack_setting_t shoud be guaranteed by caller.
*/
HV_EXPORT void hio_set_unpack(hio_t* io, unpack_setting_t* setting); HV_EXPORT void hio_set_unpack(hio_t* io, unpack_setting_t* setting);
HV_EXPORT void hio_unset_unpack(hio_t* io); HV_EXPORT void hio_unset_unpack(hio_t* io);
@ -691,6 +704,38 @@ typedef struct kcp_setting_s {
#endif #endif
} kcp_setting_t; } kcp_setting_t;
HV_INLINE void kcp_setting_init_with_normal_mode(kcp_setting_t* setting) {
memset(setting, 0, sizeof(kcp_setting_t));
setting->nodelay = 0;
setting->interval = 40;
setting->fastresend = 0;
setting->nocwnd = 0;
}
HV_INLINE void kcp_setting_init_with_fast_mode(kcp_setting_t* setting) {
memset(setting, 0, sizeof(kcp_setting_t));
setting->nodelay = 0;
setting->interval = 30;
setting->fastresend = 2;
setting->nocwnd = 1;
}
HV_INLINE void kcp_setting_init_with_fast2_mode(kcp_setting_t* setting) {
memset(setting, 0, sizeof(kcp_setting_t));
setting->nodelay = 1;
setting->interval = 20;
setting->fastresend = 2;
setting->nocwnd = 1;
}
HV_INLINE void kcp_setting_init_with_fast3_mode(kcp_setting_t* setting) {
memset(setting, 0, sizeof(kcp_setting_t));
setting->nodelay = 1;
setting->interval = 10;
setting->fastresend = 2;
setting->nocwnd = 1;
}
// @see examples/udp_echo_server.c => #define TEST_KCP 1 // @see examples/udp_echo_server.c => #define TEST_KCP 1
HV_EXPORT int hio_set_kcp(hio_t* io, kcp_setting_t* setting DEFAULT(NULL)); HV_EXPORT int hio_set_kcp(hio_t* io, kcp_setting_t* setting DEFAULT(NULL));
#endif #endif

View File

@ -68,7 +68,7 @@ typedef struct option_s {
} option_t; } option_t;
HV_EXPORT int main_ctx_init(int argc, char** argv); HV_EXPORT int main_ctx_init(int argc, char** argv);
HV_EXPORT void main_ctx_free(); HV_EXPORT void main_ctx_free(void);
// ls -a -l // ls -a -l
// ls -al // ls -al
@ -86,7 +86,7 @@ HV_EXPORT void setproctitle(const char* fmt, ...);
// pidfile // pidfile
HV_EXPORT int create_pidfile(); HV_EXPORT int create_pidfile();
HV_EXPORT void delete_pidfile(); HV_EXPORT void delete_pidfile(void);
HV_EXPORT pid_t getpid_from_pidfile(); HV_EXPORT pid_t getpid_from_pidfile();
// signal=[start,stop,restart,status,reload] // signal=[start,stop,restart,status,reload]

View File

@ -46,11 +46,10 @@ public:
#endif #endif
// KeyValue // KeyValue
namespace hv {
typedef std::map<std::string, std::string> keyval_t; typedef std::map<std::string, std::string> keyval_t;
typedef std::MultiMap<std::string, std::string> multi_keyval_t; typedef std::MultiMap<std::string, std::string> multi_keyval_t;
typedef HV_MAP<std::string, std::string> KeyValue;
namespace hv {
typedef HV_MAP<std::string, std::string> KeyValue;
} }
#endif // HV_MAP_H_ #endif // HV_MAP_H_

View File

@ -7,7 +7,7 @@
BEGIN_EXTERN_C BEGIN_EXTERN_C
#ifdef _MSC_VER #ifdef OS_WIN
#define hmutex_t CRITICAL_SECTION #define hmutex_t CRITICAL_SECTION
#define hmutex_init InitializeCriticalSection #define hmutex_init InitializeCriticalSection
#define hmutex_destroy DeleteCriticalSection #define hmutex_destroy DeleteCriticalSection

View File

@ -1,6 +1,10 @@
#ifndef HV_OBJECT_POOL_H_ #ifndef HV_OBJECT_POOL_H_
#define HV_OBJECT_POOL_H_ #define HV_OBJECT_POOL_H_
/*
* @usage unittest/objectpool_test.cpp
*/
#include <list> #include <list>
#include <memory> #include <memory>
#include <mutex> #include <mutex>

View File

@ -45,16 +45,20 @@
#endif #endif
// ARCH // ARCH
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#define ARCH_X86
#define ARCH_X86_32
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#define ARCH_X64 #define ARCH_X64
#define ARCH_X86_64 #define ARCH_X86_64
#elif defined(__arm__) #elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#define ARCH_ARM #define ARCH_X86
#elif defined(__aarch64__) || defined(__ARM64__) #define ARCH_X86_32
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
#define ARCH_ARM64 #define ARCH_ARM64
#elif defined(__arm__) || defined(_M_ARM)
#define ARCH_ARM
#elif defined(__mips64__)
#define ARCH_MIPS64
#elif defined(__mips__)
#define ARCH_MIPS
#else #else
#warning "Untested hardware architecture!" #warning "Untested hardware architecture!"
#endif #endif
@ -109,14 +113,10 @@
#pragma warning (disable: 4100) // unused param #pragma warning (disable: 4100) // unused param
#pragma warning (disable: 4102) // unreferenced label #pragma warning (disable: 4102) // unreferenced label
#pragma warning (disable: 4244) // conversion loss of data #pragma warning (disable: 4244) // conversion loss of data
#pragma warning (disable: 4251) // STL dll
#pragma warning (disable: 4267) // size_t => int #pragma warning (disable: 4267) // size_t => int
#pragma warning (disable: 4819) // Unicode #pragma warning (disable: 4819) // Unicode
#pragma warning (disable: 4996) // _CRT_SECURE_NO_WARNINGS #pragma warning (disable: 4996) // _CRT_SECURE_NO_WARNINGS
#elif defined(__MINGW32__) || defined(__MINGW64__)
#define COMPILER_MINGW
#elif defined(__GNUC__) #elif defined(__GNUC__)
#define COMPILER_GCC #define COMPILER_GCC
@ -127,6 +127,15 @@
#elif defined(__clang__) #elif defined(__clang__)
#define COMPILER_CLANG #define COMPILER_CLANG
#elif defined(__MINGW32__) || defined(__MINGW64__)
#define COMPILER_MINGW
#elif defined(__MSYS__)
#define COMPILER_MSYS
#elif defined(__CYGWIN__)
#define COMPILER_CYGWIN
#else #else
#warning "Untested compiler!" #warning "Untested compiler!"
#endif #endif
@ -136,9 +145,15 @@
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#ifndef _CRT_NONSTDC_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE #define _CRT_NONSTDC_NO_DEPRECATE
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#endif
#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS
#endif
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> // for inet_pton,inet_ntop #include <ws2tcpip.h> // for inet_pton,inet_ntop
#include <windows.h> #include <windows.h>
@ -222,11 +237,21 @@
// BYTE_ORDER // BYTE_ORDER
#ifndef BYTE_ORDER #ifndef BYTE_ORDER
#if defined(ARCH_X86) || defined(ARCH_X86_64) || \ #if defined(__BYTE_ORDER)
defined(__ARMEL__) || defined(__AARCH64EL__) #define BYTE_ORDER __BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN #elif defined(__BYTE_ORDER__)
#elif defined(__ARMEB__) || defined(__AARCH64EB__) #define BYTE_ORDER __BYTE_ORDER__
#define BYTE_ORDER BIG_ENDIAN #elif defined(ARCH_X86) || defined(ARCH_X86_64) || \
defined(__ARMEL__) || defined(__AARCH64EL__) || \
defined(__MIPSEL) || defined(__MIPS64EL)
#define BYTE_ORDER LITTLE_ENDIAN
#elif defined(__ARMEB__) || defined(__AARCH64EB__) || \
defined(__MIPSEB) || defined(__MIPS64EB)
#define BYTE_ORDER BIG_ENDIAN
#elif defined(OS_WIN)
#define BYTE_ORDER LITTLE_ENDIAN
#else
#warning "Unknown byte order!"
#endif #endif
#endif #endif

View File

@ -5,8 +5,12 @@
#include "hplatform.h" #include "hplatform.h"
#ifdef ENABLE_UDS #ifdef ENABLE_UDS
#ifdef OS_WIN
#include <afunix.h> // import struct sockaddr_un
#else
#include <sys/un.h> // import struct sockaddr_un #include <sys/un.h> // import struct sockaddr_un
#endif #endif
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "ws2_32.lib")
@ -28,7 +32,8 @@ HV_EXPORT const char* socket_strerror(int err);
#ifdef OS_WIN #ifdef OS_WIN
typedef int socklen_t; typedef SOCKET hsocket_t;
typedef int socklen_t;
void WSAInit(); void WSAInit();
void WSADeinit(); void WSADeinit();
@ -42,16 +47,15 @@ HV_INLINE int nonblocking(int sockfd) {
return ioctlsocket(sockfd, FIONBIO, &nb); return ioctlsocket(sockfd, FIONBIO, &nb);
} }
#ifndef poll
#define poll WSAPoll
#endif
#undef EAGAIN #undef EAGAIN
#define EAGAIN WSAEWOULDBLOCK #define EAGAIN WSAEWOULDBLOCK
#undef EINPROGRESS #undef EINPROGRESS
#define EINPROGRESS WSAEINPROGRESS #define EINPROGRESS WSAEINPROGRESS
#undef EINTR
#define EINTR WSAEINTR
#undef ENOTSOCK #undef ENOTSOCK
#define ENOTSOCK WSAENOTSOCK #define ENOTSOCK WSAENOTSOCK
@ -60,12 +64,27 @@ HV_INLINE int nonblocking(int sockfd) {
#else #else
#define blocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK) typedef int hsocket_t;
#define nonblocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK)
typedef int SOCKET; #ifndef SOCKET
#define SOCKET int
#endif
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1 #define INVALID_SOCKET -1
#define closesocket(fd) close(fd) #endif
HV_INLINE int blocking(int s) {
return fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK);
}
HV_INLINE int nonblocking(int s) {
return fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
}
HV_INLINE int closesocket(int sockfd) {
return close(sockfd);
}
#endif #endif
@ -163,7 +182,7 @@ HV_INLINE int tcp_nopush(int sockfd, int on DEFAULT(1)) {
#elif defined(TCP_CORK) #elif defined(TCP_CORK)
return setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, (const char*)&on, sizeof(int)); return setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, (const char*)&on, sizeof(int));
#else #else
return -10; return 0;
#endif #endif
} }
@ -188,6 +207,14 @@ HV_INLINE int udp_broadcast(int sockfd, int on DEFAULT(1)) {
return setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof(int)); return setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof(int));
} }
HV_INLINE int ip_v6only(int sockfd, int on DEFAULT(1)) {
#ifdef IPV6_V6ONLY
return setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(int));
#else
return 0;
#endif
}
// send timeout // send timeout
HV_INLINE int so_sndtimeo(int sockfd, int timeout) { HV_INLINE int so_sndtimeo(int sockfd, int timeout) {
#ifdef OS_WIN #ifdef OS_WIN
@ -208,6 +235,51 @@ HV_INLINE int so_rcvtimeo(int sockfd, int timeout) {
#endif #endif
} }
// send buffer size
HV_INLINE int so_sndbuf(int sockfd, int len) {
return setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&len, sizeof(int));
}
// recv buffer size
HV_INLINE int so_rcvbuf(int sockfd, int len) {
return setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&len, sizeof(int));
}
HV_INLINE int so_reuseaddr(int sockfd, int on DEFAULT(1)) {
#ifdef SO_REUSEADDR
// NOTE: SO_REUSEADDR allow to reuse sockaddr of TIME_WAIT status
return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(int));
#else
return 0;
#endif
}
HV_INLINE int so_reuseport(int sockfd, int on DEFAULT(1)) {
#ifdef SO_REUSEPORT
// NOTE: SO_REUSEPORT allow multiple sockets to bind same port
return setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char*)&on, sizeof(int));
#else
return 0;
#endif
}
HV_INLINE int so_linger(int sockfd, int timeout DEFAULT(1)) {
#ifdef SO_LINGER
struct linger linger;
if (timeout >= 0) {
linger.l_onoff = 1;
linger.l_linger = timeout;
} else {
linger.l_onoff = 0;
linger.l_linger = 0;
}
// NOTE: SO_LINGER change the default behavior of close, send RST, avoid TIME_WAIT
return setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&linger, sizeof(linger));
#else
return 0;
#endif
}
END_EXTERN_C END_EXTERN_C
#endif // HV_SOCKET_H_ #endif // HV_SOCKET_H_

View File

@ -8,11 +8,15 @@
!defined(WITH_GNUTLS) && \ !defined(WITH_GNUTLS) && \
!defined(WITH_MBEDTLS) !defined(WITH_MBEDTLS)
#ifdef OS_WIN #ifdef OS_WIN
#define WITH_WINTLS #define WITH_WINTLS
#ifdef _MSC_VER
#pragma comment(lib, "secur32.lib")
#pragma comment(lib, "crypt32.lib")
#endif
#elif defined(OS_DARWIN) #elif defined(OS_DARWIN)
#define WITH_APPLETLS #define WITH_APPLETLS
#else #else
#define HV_WITHOUT_SSL #define HV_WITHOUT_SSL
#endif #endif
#endif #endif
@ -78,6 +82,10 @@ HV_EXPORT int hssl_close(hssl_t ssl);
HV_EXPORT int hssl_set_sni_hostname(hssl_t ssl, const char* hostname); HV_EXPORT int hssl_set_sni_hostname(hssl_t ssl, const char* hostname);
#ifdef WITH_OPENSSL
HV_EXPORT int hssl_ctx_set_alpn_protos(hssl_ctx_t ssl_ctx, const unsigned char* protos, unsigned int protos_len);
#endif
END_EXTERN_C END_EXTERN_C
#endif // HV_SSL_H_ #endif // HV_SSL_H_

View File

@ -16,7 +16,8 @@
namespace hv { namespace hv {
HV_EXPORT extern std::string empty_string; HV_EXPORT extern std::string empty_string;
HV_EXPORT extern std::map<std::string, std::string> empty_map;
typedef std::vector<std::string> StringList; typedef std::vector<std::string> StringList;

View File

@ -1,6 +1,10 @@
#ifndef HV_THREAD_POOL_H_ #ifndef HV_THREAD_POOL_H_
#define HV_THREAD_POOL_H_ #define HV_THREAD_POOL_H_
/*
* @usage unittest/threadpool_test.cpp
*/
#include <time.h> #include <time.h>
#include <thread> #include <thread>
#include <list> #include <list>
@ -52,6 +56,10 @@ public:
int idleThreadNum() { int idleThreadNum() {
return idle_thread_num; return idle_thread_num;
} }
size_t taskNum() {
std::lock_guard<std::mutex> locker(task_mutex);
return tasks.size();
}
bool isStarted() { bool isStarted() {
return status != STOP; return status != STOP;
} }
@ -100,8 +108,8 @@ public:
} }
int wait() { int wait() {
while (1) { while (status != STOP) {
if (status == STOP || (tasks.empty() && idle_thread_num == cur_thread_num)) { if (tasks.empty() && idle_thread_num == cur_thread_num) {
break; break;
} }
std::this_thread::yield(); std::this_thread::yield();
@ -119,7 +127,7 @@ public:
template<class Fn, class... Args> template<class Fn, class... Args>
auto commit(Fn&& fn, Args&&... args) -> std::future<decltype(fn(args...))> { auto commit(Fn&& fn, Args&&... args) -> std::future<decltype(fn(args...))> {
if (status == STOP) start(); if (status == STOP) start();
if (idle_thread_num == 0 && cur_thread_num < max_thread_num) { if (idle_thread_num <= tasks.size() && cur_thread_num < max_thread_num) {
createThread(); createThread();
} }
using RetType = decltype(fn(args...)); using RetType = decltype(fn(args...));
@ -183,6 +191,7 @@ protected:
data.id = thread->get_id(); data.id = thread->get_id();
data.status = RUNNING; data.status = RUNNING;
data.start_time = time(NULL); data.start_time = time(NULL);
data.stop_time = 0;
threads.emplace_back(data); threads.emplace_back(data);
thread_mutex.unlock(); thread_mutex.unlock();
} }

View File

@ -67,6 +67,7 @@ HV_INLINE unsigned long long gettimeofday_us() {
HV_EXPORT unsigned long long gethrtime_us(); HV_EXPORT unsigned long long gethrtime_us();
HV_EXPORT datetime_t datetime_now(); HV_EXPORT datetime_t datetime_now();
HV_EXPORT datetime_t datetime_localtime(time_t seconds);
HV_EXPORT time_t datetime_mktime(datetime_t* dt); HV_EXPORT time_t datetime_mktime(datetime_t* dt);
HV_EXPORT datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1)); HV_EXPORT datetime_t* datetime_past(datetime_t* dt, int days DEFAULT(1));

View File

@ -20,7 +20,8 @@ enum http_parser_state {
HP_CHUNK_HEADER, HP_CHUNK_HEADER,
HP_BODY, HP_BODY,
HP_CHUNK_COMPLETE, HP_CHUNK_COMPLETE,
HP_MESSAGE_COMPLETE HP_MESSAGE_COMPLETE,
HP_ERROR
}; };
// http_status // http_status
@ -95,11 +96,13 @@ enum http_status {
}; };
#define HTTP_STATUS_IS_REDIRECT(status) \ #define HTTP_STATUS_IS_REDIRECT(status) \
( \
(status) == HTTP_STATUS_MOVED_PERMANENTLY || \ (status) == HTTP_STATUS_MOVED_PERMANENTLY || \
(status) == HTTP_STATUS_FOUND || \ (status) == HTTP_STATUS_FOUND || \
(status) == HTTP_STATUS_SEE_OTHER || \ (status) == HTTP_STATUS_SEE_OTHER || \
(status) == HTTP_STATUS_TEMPORARY_REDIRECT || \ (status) == HTTP_STATUS_TEMPORARY_REDIRECT || \
(status) == HTTP_STATUS_PERMANENT_REDIRECT (status) == HTTP_STATUS_PERMANENT_REDIRECT \
)
// http_mehtod // http_mehtod
// XX(num, name, string) // XX(num, name, string)
@ -156,40 +159,120 @@ enum http_method {
}; };
// MIME: https://www.iana.org/assignments/media-types/media-types.xhtml // MIME: https://www.iana.org/assignments/media-types/media-types.xhtml
// http_content_type
// XX(name, mime, suffix) // XX(name, mime, suffix)
#define HTTP_CONTENT_TYPE_MAP(XX) \ #define MIME_TYPE_TEXT_MAP(XX) \
XX(TEXT_PLAIN, text/plain, txt) \ XX(TEXT_PLAIN, text/plain, txt) \
XX(TEXT_HTML, text/html, html) \ XX(TEXT_HTML, text/html, html) \
XX(TEXT_CSS, text/css, css) \ XX(TEXT_CSS, text/css, css) \
XX(TEXT_CSV, text/csv, csv) \
XX(TEXT_MARKDOWN, text/markdown, md) \
XX(TEXT_EVENT_STREAM, text/event-stream, sse) \ XX(TEXT_EVENT_STREAM, text/event-stream, sse) \
#define MIME_TYPE_APPLICATION_MAP(XX) \
XX(APPLICATION_JAVASCRIPT, application/javascript, js) \
XX(APPLICATION_JSON, application/json, json) \
XX(APPLICATION_XML, application/xml, xml) \
XX(APPLICATION_URLENCODED, application/x-www-form-urlencoded, kv) \
XX(APPLICATION_OCTET_STREAM,application/octet-stream, bin) \
XX(APPLICATION_ZIP, application/zip, zip) \
XX(APPLICATION_GZIP, application/gzip, gzip) \
XX(APPLICATION_7Z, application/x-7z-compressed, 7z) \
XX(APPLICATION_RAR, application/x-rar-compressed, rar) \
XX(APPLICATION_PDF, application/pdf, pdf) \
XX(APPLICATION_RTF, application/rtf, rtf) \
XX(APPLICATION_GRPC, application/grpc, grpc) \
XX(APPLICATION_WASM, application/wasm, wasm) \
XX(APPLICATION_JAR, application/java-archive, jar) \
XX(APPLICATION_XHTML, application/xhtml+xml, xhtml) \
XX(APPLICATION_ATOM, application/atom+xml, atom) \
XX(APPLICATION_RSS, application/rss+xml, rss) \
XX(APPLICATION_WORD, application/msword, doc) \
XX(APPLICATION_EXCEL, application/vnd.ms-excel, xls) \
XX(APPLICATION_PPT, application/vnd.ms-powerpoint, ppt) \
XX(APPLICATION_EOT, application/vnd.ms-fontobject, eot) \
XX(APPLICATION_M3U8, application/vnd.apple.mpegurl, m3u8) \
XX(APPLICATION_DOCX, application/vnd.openxmlformats-officedocument.wordprocessingml.document, docx) \
XX(APPLICATION_XLSX, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, xlsx) \
XX(APPLICATION_PPTX, application/vnd.openxmlformats-officedocument.presentationml.presentation, pptx) \
#define MIME_TYPE_MULTIPART_MAP(XX) \
XX(MULTIPART_FORM_DATA, multipart/form-data, mp) \
#define MIME_TYPE_IMAGE_MAP(XX) \
XX(IMAGE_JPEG, image/jpeg, jpg) \ XX(IMAGE_JPEG, image/jpeg, jpg) \
XX(IMAGE_PNG, image/png, png) \ XX(IMAGE_PNG, image/png, png) \
XX(IMAGE_GIF, image/gif, gif) \ XX(IMAGE_GIF, image/gif, gif) \
XX(IMAGE_BMP, image/bmp, bmp) \ XX(IMAGE_ICO, image/x-icon, ico) \
XX(IMAGE_SVG, image/svg, svg) \ XX(IMAGE_BMP, image/x-ms-bmp, bmp) \
XX(VIDEO_AVI, video/x-msvideo, avi) \ XX(IMAGE_SVG, image/svg+xml, svg) \
XX(VIDEO_TS, video/mp2t, ts) \ XX(IMAGE_TIFF, image/tiff, tiff) \
XX(VIDEO_WEBM, video/webm, webm) \ XX(IMAGE_WEBP, image/webp, webp) \
XX(VIDEO_FLV, video/x-flv, flv) \
#define MIME_TYPE_VIDEO_MAP(XX) \
XX(VIDEO_MP4, video/mp4, mp4) \ XX(VIDEO_MP4, video/mp4, mp4) \
XX(VIDEO_FLV, video/x-flv, flv) \
XX(VIDEO_M4V, video/x-m4v, m4v) \
XX(VIDEO_MNG, video/x-mng, mng) \
XX(VIDEO_TS, video/mp2t, ts) \
XX(VIDEO_MPEG, video/mpeg, mpeg) \
XX(VIDEO_WEBM, video/webm, webm) \
XX(VIDEO_MOV, video/quicktime, mov) \
XX(VIDEO_3GPP, video/3gpp, 3gpp) \
XX(VIDEO_AVI, video/x-msvideo, avi) \
XX(VIDEO_WMV, video/x-ms-wmv, wmv) \
XX(VIDEO_ASF, video/x-ms-asf, asf) \
#define MIME_TYPE_AUDIO_MAP(XX) \
XX(AUDIO_MP3, audio/mpeg, mp3) \ XX(AUDIO_MP3, audio/mpeg, mp3) \
XX(AUDIO_OGG, audio/ogg, ogg) \ XX(AUDIO_OGG, audio/ogg, ogg) \
XX(APPLICATION_OCTET_STREAM,application/octet-stream, bin) \ XX(AUDIO_M4A, audio/x-m4a, m4a) \
XX(APPLICATION_JAVASCRIPT, application/javascript, js) \ XX(AUDIO_AAC, audio/aac, aac) \
XX(APPLICATION_XML, application/xml, xml) \ XX(AUDIO_PCMA, audio/PCMA, pcma) \
XX(APPLICATION_JSON, application/json, json) \ XX(AUDIO_OPUS, audio/opus, opus) \
XX(APPLICATION_GRPC, application/grpc, grpc) \
XX(APPLICATION_URLENCODED, application/x-www-form-urlencoded, kv) \ #define MIME_TYPE_FONT_MAP(XX) \
XX(MULTIPART_FORM_DATA, multipart/form-data, mp) \ XX(FONT_TTF, font/ttf, ttf) \
XX(FONT_OTF, font/otf, otf) \
XX(FONT_WOFF, font/woff, woff) \
XX(FONT_WOFF2, font/woff2, woff2) \
#define HTTP_CONTENT_TYPE_MAP(XX) \
MIME_TYPE_TEXT_MAP(XX) \
MIME_TYPE_APPLICATION_MAP(XX) \
MIME_TYPE_MULTIPART_MAP(XX) \
MIME_TYPE_IMAGE_MAP(XX) \
MIME_TYPE_VIDEO_MAP(XX) \
MIME_TYPE_AUDIO_MAP(XX) \
MIME_TYPE_FONT_MAP(XX) \
#define X_WWW_FORM_URLENCODED APPLICATION_URLENCODED // for compatibility #define X_WWW_FORM_URLENCODED APPLICATION_URLENCODED // for compatibility
enum http_content_type { enum http_content_type {
#define XX(name, string, suffix) name, #define XX(name, string, suffix) name,
CONTENT_TYPE_NONE, CONTENT_TYPE_NONE = 0,
HTTP_CONTENT_TYPE_MAP(XX)
CONTENT_TYPE_UNDEFINED CONTENT_TYPE_TEXT = 100,
MIME_TYPE_TEXT_MAP(XX)
CONTENT_TYPE_APPLICATION = 200,
MIME_TYPE_APPLICATION_MAP(XX)
CONTENT_TYPE_MULTIPART = 300,
MIME_TYPE_MULTIPART_MAP(XX)
CONTENT_TYPE_IMAGE = 400,
MIME_TYPE_IMAGE_MAP(XX)
CONTENT_TYPE_VIDEO = 500,
MIME_TYPE_VIDEO_MAP(XX)
CONTENT_TYPE_AUDIO = 600,
MIME_TYPE_AUDIO_MAP(XX)
CONTENT_TYPE_FONT = 700,
MIME_TYPE_FONT_MAP(XX)
CONTENT_TYPE_UNDEFINED = 1000
#undef XX #undef XX
}; };

View File

@ -9,26 +9,13 @@ class HV_EXPORT HUrl {
public: public:
static std::string escape(const std::string& str, const char* unescaped_chars = ""); static std::string escape(const std::string& str, const char* unescaped_chars = "");
static std::string unescape(const std::string& str); static std::string unescape(const std::string& str);
static inline std::string escapeUrl(const std::string& url) {
return escape(url, ":/@?=&#");
}
HUrl() : port(0) {} HUrl() : port(0) {}
~HUrl() {} ~HUrl() {}
void reset();
bool parse(const std::string& url); bool parse(const std::string& url);
const std::string& dump(); const std::string& dump();
void reset() {
url.clear();
scheme.clear();
username.clear();
password.clear();
host.clear();
port = 0;
path.clear();
query.clear();
fragment.clear();
}
std::string url; std::string url;
std::string scheme; std::string scheme;
@ -41,4 +28,14 @@ public:
std::string fragment; std::string fragment;
}; };
namespace hv {
HV_INLINE std::string escapeURL(const std::string& url) {
return HUrl::escape(url, ":/@?=&#+");
}
HV_EXPORT std::string escapeHTML(const std::string& str);
} // end namespace hv
#endif // HV_URL_H_ #endif // HV_URL_H_

View File

@ -7,8 +7,8 @@
BEGIN_EXTERN_C BEGIN_EXTERN_C
#define HV_VERSION_MAJOR 1 #define HV_VERSION_MAJOR 1
#define HV_VERSION_MINOR 2 #define HV_VERSION_MINOR 3
#define HV_VERSION_PATCH 5 #define HV_VERSION_PATCH 2
#define HV_VERSION_STRING STRINGIFY(HV_VERSION_MAJOR) "." \ #define HV_VERSION_STRING STRINGIFY(HV_VERSION_MAJOR) "." \
STRINGIFY(HV_VERSION_MINOR) "." \ STRINGIFY(HV_VERSION_MINOR) "." \

View File

@ -2,6 +2,7 @@
#define HV_INI_PARSER_H_ #define HV_INI_PARSER_H_
#include <string> #include <string>
#include <list>
#include "hexport.h" #include "hexport.h"
@ -25,6 +26,8 @@ public:
int Save(); int Save();
int SaveAs(const char* filepath); int SaveAs(const char* filepath);
std::list<std::string> GetSections();
std::list<std::string> GetKeys(const std::string& section = "");
std::string GetValue(const std::string& key, const std::string& section = ""); std::string GetValue(const std::string& key, const std::string& section = "");
void SetValue(const std::string& key, const std::string& value, const std::string& section = ""); void SetValue(const std::string& key, const std::string& value, const std::string& section = "");

View File

@ -31,7 +31,7 @@ int main() {
**/ **/
#include <memory> #include <memory>
#include "http_client.h" #include "HttpClient.h"
namespace requests { namespace requests {
@ -40,13 +40,13 @@ typedef HttpResponsePtr Response;
typedef HttpResponseCallback ResponseCallback; typedef HttpResponseCallback ResponseCallback;
HV_INLINE Response request(Request req) { HV_INLINE Response request(Request req) {
Response resp(new HttpResponse); auto resp = std::make_shared<HttpResponse>();
int ret = http_client_send(req.get(), resp.get()); int ret = http_client_send(req.get(), resp.get());
return ret ? NULL : resp; return ret ? NULL : resp;
} }
HV_INLINE Response request(http_method method, const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) { HV_INLINE Response request(http_method method, const char* url, const http_body& body = NoBody, const http_headers& headers = DefaultHeaders) {
Request req(new HttpRequest); auto req = std::make_shared<HttpRequest>();
req->method = method; req->method = method;
req->url = url; req->url = url;
if (&body != &NoBody) { if (&body != &NoBody) {
@ -58,30 +58,6 @@ HV_INLINE Response request(http_method method, const char* url, const http_body&
return request(req); return request(req);
} }
HV_INLINE Response uploadFile(http_method method, const char* url, const char* filepath, const http_headers& headers = DefaultHeaders) {
Request req(new HttpRequest);
req->method = method;
req->url = url;
if (req->File(filepath) != 200) return NULL;
if (&headers != &DefaultHeaders) {
req->headers = headers;
}
return request(req);
}
#ifndef WITHOUT_HTTP_CONTENT
HV_INLINE Response uploadFormFile(http_method method, const char* url, const char* name, const char* filepath, const http_headers& headers = DefaultHeaders) {
Request req(new HttpRequest);
req->method = method;
req->url = url;
req->FormFile(name, filepath);
if (&headers != &DefaultHeaders) {
req->headers = headers;
}
return request(req);
}
#endif
HV_INLINE Response head(const char* url, const http_headers& headers = DefaultHeaders) { HV_INLINE Response head(const char* url, const http_headers& headers = DefaultHeaders) {
return request(HTTP_HEAD, url, NoBody, headers); return request(HTTP_HEAD, url, NoBody, headers);
} }
@ -111,6 +87,147 @@ HV_INLINE int async(Request req, ResponseCallback resp_cb) {
return http_client_send_async(req, std::move(resp_cb)); return http_client_send_async(req, std::move(resp_cb));
} }
// Sample codes for uploading and downloading files
HV_INLINE Response uploadFile(const char* url, const char* filepath, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders) {
auto req = std::make_shared<HttpRequest>();
req->method = method;
req->url = url;
req->timeout = 600; // 10min
if (req->File(filepath) != 200) return NULL;
if (&headers != &DefaultHeaders) {
req->headers = headers;
}
return request(req);
}
#ifndef WITHOUT_HTTP_CONTENT
HV_INLINE Response uploadFormFile(const char* url, const char* name, const char* filepath, std::map<std::string, std::string>& params = hv::empty_map, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders) {
auto req = std::make_shared<HttpRequest>();
req->method = method;
req->url = url;
req->timeout = 600; // 10min
req->content_type = MULTIPART_FORM_DATA;
req->SetFormFile(name, filepath);
for (auto& param : params) {
req->SetFormData(param.first.c_str(), param.second);
}
if (&headers != &DefaultHeaders) {
req->headers = headers;
}
return request(req);
}
#endif
typedef std::function<void(size_t sended_bytes, size_t total_bytes)> upload_progress_cb;
HV_INLINE Response uploadLargeFile(const char* url, const char* filepath, upload_progress_cb progress_cb = NULL, http_method method = HTTP_POST, const http_headers& headers = DefaultHeaders) {
// open file
HFile file;
int ret = file.open(filepath, "rb");
if (ret != 0) {
return NULL;
}
hv::HttpClient cli;
auto req = std::make_shared<HttpRequest>();
req->method = method;
req->url = url;
req->timeout = 3600; // 1h
if (&headers != &DefaultHeaders) {
req->headers = headers;
}
// connect
req->ParseUrl();
int connfd = cli.connect(req->host.c_str(), req->port, req->IsHttps(), req->connect_timeout);
if (connfd < 0) {
return NULL;
}
// send header
size_t total_bytes = file.size(filepath);
req->SetHeader("Content-Length", hv::to_string(total_bytes));
ret = cli.sendHeader(req.get());
if (ret != 0) {
return NULL;
}
// send file
size_t sended_bytes = 0;
char filebuf[40960]; // 40K
int filebuflen = sizeof(filebuf);
int nread = 0, nsend = 0;
while (sended_bytes < total_bytes) {
nread = file.read(filebuf, filebuflen);
if (nread <= 0) {
return NULL;
}
nsend = cli.sendData(filebuf, nread);
if (nsend != nread) {
return NULL;
}
sended_bytes += nsend;
if (progress_cb) {
progress_cb(sended_bytes, total_bytes);
}
}
// recv response
auto resp = std::make_shared<HttpResponse>();
ret = cli.recvResponse(resp.get());
if (ret != 0) {
return NULL;
}
return resp;
}
// see examples/wget.cpp
typedef std::function<void(size_t received_bytes, size_t total_bytes)> download_progress_cb;
HV_INLINE size_t downloadFile(const char* url, const char* filepath, download_progress_cb progress_cb = NULL) {
// open file
std::string filepath_download(filepath);
filepath_download += ".download";
HFile file;
int ret = file.open(filepath_download.c_str(), "wb");
if (ret != 0) {
return 0;
}
// download
auto req = std::make_shared<HttpRequest>();
req->method = HTTP_GET;
req->url = url;
req->timeout = 3600; // 1h
size_t content_length = 0;
size_t received_bytes = 0;
req->http_cb = [&file, &content_length, &received_bytes, &progress_cb]
(HttpMessage* resp, http_parser_state state, const char* data, size_t size) {
if (!resp->headers["Location"].empty()) return;
if (state == HP_HEADERS_COMPLETE) {
content_length = hv::from_string<size_t>(resp->GetHeader("Content-Length"));
} else if (state == HP_BODY) {
if (data && size) {
// write file
file.write(data, size);
received_bytes += size;
if (progress_cb) {
progress_cb(received_bytes, content_length);
}
}
}
};
auto resp = request(req);
file.close();
if (resp == NULL || resp->status_code != 200) {
return 0;
}
// check filesize
if (content_length != 0 && hv_filesize(filepath_download.c_str()) != content_length) {
remove(filepath_download.c_str());
return 0;
}
rename(filepath_download.c_str(), filepath);
return hv_filesize(filepath);
}
} }
#endif // HV_REQUESTS_H_ #endif // HV_REQUESTS_H_

View File

@ -43,7 +43,7 @@ HV_EXPORT void HV_SHA1Final(
HV_EXPORT void HV_SHA1( HV_EXPORT void HV_SHA1(
char *hash_out, char *hash_out,
const char *str, const char *str,
int len); uint32_t len);
HV_EXPORT void hv_sha1(unsigned char* input, uint32_t inputlen, unsigned char digest[20]); HV_EXPORT void hv_sha1(unsigned char* input, uint32_t inputlen, unsigned char digest[20]);

View File

@ -14,28 +14,23 @@
private: \ private: \
DISABLE_COPY(Class) \ DISABLE_COPY(Class) \
static Class* s_pInstance; \ static Class* s_pInstance; \
static std::once_flag s_initFlag; \
static std::mutex s_mutex; static std::mutex s_mutex;
#define SINGLETON_IMPL(Class) \ #define SINGLETON_IMPL(Class) \
Class* Class::s_pInstance = NULL; \ Class* Class::s_pInstance = NULL; \
std::once_flag Class::s_initFlag; \
std::mutex Class::s_mutex; \ std::mutex Class::s_mutex; \
Class* Class::instance() { \ Class* Class::instance() { \
if (s_pInstance == NULL) { \ std::call_once(s_initFlag, []() {s_pInstance = new Class;}); \
s_mutex.lock(); \ return s_pInstance; \
if (s_pInstance == NULL) { \
s_pInstance = new Class; \
} \
s_mutex.unlock(); \
} \
return s_pInstance; \
} \ } \
void Class::exitInstance() { \ void Class::exitInstance() { \
s_mutex.lock(); \ std::lock_guard<std::mutex> lock(s_mutex); \
if (s_pInstance) { \ if (s_pInstance) { \
delete s_pInstance; \ delete s_pInstance; \
s_pInstance = NULL; \ s_pInstance = nullptr; \
} \ } \
s_mutex.unlock(); \
} }
#endif // HV_SINGLETON_H_ #endif // HV_SINGLETON_H_

View File

@ -6,9 +6,11 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> // import rand #include <stdlib.h> // import rand
#define SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version" #define SEC_WEBSOCKET_VERSION "Sec-WebSocket-Version"
#define SEC_WEBSOCKET_KEY "Sec-WebSocket-Key" #define SEC_WEBSOCKET_KEY "Sec-WebSocket-Key"
#define SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept" #define SEC_WEBSOCKET_ACCEPT "Sec-WebSocket-Accept"
#define SEC_WEBSOCKET_PROTOCOL "Sec-WebSocket-Protocol"
#define SEC_WEBSOCKET_EXTENSIONS "Sec-WebSocket-Extensions"
#define WS_SERVER_MIN_FRAME_SIZE 2 #define WS_SERVER_MIN_FRAME_SIZE 2
// 1000 1001 0000 0000 // 1000 1001 0000 0000
@ -61,8 +63,12 @@ HV_INLINE int ws_client_build_frame(
/* bool has_mask = true */ /* bool has_mask = true */
enum ws_opcode opcode DEFAULT(WS_OPCODE_TEXT), enum ws_opcode opcode DEFAULT(WS_OPCODE_TEXT),
bool fin DEFAULT(true)) { bool fin DEFAULT(true)) {
char mask[4]; char mask[4] = {0};
*(int*)mask = rand(); int i = 0;
int imask = rand();
for (i = 0; i < 4; i++) {
mask[i] = (imask >> (8 * i)) & 0xff;
}
return ws_build_frame(out, data, data_len, mask, true, opcode, fin); return ws_build_frame(out, data, data_len, mask, true, opcode, fin);
} }

241
sdk/include/iconv.h 100644
View File

@ -0,0 +1,241 @@
/* Copyright (C) 1999-2022 Free Software Foundation, Inc.
This file is part of the GNU LIBICONV Library.
The GNU LIBICONV Library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either version 2.1
of the License, or (at your option) any later version.
The GNU LIBICONV Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU LIBICONV Library; see the file COPYING.LIB.
If not, see <https://www.gnu.org/licenses/>. */
/* When installed, this file is called "iconv.h". */
#ifndef _LIBICONV_H
#define _LIBICONV_H
#define _LIBICONV_VERSION 0x0111 /* version number: (major<<8) + minor */
extern int _libiconv_version; /* Likewise */
/* We would like to #include any system header file which could define
iconv_t, 1. in order to eliminate the risk that the user gets compilation
errors because some other system header file includes /usr/include/iconv.h
which defines iconv_t or declares iconv after this file, 2. when compiling
for LIBICONV_PLUG, we need the proper iconv_t type in order to produce
binary compatible code.
But gcc's #include_next is not portable. Thus, once libiconv's iconv.h
has been installed in /usr/local/include, there is no way any more to
include the original /usr/include/iconv.h. We simply have to get away
without it.
Ad 1. The risk that a system header file does
#include "iconv.h" or #include_next "iconv.h"
is small. They all do #include <iconv.h>.
Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It
has to be a scalar type because (iconv_t)(-1) is a possible return value
from iconv_open().) */
/* Define iconv_t ourselves. */
#undef iconv_t
#define iconv_t libiconv_t
typedef void* iconv_t;
/* Get size_t declaration.
Get wchar_t declaration if it exists. */
#include <stddef.h>
/* Get errno declaration and values. */
#include <errno.h>
/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS,
have EILSEQ in a different header. On these systems, define EILSEQ
ourselves. */
#ifndef EILSEQ
#define EILSEQ
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Allocates descriptor for code conversion from encoding fromcode to
encoding tocode. */
#ifndef LIBICONV_PLUG
#define iconv_open libiconv_open
#endif
extern iconv_t iconv_open (const char* tocode, const char* fromcode);
/* Converts, using conversion descriptor cd, at most *inbytesleft bytes
starting at *inbuf, writing at most *outbytesleft bytes starting at
*outbuf.
Decrements *inbytesleft and increments *inbuf by the same amount.
Decrements *outbytesleft and increments *outbuf by the same amount. */
#ifndef LIBICONV_PLUG
#define iconv libiconv
#endif
extern size_t iconv (iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);
/* Frees resources allocated for conversion descriptor cd. */
#ifndef LIBICONV_PLUG
#define iconv_close libiconv_close
#endif
extern int iconv_close (iconv_t cd);
#ifdef __cplusplus
}
#endif
#ifndef LIBICONV_PLUG
/* Nonstandard extensions. */
#if 1
#if 0
/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
<wchar.h>.
BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
included before <wchar.h>. */
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#endif
#include <wchar.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* A type that holds all memory needed by a conversion descriptor.
A pointer to such an object can be used as an iconv_t. */
typedef struct {
void* dummy1[28];
#if 1
mbstate_t dummy2;
#endif
} iconv_allocation_t;
/* Allocates descriptor for code conversion from encoding fromcode to
encoding tocode into preallocated memory. Returns an error indicator
(0 or -1 with errno set). */
#define iconv_open_into libiconv_open_into
extern int iconv_open_into (const char* tocode, const char* fromcode,
iconv_allocation_t* resultp);
/* Control of attributes. */
#define iconvctl libiconvctl
extern int iconvctl (iconv_t cd, int request, void* argument);
/* Hook performed after every successful conversion of a Unicode character. */
typedef void (*iconv_unicode_char_hook) (unsigned int uc, void* data);
/* Hook performed after every successful conversion of a wide character. */
typedef void (*iconv_wide_char_hook) (wchar_t wc, void* data);
/* Set of hooks. */
struct iconv_hooks {
iconv_unicode_char_hook uc_hook;
iconv_wide_char_hook wc_hook;
void* data;
};
/* Fallback function. Invoked when a small number of bytes could not be
converted to a Unicode character. This function should process all
bytes from inbuf and may produce replacement Unicode characters by calling
the write_replacement callback repeatedly. */
typedef void (*iconv_unicode_mb_to_uc_fallback)
(const char* inbuf, size_t inbufsize,
void (*write_replacement) (const unsigned int *buf, size_t buflen,
void* callback_arg),
void* callback_arg,
void* data);
/* Fallback function. Invoked when a Unicode character could not be converted
to the target encoding. This function should process the character and
may produce replacement bytes (in the target encoding) by calling the
write_replacement callback repeatedly. */
typedef void (*iconv_unicode_uc_to_mb_fallback)
(unsigned int code,
void (*write_replacement) (const char *buf, size_t buflen,
void* callback_arg),
void* callback_arg,
void* data);
#if 1
/* Fallback function. Invoked when a number of bytes could not be converted to
a wide character. This function should process all bytes from inbuf and may
produce replacement wide characters by calling the write_replacement
callback repeatedly. */
typedef void (*iconv_wchar_mb_to_wc_fallback)
(const char* inbuf, size_t inbufsize,
void (*write_replacement) (const wchar_t *buf, size_t buflen,
void* callback_arg),
void* callback_arg,
void* data);
/* Fallback function. Invoked when a wide character could not be converted to
the target encoding. This function should process the character and may
produce replacement bytes (in the target encoding) by calling the
write_replacement callback repeatedly. */
typedef void (*iconv_wchar_wc_to_mb_fallback)
(wchar_t code,
void (*write_replacement) (const char *buf, size_t buflen,
void* callback_arg),
void* callback_arg,
void* data);
#else
/* If the wchar_t type does not exist, these two fallback functions are never
invoked. Their argument list therefore does not matter. */
typedef void (*iconv_wchar_mb_to_wc_fallback) ();
typedef void (*iconv_wchar_wc_to_mb_fallback) ();
#endif
/* Set of fallbacks. */
struct iconv_fallbacks {
iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback;
iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback;
iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback;
iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback;
void* data;
};
/* Requests for iconvctl. */
#define ICONV_TRIVIALP 0 /* int *argument */
#define ICONV_GET_TRANSLITERATE 1 /* int *argument */
#define ICONV_SET_TRANSLITERATE 2 /* const int *argument */
#define ICONV_GET_DISCARD_ILSEQ 3 /* int *argument */
#define ICONV_SET_DISCARD_ILSEQ 4 /* const int *argument */
#define ICONV_SET_HOOKS 5 /* const struct iconv_hooks *argument */
#define ICONV_SET_FALLBACKS 6 /* const struct iconv_fallbacks *argument */
/* Listing of locale independent encodings. */
#define iconvlist libiconvlist
extern void iconvlist (int (*do_one) (unsigned int namescount,
const char * const * names,
void* data),
void* data);
/* Canonicalize an encoding name.
The result is either a canonical encoding name, or name itself. */
extern const char * iconv_canonicalize (const char * name);
/* Support for relocatable packages. */
/* Sets the original and the current installation prefix of the package.
Relocation simply replaces a pathname starting with the original prefix
by the corresponding pathname with the current prefix instead. Both
prefixes should be directory names without trailing slash (i.e. use ""
instead of "/"). */
extern void libiconv_set_relocation_prefix (const char *orig_prefix,
const char *curr_prefix);
#ifdef __cplusplus
}
#endif
#endif
#endif /* _LIBICONV_H */

View File

@ -0,0 +1,45 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU CHARSET Library.
The GNU CHARSET Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU CHARSET Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU CHARSET Library; see the file COPYING.LIB. If not,
see <https://www.gnu.org/licenses/>. */
#ifndef _LIBCHARSET_H
#define _LIBCHARSET_H
#include <localcharset.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Support for relocatable packages. */
/* Sets the original and the current installation prefix of the package.
Relocation simply replaces a pathname starting with the original prefix
by the corresponding pathname with the current prefix instead. Both
prefixes should be directory names without trailing slash (i.e. use ""
instead of "/"). */
extern void libcharset_set_relocation_prefix (const char *orig_prefix,
const char *curr_prefix);
#ifdef __cplusplus
}
#endif
#endif /* _LIBCHARSET_H */

View File

@ -0,0 +1,137 @@
/* Determine a canonical name for the current locale's character encoding.
Copyright (C) 2000-2003, 2009-2019 Free Software Foundation, Inc.
This file is part of the GNU CHARSET Library.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifndef _LOCALCHARSET_H
#define _LOCALCHARSET_H
#ifdef __cplusplus
extern "C" {
#endif
/* Determine the current locale's character encoding, and canonicalize it
into one of the canonical names listed below.
The result must not be freed; it is statically allocated. The result
becomes invalid when setlocale() is used to change the global locale, or
when the value of one of the environment variables LC_ALL, LC_CTYPE, LANG
is changed; threads in multithreaded programs should not do this.
If the canonical name cannot be determined, the result is a non-canonical
name. */
extern const char * locale_charset (void);
/* About GNU canonical names for character encodings:
Every canonical name must be supported by GNU libiconv. Support by GNU libc
is also desirable.
The name is case insensitive. Usually an upper case MIME charset name is
preferred.
The current list of these GNU canonical names is:
name MIME? used by which systems
(darwin = Mac OS X, windows = native Windows)
ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin minix cygwin
ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos
ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos
ISO-8859-3 Y glibc solaris cygwin
ISO-8859-4 Y hpux osf solaris freebsd netbsd openbsd darwin
ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos
ISO-8859-6 Y glibc aix hpux solaris cygwin
ISO-8859-7 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin zos
ISO-8859-8 Y glibc aix hpux osf solaris cygwin zos
ISO-8859-9 Y glibc aix hpux irix osf solaris freebsd darwin cygwin zos
ISO-8859-13 glibc hpux solaris freebsd netbsd openbsd darwin cygwin
ISO-8859-14 glibc cygwin
ISO-8859-15 glibc aix irix osf solaris freebsd netbsd openbsd darwin cygwin
KOI8-R Y glibc hpux solaris freebsd netbsd openbsd darwin
KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin
KOI8-T glibc
CP437 dos
CP775 dos
CP850 aix osf dos
CP852 dos
CP855 dos
CP856 aix
CP857 dos
CP861 dos
CP862 dos
CP864 dos
CP865 dos
CP866 freebsd netbsd openbsd darwin dos
CP869 dos
CP874 windows dos
CP922 aix
CP932 aix cygwin windows dos
CP943 aix zos
CP949 osf darwin windows dos
CP950 windows dos
CP1046 aix
CP1124 aix
CP1125 dos
CP1129 aix
CP1131 freebsd darwin
CP1250 windows
CP1251 glibc hpux solaris freebsd netbsd openbsd darwin cygwin windows
CP1252 aix windows
CP1253 windows
CP1254 windows
CP1255 glibc windows
CP1256 windows
CP1257 windows
GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin cygwin zos
EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin
EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin zos
EUC-TW glibc aix hpux irix osf solaris netbsd
BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin zos
BIG5-HKSCS glibc hpux solaris netbsd darwin
GBK glibc aix osf solaris freebsd darwin cygwin windows dos
GB18030 glibc hpux solaris freebsd netbsd darwin
SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin
JOHAB glibc solaris windows
TIS-620 glibc aix hpux osf solaris cygwin zos
VISCII Y glibc
TCVN5712-1 glibc
ARMSCII-8 glibc freebsd netbsd darwin
GEORGIAN-PS glibc cygwin
PT154 glibc netbsd cygwin
HP-ROMAN8 hpux
HP-ARABIC8 hpux
HP-GREEK8 hpux
HP-HEBREW8 hpux
HP-TURKISH8 hpux
HP-KANA8 hpux
DEC-KANJI osf
DEC-HANYU osf
UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin zos
Note: Names which are not marked as being a MIME name should not be used in
Internet protocols for information interchange (mail, news, etc.).
Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications
must understand both names and treat them as equivalent.
*/
#ifdef __cplusplus
}
#endif
#endif /* _LOCALCHARSET_H */

View File

@ -12,7 +12,6 @@ public:
void CloseDatabase(); void CloseDatabase();
bool OpenDatabase(const std::string& db_file_path); bool OpenDatabase(const std::string& db_file_path);
void InsertMessage(const std::string& ts, const std::string& msg_type, const std::string& fsu, const std::string& content,int topic,int dev_id); void InsertMessage(const std::string& ts, const std::string& msg_type, const std::string& fsu, const std::string& content,int topic,int dev_id);
bool QueryUser(const std::string& uname, const std::string& passwd); bool QueryUser(const std::string& uname, const std::string& passwd);
protected: protected:
sqlite3* m_pSqliteDb; sqlite3* m_pSqliteDb;

View File

@ -0,0 +1,57 @@
#ifndef sodium_H
#define sodium_H
#include "sodium/core.h"
#include "sodium/crypto_aead_aes256gcm.h"
#include "sodium/crypto_aead_chacha20poly1305.h"
#include "sodium/crypto_auth.h"
#include "sodium/crypto_auth_hmacsha256.h"
#include "sodium/crypto_auth_hmacsha512.h"
#include "sodium/crypto_auth_hmacsha512256.h"
#include "sodium/crypto_box.h"
#include "sodium/crypto_box_curve25519xsalsa20poly1305.h"
#include "sodium/crypto_core_hsalsa20.h"
#include "sodium/crypto_core_hchacha20.h"
#include "sodium/crypto_core_salsa20.h"
#include "sodium/crypto_core_salsa2012.h"
#include "sodium/crypto_core_salsa208.h"
#include "sodium/crypto_generichash.h"
#include "sodium/crypto_generichash_blake2b.h"
#include "sodium/crypto_hash.h"
#include "sodium/crypto_hash_sha256.h"
#include "sodium/crypto_hash_sha512.h"
#include "sodium/crypto_onetimeauth.h"
#include "sodium/crypto_onetimeauth_poly1305.h"
#include "sodium/crypto_pwhash.h"
#include "sodium/crypto_pwhash_argon2i.h"
#include "sodium/crypto_pwhash_scryptsalsa208sha256.h"
#include "sodium/crypto_scalarmult.h"
#include "sodium/crypto_scalarmult_curve25519.h"
#include "sodium/crypto_secretbox.h"
#include "sodium/crypto_secretbox_xsalsa20poly1305.h"
#include "sodium/crypto_shorthash.h"
#include "sodium/crypto_shorthash_siphash24.h"
#include "sodium/crypto_sign.h"
#include "sodium/crypto_sign_ed25519.h"
#include "sodium/crypto_stream.h"
#include "sodium/crypto_stream_aes128ctr.h"
#include "sodium/crypto_stream_chacha20.h"
#include "sodium/crypto_stream_salsa20.h"
#include "sodium/crypto_stream_salsa2012.h"
#include "sodium/crypto_stream_salsa208.h"
#include "sodium/crypto_stream_xsalsa20.h"
#include "sodium/crypto_verify_16.h"
#include "sodium/crypto_verify_32.h"
#include "sodium/crypto_verify_64.h"
#include "sodium/randombytes.h"
#ifdef __native_client__
# include "sodium/randombytes_nativeclient.h"
#endif
#include "sodium/randombytes_salsa20_random.h"
#include "sodium/randombytes_sysrandom.h"
#include "sodium/runtime.h"
#include "sodium/utils.h"
#include "sodium/version.h"
#endif

View File

@ -0,0 +1,19 @@
#ifndef sodium_core_H
#define sodium_core_H
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
SODIUM_EXPORT
int sodium_init(void)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,141 @@
#ifndef crypto_aead_aes256gcm_H
#define crypto_aead_aes256gcm_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
SODIUM_EXPORT
int crypto_aead_aes256gcm_is_available(void);
#define crypto_aead_aes256gcm_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_aead_aes256gcm_keybytes(void);
#define crypto_aead_aes256gcm_NSECBYTES 0U
SODIUM_EXPORT
size_t crypto_aead_aes256gcm_nsecbytes(void);
#define crypto_aead_aes256gcm_NPUBBYTES 12U
SODIUM_EXPORT
size_t crypto_aead_aes256gcm_npubbytes(void);
#define crypto_aead_aes256gcm_ABYTES 16U
SODIUM_EXPORT
size_t crypto_aead_aes256gcm_abytes(void);
typedef CRYPTO_ALIGN(16) unsigned char crypto_aead_aes256gcm_state[512];
SODIUM_EXPORT
size_t crypto_aead_aes256gcm_statebytes(void);
SODIUM_EXPORT
int crypto_aead_aes256gcm_encrypt(unsigned char *c,
unsigned long long *clen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_aes256gcm_decrypt(unsigned char *m,
unsigned long long *mlen_p,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_aead_aes256gcm_encrypt_detached(unsigned char *c,
unsigned char *mac,
unsigned long long *maclen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_aes256gcm_decrypt_detached(unsigned char *m,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *mac,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* -- Precomputation interface -- */
SODIUM_EXPORT
int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c,
unsigned long long *clen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const crypto_aead_aes256gcm_state *ctx_);
SODIUM_EXPORT
int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m,
unsigned long long *mlen_p,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const crypto_aead_aes256gcm_state *ctx_)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c,
unsigned char *mac,
unsigned long long *maclen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const crypto_aead_aes256gcm_state *ctx_);
SODIUM_EXPORT
int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *mac,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const crypto_aead_aes256gcm_state *ctx_)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,156 @@
#ifndef crypto_aead_chacha20poly1305_H
#define crypto_aead_chacha20poly1305_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
/* -- IETF ChaCha20-Poly1305 construction with a 96-bit nonce and a 32-bit internal counter -- */
#define crypto_aead_chacha20poly1305_ietf_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_ietf_keybytes(void);
#define crypto_aead_chacha20poly1305_ietf_NSECBYTES 0U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_ietf_nsecbytes(void);
#define crypto_aead_chacha20poly1305_ietf_NPUBBYTES 12U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_ietf_npubbytes(void);
#define crypto_aead_chacha20poly1305_ietf_ABYTES 16U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_ietf_abytes(void);
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c,
unsigned long long *clen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m,
unsigned long long *mlen_p,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c,
unsigned char *mac,
unsigned long long *maclen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *mac,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* -- Original ChaCha20-Poly1305 construction with a 64-bit nonce and a 64-bit internal counter -- */
#define crypto_aead_chacha20poly1305_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_keybytes(void);
#define crypto_aead_chacha20poly1305_NSECBYTES 0U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_nsecbytes(void);
#define crypto_aead_chacha20poly1305_NPUBBYTES 8U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_npubbytes(void);
#define crypto_aead_chacha20poly1305_ABYTES 16U
SODIUM_EXPORT
size_t crypto_aead_chacha20poly1305_abytes(void);
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_encrypt(unsigned char *c,
unsigned long long *clen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_decrypt(unsigned char *m,
unsigned long long *mlen_p,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c,
unsigned char *mac,
unsigned long long *maclen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *nsec,
const unsigned char *npub,
const unsigned char *k);
SODIUM_EXPORT
int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m,
unsigned char *nsec,
const unsigned char *c,
unsigned long long clen,
const unsigned char *mac,
const unsigned char *ad,
unsigned long long adlen,
const unsigned char *npub,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* Aliases */
#define crypto_aead_chacha20poly1305_IETF_KEYBYTES crypto_aead_chacha20poly1305_ietf_KEYBYTES
#define crypto_aead_chacha20poly1305_IETF_NSECBYTES crypto_aead_chacha20poly1305_ietf_NSECBYTES
#define crypto_aead_chacha20poly1305_IETF_NPUBBYTES crypto_aead_chacha20poly1305_ietf_NPUBBYTES
#define crypto_aead_chacha20poly1305_IETF_ABYTES crypto_aead_chacha20poly1305_ietf_ABYTES
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,41 @@
#ifndef crypto_auth_H
#define crypto_auth_H
#include <stddef.h>
#include "crypto_auth_hmacsha512256.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
SODIUM_EXPORT
size_t crypto_auth_bytes(void);
#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
SODIUM_EXPORT
size_t crypto_auth_keybytes(void);
#define crypto_auth_PRIMITIVE "hmacsha512256"
SODIUM_EXPORT
const char *crypto_auth_primitive(void);
SODIUM_EXPORT
int crypto_auth(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *k);
SODIUM_EXPORT
int crypto_auth_verify(const unsigned char *h, const unsigned char *in,
unsigned long long inlen, const unsigned char *k)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,63 @@
#ifndef crypto_auth_hmacsha256_H
#define crypto_auth_hmacsha256_H
#include <stddef.h>
#include "crypto_hash_sha256.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_auth_hmacsha256_BYTES 32U
SODIUM_EXPORT
size_t crypto_auth_hmacsha256_bytes(void);
#define crypto_auth_hmacsha256_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_auth_hmacsha256_keybytes(void);
SODIUM_EXPORT
int crypto_auth_hmacsha256(unsigned char *out,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k);
SODIUM_EXPORT
int crypto_auth_hmacsha256_verify(const unsigned char *h,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* ------------------------------------------------------------------------- */
typedef struct crypto_auth_hmacsha256_state {
crypto_hash_sha256_state ictx;
crypto_hash_sha256_state octx;
} crypto_auth_hmacsha256_state;
SODIUM_EXPORT
size_t crypto_auth_hmacsha256_statebytes(void);
SODIUM_EXPORT
int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state,
const unsigned char *key,
size_t keylen);
SODIUM_EXPORT
int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state,
unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,63 @@
#ifndef crypto_auth_hmacsha512_H
#define crypto_auth_hmacsha512_H
#include <stddef.h>
#include "crypto_hash_sha512.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_auth_hmacsha512_BYTES 64U
SODIUM_EXPORT
size_t crypto_auth_hmacsha512_bytes(void);
#define crypto_auth_hmacsha512_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_auth_hmacsha512_keybytes(void);
SODIUM_EXPORT
int crypto_auth_hmacsha512(unsigned char *out,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k);
SODIUM_EXPORT
int crypto_auth_hmacsha512_verify(const unsigned char *h,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* ------------------------------------------------------------------------- */
typedef struct crypto_auth_hmacsha512_state {
crypto_hash_sha512_state ictx;
crypto_hash_sha512_state octx;
} crypto_auth_hmacsha512_state;
SODIUM_EXPORT
size_t crypto_auth_hmacsha512_statebytes(void);
SODIUM_EXPORT
int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state,
const unsigned char *key,
size_t keylen);
SODIUM_EXPORT
int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state,
unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,58 @@
#ifndef crypto_auth_hmacsha512256_H
#define crypto_auth_hmacsha512256_H
#include <stddef.h>
#include "crypto_auth_hmacsha512.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_auth_hmacsha512256_BYTES 32U
SODIUM_EXPORT
size_t crypto_auth_hmacsha512256_bytes(void);
#define crypto_auth_hmacsha512256_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_auth_hmacsha512256_keybytes(void);
SODIUM_EXPORT
int crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in,
unsigned long long inlen,const unsigned char *k);
SODIUM_EXPORT
int crypto_auth_hmacsha512256_verify(const unsigned char *h,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* ------------------------------------------------------------------------- */
typedef crypto_auth_hmacsha512_state crypto_auth_hmacsha512256_state;
SODIUM_EXPORT
size_t crypto_auth_hmacsha512256_statebytes(void);
SODIUM_EXPORT
int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state,
const unsigned char *key,
size_t keylen);
SODIUM_EXPORT
int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state,
unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,169 @@
#ifndef crypto_box_H
#define crypto_box_H
/*
* THREAD SAFETY: crypto_box_keypair() is thread-safe,
* provided that you called sodium_init() once before using any
* other libsodium function.
* Other functions are always thread-safe.
*/
#include <stddef.h>
#include "crypto_box_curve25519xsalsa20poly1305.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_box_SEEDBYTES crypto_box_curve25519xsalsa20poly1305_SEEDBYTES
SODIUM_EXPORT
size_t crypto_box_seedbytes(void);
#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
SODIUM_EXPORT
size_t crypto_box_publickeybytes(void);
#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
SODIUM_EXPORT
size_t crypto_box_secretkeybytes(void);
#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
SODIUM_EXPORT
size_t crypto_box_noncebytes(void);
#define crypto_box_MACBYTES crypto_box_curve25519xsalsa20poly1305_MACBYTES
SODIUM_EXPORT
size_t crypto_box_macbytes(void);
#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
SODIUM_EXPORT
const char *crypto_box_primitive(void);
SODIUM_EXPORT
int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk,
const unsigned char *seed);
SODIUM_EXPORT
int crypto_box_keypair(unsigned char *pk, unsigned char *sk);
SODIUM_EXPORT
int crypto_box_easy(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *pk, const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_open_easy(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *pk, const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_detached(unsigned char *c, unsigned char *mac,
const unsigned char *m, unsigned long long mlen,
const unsigned char *n, const unsigned char *pk,
const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_open_detached(unsigned char *m, const unsigned char *c,
const unsigned char *mac,
unsigned long long clen,
const unsigned char *n,
const unsigned char *pk,
const unsigned char *sk)
__attribute__ ((warn_unused_result));
/* -- Precomputation interface -- */
#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
SODIUM_EXPORT
size_t crypto_box_beforenmbytes(void);
SODIUM_EXPORT
int crypto_box_beforenm(unsigned char *k, const unsigned char *pk,
const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac,
const unsigned char *m, unsigned long long mlen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c,
const unsigned char *mac,
unsigned long long clen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* -- Ephemeral SK interface -- */
#define crypto_box_SEALBYTES (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES)
SODIUM_EXPORT
size_t crypto_box_sealbytes(void);
SODIUM_EXPORT
int crypto_box_seal(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *pk);
SODIUM_EXPORT
int crypto_box_seal_open(unsigned char *m, const unsigned char *c,
unsigned long long clen,
const unsigned char *pk, const unsigned char *sk)
__attribute__ ((warn_unused_result));
/* -- NaCl compatibility interface ; Requires padding -- */
#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
SODIUM_EXPORT
size_t crypto_box_zerobytes(void);
#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
SODIUM_EXPORT
size_t crypto_box_boxzerobytes(void);
SODIUM_EXPORT
int crypto_box(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *pk, const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_open(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *pk, const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_afternm(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_box_open_afternm(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,100 @@
#ifndef crypto_box_curve25519xsalsa20poly1305_H
#define crypto_box_curve25519xsalsa20poly1305_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_box_curve25519xsalsa20poly1305_SEEDBYTES 32U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_seedbytes(void);
#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES 32U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_publickeybytes(void);
#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES 32U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void);
#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES 32U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void);
#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES 24U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_noncebytes(void);
#define crypto_box_curve25519xsalsa20poly1305_MACBYTES 16U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_macbytes(void);
#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES 16U
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void);
#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES \
(crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + \
crypto_box_curve25519xsalsa20poly1305_MACBYTES)
SODIUM_EXPORT
size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void);
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305(unsigned char *c,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *n,
const unsigned char *pk,
const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m,
const unsigned char *c,
unsigned long long clen,
const unsigned char *n,
const unsigned char *pk,
const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk,
unsigned char *sk,
const unsigned char *seed);
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk,
unsigned char *sk);
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k,
const unsigned char *pk,
const unsigned char *sk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m,
const unsigned char *c,
unsigned long long clen,
const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef crypto_core_hchacha20_H
#define crypto_core_hchacha20_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_core_hchacha20_OUTPUTBYTES 32U
SODIUM_EXPORT
size_t crypto_core_hchacha20_outputbytes(void);
#define crypto_core_hchacha20_INPUTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_hchacha20_inputbytes(void);
#define crypto_core_hchacha20_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_core_hchacha20_keybytes(void);
#define crypto_core_hchacha20_CONSTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_hchacha20_constbytes(void);
SODIUM_EXPORT
int crypto_core_hchacha20(unsigned char *out, const unsigned char *in,
const unsigned char *k, const unsigned char *c);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef crypto_core_hsalsa20_H
#define crypto_core_hsalsa20_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_core_hsalsa20_OUTPUTBYTES 32U
SODIUM_EXPORT
size_t crypto_core_hsalsa20_outputbytes(void);
#define crypto_core_hsalsa20_INPUTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_hsalsa20_inputbytes(void);
#define crypto_core_hsalsa20_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_core_hsalsa20_keybytes(void);
#define crypto_core_hsalsa20_CONSTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_hsalsa20_constbytes(void);
SODIUM_EXPORT
int crypto_core_hsalsa20(unsigned char *out, const unsigned char *in,
const unsigned char *k, const unsigned char *c);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef crypto_core_salsa20_H
#define crypto_core_salsa20_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_core_salsa20_OUTPUTBYTES 64U
SODIUM_EXPORT
size_t crypto_core_salsa20_outputbytes(void);
#define crypto_core_salsa20_INPUTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_salsa20_inputbytes(void);
#define crypto_core_salsa20_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_core_salsa20_keybytes(void);
#define crypto_core_salsa20_CONSTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_salsa20_constbytes(void);
SODIUM_EXPORT
int crypto_core_salsa20(unsigned char *out, const unsigned char *in,
const unsigned char *k, const unsigned char *c);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef crypto_core_salsa2012_H
#define crypto_core_salsa2012_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_core_salsa2012_OUTPUTBYTES 64U
SODIUM_EXPORT
size_t crypto_core_salsa2012_outputbytes(void);
#define crypto_core_salsa2012_INPUTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_salsa2012_inputbytes(void);
#define crypto_core_salsa2012_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_core_salsa2012_keybytes(void);
#define crypto_core_salsa2012_CONSTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_salsa2012_constbytes(void);
SODIUM_EXPORT
int crypto_core_salsa2012(unsigned char *out, const unsigned char *in,
const unsigned char *k, const unsigned char *c);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef crypto_core_salsa208_H
#define crypto_core_salsa208_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_core_salsa208_OUTPUTBYTES 64U
SODIUM_EXPORT
size_t crypto_core_salsa208_outputbytes(void);
#define crypto_core_salsa208_INPUTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_salsa208_inputbytes(void);
#define crypto_core_salsa208_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_core_salsa208_keybytes(void);
#define crypto_core_salsa208_CONSTBYTES 16U
SODIUM_EXPORT
size_t crypto_core_salsa208_constbytes(void);
SODIUM_EXPORT
int crypto_core_salsa208(unsigned char *out, const unsigned char *in,
const unsigned char *k, const unsigned char *c);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,71 @@
#ifndef crypto_generichash_H
#define crypto_generichash_H
#include <stddef.h>
#include "crypto_generichash_blake2b.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_generichash_BYTES_MIN crypto_generichash_blake2b_BYTES_MIN
SODIUM_EXPORT
size_t crypto_generichash_bytes_min(void);
#define crypto_generichash_BYTES_MAX crypto_generichash_blake2b_BYTES_MAX
SODIUM_EXPORT
size_t crypto_generichash_bytes_max(void);
#define crypto_generichash_BYTES crypto_generichash_blake2b_BYTES
SODIUM_EXPORT
size_t crypto_generichash_bytes(void);
#define crypto_generichash_KEYBYTES_MIN crypto_generichash_blake2b_KEYBYTES_MIN
SODIUM_EXPORT
size_t crypto_generichash_keybytes_min(void);
#define crypto_generichash_KEYBYTES_MAX crypto_generichash_blake2b_KEYBYTES_MAX
SODIUM_EXPORT
size_t crypto_generichash_keybytes_max(void);
#define crypto_generichash_KEYBYTES crypto_generichash_blake2b_KEYBYTES
SODIUM_EXPORT
size_t crypto_generichash_keybytes(void);
#define crypto_generichash_PRIMITIVE "blake2b"
SODIUM_EXPORT
const char *crypto_generichash_primitive(void);
typedef crypto_generichash_blake2b_state crypto_generichash_state;
SODIUM_EXPORT
size_t crypto_generichash_statebytes(void);
SODIUM_EXPORT
int crypto_generichash(unsigned char *out, size_t outlen,
const unsigned char *in, unsigned long long inlen,
const unsigned char *key, size_t keylen);
SODIUM_EXPORT
int crypto_generichash_init(crypto_generichash_state *state,
const unsigned char *key,
const size_t keylen, const size_t outlen);
SODIUM_EXPORT
int crypto_generichash_update(crypto_generichash_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_generichash_final(crypto_generichash_state *state,
unsigned char *out, const size_t outlen);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,118 @@
#ifndef crypto_generichash_blake2b_H
#define crypto_generichash_blake2b_H
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# pragma pack(1)
#else
# pragma pack(push, 1)
#endif
typedef CRYPTO_ALIGN(64) struct crypto_generichash_blake2b_state {
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[2 * 128];
size_t buflen;
uint8_t last_node;
} crypto_generichash_blake2b_state;
#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# pragma pack()
#else
# pragma pack(pop)
#endif
#define crypto_generichash_blake2b_BYTES_MIN 16U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_bytes_min(void);
#define crypto_generichash_blake2b_BYTES_MAX 64U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_bytes_max(void);
#define crypto_generichash_blake2b_BYTES 32U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_bytes(void);
#define crypto_generichash_blake2b_KEYBYTES_MIN 16U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_keybytes_min(void);
#define crypto_generichash_blake2b_KEYBYTES_MAX 64U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_keybytes_max(void);
#define crypto_generichash_blake2b_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_keybytes(void);
#define crypto_generichash_blake2b_SALTBYTES 16U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_saltbytes(void);
#define crypto_generichash_blake2b_PERSONALBYTES 16U
SODIUM_EXPORT
size_t crypto_generichash_blake2b_personalbytes(void);
SODIUM_EXPORT
size_t crypto_generichash_blake2b_statebytes(void);
SODIUM_EXPORT
int crypto_generichash_blake2b(unsigned char *out, size_t outlen,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *key, size_t keylen);
SODIUM_EXPORT
int crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *key,
size_t keylen,
const unsigned char *salt,
const unsigned char *personal);
SODIUM_EXPORT
int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state,
const unsigned char *key,
const size_t keylen, const size_t outlen);
SODIUM_EXPORT
int crypto_generichash_blake2b_init_salt_personal(crypto_generichash_blake2b_state *state,
const unsigned char *key,
const size_t keylen, const size_t outlen,
const unsigned char *salt,
const unsigned char *personal);
SODIUM_EXPORT
int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state,
unsigned char *out,
const size_t outlen);
/* ------------------------------------------------------------------------- */
int _crypto_generichash_blake2b_pick_best_implementation(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,40 @@
#ifndef crypto_hash_H
#define crypto_hash_H
/*
* WARNING: Unless you absolutely need to use SHA512 for interoperatibility,
* purposes, you might want to consider crypto_generichash() instead.
* Unlike SHA512, crypto_generichash() is not vulnerable to length
* extension attacks.
*/
#include <stddef.h>
#include "crypto_hash_sha512.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_hash_BYTES crypto_hash_sha512_BYTES
SODIUM_EXPORT
size_t crypto_hash_bytes(void);
SODIUM_EXPORT
int crypto_hash(unsigned char *out, const unsigned char *in,
unsigned long long inlen);
#define crypto_hash_PRIMITIVE "sha512"
SODIUM_EXPORT
const char *crypto_hash_primitive(void)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,56 @@
#ifndef crypto_hash_sha256_H
#define crypto_hash_sha256_H
/*
* WARNING: Unless you absolutely need to use SHA256 for interoperatibility,
* purposes, you might want to consider crypto_generichash() instead.
* Unlike SHA256, crypto_generichash() is not vulnerable to length
* extension attacks.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
typedef struct crypto_hash_sha256_state {
uint32_t state[8];
uint64_t count;
unsigned char buf[64];
} crypto_hash_sha256_state;
SODIUM_EXPORT
size_t crypto_hash_sha256_statebytes(void);
#define crypto_hash_sha256_BYTES 32U
SODIUM_EXPORT
size_t crypto_hash_sha256_bytes(void);
SODIUM_EXPORT
int crypto_hash_sha256(unsigned char *out, const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_hash_sha256_init(crypto_hash_sha256_state *state);
SODIUM_EXPORT
int crypto_hash_sha256_update(crypto_hash_sha256_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_hash_sha256_final(crypto_hash_sha256_state *state,
unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,56 @@
#ifndef crypto_hash_sha512_H
#define crypto_hash_sha512_H
/*
* WARNING: Unless you absolutely need to use SHA512 for interoperatibility,
* purposes, you might want to consider crypto_generichash() instead.
* Unlike SHA512, crypto_generichash() is not vulnerable to length
* extension attacks.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
typedef struct crypto_hash_sha512_state {
uint64_t state[8];
uint64_t count[2];
unsigned char buf[128];
} crypto_hash_sha512_state;
SODIUM_EXPORT
size_t crypto_hash_sha512_statebytes(void);
#define crypto_hash_sha512_BYTES 64U
SODIUM_EXPORT
size_t crypto_hash_sha512_bytes(void);
SODIUM_EXPORT
int crypto_hash_sha512(unsigned char *out, const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_hash_sha512_init(crypto_hash_sha512_state *state);
SODIUM_EXPORT
int crypto_hash_sha512_update(crypto_hash_sha512_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_hash_sha512_final(crypto_hash_sha512_state *state,
unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,8 @@
#ifndef crypto_int32_H
#define crypto_int32_H
#include <stdint.h>
typedef int32_t crypto_int32;
#endif

View File

@ -0,0 +1,8 @@
#ifndef crypto_int64_H
#define crypto_int64_H
#include <stdint.h>
typedef int64_t crypto_int64;
#endif

View File

@ -0,0 +1,58 @@
#ifndef crypto_onetimeauth_H
#define crypto_onetimeauth_H
#include <stddef.h>
#include "crypto_onetimeauth_poly1305.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
typedef crypto_onetimeauth_poly1305_state crypto_onetimeauth_state;
SODIUM_EXPORT
size_t crypto_onetimeauth_statebytes(void);
#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
SODIUM_EXPORT
size_t crypto_onetimeauth_bytes(void);
#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
SODIUM_EXPORT
size_t crypto_onetimeauth_keybytes(void);
#define crypto_onetimeauth_PRIMITIVE "poly1305"
SODIUM_EXPORT
const char *crypto_onetimeauth_primitive(void);
SODIUM_EXPORT
int crypto_onetimeauth(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *k);
SODIUM_EXPORT
int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in,
unsigned long long inlen, const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_onetimeauth_init(crypto_onetimeauth_state *state,
const unsigned char *key);
SODIUM_EXPORT
int crypto_onetimeauth_update(crypto_onetimeauth_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_onetimeauth_final(crypto_onetimeauth_state *state,
unsigned char *out);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,65 @@
#ifndef crypto_onetimeauth_poly1305_H
#define crypto_onetimeauth_poly1305_H
#include <stdlib.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
typedef CRYPTO_ALIGN(16) struct crypto_onetimeauth_poly1305_state {
unsigned char opaque[256];
} crypto_onetimeauth_poly1305_state;
#define crypto_onetimeauth_poly1305_BYTES 16U
SODIUM_EXPORT
size_t crypto_onetimeauth_poly1305_bytes(void);
#define crypto_onetimeauth_poly1305_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_onetimeauth_poly1305_keybytes(void);
SODIUM_EXPORT
int crypto_onetimeauth_poly1305(unsigned char *out,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k);
SODIUM_EXPORT
int crypto_onetimeauth_poly1305_verify(const unsigned char *h,
const unsigned char *in,
unsigned long long inlen,
const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state,
const unsigned char *key);
SODIUM_EXPORT
int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state,
const unsigned char *in,
unsigned long long inlen);
SODIUM_EXPORT
int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state,
unsigned char *out);
/* ------------------------------------------------------------------------- */
int _crypto_onetimeauth_poly1305_pick_best_implementation(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,89 @@
#ifndef crypto_pwhash_H
#define crypto_pwhash_H
#include <stddef.h>
#include "crypto_pwhash_argon2i.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_pwhash_ALG_ARGON2I13 crypto_pwhash_argon2i_ALG_ARGON2I13
SODIUM_EXPORT
int crypto_pwhash_alg_argon2i13(void);
#define crypto_pwhash_ALG_DEFAULT crypto_pwhash_ALG_ARGON2I13
SODIUM_EXPORT
int crypto_pwhash_alg_default(void);
#define crypto_pwhash_SALTBYTES crypto_pwhash_argon2i_SALTBYTES
SODIUM_EXPORT
size_t crypto_pwhash_saltbytes(void);
#define crypto_pwhash_STRBYTES crypto_pwhash_argon2i_STRBYTES
SODIUM_EXPORT
size_t crypto_pwhash_strbytes(void);
#define crypto_pwhash_STRPREFIX crypto_pwhash_argon2i_STRPREFIX
SODIUM_EXPORT
const char *crypto_pwhash_strprefix(void);
#define crypto_pwhash_OPSLIMIT_INTERACTIVE crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE
SODIUM_EXPORT
size_t crypto_pwhash_opslimit_interactive(void);
#define crypto_pwhash_MEMLIMIT_INTERACTIVE crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE
SODIUM_EXPORT
size_t crypto_pwhash_memlimit_interactive(void);
#define crypto_pwhash_OPSLIMIT_MODERATE crypto_pwhash_argon2i_OPSLIMIT_MODERATE
SODIUM_EXPORT
size_t crypto_pwhash_opslimit_moderate(void);
#define crypto_pwhash_MEMLIMIT_MODERATE crypto_pwhash_argon2i_MEMLIMIT_MODERATE
SODIUM_EXPORT
size_t crypto_pwhash_memlimit_moderate(void);
#define crypto_pwhash_OPSLIMIT_SENSITIVE crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE
SODIUM_EXPORT
size_t crypto_pwhash_opslimit_sensitive(void);
#define crypto_pwhash_MEMLIMIT_SENSITIVE crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE
SODIUM_EXPORT
size_t crypto_pwhash_memlimit_sensitive(void);
SODIUM_EXPORT
int crypto_pwhash(unsigned char * const out, unsigned long long outlen,
const char * const passwd, unsigned long long passwdlen,
const unsigned char * const salt,
unsigned long long opslimit, size_t memlimit, int alg)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES],
const char * const passwd, unsigned long long passwdlen,
unsigned long long opslimit, size_t memlimit)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES],
const char * const passwd,
unsigned long long passwdlen)
__attribute__ ((warn_unused_result));
#define crypto_pwhash_PRIMITIVE "argon2i"
SODIUM_EXPORT
const char *crypto_pwhash_primitive(void)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,86 @@
#ifndef crypto_pwhash_argon2i_H
#define crypto_pwhash_argon2i_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_pwhash_argon2i_ALG_ARGON2I13 1
SODIUM_EXPORT
int crypto_pwhash_argon2i_alg_argon2i13(void);
#define crypto_pwhash_argon2i_SALTBYTES 16U
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_saltbytes(void);
#define crypto_pwhash_argon2i_STRBYTES 128U
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_strbytes(void);
#define crypto_pwhash_argon2i_STRPREFIX "$argon2i$"
SODIUM_EXPORT
const char *crypto_pwhash_argon2i_strprefix(void);
#define crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE 4ULL
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_opslimit_interactive(void);
#define crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE 33554432ULL
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_memlimit_interactive(void);
#define crypto_pwhash_argon2i_OPSLIMIT_MODERATE 6ULL
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_opslimit_moderate(void);
#define crypto_pwhash_argon2i_MEMLIMIT_MODERATE 134217728ULL
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_memlimit_moderate(void);
#define crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE 8ULL
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_opslimit_sensitive(void);
#define crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE 536870912ULL
SODIUM_EXPORT
size_t crypto_pwhash_argon2i_memlimit_sensitive(void);
SODIUM_EXPORT
int crypto_pwhash_argon2i(unsigned char * const out,
unsigned long long outlen,
const char * const passwd,
unsigned long long passwdlen,
const unsigned char * const salt,
unsigned long long opslimit, size_t memlimit,
int alg)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
const char * const passwd,
unsigned long long passwdlen,
unsigned long long opslimit, size_t memlimit)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES],
const char * const passwd,
unsigned long long passwdlen)
__attribute__ ((warn_unused_result));
/* ------------------------------------------------------------------------- */
int _crypto_pwhash_argon2i_pick_best_implementation(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,79 @@
#ifndef crypto_pwhash_scryptsalsa208sha256_H
#define crypto_pwhash_scryptsalsa208sha256_H
#include <stddef.h>
#include <stdint.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U
SODIUM_EXPORT
size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void);
#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U
SODIUM_EXPORT
size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void);
#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$"
SODIUM_EXPORT
const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void);
#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288ULL
SODIUM_EXPORT
size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void);
#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216ULL
SODIUM_EXPORT
size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void);
#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432ULL
SODIUM_EXPORT
size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void);
#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824ULL
SODIUM_EXPORT
size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void);
SODIUM_EXPORT
int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out,
unsigned long long outlen,
const char * const passwd,
unsigned long long passwdlen,
const unsigned char * const salt,
unsigned long long opslimit,
size_t memlimit)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
const char * const passwd,
unsigned long long passwdlen,
unsigned long long opslimit,
size_t memlimit)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES],
const char * const passwd,
unsigned long long passwdlen)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen,
const uint8_t * salt, size_t saltlen,
uint64_t N, uint32_t r, uint32_t p,
uint8_t * buf, size_t buflen)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,37 @@
#ifndef crypto_scalarmult_H
#define crypto_scalarmult_H
#include <stddef.h>
#include "crypto_scalarmult_curve25519.h"
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
SODIUM_EXPORT
size_t crypto_scalarmult_bytes(void);
#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
SODIUM_EXPORT
size_t crypto_scalarmult_scalarbytes(void);
#define crypto_scalarmult_PRIMITIVE "curve25519"
SODIUM_EXPORT
const char *crypto_scalarmult_primitive(void);
SODIUM_EXPORT
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
SODIUM_EXPORT
int crypto_scalarmult(unsigned char *q, const unsigned char *n,
const unsigned char *p)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
#ifndef crypto_scalarmult_curve25519_H
#define crypto_scalarmult_curve25519_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_scalarmult_curve25519_BYTES 32U
SODIUM_EXPORT
size_t crypto_scalarmult_curve25519_bytes(void);
#define crypto_scalarmult_curve25519_SCALARBYTES 32U
SODIUM_EXPORT
size_t crypto_scalarmult_curve25519_scalarbytes(void);
SODIUM_EXPORT
int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n,
const unsigned char *p)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n);
/* ------------------------------------------------------------------------- */
int _crypto_scalarmult_curve25519_pick_best_implementation(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,84 @@
#ifndef crypto_secretbox_H
#define crypto_secretbox_H
#include <stddef.h>
#include "crypto_secretbox_xsalsa20poly1305.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
SODIUM_EXPORT
size_t crypto_secretbox_keybytes(void);
#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
SODIUM_EXPORT
size_t crypto_secretbox_noncebytes(void);
#define crypto_secretbox_MACBYTES crypto_secretbox_xsalsa20poly1305_MACBYTES
SODIUM_EXPORT
size_t crypto_secretbox_macbytes(void);
#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
SODIUM_EXPORT
const char *crypto_secretbox_primitive(void);
SODIUM_EXPORT
int crypto_secretbox_easy(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_secretbox_detached(unsigned char *c, unsigned char *mac,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_secretbox_open_detached(unsigned char *m,
const unsigned char *c,
const unsigned char *mac,
unsigned long long clen,
const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
/* -- NaCl compatibility interface ; Requires padding -- */
#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
SODIUM_EXPORT
size_t crypto_secretbox_zerobytes(void);
#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
SODIUM_EXPORT
size_t crypto_secretbox_boxzerobytes(void);
SODIUM_EXPORT
int crypto_secretbox(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_secretbox_open(unsigned char *m, const unsigned char *c,
unsigned long long clen, const unsigned char *n,
const unsigned char *k)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,54 @@
#ifndef crypto_secretbox_xsalsa20poly1305_H
#define crypto_secretbox_xsalsa20poly1305_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_secretbox_xsalsa20poly1305_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_secretbox_xsalsa20poly1305_keybytes(void);
#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES 24U
SODIUM_EXPORT
size_t crypto_secretbox_xsalsa20poly1305_noncebytes(void);
#define crypto_secretbox_xsalsa20poly1305_MACBYTES 16U
SODIUM_EXPORT
size_t crypto_secretbox_xsalsa20poly1305_macbytes(void);
#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 16U
SODIUM_EXPORT
size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void);
#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES \
(crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + \
crypto_secretbox_xsalsa20poly1305_MACBYTES)
SODIUM_EXPORT
size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void);
SODIUM_EXPORT
int crypto_secretbox_xsalsa20poly1305(unsigned char *c,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m,
const unsigned char *c,
unsigned long long clen,
const unsigned char *n,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
#ifndef crypto_shorthash_H
#define crypto_shorthash_H
#include <stddef.h>
#include "crypto_shorthash_siphash24.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_shorthash_BYTES crypto_shorthash_siphash24_BYTES
SODIUM_EXPORT
size_t crypto_shorthash_bytes(void);
#define crypto_shorthash_KEYBYTES crypto_shorthash_siphash24_KEYBYTES
SODIUM_EXPORT
size_t crypto_shorthash_keybytes(void);
#define crypto_shorthash_PRIMITIVE "siphash24"
SODIUM_EXPORT
const char *crypto_shorthash_primitive(void);
SODIUM_EXPORT
int crypto_shorthash(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,30 @@
#ifndef crypto_shorthash_siphash24_H
#define crypto_shorthash_siphash24_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_shorthash_siphash24_BYTES 8U
SODIUM_EXPORT
size_t crypto_shorthash_siphash24_bytes(void);
#define crypto_shorthash_siphash24_KEYBYTES 16U
SODIUM_EXPORT
size_t crypto_shorthash_siphash24_keybytes(void);
SODIUM_EXPORT
int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,77 @@
#ifndef crypto_sign_H
#define crypto_sign_H
/*
* THREAD SAFETY: crypto_sign_keypair() is thread-safe,
* provided that you called sodium_init() once before using any
* other libsodium function.
* Other functions, including crypto_sign_seed_keypair() are always thread-safe.
*/
#include <stddef.h>
#include "crypto_sign_ed25519.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
SODIUM_EXPORT
size_t crypto_sign_bytes(void);
#define crypto_sign_SEEDBYTES crypto_sign_ed25519_SEEDBYTES
SODIUM_EXPORT
size_t crypto_sign_seedbytes(void);
#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
SODIUM_EXPORT
size_t crypto_sign_publickeybytes(void);
#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
SODIUM_EXPORT
size_t crypto_sign_secretkeybytes(void);
#define crypto_sign_PRIMITIVE "ed25519"
SODIUM_EXPORT
const char *crypto_sign_primitive(void);
SODIUM_EXPORT
int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
const unsigned char *seed);
SODIUM_EXPORT
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk);
SODIUM_EXPORT
int crypto_sign(unsigned char *sm, unsigned long long *smlen_p,
const unsigned char *m, unsigned long long mlen,
const unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p,
const unsigned char *sm, unsigned long long smlen,
const unsigned char *pk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p,
const unsigned char *m, unsigned long long mlen,
const unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_verify_detached(const unsigned char *sig,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *pk)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,82 @@
#ifndef crypto_sign_ed25519_H
#define crypto_sign_ed25519_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_sign_ed25519_BYTES 64U
SODIUM_EXPORT
size_t crypto_sign_ed25519_bytes(void);
#define crypto_sign_ed25519_SEEDBYTES 32U
SODIUM_EXPORT
size_t crypto_sign_ed25519_seedbytes(void);
#define crypto_sign_ed25519_PUBLICKEYBYTES 32U
SODIUM_EXPORT
size_t crypto_sign_ed25519_publickeybytes(void);
#define crypto_sign_ed25519_SECRETKEYBYTES (32U + 32U)
SODIUM_EXPORT
size_t crypto_sign_ed25519_secretkeybytes(void);
SODIUM_EXPORT
int crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p,
const unsigned char *m, unsigned long long mlen,
const unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p,
const unsigned char *sm, unsigned long long smlen,
const unsigned char *pk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_sign_ed25519_detached(unsigned char *sig,
unsigned long long *siglen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_ed25519_verify_detached(const unsigned char *sig,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *pk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk,
const unsigned char *seed);
SODIUM_EXPORT
int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk,
const unsigned char *ed25519_pk)
__attribute__ ((warn_unused_result));
SODIUM_EXPORT
int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
const unsigned char *ed25519_sk);
SODIUM_EXPORT
int crypto_sign_ed25519_sk_to_seed(unsigned char *seed,
const unsigned char *sk);
SODIUM_EXPORT
int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,54 @@
#ifndef crypto_sign_edwards25519sha512batch_H
#define crypto_sign_edwards25519sha512batch_H
/*
* WARNING: This construction was a prototype, which should not be used
* any more in new projects.
*
* crypto_sign_edwards25519sha512batch is provided for applications
* initially built with NaCl, but as recommended by the author of this
* construction, new applications should use ed25519 instead.
*
* In Sodium, you should use the high-level crypto_sign_*() functions instead.
*/
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_sign_edwards25519sha512batch_BYTES 64U
#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 32U
#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES (32U + 32U)
SODIUM_EXPORT
int crypto_sign_edwards25519sha512batch(unsigned char *sm,
unsigned long long *smlen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *sk)
__attribute__ ((deprecated));
SODIUM_EXPORT
int crypto_sign_edwards25519sha512batch_open(unsigned char *m,
unsigned long long *mlen_p,
const unsigned char *sm,
unsigned long long smlen,
const unsigned char *pk)
__attribute__ ((deprecated));
SODIUM_EXPORT
int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk,
unsigned char *sk)
__attribute__ ((deprecated));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,49 @@
#ifndef crypto_stream_H
#define crypto_stream_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include "crypto_stream_xsalsa20.h"
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
SODIUM_EXPORT
size_t crypto_stream_keybytes(void);
#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
SODIUM_EXPORT
size_t crypto_stream_noncebytes(void);
#define crypto_stream_PRIMITIVE "xsalsa20"
SODIUM_EXPORT
const char *crypto_stream_primitive(void);
SODIUM_EXPORT
int crypto_stream(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,60 @@
#ifndef crypto_stream_aes128ctr_H
#define crypto_stream_aes128ctr_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_aes128ctr_KEYBYTES 16U
SODIUM_EXPORT
size_t crypto_stream_aes128ctr_keybytes(void);
#define crypto_stream_aes128ctr_NONCEBYTES 16U
SODIUM_EXPORT
size_t crypto_stream_aes128ctr_noncebytes(void);
#define crypto_stream_aes128ctr_BEFORENMBYTES 1408U
SODIUM_EXPORT
size_t crypto_stream_aes128ctr_beforenmbytes(void);
SODIUM_EXPORT
int crypto_stream_aes128ctr(unsigned char *out, unsigned long long outlen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_aes128ctr_xor(unsigned char *out, const unsigned char *in,
unsigned long long inlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_aes128ctr_beforenm(unsigned char *c, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_aes128ctr_afternm(unsigned char *out, unsigned long long len,
const unsigned char *nonce, const unsigned char *c);
SODIUM_EXPORT
int crypto_stream_aes128ctr_xor_afternm(unsigned char *out, const unsigned char *in,
unsigned long long len,
const unsigned char *nonce,
const unsigned char *c);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,77 @@
#ifndef crypto_stream_chacha20_H
#define crypto_stream_chacha20_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include <stdint.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_chacha20_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_stream_chacha20_keybytes(void);
#define crypto_stream_chacha20_NONCEBYTES 8U
SODIUM_EXPORT
size_t crypto_stream_chacha20_noncebytes(void);
/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */
SODIUM_EXPORT
int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint64_t ic,
const unsigned char *k);
/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */
#define crypto_stream_chacha20_IETF_NONCEBYTES 12U
SODIUM_EXPORT
size_t crypto_stream_chacha20_ietf_noncebytes(void);
SODIUM_EXPORT
int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint32_t ic,
const unsigned char *k);
/* ------------------------------------------------------------------------- */
int _crypto_stream_chacha20_pick_best_implementation(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,49 @@
#ifndef crypto_stream_salsa20_H
#define crypto_stream_salsa20_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include <stdint.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_salsa20_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_stream_salsa20_keybytes(void);
#define crypto_stream_salsa20_NONCEBYTES 8U
SODIUM_EXPORT
size_t crypto_stream_salsa20_noncebytes(void);
SODIUM_EXPORT
int crypto_stream_salsa20(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint64_t ic,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,43 @@
#ifndef crypto_stream_salsa2012_H
#define crypto_stream_salsa2012_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_salsa2012_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_stream_salsa2012_keybytes(void);
#define crypto_stream_salsa2012_NONCEBYTES 8U
SODIUM_EXPORT
size_t crypto_stream_salsa2012_noncebytes(void);
SODIUM_EXPORT
int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,43 @@
#ifndef crypto_stream_salsa208_H
#define crypto_stream_salsa208_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_salsa208_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_stream_salsa208_keybytes(void);
#define crypto_stream_salsa208_NONCEBYTES 8U
SODIUM_EXPORT
size_t crypto_stream_salsa208_noncebytes(void);
SODIUM_EXPORT
int crypto_stream_salsa208(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,49 @@
#ifndef crypto_stream_xsalsa20_H
#define crypto_stream_xsalsa20_H
/*
* WARNING: This is just a stream cipher. It is NOT authenticated encryption.
* While it provides some protection against eavesdropping, it does NOT
* provide any security against active attacks.
* Unless you know what you're doing, what you are looking for is probably
* the crypto_box functions.
*/
#include <stddef.h>
#include <stdint.h>
#include "export.h"
#ifdef __cplusplus
# if __GNUC__
# pragma GCC diagnostic ignored "-Wlong-long"
# endif
extern "C" {
#endif
#define crypto_stream_xsalsa20_KEYBYTES 32U
SODIUM_EXPORT
size_t crypto_stream_xsalsa20_keybytes(void);
#define crypto_stream_xsalsa20_NONCEBYTES 24U
SODIUM_EXPORT
size_t crypto_stream_xsalsa20_noncebytes(void);
SODIUM_EXPORT
int crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen,
const unsigned char *n, const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m,
unsigned long long mlen, const unsigned char *n,
const unsigned char *k);
SODIUM_EXPORT
int crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m,
unsigned long long mlen,
const unsigned char *n, uint64_t ic,
const unsigned char *k);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,8 @@
#ifndef crypto_uint16_H
#define crypto_uint16_H
#include <stdint.h>
typedef uint16_t crypto_uint16;
#endif

View File

@ -0,0 +1,8 @@
#ifndef crypto_uint32_H
#define crypto_uint32_H
#include <stdint.h>
typedef uint32_t crypto_uint32;
#endif

View File

@ -0,0 +1,8 @@
#ifndef crypto_uint64_H
#define crypto_uint64_H
#include <stdint.h>
typedef uint64_t crypto_uint64;
#endif

View File

@ -0,0 +1,8 @@
#ifndef crypto_uint8_H
#define crypto_uint8_H
#include <stdint.h>
typedef uint8_t crypto_uint8;
#endif

View File

@ -0,0 +1,23 @@
#ifndef crypto_verify_16_H
#define crypto_verify_16_H
#include <stddef.h>
#include "export.h"
#ifdef __cplusplus
extern "C" {
#endif
#define crypto_verify_16_BYTES 16U
SODIUM_EXPORT
size_t crypto_verify_16_bytes(void);
SODIUM_EXPORT
int crypto_verify_16(const unsigned char *x, const unsigned char *y)
__attribute__ ((warn_unused_result));
#ifdef __cplusplus
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More