コード例 #1
0
ファイル: load_balancer.c プロジェクト: linersheng/mongoose
static int is_keep_alive(struct http_message *hm) {
  const struct mg_str *connection_header = mg_get_http_header(hm, "Connection");
  if (connection_header == NULL) {
    /* HTTP/1.1 connections are keep-alive by default. */
    if (mg_vcasecmp(&hm->proto, "HTTP/1.1") != 0) return 0;
  } else if (mg_vcasecmp(connection_header, "keep-alive") != 0) {
    return 0;
  }
  // We must also have Content-Length.
  return mg_get_http_header(hm, "Content-Length") != NULL;
}
コード例 #2
0
ファイル: mongoose_interface.c プロジェクト: siemens/swupdate
/*
 * These functions are for V1 of the protocol
 */
static void upload_handler_v1(struct mg_connection *nc, int ev, void *p)
{
	struct mg_str *filename, *data;
	struct http_message *hm;
	size_t length;
	char buf[16];
	int fd;

	switch (ev) {
	case MG_EV_HTTP_REQUEST:
		hm = (struct http_message *) p;

		filename = mg_get_http_header(hm, "X_FILENAME");
		if (filename == NULL) {
			mg_http_send_error(nc, 403, NULL);
			return;
		}

		data = mg_get_http_header(hm, "Content-length");
		if (data == NULL || data->len >= ARRAY_SIZE(buf)) {
			mg_http_send_error(nc, 403, NULL);
			return;
		}

		memcpy(buf, data->p, data->len);
		buf[data->len] = '\0';
		length = strtoul(data->p, NULL, 10);
		if (length == 0) {
			mg_http_send_error(nc, 403, NULL);
			return;
		}

		fd = ipc_inst_start_ext(SOURCE_WEBSERVER, filename->len, filename->p, false);
		ipc_send_data(fd, (char *) hm->body.p, hm->body.len);
		ipc_end(fd);

		mg_send_response_line(nc, 200,
			"Content-Type: text/plain\r\n"
			"Connection: close");
		mg_send(nc, "\r\n", 2);
		mg_printf(nc, "Ok, %.*s - %d bytes.\r\n", (int) filename->len, filename->p, (int) length);
		nc->flags |= MG_F_SEND_AND_CLOSE;
		break;
	default:
		upload_handler(nc, ev, p);
		break;
	}
}
コード例 #3
0
ファイル: load_balancer.c プロジェクト: linersheng/mongoose
static struct http_backend *choose_backend_from_list(
    struct http_message *hm, struct http_backend *backends, int num_backends) {
  int i;
  struct mg_str vhost = {"", 0};
  const struct mg_str *host = mg_get_http_header(hm, "host");
  if (host != NULL) vhost = *host;

  const char *vhost_end = vhost.p;

  while (vhost_end < vhost.p + vhost.len && *vhost_end != ':') {
    vhost_end++;
  }
  vhost.len = vhost_end - vhost.p;

  struct http_backend *chosen = NULL;
  for (i = 0; i < num_backends; i++) {
    struct http_backend *be = &backends[i];
    if (has_prefix(&hm->uri, be->uri_prefix) &&
        matches_vhost(&vhost, be->vhost) &&
        (chosen == NULL ||
         /* Prefer most specific URI prefixes */
         strlen(be->uri_prefix) > strlen(chosen->uri_prefix) ||
         /* Among prefixes of the same length chose the least used. */
         (strlen(be->uri_prefix) == strlen(chosen->uri_prefix) &&
          be->usage_counter < chosen->usage_counter))) {
      chosen = be;
    }
  }

  return chosen;
}
コード例 #4
0
ファイル: server.cpp プロジェクト: lactide/spectrum2
void Server::authorize(struct mg_connection *conn, struct http_message *hm) {
	Server::session *session;
	std::string user = get_http_var(hm, "user");
	std::string password = get_http_var(hm, "password");

	std::string host;
	mg_str *host_hdr = mg_get_http_header(hm, "Host");
	if (host_hdr) {
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
			host += "https://";
		}
		else {
			host += "http://";
		}
		host += std::string(host_hdr->p, host_hdr->len);
	}

	if (check_password(user, password) && (session = new_session(user)) != NULL) {
		std::cout << "User authorized\n";
		mg_printf(conn, "HTTP/1.1 302 Found\r\n"
			"Set-Cookie: session=%s; max-age=3600; http-only\r\n"  // Session ID
			"Set-Cookie: user=%s\r\n"  // Set user, needed by Javascript code
			"Set-Cookie: admin=%s\r\n"  // Set user, needed by Javascript code
			"Set-Cookie: base_location=%s\r\n"  // Set user, needed by Javascript code
			"Set-Cookie: original_url=/; max-age=0\r\n"  // Delete original_url
			"Location: %s%sinstances\r\n\r\n",
			session->session_id, session->user, session->admin ? "1" : "0", CONFIG_STRING(m_config, "service.base_location").c_str(), host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str());
	} else {
		// Authentication failure, redirect to login.
		redirect_to(conn, hm, "/login");
	}
}
コード例 #5
0
std::string ccMongooseWebServerRequest::GetHeader(const std::string& name)
{
    if (_pMgHttpMessage == NULL)
        return _strNullData;

    struct mg_str* pResult = mg_get_http_header(_pMgHttpMessage, name.c_str());

    if (pResult == NULL)
        return _strNullData;

    std::string strHeader(pResult->p, pResult->len);

    return strHeader;
}
コード例 #6
0
ファイル: server.cpp プロジェクト: lactide/spectrum2
// Get session object for the connection. Caller must hold the lock.
Server::session *Server::get_session(struct http_message *hm) {
	time_t now = time(NULL);
	char session_id[255];
	struct mg_str *hdr = mg_get_http_header(hm, "Cookie");
	int len = mg_http_parse_header(hdr, "session", session_id, sizeof(session_id));
	session_id[len] = 0;

	if (sessions.find(session_id) == sessions.end()) {
		return NULL;
	}

	if (sessions[session_id]->expire != 0 && sessions[session_id]->expire > now) {
		return sessions[session_id];
	}

	return NULL;
}
コード例 #7
0
ファイル: cookie_auth.c プロジェクト: BenDerPan/mongoose
/*
 * Parses the session cookie and returns a pointer to the session struct
 * or NULL if not found.
 */
