Beispiel #1
0
static void redirect_to_ssl(struct mg_connection *conn,
                            const struct mg_request_info *request_info) {
  const char *p, *host = mg_get_header(conn, "Host");
  //  u_int16_t port = ntop->get_HTTPserver()->get_port();

  if(host != NULL && (p = strchr(host, ':')) != NULL) {
    mg_printf(conn, "HTTP/1.1 302 Found\r\n"
              "Location: https://%.*s:%u/%s\r\n\r\n",
              (int) (p - host), host, ntop->getPrefs()->get_https_port(), request_info->uri);
  } else {
    mg_printf(conn, "%s", "HTTP/1.1 500 Error\r\n\r\nHost: header is not set");
  }
}
Beispiel #2
0
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
    std::string uri;
    const char* secret = NULL;
    const char* requested_with = NULL;
    int retval = MG_FALSE;

    switch (ev) {
        case MG_REQUEST:
            boinc_resolve_filename_s(conn->uri+1, uri);
            mg_send_file(
                conn,
                uri.c_str(),
                "Access-Control-Allow-Origin: *\r\n"
            );
            return MG_MORE;
        case MG_AUTH:
            retval = MG_FALSE;

            if (!webserver_debugging) {
                secret = mg_get_header(conn, "Secret");
                if (secret) {
                    if (0 == strcmp(secret, webserver_secret)) {
                        retval = MG_TRUE;
                    }
                }
                requested_with = mg_get_header(conn, "X-Requested-With");
                if (requested_with) {
                    retval = MG_TRUE;
                }
            } else {
                retval = MG_TRUE;
            }

            return retval;
        default:
            return MG_FALSE;
    }
}
Beispiel #3
0
// Get session object for the connection. Caller must hold the lock.
static struct session *get_session(const struct mg_connection *conn) {
	int i;
	const char *cookie = mg_get_header(conn, "Cookie");
	char session_id[33];
	time_t now = time(NULL);
	mg_get_cookie(cookie, "session", session_id, sizeof(session_id));
	for (i = 0; i < MAX_SESSIONS; i++) {
		if (sessions[i].expire != 0 && sessions[i].expire > now
				&& strcmp(sessions[i].session_id, session_id) == 0) {
			break;
		}
	}
	return i == MAX_SESSIONS ? NULL : &sessions[i];
}
Beispiel #4
0
void atlas::http::detail::basic_function::serve(
        uri_parameters_type match,
        mg_connection *conn,
        uri_callback_type success,
        uri_callback_type failure
        ) const
{
    const char *token = mg_get_header(conn, "Authorization");

    bool authorised = false;
    try
    {
        authorised = m_auth_function((token == nullptr) ? "" : token, match);
    }
    catch(const std::exception& e)
    {
        log::error("atlas::http::detail::basic_function::serve") <<
            "error checking authentication token: " << e.what();
        http::error(403, "checking authentication", conn);
        success();
    }

    if(authorised)
    {
        try
        {
            m_serve(conn, match, success, failure);
        }
        catch(const http::exception& e)
        {
            log::error("atlas::http::detail::basic_function::serve") <<
                "error in http handler returned to client: " << e.what();
            http::error(e.code(), e.what(), conn);
            success();
        }
        catch(const std::exception& e)
        {
            log::error("atlas::http::detail::basic_function::serve") <<
                "error in http handler: " << e.what();
            http::error(500, "unknown error", conn);
            success();
        }
    }
    else
    {
        http::error(403, "unauthorised", conn);
        success();
    }
}
Beispiel #5
0
static int event_handler(struct mg_connection *conn, enum mg_event ev)
{
    if(ev == MG_REQUEST)
    {
        if(conn->is_websocket)
        {
            ws_handler(conn, FLAG_WS_DATA);
            return MG_TRUE;
        }
        else
        {
            int ret = web_handler(conn);
            if(ret < 0)
            {
                const char* srvfilepath = strlen(conn->uri) <= 1 ? "index.html" : conn->uri;
                if(srvfilepath[0] == '/')
                    srvfilepath++;
                mg_send_file(conn, srvfilepath, NULL);
                return MG_MORE;
            }
            return MG_TRUE;
        }
    }
    else if(ev == MG_WS_CONNECT)
    {
        conn->connection_param = malloc(25);
        const char* key = mg_get_header(conn, "Sec-WebSocket-Key");
        strncpy(conn->connection_param, key, 24);
        char *p = (char*)(conn->connection_param);
        p[24] = '\0';
        ws_handler(conn, FLAG_WS_OPEN);
        return MG_TRUE;
    }
    else if(ev == MG_CLOSE)
    {
        if(conn->is_websocket)
        {
            ws_handler(conn, FLAG_WS_CLOSE);
        }
        free(conn->connection_param);
        return MG_TRUE;
    }
    else if(ev == MG_AUTH)
    {
        return MG_TRUE;
    }
    return MG_FALSE;
}
Beispiel #6
0
static void test_post(struct mg_connection *conn,
                      const struct mg_request_info *ri) {
  const char *cl;
  char *buf;
  int len;

  mg_printf(conn, "%s", standard_reply);
  if (strcmp(ri->request_method, "POST") == 0 &&
      (cl = mg_get_header(conn, "Content-Length")) != NULL) {
    len = atoi(cl);
    if ((buf = malloc(len)) != NULL) {
      mg_write(conn, buf, len);
      free(buf);
    }
  }
}
Beispiel #7
0
static void test_get_header(struct mg_connection *conn,
                            const struct mg_request_info *ri) {
  const char *value;
  int i;

  mg_printf(conn, "%s", standard_reply);
  printf("HTTP headers: %d\n", ri->num_headers);
  for (i = 0; i < ri->num_headers; i++) {
    printf("[%s]: [%s]\n", ri->http_headers[i].name, ri->http_headers[i].value);
  }

  value = mg_get_header(conn, "Host");
  if (value != NULL) {
    mg_printf(conn, "Value: [%s]", value);
  }
}
Beispiel #8
0
static int api_callback(struct mg_connection *conn) {
  struct mg_request_info *ri = mg_get_request_info(conn);
  char post_data[100] = "";

  ASSERT(ri->user_data == (void *) 123);
  ASSERT(ri->num_headers == 2);
  ASSERT(strcmp(mg_get_header(conn, "host"), "blah.com") == 0);
  ASSERT(mg_read(conn, post_data, sizeof(post_data)) == 3);
  ASSERT(memcmp(post_data, "b=1", 3) == 0);
  ASSERT(ri->query_string != NULL);
  ASSERT(ri->remote_ip > 0);
  ASSERT(ri->remote_port > 0);
  ASSERT(strcmp(ri->http_version, "1.0") == 0);

  mg_printf(conn, "HTTP/1.0 200 OK\r\n\r\n");
  return 1;
}
Beispiel #9
0
/*
    get json_data value form post data.
*/
char * get_post_data(struct mg_connection *conn)
{
    char *buff = NULL;

    size_t buf_len;
    const char *cl;

    cl = mg_get_header(conn, "Content-Length");
    if ((!strcmp(conn->request_method, "POST") || (!strcmp(conn->request_method, "PUT"))&& cl != NULL))
    {
        buf_len = atoi(cl)+1;
        buff = malloc(buf_len);
        memset(buff,0,buf_len);
        memcpy(buff,conn->content,conn->content_len);
    }
    return buff; /*should free outside*/
}
Beispiel #10
0
    Request::Request(struct mg_connection *connection_, const struct mg_request_info *request_) : 
        connection(connection_),
        request(request_)
    {
        url = string(request->uri);
        method = string(request->request_method);

        // Downloading POST data
        ostringstream postData;
        if (mg_get_header(connection, "Content-Type") != NULL) {
            int n;
            char post[1024];
            while (n = mg_read(connection, post, sizeof(post))) {
                postData.write(post, n);
            }
        }
        data = postData.str();
    }
