예제 #1
0
bool husthttp_t::open2 (
                         std::string & method,
                         std::string & path,
                         std::string & query_string,
                         std::string & data,
                         int conn_timeout,
                         int recv_timeout
                         )
{
    if ( unlikely ( ! m_h ) )
    {
        m_h = http_create ();
        if ( ! m_h )
        {
            return false;
        }
    }

    if ( unlikely ( method.empty () || path.empty () ) )
    {
        return false;
    }

    if ( m_method.compare ( method ) != 0 )
    {
        m_method = method;
    }

    if ( m_path.compare ( path ) != 0 )
    {
        m_path = path;
    }

    if ( query_string.size () <= 0 )
    {
        m_query_string.resize ( 0 );
    }
    else if ( m_query_string.compare ( query_string ) != 0 )
    {
        m_query_string = query_string;
    }

    m_data.resize ( 0 );
    if ( data.size () > 0 )
    {
        m_data = data;
    }

    if ( conn_timeout > 0 )
    {
        m_conn_timeout = conn_timeout;
    }

    if ( recv_timeout > 0 )
    {
        m_recv_timeout = recv_timeout;
    }

    return true;
}
int mfconn_api_device_get_status(mfconn * conn, uint64_t * revision)
{
    const char     *api_call;
    int             retval;
    mfhttp         *http;
    int             i;

    if (conn == NULL)
        return -1;

    for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
        api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php",
                                            "?response_format=json");
        if (api_call == NULL) {
            fprintf(stderr, "mfconn_create_signed_get failed\n");
            return -1;
        }

        http = http_create();

        if (mfconn_get_http_flags(conn) & HTTP_FLAG_LAZY_SSL) {

            http_set_connect_flags(http, HTTP_FLAG_LAZY_SSL);
        }

        http_set_data_handler(http, _decode_device_get_status,
                              (void *)revision);

        retval = http_get_buf(http, api_call);

        http_destroy(http);

        mfconn_update_secret_key(conn);

        free((void *)api_call);

        if (retval != 127 && retval != 28)
            break;

        // if there was either a curl timeout or a token error, get a new
        // token and try again
        //
        // on a curl timeout we get a new token because it is likely that we
        // lost signature synchronization (we don't know whether the server
        // accepted or rejected the last call)
        fprintf(stderr, "got error %d - negotiate a new token\n", retval);
        retval = mfconn_refresh_token(conn);
        if (retval != 0) {
            fprintf(stderr, "failed to get a new token\n");
            break;
        }
    }

    return retval;
}
예제 #3
0
/** Process an incoming request
	@returns nothing
 **/
