29#define DISABLE_DEBUGLOG
33#include "syncio_http_p.h"
36#include <gwenhywfar/misc.h>
37#include <gwenhywfar/debug.h>
38#include <gwenhywfar/gui.h>
39#include <gwenhywfar/text.h>
55 GWEN_SYNCIO_HTTP *xio;
82 GWEN_SYNCIO_HTTP *xio;
84 xio=(GWEN_SYNCIO_HTTP *) p;
101 GWEN_SYNCIO_HTTP *xio;
133 GWEN_SYNCIO_HTTP *xio;
163 GWEN_SYNCIO_HTTP *xio;
169 xio->readMode=GWEN_SyncIo_Http_Mode_Idle;
178 GWEN_SYNCIO_HTTP *xio;
190 if (xio->readMode==GWEN_SyncIo_Http_Mode_Idle) {
203 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
209 if (!(s && strcasecmp(s,
"HTTP/0.9")==0)) {
213 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
223 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
229 if (!(s && strcasecmp(s,
"HTTP/0.9")==0)) {
233 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
241 if (xio->readMode==GWEN_SyncIo_Http_Mode_ChunkSize) {
245 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
248 if (xio->currentReadChunkSize==0) {
268 else if (xio->currentReadChunkSize==-1) {
270 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
275 xio->readMode=GWEN_SyncIo_Http_Mode_Chunk;
278 if (xio->readMode==GWEN_SyncIo_Http_Mode_Chunk) {
282 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
290 if (xio->readMode==GWEN_SyncIo_Http_Mode_Body) {
294 xio->readMode=GWEN_SyncIo_Http_Mode_Error;
302 if (xio->readMode==GWEN_SyncIo_Http_Mode_Error) {
313 const uint8_t *buffer,
316 GWEN_SYNCIO_HTTP *xio;
332 if (xio->writeMode==GWEN_SyncIo_Http_Mode_Idle) {
342 xio->writeMode=GWEN_SyncIo_Http_Mode_Error;
348 if (!(s && strcasecmp(s,
"HTTP/0.9")==0)) {
351 xio->writeMode=GWEN_SyncIo_Http_Mode_Error;
357 if (xio->writeMode==GWEN_SyncIo_Http_Mode_ChunkSize) {
360 xio->writeMode=GWEN_SyncIo_Http_Mode_Error;
370 xio->writeMode=GWEN_SyncIo_Http_Mode_Chunk;
373 if (xio->writeMode==GWEN_SyncIo_Http_Mode_Chunk) {
378 xio->writeMode=GWEN_SyncIo_Http_Mode_Error;
381 xio->writeMode=GWEN_SyncIo_Http_Mode_ChunkSize;
386 if (xio->writeMode==GWEN_SyncIo_Http_Mode_Body) {
387 if ((xio->currentWriteBodySize!=-1) &&
388 ((
int)size>xio->currentWriteBodySize)) {
390 xio->writeMode=GWEN_SyncIo_Http_Mode_Error;
398 xio->writeMode=GWEN_SyncIo_Http_Mode_Error;
401 if (xio->currentWriteBodySize!=-1) {
402 xio->currentWriteBodySize-=rv;
403 if (xio->currentWriteBodySize==0)
410 if (xio->writeMode==GWEN_SyncIo_Http_Mode_Error) {
422 GWEN_SYNCIO_HTTP *xio;
474 GWEN_SYNCIO_HTTP *xio;
489 "Bad format of HTTP status (%s)", buffer);
499 while (*p && isdigit((
int)*p))
505 if (1!=sscanf(s,
"%d", &code)) {
522 GWEN_SYNCIO_HTTP *xio;
538 "Bad format of HTTP request (%s)", buffer);
552 "Bad format of HTTP request (%s)", buffer);
580 GWEN_SYNCIO_HTTP *xio;
631 GWEN_SYNCIO_HTTP *xio;
668 GWEN_SYNCIO_HTTP *xio;
685 if (p[1]==32 || p[1]==9)
705 while (*p && (*p==32 || *p==9))
709 while (*p && *p!=
':' && *p>32 && *p<127)
719 while (*p && (*p==32 || *p==9))
729 xio->readMode=GWEN_SyncIo_Http_Mode_Body;
736 xio->currentReadChunkSize=-1;
737 xio->readMode=GWEN_SyncIo_Http_Mode_ChunkSize;
742 if (xio->currentReadBodySize==0) {
746 else if (xio->currentReadBodySize==-1) {
754 if (rcode<0 || rcode>=300) {
767 GWEN_SYNCIO_HTTP *xio;
848 GWEN_SYNCIO_HTTP *xio;
888 xio->currentReadChunkSize=csize;
898 GWEN_SYNCIO_HTTP *xio;
913 if ((
int)size>xio->currentReadChunkSize)
914 size=xio->currentReadChunkSize;
922 xio->currentReadChunkSize-=rv;
923 if (xio->currentReadBodySize>0)
924 xio->currentReadBodySize-=rv;
926 if (xio->currentReadChunkSize==0) {
943 xio->readMode=GWEN_SyncIo_Http_Mode_ChunkSize;
953 GWEN_SYNCIO_HTTP *xio;
970 if ((xio->currentReadBodySize>=0) &&
971 ((
int)size>xio->currentReadBodySize)) {
973 size, xio->currentReadBodySize);
974 size=xio->currentReadBodySize;
983 if (xio->currentReadBodySize>=0)
984 xio->currentReadBodySize-=rv;
986 if (xio->currentReadBodySize==0)
997 GWEN_SYNCIO_HTTP *xio;
1053 GWEN_SYNCIO_HTTP *xio;
1083 snprintf(numbuf,
sizeof(numbuf),
"%d ", i);
1108 GWEN_SYNCIO_HTTP *xio;
1127 xio->writeMode=GWEN_SyncIo_Http_Mode_Body;
1132 xio->currentWriteBodySize=i;
1157 xio->writeMode=GWEN_SyncIo_Http_Mode_ChunkSize;
1169 snprintf(numbuf,
sizeof(numbuf),
"%d", i);
1205 if (xio->currentWriteBodySize==0)
1215 GWEN_SYNCIO_HTTP *xio;
1230 snprintf(numbuf,
sizeof(numbuf)-1,
"%x\r\n", size);
1231 numbuf[
sizeof(numbuf)-1]=0;
1246 GWEN_SYNCIO_HTTP *xio;
1252 xio->writeMode=GWEN_SyncIo_Http_Mode_Idle;
1261 GWEN_SYNCIO_HTTP *xio;
1267 return xio->dbCommandIn;
1274 GWEN_SYNCIO_HTTP *xio;
1280 return xio->dbStatusIn;
1287 GWEN_SYNCIO_HTTP *xio;
1293 return xio->dbHeaderIn;
1300 GWEN_SYNCIO_HTTP *xio;
1306 return xio->dbCommandOut;
1313 GWEN_SYNCIO_HTTP *xio;
1319 return xio->dbStatusOut;
1326 GWEN_SYNCIO_HTTP *xio;
1332 return xio->dbHeaderOut;
1340 GWEN_SYNCIO_HTTP *xio;
1356 I18N(
"Network Operation"),
1357 I18N(
"Receiving data"),
1385 if (bodySize!=-1 && bytesRead<bodySize) {
1387 "EOF met prematurely (%d < %d)",
1388 bytesRead, bodySize);
1422 if (bodySize!=-1 && bytesRead>=bodySize) {
1435 "We received an error, but we still got data, "
1436 "so we ignore the error here");
1442 I18N(
"No message received"));
1450 I18N(
"No message received"));
1464 code, s?s:
"- no text -");
1466 I18N(
"HTTP-Status: %d (%s)"),
1467 code, s?s:
I18N(
"- no details -"));
1473 I18N(
"No HTTP status code received"));
1485 GWEN_SYNCIO_HTTP *xio;
1501 I18N(
"Network Operation"),
1502 I18N(
"Receiving data"),
1524 if (bodySize!=-1 && bytesRead<bodySize) {
1526 "EOF met prematurely (%d < %d)",
1527 bytesRead, bodySize);
1567 if (bodySize!=-1 && bytesRead>=bodySize) {
1580 "We received an error, but we still got data, "
1581 "so we ignore the error here");
1587 I18N(
"No message received"));
1595 I18N(
"No message received"));
1609 code, s?s:
"- no text -");
1611 I18N(
"HTTP-Status: %d (%s)"),
1612 code, s?s:
I18N(
"- no details -)"));
1618 I18N(
"No HTTP status code received"));
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
void GWEN_Buffer_free(GWEN_BUFFER *bf)
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, const char *path)
GWEN_DB_NODE * GWEN_DB_GetNextVar(GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
const char * GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n)
GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n)
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
GWEN_DB_NODE * GWEN_DB_GetFirstVar(GWEN_DB_NODE *n)
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
const char * GWEN_DB_VariableName(GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_GetFirstValue(GWEN_DB_NODE *n)
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n)
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
@ GWEN_DB_NodeType_ValueInt
@ GWEN_DB_NodeType_ValueChar
#define GWEN_DB_FLAGS_OVERWRITE_VARS
struct GWEN_DB_NODE GWEN_DB_NODE
#define DBG_DEBUG(dbg_logger, format, args...)
#define DBG_INFO(dbg_logger, format, args...)
#define DBG_ERROR(dbg_logger, format, args...)
#define GWEN_ERROR_INVALID
#define GWEN_ERROR_BAD_DATA
#define GWEN_ERROR_NOT_CONNECTED
#define GWEN_ERROR_GENERIC
#define GWEN_ERROR_USER_ABORTED
#define GWEN_ERROR_INTERRUPTED
#define GWEN_ERROR_NO_DATA
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
#define GWEN_GUI_PROGRESS_DELAY
GWENHYWFAR_API uint32_t GWEN_Gui_ProgressStart(uint32_t progressFlags, const char *title, const char *text, uint64_t total, uint32_t guiid)
#define GWEN_GUI_PROGRESS_SHOW_PROGRESS
GWENHYWFAR_API int GWEN_Gui_ProgressEnd(uint32_t id)
GWENHYWFAR_API int GWEN_Gui_ProgressLog(uint32_t id, GWEN_LOGGER_LEVEL level, const char *text)
#define GWEN_GUI_PROGRESS_SHOW_ABORT
GWENHYWFAR_API int GWEN_Gui_ProgressSetTotal(uint32_t id, uint64_t total)
GWENHYWFAR_API int GWEN_Gui_ProgressLog2(uint32_t id, GWEN_LOGGER_LEVEL level, const char *text,...)
GWENHYWFAR_API int GWEN_Gui_ProgressAdvance(uint32_t id, uint32_t progress)
#define GWEN_GUI_PROGRESS_ALLOW_EMBED
#define GWEN_INHERIT_SETDATA(bt, t, element, data, fn)
#define GWEN_INHERIT(bt, t)
#define GWEN_INHERIT_GETDATA(bt, t, element)
int GWEN_Logger_GetLevel(const char *logDomain)
#define GWEN_FREE_OBJECT(varname)
#define GWEN_NEW_OBJECT(typ, varname)
#define GWEN_PATH_FLAGS_CREATE_VAR
uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio)
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
GWEN_SYNCIO * GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo)
GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn)
GWEN_SYNCIO * GWEN_SyncIo_GetBaseIo(const GWEN_SYNCIO *sio)
GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn)
void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl)
GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn)
int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
GWEN_SYNCIO_STATUS GWEN_SyncIo_GetStatus(const GWEN_SYNCIO *sio)
int GWEN_SyncIo_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn)
void GWEN_SyncIo_SetStatus(GWEN_SYNCIO *sio, GWEN_SYNCIO_STATUS st)
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
#define GWEN_SYNCIO_FLAGS_PASSIVE
struct GWEN_SYNCIO GWEN_SYNCIO
@ GWEN_SyncIo_Status_Connected
@ GWEN_SyncIo_Status_Disconnected
#define GWEN_SYNCIO_FLAGS_TRANSPARENT
int GWEN_SyncIo_Http_WriteStatus(GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_WriteCommand(GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_ReadLine(GWEN_SYNCIO *sio, GWEN_BUFFER *tbuf)
GWEN_DB_NODE * GWEN_SyncIo_Http_GetDbCommandOut(const GWEN_SYNCIO *sio)
GWEN_SYNCIO * GWEN_SyncIo_Http_new(GWEN_SYNCIO *baseIo)
int GWEN_SyncIo_Http_RecvBody(GWEN_SYNCIO *sio, GWEN_BUFFER *buf)
int GWEN_SyncIo_Http_ReadCommand(GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_WriteHeader(GWEN_SYNCIO *sio)
void GWENHYWFAR_CB GWEN_SyncIo_Http_FreeData(GWEN_UNUSED void *bp, void *p)
int GWEN_SyncIo_Http_ParseCommand(GWEN_SYNCIO *sio, const char *buffer)
int GWEN_SyncIo_Http_RecvBodyToSio(GWEN_SYNCIO *sio, GWEN_SYNCIO *sout)
int GWEN_SyncIo_Http_ReadChunkSize(GWEN_SYNCIO *sio)
GWEN_DB_NODE * GWEN_SyncIo_Http_GetDbStatusOut(const GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_ReadHeader(GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_ReadBody(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
int GWEN_SyncIo_Http_ParseStatus(GWEN_SYNCIO *sio, char *buffer)
int GWEN_SyncIo_Http_ReadStatus(GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_ParseHeader(GWEN_SYNCIO *sio, char *buf)
GWEN_DB_NODE * GWEN_SyncIo_Http_GetDbStatusIn(const GWEN_SYNCIO *sio)
GWEN_DB_NODE * GWEN_SyncIo_Http_GetDbHeaderIn(const GWEN_SYNCIO *sio)
int GWENHYWFAR_CB GWEN_SyncIo_Http_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
int GWENHYWFAR_CB GWEN_SyncIo_Http_Disconnect(GWEN_SYNCIO *sio)
int GWENHYWFAR_CB GWEN_SyncIo_Http_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
GWEN_DB_NODE * GWEN_SyncIo_Http_GetDbHeaderOut(const GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_WriteChunkSize(GWEN_SYNCIO *sio, uint32_t size)
GWEN_DB_NODE * GWEN_SyncIo_Http_GetDbCommandIn(const GWEN_SYNCIO *sio)
int GWEN_SyncIo_Http_ReadChunk(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
int GWENHYWFAR_CB GWEN_SyncIo_Http_Connect(GWEN_SYNCIO *sio)
void GWEN_SyncIo_Http_SetReadIdle(GWEN_SYNCIO *sio)
void GWEN_SyncIo_Http_SetWriteIdle(GWEN_SYNCIO *sio)
#define GWEN_SYNCIO_HTTP_TYPE
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
void GWEN_Text_LogString(const char *s, unsigned int l, const char *logDomain, GWEN_LOGGER_LEVEL lv)