////////////////////////////////////////////////////////////////
///Function to send a simple text ajax rely
void Executive::ajaxReply(struct mg_connection *conn, const struct mg_request_info *request_info)
{
	try{
	const char * clength;
	char h1[] = "Content-Length";
	clength = mg_get_header(conn,h1);	//get length of post data
	int clen = atoi(clength);
	char *pdata = (char *)malloc(clen+clen/8+1);
	int datalen = mg_read(conn,pdata,clen);	//read post data
	pdata[clen] = '\0';
	printf("\nUser data: %s",pdata);
	mg_printf(conn, "%s\r\n%s", ajax_reply_start,pdata);
	free(pdata);
	}
	catch(std::exception ex)
	{
		std::cout << "\n  " << ex.what() << "\n\n";
	}
}
Beispiel #12
0
static void
login_page(struct mg_connection *conn,
		const struct mg_request_info *ri, void *data)
{
	char		*name, *pass, uri[100];
	const char	*cookie;

	name = mg_get_var(conn, "name");
	pass = mg_get_var(conn, "pass");
	cookie = mg_get_header(conn, "Cookie");

	/*
	 * Here user name and password must be checked against some
	 * database - this is step 2 from the algorithm described above.
	 * This is an example, so hardcode name and password to be
	 * admin/admin, and if this is so, set "allow=yes" cookie and
	 * redirect back to the page where we have been redirected to login.
	 */
	if (name != NULL && pass != NULL &&
	    strcmp(name, "admin") == 0 && strcmp(pass, "admin") == 0) {
		if (cookie == NULL || sscanf(cookie, "uri=%99s", uri) != 1)
			(void) strcpy(uri, "/");
		/* Set allow=yes cookie, which is expected by authorize() */
		mg_printf(conn, "HTTP/1.1 301 Moved Permanently\r\n"
		    "Location: %s\r\n"
		    "Set-Cookie: allow=yes;\r\n\r\n", uri);
	} else {
		/* Print login page */
		mg_printf(conn, "HTTP/1.1 200 OK\r\n"
		    "content-Type: text/html\r\n\r\n"
		    "Please login (enter admin/admin to pass)<br>"
		    "<form method=post>"
		    "Name: <input type=text name=name></input><br/>"
		    "Password: <input type=password name=pass></input><br/>"
		    "<input type=submit value=Login></input>"
		    "</form>");
	}

	if (name != NULL)
		mg_free(name);
	if (pass != NULL)
		mg_free(pass);
}
Beispiel #13
0
int
CookieHandler(struct mg_connection *conn, void *cbdata)
{
	/* Handler may access the request info using mg_get_request_info */
	const struct mg_request_info *req_info = mg_get_request_info(conn);
	const char *cookie = mg_get_header(conn, "Cookie");
	char first_str[64], count_str[64];
	int count;

	(void)mg_get_cookie(cookie, "first", first_str, sizeof(first_str));
	(void)mg_get_cookie(cookie, "count", count_str, sizeof(count_str));

	mg_printf(conn, "HTTP/1.1 200 OK\r\nConnection: close\r\n");
	if (first_str[0] == 0) {
		time_t t = time(0);
		struct tm *ptm = localtime(&t);
		mg_printf(conn,
		          "Set-Cookie: first=%04i-%02i-%02iT%02i:%02i:%02i\r\n",
		          ptm->tm_year + 1900,
		          ptm->tm_mon + 1,
		          ptm->tm_mday,
		          ptm->tm_hour,
		          ptm->tm_min,
		          ptm->tm_sec);
	}
	count = (count_str[0] == 0) ? 0 : atoi(count_str);
	mg_printf(conn, "Set-Cookie: count=%i\r\n", count + 1);
	mg_printf(conn, "Content-Type: text/html\r\n\r\n");

	mg_printf(conn, "<html><body>");
	mg_printf(conn, "<h2>This is the CookieHandler.</h2>");
	mg_printf(conn, "<p>The actual uri is %s</p>", req_info->local_uri);

	if (first_str[0] == 0) {
		mg_printf(conn, "<p>This is the first time, you opened this page</p>");
	} else {
		mg_printf(conn, "<p>You opened this page %i times before.</p>", count);
		mg_printf(conn, "<p>You first opened this page on %s.</p>", first_str);
	}

	mg_printf(conn, "</body></html>\n");
	return 1;
}
Beispiel #14
0
static char *field(struct mg_connection *conn, char *fieldname)
{
    char buf[BUFSIZ], *p, *h;
    int ret;

    snprintf(buf, sizeof(buf), "X-Limit-%s", fieldname);

    if ((h = (char *)mg_get_header(conn, buf)) != NULL) {
        p = strdup(h);
        lowercase(p);
        return (p);
    }

    if ((ret = mg_get_var(conn, fieldname, buf, sizeof(buf))) > 0) {
        p = strdup(buf);
        lowercase(p);
        return (p);
    }
    return (NULL);
}
Beispiel #15
0
static void test_get_var(struct mg_connection *conn) {
  char *var, *buf;
  size_t buf_len;
  const char *cl;
  int var_len;
  const struct mg_request_info *ri = mg_get_request_info(conn);
  int is_form_enc = 0;

  send_standard_reply_head(conn);

  buf_len = 0;
  var = buf = NULL;
  cl = mg_get_header(conn, "Content-Length");
  mg_printf(conn, "cl: %p\n", cl);
  if ((!strcmp(ri->request_method, "POST") ||
       !strcmp(ri->request_method, "PUT"))
      && cl != NULL) {
    buf_len = atoi(cl);
    buf = malloc(buf_len);
    /* Read in two pieces, to test continuation */
    if (buf_len > 2) {
      mg_read(conn, buf, 2);
      mg_read(conn, buf + 2, buf_len - 2);
    } else {
      mg_read(conn, buf, buf_len);
    }
    is_form_enc = 1;
  } else {
    MG_ASSERT(ri->query_string != NULL); // query_string ~ "" when no query string was specified in the request
    buf_len = strlen(ri->query_string);
    buf = malloc(buf_len + 1);
    strcpy(buf, ri->query_string);
    is_form_enc = 1;
  }
  var = malloc(buf_len + 1);
  var_len = mg_get_var(buf, buf_len, "my_var", var, buf_len + 1, is_form_enc);
  mg_printf(conn, "Value: [%s]\n", var);
  mg_printf(conn, "Value size: [%d]\n", var_len);
  free(buf);
  free(var);
}
////////////////////////////////////////////////////////////////
///Function to send sniffed file list to the client
void Executive::listReply(struct mg_connection *conn, const struct mg_request_info *request_info)
{
	try{
	int is_jsonp;
	char text[100];
	const char * json;
	std::stringstream ss;
	std::string msg;
	mg_printf(conn, "%s\r\n", json_reply_start);	//prints the json message starting headers
	const char * clength;
	char h1[] = "Content-Length";
	clength = mg_get_header(conn,h1);	//get the length of post data
	int clen = atoi(clength);
	char *pdata = (char *)malloc(clen+clen/8+1);
	int datalen = mg_read(conn,pdata,clen);	//read post data
	pdata[clen] = '\0';
	mg_get_var(pdata, strlen(pdata == NULL ? "" : pdata), "text", text, sizeof(text));
	std::string path(text);
	is_jsonp = handle_jsonp(pdata,conn, request_info);	//find the callback function
	srand((size_t)time(NULL));
	ss<<"[";
	fsniffer2.Clear();
	fsniffer2.sniffFiles(path);
	std::set<std::string> filelist = fsniffer2.getFiles();	//get sniffed files
	for (std::set<std::string>::iterator it=filelist.begin(); it != filelist.end(); it++)
	{
		std::string tempstr = HTMLEncode(*it);	//html encode filepaths
		ss<<"{item: \""<<tempstr<<"\"},";
	}
	ss<<"]";
	msg = ss.str();
	json = msg.c_str();
	mg_printf(conn, "%s", json);	//print json array to the connection

	if (is_jsonp) 	{
		mg_printf(conn, "%s", ")");	//print closing bracket for the function
	}
//	fsniffer2.saveFiles();	//save sniffed files
	}
	catch(std::exception ex){std::cout << "\n  " << ex.what() << "\n\n";}
}
Beispiel #17
0
static void
authorize(struct mg_connection *conn,
		const struct mg_request_info *ri, void *data)
{
	const char	*cookie, *domain;

	cookie = mg_get_header(conn, "Cookie");

	if (!strcmp(ri->uri, "/login")) {
		/* Always authorize accesses to the login page */
		mg_authorize(conn);
	} else if (cookie != NULL && strstr(cookie, "allow=yes") != NULL) {
		/* Valid cookie is present, authorize */
		mg_authorize(conn);
	} else {
		/* Not authorized. Redirect to the login page */
		mg_printf(conn, "HTTP/1.1 301 Moved Permanently\r\n"
		    "Set-Cookie: uri=%s;\r\n"
		    "Location: /login\r\n\r\n", ri->uri);
	}
}
////////////////////////////////////////////////////////////////
///Function to send sniffed process list
void Executive::procReply(struct mg_connection *conn, const struct mg_request_info *request_info)
{
	try{
	int is_jsonp;

	const char * json;
	std::stringstream ss;
	std::string msg;
	mg_printf(conn, "%s\r\n", json_reply_start);	//prints the json message starting headers
	const char * clength;
	char h1[] = "Content-Length";
	clength = mg_get_header(conn,h1);	//get the length of post data
	int clen = atoi(clength);
	char *pdata = (char *)malloc(clen+clen/8+1);
	int datalen = mg_read(conn,pdata,clen);	//read post data
	pdata[clen] = '\0';
	/*mg_get_var(pdata, strlen(pdata == NULL ? "" : pdata), "text", text, sizeof(text));
	std::string path(text);*/
	is_jsonp = handle_jsonp(pdata,conn, request_info);	//find the callback function
	srand((size_t)time(NULL));
	ss<<"[";
	prsniffer.Clear();
	prsniffer.sniffProcesses();
	std::map<std::string,int> filelist = prsniffer.getProcesses();	//get process list
	for (std::map<std::string,int>::iterator it=filelist.begin(); it != filelist.end(); it++)
	{
		std::string tempstr = HTMLEncode((*it).first);
		ss<<"{item: \""<<tempstr<<" ("<<(*it).second<<")\"},";	//store process name and count
	}
	ss<<"]";
	msg = ss.str();
	json = msg.c_str();
	mg_printf(conn, "%s", json);	//print json array to the connection
	if (is_jsonp)
	{
		mg_printf(conn, "%s", ")");	//print closing bracket for the function
	}
	//prsniffer.saveProcesses();
	}catch(std::exception ex){std::cout << "\n  " << ex.what() << "\n\n";}
}
Beispiel #19
0
static int api_cb(struct mg_event *event) {
  struct mg_request_info *ri = event->request_info;
  char post_data[100] = "";

  if (event->type == MG_REQUEST_BEGIN) {
    ASSERT(event->user_data == (void *) 123);
    ASSERT(ri->num_headers == 2);
    ASSERT(strcmp(mg_get_header(event->conn, "host"), "blah.com") == 0);
    ASSERT(mg_read(event->conn, post_data, sizeof(post_data)) == 3);
    ASSERT(memcmp(post_data, "b=1", 3) == 0);
    ASSERT(ri->query_string != NULL);
    ASSERT(strcmp(ri->query_string, api_uri + 2) == 0);
    ASSERT(ri->remote_ip > 0);
    ASSERT(ri->remote_port > 0);
    ASSERT(strcmp(ri->http_version, "1.0") == 0);

    mg_printf(event->conn, "HTTP/1.0 200 OK\r\n\r\n");
    return 1;
  }

  return 0;
}
Beispiel #20
0
static void mg_keep_alive(struct mg_connection* conn, const struct mg_request_info* ri) {
	const char *cl;
	char *buf;
	int len;

	mg_printf(conn, "%s", standard_reply);
	if (strcmp(ri->request_method, "POST") == 0 &&
		(cl = mg_get_header(conn, "Content-Length")) != NULL) {
		len = atoi(cl);
		if ((buf = MEM_ALLOC(len+1)) != NULL) {
			mg_read(conn, buf, len);
			buf[len] = '\0';

			uint id;
			sscanf(buf, "%u", &id); 
			MEM_FREE(buf);

			// Invoke keep_alive
			_invoke("keep_alive_cb", id, NULL);
		}
	}
}
Beispiel #21
0
    static void *callback(enum mg_event event, struct mg_connection *conn)
    {
        const struct mg_request_info *request_info = mg_get_request_info(conn);
        char* readBuffer = NULL;
        int postSize = 0;

        HttpServer* _this = (HttpServer*) request_info->user_data;

        if (event == MG_NEW_REQUEST)
        {

            if (strcmp(request_info->request_method, "GET") == 0)
            {
                //Mark the request as unprocessed.
                return NULL;
            }
            else if (strcmp(request_info->request_method, "POST") == 0)
            {
                //get size of postData
                sscanf(mg_get_header(conn, "Content-Length"), "%d", &postSize);
                readBuffer = (char*) malloc(sizeof(char) * (postSize + 1));
                mg_read(conn, readBuffer, postSize);
                _this->OnRequest(readBuffer, conn);
                free(readBuffer);

                //Mark the request as processed by our handler.
                return (void*) "";
            }
            else
            {
                return NULL;
            }
        }
        else
        {
            return NULL;
        }
    }
