- Adapted indenation to new agreed upon system
- Fixed bad status in poldi zug driver
This commit is contained in:
479
sinqhttpprot.c
479
sinqhttpprot.c
@ -17,244 +17,255 @@
|
||||
#include "uselect.h"
|
||||
/*---------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
ghttp_request *request;
|
||||
char *userName;
|
||||
char *password;
|
||||
pSICSData binData;
|
||||
}HttpProt, *pHttpProt;
|
||||
ghttp_request *request;
|
||||
char *userName;
|
||||
char *password;
|
||||
pSICSData binData;
|
||||
} HttpProt, *pHttpProt;
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int configRequest(Ascon *a){
|
||||
pHttpProt pHttp = (pHttpProt)a->private;
|
||||
pDynString request;
|
||||
char *uri = NULL;
|
||||
|
||||
request = CreateDynString(64,64);
|
||||
if(request == NULL){
|
||||
AsconError(a,"Out of memory", 122);
|
||||
return 0;
|
||||
}
|
||||
DynStringConcat(request,"http://");
|
||||
DynStringConcat(request,a->hostport);
|
||||
DynStringConcatChar(request,'/');
|
||||
DynStringConcat(request,GetCharArray(a->wrBuffer));
|
||||
uri = GetCharArray(request);
|
||||
|
||||
ghttp_clean(pHttp->request);
|
||||
ghttp_set_type(pHttp->request,ghttp_type_get);
|
||||
ghttp_set_header(pHttp->request,"connection", "keep-alive");
|
||||
if(ghttp_set_uri(pHttp->request,uri) < 0){
|
||||
AsconError(a,"Bad URL", a->state);
|
||||
return 0;
|
||||
}
|
||||
if(pHttp->userName != NULL && pHttp->password != NULL){
|
||||
ghttp_set_authinfo(pHttp->request,
|
||||
pHttp->userName, pHttp->password);
|
||||
}
|
||||
ghttp_set_sync(pHttp->request,ghttp_async);
|
||||
ghttp_prepare(pHttp->request);
|
||||
DeleteDynString(request);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void handleReply(Ascon *a){
|
||||
char *pPtr = NULL, *pType = NULL;
|
||||
int len, i, *dataPtr = NULL;
|
||||
HistInt *hmData = NULL;
|
||||
pHttpProt pHttp = (pHttpProt)a->private;
|
||||
|
||||
pPtr = ghttp_get_body(pHttp->request);
|
||||
len = ghttp_get_body_len(pHttp->request);
|
||||
if(strstr(pPtr,"ERROR") != NULL){
|
||||
AsconError(a,pPtr, a->state);
|
||||
DynStringConcat(a->rdBuffer,pPtr);
|
||||
} else if(strstr(pPtr,"Authentication Error") != NULL){
|
||||
DynStringConcat(a->rdBuffer,pPtr);
|
||||
AsconError(a,pPtr, a->state);
|
||||
} else {
|
||||
pType = (char *)ghttp_get_header(pHttp->request,"Content-Type");
|
||||
if(strstr(pType,"sinqhm") == NULL){
|
||||
/* text data */
|
||||
for(i = 0; i < len; i++){
|
||||
DynStringConcatChar(a->rdBuffer, pPtr[i]);
|
||||
}
|
||||
} else {
|
||||
hmData = (HistInt *)pPtr;
|
||||
clearSICSData(pHttp->binData);
|
||||
len = len/sizeof(HistInt);
|
||||
dataPtr = getSICSDataPointer(pHttp->binData, 0, len);
|
||||
for(i = 0; i < len; i++){
|
||||
dataPtr[i] = htonl(hmData[i]);
|
||||
}
|
||||
assignSICSType(pHttp->binData, 0, len, INTTYPE);
|
||||
DynStringCopy(a->rdBuffer,"SICSDATA");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int HttpHandler(Ascon *a) {
|
||||
ghttp_status status;
|
||||
pHttpProt pHttp = (pHttpProt)a->private;
|
||||
int socke, selStat;
|
||||
fd_set rmask;
|
||||
struct timeval tmo = {0,0};
|
||||
char buffer[1024];
|
||||
ghttp_current_status procStatus;
|
||||
|
||||
switch (a->state) {
|
||||
case AsconConnectStart:
|
||||
a->state = AsconConnecting;
|
||||
break;
|
||||
case AsconConnecting:
|
||||
a->state = AsconConnectDone; /* success */
|
||||
break;
|
||||
case AsconWriteStart:
|
||||
if(configRequest(a)){
|
||||
a->state = AsconWriting;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case AsconWriting:
|
||||
status = ghttp_process(pHttp->request);
|
||||
if(status == ghttp_error){
|
||||
ghttp_close(pHttp->request);
|
||||
configRequest(a);
|
||||
status = ghttp_process(pHttp->request);
|
||||
}
|
||||
if(status == ghttp_error){
|
||||
AsconError(a,"Server error", 123);
|
||||
DynStringConcat(a->rdBuffer,"Server error");
|
||||
a->state = AsconReadDone;
|
||||
} else {
|
||||
procStatus = ghttp_get_status(pHttp->request);
|
||||
if(procStatus.proc == ghttp_proc_response_hdrs || procStatus.proc == ghttp_proc_response){
|
||||
a->state = AsconWriteDone;
|
||||
}
|
||||
}
|
||||
a->start = DoubleTime();
|
||||
DynStringClear(a->rdBuffer);
|
||||
break;
|
||||
case AsconReadStart:
|
||||
socke = ghttp_get_socket(pHttp->request);
|
||||
FD_ZERO(&rmask);
|
||||
FD_SET(socke,&rmask);
|
||||
selStat = uselect(socke+1,&rmask, NULL, NULL, &tmo);
|
||||
if(selStat > 0 && FD_ISSET(socke,&rmask)){
|
||||
status = ghttp_process(pHttp->request);
|
||||
a->state = AsconReading;
|
||||
} else {
|
||||
if(DoubleTime() > a->start + a->timeout){
|
||||
AsconError(a," read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
/* this to clear the line */
|
||||
ghttp_close(pHttp->request);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case AsconReading:
|
||||
socke = ghttp_get_socket(pHttp->request);
|
||||
FD_ZERO(&rmask);
|
||||
FD_SET(socke,&rmask);
|
||||
selStat = select(socke+1,&rmask, NULL, NULL, &tmo);
|
||||
if(selStat == 0 ){
|
||||
return 1;
|
||||
}
|
||||
status = ghttp_process(pHttp->request);
|
||||
switch(status){
|
||||
case ghttp_not_done:
|
||||
if(DoubleTime() > a->start + a->timeout){
|
||||
AsconError(a," read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
/* this to clear the line */
|
||||
ghttp_close(pHttp->request);
|
||||
}
|
||||
return 1;
|
||||
case ghttp_done:
|
||||
handleReply(a);
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
case ghttp_error:
|
||||
/*
|
||||
* A first error may not be an error but a
|
||||
* reconnect
|
||||
*/
|
||||
ghttp_close(pHttp->request);
|
||||
configRequest(a);
|
||||
status = ghttp_process(pHttp->request);
|
||||
if(status == ghttp_error){
|
||||
AsconError(a,"Server error", a->state);
|
||||
DynStringConcat(a->rdBuffer,"Server error");
|
||||
a->state = AsconReadDone;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return AsconStdHandler(a);
|
||||
}
|
||||
static int configRequest(Ascon * a)
|
||||
{
|
||||
pHttpProt pHttp = (pHttpProt) a->private;
|
||||
pDynString request;
|
||||
char *uri = NULL;
|
||||
|
||||
request = CreateDynString(64, 64);
|
||||
if (request == NULL) {
|
||||
AsconError(a, "Out of memory", 122);
|
||||
return 0;
|
||||
}
|
||||
DynStringConcat(request, "http://");
|
||||
DynStringConcat(request, a->hostport);
|
||||
DynStringConcatChar(request, '/');
|
||||
DynStringConcat(request, GetCharArray(a->wrBuffer));
|
||||
uri = GetCharArray(request);
|
||||
|
||||
ghttp_clean(pHttp->request);
|
||||
ghttp_set_type(pHttp->request, ghttp_type_get);
|
||||
ghttp_set_header(pHttp->request, "connection", "keep-alive");
|
||||
if (ghttp_set_uri(pHttp->request, uri) < 0) {
|
||||
AsconError(a, "Bad URL", a->state);
|
||||
return 0;
|
||||
}
|
||||
if (pHttp->userName != NULL && pHttp->password != NULL) {
|
||||
ghttp_set_authinfo(pHttp->request, pHttp->userName, pHttp->password);
|
||||
}
|
||||
ghttp_set_sync(pHttp->request, ghttp_async);
|
||||
ghttp_prepare(pHttp->request);
|
||||
DeleteDynString(request);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void killHttp(void *data){
|
||||
pHttpProt prot = (pHttpProt)data;
|
||||
if(prot == NULL){
|
||||
return;
|
||||
}
|
||||
if(prot->request != NULL){
|
||||
ghttp_close(prot->request);
|
||||
}
|
||||
if(prot->password != NULL){
|
||||
free(prot->password);
|
||||
}
|
||||
if(prot->userName != NULL){
|
||||
free(prot->userName);
|
||||
}
|
||||
free(prot);
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void handleReply(Ascon * a)
|
||||
{
|
||||
char *pPtr = NULL, *pType = NULL;
|
||||
int len, i, *dataPtr = NULL;
|
||||
HistInt *hmData = NULL;
|
||||
pHttpProt pHttp = (pHttpProt) a->private;
|
||||
|
||||
pPtr = ghttp_get_body(pHttp->request);
|
||||
len = ghttp_get_body_len(pHttp->request);
|
||||
if (strstr(pPtr, "ERROR") != NULL) {
|
||||
AsconError(a, pPtr, a->state);
|
||||
DynStringConcat(a->rdBuffer, pPtr);
|
||||
} else if (strstr(pPtr, "Authentication Error") != NULL) {
|
||||
DynStringConcat(a->rdBuffer, pPtr);
|
||||
AsconError(a, pPtr, a->state);
|
||||
} else {
|
||||
pType = (char *) ghttp_get_header(pHttp->request, "Content-Type");
|
||||
if (strstr(pType, "sinqhm") == NULL) {
|
||||
/* text data */
|
||||
for (i = 0; i < len; i++) {
|
||||
DynStringConcatChar(a->rdBuffer, pPtr[i]);
|
||||
}
|
||||
} else {
|
||||
hmData = (HistInt *) pPtr;
|
||||
clearSICSData(pHttp->binData);
|
||||
len = len / sizeof(HistInt);
|
||||
dataPtr = getSICSDataPointer(pHttp->binData, 0, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
dataPtr[i] = htonl(hmData[i]);
|
||||
}
|
||||
assignSICSType(pHttp->binData, 0, len, INTTYPE);
|
||||
DynStringCopy(a->rdBuffer, "SICSDATA");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int HttpProtInit(Ascon *a, SConnection *con,
|
||||
int argc, char *argv[]){
|
||||
pHttpProt pHttp = NULL;
|
||||
|
||||
pHttp = calloc(sizeof(HttpProt), 1);
|
||||
if(pHttp == NULL){
|
||||
SCWrite(con,"ERROR: out of memory in HttpProtInit", eError);
|
||||
return 0;
|
||||
}
|
||||
if(argc < 3){
|
||||
return 0;
|
||||
}
|
||||
a->hostport = strdup(argv[1]);
|
||||
pHttp->binData = (pSICSData)FindCommandData(pServ->pSics,
|
||||
argv[2], "SICSData");
|
||||
if(pHttp->binData == NULL){
|
||||
SCWrite(con,"ERROR: SICSData objct not found", eError);
|
||||
return 0;
|
||||
}
|
||||
if(argc > 3){
|
||||
a->timeout = atof(argv[3]);
|
||||
} else {
|
||||
a->timeout = 10.;
|
||||
}
|
||||
if(argc > 5){
|
||||
pHttp->userName = strdup(argv[4]);
|
||||
pHttp->password = strdup(argv[5]);
|
||||
}
|
||||
pHttp->request = ghttp_request_new();
|
||||
a->private = pHttp;
|
||||
a->killPrivate = killHttp;
|
||||
a->state = AsconConnectStart;
|
||||
return 1;
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int HttpHandler(Ascon * a)
|
||||
{
|
||||
ghttp_status status;
|
||||
pHttpProt pHttp = (pHttpProt) a->private;
|
||||
int socke, selStat;
|
||||
fd_set rmask;
|
||||
struct timeval tmo = { 0, 0 };
|
||||
char buffer[1024];
|
||||
ghttp_current_status procStatus;
|
||||
|
||||
switch (a->state) {
|
||||
case AsconConnectStart:
|
||||
a->state = AsconConnecting;
|
||||
break;
|
||||
case AsconConnecting:
|
||||
a->state = AsconConnectDone; /* success */
|
||||
break;
|
||||
case AsconWriteStart:
|
||||
if (configRequest(a)) {
|
||||
a->state = AsconWriting;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case AsconWriting:
|
||||
status = ghttp_process(pHttp->request);
|
||||
if (status == ghttp_error) {
|
||||
ghttp_close(pHttp->request);
|
||||
configRequest(a);
|
||||
status = ghttp_process(pHttp->request);
|
||||
}
|
||||
if (status == ghttp_error) {
|
||||
AsconError(a, "Server error", 123);
|
||||
DynStringConcat(a->rdBuffer, "Server error");
|
||||
a->state = AsconReadDone;
|
||||
} else {
|
||||
procStatus = ghttp_get_status(pHttp->request);
|
||||
if (procStatus.proc == ghttp_proc_response_hdrs
|
||||
|| procStatus.proc == ghttp_proc_response) {
|
||||
a->state = AsconWriteDone;
|
||||
}
|
||||
}
|
||||
a->start = DoubleTime();
|
||||
DynStringClear(a->rdBuffer);
|
||||
break;
|
||||
case AsconReadStart:
|
||||
socke = ghttp_get_socket(pHttp->request);
|
||||
FD_ZERO(&rmask);
|
||||
FD_SET(socke, &rmask);
|
||||
selStat = uselect(socke + 1, &rmask, NULL, NULL, &tmo);
|
||||
if (selStat > 0 && FD_ISSET(socke, &rmask)) {
|
||||
status = ghttp_process(pHttp->request);
|
||||
a->state = AsconReading;
|
||||
} else {
|
||||
if (DoubleTime() > a->start + a->timeout) {
|
||||
AsconError(a, " read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
/* this to clear the line */
|
||||
ghttp_close(pHttp->request);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case AsconReading:
|
||||
socke = ghttp_get_socket(pHttp->request);
|
||||
FD_ZERO(&rmask);
|
||||
FD_SET(socke, &rmask);
|
||||
selStat = select(socke + 1, &rmask, NULL, NULL, &tmo);
|
||||
if (selStat == 0) {
|
||||
return 1;
|
||||
}
|
||||
status = ghttp_process(pHttp->request);
|
||||
switch (status) {
|
||||
case ghttp_not_done:
|
||||
if (DoubleTime() > a->start + a->timeout) {
|
||||
AsconError(a, " read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
/* this to clear the line */
|
||||
ghttp_close(pHttp->request);
|
||||
}
|
||||
return 1;
|
||||
case ghttp_done:
|
||||
handleReply(a);
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
case ghttp_error:
|
||||
/*
|
||||
* A first error may not be an error but a
|
||||
* reconnect
|
||||
*/
|
||||
ghttp_close(pHttp->request);
|
||||
configRequest(a);
|
||||
status = ghttp_process(pHttp->request);
|
||||
if (status == ghttp_error) {
|
||||
AsconError(a, "Server error", a->state);
|
||||
DynStringConcat(a->rdBuffer, "Server error");
|
||||
a->state = AsconReadDone;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return AsconStdHandler(a);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void killHttp(void *data)
|
||||
{
|
||||
pHttpProt prot = (pHttpProt) data;
|
||||
if (prot == NULL) {
|
||||
return;
|
||||
}
|
||||
if (prot->request != NULL) {
|
||||
ghttp_close(prot->request);
|
||||
}
|
||||
if (prot->password != NULL) {
|
||||
free(prot->password);
|
||||
}
|
||||
if (prot->userName != NULL) {
|
||||
free(prot->userName);
|
||||
}
|
||||
free(prot);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int HttpProtInit(Ascon * a, SConnection * con,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pHttpProt pHttp = NULL;
|
||||
|
||||
pHttp = calloc(sizeof(HttpProt), 1);
|
||||
if (pHttp == NULL) {
|
||||
SCWrite(con, "ERROR: out of memory in HttpProtInit", eError);
|
||||
return 0;
|
||||
}
|
||||
if (argc < 3) {
|
||||
return 0;
|
||||
}
|
||||
a->hostport = strdup(argv[1]);
|
||||
pHttp->binData = (pSICSData) FindCommandData(pServ->pSics,
|
||||
argv[2], "SICSData");
|
||||
if (pHttp->binData == NULL) {
|
||||
SCWrite(con, "ERROR: SICSData objct not found", eError);
|
||||
return 0;
|
||||
}
|
||||
if (argc > 3) {
|
||||
a->timeout = atof(argv[3]);
|
||||
} else {
|
||||
a->timeout = 10.;
|
||||
}
|
||||
if (argc > 5) {
|
||||
pHttp->userName = strdup(argv[4]);
|
||||
pHttp->password = strdup(argv[5]);
|
||||
}
|
||||
pHttp->request = ghttp_request_new();
|
||||
a->private = pHttp;
|
||||
a->killPrivate = killHttp;
|
||||
a->state = AsconConnectStart;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void AddHttpProtocoll(){
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("sinqhttp");
|
||||
prot->init = HttpProtInit;
|
||||
prot->handler = HttpHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
void AddHttpProtocoll()
|
||||
{
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("sinqhttp");
|
||||
prot->init = HttpProtInit;
|
||||
prot->handler = HttpHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
|
Reference in New Issue
Block a user