void cg_upnp_control_request_sethostfromservice(CgSoapRequest *soapReq, CgUpnpService *service) { CgHttpRequest *httpReq; CgNetURL *ctrlURL; cg_log_debug_l4("Entering...\n"); httpReq = cg_soap_request_gethttprequest(soapReq); ctrlURL = cg_upnp_service_getcontrolurl(service); cg_log_debug_s("Ctrl URL: %s - %d -%s", cg_net_url_gethost(ctrlURL), cg_net_url_getport(ctrlURL), cg_net_url_getpath(ctrlURL)); //cg_http_request_seturi(httpReq, cg_xml_node_getchildnodevalue(cg_upnp_service_getservicenode(service), CG_UPNP_SERVICE_CONTROL_URL)); cg_http_request_seturi(httpReq, cg_net_url_getrequest(ctrlURL)); /**** Host ****/ cg_net_url_delete(httpReq->postURL); httpReq->postURL = ctrlURL; cg_log_debug_s("Post URL: %s - %d -%s", cg_net_url_gethost(httpReq->postURL), cg_net_url_getport(httpReq->postURL), cg_net_url_getpath(httpReq->postURL)); cg_log_debug_l4("Leaving...\n"); }
char *cg_net_uri_getupnpbasepath(CgNetURI *locationURL) { char *path, *c; int i; path = cg_strdup(cg_net_uri_getpath(locationURL)); cg_log_debug_s("Mangling url string: %s\n", path); i = cg_strlen(path); if ( 0 >= i ) { cg_log_debug("No base path, doing nothing.\n"); return NULL; } /* Truncating out the "file name" from path */ for ( c=( path + --i); 0<=i; c=( path + --i )) if ( '/' == *c ) { *( path + i + 1 ) = '\0'; cg_log_debug_s("Truncating string from place %d\n", i); break; } cg_log_debug_s("url string after mangling: %s\n", path); return path; }
void cg_http_packet_print(CgHttpPacket *httpPkt) { CgHttpHeader *header; char *content; long contentLen; cg_log_debug_l4("Entering...\n"); /**** print headers ****/ for (header = cg_http_packet_getheaders(httpPkt); header != NULL; header = cg_http_header_next(header)) { cg_log_debug_s("%s: %s\n", cg_http_header_getname(header), cg_http_header_getvalue(header)); } cg_log_debug_s("\n"); /**** print content ****/ content = cg_http_packet_getcontent(httpPkt); contentLen = cg_http_packet_getcontentlength(httpPkt); if (content != NULL && 0 < contentLen) cg_log_debug_s("%s\n", content); cg_log_debug_l4("Leaving...\n"); }
BOOL cg_socket_tosockaddrinfo(int sockType, char *addr, int port, struct addrinfo **addrInfo, BOOL isBindAddr) { #if defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) struct addrinfo hints; char portStr[32]; #else struct addrinfo hints; char portStr[32]; int errorn; #endif cg_log_debug_l4("Entering...\n"); cg_socket_startup(); #if defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = sockType; hints.ai_flags= 0; /*AI_NUMERICHOST | AI_PASSIVE*/; sprintf(portStr, "%d", port); if (ka_getaddrinfo(addr, portStr, &hints, addrInfo) != 0) return FALSE; if (isBindAddr == TRUE) return TRUE; hints.ai_family = (*addrInfo)->ai_family; ka_freeaddrinfo(*addrInfo); if (ka_getaddrinfo(NULL, portStr, &hints, addrInfo) != 0) return FALSE; return TRUE; #else memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = sockType; hints.ai_flags= /*AI_NUMERICHOST | */AI_PASSIVE; sprintf(portStr, "%d", port); cg_log_debug("Address: %s, port: %s\n", addr, portStr); if ( (errorn = getaddrinfo(addr, portStr, &hints, addrInfo)) != 0) { #if !defined(WINCE) cg_log_debug_s("ERROR: %s\n", gai_strerror(errorn)); cg_log_debug_s("SERROR: %s\n", strerror(errno)); #endif return FALSE; } if (isBindAddr == TRUE) return TRUE; hints.ai_family = (*addrInfo)->ai_family; freeaddrinfo(*addrInfo); if ((errorn = getaddrinfo(NULL, portStr, &hints, addrInfo)) != 0) { #if !defined(WINCE) cg_log_debug_s("ERROR: %s\n", gai_strerror(errorn)); cg_log_debug_s("SERROR: %s\n", strerror(errno)); #endif return FALSE; } return TRUE; #endif }
static int cg_http_request_progress_callback(void *ptr, double dltotal, double dlnow, double ultotal, double ulnow) { CgThread *self = cg_thread_self(); cg_log_debug_s("Curl call progressing... Got thread %p\n", self); if ( ( NULL != self ) && !cg_thread_isrunnable(self)) { cg_log_debug_s("Thread is not runnable anymore! Informing libcurl to abort\n"); return TRUE; } return FALSE; }
/** * Parse the service description from the service's SCPD URL. Do not call * this from user applications. * * @param service The service in question * @return TRUE if successful; otherwise FALSE */ BOOL cg_upnp_controlpoint_parsescservicescpd(CgUpnpService *service) { CgNetURL *scpdURL; BOOL scpdParseSuccess; cg_log_debug_l4("Entering...\n"); scpdURL = cg_upnp_service_getscpdurl(service); if ( NULL == scpdURL ) return FALSE; cg_log_debug_s("SCPD URL: %s\n", cg_net_url_getrequest(scpdURL)); scpdParseSuccess = cg_upnp_service_parsedescriptionurl(service, scpdURL); cg_net_url_delete(scpdURL); if (scpdParseSuccess == TRUE) return TRUE; #if defined(CG_UPNP_USE_STDDCP) if (cg_upnp_service_hasstddcp(service)) { char *stdDCP = cg_upnp_service_getstddcp(service); scpdParseSuccess = cg_upnp_service_parsedescription(service, stdDCP, cg_strlen(stdDCP)); } #endif cg_log_debug_l4("Leaving...\n"); return scpdParseSuccess; }
CgThread *cg_thread_new() { CgThread *thread; cg_log_debug_l4("Entering...\n"); thread = (CgThread *)malloc(sizeof(CgThread)); cg_log_debug_s("Creating thread data into %p\n", thread); if ( NULL != thread ) { cg_list_node_init((CgList *)thread); thread->runnableFlag = FALSE; thread->action = NULL; thread->userData = NULL; } #if defined (WINCE) thread->hThread = NULL; //WINCE trial result: default sleep value to keep system load down thread->sleep = CG_THREAD_MIN_SLEEP; thread->isRunning = FALSE; thread->deletePending = FALSE; #if defined DEBUG strcpy(thread->friendlyName,"-"); #endif //DEBUG #endif //WINCE #if defined(FREE_RTOS) thread->usTasckDepth = 0; thread->uxPriority = 0;; #endif cg_log_debug_l4("Leaving...\n"); return thread; }
char *cg_string_replace(CgString *str, char *fromStr[], char *toStr[], size_t fromStrCnt) { char *orgValue = NULL; size_t orgValueLen = 0; int n = 0; int copyPos = 0; size_t *fromStrLen = NULL; CgString *repValue = NULL; BOOL isReplaced = FALSE; cg_log_debug_l5("Entering...\n"); if (NULL == str ) return NULL; repValue = cg_string_new(); fromStrLen = (size_t *)malloc(sizeof(size_t) * fromStrCnt); if ( NULL == fromStrLen ) { cg_string_delete(repValue); cg_log_debug_s("Memory allocation failure!\n"); return NULL; } for (n=0; n<fromStrCnt; n++) fromStrLen[n] = cg_strlen(fromStr[n]); orgValue = cg_string_getvalue(str); orgValueLen = cg_string_length(str); copyPos = 0; while (copyPos<orgValueLen) { isReplaced = FALSE; for (n=0; n<fromStrCnt; n++) { if (strncmp(fromStr[n], orgValue + copyPos, fromStrLen[n]) == 0) { cg_string_addvalue(repValue, toStr[n]); copyPos += fromStrLen[n]; isReplaced = TRUE; continue; } } if (isReplaced == TRUE) continue; cg_string_naddvalue(repValue, orgValue + copyPos, 1); copyPos++; } free(fromStrLen); cg_string_setvalue(str, cg_string_getvalue(repValue)); cg_string_delete(repValue); cg_log_debug_l5("Leaving...\n"); return cg_string_getvalue(str); }
BOOL cg_http_request_postresponse(CgHttpRequest *httpReq, CgHttpResponse *httpRes) { CgSocket *sock; char httpDate[CG_HTTP_DATE_MAXLEN]; char *version, *reasonPhrase; int statusCode; char statusCodeBuf[CG_STRING_INTEGER_BUFLEN]; cg_log_debug_l4("Entering...\n"); sock = cg_http_request_getsocket(httpReq); cg_log_debug_s("Got request:\n"); cg_http_request_print(httpReq); cg_http_response_setdate(httpRes, cg_http_getdate(cg_getcurrentsystemtime(), httpDate, sizeof(httpDate))); version = cg_http_response_getversion(httpRes); statusCode = cg_http_response_getstatuscode(httpRes); reasonPhrase = cg_http_response_getreasonphrase(httpRes); if (version == NULL || reasonPhrase == NULL) return FALSE; cg_int2str(statusCode, statusCodeBuf, sizeof(statusCodeBuf)); /**** send first line ****/ cg_socket_write(sock, version, cg_strlen(version)); cg_socket_write(sock, CG_HTTP_SP, sizeof(CG_HTTP_SP)-1); cg_socket_write(sock, statusCodeBuf, cg_strlen(statusCodeBuf)); cg_socket_write(sock, CG_HTTP_SP, sizeof(CG_HTTP_SP)-1); cg_socket_write(sock, reasonPhrase, cg_strlen(reasonPhrase)); cg_socket_write(sock, CG_HTTP_CRLF, sizeof(CG_HTTP_CRLF)-1); cg_log_debug_s("Posting response:\n"); cg_http_response_print(httpRes); /**** send header and content ****/ cg_http_packet_post((CgHttpPacket *)httpRes, sock); cg_log_debug_l4("Leaving...\n"); return TRUE; }
void cg_http_request_print(CgHttpRequest *httpReq) { cg_log_debug_l4("Entering...\n"); cg_log_debug_s("%s %s %s\n", cg_http_request_getmethod(httpReq), cg_http_request_geturi(httpReq), cg_http_request_getversion(httpReq)); cg_http_packet_print((CgHttpPacket *)httpReq); cg_log_debug_l4("Leaving...\n"); }
char *cg_net_uri_escapestring(char *buf, int bufSize, CgString *retBuf) { #if defined(CG_HTTP_CURL) char *tmp; #else int n; unsigned char c; char hexChar[4]; #endif cg_log_debug_l4("Entering...\n"); if (!retBuf) return NULL; #if defined(CG_HTTP_CURL) tmp = (bufSize < 1)?curl_escape(buf, 0):curl_escape(buf, bufSize); if (tmp == NULL) { cg_log_debug_s("Memory allocation problem!\n"); return NULL; } cg_string_addvalue(retBuf, tmp); curl_free(tmp); #else if (bufSize < 1) bufSize = cg_strlen(buf) + 1; for (n=0; n<bufSize; n++) { c = (unsigned char)buf[n]; if (!cg_net_uri_isalphanumchar(c)) { #if defined(HAVE_SNPRINTF) snprintf(hexChar, sizeof(hexChar), "%%%02X", c); #else sprintf(hexChar, "%%%02X", c); #endif cg_string_naddvalue(retBuf, hexChar, 3); } else cg_string_naddvalue(retBuf, buf+n, 1); } #endif cg_log_debug_l4("Leaving...\n"); return cg_string_getvalue(retBuf); }
size_t cg_http_packet_read_chunk(CgHttpPacket *httpPkt, CgSocket *sock, char *lineBuf, size_t lineBufSize) { ssize_t readLen = 0; ssize_t conLen = 0; int tries = 0; char *content = NULL; cg_log_debug_l4("Entering...\n"); /* Read chunk header */ readLen = cg_socket_readline(sock, lineBuf, lineBufSize); conLen = cg_strhex2long(lineBuf); if (conLen < 1) return 0; content = (char *)malloc(conLen+1); if (content == NULL) { cg_log_debug_s("Memory allocation problem!\n"); return 0; } content[conLen] = 0; readLen = 0; /* Read content until conLen is reached, or tired of trying */ while (readLen < conLen && tries < 20) { readLen += cg_socket_read(sock, (content+readLen), (conLen-readLen)); tries++; } /* Append content to packet */ cg_http_packet_appendncontent(httpPkt, content, readLen); free(content); content = NULL; if (readLen == conLen) { /* Read CRLF bytes */ cg_socket_readline(sock, lineBuf, lineBufSize); } cg_log_debug_l4("Leaving...\n"); return readLen; }
BOOL cg_socket_initwindowbuffer(CgSocket *sock) { cg_log_debug_l4("Entering...\n"); if (sock->sendWinBuf == NULL) sock->sendWinBuf = (char *)malloc(sizeof(UH) * CG_NET_SOCKET_WINDOW_BUFSIZE); if (sock->sendWinBuf == NULL) sock->recvWinBuf = (char *)malloc(sizeof(UH) * CG_NET_SOCKET_WINDOW_BUFSIZE); cg_log_debug_l4("Leaving...\n"); if ( ( NULL == sock->sendWinBuf ) || ( NULL == sock->sendWinBuf ) ) { cg_log_debug_s("Memory allocation failure!\n"); return FALSE; } else return TRUE; }
void cg_string_tokenizer_print(CgStringTokenizer *strToken) { cg_log_debug_l4("Entering...\n"); cg_log_debug_s( "cg_string_tokenizer_print\n" "value = %s\n, delim = %s,\n delimCnt = %d,\n nextStartPos = %d,\n lastPos = %d,\n currToken = %s,\n nextToken = %s,\n repToken = %c,\n hasNextTokens = %d\n", strToken->value, strToken->delim, strToken->delimCnt, strToken->nextStartPos, strToken->lastPos, strToken->currToken, strToken->nextToken, strToken->repToken, strToken->hasNextTokens); cg_log_debug_l4("Leaving...\n"); }
int cg_socket_read(CgSocket *sock, char *buffer, int bufferLen) { int recvLen; #if defined(CG_USE_OPENSSL) if (cg_socket_isssl(sock) == FALSE) { #endif #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) recvLen = so_recv(sock->id, buffer, bufferLen, 0); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) recvLen = ka_recv(sock->id, buffer, bufferLen, 0); #elif defined(ITRON) recvLen = tcp_rcv_dat(sock->id, buffer, bufferLen, TMO_FEVR); #else recvLen = recv(sock->id, buffer, bufferLen, 0); #endif #if defined(CG_USE_OPENSSL) } else { recvLen = SSL_read(sock->ssl, buffer, bufferLen); } #endif cg_log_debug_l4("Entering...\n"); #ifdef SOCKET_DEBUG if (0 <= recvLen) buffer[recvLen] = '\0'; cg_log_debug_s("r %d : %s\n", recvLen, (0 <= recvLen) ? buffer : ""); #endif cg_log_debug_l4("Leaving...\n"); return recvLen; }
void cg_string_setnvalue(CgString *str, const char *value, size_t len) { cg_log_debug_l5("Entering...\n"); if (NULL != str) { cg_string_clear(str); if (value != NULL) { str->valueSize = len; str->memSize = str->valueSize + 1; str->value = (char *)malloc(str->memSize * sizeof(char)); if ( NULL == str->value ) { cg_log_debug_s("Memory allocation failure!\n"); return; } /* memcpy works better with non-zero-terminated data than strncpy */ memcpy(str->value, value, len); str->value[len] = '\0'; } } cg_log_debug_l5("Leaving...\n"); }
BOOL cg_xml_parse(CgXmlParser *parser, CgXmlNodeList *nodeList, const char *data, size_t len) { #if defined DEBUG_XML_RESULT CgString* resdata = NULL; #endif XML_Parser p; CgExpatData expatData; #ifdef CG_SHOW_TIMINGS struct timeval start_time, end_time, elapsed_time; #endif cg_log_debug_l4("Entering...\n"); #ifdef CG_SHOW_TIMINGS gettimeofday(&start_time, NULL); #endif if (!data || len <= 0) return FALSE; p = XML_ParserCreate(NULL); if (!p) return FALSE; /* Fix to get expat parser to work with DLink-routers */ if (data[len-1] == 0) len--; expatData.rootNode = NULL; expatData.currNode = NULL; XML_SetUserData(p, &expatData); XML_SetElementHandler(p, cg_expat_element_start, cg_expat_element_end); XML_SetCharacterDataHandler(p, cg_expat_character_data); parser->parseResult = XML_Parse(p, data, len, 1); XML_ParserFree(p); if (parser->parseResult == 0 /*XML_STATUS_ERROR*/) { if (expatData.rootNode != NULL) cg_xml_node_delete(expatData.rootNode); #if defined DEBUG_XML_RESULT resdata = cg_string_new(); cg_string_naddvalue(resdata,data,len); printf("XML parse Error on data %s\n time used = %ds\n", cg_string_getvalue(resdata), time(NULL)-startTime); cg_string_delete(resdata); #endif return FALSE; } cg_xml_nodelist_add(nodeList, expatData.rootNode); #ifdef CG_SHOW_TIMINGS gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); cg_log_debug_s("Parsing XML completed. Elapsed time: " "%ld msec\n", ((elapsed_time.tv_sec*1000) + (elapsed_time.tv_usec/1000))); cg_total_elapsed_time += (elapsed_time.tv_sec*1000000)+ (elapsed_time.tv_usec); cg_log_debug_s("Total elapsed time: %ld msec\n", cg_total_elapsed_time / 1000); #endif #if defined DEBUG_XML_RESULT resdata = cg_string_new(); cg_string_naddvalue(resdata,data,len); printf("XML parse success - time used %ds\n",time(NULL)-startTime); cg_string_delete(resdata); #endif return TRUE; cg_log_debug_l4("Leaving...\n"); }
/** * Stop the control point. Stops sending/receiveing/responding to any messages. * * @param ctrlPoint The control point to stop * * @return TRUE if successful; otherwise FALSE * */ BOOL cg_upnp_controlpoint_stop(CgUpnpControlPoint *ctrlPoint) { CgUpnpDevice *dev = NULL; CgUpnpSSDPServerList *ssdpServerList; CgUpnpSSDPResponseServerList *ssdpResServerList; CgHttpServerList *httpServerList; const char *udn = NULL; CG_UPNP_DEVICE_LISTENER listener = cg_upnp_controlpoint_getdevicelistener(ctrlPoint); cg_log_debug_l4("Entering...\n"); /* Stop expiration handling */ cg_thread_stop_with_cond(ctrlPoint->expThread, ctrlPoint->expCond); cg_log_debug_s("Expiration thread stopped.\n"); /**** SSDP Server ****/ ssdpServerList = cg_upnp_controlpoint_getssdpserverlist(ctrlPoint); cg_log_debug_s("Stopping ssdp servers.\n"); cg_upnp_ssdp_serverlist_stop(ssdpServerList); cg_log_debug_s("Done\n"); cg_upnp_ssdp_serverlist_close(ssdpServerList); cg_upnp_ssdp_serverlist_clear(ssdpServerList); /**** SSDP Response Server ****/ ssdpResServerList = cg_upnp_controlpoint_getssdpresponseserverlist(ctrlPoint); cg_log_debug_s("Stopping ssdp response servers.\n"); cg_upnp_ssdpresponse_serverlist_stop(ssdpResServerList); cg_log_debug_s("Done\n"); cg_upnp_ssdpresponse_serverlist_close(ssdpResServerList); cg_upnp_ssdpresponse_serverlist_clear(ssdpResServerList); /**** HTTP Server ****/ httpServerList = cg_upnp_controlpoint_gethttpserverlist(ctrlPoint); cg_log_debug_s("Stopping http servers.\n"); cg_http_serverlist_stop(httpServerList); cg_log_debug_s("Done\n"); cg_http_serverlist_close(httpServerList); cg_http_serverlist_clear(httpServerList); cg_upnp_controlpoint_lock(ctrlPoint); cg_log_debug_s("Got controlpoint lock.\n"); /* Unsubscribe from all services */ for (dev = cg_upnp_controlpoint_getdevices(ctrlPoint); dev != NULL; dev = cg_upnp_device_next(dev)) { udn = cg_upnp_device_getudn(dev); /* Call device listener for each device */ if (udn != NULL && listener != NULL) { cg_upnp_controlpoint_unlock(ctrlPoint); listener(ctrlPoint, udn, CgUpnpDeviceStatusRemoved); cg_upnp_controlpoint_lock(ctrlPoint); } } /* Empty device cache */ cg_upnp_devicelist_clear(ctrlPoint->deviceList); cg_log_debug_s("Device list cleared.\n"); cg_upnp_controlpoint_unlock(ctrlPoint); cg_log_debug_l4("Leaving...\n"); return TRUE; }
char *cg_net_uri_unescapestring(char *buf, int bufSize, CgString *retBuf) { #if defined(CG_HTTP_CURL) char *tmp; #else int n; char hexStr[3]; long hex; unsigned char c; #endif int idx = 0; #if defined(CG_USE_NET_URI_ESCAPESTRING_SKIP) int tmpIdx = 0; #endif cg_log_debug_l4("Entering...\n"); if (!retBuf) return NULL; /* Check if URI is already escaped */ if (cg_net_uri_isescapedstring(buf + idx, bufSize) == TRUE) return buf; /* We can safely assume that the non-path part is already escaped */ #if defined(CG_USE_NET_URI_ESCAPESTRING_SKIP) idx = cg_strstr(buf, CG_NET_URI_PROTOCOL_DELIM); if (idx > 0) { idx = idx + cg_strlen(CG_NET_URI_PROTOCOL_DELIM); tmpIdx = cg_strstr(buf + idx, CG_NET_URI_SLASH_DELIM); if (tmpIdx > 0) idx += tmpIdx + cg_strlen(CG_NET_URI_SLASH_DELIM); } else { idx = 0; } #endif if (bufSize < 1) bufSize = cg_strlen(buf) + 1; #if defined(CG_HTTP_CURL) tmp = curl_unescape(buf + idx, 0); if (tmp == NULL) return NULL; cg_string_addvalue(retBuf, tmp); cg_log_debug_s("%s ==> %s\n", buf + idx, tmp); curl_free(tmp); #else for (n=0; n<bufSize;) { c = (unsigned char)buf[n]; if (buf[n] == '%' && cg_net_uri_isalphanumchar(buf[n+1]) && cg_net_uri_isalphanumchar(buf[n+2])) { hexStr[0] = buf[n+1]; hexStr[1] = buf[n+2]; hexStr[2] = '\0'; hex = strtol(hexStr, NULL, 16); c = (unsigned char)hex; n += 3; } else n++; cg_string_naddvalue(retBuf, (char *)&c, 1); } #endif cg_log_debug_l4("Leaving...\n"); return cg_string_getvalue(retBuf); }
CgHttpResponse *cg_http_request_post(CgHttpRequest *httpReq, char *ipaddr, int port) { CgHttpResponse *httpRes; BOOL newCurl = FALSE; CURL *curl; CgHttpHeader *reqHeader; struct curl_slist *curlHeaderList; CgString *headerStr; CURLcode res; char *uri, *method; char url[CG_NET_URI_MAXLEN]; long retcode; #ifdef CG_SHOW_TIMINGS struct timeval start_time, end_time, elapsed_time; #endif cg_log_debug_l4("Entering...\n"); #ifdef CG_SHOW_TIMINGS gettimeofday(&start_time, NULL); #endif httpRes = httpReq->httpRes; /* Clear the response data because new data will not * overwrite it, but it is appended to the end */ cg_string_clear(httpRes->content); cg_log_debug_s("Posting HTTP request (Curl)\n"); cg_http_request_print(httpReq); cg_http_persistentconnection_lock(); #ifdef CG_HTTP_USE_PERSISTENT_CONNECTIONS cg_log_debug_s("Looking for persistent connection to %s, port %d\n", ipaddr, port); curl = (CURL*)cg_http_persistentconnection_get(ipaddr, port); if (curl == NULL) { cg_log_debug_s("Persistent connection not found...\n"); #endif curl = curl_easy_init(); if (curl == NULL) { cg_http_persistentconnection_unlock(); return httpReq->httpRes; } #ifdef CG_HTTP_USE_PERSISTENT_CONNECTIONS newCurl = TRUE; } #endif method = cg_http_request_getmethod(httpReq); uri = cg_http_request_geturi(httpReq); /**** method ****/ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method); /**** url ****/ if (uri && cg_strstr(uri, CG_NET_URI_PROTOCOL_DELIM) > 0) { curl_easy_setopt(curl, CURLOPT_URL, uri); } else { cg_net_gethosturl(ipaddr, port, uri, url, sizeof(url)); curl_easy_setopt(curl, CURLOPT_URL, url); cg_log_debug_s("\n\nCURL: %s\n\n", url); } /**** header ****/ curlHeaderList = NULL; headerStr = cg_string_new(); for (reqHeader = cg_http_request_getheaders(httpReq); reqHeader; reqHeader = cg_http_header_next(reqHeader)) { cg_string_setvalue(headerStr, cg_http_header_getname(reqHeader)); if (cg_string_addvalue(headerStr, CG_HTTP_COLON CG_HTTP_SP) && cg_string_addvalue(headerStr, cg_http_header_getvalue(reqHeader))) curlHeaderList = curl_slist_append(curlHeaderList, cg_string_getvalue(headerStr)); } cg_string_delete(headerStr); /* Disable Expect header because it causes IOP issues */ curlHeaderList = curl_slist_append(curlHeaderList, "Expect:"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curlHeaderList); /**** content ****/ /*if (cg_http_request_ispostrequest(httpReq) == TRUE) {*/ if (cg_http_request_getcontentlength(httpReq) > 0) { curl_easy_setopt(curl, CURLOPT_POSTFIELDS, cg_http_request_getcontent(httpReq)); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, cg_http_request_getcontentlength(httpReq)); } else { curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0); } /* This has to be enabled for progress callback to be called */ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); /* Used for checking stack state during curl easy perform */ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, cg_http_request_progress_callback); /**** response header callback ****/ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, cg_http_request_header_callback); curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)httpRes); /**** response content callback ****/ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cg_http_request_content_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)httpRes); /**** useragent ****/ curl_easy_setopt(curl, CURLOPT_USERAGENT, cg_http_request_getuseragent(httpReq) ); /**** Prohibit curl from using signals ****/ curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); /**** Set the connection timeout so we don't wait forever ****/ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, CG_HTTP_CURL_CONNECTTIMEOUT); curl_easy_setopt(curl, CURLOPT_TIMEOUT, CG_HTTP_CONN_TIMEOUT); #ifdef CG_SHOW_TIMINGS cg_log_debug_s("\nRequest: %s%s%s\n", method, CG_HTTP_SP, url); #endif /* Get the XML document with CURL */ res = curl_easy_perform(curl); if (res != CURLE_OK) cg_log_debug_s("curl_easy_perform: %s\n", curl_easy_strerror(res)); /* Set the content length, if it wasn't said in the header */ if (cg_http_response_getcontentlength(httpRes) <= 0) { cg_http_response_setcontentlength(httpRes, cg_string_length(httpRes->content)); } curl_slist_free_all(curlHeaderList); curl_easy_getinfo (curl, CURLINFO_HTTP_CODE, &retcode); cg_http_response_setstatuscode(httpRes, retcode); #ifdef CG_SHOW_TIMINGS gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); cg_log_debug_s("Getting HTTP-response completed. Elapsed time: " "%ld msec\n", ((elapsed_time.tv_sec*1000) + (elapsed_time.tv_usec/1000))); cg_total_elapsed_time += (elapsed_time.tv_sec*1000000)+ (elapsed_time.tv_usec); #endif #ifdef CG_HTTP_USE_PERSISTENT_CONNECTIONS if (newCurl) { cg_log_debug_s("Putting new connection into cache: %s %d\n", ipaddr, port); cg_http_persistentconnection_put(ipaddr, port, curl); } #else curl_easy_cleanup(curl); #endif cg_http_persistentconnection_unlock(); cg_log_debug_s("Response for HTTP request (Curl)\n"); cg_http_response_print(httpReq->httpRes); return httpReq->httpRes; cg_log_debug_l4("Leaving...\n"); }
int cg_socket_recv(CgSocket *sock, CgDatagramPacket *dgmPkt) { int recvLen = 0; char recvBuf[CG_NET_SOCKET_DGRAM_RECV_BUFSIZE+1]; char remoteAddr[CG_NET_SOCKET_MAXHOST]; char remotePort[CG_NET_SOCKET_MAXSERV]; char *localAddr; #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) struct sockaddr_in from; W fromLen = sizeof(from); recvLen = so_recvfrom(sock->id, recvBuf, sizeof(recvBuf)-1, 0, (struct sockaddr *)&from, &fromLen); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) struct sockaddr_in from; int fromLen = sizeof(from); recvLen = ka_recvfrom(sock->id, recvBuf, sizeof(recvBuf)-1, 0, (struct sockaddr *)&from, &fromLen); #elif defined(ITRON) T_IPV4EP remoteHost; recvLen = udp_rcv_dat(sock->id, &remoteHost, recvBuf, sizeof(recvBuf)-1, TMO_FEVR); #else struct sockaddr_storage from; socklen_t fromLen = sizeof(from); recvLen = recvfrom(sock->id, recvBuf, sizeof(recvBuf)-1, 0, (struct sockaddr *)&from, &fromLen); #endif cg_log_debug_l4("Entering...\n"); if (recvLen <= 0) return 0; recvBuf[recvLen] = '\0'; cg_socket_datagram_packet_setdata(dgmPkt, recvBuf); cg_socket_datagram_packet_setlocalport(dgmPkt, cg_socket_getport(sock)); cg_socket_datagram_packet_setremoteaddress(dgmPkt, ""); cg_socket_datagram_packet_setremoteport(dgmPkt, 0); #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) cg_socket_datagram_packet_setlocaladdress(dgmPkt, cg_socket_getaddress(sock)); cg_socket_datagram_packet_setremoteaddress(dgmPkt, inet_ntoa(from.sin_addr)); cg_socket_datagram_packet_setremoteport(dgmPkt, ntohl(from.sin_port)); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) cg_socket_datagram_packet_setlocaladdress(dgmPkt, cg_socket_getaddress(sock)); ka_tfInetToAscii((unsigned long)from.sin_addr.s_addr, remoteAddr); cg_socket_datagram_packet_setremoteaddress(dgmPkt, remoteAddr); cg_socket_datagram_packet_setremoteport(dgmPkt, ka_ntohl(from.sin_port)); #elif defined(ITRON) cg_socket_datagram_packet_setlocaladdress(dgmPkt, cg_socket_getaddress(sock)); ipaddr_to_ascii(remoteAddr, remoteHost.ipaddr); cg_socket_datagram_packet_setremoteaddress(dgmPkt, remoteAddr); cg_socket_datagram_packet_setremoteport(dgmPkt, ntohs(remoteHost.portno)); #else if (getnameinfo((struct sockaddr *)&from, fromLen, remoteAddr, sizeof(remoteAddr), remotePort, sizeof(remotePort), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { cg_socket_datagram_packet_setremoteaddress(dgmPkt, remoteAddr); cg_socket_datagram_packet_setremoteport(dgmPkt, atol(remotePort)); } cg_log_debug_s("From pointer %p\n", &from); localAddr = cg_net_selectaddr((struct sockaddr *)&from); cg_socket_datagram_packet_setlocaladdress(dgmPkt, localAddr); free(localAddr); #endif cg_log_debug_l4("Leaving...\n"); return recvLen; }
int cg_socket_sendto(CgSocket *sock, char *addr, int port, char *data, int dataLen) { #if defined(BTRON) || defined(TENGINE) struct sockaddr_in sockaddr; #elif defined(ITRON) T_IPV4EP dstaddr; T_UDP_CCEP udpccep = { 0, { IPV4_ADDRANY, UDP_PORTANY }, (FP)cg_socket_udp_callback }; #else struct addrinfo *addrInfo; #endif int sentLen; BOOL isBoundFlag; cg_log_debug_l4("Entering...\n"); if (data == NULL) return 0; if (dataLen < 0) dataLen = cg_strlen(data); if (dataLen <= 0) return 0; isBoundFlag = cg_socket_isbound(sock); sentLen = -1; #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) if (cg_socket_tosockaddrin(addr, port, &sockaddr, TRUE) == FALSE) return -1; if (isBoundFlag == FALSE) cg_socket_setid(sock, so_socket(PF_INET, cg_socket_getrawtype(sock), 0)); if (0 <= sock->id) sentLen = so_sendto(sock->id, (B*)data, dataLen, 0, (SOCKADDR*)&sockaddr, sizeof(struct sockaddr_in)); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) if (cg_socket_tosockaddrin(addr, port, &sockaddr, TRUE) == FALSE) return -1; if (isBoundFlag == FALSE) { cg_socket_setid(sock, ka_socket(PF_INET, cg_socket_getrawtype(sock), cg_socket_getprototype(sock))); cg_socket_setmulticastinterface(sock, NULL); } if (0 <= sock->id) sentLen = ka_sendto(sock->id, data, dataLen, 0, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr_in)); #elif defined(ITRON) if (isBoundFlag == FALSE) { cg_socket_setid(sock, cg_socket_getavailableid(cg_socket_issocketstream(sock))); if (sock->id < 0) return FALSE; if (udp_cre_cep(sock->id, &udpccep) != E_OK) return FALSE; } dstaddr.ipaddr = ascii_to_ipaddr(addr); dstaddr.portno = htons(port); sentLen = udp_snd_dat(sock->id, &dstaddr, data, dataLen, TMO_FEVR); #else if (cg_socket_tosockaddrinfo(cg_socket_getrawtype(sock), addr, port, &addrInfo, TRUE) == FALSE) return -1; if (isBoundFlag == FALSE) cg_socket_setid(sock, socket(addrInfo->ai_family, addrInfo->ai_socktype, 0)); /* Setting multicast time to live in any case to default */ cg_socket_setmulticastttl(sock, CG_UPNP_SSDP_MULTICAST_DEFAULT_TTL); if (0 <= sock->id) sentLen = sendto(sock->id, data, dataLen, 0, addrInfo->ai_addr, addrInfo->ai_addrlen); freeaddrinfo(addrInfo); #endif if (isBoundFlag == FALSE) cg_socket_close(sock); #ifdef SOCKET_DEBUG cg_log_debug_s("sentLen : %d\n", sentLen); #endif cg_log_debug_l4("Leaving...\n"); return sentLen; }
/** * Callback function for CURL to read each HTTP header line * CgStringTokenizer might have been a viable choice to do the parsing * of various fields. Then again, it would not have read correctly a * header line with, for example, the time (because of multiple use of colons): * Foo: 12:34:56 EEST DST */ static size_t cg_http_request_header_callback(void *ptr, size_t size, size_t nmemb, void *stream) { char* headerLine = NULL; char* name = NULL; char* value = NULL; CgStringTokenizer* strTok = NULL; CgHttpResponse* httpRes = NULL; int head = 0; int tail = 0; cg_log_debug_l4("Entering...\n"); if (stream == NULL || ptr == NULL) { return 0; } httpRes = (CgHttpResponse*) stream; headerLine = (char*) ptr; /* Read header items */ if (cg_strncmp(headerLine, CG_HTTP_VER11, cg_strlen(CG_HTTP_VER11)) == 0 || cg_strncmp(headerLine, CG_HTTP_VER10, cg_strlen(CG_HTTP_VER10)) == 0) { /* <HTTP/version> <status code> <reason phrase> */ strTok = cg_string_tokenizer_new(headerLine, CG_HTTP_STATUSLINE_DELIM); if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) { cg_http_response_setversion(httpRes, cg_string_tokenizer_nexttoken(strTok)); } if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) { cg_http_response_setstatuscode(httpRes, atoi(cg_string_tokenizer_nexttoken(strTok))); } if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE) { value = cg_string_tokenizer_nextalltoken(strTok); cg_strrtrim(value, CG_HTTP_STATUSLINE_DELIM, cg_strlen(CG_HTTP_STATUSLINE_DELIM)); cg_http_response_setreasonphrase(httpRes, value); } cg_string_tokenizer_delete(strTok); } else { /* Find the header delimiter */ for (head = 0; head < size * nmemb; head++) { if (headerLine[head] == ':') { break; } } /* Unable to find a colon, this is not a valid header line */ if (head <= 0 || head >= (size * nmemb) - 1) { return size * nmemb; } /* Take the header name */ name = (char*) malloc(head + 1); if ( NULL == name ) { cg_log_debug_s("Memory allocation failure!\n"); return 0; } memcpy(name, headerLine, head); name[head] = '\0'; /* Skip colon and space(s) */ for (head++; head < size * nmemb; head++) { if (headerLine[head] != 0x20) { break; } } /* Unable to find anything sensible anymore */ if (head >= (size * nmemb) - 1) { return size * nmemb; } /* Find the end of the actual value, without CRLF */ for (tail = size * nmemb; tail > 0; tail --) { if (headerLine[tail] == '\r') { break; } else if (headerLine[tail] == '\n') { if (tail > 0 && headerLine[tail - 1] == '\r') { tail--; break; } } } /* Unable to find CRLF */ if (tail <= head) { free(name); return size * nmemb; } /* Take the header value */ value = (char*) malloc(tail - head + 1); if ( NULL == value ) { cg_log_debug_s("Memory allocation failure!\n"); return 0; } memcpy(value, headerLine + head, tail - head); value[tail - head] = '\0'; /* Set the header value to the response */ cg_http_response_setheadervalue(httpRes, name, value); free(name); free(value); } return size * nmemb; cg_log_debug_l4("Leaving...\n"); }
BOOL cg_http_packet_read_body(CgHttpPacket *httpPkt, CgSocket *sock, char *lineBuf, size_t lineBufSize) { ssize_t readLen; ssize_t conLen; char *content; char readBuf[READBUF_LENGTH + 1]; int tries = 0; cg_log_debug_l4("Entering...\n"); conLen = cg_http_packet_getcontentlength(httpPkt); content = NULL; if (0 < conLen) { content = (char *)malloc(conLen+1); if (content == NULL) { cg_log_debug_s("Memory allocation problem!\n"); return FALSE; } content[0] = '\0'; readLen = 0; /* Read content until conLen is reached, or tired of trying */ while (readLen < conLen && tries < 20) { readLen += cg_socket_read(sock, (content+readLen), (conLen-readLen)); /* Fixed to increment the counter only when cg_socket_read() doesn't read data */ if (readLen <= 0) tries++; } if (readLen <= 0) return TRUE; content[readLen] = '\0'; cg_http_packet_setcontentpointer(httpPkt, content, readLen); } else if (cg_http_packet_getheadervalue(httpPkt, CG_HTTP_CONTENT_LENGTH) == NULL) { /* header existance must be checked! otherwise packets which rightly report 0 as content length, will jam the http */ /* Check if we read chunked encoding */ if (cg_http_packet_ischunked(httpPkt) == TRUE) { conLen = 0; do { readLen = cg_http_packet_read_chunk(httpPkt, sock, lineBuf, lineBufSize); conLen += readLen; } while (readLen > 0); cg_http_packet_setcontentlength(httpPkt,conLen); } else { readLen = 0; conLen = 0; while ((readLen = cg_socket_read(sock, readBuf, READBUF_LENGTH)) > 0) { cg_http_packet_appendncontent(httpPkt, readBuf, readLen); conLen += readLen; } cg_http_packet_setcontentlength(httpPkt, conLen); } } cg_log_debug_l4("Leaving...\n"); return TRUE; }
static int filter_duplicate_m_search(CgUpnpSSDPPacket *ssdpPkt) { CgSysTime *timestamps = ssdpPkt->timestamps; int loc, s_length; char *id_string, *r_address, *st, port[6]; CgSysTime curr_time; cg_log_debug_l4("Entering...\n"); /* Initializing hash table to zero */ if (!ssdpPkt->initialized) { ssdpPkt->initialized = 1; memset(timestamps, '\0', CG_UPNP_SSDP_FILTER_TABLE_SIZE * sizeof( CgSysTime )); } r_address = cg_string_getvalue(ssdpPkt->dgmPkt->remoteAddress); st = cg_upnp_ssdp_packet_getst(ssdpPkt); sprintf(port, "%d", ssdpPkt->dgmPkt->remotePort); /* Catenating remote address string with ssdp ST header field. */ s_length = strlen( r_address ) + strlen( st ) + strlen( port ); id_string = (char *)malloc( s_length + 1 ); if ( NULL == id_string ) { cg_log_debug_s("Memory allocation problem!\n"); return FALSE; } memset(id_string, '\0', s_length + 1); cg_strcat(id_string, r_address ); cg_strcat(id_string, port); cg_strcat(id_string, st ); loc = simple_string_hash(id_string, CG_UPNP_SSDP_FILTER_TABLE_SIZE); cg_log_debug("Calculated hash: %d\n", loc); free(id_string); curr_time = cg_getcurrentsystemtime(); if ( 0 == timestamps[loc] ) { timestamps[loc] = curr_time; cg_log_debug("First packet... Updating hash table.\n"); return FALSE; } else if ( ( curr_time - timestamps[loc] ) < CG_UPNP_DEVICE_M_SEARCH_FILTER_INTERVAL ) { cg_log_debug("Filtering packet!\n"); timestamps[loc] = curr_time; return TRUE; } else { timestamps[loc] = curr_time; cg_log_debug("Old timestamp found, just updating it.\n"); return FALSE; } cg_log_debug_l4("Leaving...\n"); }
static void cg_http_server_clientthread(CgThread *thread) { CgHttpServerClientData *clientData; CgHttpServer *httpServer; CgSocket *clientSock; void *httpServerUserData; CgHttpRequest *httpReq; char *version = NULL; cg_log_debug_l4("Entering...\n"); clientData = (CgHttpServerClientData *)cg_thread_getuserdata(thread); httpServer = clientData->httpServer; clientSock = clientData->clientSock; httpServerUserData = cg_http_server_getuserdata(httpServer); httpReq = cg_http_request_new(); cg_http_request_setsocket(httpReq, clientSock); /**** Thanks for Makela Aapo (10/31/05) ****/ while (cg_http_request_read(httpReq, clientSock) == TRUE && cg_thread_isrunnable(thread) == TRUE) { /* Check some validity of the request */ version = cg_http_request_getversion(httpReq); if (cg_strcmp(version, CG_HTTP_VER11) == 0) { /* According to HTTP/1.1 spec, we must not tolerate HTTP/1.1 request without HOST-header */ if (cg_http_request_gethost(httpReq) == NULL) { cg_http_request_postbadrequest(httpReq); continue; } } if (httpServer->listener != NULL) { cg_http_request_setuserdata(httpReq, httpServerUserData); httpServer->listener(httpReq); } /* Close connection according to HTTP version and headers */ if (cg_strcmp(version, CG_HTTP_VER10) == 0) { /* Terminate connection after HTTP/1.0 request */ break; } /* We are having HTTP/1.1 or better => terminate, if requested */ if (cg_http_request_iskeepaliveconnection(httpReq) == FALSE) { break; } } cg_log_debug_s("Dropping HTTP client\n"); cg_http_request_delete(httpReq); cg_socket_close(clientSock); cg_socket_delete(clientSock); cg_http_server_clientdata_delete(clientData); cg_thread_setuserdata(thread, NULL); // This code frequently crashes. mutex lock referencing free'd memory. cg_http_server_lock(httpServer); cg_thread_remove(thread); cg_http_server_unlock(httpServer); cg_log_debug_l4("Leaving...\n"); cg_thread_delete(thread); }
int cg_socket_write(CgSocket *sock, char *cmd, int cmdLen) { int nSent; int nTotalSent = 0; int cmdPos = 0; int retryCnt = 0; cg_log_debug_l4("Entering...\n"); if (cmdLen <= 0) return 0; do { #if defined(CG_USE_OPENSSL) if (cg_socket_isssl(sock) == FALSE) { #endif #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) nSent = so_send(sock->id, (B*)(cmd + cmdPos), cmdLen, 0); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) nSent = ka_send(sock->id, (B*)(cmd + cmdPos), cmdLen, 0); #elif defined(ITRON) nSent = tcp_snd_dat(sock->id, cmd + cmdPos, cmdLen, TMO_FEVR); #else nSent = send(sock->id, cmd + cmdPos, cmdLen, 0); #endif #if defined(CG_USE_OPENSSL) } else { nSent = SSL_write(sock->ssl, cmd + cmdPos, cmdLen); } #endif /* Try to re-send in case sending has failed */ if (nSent <= 0) { retryCnt++; if (CG_NET_SOCKET_SEND_RETRY_CNT < retryCnt) { /* Must reset this because otherwise return value is interpreted as something else than fault and this function loops forever */ nTotalSent = 0; break; } cg_wait(CG_NET_SOCKET_SEND_RETRY_WAIT_MSEC); } else { nTotalSent += nSent; cmdPos += nSent; cmdLen -= nSent; retryCnt = 0; } } while (0 < cmdLen); #ifdef SOCKET_DEBUG cg_log_debug_s("w %d : %s\n", nTotalSent, ((cmd != NULL) ? cmd : "")); #endif cg_log_debug_l4("Leaving...\n"); return nTotalSent; }
CgHttpResponse *cg_http_request_post_main(CgHttpRequest *httpReq, char *ipaddr, int port, BOOL isSecure) { CgSocket *sock; char *method, *uri, *version; #ifdef CG_SHOW_TIMINGS struct timeval start_time, end_time, elapsed_time; #endif CgString *firstLine; cg_log_debug_l4("Entering...\n"); #ifdef CG_SHOW_TIMINGS gettimeofday(&start_time, NULL); #endif cg_http_response_clear(httpReq->httpRes); cg_log_debug_s("(HTTP) Posting:\n"); cg_http_request_print(httpReq); #if defined(CG_USE_OPENSSL) if (isSecure == FALSE) sock = cg_socket_stream_new(); else sock = cg_socket_ssl_new(); #else sock = cg_socket_stream_new(); #endif cg_socket_settimeout(sock, cg_http_request_gettimeout(httpReq)); if (cg_socket_connect(sock, ipaddr, port) == FALSE) { cg_socket_delete(sock); return httpReq->httpRes; } cg_http_request_sethost(httpReq, ipaddr, port); cg_http_packet_setheadervalue((CgHttpPacket*)httpReq, CG_HTTP_USERAGENT, cg_http_request_getuseragent(httpReq)); method = cg_http_request_getmethod(httpReq); uri = cg_http_request_geturi(httpReq); version = cg_http_request_getversion(httpReq); if (method == NULL || uri == NULL || version == NULL) { cg_socket_close(sock); cg_socket_delete(sock); return httpReq->httpRes; } #ifdef CG_SHOW_TIMINGS cg_log_debug_s("\nRequest: %s%s%s:%d%s%s%s\n", method, CG_HTTP_SP, ipaddr, port, uri, CG_HTTP_SP, version); #endif /**** send first line ****/ firstLine = cg_string_new(); cg_string_addvalue(firstLine, method); cg_string_addvalue(firstLine, CG_HTTP_SP); cg_string_addvalue(firstLine, uri); cg_string_addvalue(firstLine, CG_HTTP_SP); cg_string_addvalue(firstLine, version); cg_string_addvalue(firstLine, CG_HTTP_CRLF); cg_socket_write(sock, cg_string_getvalue(firstLine), cg_string_length(firstLine)); cg_string_delete(firstLine); /**** send header and content ****/ cg_http_packet_post((CgHttpPacket *)httpReq, sock); /**** read response ****/ cg_http_response_read(httpReq->httpRes, sock, cg_http_request_isheadrequest(httpReq)); #ifdef CG_SHOW_TIMINGS gettimeofday(&end_time, NULL); timersub(&end_time, &start_time, &elapsed_time); cg_log_debug_s("Getting HTTP-response completed. Elapsed time: " "%ld msec\n", ((elapsed_time.tv_sec*1000) + (elapsed_time.tv_usec/1000))); cg_total_elapsed_time += (elapsed_time.tv_sec*1000000)+ (elapsed_time.tv_usec); #endif cg_socket_close(sock); cg_socket_delete(sock); cg_http_response_print(httpReq->httpRes); cg_log_debug_l4("Leaving...\n"); return httpReq->httpRes; }
CgXmlNode *cg_soap_request_getbodynode(CgSoapRequest *soapReq) { CgXmlNode *envNode; CgXmlNode *bodyNode = NULL; CgXmlAttribute *attr; char *name; CgStringTokenizer *tok; char *nsPrefix; size_t bodyLen; char *body; cg_log_debug_l4("Entering...\n"); envNode = cg_soap_request_getenvelopenode(soapReq); if (envNode == NULL) return NULL; if (cg_xml_node_haschildnodes(envNode) == FALSE) return NULL; /* We cannot assume the namespace prefix for Body is 's'. According to spec, it could be anything... */ for (attr = cg_xml_node_getattributes(envNode); attr != NULL; attr = cg_xml_attribute_next(attr)) { /* First, find the namespace declaration attribute. */ /* Note: We must take a copy of the attr name. Tokenizer doesn't do it (by default) */ name = cg_strdup( cg_xml_attribute_getname(attr) ); tok = cg_string_tokenizer_new(name, ":"); nsPrefix = cg_string_tokenizer_nexttoken(tok); if ( -1 != cg_strstr(nsPrefix, "xmlns")) { /* This attribute is a namespace declaration. Check is it the one defined for SOAP. */ if (cg_strcmp(cg_xml_attribute_getvalue(attr), CG_SOAP_XMLNS_URL) == 0) { /* This namespace declaration is correct. Use it to find the body node... */ if (cg_string_tokenizer_hasmoretoken(tok)) { /* There is a prefix */ nsPrefix = cg_string_tokenizer_nexttoken(tok); bodyLen = cg_strlen(nsPrefix) + cg_strlen(CG_SOAP_DELIM) + cg_strlen(CG_SOAP_BODY) + 1; /* +1 for trailing '\0'*/ body = (char*)malloc(bodyLen); if ( NULL == body ) { cg_log_debug_s("Memory allocation failure!\n"); return NULL; } #if defined(HAVE_SNPRINTF) snprintf(body, bodyLen, "%s%s%s", nsPrefix, CG_SOAP_DELIM, CG_SOAP_BODY); #else sprintf(body, "%s%s%s", nsPrefix, CG_SOAP_DELIM, CG_SOAP_BODY); #endif bodyNode = cg_xml_node_getchildnode(envNode, body); free(body); } else { /* No prefix */ bodyNode = cg_xml_node_getchildnode(envNode, CG_SOAP_BODY); } /* Free memory before leaving the loop */ cg_string_tokenizer_delete(tok); free(name); break; } } cg_string_tokenizer_delete(tok); free(name); } cg_log_debug_l4("Leaving...\n"); return bodyNode; }
BOOL cg_socket_accept(CgSocket *serverSock, CgSocket *clientSock) { struct sockaddr_in sockaddr; socklen_t socklen; char localAddr[CG_NET_SOCKET_MAXHOST]; char localPort[CG_NET_SOCKET_MAXSERV]; #if defined(BTRON) || (defined(TENGINE) && !defined(CG_TENGINE_NET_KASAGO)) struct sockaddr_in sockaddr; W nLength = sizeof(struct sockaddr_in); cg_socket_setid(clientSock, so_accept(serverSock->id, (SOCKADDR *)&sockaddr, &nLength)); #elif defined(TENGINE) && defined(CG_TENGINE_NET_KASAGO) struct sockaddr_in sockaddr; int nLength = sizeof(struct sockaddr_in); cg_socket_setid(clientSock, ka_accept(serverSock->id, (struct sockaddr *)&sockaddr, &nLength)); #elif defined(ITRON) T_IPV4EP dstAddr; if (tcp_acp_cep(serverSock->id, serverSock->id, &dstAddr, TMO_FEVR) != E_OK) return FALSE; cg_socket_setid(clientSock, cg_socket_getid(serverSock)); #else struct sockaddr_storage sockClientAddr; socklen_t nLength = sizeof(sockClientAddr); cg_socket_setid(clientSock, accept(serverSock->id, (struct sockaddr *)&sockClientAddr, &nLength)); #endif cg_log_debug_l4("Entering...\n"); #ifdef SOCKET_DEBUG cg_log_debug_s("clientSock->id = %d\n", clientSock->id); #endif #if defined (WIN32) && !defined(ITRON) if (clientSock->id == INVALID_SOCKET) return FALSE; #else if (clientSock->id < 0) return FALSE; #endif cg_socket_setaddress(clientSock, cg_socket_getaddress(serverSock)); cg_socket_setport(clientSock, cg_socket_getport(serverSock)); socklen = sizeof(struct sockaddr_in); if (getsockname(clientSock->id, (struct sockaddr *)&sockaddr, &socklen) == 0 && getnameinfo((struct sockaddr *)&sockaddr, socklen, localAddr, sizeof(localAddr), localPort, sizeof(localPort), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { /* Set address for the sockaddr to real addr */ cg_socket_setaddress(clientSock, localAddr); } #ifdef SOCKET_DEBUG cg_log_debug_s("clientSock->id = %s\n", cg_socket_getaddress(clientSock)); cg_log_debug_s("clientSock->id = %d\n", cg_socket_getport(clientSock)); #endif return TRUE; cg_log_debug_l4("Leaving...\n"); }