00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016
00017
00018 #include "io_http_p.h"
00019 #include <gwenhywfar/iolayer_be.h>
00020 #include <gwenhywfar/iorequest_be.h>
00021 #include <gwenhywfar/iomanager.h>
00022 #include <gwenhywfar/io_buffered.h>
00023
00024 #include "i18n_l.h"
00025 #include <gwenhywfar/misc.h>
00026 #include <gwenhywfar/debug.h>
00027 #include <gwenhywfar/gui.h>
00028 #include <gwenhywfar/text.h>
00029
00030 #include <assert.h>
00031 #include <ctype.h>
00032
00033
00034
00035
00036 GWEN_INHERIT(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP)
00037
00038
00039
00040
00041
00042 GWEN_IO_LAYER *GWEN_Io_LayerHttp_new(GWEN_IO_LAYER *baseLayer) {
00043 GWEN_IO_LAYER *io;
00044 GWEN_IO_LAYER_HTTP *xio;
00045
00046 io=GWEN_Io_Layer_new(GWEN_IO_LAYER_HTTP_TYPE, baseLayer);
00047 assert(io);
00048 GWEN_NEW_OBJECT(GWEN_IO_LAYER_HTTP, xio);
00049 assert(xio);
00050 GWEN_INHERIT_SETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io, xio, GWEN_Io_LayerHttp_freeData);
00051
00052 xio->dbCommandIn=GWEN_DB_Group_new("command");
00053 xio->dbStatusIn=GWEN_DB_Group_new("status");
00054 xio->dbHeaderIn=GWEN_DB_Group_new("header");
00055 xio->readBuffer=GWEN_Buffer_new(0, GWEN_IO_LAYER_HTTP_LINE_STEPSIZE, 0, 1);
00056
00057 xio->dbCommandOut=GWEN_DB_Group_new("command");
00058 xio->dbStatusOut=GWEN_DB_Group_new("status");
00059 xio->dbHeaderOut=GWEN_DB_Group_new("header");
00060 xio->writeBuffer=GWEN_Buffer_new(0, GWEN_IO_LAYER_HTTP_LINE_STEPSIZE, 0, 1);
00061
00062 GWEN_Io_Layer_SetWorkOnRequestsFn(io, GWEN_Io_LayerHttp_WorkOnRequests);
00063 GWEN_Io_Layer_SetAddRequestFn(io, GWEN_Io_LayerHttp_AddRequest);
00064 GWEN_Io_Layer_SetDelRequestFn(io, GWEN_Io_LayerHttp_DelRequest);
00065 GWEN_Io_Layer_SetHasWaitingRequestsFn(io, GWEN_Io_LayerHttp_HasWaitingRequests);
00066
00067 return io;
00068 }
00069
00070
00071
00072 GWENHYWFAR_CB
00073 void GWEN_Io_LayerHttp_freeData(void *bp, void *p) {
00074 GWEN_IO_LAYER_HTTP *xio;
00075
00076 xio=(GWEN_IO_LAYER_HTTP*) p;
00077 GWEN_DB_Group_free(xio->dbCommandIn);
00078 GWEN_DB_Group_free(xio->dbStatusIn);
00079 GWEN_DB_Group_free(xio->dbHeaderIn);
00080 GWEN_Buffer_free(xio->readBuffer);
00081
00082 GWEN_DB_Group_free(xio->dbCommandOut);
00083 GWEN_DB_Group_free(xio->dbStatusOut);
00084 GWEN_DB_Group_free(xio->dbHeaderOut);
00085 GWEN_Buffer_free(xio->writeBuffer);
00086
00087 GWEN_FREE_OBJECT(xio);
00088 }
00089
00090
00091
00092 GWEN_DB_NODE *GWEN_Io_LayerHttp_GetDbCommandIn(const GWEN_IO_LAYER *io) {
00093 GWEN_IO_LAYER_HTTP *xio;
00094
00095 assert(io);
00096 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00097 assert(xio);
00098
00099 return xio->dbCommandIn;
00100 }
00101
00102
00103
00104 GWEN_DB_NODE *GWEN_Io_LayerHttp_GetDbStatusIn(const GWEN_IO_LAYER *io) {
00105 GWEN_IO_LAYER_HTTP *xio;
00106
00107 assert(io);
00108 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00109 assert(xio);
00110
00111 return xio->dbStatusIn;
00112 }
00113
00114
00115
00116 GWEN_DB_NODE *GWEN_Io_LayerHttp_GetDbHeaderIn(const GWEN_IO_LAYER *io) {
00117 GWEN_IO_LAYER_HTTP *xio;
00118
00119 assert(io);
00120 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00121 assert(xio);
00122
00123 return xio->dbHeaderIn;
00124 }
00125
00126
00127
00128 GWEN_DB_NODE *GWEN_Io_LayerHttp_GetDbCommandOut(const GWEN_IO_LAYER *io) {
00129 GWEN_IO_LAYER_HTTP *xio;
00130
00131 assert(io);
00132 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00133 assert(xio);
00134
00135 return xio->dbCommandOut;
00136 }
00137
00138
00139
00140 GWEN_DB_NODE *GWEN_Io_LayerHttp_GetDbStatusOut(const GWEN_IO_LAYER *io) {
00141 GWEN_IO_LAYER_HTTP *xio;
00142
00143 assert(io);
00144 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00145 assert(xio);
00146
00147 return xio->dbStatusOut;
00148 }
00149
00150
00151
00152 GWEN_DB_NODE *GWEN_Io_LayerHttp_GetDbHeaderOut(const GWEN_IO_LAYER *io) {
00153 GWEN_IO_LAYER_HTTP *xio;
00154
00155 assert(io);
00156 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00157 assert(xio);
00158
00159 return xio->dbHeaderOut;
00160 }
00161
00162
00163
00164 void GWEN_Io_LayerHttp_AbortInRequests(GWEN_IO_LAYER *io, int errorCode) {
00165 GWEN_IO_LAYER_HTTP *xio;
00166
00167 assert(io);
00168 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00169 assert(xio);
00170
00171 if (xio->readRequestIn) {
00172 GWEN_IO_REQUEST *r;
00173
00174 r=xio->readRequestIn;
00175 xio->readRequestIn=NULL;
00176 DBG_INFO(GWEN_LOGDOMAIN, "Aborting in read request");
00177 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00178 GWEN_Io_Request_free(r);
00179 }
00180 if (xio->writeRequestIn) {
00181 GWEN_IO_REQUEST *r;
00182
00183 r=xio->writeRequestIn;
00184 xio->writeRequestIn=NULL;
00185 DBG_INFO(GWEN_LOGDOMAIN, "Aborting in write request");
00186 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00187 GWEN_Io_Request_free(r);
00188 }
00189 }
00190
00191
00192
00193 void GWEN_Io_LayerHttp_AbortOutRequests(GWEN_IO_LAYER *io) {
00194 GWEN_IO_LAYER_HTTP *xio;
00195
00196 assert(io);
00197 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00198 assert(xio);
00199
00200 if (xio->readRequestOut) {
00201 GWEN_IO_REQUEST *r;
00202
00203 r=xio->readRequestOut;
00204 GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00205 xio->readRequestOut=NULL;
00206 GWEN_Io_Request_free(r);
00207 }
00208 if (xio->writeRequestIn) {
00209 GWEN_IO_REQUEST *r;
00210
00211 r=xio->writeRequestIn;
00212 GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00213 xio->writeRequestIn=NULL;
00214 GWEN_Io_Request_free(r);
00215 }
00216 }
00217
00218
00219
00220
00221
00222 int GWEN_Io_LayerHttp_ParseCommand(GWEN_IO_LAYER *io, const char *buffer) {
00223 GWEN_IO_LAYER_HTTP *xio;
00224 char *tmp;
00225 char *p;
00226 char *s;
00227
00228 assert(io);
00229 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00230 assert(xio);
00231
00232 tmp=strdup(buffer);
00233 s=tmp;
00234
00235
00236 p=strchr(s, ' ');
00237 if (!p) {
00238 DBG_ERROR(GWEN_LOGDOMAIN,
00239 "Bad format of HTTP request (%s)", buffer);
00240 free(tmp);
00241 return GWEN_ERROR_INVALID;
00242 }
00243 *p=0;
00244 p++;
00245
00246 GWEN_DB_SetCharValue(xio->dbCommandIn, GWEN_DB_FLAGS_OVERWRITE_VARS, "command", s);
00247 s=p;
00248
00249
00250 p=strchr(s, ' ');
00251 if (!p) {
00252
00253 if (GWEN_Io_Layer_GetFlags(io) & GWEN_IO_LAYER_HTTP_FLAGS_IPC) {
00254 DBG_INFO(GWEN_LOGDOMAIN, "Ignoring missing url");
00255 free(tmp);
00256 return 0;
00257 }
00258 else {
00259 DBG_ERROR(GWEN_LOGDOMAIN,
00260 "Bad format of HTTP request (%s)", buffer);
00261 free(tmp);
00262 return GWEN_ERROR_INVALID;
00263 }
00264 }
00265 *p=0;
00266 p++;
00267
00268 GWEN_DB_SetCharValue(xio->dbCommandIn, GWEN_DB_FLAGS_OVERWRITE_VARS, "url", s);
00269 s=p;
00270
00271 if (*s==0) {
00272
00273 DBG_ERROR(GWEN_LOGDOMAIN, "Bad request (not in HTTP>=1.0)");
00274 free(tmp);
00275 return GWEN_ERROR_INVALID;
00276 }
00277 else {
00278 GWEN_DB_SetCharValue(xio->dbCommandIn, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", s);
00279 }
00280
00281 free(tmp);
00282 return 0;
00283 }
00284
00285
00286
00287 int GWEN_Io_LayerHttp_ParseStatus(GWEN_IO_LAYER *io, const char *buffer) {
00288 GWEN_IO_LAYER_HTTP *xio;
00289 char *tmp;
00290 char *p;
00291 char *s;
00292 int code;
00293
00294 assert(io);
00295 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00296 assert(xio);
00297
00298 tmp=strdup(buffer);
00299 s=tmp;
00300
00301
00302 p=strchr(s, ' ');
00303 if (!p) {
00304 DBG_ERROR(GWEN_LOGDOMAIN,
00305 "Bad format of HTTP status (%s)", buffer);
00306 free(tmp);
00307 return GWEN_ERROR_INVALID;
00308 }
00309 *p=0;
00310 p++;
00311
00312 GWEN_DB_SetCharValue(xio->dbStatusIn, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", s);
00313 s=p;
00314
00315
00316 while(*p && isdigit((int)*p))
00317 p++;
00318 if (*p) {
00319 *p=0;
00320 p++;
00321 }
00322 if (1!=sscanf(s, "%d", &code)) {
00323 DBG_ERROR(GWEN_LOGDOMAIN, "Bad request (status code \"%s\")", s);
00324 free(tmp);
00325 return GWEN_ERROR_INVALID;
00326 }
00327 GWEN_DB_SetIntValue(xio->dbStatusIn, GWEN_DB_FLAGS_OVERWRITE_VARS, "code", code);
00328 s=p;
00329
00330
00331 GWEN_DB_SetCharValue(xio->dbStatusIn, GWEN_DB_FLAGS_OVERWRITE_VARS, "text", s);
00332
00333 free(tmp);
00334 return 0;
00335 }
00336
00337
00338
00339 int GWEN_Io_LayerHttp_ParseHeader(GWEN_IO_LAYER *io, char *buf) {
00340 GWEN_IO_LAYER_HTTP *xio;
00341 char *p;
00342 const char *s;
00343
00344 assert(io);
00345 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00346 assert(xio);
00347
00348
00349 p=buf;
00350 while(*p) {
00351 p=strchr(p, 10);
00352 if (p) {
00353 if (p[1]==32 || p[1]==9)
00354
00355 *p=32;
00356 p++;
00357 }
00358 }
00359
00360
00361 p=buf;
00362 while(p && *p) {
00363 char *pNext;
00364 char *pVarBegin;
00365 char *pVarEnd;
00366
00367
00368 pNext=strchr(p, 10);
00369 if (pNext) {
00370 *pNext=0;
00371 pNext++;
00372 }
00373 while(*p && (*p==32 || *p==9))
00374 p++;
00375 if (*p) {
00376 pVarBegin=p;
00377 while(*p && *p!=':' && *p>32 && *p<127)
00378 p++;
00379 pVarEnd=p;
00380 if (*p!=':') {
00381 DBG_INFO(GWEN_LOGDOMAIN, "No separator after variable name in received header");
00382 return GWEN_ERROR_BAD_DATA;
00383 }
00384 *pVarEnd=0;
00385 p++;
00386
00387 while(*p && (*p==32 || *p==9))
00388 p++;
00389 if (*p)
00390 GWEN_DB_SetCharValue(xio->dbHeaderIn, GWEN_PATH_FLAGS_CREATE_VAR, pVarBegin, p);
00391 }
00392 p=pNext;
00393 }
00394
00395
00396
00397 xio->readMode=GWEN_Io_LayerHttp_Mode_Body;
00398
00399
00400 s=GWEN_DB_GetCharValue(xio->dbHeaderIn, "Transfer-Encoding", 0, 0);
00401 if (s && (-1!=GWEN_Text_ComparePattern(s, "*chunked*", 0))) {
00402
00403 xio->currentReadChunkSize=-1;
00404 xio->readMode=GWEN_Io_LayerHttp_Mode_ChunkSize;
00405 }
00406
00407
00408 xio->currentReadBodySize=GWEN_DB_GetIntValue(xio->dbHeaderIn, "Content-Length", 0, -1);
00409 if (xio->currentReadBodySize==0) {
00410
00411 xio->readMode=GWEN_Io_LayerHttp_Mode_Finished;
00412 }
00413 if (xio->currentReadBodySize==-1) {
00414 int rcode;
00415
00416
00417
00418
00419
00420 rcode=GWEN_DB_GetIntValue(xio->dbStatusIn, "code", 0, -1);
00421 if (rcode<0 || rcode>=300) {
00422
00423 xio->readMode=GWEN_Io_LayerHttp_Mode_Finished;
00424 }
00425 }
00426
00427 return 0;
00428 }
00429
00430
00431
00432 int GWEN_Io_LayerHttp_WriteCommand(GWEN_IO_LAYER *io, GWEN_BUFFER *buf) {
00433 GWEN_IO_LAYER_HTTP *xio;
00434 const char *s;
00435
00436 assert(io);
00437 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00438 assert(xio);
00439
00440 s=GWEN_DB_GetCharValue(xio->dbCommandOut, "command", 0, "GET");
00441 GWEN_Buffer_AppendString(buf, s);
00442 GWEN_Buffer_AppendString(buf, " ");
00443
00444 s=GWEN_DB_GetCharValue(xio->dbCommandOut, "url", 0, "/");
00445 GWEN_Buffer_AppendString(buf, s);
00446 GWEN_Buffer_AppendString(buf, " ");
00447
00448 s=GWEN_DB_GetCharValue(xio->dbCommandOut, "protocol", 0, "HTTP/1.0");
00449 GWEN_Buffer_AppendString(buf, s);
00450 GWEN_Buffer_AppendString(buf, "\r\n");
00451
00452 return 0;
00453 }
00454
00455
00456
00457 int GWEN_Io_LayerHttp_WriteStatus(GWEN_IO_LAYER *io, GWEN_BUFFER *buf) {
00458 GWEN_IO_LAYER_HTTP *xio;
00459 const char *s;
00460 int i;
00461 char numbuf[32];
00462
00463 assert(io);
00464 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00465 assert(xio);
00466
00467 s=GWEN_DB_GetCharValue(xio->dbStatusOut, "protocol", 0, "HTTP/1.0");
00468 GWEN_Buffer_AppendString(buf, s);
00469 GWEN_Buffer_AppendString(buf, " ");
00470
00471 i=GWEN_DB_GetIntValue(xio->dbStatusOut, "code", 0, -1);
00472 if (i==-1) {
00473 DBG_INFO(GWEN_LOGDOMAIN, "Missing status code");
00474 return GWEN_ERROR_NO_DATA;
00475 }
00476 snprintf(numbuf, sizeof(numbuf), "%d ", i);
00477 GWEN_Buffer_AppendString(buf, numbuf);
00478
00479 s=GWEN_DB_GetCharValue(xio->dbStatusOut, "text", 0, "No text.");
00480 GWEN_Buffer_AppendString(buf, s);
00481 GWEN_Buffer_AppendString(buf, "\r\n");
00482
00483 return 0;
00484 }
00485
00486
00487
00488 int GWEN_Io_LayerHttp_WriteHeader(GWEN_IO_LAYER *io, GWEN_BUFFER *buf) {
00489 GWEN_IO_LAYER_HTTP *xio;
00490 int i;
00491 GWEN_DB_NODE *dbVar;
00492
00493 assert(io);
00494 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00495 assert(xio);
00496
00497 i=GWEN_DB_GetIntValue(xio->dbHeaderOut, "Content-Length", 0, -1);
00498 if (i!=-1)
00499 xio->currentWriteBodySize=i;
00500
00501 dbVar=GWEN_DB_GetFirstVar(xio->dbHeaderOut);
00502 while (dbVar) {
00503 GWEN_DB_NODE *dbVal;
00504
00505
00506 dbVal=GWEN_DB_GetFirstValue(dbVar);
00507 if (dbVal) {
00508 GWEN_DB_NODE_TYPE vtype;
00509
00510 vtype=GWEN_DB_GetValueType(dbVal);
00511 if (vtype==GWEN_DB_NodeType_ValueChar) {
00512 const char *s;
00513
00514 GWEN_Buffer_AppendString(buf, GWEN_DB_VariableName(dbVar));
00515 GWEN_Buffer_AppendString(buf, ":");
00516 s=GWEN_DB_GetCharValueFromNode(dbVal);
00517 if (s)
00518 GWEN_Buffer_AppendString(buf, s);
00519 GWEN_Buffer_AppendString(buf, "\r\n");
00520 }
00521 else if (vtype==GWEN_DB_NodeType_ValueInt) {
00522 i=GWEN_DB_GetIntValueFromNode(dbVal);
00523 if (i!=-1 || strcasecmp(GWEN_DB_VariableName(dbVar), "Content-Length")==0) {
00524 char numbuf[32];
00525
00526
00527 GWEN_Buffer_AppendString(buf, GWEN_DB_VariableName(dbVar));
00528 GWEN_Buffer_AppendString(buf, ":");
00529 snprintf(numbuf, sizeof(numbuf), "%d", i);
00530 GWEN_Buffer_AppendString(buf, numbuf);
00531 GWEN_Buffer_AppendString(buf, "\r\n");
00532 }
00533 }
00534 else {
00535 DBG_INFO(GWEN_LOGDOMAIN, "Variable type %d of var [%s] not supported",
00536 vtype, GWEN_DB_VariableName(dbVar));
00537 return GWEN_ERROR_BAD_DATA;
00538 }
00539 }
00540 dbVar=GWEN_DB_GetNextVar(dbVar);
00541 }
00542
00543
00544 GWEN_Buffer_AppendString(buf, "\r\n");
00545
00546 return 0;
00547 }
00548
00549
00550
00551 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnReadRequest1(GWEN_IO_LAYER *io) {
00552 GWEN_IO_LAYER_HTTP *xio;
00553 int doneSomething=0;
00554
00555 assert(io);
00556 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00557 assert(xio);
00558
00559 DBG_VERBOUS(GWEN_LOGDOMAIN, "GWEN_Io_LayerHttp_WorkOnReadRequest1 (%d)", xio->readMode);
00560
00561 if (xio->readRequestOut) {
00562
00563 if (GWEN_Io_Request_GetStatus(xio->readRequestOut)==GWEN_Io_Request_StatusFinished) {
00564 uint32_t bpos;
00565 uint32_t flags;
00566
00567 doneSomething=1;
00568
00569
00570 xio->lastReadOutResult=GWEN_Io_Request_GetResultCode(xio->readRequestOut);
00571 flags=GWEN_Io_Request_GetFlags(xio->readRequestOut);
00572 bpos=GWEN_Io_Request_GetBufferPos(xio->readRequestOut);
00573
00574
00575 GWEN_Buffer_IncrementPos(xio->readBuffer, bpos);
00576 GWEN_Buffer_AdjustUsedBytes(xio->readBuffer);
00577
00578 if (flags & GWEN_IO_REQUEST_FLAGS_PACKETEND) {
00579 xio->readLineFinished=1;
00580 }
00581
00582 DBG_VERBOUS(GWEN_LOGDOMAIN, "Received %d bytes (%s)",
00583 bpos, (xio->readLineFinished)?"line finished":"line open");
00584
00585
00586 GWEN_Io_Request_free(xio->readRequestOut);
00587 xio->readRequestOut=NULL;
00588 }
00589 }
00590
00591 if (xio->readRequestIn) {
00592 GWEN_IO_REQUEST *rIn;
00593
00594 rIn=xio->readRequestIn;
00595 if (xio->readLineFinished==0) {
00596 if (xio->readRequestOut==NULL) {
00597 int rv;
00598
00599 if (xio->lastReadOutResult) {
00600 xio->readRequestIn=NULL;
00601 DBG_INFO(GWEN_LOGDOMAIN, "Aborting out read request (reason: %d)",
00602 xio->lastReadOutResult);
00603 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, xio->lastReadOutResult);
00604 GWEN_Io_Request_free(rIn);
00605 rIn=NULL;
00606 doneSomething=1;
00607 }
00608 else {
00609 rv=GWEN_Buffer_AllocRoom(xio->readBuffer, GWEN_IO_LAYER_HTTP_LINE_STEPSIZE);
00610 if (rv<0) {
00611 xio->readRequestIn=NULL;
00612 xio->lastReadOutResult=GWEN_ERROR_MEMORY_FULL;
00613 DBG_INFO(GWEN_LOGDOMAIN, "Aborting out read request (reason: %d)",
00614 xio->lastReadOutResult);
00615 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, GWEN_ERROR_MEMORY_FULL);
00616 GWEN_Io_Request_free(rIn);
00617 rIn=NULL;
00618 doneSomething=1;
00619 }
00620 else {
00621 GWEN_IO_REQUEST *rOut;
00622
00623 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %d header bytes", GWEN_IO_LAYER_HTTP_LINE_STEPSIZE);
00624 rOut=GWEN_Io_Request_new(GWEN_Io_Request_TypeRead,
00625 (uint8_t*)GWEN_Buffer_GetPosPointer(xio->readBuffer),
00626 GWEN_IO_LAYER_HTTP_LINE_STEPSIZE,
00627 NULL, NULL,
00628 GWEN_Io_Request_GetGuiId(rIn));
00629 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), rOut);
00630 if (rv) {
00631 if (rv!=GWEN_ERROR_TRY_AGAIN) {
00632 GWEN_Io_Request_free(rOut);
00633 xio->readRequestIn=NULL;
00634 xio->lastReadOutResult=rv;
00635 DBG_INFO(GWEN_LOGDOMAIN,
00636 "Aborting out read request (reason: %d)",
00637 xio->lastReadOutResult);
00638 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
00639 GWEN_Io_Request_free(rIn);
00640 rIn=NULL;
00641 doneSomething=1;
00642 }
00643 }
00644 else {
00645 DBG_DEBUG(GWEN_LOGDOMAIN, "Added header read request");
00646 xio->readRequestOut=rOut;
00647 doneSomething=1;
00648 }
00649 }
00650 }
00651 }
00652 }
00653 else {
00654 int rv;
00655
00656
00657 doneSomething=1;
00658 xio->readLineFinished=0;
00659 switch(xio->readMode) {
00660 case GWEN_Io_LayerHttp_Mode_Command:
00661 DBG_DEBUG(GWEN_LOGDOMAIN, "Command received: [%s]", GWEN_Buffer_GetStart(xio->readBuffer));
00662 rv=GWEN_Io_LayerHttp_ParseCommand(io, GWEN_Buffer_GetStart(xio->readBuffer));
00663 if (rv) {
00664 xio->lastReadOutResult=rv;
00665 xio->readRequestIn=NULL;
00666 DBG_INFO(GWEN_LOGDOMAIN,
00667 "Aborting in read request (reason: %d)",
00668 xio->lastReadOutResult);
00669 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
00670 GWEN_Io_Request_free(rIn);
00671 rIn=NULL;
00672 }
00673 else {
00674 xio->lastHeaderPos=0;
00675 xio->readMode=GWEN_Io_LayerHttp_Mode_Header;
00676 }
00677 GWEN_Buffer_Reset(xio->readBuffer);
00678 break;
00679
00680 case GWEN_Io_LayerHttp_Mode_Status:
00681 DBG_DEBUG(GWEN_LOGDOMAIN, "Status received: [%s]", GWEN_Buffer_GetStart(xio->readBuffer));
00682 rv=GWEN_Io_LayerHttp_ParseStatus(io, GWEN_Buffer_GetStart(xio->readBuffer));
00683 if (rv) {
00684 xio->lastReadOutResult=rv;
00685 xio->readRequestIn=NULL;
00686 DBG_INFO(GWEN_LOGDOMAIN,
00687 "Aborting in read request (reason: %d)",
00688 xio->lastReadOutResult);
00689 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
00690 GWEN_Io_Request_free(rIn);
00691 rIn=NULL;
00692 }
00693 else {
00694 xio->lastHeaderPos=0;
00695 xio->readMode=GWEN_Io_LayerHttp_Mode_Header;
00696 }
00697 GWEN_Buffer_Reset(xio->readBuffer);
00698 break;
00699
00700 case GWEN_Io_LayerHttp_Mode_Header: {
00701 uint32_t i;
00702
00703 DBG_DEBUG(GWEN_LOGDOMAIN, "Header received: [%s]",
00704 GWEN_Buffer_GetStart(xio->readBuffer)+xio->lastHeaderPos);
00705 i=GWEN_Buffer_GetUsedBytes(xio->readBuffer);
00706
00707 GWEN_Buffer_AppendByte(xio->readBuffer, 10);
00708 if ((i-xio->lastHeaderPos)==0) {
00709
00710
00711 DBG_DEBUG(GWEN_LOGDOMAIN, "Parsing header");
00712 rv=GWEN_Io_LayerHttp_ParseHeader(io, GWEN_Buffer_GetStart(xio->readBuffer));
00713 if (rv<0) {
00714 xio->lastReadOutResult=rv;
00715 xio->readRequestIn=NULL;
00716 DBG_INFO(GWEN_LOGDOMAIN,
00717 "Aborting in read request (reason: %d)",
00718 xio->lastReadOutResult);
00719 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
00720 GWEN_Io_Request_free(rIn);
00721 rIn=NULL;
00722 }
00723 GWEN_Buffer_Reset(xio->readBuffer);
00724 }
00725 else {
00726 DBG_DEBUG(GWEN_LOGDOMAIN, "Awaiting next header");
00727 xio->lastHeaderPos=i+1;
00728 if (xio->readRequestOut==NULL) {
00729 int rv;
00730
00731 if (xio->lastReadOutResult) {
00732 xio->readRequestIn=NULL;
00733 DBG_INFO(GWEN_LOGDOMAIN,
00734 "Aborting in read request (reason: %d)",
00735 xio->lastReadOutResult);
00736 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, xio->lastReadOutResult);
00737 GWEN_Io_Request_free(rIn);
00738 rIn=NULL;
00739 doneSomething=1;
00740 }
00741 else {
00742
00743 rv=GWEN_Buffer_AllocRoom(xio->readBuffer, GWEN_IO_LAYER_HTTP_LINE_STEPSIZE);
00744 if (rv<0) {
00745 xio->readRequestIn=NULL;
00746 xio->lastReadOutResult=GWEN_ERROR_MEMORY_FULL;
00747 DBG_INFO(GWEN_LOGDOMAIN,
00748 "Aborting in read request (reason: %d)",
00749 xio->lastReadOutResult);
00750 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, GWEN_ERROR_MEMORY_FULL);
00751 GWEN_Io_Request_free(rIn);
00752 rIn=NULL;
00753 doneSomething=1;
00754 }
00755 else {
00756 GWEN_IO_REQUEST *rOut;
00757
00758 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %d header bytes", GWEN_IO_LAYER_HTTP_LINE_STEPSIZE);
00759 rOut=GWEN_Io_Request_new(GWEN_Io_Request_TypeRead,
00760 (uint8_t*)GWEN_Buffer_GetPosPointer(xio->readBuffer),
00761 GWEN_IO_LAYER_HTTP_LINE_STEPSIZE,
00762 NULL, NULL,
00763 GWEN_Io_Request_GetGuiId(rIn));
00764 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), rOut);
00765 if (rv) {
00766 if (rv!=GWEN_ERROR_TRY_AGAIN) {
00767 GWEN_Io_Request_free(rOut);
00768 xio->readRequestIn=NULL;
00769 xio->lastReadOutResult=rv;
00770 DBG_INFO(GWEN_LOGDOMAIN,
00771 "Aborting in read request (reason: %d)",
00772 xio->lastReadOutResult);
00773 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
00774 GWEN_Io_Request_free(rIn);
00775 rIn=NULL;
00776 doneSomething=1;
00777 }
00778 }
00779 else {
00780 DBG_DEBUG(GWEN_LOGDOMAIN, "Added header read request");
00781 xio->readRequestOut=rOut;
00782 doneSomething=1;
00783 }
00784 }
00785 }
00786 }
00787 }
00788 break;
00789 }
00790
00791 case GWEN_Io_LayerHttp_Mode_ChunkSize: {
00792 int csize;
00793
00794 if (GWEN_Buffer_GetUsedBytes(xio->readBuffer)==0) {
00795 DBG_INFO(GWEN_LOGDOMAIN, "Empty line, skipping");
00796 }
00797 else {
00798 if (1!=sscanf(GWEN_Buffer_GetStart(xio->readBuffer), "%x", &csize)) {
00799 DBG_INFO(GWEN_LOGDOMAIN, "Invalid chunksize [%s]", GWEN_Buffer_GetStart(xio->readBuffer));
00800 xio->lastReadOutResult=GWEN_ERROR_BAD_DATA;
00801 xio->readRequestIn=NULL;
00802 DBG_INFO(GWEN_LOGDOMAIN,
00803 "Aborting in read request (reason: %d)",
00804 xio->lastReadOutResult);
00805 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, GWEN_ERROR_BAD_DATA);
00806 GWEN_Io_Request_free(rIn);
00807 rIn=NULL;
00808 }
00809 else {
00810 xio->currentReadChunkSize=csize;
00811 DBG_DEBUG(GWEN_LOGDOMAIN, "Chunksize: %d", csize);
00812 if (csize==0) {
00813 DBG_DEBUG(GWEN_LOGDOMAIN, "Last chunk received");
00814 xio->readMode=GWEN_Io_LayerHttp_Mode_Finished;
00815 GWEN_Io_Request_AddFlags(rIn, GWEN_IO_REQUEST_FLAGS_PACKETEND);
00816 }
00817 else {
00818 DBG_DEBUG(GWEN_LOGDOMAIN, "Started reading next chunk (%d bytes)",
00819 csize);
00820 xio->readMode=GWEN_Io_LayerHttp_Mode_Chunk;
00821 }
00822 }
00823 }
00824 break;
00825 }
00826
00827 default:
00828
00829 assert(0);
00830 break;
00831 }
00832 }
00833 }
00834
00835 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00836 }
00837
00838
00839
00840 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnReadRequest2(GWEN_IO_LAYER *io) {
00841 GWEN_IO_LAYER_HTTP *xio;
00842 int doneSomething=0;
00843
00844 assert(io);
00845 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
00846 assert(xio);
00847
00848 DBG_VERBOUS(GWEN_LOGDOMAIN, "GWEN_Io_LayerHttp_WorkOnReadRequest2 (%d)", xio->readMode);
00849
00850 if (xio->readRequestOut) {
00851
00852 if (GWEN_Io_Request_GetStatus(xio->readRequestOut)==GWEN_Io_Request_StatusFinished) {
00853 GWEN_IO_REQUEST *rOut;
00854 uint32_t bposOut;
00855 uint32_t flagsOut;
00856
00857 rOut=xio->readRequestOut;
00858 flagsOut=GWEN_Io_Request_GetFlags(rOut);
00859 bposOut=GWEN_Io_Request_GetBufferPos(rOut);
00860
00861 doneSomething=1;
00862
00863 if (xio->readRequestIn) {
00864 GWEN_IO_REQUEST *rIn;
00865 uint32_t bposIn;
00866 uint32_t flagsIn;
00867
00868 rIn=xio->readRequestIn;
00869 flagsIn=GWEN_Io_Request_GetFlags(rIn);
00870 bposIn=GWEN_Io_Request_GetBufferPos(rIn);
00871
00872 DBG_VERBOUS(GWEN_LOGDOMAIN, "Received %d (total: %d) bytes", bposIn, bposIn+bposOut);
00873
00874
00875 xio->lastReadOutResult=GWEN_Io_Request_GetResultCode(xio->readRequestOut);
00876
00877
00878 GWEN_Io_Request_free(xio->readRequestOut);
00879 xio->readRequestOut=NULL;
00880
00881
00882 bposIn+=bposOut;
00883 GWEN_Io_Request_SetBufferPos(rIn, bposIn);
00884
00885 if (xio->currentReadBodySize!=-1) {
00886 xio->currentReadBodySize-=bposOut;
00887 }
00888
00889 if (xio->readMode==GWEN_Io_LayerHttp_Mode_Chunk) {
00890 xio->currentReadChunkSize-=bposOut;
00891 }
00892
00893 if (xio->currentReadBodySize==0) {
00894
00895 GWEN_Io_Request_AddFlags(rIn, GWEN_IO_REQUEST_FLAGS_PACKETEND);
00896 xio->readMode=GWEN_Io_LayerHttp_Mode_Finished;
00897 }
00898 else {
00899 if (xio->readMode==GWEN_Io_LayerHttp_Mode_Chunk && xio->currentReadChunkSize==0) {
00900
00901 DBG_DEBUG(GWEN_LOGDOMAIN, "Chunk finished");
00902 xio->currentReadChunkSize=-1;
00903 xio->readMode=GWEN_Io_LayerHttp_Mode_ChunkSize;
00904 xio->readLineFinished=0;
00905 GWEN_Buffer_Reset(xio->readBuffer);
00906 doneSomething=1;
00907 }
00908 }
00909 }
00910 }
00911 }
00912
00913 if (xio->readRequestIn) {
00914 GWEN_IO_REQUEST *rIn;
00915 uint32_t flagsIn;
00916
00917 rIn=xio->readRequestIn;
00918 flagsIn=GWEN_Io_Request_GetFlags(rIn);
00919
00920 if (xio->readMode==GWEN_Io_LayerHttp_Mode_Finished) {
00921 uint32_t bposIn;
00922
00923 GWEN_Io_Request_AddFlags(rIn, GWEN_IO_REQUEST_FLAGS_PACKETEND);
00924 bposIn=GWEN_Io_Request_GetBufferPos(rIn);
00925 if (bposIn<GWEN_Io_Request_GetBufferSize(rIn) &&
00926 (flagsIn & GWEN_IO_REQUEST_FLAGS_READALL)) {
00927
00928 xio->readRequestIn=NULL;
00929 DBG_INFO(GWEN_LOGDOMAIN,
00930 "Aborting in read request (reason: %d)",
00931 GWEN_ERROR_BAD_SIZE);
00932 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, GWEN_ERROR_BAD_SIZE);
00933 GWEN_Io_Request_free(rIn);
00934 rIn=NULL;
00935 }
00936 else {
00937
00938 xio->readRequestIn=NULL;
00939 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, 0);
00940 GWEN_Io_Request_free(rIn);
00941 rIn=NULL;
00942 }
00943 xio->readMode=GWEN_Io_LayerHttp_Mode_Idle;
00944 doneSomething=1;
00945 }
00946 else if (xio->readMode==GWEN_Io_LayerHttp_Mode_ChunkSize) {
00947
00948
00949 }
00950 else {
00951 uint32_t len;
00952 uint32_t bposIn;
00953
00954 bposIn=GWEN_Io_Request_GetBufferPos(rIn);
00955 len=GWEN_Io_Request_GetBufferSize(rIn)-bposIn;
00956 if (len==0) {
00957
00958 xio->readRequestIn=NULL;
00959 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, 0);
00960 GWEN_Io_Request_free(rIn);
00961 rIn=NULL;
00962 doneSomething=1;
00963 }
00964 else {
00965 if (xio->readRequestOut==NULL) {
00966 if (xio->lastReadOutResult) {
00967 xio->readRequestIn=NULL;
00968 DBG_INFO(GWEN_LOGDOMAIN,
00969 "Aborting in read request (reason: %d)",
00970 xio->lastReadOutResult);
00971 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, xio->lastReadOutResult);
00972 GWEN_Io_Request_free(rIn);
00973 rIn=NULL;
00974 doneSomething=1;
00975 }
00976 else {
00977 if (xio->readMode==GWEN_Io_LayerHttp_Mode_Chunk &&
00978 xio->currentReadChunkSize!=-1 &&
00979 len>xio->currentReadChunkSize)
00980 len=xio->currentReadChunkSize;
00981 else if (xio->readMode==GWEN_Io_LayerHttp_Mode_Body &&
00982 xio->currentReadBodySize!=-1 &&
00983 len>xio->currentReadBodySize)
00984 len=xio->currentReadBodySize;
00985
00986 if (len) {
00987 GWEN_IO_REQUEST *rOut;
00988 int rv;
00989
00990 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reading %d body bytes (already have %d/%d)",
00991 len, bposIn, GWEN_Io_Request_GetBufferSize(rIn));
00992 rOut=GWEN_Io_Request_new(GWEN_Io_Request_TypeRead,
00993 GWEN_Io_Request_GetBufferPtr(rIn)+bposIn, len,
00994 NULL, NULL,
00995 GWEN_Io_Request_GetGuiId(rIn));
00996 GWEN_Io_Request_AddFlags(rOut, GWEN_IO_REQUEST_BUFFERED_FLAGS_RAW);
00997 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), rOut);
00998 if (rv) {
00999 GWEN_Io_Request_free(rOut);
01000 if (rv!=GWEN_ERROR_TRY_AGAIN) {
01001 xio->lastReadOutResult=rv;
01002 xio->readRequestIn=NULL;
01003 DBG_INFO(GWEN_LOGDOMAIN,
01004 "Aborting in read request (reason: %d)",
01005 xio->lastReadOutResult);
01006 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
01007 GWEN_Io_Request_free(rIn);
01008 rIn=NULL;
01009 doneSomething=1;
01010 }
01011 }
01012 else {
01013 xio->readRequestOut=rOut;
01014 doneSomething=1;
01015 }
01016 }
01017 else {
01018 if (xio->currentReadBodySize==0)
01019 xio->readMode=GWEN_Io_LayerHttp_Mode_Finished;
01020 if (xio->currentReadChunkSize==0) {
01021 xio->currentReadChunkSize=-1;
01022 xio->readMode=GWEN_Io_LayerHttp_Mode_ChunkSize;
01023 }
01024 }
01025 }
01026 }
01027 }
01028 }
01029 }
01030
01031 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
01032 }
01033
01034
01035
01036 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnReadRequest(GWEN_IO_LAYER *io) {
01037 GWEN_IO_LAYER_HTTP *xio;
01038
01039 assert(io);
01040 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01041 assert(xio);
01042
01043 DBG_VERBOUS(GWEN_LOGDOMAIN, "GWEN_Io_LayerHttp_WorkOnReadRequest (%d)", xio->readMode);
01044
01045 switch(xio->readMode) {
01046 case GWEN_Io_LayerHttp_Mode_Command:
01047 case GWEN_Io_LayerHttp_Mode_Status:
01048 case GWEN_Io_LayerHttp_Mode_Header:
01049 case GWEN_Io_LayerHttp_Mode_ChunkSize:
01050 return GWEN_Io_LayerHttp_WorkOnReadRequest1(io);
01051
01052 case GWEN_Io_LayerHttp_Mode_Chunk:
01053 case GWEN_Io_LayerHttp_Mode_Body:
01054 case GWEN_Io_LayerHttp_Mode_Finished:
01055 default:
01056 return GWEN_Io_LayerHttp_WorkOnReadRequest2(io);
01057 }
01058 }
01059
01060
01061
01062
01063 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnWriteRequest1(GWEN_IO_LAYER *io) {
01064 GWEN_IO_LAYER_HTTP *xio;
01065 int doneSomething=0;
01066
01067 assert(io);
01068 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01069 assert(xio);
01070
01071 DBG_VERBOUS(GWEN_LOGDOMAIN, "GWEN_Io_LayerHttp_WorkOnWriteRequest1 (%d)", xio->writeMode);
01072
01073 if (xio->writeRequestOut) {
01074 if (GWEN_Io_Request_GetStatus(xio->writeRequestOut)==GWEN_Io_Request_StatusFinished) {
01075 GWEN_IO_REQUEST *rOut;
01076 uint32_t bposOut;
01077 uint32_t flagsOut;
01078
01079 rOut=xio->writeRequestOut;
01080 flagsOut=GWEN_Io_Request_GetFlags(rOut);
01081 bposOut=GWEN_Io_Request_GetBufferPos(rOut);
01082
01083 DBG_VERBOUS(GWEN_LOGDOMAIN, "Sent %d bytes", bposOut);
01084
01085 GWEN_Buffer_IncrementPos(xio->writeBuffer, bposOut);
01086 xio->lastWriteOutResult=GWEN_Io_Request_GetResultCode(xio->writeRequestOut);
01087
01088
01089 GWEN_Io_Request_free(xio->writeRequestOut);
01090 xio->writeRequestOut=NULL;
01091
01092 doneSomething=1;
01093 }
01094 }
01095
01096 if (xio->writeRequestIn) {
01097 GWEN_IO_REQUEST *rIn;
01098
01099 rIn=xio->writeRequestIn;
01100 if (GWEN_Buffer_GetBytesLeft(xio->writeBuffer)) {
01101 if (xio->writeRequestOut==NULL) {
01102 if (xio->lastWriteOutResult) {
01103 xio->writeRequestIn=NULL;
01104 DBG_INFO(GWEN_LOGDOMAIN,
01105 "Aborting in write request (reason: %d)",
01106 xio->lastWriteOutResult);
01107 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, xio->lastWriteOutResult);
01108 GWEN_Io_Request_free(rIn);
01109 rIn=NULL;
01110 doneSomething=1;
01111 }
01112 else {
01113 GWEN_IO_REQUEST *rOut;
01114 int rv;
01115
01116 DBG_VERBOUS(GWEN_LOGDOMAIN, "Sending %d header bytes", GWEN_Buffer_GetBytesLeft(xio->writeBuffer));
01117 rOut=GWEN_Io_Request_new(GWEN_Io_Request_TypeWrite,
01118 (uint8_t*)GWEN_Buffer_GetPosPointer(xio->writeBuffer),
01119 GWEN_Buffer_GetBytesLeft(xio->writeBuffer),
01120 NULL, NULL,
01121 GWEN_Io_Request_GetGuiId(rIn));
01122 GWEN_Io_Request_AddFlags(rOut,
01123 GWEN_IO_REQUEST_BUFFERED_FLAGS_RAW |
01124 GWEN_IO_REQUEST_FLAGS_FLUSH |
01125 GWEN_IO_REQUEST_FLAGS_WRITEALL);
01126 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), rOut);
01127 if (rv) {
01128 GWEN_Io_Request_free(rOut);
01129 if (rv!=GWEN_ERROR_TRY_AGAIN) {
01130 xio->lastWriteOutResult=rv;
01131 xio->writeRequestIn=NULL;
01132 DBG_INFO(GWEN_LOGDOMAIN,
01133 "Aborting in write request (reason: %d)",
01134 xio->lastWriteOutResult);
01135 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
01136 GWEN_Io_Request_free(rIn);
01137 rIn=NULL;
01138 doneSomething=1;
01139 }
01140 }
01141 else {
01142 xio->writeRequestOut=rOut;
01143 doneSomething=1;
01144 }
01145 }
01146 }
01147 }
01148 else {
01149
01150 GWEN_Buffer_Reset(xio->writeBuffer);
01151 if (xio->currentWriteBodySize!=0)
01152
01153 xio->writeMode=GWEN_Io_LayerHttp_Mode_Body;
01154 else
01155
01156 xio->writeMode=GWEN_Io_LayerHttp_Mode_Finished;
01157 }
01158 }
01159
01160
01161 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
01162 }
01163
01164
01165
01166
01167 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnWriteRequest2(GWEN_IO_LAYER *io) {
01168 GWEN_IO_LAYER_HTTP *xio;
01169 int doneSomething=0;
01170
01171 assert(io);
01172 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01173 assert(xio);
01174
01175 DBG_VERBOUS(GWEN_LOGDOMAIN, "GWEN_Io_LayerHttp_WorkOnWriteRequest2 (%d)", xio->writeMode);
01176
01177 if (xio->writeRequestOut) {
01178 if (GWEN_Io_Request_GetStatus(xio->writeRequestOut)==GWEN_Io_Request_StatusFinished) {
01179 GWEN_IO_REQUEST *rOut;
01180
01181 doneSomething=1;
01182 rOut=xio->writeRequestOut;
01183 if (xio->writeRequestIn) {
01184 uint32_t bposOut;
01185 uint32_t flagsOut;
01186 GWEN_IO_REQUEST *rIn;
01187 uint32_t bposIn;
01188 uint32_t flagsIn;
01189
01190 rOut=xio->writeRequestOut;
01191 flagsOut=GWEN_Io_Request_GetFlags(rOut);
01192 bposOut=GWEN_Io_Request_GetBufferPos(rOut);
01193
01194 rIn=xio->writeRequestIn;
01195 flagsIn=GWEN_Io_Request_GetFlags(rIn);
01196 bposIn=GWEN_Io_Request_GetBufferPos(rIn)+bposOut;
01197 GWEN_Io_Request_SetBufferPos(rIn, bposIn);
01198
01199 DBG_VERBOUS(GWEN_LOGDOMAIN, "Sent %d body bytes (%d)",
01200 bposOut, GWEN_Io_Request_GetResultCode(rOut));
01201
01202
01203 xio->lastWriteOutResult=GWEN_Io_Request_GetResultCode(rOut);
01204
01205
01206 GWEN_Io_Request_free(xio->writeRequestOut);
01207 xio->writeRequestOut=NULL;
01208
01209 if (xio->currentWriteBodySize!=-1)
01210 xio->currentWriteBodySize-=bposOut;
01211
01212
01213 if (xio->currentWriteBodySize==0) {
01214
01215 GWEN_Io_Request_AddFlags(rIn, GWEN_IO_REQUEST_FLAGS_PACKETEND);
01216 xio->writeMode=GWEN_Io_LayerHttp_Mode_Finished;
01217 if (bposIn<GWEN_Io_Request_GetBufferSize(rIn) &&
01218 (flagsIn & GWEN_IO_REQUEST_FLAGS_WRITEALL)) {
01219
01220 xio->writeRequestIn=NULL;
01221 DBG_INFO(GWEN_LOGDOMAIN,
01222 "Aborting in write request (reason: %d)",
01223 GWEN_ERROR_BAD_SIZE);
01224 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, GWEN_ERROR_BAD_SIZE);
01225 GWEN_Io_Request_free(rIn);
01226 rIn=NULL;
01227 }
01228 }
01229 else {
01230
01231 if (bposIn>=GWEN_Io_Request_GetBufferSize(rIn) ||
01232 (bposIn && !(flagsIn & GWEN_IO_REQUEST_FLAGS_WRITEALL))) {
01233
01234 xio->writeRequestIn=NULL;
01235 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, 0);
01236 GWEN_Io_Request_free(rIn);
01237 rIn=NULL;
01238 }
01239 }
01240 }
01241 }
01242 }
01243
01244 if (xio->writeRequestIn) {
01245 GWEN_IO_REQUEST *rIn;
01246
01247 rIn=xio->writeRequestIn;
01248 if (xio->writeRequestOut==NULL) {
01249 if (xio->lastWriteOutResult) {
01250 xio->writeRequestIn=NULL;
01251 DBG_INFO(GWEN_LOGDOMAIN,
01252 "Aborting in write request (reason: %d)",
01253 xio->lastWriteOutResult);
01254 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, xio->lastWriteOutResult);
01255 GWEN_Io_Request_free(rIn);
01256 rIn=NULL;
01257 doneSomething=1;
01258 }
01259 else {
01260 int len;
01261 int bpos;
01262
01263
01264 bpos=GWEN_Io_Request_GetBufferPos(rIn);
01265 len=GWEN_Io_Request_GetBufferSize(rIn)-bpos;
01266 if (xio->currentWriteBodySize!=-1 && len>xio->currentWriteBodySize)
01267
01268 len=xio->currentWriteBodySize;
01269
01270 if (len==0) {
01271 if (xio->currentWriteBodySize==0)
01272 GWEN_Io_Request_AddFlags(rIn, GWEN_IO_REQUEST_FLAGS_PACKETEND);
01273 xio->writeRequestIn=NULL;
01274 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, 0);
01275 GWEN_Io_Request_free(rIn);
01276 rIn=NULL;
01277 doneSomething=1;
01278 }
01279 else {
01280 GWEN_IO_REQUEST *rOut;
01281 int rv;
01282
01283
01284 DBG_VERBOUS(GWEN_LOGDOMAIN, "Sending %d body bytes", len);
01285 rOut=GWEN_Io_Request_new(GWEN_Io_Request_TypeWrite,
01286 GWEN_Io_Request_GetBufferPtr(rIn)+bpos, len,
01287 NULL, NULL,
01288 GWEN_Io_Request_GetGuiId(rIn));
01289 GWEN_Io_Request_AddFlags(rOut,
01290 GWEN_IO_REQUEST_BUFFERED_FLAGS_RAW |
01291 GWEN_IO_REQUEST_FLAGS_FLUSH |
01292 GWEN_IO_REQUEST_FLAGS_WRITEALL);
01293 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), rOut);
01294 if (rv) {
01295 GWEN_Io_Request_free(rOut);
01296 if (rv!=GWEN_ERROR_TRY_AGAIN) {
01297 xio->lastWriteOutResult=rv;
01298 xio->writeRequestIn=NULL;
01299 DBG_INFO(GWEN_LOGDOMAIN,
01300 "Aborting in write request (reason: %d)",
01301 xio->lastWriteOutResult);
01302 GWEN_Io_Request_Finished(rIn, GWEN_Io_Request_StatusFinished, rv);
01303 GWEN_Io_Request_free(rIn);
01304 rIn=NULL;
01305 doneSomething=1;
01306 }
01307 }
01308 else {
01309 xio->writeRequestOut=rOut;
01310 doneSomething=1;
01311 }
01312 }
01313 }
01314 }
01315
01316
01317 }
01318
01319
01320 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
01321 }
01322
01323
01324
01325 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnWriteRequest(GWEN_IO_LAYER *io) {
01326 GWEN_IO_LAYER_HTTP *xio;
01327
01328 assert(io);
01329 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01330 assert(xio);
01331
01332 DBG_VERBOUS(GWEN_LOGDOMAIN, "GWEN_Io_LayerHttp_WorkOnWriteRequest (%d)", xio->writeMode);
01333
01334 switch(xio->writeMode) {
01335 case GWEN_Io_LayerHttp_Mode_Command:
01336 case GWEN_Io_LayerHttp_Mode_Status:
01337 case GWEN_Io_LayerHttp_Mode_Header:
01338 case GWEN_Io_LayerHttp_Mode_ChunkSize:
01339 return GWEN_Io_LayerHttp_WorkOnWriteRequest1(io);
01340
01341 case GWEN_Io_LayerHttp_Mode_Chunk:
01342 case GWEN_Io_LayerHttp_Mode_Body:
01343 case GWEN_Io_LayerHttp_Mode_Finished:
01344 default:
01345 return GWEN_Io_LayerHttp_WorkOnWriteRequest2(io);
01346 }
01347 }
01348
01349
01350
01351 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerHttp_WorkOnRequests(GWEN_IO_LAYER *io) {
01352 GWEN_IO_LAYER_HTTP *xio;
01353 int doneSomething=0;
01354
01355 assert(io);
01356 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01357 assert(xio);
01358
01359
01360 if (GWEN_Io_LayerHttp_WorkOnReadRequest(io)!=GWEN_Io_Layer_WorkResultBlocking)
01361 doneSomething=1;
01362
01363
01364 if (GWEN_Io_LayerHttp_WorkOnWriteRequest(io)!=GWEN_Io_Layer_WorkResultBlocking)
01365 doneSomething=1;
01366
01367
01368 if (GWEN_Io_Layer_WorkOnRequests(GWEN_Io_Layer_GetBaseLayer(io))!=GWEN_Io_Layer_WorkResultBlocking)
01369 doneSomething=1;
01370
01371 if (GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening) {
01372 GWEN_IO_LAYER *newIo;
01373
01374 newIo=GWEN_Io_Layer_GetNextIncomingLayer(GWEN_Io_Layer_GetBaseLayer(io));
01375 if (newIo) {
01376 GWEN_IO_LAYER *newNewIo;
01377 GWEN_DB_NODE *dbSrc;
01378 GWEN_DB_NODE *dbDst;
01379 uint32_t fl;
01380
01381 fl=GWEN_Io_Layer_GetFlags(io);
01382 newNewIo=GWEN_Io_LayerHttp_new(newIo);
01383 GWEN_Io_Layer_AddFlags(newNewIo, GWEN_IO_LAYER_FLAGS_PASSIVE);
01384 GWEN_Io_Layer_AddFlags(newNewIo, fl & 0xffff);
01385
01386 dbDst=GWEN_Io_LayerHttp_GetDbCommandOut(newNewIo);
01387 dbSrc=xio->dbCommandOut;
01388 GWEN_DB_AddGroupChildren(dbDst, dbSrc);
01389
01390 GWEN_Io_Layer_AddIncomingLayer(io, newNewIo);
01391 doneSomething=1;
01392 }
01393 }
01394
01395 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
01396 }
01397
01398
01399
01400
01401 int GWEN_Io_LayerHttp_AddRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
01402 GWEN_IO_LAYER_HTTP *xio;
01403 GWEN_IO_LAYER_STATUS st;
01404 uint32_t lflags;
01405 uint32_t rflags;
01406
01407 assert(io);
01408 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01409 assert(xio);
01410
01411 st=GWEN_Io_Layer_GetStatus(io);
01412 lflags=GWEN_Io_Layer_GetFlags(io);
01413 rflags=GWEN_Io_Request_GetFlags(r);
01414
01415 switch(GWEN_Io_Request_GetType(r)) {
01416 case GWEN_Io_Request_TypeRead:
01417
01418 if (st!=GWEN_Io_Layer_StatusConnected) {
01419 DBG_INFO(GWEN_LOGDOMAIN, "Layer not connected (%d)", st);
01420 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
01421 return GWEN_ERROR_NOT_OPEN;
01422 }
01423
01424 if (xio->lastReadOutResult) {
01425 DBG_INFO(GWEN_LOGDOMAIN, "Unable to read (%d)", xio->lastReadOutResult);
01426 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, xio->lastReadOutResult);
01427 return xio->lastReadOutResult;
01428 }
01429
01430
01431 if (xio->readRequestIn) {
01432 DBG_INFO(GWEN_LOGDOMAIN, "There already is a read request");
01433 return GWEN_ERROR_TRY_AGAIN;
01434 }
01435
01436 if (rflags & GWEN_IO_REQUEST_FLAGS_PACKETBEGIN) {
01437 if (xio->readMode!=GWEN_Io_LayerHttp_Mode_Idle) {
01438 DBG_INFO(GWEN_LOGDOMAIN, "Packetbegin requested while there is still a packet in work");
01439 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_INVALID);
01440 return GWEN_ERROR_INVALID;
01441 }
01442
01443 GWEN_Buffer_Reset(xio->readBuffer);
01444 GWEN_DB_ClearGroup(xio->dbCommandIn, NULL);
01445 GWEN_DB_ClearGroup(xio->dbStatusIn, NULL);
01446 GWEN_DB_ClearGroup(xio->dbHeaderIn, NULL);
01447 xio->currentReadChunkSize=-1;
01448 xio->currentReadBodySize=-1;
01449 xio->readLineFinished=0;
01450 if ((lflags & GWEN_IO_LAYER_HTTP_FLAGS_IPC) ||
01451 (lflags & GWEN_IO_LAYER_FLAGS_PASSIVE))
01452 xio->readMode=GWEN_Io_LayerHttp_Mode_Command;
01453 else
01454 xio->readMode=GWEN_Io_LayerHttp_Mode_Status;
01455 }
01456 else {
01457 if (xio->readMode!=GWEN_Io_LayerHttp_Mode_ChunkSize &&
01458 xio->readMode!=GWEN_Io_LayerHttp_Mode_Chunk &&
01459 xio->readMode!=GWEN_Io_LayerHttp_Mode_Body) {
01460 DBG_INFO(GWEN_LOGDOMAIN, "Bad read mode and flag GWEN_IO_REQUEST_FLAGS_PACKETBEGIN not set");
01461 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_INVALID);
01462 return GWEN_ERROR_INVALID;
01463 }
01464 }
01465
01466
01467 xio->readRequestIn=r;
01468 GWEN_Io_Request_Attach(xio->readRequestIn);
01469 break;
01470
01471 case GWEN_Io_Request_TypeWrite:
01472
01473 if (st!=GWEN_Io_Layer_StatusConnected) {
01474 DBG_INFO(GWEN_LOGDOMAIN, "Layer is not connected");
01475 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
01476 return GWEN_ERROR_NOT_OPEN;
01477 }
01478
01479
01480 if (xio->writeRequestIn) {
01481 DBG_INFO(GWEN_LOGDOMAIN, "There already is a write request");
01482 return GWEN_ERROR_TRY_AGAIN;
01483 }
01484
01485 if (rflags & GWEN_IO_REQUEST_FLAGS_PACKETBEGIN) {
01486 int rv;
01487
01488 if (xio->writeMode!=GWEN_Io_LayerHttp_Mode_Idle && xio->writeMode!=GWEN_Io_LayerHttp_Mode_Finished) {
01489 DBG_INFO(GWEN_LOGDOMAIN, "Packetbegin requested while there is still a packet in work");
01490 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_INVALID);
01491 return GWEN_ERROR_INVALID;
01492 }
01493
01494 DBG_VERBOUS(GWEN_LOGDOMAIN, "Packet begin");
01495 GWEN_Buffer_Reset(xio->writeBuffer);
01496
01497 if ((lflags & GWEN_IO_LAYER_HTTP_FLAGS_IPC) ||
01498 !(lflags & GWEN_IO_LAYER_FLAGS_PASSIVE)) {
01499 rv=GWEN_Io_LayerHttp_WriteCommand(io, xio->writeBuffer);
01500 xio->writeMode=GWEN_Io_LayerHttp_Mode_Command;
01501 }
01502 else {
01503 rv=GWEN_Io_LayerHttp_WriteStatus(io, xio->writeBuffer);
01504 xio->writeMode=GWEN_Io_LayerHttp_Mode_Status;
01505 }
01506 if (rv<0) {
01507 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01508 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
01509 xio->writeMode=GWEN_Io_LayerHttp_Mode_Idle;
01510 return rv;
01511 }
01512
01513 if (rflags & GWEN_IO_REQUEST_FLAGS_PACKETEND)
01514
01515 GWEN_DB_SetIntValue(xio->dbHeaderOut, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-length",
01516 GWEN_Io_Request_GetBufferSize(r));
01517
01518
01519 rv=GWEN_Io_LayerHttp_WriteHeader(io, xio->writeBuffer);
01520 if (rv<0) {
01521 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01522 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
01523 xio->writeMode=GWEN_Io_LayerHttp_Mode_Idle;
01524 return rv;
01525 }
01526 GWEN_Buffer_Rewind(xio->writeBuffer);
01527 xio->writeMode=GWEN_Io_LayerHttp_Mode_Header;
01528 DBG_VERBOUS(GWEN_LOGDOMAIN, "Buffer: %d/%d",
01529 GWEN_Buffer_GetBytesLeft(xio->writeBuffer),
01530 GWEN_Buffer_GetUsedBytes(xio->writeBuffer));
01531 }
01532 else {
01533 if (xio->writeMode!=GWEN_Io_LayerHttp_Mode_Body) {
01534 if ((GWEN_Io_Request_GetBufferSize(r)==0) &&
01535 (rflags & GWEN_IO_REQUEST_FLAGS_FLUSH)) {
01536
01537 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
01538 return 0;
01539 }
01540 else {
01541 DBG_INFO(GWEN_LOGDOMAIN, "Bad write mode and flag GWEN_IO_REQUEST_FLAGS_PACKETBEGIN not set");
01542 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_INVALID);
01543 return GWEN_ERROR_INVALID;
01544 }
01545 }
01546 }
01547
01548
01549 xio->writeRequestIn=r;
01550 GWEN_Io_Request_Attach(xio->writeRequestIn);
01551 break;
01552
01553 case GWEN_Io_Request_TypeConnect:
01554
01555 if (st!=GWEN_Io_Layer_StatusUnconnected &&
01556 st!=GWEN_Io_Layer_StatusDisconnected) {
01557 DBG_INFO(GWEN_LOGDOMAIN, "Layer not un-/disconnected");
01558 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
01559 return GWEN_ERROR_NOT_OPEN;
01560 }
01561 else {
01562
01563 xio->lastReadOutResult=0;
01564 GWEN_Buffer_Reset(xio->readBuffer);
01565 xio->readMode=GWEN_Io_LayerHttp_Mode_Idle;
01566 xio->currentReadChunkSize=-1;
01567 xio->currentReadBodySize=-1;
01568 xio->readLineFinished=0;
01569
01570 xio->lastWriteOutResult=0;
01571 GWEN_Buffer_Reset(xio->writeBuffer);
01572 xio->writeMode=GWEN_Io_LayerHttp_Mode_Idle;
01573
01574 GWEN_DB_ClearGroup(xio->dbCommandIn, NULL);
01575 GWEN_DB_ClearGroup(xio->dbStatusIn, NULL);
01576 GWEN_DB_ClearGroup(xio->dbHeaderIn, NULL);
01577
01578 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
01579 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
01580 DBG_INFO(GWEN_LOGDOMAIN, "Layer now connected");
01581 }
01582 break;
01583
01584 case GWEN_Io_Request_TypeDisconnect:
01585
01586 if (st!=GWEN_Io_Layer_StatusConnected) {
01587 DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
01588 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
01589 return GWEN_ERROR_NOT_OPEN;
01590 }
01591 else {
01592
01593 GWEN_Io_LayerHttp_AbortInRequests(io, GWEN_ERROR_ABORTED);
01594 GWEN_Io_LayerHttp_AbortOutRequests(io);
01595
01596
01597 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
01598 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
01599 }
01600 break;
01601
01602 default:
01603 DBG_INFO(GWEN_LOGDOMAIN, "This request type is not supported (%d)", GWEN_Io_Request_GetType(r));
01604 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_SUPPORTED);
01605 return GWEN_ERROR_NOT_SUPPORTED;
01606 }
01607
01608 return 0;
01609 }
01610
01611
01612
01613 int GWEN_Io_LayerHttp_DelRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
01614 GWEN_IO_LAYER_HTTP *xio;
01615
01616 assert(io);
01617 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01618 assert(xio);
01619
01620 switch(GWEN_Io_Request_GetType(r)) {
01621 case GWEN_Io_Request_TypeRead:
01622 if (xio->readRequestIn==r) {
01623 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted read request");
01624 xio->readRequestIn=NULL;
01625 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
01626 GWEN_Io_Request_free(r);
01627 }
01628 else {
01629
01630 DBG_INFO(GWEN_LOGDOMAIN, "Read request not registered with this io layer");
01631 return GWEN_ERROR_INVALID;
01632 }
01633 break;
01634
01635 case GWEN_Io_Request_TypeWrite:
01636 if (xio->writeRequestIn==r) {
01637 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted write request");
01638 xio->writeRequestIn=NULL;
01639 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
01640 GWEN_Io_Request_free(r);
01641 }
01642 else {
01643
01644 DBG_INFO(GWEN_LOGDOMAIN, "Write request not registered with this io layer");
01645 return GWEN_ERROR_INVALID;
01646 }
01647 break;
01648
01649 default:
01650 break;
01651 }
01652
01653 return 0;
01654 }
01655
01656
01657
01658 int GWEN_Io_LayerHttp_HasWaitingRequests(GWEN_IO_LAYER *io) {
01659 GWEN_IO_LAYER_HTTP *xio;
01660
01661 assert(io);
01662 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_HTTP, io);
01663 assert(xio);
01664
01665 if (xio->readRequestIn || xio->writeRequestIn)
01666 return 1;
01667 else
01668 return 0;
01669 }
01670
01671
01672
01673
01674
01675