#include #include #include #include #include #include #include #include #include "base64.h" #include "io_buf.h" struct web_client_http:ev::io { in_buff m_buff; int m_data_len=-1; int m_mask_pos=-1; int m_data_pos=-1; int m_fd,m_status; web_client_http() :m_buff(8192) { m_fd=-1; } int connect_tcp(const char*ip,int port) { int fd=zio::build_stream(); if(zio::connect(fd,ip,port)) { zio::close(fd); return m_fd=-1; } zio::setiobuf(fd,16<<10,16<<10); zio::setblocking(fd,false); return m_fd=fd; } void ws_reset() { if(m_data_pos+m_data_len>0) { m_buff.free(m_data_len+m_data_pos); } m_data_len=-1; m_mask_pos=-1; m_data_pos=-1; } bool ws_fin()const { return (m_buff[0]&0x80) != 0; } bool ws_more()const { return (m_buff[0]&0xF) ==0 ; } bool ws_text()const { return (m_buff[0]&0xF) ==1 ; } bool ws_bin()const { return (m_buff[0]&0xF) ==2 ; } bool ws_ping()const { return (m_buff[0]&0xF) ==9 ; } bool ws_pong()const { return (m_buff[0]&0xF) ==10 ; } bool ws_close()const { return (m_buff[0]&0xF) ==8 ; } bool ws_mask()const { return (m_buff[1]&0x80) !=0 ; } int parse_length() { if(m_buff.len_data()<2) return -1; if(m_data_pos>0) return 0; if((m_buff[1]&0x7F)<=125) { m_mask_pos=ws_mask()?2:-1; m_data_pos=ws_mask()?6:2; m_data_len=m_buff[1]&0x7F; } else if((m_buff[1]&0x7F)==126) { if(m_buff.len_data()<4) return -1; m_mask_pos=ws_mask()?4:-1; m_data_pos=ws_mask()?8:4; m_data_len=(m_buff[2]<<8) | m_buff[3]; } else { if(m_buff.len_data()<9) return -1; m_mask_pos=ws_mask()?9:-1; m_data_pos=ws_mask()?13:9; //不考虑大于20G的数据 m_data_len=(m_buff[6]<<24)|(m_buff[7]<<16)|(m_buff[8]<<8)|(m_buff[9]); } int i=0; for(i=0;i=0x30 && b<=0x39) continue; break; } m_data_len-=i; m_data_pos+=i; return 0; } void mask(const uint8_t*m,uint8_t*d,int len) { for(int i=0;itimeout) { log_error("websocket read timeout in %dms",timeout); return -1; } if(len==-1) { return -1; } if(len==-2) continue; if(len==0) { log_info("remote close the socket"); return 0; } m_buff.commit(len); rc+=len; if(m_buff.find(what)) return rc; } } void close() { zio::close(m_fd); } ~web_client_http() { close(); } }; int realpath_test() { char buf[4096]; realpath(".",buf); log_info("curpath=%s",buf); return 0; } #if 0 std::string test_json() { struct json { json&put(const char*k,const json&n) { return *this; } json&put(const char*k,int v) { return *this; } json&put(const char*k,const char*v) { return *this; } std::string to_string()const { return std::string(); } }; return json().put("cmd","login") .put("data",json() .put("uname","wyj") .put("passwd",111111) ).to_string(); } #endif int main() { unsigned char buf[32]; const char*s64="puVOuWb7rel6z2AVZBKnfw=="; const char*login="{\"cmd\":\"login\",\"data\":{\"user_name\":\"zzj\",\"user_pass\":\"111111\"}}\n"; int blen=32; base64::decode((char*)s64,strlen(s64),buf,blen); web_client_http client; client.connect_ws("127.0.0.1",9001); for(;;) { while(client.ws_parse()==0) client.ws_reset(); client.request(login); client.read_until("\n"); } return 0; }