예제 #1
0
int ICACHE_FLASH_ATTR http_relay_api_toggle(http_connection *c) {


	NODE_DBG("http_wifi_api_get_status");	
	

	//wait for whole body
	if(c->state <HTTPD_STATE_BODY_END)
		return HTTPD_CGI_MORE; 

	
	int ret = json_count_token(c->body.data,c->body.len);
	
	jsonPair fields[1]={
		{
			.key="relay",
			.value=NULL
		}
	};

	if(json_parse(&fields[0],1,c->body.data,c->body.len)){
		
		int relayNumber = atoi(fields[0].value);	

		if(relayNumber<0 || relayNumber >=relay_count()){
			http_response_BAD_REQUEST(c);
			NODE_DBG("Wrong relay");		
			return HTTPD_CGI_DONE;
		}

		unsigned status = relay_get_state(relayNumber);
		status = relay_toggle_state(relayNumber);

		//write headers
		http_SET_HEADER(c,HTTP_CONTENT_TYPE,JSON_CONTENT_TYPE);	
		http_response_OK(c);

		write_json_object_start(c);
		write_json_pair_int(c,"relay",relayNumber);
		write_json_list_separator(c);
		write_json_pair_int(c,"state",status);
		write_json_object_end(c);

		return HTTPD_CGI_DONE;

	}
	else{
		http_response_BAD_REQUEST(c);		
		return HTTPD_CGI_DONE;
	}

	http_response_BAD_REQUEST(c);		
	return HTTPD_CGI_DONE;


}
예제 #2
0
파일: cgi_relay.c 프로젝트: HaknCo/esp-ginx
int ICACHE_FLASH_ATTR http_relay_api_toggle(http_connection *c) {


	NODE_DBG("http_wifi_api_get_status");	
	

	//wait for whole body
	if(c->state <HTTPD_STATE_BODY_END)
		return HTTPD_CGI_MORE; 

	//parse json
	cJSON * root = cJSON_Parse(c->body.data);
	if(root==NULL) goto badrequest;
	
	cJSON * relay = cJSON_GetObjectItem(root,"relay");
	if(relay==NULL) goto badrequest;


	int relayNumber = relay->valueint;
	cJSON_Delete(root);	

	if(relayNumber<0 || relayNumber >=relay_count()){
		http_response_BAD_REQUEST(c);
		NODE_DBG("Wrong relay");		
		return HTTPD_CGI_DONE;
	}
	else{
		//valid relay

		unsigned status = relay_get_state(relayNumber);
		status = relay_toggle_state(relayNumber);

		//write headers
		http_SET_HEADER(c,HTTP_CONTENT_TYPE,JSON_CONTENT_TYPE);	
		http_response_OK(c);


		//create json
		root = cJSON_CreateObject();
		cJSON_AddNumberToObject(root,"relay",relayNumber);
		cJSON_AddNumberToObject(root,"state",status);

		http_write_json(c,root);

		//delete json struct
		cJSON_Delete(root);

		return HTTPD_CGI_DONE;

	}	

badrequest:
	http_response_BAD_REQUEST(c);
	return HTTPD_CGI_DONE;

}
예제 #3
0
파일: cgi.c 프로젝트: someburner/esp-rfm69
// This makes sure we aren't serving static files on POST requests for example
int cgi_enforce_method(http_connection *connData)
{
	enum http_method *method = (enum http_method *)connData->cgi.argument;

	if(connData->state == HTTPD_STATE_BODY_END)
   	if(connData->parser.method!=*method && (int)*method>=0)
   	{
   		HTTP_CGI_DBG("Wrong HTTP method. Enforce is %d and request is %d\n",method,connData->parser.method);

   		http_response_BAD_REQUEST(connData);
   		return HTTPD_CGI_DONE;
   	}
	return HTTPD_CGI_NEXT_RULE;
}
예제 #4
0
파일: cgi.c 프로젝트: andresvidal/esp-ginx
// This makes sure we have a body
int ICACHE_FLASH_ATTR cgi_enforce_body(http_connection *connData) {	

	if(connData->state ==HTTPD_STATE_ON_URL){	
		http_set_save_body(connData); //request body to be saved
	}

	//wait for whole body
	if(connData->state <HTTPD_STATE_BODY_END)
		return HTTPD_CGI_NEXT_RULE; 

	//if body empty, bad request
	if(connData->body.len <=0){
		http_response_BAD_REQUEST(connData);
		NODE_DBG("No body");		
		return HTTPD_CGI_DONE;
	}
	else
		return HTTPD_CGI_NEXT_RULE;

	
}
예제 #5
0
파일: cgi.c 프로젝트: someburner/esp-rfm69
// This makes sure we have a body
int cgi_enforce_body(http_connection *connData)
{
	if(connData->state ==HTTPD_STATE_ON_URL)
		{ http_set_save_body(connData); }//request body to be saved

	//wait for whole body
	if(connData->state <HTTPD_STATE_BODY_END)
	{
      HTTP_CGI_DBG("cgi_enforce: next_rule\n");
		return HTTPD_CGI_NEXT_RULE;
	}

	//if body empty, bad request
	if(connData->body.len <=0)
	{
		http_response_BAD_REQUEST(connData);
      HTTP_CGI_DBG("No body\n");
		return HTTPD_CGI_DONE;
	}
	else
		{ return HTTPD_CGI_NEXT_RULE; }
}
예제 #6
0
int http_wifi_api_connect_ap(http_connection *c)
{
    CGI_WIFI_DBG("http_wifi_api_connect_ap\n");

    //wait for whole body
    if(c->state <HTTPD_STATE_BODY_END) {
        return HTTPD_CGI_MORE;
    }

    api_cgi_connect_status * status = c->cgi.data;

    if(status==NULL)
    {
        // CGI_WIFI_DBG("http_wifi_api_connect_ap status NULL\n");

        status = (api_cgi_connect_status*)os_malloc(sizeof(api_cgi_connect_status));
        status->state=1;
        c->cgi.data=status;

        //parse json and validate
        cJSON * root = cJSON_Parse(c->body.data);
        if(root==NULL) goto badrequest;

        cJSON * ssid = cJSON_GetObjectItem(root,"ssid");
        if(ssid==NULL) goto badrequest;
        else if(ssid->type != cJSON_String) goto badrequest;

        cJSON * pwd = cJSON_GetObjectItem(root,"pwd");
        if(pwd==NULL) goto badrequest;
        else if(pwd->type!=cJSON_String) goto badrequest;

        //parse ok
        strncpy(status->ssid,ssid->valuestring,32);
        strncpy(status->pwd,pwd->valuestring,64);

        //set timer to connect
        os_timer_disarm(&status->timer);
        os_timer_setfn(&status->timer, (os_timer_func_t *)http_execute_cgi, c);
        os_timer_arm(&status->timer, 10, 0);

        return HTTPD_CGI_MORE;
    }
    else if (status->state==1)
    {
        CGI_WIFI_DBG("connect_ap status %d\n",status->state);
        //try connect

        if(strlen(status->ssid)>32 || strlen(status->pwd)>64)
            goto badrequest;

        CGI_WIFI_DBG("ap connect ssid: %s, pwd: %s\n",status->ssid,status->pwd);

        strcpy(wifi_status.station_config.ssid,status->ssid);
        strcpy(wifi_status.station_config.password,status->pwd);
        wifi_status.station_config.bssid_set=0;

        wifi_station_disconnect();
        wifi_station_set_config(&wifi_status.station_config);
        wifi_station_connect();

        //set timer to check status
        os_timer_disarm(&status->timer);
        os_timer_setfn(&status->timer, (os_timer_func_t *)http_execute_cgi, c);
        os_timer_arm(&status->timer, 500, 0);

        status->state=2;

        return HTTPD_CGI_MORE;
    }
    else if (status->state==2)
    {
        CGI_WIFI_DBG("connect_ap status %d\n",status->state);
        uint8_t c_status = wifi_station_get_connect_status();

        CGI_WIFI_DBG("wifi sta status %d\n",c_status);
        if (c_status>=2 && c_status <= 4 )
        {
            wifi_station_disconnect();
            strcpy(wifi_status.station_config.ssid,"");
            strcpy(wifi_status.station_config.password,"");
            wifi_station_set_config(&wifi_status.station_config);
        }

        if (c_status==1)
        {
            //set timer to check status
            os_timer_disarm(&status->timer);
            os_timer_setfn(&status->timer, (os_timer_func_t *)http_execute_cgi, c);
            os_timer_arm(&status->timer, 500, 0);
            return HTTPD_CGI_MORE;
        }
        else
        {
            //write headers
            http_SET_HEADER(c,HTTP_CONTENT_TYPE,JSON_CONTENT_TYPE);
            http_response_OK(c);

            //create json
            cJSON *root = cJSON_CreateObject();
            cJSON_AddNumberToObject(root,"status",c_status);

            //got ip
            if(c_status==5)
            {
                struct ip_info ip;
                wifi_get_ip_info(0x0,&ip);
                char *ip_str = (char*)ipaddr_ntoa(&ip.ip);
                cJSON_AddStringToObject(root,"ip",ip_str);
            }
            else
            {
                cJSON_AddStringToObject(root,"ip","");
            }

            http_write_json(c,root);

            //delete json struct
            cJSON_Delete(root);

            status->state=99;

            return HTTPD_CGI_MORE;
        }
    }
    else //status=99
    {
        CGI_WIFI_DBG("connect_ap status %d\n",status->state);
        //clean
        os_free(c->cgi.data);
        return HTTPD_CGI_DONE;
    }

badrequest:
    http_response_BAD_REQUEST(c);
    status->state=99;
    return HTTPD_CGI_MORE;

    //shut up compiler
    return HTTPD_CGI_DONE;
}
예제 #7
0
int http_console_api(http_connection *c)
{
	CGI_CONS_DBG("http_console_api\n");

	//wait for whole body
	if(c->state <HTTPD_STATE_BODY_END)
		return HTTPD_CGI_MORE;

	http_SET_HEADER(c,HTTP_CONTENT_TYPE,JSON_CONTENT_TYPE);
	// http_response_OK(c);

	//parse json and validate
   cJSON * root = cJSON_Parse(c->body.data);
   if(root==NULL) goto badrequest;

	cJSON * first = NULL;
	unsigned i;
	for (i=0; i < CONS_CMDS_CT; i++)
	{
		if (cJSON_HasObjectItem(root, console_json[i]))
		{
			first = cJSON_GetObjectItem(root,console_json[i]);
			break;
		}
	}

	if ((first==NULL) || i == CONS_CMDS_CT) { goto badrequest; }
	if ((first->type != cJSON_String) && (i != cons_start_t) && (i != cons_to_node_t)) { goto badrequest; }

	int tx = 0;
	int btn_val = 99;

	cJSON * cmd_ct = NULL;
	if (i > 0)
	{
		cmd_ct = cJSON_GetObjectItem(root,"ctcnt");
		if (cmd_ct==NULL) { goto badrequest; }
		if (cmd_ct->type != cJSON_Number) { goto badrequest; }
		btn_val = cmd_ct->valueint;
	}

	CGI_CONS_DBG("BTN Value: %d index: %d\n", btn_val, i);

	switch (i)
	{
		case cons_start_t:
		{
			char buff[256];
			if (first->type != cJSON_Number)
				{ goto badrequest; }

			int start = first->valueint;
			int len = 0; // length of text in buff
			int console_len = (console_wr+BUF_MAX-console_rd) % BUF_MAX; // num chars in console_buf

			if (start < console_pos) 							{ start = 0; }
			else if (start >= console_pos+console_len) 	{ start = console_len; }
			else { start = start - console_pos; }
			int rd = (console_rd+start) % BUF_MAX;
			while (len < BUF_MAX && rd != console_wr)
			{
				uint8_t c = console_buf[rd];
				buff[len++] = c;
				rd = (rd + 1) % BUF_MAX;
			}
			buff[len] = '\0'; //null terminate

			cJSON_AddNumberToObject(root,"len",console_len-start);
			cJSON *newSt = cJSON_CreateNumber(console_pos+start);
			cJSON_ReplaceItemInObject(root, "start", newSt);
			cJSON_AddStringToObject(root,"text", (const char *)buff);

			http_write_json(c,root);
			cJSON_Delete(root);
			return HTTPD_CGI_DONE;
		} break;

		case cons_pwr_t:
		{
			sendTxBuff[0] = (uint8_t) (49-btn_val);
         tx = 1;
			NODE_DBG("sendtxbuff[0]==%02x\n", sendTxBuff[0]);
			NODE_DBG("Sending %d bytes to node %d\n",tx, 99);
			generateRfmTxMsg(99, sendTxBuff, tx, false, false);
      } break;

		case cons_to_node_t:
		{
			/* Get requested payload */
			cJSON * dataJson = cJSON_GetObjectItem(root,"data");
		   if(dataJson==NULL) { goto badrequest; }
		   else if (dataJson->type != cJSON_String) { goto badrequest; }
			bool reqAck = false;

			/* Get ack checkbox value */
			cJSON * ackJson = cJSON_GetObjectItem(root,"ack");
			if ((ackJson!=NULL) && (ackJson->type == cJSON_Number))
				{ reqAck = (bool) ackJson->valueint; }

			int len, nodeid;
			len = strlen(dataJson->valuestring);
			NODE_DBG("send len = %d\n", len);
			nodeid = first->valueint;

			if ((len > 0) && (nodeid>0) && (nodeid < 255))
			{
				CGI_CONS_DBG("Sending %s to node %d\n", dataJson->valuestring, nodeid);
				generateRfmTxMsg((uint8_t)nodeid, dataJson->valuestring, len, reqAck, false);
			}

		} break;

		case cons_disp_t:
		{
			rfm_toggle_all_output();
		} break;

	} /* End cons_method_t Switch() */
	http_response_OK(c);
	cJSON_Delete(root);
	return HTTPD_CGI_DONE;

badrequest:
	http_response_BAD_REQUEST(c);
	cJSON_Delete(root);
	return HTTPD_CGI_DONE;

	//shut up compiler
	return HTTPD_CGI_DONE;
}
예제 #8
0
파일: cgi.c 프로젝트: andresvidal/esp-ginx
//Cgi that check the request has the correct HOST header
//Using it we can ensure our server has a domain of our choice
int ICACHE_FLASH_ATTR cgi_check_host(http_connection *connData) {
	
	http_server_config *config = (http_server_config*)connData->cgi.argument;
	if(config==NULL)
		return HTTPD_CGI_NEXT_RULE;

	if(config->host_domain==NULL)
		return HTTPD_CGI_NEXT_RULE;

	
	if(connData->state==HTTPD_STATE_ON_URL){

		http_set_save_header(connData,HTTP_HOST);
		return HTTPD_CGI_NEXT_RULE;
	}

	if(connData->state==HTTPD_STATE_HEADERS_END){

		header *hostHeader = http_get_header(connData,HTTP_HOST);
		if(hostHeader==NULL){
			NODE_DBG("Host header not found");
			http_response_BAD_REQUEST(connData);
			return HTTPD_CGI_DONE;
		}

		const char * domain = config->host_domain;

		NODE_DBG("Host header found: %s, domain: %s",hostHeader->value,domain);


		if(os_strncmp(hostHeader->value,domain,strlen(domain))==0) //compare ignoring http:// and last /
		{
			NODE_DBG("Hosts match");
			return HTTPD_CGI_NEXT_RULE;
		}
		else{
			NODE_DBG("Hosts don't match");
			
			if(config->enable_captive){
				//to enable a captive portal we should redirect here

				char * redirectUrl = (char *)os_zalloc(strlen(domain)+9); // domain lenght + http:// + / + \0
				os_strcpy(redirectUrl,"http://");
				os_strcat(redirectUrl,domain);
				os_strcat(redirectUrl,"/");

				http_response_REDIRECT(connData, redirectUrl);

				os_free(redirectUrl);

			}
			else{
				//bad request
				http_response_BAD_REQUEST(connData);

			}
			
			

			return HTTPD_CGI_DONE;
		}
		

	}

	
	return HTTPD_CGI_NEXT_RULE;

}
예제 #9
0
파일: cgi.c 프로젝트: someburner/esp-rfm69
//Cgi that check the request has the correct HOST header
//Using it we can ensure our server has a domain of our choice
int cgi_check_host(http_connection *connData)
{
	http_server_config *config = (http_server_config*)connData->cgi.argument;
	if(config==NULL)
		return HTTPD_CGI_NEXT_RULE;

	if(config->host_domain==NULL)
		return HTTPD_CGI_NEXT_RULE;


	if(connData->state==HTTPD_STATE_ON_URL)
	{
		http_set_save_header(connData,HTTP_HOST);
		return HTTPD_CGI_NEXT_RULE;
	}

	if(connData->state==HTTPD_STATE_HEADERS_END)
	{
		header *hostHeader = http_get_header(connData,HTTP_HOST);
		if(hostHeader==NULL)
		{
         NODE_ERR("Host header not found\n");
			http_response_BAD_REQUEST(connData);
			return HTTPD_CGI_DONE;
		}
		const char * domain = config->host_domain;

      HTTP_CGI_DBG("Host header: %s, domain: %s\n",hostHeader->value,domain);

		if(strncmp(hostHeader->value,domain,strlen(domain))==0) //compare ignoring http:// and last /
		{
         HTTP_CGI_DBG("Domain match\n");
			return HTTPD_CGI_NEXT_RULE;
		}
		else{
			uint8_t op = wifi_get_opmode();
			char ipaddrstr[17];
			os_bzero(ipaddrstr, sizeof(ipaddrstr));
			struct ip_info ipConfig;
			switch (op)
			{
				case STATIONAP_MODE:
				{
					wifi_get_ip_info(SOFTAP_IF,&ipConfig); //0x01
					ipaddr_ntoa_r(&ipConfig.ip,ipaddrstr, sizeof(ipaddrstr));

					if(strncmp(hostHeader->value,ipaddrstr,strlen(ipaddrstr))==0)
						{ HTTP_CGI_DBG("SoftAp ip match"); return HTTPD_CGI_NEXT_RULE; }
				}
				case STATION_MODE:
				{
					os_bzero(ipaddrstr, sizeof(ipaddrstr));
					wifi_get_ip_info(STATION_IF,&ipConfig); //0x00
					ipaddr_ntoa_r(&ipConfig.ip,ipaddrstr, sizeof(ipaddrstr));

					if(strncmp(hostHeader->value,ipaddrstr,strlen(ipaddrstr))==0)
						{ HTTP_CGI_DBG("Station ip match"); return HTTPD_CGI_NEXT_RULE; }
				}
			}
         HTTP_CGI_DBG("Hosts don't match\n");

			if(config->enable_captive)
			{
				//to enable a captive portal we should redirect here
				char * redirectUrl = (char *)os_zalloc(strlen(domain)+9); // domain length + http:// + / + \0
				strcpy(redirectUrl,"http://");
				os_strcat(redirectUrl,domain);
				os_strcat(redirectUrl,"/");
				http_response_REDIRECT(connData, redirectUrl);
				os_free(redirectUrl);
            HTTP_CGI_DBG("Redirect URL = %s\n", redirectUrl);

			} else {
			//bad request else
			http_response_BAD_REQUEST(connData);
			}
		return HTTPD_CGI_DONE;
		}
	}
	return HTTPD_CGI_NEXT_RULE;
}
예제 #10
0
int ICACHE_FLASH_ATTR http_ws_handle_connect(http_connection *c) {	

	NODE_DBG("http_ws_handle_connect c =%p",c);

	if(c->state == HTTPD_STATE_ON_URL){
		http_set_save_header(c,HTTP_ORIGIN);	
		http_set_save_header(c,HTTP_CONNECTION);	
		http_set_save_header(c,HTTP_UPGRADE);		
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_KEY);
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_PROTOCOL);
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_VERSION);

		return HTTP_WS_CGI_MORE;
	}

	//wait handshake request complete
	if(c->state != HTTPD_STATE_BODY_END)
		return HTTP_WS_CGI_MORE;


	header * upgrade_header = http_get_header(c,HTTP_UPGRADE);
	header * connection_header = http_get_header(c,HTTP_CONNECTION);
	header * origin_header = http_get_header(c,HTTP_ORIGIN);
	header * key_header = http_get_header(c,HTTP_SEC_WEBSOCKET_KEY);

	if(upgrade_header==NULL) goto badrequest;
	if(connection_header==NULL) goto badrequest;
	if(origin_header==NULL) goto badrequest;
	if(key_header==NULL) goto badrequest;

	NODE_DBG("headers ok");

	if(os_strcasecmp(upgrade_header->value,"websocket")!=0) goto badrequest;

	// Following (https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17)
	//calculate sha1 of concatenetion key+uuid
	uint8_t digest[20]; //sha1 is always 20 byte long
	SHA1_CTX ctx;
	SHA1_Init(&ctx);
	SHA1_Update(&ctx,key_header->value,os_strlen(key_header->value));
	SHA1_Update(&ctx,ws_uuid,os_strlen(ws_uuid));
	SHA1_Final(digest,&ctx);
		
	char base64Digest[31]; // 
	Base64encode(base64Digest,(const char*)digest,20);

	//accept the handshake
	http_SET_HEADER(c,HTTP_UPGRADE,"WebSocket");
	http_SET_HEADER(c,HTTP_CONNECTION,"Upgrade");
	
	http_SET_HEADER(c,HTTP_WEBSOCKET_ACCEPT,base64Digest);

	http_websocket_HANDSHAKE(c);
	c->handshake_ok=1;

	if(client_connected_callback!=NULL)
		client_connected_callback(c);

	return HTTP_WS_CGI_MORE;

badrequest:
	http_response_BAD_REQUEST(c);
	return HTTP_WS_CGI_DONE;

}