Beispiel #22
0
static void mg_leave(struct mg_connection* conn, const struct mg_request_info* ri) {
	const char *cl;
	char *buf;
	int len;

	if (strcmp(ri->request_method, "POST") == 0 &&
		(cl = mg_get_header(conn, "Content-Length")) != NULL) {
		len = atoi(cl);
		if ((buf = MEM_ALLOC(len+1)) != NULL) {
			mg_read(conn, buf, len);
			buf[len] = '\0';

			uint id;
			sscanf(buf, "%u", &id); 
			MEM_FREE(buf);

			if(aatree_size(&clients)) {
				aatree_remove(&clients, id);

				// Invoke leave_cb
				_invoke("leave_cb", id, NULL);

				mg_printf(conn, "%s", standard_reply);
				return;
			}
			else {
				goto error;
			}
		}
	}
	else if(strcmp(ri->request_method, "OPTIONS") == 0) {
		mg_printf(conn, "%s", standard_reply);
		return;
	}

error:
	mg_error(conn, ri);
}
Beispiel #23
0
static void test_get_var(struct mg_connection *conn,
                         const struct mg_request_info *ri) {
  char *var, *buf;
  size_t buf_len;
  const char *cl;
  int var_len;

  mg_printf(conn, "%s", standard_reply);

  buf_len = 0;
  var = buf = NULL;
  cl = mg_get_header(conn, "Content-Length");
  mg_printf(conn, "cl: %p\n", cl);
  if ((!strcmp(ri->request_method, "POST") ||
       !strcmp(ri->request_method, "PUT"))
      && cl != NULL) {
    buf_len = atoi(cl);
    buf = malloc(buf_len);
    /* Read in two pieces, to test continuation */
    if (buf_len > 2) {
      mg_read(conn, buf, 2);
      mg_read(conn, buf + 2, buf_len - 2);
    } else {
      mg_read(conn, buf, buf_len);
    }
  } else if (ri->query_string != NULL) {
    buf_len = strlen(ri->query_string);
    buf = malloc(buf_len + 1);
    strcpy(buf, ri->query_string);
  }
  var = malloc(buf_len + 1);
  var_len = mg_get_var(buf, buf_len, "my_var", var, buf_len + 1);
  mg_printf(conn, "Value: [%s]\n", var);
  mg_printf(conn, "Value size: [%d]\n", var_len);
  free(buf);
  free(var);
}
Beispiel #24
0
int event_handler(struct mg_event *event){
  struct mg_request_info *request_info = event->request_info;
  struct mg_connection *conn = event->conn;
  regex_t regex;
  int rc;
  const char *override_method;

  if (event->type != MG_REQUEST_BEGIN) return 0;

  override_method = mg_get_header(conn, HTTP_METHOD_HEADER);

  printf("\x1B[0;32m[%s]\x1B[0m %s\n",
    override_method ? override_method : request_info->request_method,
    request_info->uri
  );

  rc = regcomp(&regex, TODO_UPDATE_REGEX, 0);

  if(strcmp(request_info->uri, TODO_LIST_URL) == 0 &&
          strcmp(request_info->request_method, "GET") == 0){
    todos_index(conn);
  }else if(strcmp(request_info->uri, TODO_CREATE_URL) == 0 &&
          strcmp(request_info->request_method, "POST") == 0){
    todos_create(conn);
  }else if(regexec(&regex, request_info->uri, 0, NULL, 0) == 0){
    int todo_id = atoi(&request_info->uri[7]);
    if(strcmp(override_method, "PUT") == 0){
      todos_update(conn, todo_id);
    }else if(strcmp(override_method, "DELETE") == 0){
      todos_delete(conn, todo_id);
    }
  }

  regfree(&regex);

  return 0;
}
Beispiel #25
0
/*
 * This callback function is attached to the "/" and "/abc.html" URIs,
 * thus is acting as "index.html" file. It shows a bunch of links
 * to other URIs, and allows to change the value of program's
 * internal variable. The pointer to that variable is passed to the
 * callback function as arg->user_data.
 */
