int HTTP::Server::request(uint32_t ms) { // Wait for incoming connection requests uint32_t start = Watchdog::millis(); int res; while (((res = m_sock->accept()) != 0) && ((ms == 0L) || (Watchdog::millis() - start < ms))) Watchdog::delay(16); if (res != 0) return (-2); // Wait for the HTTP request while ((res = m_sock->available()) == 0) Watchdog::delay(16); if (res < 0) goto error; // Read request, call handler and flush/send any buffered response char line[REQUEST_MAX]; m_sock->gets(line, sizeof(line)); on_request(line); m_sock->flush(); // Disconnect the client and allow new connection requests error: m_sock->disconnect(); m_sock->listen(); return (res); }
void curl(const std::string& uri, const std::string& method = "GET", const std::string& content="", bool auth=false) { set_url(uri); if (auth) { cout << __LINE__ << ":" << uri << endl; add_header("Accept: application/json"); add_header("Accept-Language: en_US"); /* string userpass = m_client_id + ":" + m_client_secret; curl_easy_setopt(m_curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_BASIC); curl_easy_setopt(m_curl, CURLOPT_USERPWD, userpass.c_str()); curl_easy_setopt(m_curl, CURLOPT_SSH_KNOWNHOSTS, "/root/.ssh/known_hosts"); */ curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, auth_request_callback); //curl_easy_setopt(m_curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)29); //curl_easy_setopt(m_curl, CURLOPT_MAXREDIRS, 50L); ////////////////////////////////////////////////////////////////////////// curl_easy_setopt(m_curl, CURLOPT_URL, "https://api.sandbox.paypal.com/v1/oauth2/token"); curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(m_curl, CURLOPT_USERPWD, "AQHK3B-gB3sdb1ierWaMMap-6dKJtC-NGIRPeCa6GsZHVioiso-peMOyDgdCpThLv2rz39BTzqk6ajWy:EOiC6EF3aXo9X4whY5l51QPlQ9vzDsbcM2ihIyUqqNDUQ2NrMpvpjUZqeJ6AJ7bmzXXXyV4BOYsmq-Lo"); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, "grant_type=client_credentials"); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)29); curl_easy_setopt(m_curl, CURLOPT_USERAGENT, "curl/7.29.0"); curl_easy_setopt(m_curl, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(m_curl, CURLOPT_SSH_KNOWNHOSTS, "/root/.ssh/known_hosts"); curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L); } else { cout << __LINE__ << ":" << uri << endl; add_header("Content-Type:application/json"); add_header("Authorization:"+m_token_type+" "+ m_access_token); } #ifdef DEBUG curl_easy_setopt(m_curl, CURLOPT_HEADER, 1); #endif /*curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, content.c_str()); curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, m_headerlist); curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, method.c_str());*/ on_request(); curl_slist_free_all(m_headerlist); m_headerlist = NULL; }
int HTTP::Server::run(uint32_t ms) { // Wait for incoming connection requests // NOTE: LTO error; need rewrite to stack allocation // char line[REQUEST_MAX]; IOStream page(m_sock); char* line = (char*) alloca(REQUEST_MAX); char* method; char* path; char* query; char* sp; int res; uint32_t start = Watchdog::millis(); while (((res = m_sock->accept()) != 0) && ((ms == 0L) || (Watchdog::millis() - start < ms))) yield(); if (res != 0) return (-2); // Wait for the HTTP request while ((res = m_sock->available()) == 0) yield(); // Parse request (method and url), call handler and flush buffered response if (res < 0) goto error; m_sock->gets(line, REQUEST_MAX); method = line; sp = strpbrk(line, " "); if (sp == NULL) goto error; path = sp + 1; *sp = 0; sp = strpbrk(path, " ?"); if (sp == NULL) goto error; if (*sp != '?') query = NULL; else { query = sp + 1; *sp = 0; sp = strpbrk(query, " "); if (sp == NULL) goto error; } *sp = 0; // Bind the socket to an iostream, handle the request and flush response on_request(page, method, path, query); m_sock->flush(); // Disconnect the client and allow new connection requests error: m_sock->disconnect(); m_sock->listen(); return (res); }
/* Called when all the headers are complete but before the content body, if present. Returning 1 from here tells the joyent parser that the message has no body (e.g. a HEAD request). */ int basic_parser::do_headers_complete() { check_header(); auto const p (reinterpret_cast <joyent::http_parser const*> (&state_)); bool const keep_alive (joyent::http_should_keep_alive (p) != 0); if (p->type == joyent::http_parser_type::HTTP_REQUEST) return on_request (joyent::convert_http_method ( joyent::http_method(p->method)), url_, p->http_major, p->http_minor, keep_alive, p->upgrade) ? 0 : 1; return on_response (p->status_code, status_, p->http_major, p->http_minor, keep_alive, p->upgrade) ? 0 : 1; }
void TWI::Slave::on_event(uint8_t type, uint16_t value) { if (type != Event::WRITE_COMPLETED_TYPE) return; void* buf = twi.m_vec[WRITE_IX].buf; size_t size = value; on_request(buf, size); twi.set_state(IDLE); synchronized { USICR = TWI::CR_START_MODE; USISR = TWI::SR_CLEAR_DATA; } }
void http_server::on_connection(tcp_socket& socket) { http_request* request = new http_request(socket); request->connect_on_headers_end([this](http_request& request, http_response& response){ on_request(request, response); }); request->connect_on_body([this](http_request& request, const std::string& data, http_response& response){ if (data != "") { on_body(request, data, response, *this); } }); requests_.push_back(std::unique_ptr<http_request>(request)); }
/*---------------------------------------------------------------------------*/ static int on_message(struct xio_session *session, struct xio_msg *msg, int more_in_batch, void *cb_prv_data) { switch (msg->type) { case XIO_MSG_TYPE_REQ: on_request(session, msg, more_in_batch, cb_prv_data); break; case XIO_MSG_TYPE_RSP: on_response(session, msg, more_in_batch, cb_prv_data); break; default: printf("unknown message type : %d\n", msg->type); break; } return 0; }
int event_handler(struct mg_connection* conn, enum mg_event ev) { switch (ev) { case MG_AUTH: return MG_TRUE; case MG_REQUEST: return on_request(conn); case MG_WS_HANDSHAKE: // LOG(("MG_WS_HANDSHAKE: %p %d %d\n", conn, conn->is_websocket, conn->wsbits)); return MG_FALSE; case MG_WS_CONNECT: LOG(("MG_WS_CONNECT: %p %d %d\n", conn, conn->is_websocket, conn->wsbits)); ws_conn = conn; return MG_TRUE; case MG_CLOSE: if (conn == ws_conn) { LOG(("MG_CLOSE: %p %d %d\n", conn, conn->is_websocket, conn->wsbits)); ws_conn = NULL; } return MG_TRUE; default: return MG_FALSE; } }
void curl(const std::string& uri, const std::string& method = "GET", const std::string& param = "", const std::string& content = "") { set_url(m_url + uri + "?" + param); //cout << __LINE__ << ":" << uri << endl; #ifdef DEBUG curl_easy_setopt(m_curl, CURLOPT_HEADER, 1); #endif curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, request_callback); curl_easy_setopt(m_curl, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(m_curl, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, method.c_str()); //curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS,0L); curl_easy_setopt(m_curl, CURLOPT_CLOSESOCKETFUNCTION, close_socket_callback); curl_easy_setopt(m_curl, CURLOPT_CLOSESOCKETDATA, this); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, content.c_str()); curl_easy_setopt(m_curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)content.length()); on_request(); }
void HttpServerConnection::read() { while(!is_closed()) { switch(read_state) { case LINE: // get the request line try { if(!async_read_in(line,sizeof(uri)-1)) return; } catch(EndOfStreamError*) { if(!count) throw; // so we get end-of-stream when keep-alive? no problem return; } if(!line.ends_with("\r\n",2)) HttpError::Throw(HttpError::ERequestURITooLong,*this); if(!memcmp(line.cstr(),"\r\n",3)) { // empty lines are ok before request line line.clear(); continue; } count++; read_state = HEADER; { const char* method = strtok(line.cstr()," "); strncpy(uri,strtok(NULL," \r"),sizeof(this->uri)); const char* v = strtok(NULL,"\r"); if(!memcmp(v,"HTTP/1.1",9)) version = HTTP_1_1; else if(!memcmp(v,"HTTP/1.0",9)) version = HTTP_1_0; else version = HTTP_0_9; in_encoding_chunked = false; in_content_length = -1; // not known keep_alive = out_encoding_chunked = (HTTP_1_1 == version); on_request(method,uri); } line.clear(); break; case HEADER: if(!async_read_in(line)) return; if(!memcmp("\r\n",line.cstr(),3)) { read_state = BODY; if(keep_alive && !in_encoding_chunked && (-1 == in_content_length)) in_content_length = 0; // length isn't specified, yet its keep-alive, so there is no content line.clear(); on_body(); break; } if(!line.ends_with("\r\n",2)) HttpError::Throw(HttpError::ERequestEntityTooLarge,*this); { const char* header = strtok(line.cstr()," "), *value = strtok(NULL,"\r"); if(!ends_with(header,":",1)) HttpError::Throw(HttpError::EBadRequest,*this); if((write_state == LINE) && !strcasecmp(header,"connection:") && !strcasecmp(value,"keep-alive")) keep_alive = true; else if(!strcasecmp(header,"content-length:")) { in_content_length = atoi(value); if(in_content_length < 0) HttpError::Throw(HttpError::EBadRequest,*this); } else if(!strcasecmp(header,"transfer-encoding:")) in_encoding_chunked = !strcasecmp(value,"chunked"); on_header(header,value); } line.clear(); break; case BODY: if(in_encoding_chunked) { //RFC2616-s4.4 says this overrides any explicit content-length header ThrowInternalError("in encoding chunked not implemented yet"); } else if(!keep_alive && (-1 == in_content_length)) { // read all available uint8_t* chunk; while(uint16_t len = async_read_buffered(chunk)) on_data(chunk,len); } else if(-1 != in_content_length) { // read all available while(in_content_length) { uint8_t* chunk; if(const uint16_t len = async_read_buffered(chunk,in_content_length)) { in_content_length -= len; on_data(chunk,len); } else return; } if(!keep_alive) { read_state = FINISHED; shutdown(fd,SHUT_RD); return; } read_state = LINE; } else ThrowInternalError("cannot cope with combination of keep_alive %d, content_length %d and encoding_chunked %d", keep_alive,in_content_length,in_encoding_chunked); break; default: ThrowInternalError("unexpected read_state"); } } }
bool CDistributedObjectBase::do_request(const TDistributedMessage* message) { // callback return on_request(message); }