void http_response(SOCKET fd)
{
	HTTP *http = http_create(fd);
	size_t len;
	int content_length = 0;
	char *user_agent = NULL;
	char *host = NULL;
	int keep_alive = 0;
	char *connection = NULL;
	char *accept = NULL;
	struct s_map {
		char *name;
		enum {INTEGER,STRING} type;
		void *value;
		size_t sz;
	} map[] = {
		{"Content-Length", INTEGER, (void*)&content_length, 0},
		{"Host", STRING, (void*)&host, 0},
		{"Keep-Alive", INTEGER, (void*)&keep_alive, 0},
		{"Connection", STRING, (void*)&connection, 0},
		{"Accept", STRING, (void*)&accept, 0},
	};

	while ( (int)(len=recv_data(fd,http->query,sizeof(http->query)))>0 )
	{
		/* first term is always the request */
		char *request = http->query;
		char method[32];
		char uri[1024];
		char version[32];
		char *p = strchr(http->query,'\r');
		int v;
		
		/* initialize the response */
		http_reset(http);

		/* read the request string */
		if (sscanf(request,"%s %s %s",method,uri,version)!=3)
		{
			http_status(http,HTTP_BADREQUEST);
			http_format(http,HTTP_BADREQUEST);
			http_type(http,"text/html");
			http_send(http);
			break;
		}

		/* read the rest of the header */
		while (p!=NULL && (p=strchr(p,'\r'))!=NULL) 
		{
 			*p = '\0';
			p+=2;
			for ( v=0 ; v<sizeof(map)/sizeof(map[0]) ; v++ )
			{
				if (map[v].sz==0) map[v].sz = strlen(map[v].name);
				if (strnicmp(map[v].name,p,map[v].sz)==0 && strncmp(p+map[v].sz,": ",2)==0)
				{
					if (map[v].type==INTEGER) { *(int*)(map[v].value) = atoi(p+map[v].sz+2); break; }
					else if (map[v].type==STRING) { *(char**)map[v].value = p+map[v].sz+2; break; }
				}
			}
		}
		output_verbose("%s (host='%s', len=%d)",http->query,host?host:"???",content_length);

		/* reject anything but a GET */
		if (stricmp(method,"GET")!=0)
		{
			http_status(http,HTTP_METHODNOTALLOWED);
			http_format(http,HTTP_METHODNOTALLOWED);
			http_type(http,"text/html");
			/* technically, we should add an Allow entry to the response header */
			http_send(http);
			break;
		}

		/* handle request */
		if ( strcmp(uri,"/favicon.ico")==0 )
		{
			if ( http_favicon(http) )
				http_status(http,HTTP_OK);
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else {
			static struct s_map {
				char *path;
				int (*request)(HTTP*,char*);
				char *success;
				char *failure;
			} map[] = {
				/* this is the map of recognize request types */
				{"/xml/",		http_xml_request,		HTTP_OK, HTTP_NOTFOUND},
				{"/gui/",		http_gui_request,		HTTP_OK, HTTP_NOTFOUND},
				{"/output/",	http_output_request,	HTTP_OK, HTTP_NOTFOUND},
				{"/action/",	http_action_request,	HTTP_ACCEPTED,HTTP_NOTFOUND},
				{"/rt/",		http_get_rt,			HTTP_OK, HTTP_NOTFOUND},
				{"/perl/",		http_run_perl,			HTTP_OK, HTTP_NOTFOUND},
				{"/gnuplot/",	http_run_gnuplot,		HTTP_OK, HTTP_NOTFOUND},
				{"/java/",		http_run_java,			HTTP_OK, HTTP_NOTFOUND},
				{"/python/",	http_run_python,		HTTP_OK, HTTP_NOTFOUND},
				{"/r/",			http_run_r,				HTTP_OK, HTTP_NOTFOUND},
				{"/scilab/",	http_run_scilab,		HTTP_OK, HTTP_NOTFOUND},
				{"/octave/",	http_run_octave,		HTTP_OK, HTTP_NOTFOUND},
			};
			int n;
			for ( n=0 ; n<sizeof(map)/sizeof(map[0]) ; n++ )
			{
				size_t len = strlen(map[n].path);
				if (strncmp(uri,map[n].path,len)==0)
				{
					if ( map[n].request(http,uri+len) )
						http_status(http,map[n].success);
					else
						http_status(http,map[n].failure);
					http_send(http);
					goto Next;
				}
			}
		}
		/* deprecated XML usage */
		if (strncmp(uri,"/",1)==0 )
		{
			if ( http_xml_request(http,uri+1) )
			{	
				output_warning("deprecate XML usage in request '%s'", uri);
				http_status(http,HTTP_OK);
			}
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else 
		{
			http_status(http,HTTP_NOTFOUND);
			http_format(http,HTTP_NOTFOUND);
			http_type(http,"text/html");
			http_send(http);
		}

		/* keep-alive not desired*/
Next:
		if (connection && stricmp(connection,"close")==0)
			break;
	}
	http_close(http);
	output_verbose("socket %d closed",http->s);
}
예제 #4
0
int mfconn_api_file_get_links(mfconn * conn, mffile * file,
                              const char *quickkey,
                              enum mfconn_file_link_type link_mask)
{
    const char     *api_call;
    int             retval;
    int             len;
    mfhttp         *http;
    int             i;

    if (conn == NULL)
        return -1;

    if (file == NULL)
        return -1;
    if (quickkey == NULL)
        return -1;

    len = strlen(quickkey);

    // key must either be 11 or 15 chars
    if (len != 11 && len != 15)
        return -1;

    for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
        api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php",
                                            "?quick_key=%s"
                                            "&link_type=%s"
                                            "&response_format=json",
                                            quickkey,
                                            mfconn_file_link_types[link_mask]);
        if (api_call == NULL) {
            fprintf(stderr, "mfconn_create_signed_get failed\n");
            return -1;
        }

        http = http_create();

        if (mfconn_get_http_flags(conn) & HTTP_FLAG_LAZY_SSL) {

            http_set_connect_flags(http, HTTP_FLAG_LAZY_SSL);
        }

        http_set_data_handler(http, _decode_file_get_links, file);

        retval = http_get_buf(http, api_call);

        http_destroy(http);

        mfconn_update_secret_key(conn);

        free((void *)api_call);

        if (retval != 127 && retval != 28)
            break;

        // if there was either a curl timeout or a token error, get a new
        // token and try again
        //
        // on a curl timeout we get a new token because it is likely that we
        // lost signature synchronization (we don't know whether the server
        // accepted or rejected the last call)
        fprintf(stderr, "got error %d - negotiate a new token\n", retval);
        retval = mfconn_refresh_token(conn);
        if (retval != 0) {
            fprintf(stderr, "failed to get a new token\n");
            break;
        }
    }

    return retval;
}
int
mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
                           const char *folderkey)
{
    const char     *api_call;
    int             retval;
    mfhttp         *http;
    int             i;

    if (conn == NULL)
        return -1;

    if (folder == NULL)
        return -1;

    // key must either be 13 chars or NULL
    if (folderkey != NULL && strlen(folderkey) != 13) {
        return -1;
    }

    for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
        if (folderkey == NULL) {
            api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
                                                "?response_format=json");
        } else {
            api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
                                                "?folder_key=%s"
                                                "&response_format=json",
                                                folderkey);
        }
        if (api_call == NULL) {
            fprintf(stderr, "mfconn_create_signed_get failed\n");
            return -1;
        }

        http = http_create();

        if (mfconn_get_http_flags(conn) & HTTP_FLAG_LAZY_SSL) {

            http_set_connect_flags(http, HTTP_FLAG_LAZY_SSL);
        }

        http_set_data_handler(http, _decode_folder_get_info, folder);

        retval = http_get_buf(http, api_call);

        http_destroy(http);

        mfconn_update_secret_key(conn);

        free((void *)api_call);

        if (retval != 127 && retval != 28)
            break;

        // if there was either a curl timeout or a token error, get a new
        // token and try again
        //
        // on a curl timeout we get a new token because it is likely that we
        // lost signature synchronization (we don't know whether the server
        // accepted or rejected the last call)
        fprintf(stderr, "got error %d - negotiate a new token\n", retval);
        retval = mfconn_refresh_token(conn);
        if (retval != 0) {
            fprintf(stderr, "failed to get a new token\n");
            break;
        }
    }

    return retval;
}
예제 #6
0
bool husthttp_t::open (
                        const char * method,
                        const char * path,
                        const char * query_string,
                        const char * data,
                        size_t data_len,
                        int conn_timeout,
                        int recv_timeout
                        )
{
    if ( unlikely ( ! m_h ) )
    {
        m_h = http_create ();
        if ( ! m_h )
        {
            return false;
        }
    }

    if ( unlikely ( ! method || ! path ) )
    {
        return false;
    }

    if ( m_method.compare ( method ) != 0 )
    {
        m_method = method;
    }

    if ( m_path.compare ( path ) != 0 )
    {
        m_path = path;
    }

    if ( ! query_string )
    {
        m_query_string.resize ( 0 );
    }
    else if ( m_query_string.compare ( query_string ) != 0 )
    {
        m_query_string = query_string;
    }

    m_data.resize ( 0 );
    if ( data_len > 0 )
    {
        m_data.assign (( const char * ) data, ( const char * ) ( data + data_len ));
    }

    if ( conn_timeout > 0 )
    {
        m_conn_timeout = conn_timeout;
    }

    if ( recv_timeout > 0 )
    {
        m_recv_timeout = recv_timeout;
    }

    return true;
}
예제 #7
0
void http_response(SOCKET fd)
{
	HTTP *http = http_create(fd);
	size_t len;
	int content_length = 0;
	char *user_agent = NULL;
	char *host = NULL;
	int keep_alive = 0;
	char *connection = NULL;
	char *accept = NULL;
	struct s_map {
		char *name;
		enum {INTEGER,STRING} type;
		void *value;
		int sz;
	} map[] = {
		{"Content-Length", INTEGER, (void*)&content_length, 0},
		{"Host", STRING, (void*)&host, 0},
		{"Keep-Alive", INTEGER, (void*)&keep_alive, 0},
		{"Connection", STRING, (void*)&connection, 0},
		{"Accept", STRING, (void*)&accept, 0},
	};

	while ( (int)(len=recv_data(fd,http->query,sizeof(http->query)))>0 )
	{
		/* first term is always the request */
		char *request = http->query;
		char method[32];
		char uri[1024];
		char version[32];
		char *p = strchr(http->query,'\r');
		int v;

		/* read the request string */
		if (sscanf(request,"%s %s %s",method,uri,version)!=3)
		{
			http_status(http,HTTP_BADREQUEST);
			http_format(http,HTTP_BADREQUEST);
			http_type(http,"text/html");
			http_send(http);
			break;
		}

		/* read the rest of the header */
		while (p!=NULL && (p=strchr(p,'\r'))!=NULL) 
		{
 			*p = '\0';
			p+=2;
			for ( v=0 ; v<sizeof(map)/sizeof(map[0]) ; v++ )
			{
				if (map[v].sz==0) map[v].sz = strlen(map[v].name);
				if (strnicmp(map[v].name,p,map[v].sz)==0 && strncmp(p+map[v].sz,": ",2)==0)
				{
					if (map[v].type==INTEGER) { *(int*)(map[v].value) = atoi(p+map[v].sz+2); break; }
					else if (map[v].type==STRING) { *(char**)map[v].value = p+map[v].sz+2; break; }
				}
			}
		}
		output_verbose("%s (host='%s', len=%d)",http->query,host?host:"???",content_length);

		/* reject anything but a GET */
		if (stricmp(method,"GET")!=0)
		{
			http_status(http,HTTP_METHODNOTALLOWED);
			http_format(http,HTTP_METHODNOTALLOWED);
			http_type(http,"text/html");
			/* technically, we should add an Allow entry to the response header */
			http_send(http);
			break;
		}

		/* handle request */
		if (strncmp(uri,"/gui/",5)==0 )
		{
			if ( http_gui_request(http,uri+5) )
				http_status(http,HTTP_OK);
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else if (strncmp(uri,"/output/",8)==0 )
		{
			if ( http_output_request(http,uri+8) )
				http_status(http,HTTP_OK);
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else if (strncmp(uri,"/action/",8)==0) 
		{
			if ( http_action_request(http,uri+8) )
				http_status(http,HTTP_ACCEPTED);
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else if ( strcmp(uri,"/favicon.ico")==0 )
		{
			if ( http_favicon(http) )
				http_status(http,HTTP_OK);
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else if (strncmp(uri,"/",1)==0 )
		{
			if ( http_xml_request(http,uri+1) )
				http_status(http,HTTP_OK);
			else
				http_status(http,HTTP_NOTFOUND);
			http_send(http);
		}
		else 
		{
			http_status(http,HTTP_NOTFOUND);
			http_format(http,HTTP_NOTFOUND);
			http_type(http,"text/html");
			http_send(http);
		}

		/* keep-alive not desired*/
		if (connection && stricmp(connection,"close")==0)
			break;
	}
	http_close(http);
	output_verbose("socket %d closed",http->s);
}