static void
show_index(struct mg_connection *conn,
		const struct mg_request_info *request_info,
		void *user_data)
{
	char		*value;
	const char	*host;

	/* Change the value of integer variable */
	value = mg_get_var(conn, "name1");
	if (value != NULL) {
		* (int *) user_data = atoi(value);
		free(value);

		/*
		 * Suggested by Luke Dunstan. When POST is used,
		 * send 303 code to force the browser to re-request the
		 * page using GET method. This prevents the possibility of
		 * the user accidentally resubmitting the form when using
		 * Refresh or Back commands in the browser.
		 */
		if (!strcmp(request_info->request_method, "POST")) {
			(void) mg_printf(conn, "HTTP/1.1 303 See Other\r\n"
				"Location: %s\r\n\r\n", request_info->uri);
			return;
		}
	}

	mg_printf(conn, "%s",
		"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
		"<html><body><h1>Welcome to embedded example of Mongoose");
#if 0

	mg_printf(conn, " v. %s </h1><ul>", mg_version());

	mg_printf(conn, "<li><code>REQUEST_METHOD: %s "
	    "REQUEST_URI: \"%s\" QUERY_STRING: \"%s\""
	    " REMOTE_ADDR: %lx REMOTE_USER: \"(null)\"</code><hr>",
	    request_info->request_method, request_info->uri,
	    request_info->query_string ? request_info->query_string : "(null)",
	    request_info->remote_ip);
	mg_printf(conn, "<li>Internal int variable value: <b>%d</b>",
			* (int *) user_data);

	mg_printf(conn, "%s",
		"<form method=\"GET\">Enter new value: "
		"<input type=\"text\" name=\"name1\"/>"
		"<input type=\"submit\" value=\"set new value using GET method\"></form>");
	mg_printf(conn, "%s",
		"<form method=\"POST\">Enter new value: "
		"<input type=\"text\" name=\"name1\"/>"
		"<input type=\"submit\" "
		"value=\"set new value using POST method\"></form>");
		
		mg_printf(conn, "%s",
		"<li><a href=\"/Makefile\">Regular file (Makefile)</a><hr>"
		"<li><a href=\"/ssi_test.shtml\">SSI file "
			"(ssi_test.shtml)</a><hr>"
		"<li><a href=\"/users/joe/\">Wildcard URI example</a><hr>"
		"<li><a href=\"/not-existent/\">Custom 404 handler</a><hr>");

	host = mg_get_header(conn, "Host");
	mg_printf(conn, "<li>'Host' header value: [%s]<hr>",
	    host ? host : "NOT SET");
#endif

	mg_printf(conn, "<li>Upload file example. "
	    "<form method=\"post\" enctype=\"multipart/form-data\" "
	    "action=\"/post\"><input type=\"file\" name=\"file\">"
	    "<input type=\"submit\"></form>");

	mg_printf(conn, "%s", "</body></html>");
}
Beispiel #26
0
static void test_mg_download(void) {
  char *p1, *p2, ebuf[100];
  int len1, len2, port = atoi(HTTPS_PORT);
  struct mg_connection *conn;
  struct mg_context *ctx;

  ASSERT((ctx = mg_start(&CALLBACKS, NULL, OPTIONS)) != NULL);

  ASSERT(mg_download(NULL, port, 0, ebuf, sizeof(ebuf), "%s", "") == NULL);
  ASSERT(mg_download("localhost", 0, 0, ebuf, sizeof(ebuf), "%s", "") == NULL);
  ASSERT(mg_download("localhost", port, 1, ebuf, sizeof(ebuf),
                     "%s", "") == NULL);

  // Fetch nonexistent file, should see 404
  ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s",
                             "GET /gimbec HTTP/1.0\r\n\r\n")) != NULL);
  ASSERT(strcmp(conn->request_info.uri, "404") == 0);
  mg_close_connection(conn);

  ASSERT((conn = mg_download("google.com", 443, 1, ebuf, sizeof(ebuf), "%s",
                             "GET / HTTP/1.0\r\n\r\n")) != NULL);
  mg_close_connection(conn);

  // Fetch civetweb.c, should succeed
  ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s",
                             "GET /civetweb.c HTTP/1.0\r\n\r\n")) != NULL);
  ASSERT(!strcmp(conn->request_info.uri, "200"));
  ASSERT((p1 = read_conn(conn, &len1)) != NULL);
  ASSERT((p2 = read_file("civetweb.c", &len2)) != NULL);
  ASSERT(len1 == len2);
  ASSERT(memcmp(p1, p2, len1) == 0);
  free(p1), free(p2);
  mg_close_connection(conn);


  // Fetch in-memory file, should succeed.
  ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s",
                             "GET /blah HTTP/1.1\r\n\r\n")) != NULL);
  ASSERT((p1 = read_conn(conn, &len1)) != NULL);
  ASSERT(len1 == (int) strlen(inmemory_file_data));
  ASSERT(memcmp(p1, inmemory_file_data, len1) == 0);
  free(p1);
  mg_close_connection(conn);

  // Fetch in-memory data with no Content-Length, should succeed.
  ASSERT((conn = mg_download("localhost", port, 1, ebuf, sizeof(ebuf), "%s",
                             "GET /data HTTP/1.1\r\n\r\n")) != NULL);
  ASSERT((p1 = read_conn(conn, &len1)) != NULL);
  ASSERT(len1 == (int) strlen(fetch_data));
  ASSERT(memcmp(p1, fetch_data, len1) == 0);
  free(p1);
  mg_close_connection(conn);

  // Test SSL redirect, IP address
  ASSERT((conn = mg_download("localhost", atoi(HTTP_PORT), 0,
                             ebuf, sizeof(ebuf), "%s",
                             "GET /foo HTTP/1.1\r\n\r\n")) != NULL);
  ASSERT(strcmp(conn->request_info.uri, "302") == 0);
  ASSERT(strcmp(mg_get_header(conn, "Location"),
                "https://127.0.0.1:" HTTPS_PORT "/foo") == 0);
  mg_close_connection(conn);

  // Test SSL redirect, Host:
  ASSERT((conn = mg_download("localhost", atoi(HTTP_PORT), 0,
                             ebuf, sizeof(ebuf), "%s",
                             "GET /foo HTTP/1.1\r\nHost: a.b:77\n\n")) != NULL);
  ASSERT(strcmp(conn->request_info.uri, "302") == 0);
  ASSERT(strcmp(mg_get_header(conn, "Location"),
                "https://a.b:" HTTPS_PORT "/foo") == 0);
  mg_close_connection(conn);

  mg_stop(ctx);
}
void *TMongSrv::HandleRequest(enum mg_event event, struct mg_connection *conn,
		const struct mg_request_info *request_info) {

	// Since this is a static request handler, find out for which
	// server instance this is for. The URL should tell that.

	
	TChA UrlStr = "http://";
	const char *Host = mg_get_header(conn, "Host");
	UrlStr += Host != NULL ? Host : "localhost";
	UrlStr += request_info->uri;
	if (request_info->query_string != NULL) {
		UrlStr += "?";
		UrlStr += request_info->query_string;
	}
	
	void *processed = (void *) "yes";
	TStr UrlS = UrlStr;
	PUrl Url = TUrl::New(UrlS);

	if (!Url->IsOk(usHttp)) {
		TNotify::OnNotify(TNotify::StdNotify, ntErr,
				TStr("Invalid URI: ") + UrlStr);
		return NULL;
	}

	PMongSrv& Server = TMongSrv::Get(Url);

	if (request_info->log_message != NULL) {
		TNotify::OnNotify(Server->GetNotify(), ntErr,
				TStr(request_info->log_message));
		return NULL;
	}

	THttpRqMethod Method = hrmUndef;

	if (strncmp(request_info->request_method, "POST", 4) == 0) {
		Method = hrmPost;
	} else if (strncmp(request_info->request_method, "GET", 3) == 0) {
		Method = hrmGet;
	} else if (strncmp(request_info->request_method, "HEAD", 4) == 0) {
		Method = hrmHead;
	} else {
		return NULL;
	}

	TStr ContentType = mg_get_header(conn, THttp::ContTypeFldNm.CStr());
	const char *ContentLenStr = mg_get_header(conn, "Content-Length");
	PHttpRq Rq;
	if (Method == hrmPost) {

		int ContentLength = atoi(ContentLenStr);
		char *Body = new char[ContentLength];
		mg_read(conn, Body, ContentLength);
		Rq = THttpRq::New(Method, Url, ContentType, TMem(Body, ContentLength));
		delete[] Body;
	} else {
		Rq = THttpRq::New(Method, Url, ContentType, TMem());
	}
	

	int ClientId = Server->NewClient(conn, request_info); 
			
	try {
		Server->OnHttpRq(ClientId, Rq);
		Server->DropClient(ClientId);
		return processed;
	} catch (PExcept& Exception) {
		TNotify::OnNotify(Server->GetNotify(), ntErr, Exception->GetStr());
		Server->DropClient(ClientId);
		return NULL;
	}

}
Beispiel #28
0
const char* CivetServer::getHeader(struct mg_connection *conn, const std::string &headerName)
{
	return mg_get_header(conn, headerName.c_str());
}
Beispiel #29
0
FILE *mg_upload(struct mg_connection *conn, const char *destination_dir,
                char *path, int path_len) {
  const char *content_type_header, *boundary_start;
  char *buf, fname[1024], boundary[100], *s, *p;
  int bl, n, i, j, headers_len, boundary_len, eof, buf_len, to_read, len = 0;
  FILE *fp;

  // Request looks like this:
  //
  // POST /upload HTTP/1.1
  // Host: 127.0.0.1:8080
  // Content-Length: 244894
  // Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryRVr
  //
  // ------WebKitFormBoundaryRVr
  // Content-Disposition: form-data; name="file"; filename="accum.png"
  // Content-Type: image/png
  //
  //  <89>PNG
  //  <PNG DATA>
  // ------WebKitFormBoundaryRVr

  // Extract boundary string from the Content-Type header
  if ((content_type_header = mg_get_header(conn, "Content-Type")) == NULL ||
      (boundary_start = mg_strcasestr(content_type_header,
                                      "boundary=")) == NULL ||
      (sscanf(boundary_start, "boundary=\"%99[^\"]\"", boundary) == 0 &&
       sscanf(boundary_start, "boundary=%99s", boundary) == 0) ||
      boundary[0] == '\0') {
    return NULL;
  }

  boundary_len = strlen(boundary);
  bl = boundary_len + 4;  // \r\n--<boundary>

  //                     buf
  // conn->buf            |<--------- buf_len ------>|
  //    |=================|==========|===============|
  //    |<--request_len-->|<--len--->|               |
  //    |<-----------data_len------->|      conn->buf + conn->buf_size

  buf = conn->buf + conn->request_len;
  buf_len = conn->buf_size - conn->request_len;
  len = conn->data_len - conn->request_len;

  for (;;) {
    // Pull in headers
    assert(len >= 0 && len <= buf_len);
    to_read = buf_len - len;
    if (to_read > left_to_read(conn)) {
      to_read = (int) left_to_read(conn);
    }
    while (len < buf_len &&
           (n = pull(NULL, conn, buf + len, to_read)) > 0) {
      len += n;
    }
    if ((headers_len = get_request_len(buf, len)) <= 0) {
      break;
    }

    // Fetch file name.
    fname[0] = '\0';
    for (i = j = 0; i < headers_len; i++) {
      if (buf[i] == '\r' && buf[i + 1] == '\n') {
        buf[i] = buf[i + 1] = '\0';
        // TODO(lsm): don't expect filename to be the 3rd field,
        // parse the header properly instead.
        sscanf(&buf[j], "Content-Disposition: %*s %*s filename=\"%1023[^\"]",
               fname);
        j = i + 2;
      }
    }

    // Give up if the headers are not what we expect
    if (fname[0] == '\0') {
      break;
    }

    // Move data to the beginning of the buffer
    assert(len >= headers_len);
    memmove(buf, &buf[headers_len], len - headers_len);
    len -= headers_len;
    conn->data_len = conn->request_len + len;

    // We open the file with exclusive lock held. This guarantee us
    // there is no other thread can save into the same file simultaneously.
    fp = NULL;

    // Construct destination file name. Do not allow paths to have slashes.
    s = fname;
    if ((p = strrchr(fname, '/')) != NULL && p > s) s = p;
    if ((p = strrchr(fname, '\\')) != NULL && p > s) s = p;

    // Open file in binary mode. TODO: set an exclusive lock.
    snprintf(path, path_len, "%s/%s", destination_dir, s);
    if ((fp = fopen(path, "wb")) == NULL) {
      break;
    }

    // Read POST data, write into file until boundary is found.
    eof = n = 0;
    do {
      len += n;
      for (i = 0; i < len - bl; i++) {
        if (!memcmp(&buf[i], "\r\n--", 4) &&
            !memcmp(&buf[i + 4], boundary, boundary_len)) {
          // Found boundary, that's the end of file data.
          fwrite(buf, 1, i, fp);
          eof = 1;
          memmove(buf, &buf[i + bl], len - (i + bl));
          len -= i + bl;
          break;
        }
      }
      if (!eof && len > bl) {
        fwrite(buf, 1, len - bl, fp);
        memmove(buf, &buf[len - bl], bl);
        len = bl;
      }
      to_read = buf_len - len;
      if (to_read > left_to_read(conn)) {
        to_read = (int) left_to_read(conn);
      }
    } while (!eof && (n = pull(NULL, conn, buf + len, to_read)) > 0);
    conn->data_len = conn->request_len + len;

    if (eof) {
      rewind(fp);
      return fp;
    } else {
      fclose(fp);
    }
  }

  return NULL;
}
Beispiel #30
0
static void *callback__(enum mg_event event,
                      struct mg_connection *conn,
                      const struct mg_request_info *request_info) {
	if (event == MG_NEW_REQUEST) {
		bool is_zs;
		{
			char*s=request_info->uri;
			int i=0;
			for(;*s;s++,i++);
			s=request_info->uri;
			is_zs=(i>=4&&s[i-4]=='.'&&s[i-3]=='w'&&s[i-2]=='z'&&s[i-1]=='s');
		}
		if(is_zs){
			void* qu=qu_new_(shangji_);
			char out[8]="";
			int err;
			const char* ret="";
			for(;;){
				{
					char* echo_def=new char[echo_def_fmt_.size()+32];
					sprintf(echo_def,echo_def_fmt_.c_str(),sprintf,mg_printf,conn,out);
					err=var_new_(jsq_,qu,kw_echo_.c_str(),echo_def,true,vartype_def_,false);
					delete echo_def;
					if(err)
						break;
				}
				if((err=var_new_(jsq_,qu,"ip",inet_ntoa(conn->client.rsa.u.sin.sin_addr),true,vartype_var_,false)))
					break;
				{
					const char *cl=mg_get_header(conn, "Content-Length");
					if(cl){
						size_t cl1=atoi(cl);
						const char* ct=mg_get_header(conn, "Content-Type");
						std::string boundary;
						if(ct){
							const char* ct1="multipart/form-data; boundary=";
							for(;;ct++,ct1++){
								if(!*ct1){
									boundary=ct;
									break;
								}
								if(*ct!=*ct1)
									break;
							}
						}
						if(boundary.empty()){
							char* postdata=new char[cl1+1];
							postdata[mg_read(conn, postdata, cl1)]=0;
							qu_var_new_form_url__(qu,postdata,1,&err);
							delete postdata;
							if(err)
								break;
						}else{
							std::string buf2;
							{
								char*buf=new char[128];
								for(;;){
									int siz=mg_read(conn, buf, 128);
									if(siz<=0)
										break;
									for(int i=0;i<siz;i++)
										buf2.append(1,buf[i]);
								}
								delete buf;
							}
							size_t pos1=0;
							std::string sp="\r\n\r\n";
							for(;;){
								size_t pos2=buf2.find(boundary,pos1);
								if(pos2==std::string::npos)
									break;
								if(pos1>0){
									std::string value,name,filename,s,s2;
									size_t posp=buf2.find(sp,pos1);
									bool is2=false;
									for(size_t i=pos1;i<posp+2/*\r\n*/;i++){
										char c=buf2[i];
										//printf("%c",c);
										if(c=='\n'||c==';'){
											//printf("<%s=%s>",s.c_str(),s2.c_str());
											if(is2){
												if(s=="name")
													name=s2;
												else if(s=="filename")
													filename=s2;
												is2=false;
											}
											s.clear();
											continue;
										}
										if(c=='='||c==':'){
											is2=true;
											s2.clear();
											continue;
										}
										if((c>=0&&c<=' ')||c=='"')
											continue;
										if(is2)
											s2+=c;
										else
											s+=c;
									}
									//printf("|\n");
									size_t 	i_b=posp+sp.length(),
											i_e=pos2-4/*\r\n--*/;
									if(i_b<i_e){
										/*for(size_t i=i_b;i<i_e;i++){
											char c=buf2[i];
											if(c>=' '&&c<='~')
												printf("%c",c);
											else if(c=='\n')
												printf("</\n");
											else
												printf(" %i ",c);
										}*/
										if(filename.empty()){
											value=buf2.substr(i_b,i_e-i_b);
										}else{
											filename=uploadir_+filename;
											value=filename;
											FILE *fp;
											if ((fp = fopen(filename.c_str(), "wb+")) == NULL){
											}else{
												fwrite(buf2.c_str()+i_b, 1, i_e-i_b, fp);
												if (ferror(fp)){
												}
												(void) fclose(fp);
											}
										}
									}
									//printf("|%u-%u-%u/%s=%s;\n|\n|\n",pos1,posp,pos2,name.c_str(),value.c_str());
									if((err=var_new_(jsq_,qu,name.c_str(),value.c_str(),false,vartype_var_,false)))
										break;
								}
								pos1=pos2+boundary.size()+2/*\r\n*/;
							}
							if(err)
								break;
						}
					}
				}

				/*for(int i=0;i<request_info->num_headers;i++){
					printf("%s\t%s\n",request_info->http_headers[i].name,request_info->http_headers[i].value);
				}*/

				std::string script=mg_get_option(ctx_, "document_root");
				script+=request_info->uri;
				char* qs=request_info->query_string;
				if(qs){
					qu_var_new_form_url__(qu,qs,1,&err);
					if(err)
						break;
				}
				ret=cb_(jsq_,qu,&err,script.c_str(),true,0);
				qu_delete_(qu);
				break;
			}
			//printf("out%s\n",out);
			switch(err){
			case jieshiqi_err_go_+keyword_end_:
			case jieshiqi_err_go_+keyword_exit_:
				break;
			default:
				if(err){
					if(!out[0])
						mg_printf(conn, "HTTP/1.1 200 OK\r\n"
				              "Content-Type: text/plain\r\n\r\n");
					if(err>=jieshiqi_err_){
						err-=jieshiqi_err_;
						//mg_printf(conn, "%s", ret);
						mg_printf(conn, "%s%s", l4_err_(jsq_),l4_errinfo_(jsq_,err));
						l4_err_clear_(jsq_);
					}else
						mg_printf(conn, "%s err%d", ret,err);
				}
				break;
			}
			return (void*)"";
		}
	}
	return NULL;
}