Beispiel #1
0
char *cg_upnp_ssdprequest_tostring(CgUpnpSSDPRequest *ssdpReq, CgString *ssdpMsg)
{
	CgHttpHeader *header;
	const char *name;
	const char *value;
	
	cg_log_debug_l4("Entering...\n");

	cg_string_addvalue(ssdpMsg, cg_http_request_getmethod(ssdpReq));
	cg_string_addvalue(ssdpMsg, CG_HTTP_SP);
	cg_string_addvalue(ssdpMsg, cg_http_request_geturi(ssdpReq));
	cg_string_addvalue(ssdpMsg, CG_HTTP_SP);
	cg_string_addvalue(ssdpMsg, cg_http_request_getversion(ssdpReq));
	cg_string_addvalue(ssdpMsg, CG_HTTP_CRLF);
	
	for (header = cg_http_packet_getheaders((CgHttpPacket *)ssdpReq); header != NULL; header = cg_http_header_next(header)) {
		name = cg_http_header_getname(header);
		value = cg_http_header_getvalue(header);
		cg_string_addvalue(ssdpMsg, name);
		cg_string_addvalue(ssdpMsg, CG_HTTP_COLON);
		cg_string_addvalue(ssdpMsg, CG_HTTP_SP);
		cg_string_addvalue(ssdpMsg, value);
		cg_string_addvalue(ssdpMsg, CG_HTTP_CRLF);
	}
	cg_string_addvalue(ssdpMsg, CG_HTTP_CRLF);
	
	return cg_string_getvalue(ssdpMsg);

	cg_log_debug_l4("Leaving...\n");
}
Beispiel #2
0
void cg_http_request_copy(CgHttpRequest *destHttpReq, CgHttpRequest *srcHttpReq)
{
    cg_log_debug_l4("Entering...\n");

    cg_http_request_setmethod(destHttpReq, cg_http_request_getmethod(srcHttpReq));
    cg_http_request_seturi(destHttpReq, cg_http_request_geturi(srcHttpReq));
    cg_http_request_setversion(destHttpReq, cg_http_request_getversion(srcHttpReq));

    cg_http_packet_copy((CgHttpPacket *)destHttpReq, (CgHttpPacket *)srcHttpReq);

    cg_log_debug_l4("Leaving...\n");
}
Beispiel #3
0
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");
}
void cg_upnp_dms_youtube_http_listener(CgHttpRequest *httpReq)
{
	CgUpnpMediaServer *dms;
	CgUpnpDevice *dev;
	char *httpURI;
	int contentMD5Idx;
	char *contentMd5;
	CgHttpResponse *httpRes;
	CgSocket *sock;
	char chunkedChar[32];
	BOOL isHeadRequest;
	struct stat fileStat;
	off_t fileSize;
	FILE *fp;
	char readBuf[CG_FILE_READ_CHUNK_SIZE];
	off_t nRead;
	off_t nReadCnt;
	off_t nWroteCnt;
	char contentFile[CG_MD5_STRING_BUF_SIZE+8];

	dev = (CgUpnpDevice *)cg_http_request_getuserdata(httpReq);
	if (!dev) {
		cg_http_request_postbadrequest(httpReq);
		return;
	}

	dms = (CgUpnpMediaServer *)cg_upnp_device_getuserdata(dev);
	if (!dms) {
		cg_http_request_postbadrequest(httpReq);
		return;
	}

	httpURI = cg_http_request_geturi(httpReq);
	if (cg_strlen(httpURI) <= 0) {
		cg_http_request_postbadrequest(httpReq);
		return;
	}

	if (cg_strstr(httpURI, CG_UPNP_MEDIA_YOUTUBE_RESURL_PATH) < 0) {
		cg_upnp_device_httprequestrecieved(httpReq);
		return;
	}

	contentMD5Idx = cg_strrchr(httpURI, "/", 1);
	
	if (contentMD5Idx < 0) {
		cg_http_request_postbadrequest(httpReq);
		return;
	}
	
	contentMd5 = httpURI + contentMD5Idx + 1;
	cg_strcpy(contentFile, contentMd5);
	cg_strcat(contentFile, "." CG_UPNP_MEDIA_YOUTUBE_TRANSCODE_FILEEXT);

	cg_upnp_dms_lock(dms);

	isHeadRequest = cg_http_request_isheadrequest(httpReq);
	
	httpRes = cg_http_response_new();
#if defined(CG_USE_CHUNKED_STREAM)
	cg_http_response_setversion(httpRes, CG_HTTP_VER11);
#else
	cg_http_response_setversion(httpRes, CG_HTTP_VER10);
#endif
	cg_http_response_setstatuscode(httpRes, CG_HTTP_STATUS_OK);
	cg_http_response_setcontenttype(httpRes, CG_UPNP_MEDIA_YOUTUBE_CONTENT_MIMETYPE);
	
	sock = cg_http_request_getsocket(httpReq);
	cg_socket_settimeout(sock, 0);

	fileSize = 0;
	if (stat(contentFile, &fileStat) == 0)
		fileSize = fileStat.st_size;
#if defined(CG_USE_CHUNKED_STREAM)
	cg_http_packet_setheadervalue((CgHttpPacket*)httpRes, "Transfer-Encoding", "chunked");
#else
	cg_http_response_setcontentlength(httpRes, fileSize);
#endif
	cg_http_request_postresponse(httpReq, httpRes);

	if (0 < fileSize) {		
		nReadCnt = 0;
		nWroteCnt = 0;
		fp = fopen(contentFile, "rb");
		if (fp) {
			nRead = fread(readBuf, sizeof(char), CG_FILE_READ_CHUNK_SIZE, fp);
			while (nReadCnt < fileSize && 0 < nRead) {
				nReadCnt += nRead;
#if defined(CG_USE_CHUNKED_STREAM)
				sprintf(chunkedChar, "%x%s", nRead, CG_HTTP_CRLF);
				cg_socket_write(sock, chunkedChar, cg_strlen(chunkedChar));
#endif
				nWroteCnt += cg_socket_write(sock, readBuf, nRead);
#if defined(CG_USE_CHUNKED_STREAM)
				cg_socket_write(sock, CG_HTTP_CRLF, sizeof(CG_HTTP_CRLF)-1);
#endif
				nRead = fread(readBuf, sizeof(char), CG_FILE_READ_CHUNK_SIZE, fp);
			}
			fclose(fp);
		}
	}
	
#if defined(CG_USE_CHUNKED_STREAM)
	sprintf(chunkedChar, "%x%s", 0, CG_HTTP_CRLF);
	cg_socket_write(sock, chunkedChar, cg_strlen(chunkedChar));
#endif
	
	cg_socket_close(sock);
	cg_http_response_delete(httpRes);

	cg_upnp_dms_unlock(dms);
}
Beispiel #5
0
void upnp_clock_device_httprequestrecieved(CgHttpRequest *httpReq)
{
    CgTime currTime;
    CgUpnpDevice *dev;
    char *uri;
    char content[2048];
    char sysTimeStr[SYSTEM_TIME_BUF_LEN];
    char serverName[CG_UPNP_SEVERNAME_MAXLEN];
    CgHttpResponse *httpRes;
    BOOL postRet;

    dev = (CgUpnpDevice *)cg_http_request_getuserdata(httpReq);

    uri = cg_http_request_geturi(httpReq);
    if (strcmp(uri, "/presentation") != 0) {
        cg_upnp_device_httprequestrecieved(httpReq);
        return;
    }

    currTime = cg_getcurrentsystemtime();

#if defined(HAVE_SNPRINTF)
    snprintf(content, sizeof(content),
#else
    sprintf(content,
#endif
             "<HTML>"
             "<HEAD>"
             "<TITLE>UPnP Clock Sample</TITLE>"
             "</HEAD>"
             "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"1; URL=/presentation\">"
             "<BODY><CENTER>"
             "<H1>UPnP Clock Sample</H1>"
             "<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"
             "<TR>"
             "<TD style=\"width: 50px; height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "<TD style=\"background-color: rgb(176, 176, 176);\"></TD>"
             "<TD style=\"width: 50px; height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "</TR>"
             "<TR>"
             "<TD style=\"height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "<TD style=\"height: 50px; background-color: rgb(221, 236, 245);\" align=\"center\"><H1>"
             "%s"
             "</H1></TD>"
             "<TD style=\"height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "</TR>"
             "<TR>"
             "<TD style=\"height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "<TD style=\"height: 50px; background-color: rgb(221, 236, 245);\" align=\"center\"><H3>"
             "Server : %s"
             "</H3></TD>"
             "<TD style=\"height: 30px; background-color: rgb(176, 176, 176);\"></TD>"
             "</TR>"
             "<TR>"
             "<TD style=\"width: 30px; height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "<TD style=\"background-color: rgb(176, 176, 176);\"></TD>"
             "<TD style=\"width: 30px; height: 50px; background-color: rgb(176, 176, 176);\"></TD>"
             "</TR>"
             "</TABLE>"
             "<CENTER></BODY>"
             "</HTML>",
             GetSystemTimeString(currTime, sysTimeStr),
             cg_upnp_getservername(serverName, sizeof(serverName)));

    httpRes = cg_http_response_new();
    cg_http_response_setstatuscode(httpRes, CG_HTTP_STATUS_OK);
    cg_http_response_setcontent(httpRes, content);
    cg_http_response_setcontenttype(httpRes, "text/html");
    cg_http_response_setcontentlength(httpRes, strlen(content));
    postRet = cg_http_request_postresponse(httpReq, httpRes);
    cg_http_response_delete(httpRes);
}
Beispiel #6
0
BOOL cg_http_request_read(CgHttpRequest *httpReq, CgSocket *sock)
{
    char lineBuf[CG_HTTP_READLINE_BUFSIZE];
    CgStringTokenizer *strTok;
    int readLen;
    CgNetURI *uri = NULL;
    BOOL failed = FALSE;

    cg_log_debug_l4("Entering...\n");

    cg_http_request_clear(httpReq);

    /* If first character(s) is \n or \r\n we ignore it(them) and read second line. */
    do {
        readLen = cg_socket_readline(sock, lineBuf, sizeof(lineBuf));
    } while (readLen >= 1 && readLen <=2);

    if (readLen <= 0)
        return FALSE;

    strTok = cg_string_tokenizer_new(lineBuf, CG_HTTP_STATUSLINE_DELIM);
    if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        cg_http_request_setmethod(httpReq, cg_string_tokenizer_nexttoken(strTok));
    else
        failed = TRUE;
    if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        cg_http_request_seturi(httpReq, cg_string_tokenizer_nexttoken(strTok));
    else
        failed = TRUE;
    if (cg_string_tokenizer_hasmoretoken(strTok) == TRUE)
        cg_http_request_setversion(httpReq, cg_string_tokenizer_nexttoken(strTok));
    else
        failed = TRUE;
    cg_string_tokenizer_delete(strTok);

    if (failed == TRUE) return FALSE;

    /* We could do some further validation for the HTTP-request? */

    /* Change URI to be relative (absolute not needed anymore) */
    uri = cg_net_uri_new();
    if (uri != NULL)
    {
        cg_net_uri_set(uri, cg_http_request_geturi(httpReq));
        if (cg_net_uri_isabsolute(uri) == TRUE &&
                cg_net_uri_getrequest(uri) != NULL)
        {
            cg_http_request_seturi(httpReq,
                                   cg_net_uri_getrequest(uri));
        }
        cg_net_uri_delete(uri);
        uri = NULL;
    }

    /* Read headers */
    cg_http_packet_clear((CgHttpPacket *)httpReq);
    cg_http_packet_read_headers((CgHttpPacket *)httpReq, sock, lineBuf, sizeof(lineBuf));

    /* HTTP-request must have Content-Length or Transfer-Encoding header
       in order to have body */
    if (cg_http_packet_hasheader((CgHttpPacket *)httpReq, CG_HTTP_CONTENT_LENGTH) ||
            cg_http_packet_hasheader((CgHttpPacket *)httpReq, CG_HTTP_TRANSFER_ENCODING))
        cg_http_packet_read_body((CgHttpPacket *)httpReq, sock, lineBuf, sizeof(lineBuf));

    cg_log_debug_l4("Leaving...\n");

    return TRUE;
}
Beispiel #7
0
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");
}
Beispiel #8
0
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;
}