static struct session *get_session(struct http_message *hm) {
  struct mg_str *cookie_header = mg_get_http_header(hm, "cookie");
  if (cookie_header == NULL) return NULL;
  char ssid[21];
  if (!mg_http_parse_header(cookie_header, SESSION_COOKIE_NAME, ssid,
                            sizeof(ssid))) {
    return NULL;
  }
  uint64_t sid = strtoull(ssid, NULL, 16);
  for (int i = 0; i < NUM_SESSIONS; i++) {
    if (s_sessions[i].id == sid) {
      s_sessions[i].last_used = mg_time();
      return &s_sessions[i];
    }
  }
  return NULL;
}
コード例 #8
0
ファイル: server.cpp プロジェクト: lactide/spectrum2
void Server::redirect_to(struct mg_connection *conn, struct http_message *hm, const char *where) {
	std::string host;
	mg_str *host_hdr = mg_get_http_header(hm, "Host");
	if (host_hdr) {
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
			host += "https://";
		}
		else {
			host += "http://";
		}
		host += std::string(host_hdr->p, host_hdr->len);
	}

	where = where + 1;

	mg_printf(conn, "HTTP/1.1 302 Found\r\n"
		"Set-Cookie: original_url=/\r\n"
		"Location: %s%s%s\r\n\r\n", host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str(), where);
}
コード例 #9
0
ファイル: RestServ.cpp プロジェクト: dusteye/tinychain
bool RestServ::remove_from_session_list(HttpMessage data)
{
    mg_str* cookie_header = mg_get_http_header(data.get(), "cookie");;
    if (cookie_header == nullptr) 
        return false;

    char ssid[32]{0x00};
    if (!mg_http_parse_header(cookie_header, SESSION_COOKIE_NAME, ssid, sizeof(ssid)))
        return false;

    auto sid = std::stoul(ssid, nullptr, 10);

    for (auto iter = session_list_.begin(); iter != session_list_.end(); ++iter)
    {
        if ( (*iter)->id == sid )
        {
            iter = session_list_.erase(iter);
        }
    }

    return true;
}
コード例 #10
0
ファイル: RestServ.cpp プロジェクト: dusteye/tinychain
std::shared_ptr<Session> RestServ::get_from_session_list(HttpMessage data)
{
    mg_str* cookie_header = mg_get_http_header(data.get(), "cookie");;
    if (cookie_header == nullptr) 
        return nullptr;

    char ssid[32]{0x00};
    if (!mg_http_parse_header(cookie_header, SESSION_COOKIE_NAME, ssid, sizeof(ssid)))
        return nullptr;

    auto sid = std::stoul(ssid, nullptr, 10);

    auto ret = std::find_if(session_list_.begin(), session_list_.end(), [&sid](std::shared_ptr<Session> p){
            return sid == p->id;
            });

    if (ret == session_list_.end())
        return nullptr;

    (*ret)->last_used = mg_time();
    return *ret;
}
コード例 #11
0
ファイル: server.cpp プロジェクト: lactide/spectrum2
void Server::serve_logout(struct mg_connection *conn, struct http_message *hm) {
	std::string host;
	mg_str *host_hdr = mg_get_http_header(hm, "Host");
	if (host_hdr) {
		if (!CONFIG_STRING(m_config, "service.cert").empty()) {
			host += "https://";
		}
		else {
			host += "http://";
		}
		host += std::string(host_hdr->p, host_hdr->len);
	}

	Server:session *session = get_session(hm);
	mg_printf(conn, "HTTP/1.1 302 Found\r\n"
		"Set-Cookie: session=%s; max-age=0\r\n"
		"Set-Cookie: admin=%s; max-age=0\r\n"
		"Location: %s%s\r\n\r\n",
		session->session_id, session->admin ? "1" : "0", host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str());

	sessions.erase(session->session_id);
	delete session;
}
コード例 #12
0
void UpdateUserData::handle(Manager* manager, SharedManager* sManager) {
    bool validation = this->validateInput();
    if(validation) {
        struct mg_str *cl_header = mg_get_http_header(hm, "Token");
        if(!cl_header) {
            this->response(1, "Token Missing ", returnEmptyJsonObject());
            return;
        }
        Json::Reader r = Json::Reader();
        Json::Value value = Json::Value();
        r.parse(hm->body.p, value);
        // Local user update
        User* user = manager->getUser(value.get("username","").asString());
        if(!user) {
            this->response(1, "User could not be modified", returnEmptyJsonObject());
            return;
        }
        std::string token(getHeaderParam(cl_header->p));
        if(token.compare(user->getToken()) != 0) {
            this->response(2, "Invalid Token", returnEmptyJsonObject());
            return;
        }
        user->updateWithJson(value);
        bool updateUser = manager->updateUser(user);
        if(updateUser) {
            value["id"] = user->getId();
            if(value.isMember("photoProfile") || value.isMember("photo_profile")) {
                // Photo Profile Upload
                std::string key = "";
                value.isMember("photoProfile") ? key = "photoProfile" : key = "photo_profile";
                Json::Value uploadP = Json::Value();
                uploadP["photo"] = value.get(key, "").asString();
                uploadP["id"] = user->getId();
                value.removeMember(key);
                int photoUp = sManager->putUserPhoto(uploadP);
                if(!photoUp) {
                    this->response(1, "User photo profile could not be uploaded", returnEmptyJsonObject());
                    return;
                }
            }
            // Rest of user data to update on Shared Server
            // TODO: Falta subir los intereses nuevos que haya!
            if(value.isMember("interests")) {
                Json::Value interests = value.get("interests", Json::Value(Json::arrayValue));
                Json::ValueConstIterator interestsIt = interests.begin();
                while(interestsIt != interests.end()) {
                    Json::Value response = sManager->postInterest(*interestsIt);
                    // TODO: Alguna cola para reupload de intereses que debieron subir
                    // pero no pudieron por algun problema (que no sea duplicado)
                    interestsIt++;
                }
            }
            if(value.isMember("edad")) value["age"] = value.get("edad", 18).asInt();
            int sharedUpdate = sManager->putUser(value);
            if(sharedUpdate) {
                this->response(0, "Modified", user->getJson());
            } else {
                this->response(1, "User could not be modified", returnEmptyJsonObject());
            }
        } else {
            this->response(1, "User could not be modified", returnEmptyJsonObject());
        }
        delete user;
    }
}
コード例 #13
0
ファイル: main.c プロジェクト: gavinying/mongoose
static void mg_ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
  switch (ev) {
    case MG_EV_ACCEPT: {
      char addr[32];
      mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
                                                      MG_SOCK_STRINGIFY_IP |
                                                      MG_SOCK_STRINGIFY_PORT);
      LOG(LL_INFO, ("%p conn from %s", nc, addr));
      break;
    }
    case MG_EV_HTTP_REQUEST: {
      char addr[32];
      struct http_message *hm = (struct http_message *) ev_data;
      cs_stat_t st;
      mg_conn_addr_to_str(nc, addr, sizeof(addr), MG_SOCK_STRINGIFY_REMOTE |
                                                      MG_SOCK_STRINGIFY_IP |
                                                      MG_SOCK_STRINGIFY_PORT);
      LOG(LL_INFO,
          ("HTTP request from %s: %.*s %.*s", addr, (int) hm->method.len,
           hm->method.p, (int) hm->uri.len, hm->uri.p));
      if (mg_vcmp(&hm->uri, "/upload") == 0 ||
          (mg_vcmp(&hm->uri, "/") == 0 && mg_stat("SL:index.html", &st) != 0)) {
        mg_send(nc, upload_form, strlen(upload_form));
        nc->flags |= MG_F_SEND_AND_CLOSE;
        break;
      }
      struct mg_serve_http_opts opts;
      memset(&opts, 0, sizeof(opts));
      opts.document_root = "SL:";
      mg_serve_http(nc, hm, opts);
      break;
    }
    case MG_EV_CLOSE: {
      LOG(LL_INFO, ("%p closed", nc));
      break;
    }
    case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
      LOG(LL_INFO, ("%p switching to data mode", nc));
      nc->handler = data_conn_handler;
      nc->ev_timer_time = mg_time(); /* Immediately */
      break;
    }
    case MG_EV_TIMER: {
      data_collect();
      nc->ev_timer_time = mg_time() + (DATA_COLLECTION_INTERVAL_MS * 0.001);
      break;
    }
    /* SimpleLink FS requires pre-declaring max file size. We use Content-Length
     * for that purpose - it will not exactly match file size, but is guaranteed
     * to exceed it and should be close enough. */
    case MG_EV_HTTP_MULTIPART_REQUEST: {
      struct http_message *hm = (struct http_message *) ev_data;
      struct mg_str *cl_header = mg_get_http_header(hm, "Content-Length");
      intptr_t cl = -1;
      if (cl_header != NULL && cl_header->len < 20) {
        char buf[20];
        memcpy(buf, cl_header->p, cl_header->len);
        buf[cl_header->len] = '\0';
        cl = atoi(buf);
        if (cl < 0) cl = -1;
      }
      nc->user_data = (void *) cl;
      break;
    }
    case MG_EV_HTTP_PART_BEGIN:
    case MG_EV_HTTP_PART_DATA:
    case MG_EV_HTTP_PART_END: {
      struct mg_http_multipart_part *mp =
          (struct mg_http_multipart_part *) ev_data;
      if (ev == MG_EV_HTTP_PART_BEGIN) {
        LOG(LL_INFO, ("Begin file upload: %s", mp->file_name));
      } else if (ev == MG_EV_HTTP_PART_END) {
        LOG(LL_INFO, ("End file upload: %s", mp->file_name));
      }
      mg_file_upload_handler(nc, ev, ev_data, upload_fname);
    }
  }
}