示例#1
0
/**
* Create a command object based on incoming request details
**/
Cmd* CmdManager::dispatch(
    struct MHD_Connection* connection,
    const char* url, const char* method
) {
    if (strcmp(url, "/echo") == 0) {
        const char *val = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "msg");
        if (val) {
            return new CmdEcho(std::string(val));
        }
    }

    if (strcmp(url, "/stats") == 0) {
        return new CmdStats();
    }

    if (strcmp(url, "/env/day-night") == 0) {
        float target_val = atof(MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "val"));
        float total_time = atof(MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "time"));
        return new CmdDayNightAnimate(target_val, total_time);
    }

    return NULL;
}
示例#2
0
static void _put_check_headers(struct MHD_Connection *connection,
		GHashTable *wanted_headers)
{
	GHashTableIter iter;
	gpointer key, value;
	const gchar *rec_value;

	g_hash_table_iter_init(&iter, wanted_headers);
	while (g_hash_table_iter_next(&iter, &key, &value)) 
	{
		rec_value = MHD_lookup_connection_value(connection,
				MHD_HEADER_KIND, key);
		g_assert(rec_value != NULL && "Missing required header");
		g_assert_cmpstr(value, ==, rec_value);
	}
}
示例#3
0
/**
 * Return the session handle for this connection, or 
 * create one if this is a new user.
 */
static struct Session *
get_session (struct MHD_Connection *connection)
{
  struct Session *ret;
  const char *cookie;

  cookie = MHD_lookup_connection_value (connection,
					MHD_COOKIE_KIND,
					COOKIE_NAME);
  if (cookie != NULL)
    {
      /* find existing session */
      ret = sessions;
      while (NULL != ret)
	{
	  if (0 == strcmp (cookie, ret->sid))
	    break;
	  ret = ret->next;
	}
      if (NULL != ret)
	{
	  ret->rc++;
	  return ret;
	}
    }
  /* create fresh session */
  ret = calloc (1, sizeof (struct Session));
  if (NULL == ret)
    {						
      fprintf (stderr, "calloc error: %s\n", strerror (errno));
      return NULL; 
    }
  /* not a super-secure way to generate a random session ID,
     but should do for a simple example... */
  snprintf (ret->sid,
	    sizeof (ret->sid),
	    "%X%X%X%X",
	    (unsigned int) random (),
	    (unsigned int) random (),
	    (unsigned int) random (),
	    (unsigned int) random ());
  ret->rc++;  
  ret->start = time (NULL);
  ret->next = sessions;
  sessions = ret;
  return ret;
}
示例#4
0
void RESTRequestState::set_callback_response(RESTContentReaderCallback rsp_writer, const char* content_type)
{
	const char* accept_enc = MHD_lookup_connection_value(get_conn(), MHD_HEADER_KIND, "Accept-Encoding");
	bool use_gzip = accept_enc && strstr(accept_enc, "gzip");

	set_response(MHD_create_response_from_callback(
			-1, RESPONSE_BLOCK_SIZE,
			callback_write,
			new ContentReaderState(rsp_writer, get_free_callback(), get_callback_data(), use_gzip),
			callback_free));
	MHD_add_response_header(get_response(), "Content-Type", content_type);
	if (use_gzip)
		MHD_add_response_header(get_response(), "Content-Encoding", "gzip");

	/* libmicrohttpd will call the appropriate callback to free the data instead of us */
	set_free_callback(NULL);
}
示例#5
0
/**
 * Gets all data from a list of hash obtained from X-Get-Hash-Array HTTP
 * header.
 * @param server_struct is the main structure for the server.
 * @param connection is the connection in MHD
 * @returns a newlly allocated gchar * string that contains the anwser to be
 *          sent back to the client (hopefully a json string containing
 *          a hash (that is a fake one here), data and size of the data.
 */
static gchar *get_data_from_a_list_of_hashs(server_struct_t *server_struct, struct MHD_Connection *connection)
{
    const char *header = NULL;
    gchar *answer = NULL;
    gchar *hash = NULL;
    GList *head = NULL;
    GList *header_hdl = NULL;
    GList *hash_data_list = NULL;
    hash_data_t *header_hd = NULL;
    hash_data_t *hash_data = NULL;
    backend_t *backend = server_struct->backend;
    guint size = 0;


    header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "X-Get-Hash-Array");
    header_hdl = make_hash_data_list_from_string((gchar *)header);

    head = header_hdl;
    while (header_hdl != NULL)
        {
            header_hd = header_hdl->data;
            hash = hash_to_string(header_hd->hash);
            hash_data = backend->retrieve_data(server_struct, hash);
            free_variable(hash);
            size = size + hash_data->read;
            hash_data_list = g_list_prepend(hash_data_list, hash_data);
            header_hdl = g_list_next(header_hdl);
        }

    g_list_free_full(head, free_hdt_struct);
    hash_data_list = g_list_reverse(hash_data_list);

    head = hash_data_list;

    hash_data = create_one_hash_data_t_from_hash_data_list(hash_data_list, size);

    g_list_free_full(head, free_hdt_struct);

    answer = convert_hash_data_t_to_string(hash_data);

    free_hash_data_t(hash_data);

    return answer;
}
示例#6
0
文件: mp3d.cpp 项目: JoeBargo/enh
static int handle_request(void* /*cls*/, MHD_Connection* connection, const char* url, const char* method, const char*, const char*, unsigned int*, void** /*con_cls*/) {
  if (std::string(method) != "GET") {
    return report_error(connection, MHD_HTTP_NOT_IMPLEMENTED, "501 Not Implemented");
  }
  
  if (mp3d_debug_httpd) {
    MHD_get_connection_values(connection, MHD_HEADER_KIND, dump_key, NULL);
    MHD_get_connection_values(connection, MHD_COOKIE_KIND, dump_key, NULL);
    MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, dump_key, NULL);
    std::cout << "*** " << method << " request for '" << url << "'" << std::endl;
  }
  
  const char* q = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "mp3d_q");
  
  const std::string request_url(url);
  if (request_url == "/") {
    std::string page_data;
    make_main_page(page_data, q);
    return send_string_response(connection, MHD_HTTP_OK, page_data);
  } else if (boost::starts_with(request_url, "/static/")) {
    StringStringMap::const_iterator it = static_file_map.find(request_url);
    if (it == static_file_map.end()) {
      return report_error(connection, MHD_HTTP_NOT_FOUND, "404 Not Found");
    }
    return send_string_response(connection, MHD_HTTP_OK, it->second);
  } else if (boost::starts_with(request_url, "/play/")) {
    const size_t id = strtoul(request_url.substr(6).c_str(), 0, 10); // FIXME: error checking.
    play_queue.clear();
    play_queue.push_back(all_mp3s[id]); // FIXME: lookup by id (don't assume id == index).
    return see_other(connection, "/");
  } else if (boost::starts_with(request_url, "/add/")) {
    const size_t id = strtoul(request_url.substr(5).c_str(), 0, 10); // FIXME: error checking.
    play_queue.push_back(all_mp3s[id]); // FIXME: lookup by id (don't assume id == index).
    return see_other(connection, "/");
  } else if (boost::starts_with(request_url, "/remove/")) {
    const size_t id = strtoul(request_url.substr(8).c_str(), 0, 10); // FIXME: error checking.
    play_queue.remove(id); // FIXME: is this set-like behavior the behavior we want?
    return see_other(connection, "/");
  } else {
    return report_error(connection, MHD_HTTP_NOT_FOUND, "404 Not Found");
  }
}
static int
serveMasterNameXML (const void *cls,
	      		  const char *mime,
	      		  struct Session *session,
	      		  struct MHD_Connection *connection)
{
  int ret;
  //char *reply;
  struct MHD_Response *response;
   
  const char *pCmd = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "Cmd");
  printf("Cmd = %s\n", pCmd);
  
  // The XML is filled up by the CommandDispatcher using a static string object.
  // Since this is a .c file, we cannot use class objects here, so we basically
  // extract a char point from it.
  const char *pString;   
  // Dispatch the command
  CommandDispatcher(&pString, pCmd);
  //strcpy(pString, MASTER_NAME);
  //sprintf(pString, reply, String);
  //free(reply);
  
  fprintf(stdout, "%s\n", pString);
  
  /* return static form */
  response = MHD_create_response_from_buffer (strlen (pString),
					      (void *) pString,
					      MHD_RESPMEM_PERSISTENT);				  
  if (NULL == response)
    return MHD_NO;
  add_session_cookie (session, response);
  MHD_add_response_header (response,
			   MHD_HTTP_HEADER_CONTENT_ENCODING,
			   mime);
  ret = MHD_queue_response (connection,
			    MHD_HTTP_OK,
			    response);
  MHD_destroy_response (response);
  return ret;
}
示例#8
0
/**
 * Performs lookup values for given keys.
 * For GET requests, we will use the libmicrohttpd's
 * internal API: MHD_lookup_connection_value().
 * For POST requests, we will retrieve the value from
 * the slinkedl_list that was created and populated by
 * the post_iterator().
 *
 * @param connection Pointer to the MHD_Connection
 * @param key        The key for which we need to retrieve
 *                   the value.
 * @param con_cls    This is a pointer to the slinkedl_list
 *                   that was passed back and forth via
 *                   several callback between the application
 *                   and the libmicrohttpd library.
 * @param val        Pointer to the value that we are looking
 *                   for.
 */
void httpd_lookup_arg(void *connection, const char *key,
		void *con_cls, str *val)
{
	slinkedl_list_t *list = (slinkedl_list_t*)con_cls;

	if (val) {
		if (list==NULL) {
			val->s = (char *)MHD_lookup_connection_value(
					(struct MHD_Connection *)connection,
						MHD_GET_ARGUMENT_KIND, key);
			if (val->s) val->len = strlen(val->s);
			else val->len = 0;
		} else {
			slinkedl_traverse(list, &httpd_get_val, (void *)key, val);
		}
	} else {
		LM_ERR("NULL holder for requested val\n");
	}

	return;
}
示例#9
0
static int
ahc_echo (void *cls,
          struct MHD_Connection *connection,
          const char *url,
          const char *method,
          const char *version,
          const char *upload_data, size_t *upload_data_size, void **ptr)
{
  static int aptr;
  const char *fmt = cls;
  const char *val;
  char *me;
  struct MHD_Response *response;
  int ret;

  if (0 != strcmp (method, "GET"))
    return MHD_NO;              /* unexpected method */
  if (&aptr != *ptr)
    {
      /* do never respond on first call */
      *ptr = &aptr;
      return MHD_YES;
    }
  *ptr = NULL;                  /* reset when done */
  val = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "q");
  me = malloc (snprintf (NULL, 0, fmt, "q", val) + 1);
  if (me == NULL)
    return MHD_NO;
  sprintf (me, fmt, "q", val);
  response = MHD_create_response_from_buffer (strlen (me), me,
					      MHD_RESPMEM_MUST_FREE);
  if (response == NULL)
    {
      free (me);
      return MHD_NO;
    }
  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
  MHD_destroy_response (response);
  return ret;
}
示例#10
0
std::string CWebServer::GetRequestHeaderValue(struct MHD_Connection *connection, enum MHD_ValueKind kind, const std::string &key)
{
  if (connection == NULL)
    return "";

  const char* value = MHD_lookup_connection_value(connection, kind, key.c_str());
  if (value == NULL)
    return "";

  if (StringUtils::EqualsNoCase(key, MHD_HTTP_HEADER_CONTENT_TYPE))
  {
    // Work around a bug in firefox (see https://bugzilla.mozilla.org/show_bug.cgi?id=416178)
    // by cutting of anything that follows a ";" in a "Content-Type" header field
    std::string strValue(value);
    size_t pos = strValue.find(';');
    if (pos != std::string::npos)
      strValue = strValue.substr(0, pos);

    return strValue;
  }

  return value;
}
示例#11
0
/**
 * @param connection is the connection in MHD
 * @returns in bytes the value (a guint) of the Content-Length: header
 */
static guint64 get_content_length(struct MHD_Connection *connection)
{
    const char *length = NULL;
    guint64 len = DEFAULT_SERVER_BUFFER_SIZE;

    length = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length");

    if (length != NULL)
        {
            /** @todo test len and return code for sscanf to validate a correct entry */
            if (sscanf(length, "%"G_GUINT64_FORMAT, &len) <= 0)
                {
                    print_error(__FILE__, __LINE__, _("Could not guess Content-Length header value: %s\n"), strerror(errno));
                    len = DEFAULT_SERVER_BUFFER_SIZE;
                }

            if (len < 0 || len > 4294967296)
                {
                    len = DEFAULT_SERVER_BUFFER_SIZE;
                }
        }

    return len;
}
示例#12
0
/**
 * Return the session handle for this connection, or
 * create one if this is a new user.
 */
WebSession * WebServer::getSession (struct MHD_Connection *connection)
{
    WebSession *result = NULL;
    const char *cookie;
    
    cookie = MHD_lookup_connection_value (connection,
                                          MHD_COOKIE_KIND,
                                          COOKIE_NAME);
    if (cookie != NULL)
    {
        for (auto it = _sessions.begin(); it != _sessions.end(); it++)
        {
            WebSession *current = *it;
            if (strcmp (cookie, current->getSID().c_str()))
            {
                result = current;
                break;
            }
        }
    }
    
    if (result == NULL)
    {
        /* not a super-secure way to generate a random session ID,
         but should do for a simple example... */
        std::string sid;
        sid += (unsigned int) rand ();
        sid += (unsigned int) rand ();
        sid += (unsigned int) rand ();
        sid += (unsigned int) rand ();
        WebSession *newSession = new WebSession(sid, 1, time(NULL));
        _sessions.push_back(newSession);
        result = newSession;
    }
    return result;
}
/**
 * Callback function used to answer clients's connection (MHD_AccessHandlerCallback)
 *
 * @param cls Custom value selected at callback registration time, used to initialize the done flag
 *	
 * @param connection The client connection 
 *
 * @param url The url on which the client made its request
 *
 * @param method The http method with which the client made its request (Only GET and PUT supported)
 *
 * @param version The HTTP version string (i.e. HTTP/1.1)
 *
 * @param upload_data Data beeing uploaded when receiving PUT
 *
 * @param upload_data_size Size of the data beeing uploaded when receiving PUT
 *
 * @param con_cls reference to a pointer, initially set to NULL, that this callback can set to some 
 *        address and that will be preserved by MHD for future calls for this request
 *
 * @return MHD_YES to pursue the request handling, MHD_NO in case of error with 
 *         the request, return value of the send_* functions otherwise
 */
int 
answer_to_connection ( void *cls, struct MHD_Connection *connection, 
                       const char *url, 
                       const char *method, const char *version, 
                       const char *upload_data, 
                       size_t *upload_data_size, void **con_cls		)
{
	Service *requested_service;
	char *xmlbuff = NULL;
	int ret;
	int *done = cls;
	static int aptr;
	const char *get_arg;
	struct sockaddr *addr;
	addr = MHD_get_connection_info (connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS)->client_addr;
	char IP[16];
	inet_ntop(addr->sa_family,addr->sa_data + 2, IP, 16);

	if( 0 == strcmp (method, MHD_HTTP_METHOD_GET) )
	{

		if ( &aptr != *con_cls )
		{
			/* do never respond on first call */
			*con_cls = &aptr;
			return MHD_YES;
		}
		*con_cls = NULL;


		if( strcmp(url,"/log") == 0 )
		{
			ret = subscribe_to_log_events(connection, con_cls, HPD_IS_UNSECURE_CONNECTION);
			Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
			return ret;
		}
		else if( strcmp(url,"/events") == 0 )
		{
			ret = set_up_server_sent_event_connection( connection, HPD_IS_UNSECURE_CONNECTION );
			if( ret == MHD_HTTP_NOT_FOUND ) 
			{
				Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
				return send_error (connection, MHD_HTTP_NOT_FOUND);
			}
			else 
			{
				Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
				return ret;
			}
		}
		else if( strcmp(url,"/devices") == 0 )
		{
			xmlbuff = get_xml_device_list();
			ret = send_xml (connection, xmlbuff);
			Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
			return ret;
		}
		else if( ( requested_service = matching_service (service_head, url) ) != NULL )
		{
			get_arg = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "x");
			if( get_arg != NULL )
			{
				if( strcmp(get_arg, "1") == 0 )
				{
					pthread_mutex_lock(requested_service->mutex);
					xmlbuff = extract_service_xml(requested_service);
					pthread_mutex_unlock(requested_service->mutex);
					ret = send_xml (connection, xmlbuff);
					Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, "x=1");
					return ret;
				}
			}

			get_arg = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "p");
			if( get_arg != NULL )
			{
				if( strcmp(get_arg, "1") == 0 )
				{
					ret = subscribe_to_service(connection, requested_service, con_cls, HPD_IS_UNSECURE_CONNECTION);
					Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, "p=1");
					return ret;
				}
			}

			pthread_mutex_lock( requested_service->mutex );
			ret = requested_service-> get_function(	requested_service, 
			                                        requested_service->get_function_buffer,
			                                        MHD_MAX_BUFFER_SIZE);
			if( ret != 0 )
				requested_service->get_function_buffer[ret] = '\0';
			else
			{
				pthread_mutex_unlock( requested_service->mutex );
				ret = send_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR);
				Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
				return ret;
			}

			xmlbuff = get_xml_value (requested_service->get_function_buffer);
			pthread_mutex_unlock(requested_service->mutex);
			ret = send_xml(connection, xmlbuff);
			Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
			return ret;
		}
		else
		{
			ret = send_error(connection, MHD_HTTP_NOT_FOUND);
			Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
			return ret;
		}
	}

	else if( 0 == strcmp(method, MHD_HTTP_METHOD_PUT) )
	{ 

		if( ( *con_cls ) == NULL )
		{
			if( *upload_data_size == 0 )
			{
				return MHD_YES; /* not ready yet */
			}	    
			/* Add a space for a '/0' in order to clear the end of the XML */
			char *put_data_temp = (char*)malloc((*upload_data_size)*sizeof(char)+1);
			memcpy(put_data_temp, upload_data, *upload_data_size);
			put_data_temp[*upload_data_size]='\0';
			*con_cls = put_data_temp;
			*upload_data_size = 0;
			return MHD_YES;
		}
		else
		{
			if( ( requested_service = matching_service (service_head, url) ) !=NULL )
			{
				pthread_mutex_lock(requested_service->mutex);
				if( requested_service->put_function != NULL && *con_cls != NULL )
				{
					char* _value = get_value_from_xml_value (*con_cls);
					if(_value == NULL)
					{
						pthread_mutex_unlock(requested_service->mutex);
						ret = send_error (connection, MHD_HTTP_BAD_REQUEST);
						Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
						return ret;
					}

					free(*con_cls);
					ret = requested_service-> put_function( requested_service, 
					                                        requested_service->get_function_buffer,
					                                        MHD_MAX_BUFFER_SIZE,
					                                        _value );
					free(_value);

					if( ret != 0 )
						requested_service->get_function_buffer[ret] = '\0';
					else
					{
						pthread_mutex_unlock( requested_service->mutex );
						ret = send_error(connection, MHD_HTTP_INTERNAL_SERVER_ERROR);
						Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
						return ret;
					}

					xmlbuff = get_xml_value (requested_service->get_function_buffer);
					pthread_mutex_unlock(requested_service->mutex);
					send_event_of_value_change (requested_service, requested_service->get_function_buffer);
					ret = send_xml (connection, xmlbuff);
					Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
					return ret;
				}
				else
				{
					pthread_mutex_unlock(requested_service->mutex);
					ret = send_error(connection, MHD_HTTP_BAD_REQUEST);
					Log (HPD_LOG_ONLY_REQUESTS, NULL, IP, method, url, NULL);
					return ret;
				}
			}
			else
				return send_error (connection, MHD_HTTP_NOT_FOUND);
		}
	}
	return MHD_NO;
}
示例#14
0
static int
ahc_echo (void *cls,
          struct MHD_Connection *connection,
          const char *url,
          const char *method,
          const char *version,
          const char *upload_data, size_t *upload_data_size,
          void **unused)
{
  static int ptr;
  const char *me = cls;
  struct MHD_Response *response;
  int ret;
  const char *hdr;

  if (0 != strcmp (me, method))
    return MHD_NO;              /* unexpected method */
  if (&ptr != *unused)
    {
      *unused = &ptr;
      return MHD_YES;
    }
  *unused = NULL;
  ret = 0;
  MHD_get_connection_values (connection, MHD_HEADER_KIND, &kv_cb, &ret);
  if (ret != 1)
    abort ();
  hdr = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "NotFound");
  if (hdr != NULL)
    abort ();
  hdr = MHD_lookup_connection_value (connection,
                                     MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT);
  if ((hdr == NULL) || (0 != strcmp (hdr, "*/*")))
    abort ();
  hdr = MHD_lookup_connection_value (connection,
                                     MHD_HEADER_KIND, MHD_HTTP_HEADER_HOST);
  if ((hdr == NULL) || (0 != strcmp (hdr, "127.0.0.1:21080")))
    abort ();
  MHD_set_connection_value (connection,
                            MHD_HEADER_KIND, "FakeHeader", "NowPresent");
  hdr = MHD_lookup_connection_value (connection,
                                     MHD_HEADER_KIND, "FakeHeader");
  if ((hdr == NULL) || (0 != strcmp (hdr, "NowPresent")))
    abort ();

  response = MHD_create_response_from_buffer (strlen (url),
					      (void *) url,
					      MHD_RESPMEM_MUST_COPY);
  MHD_add_response_header (response, "MyHeader", "MyValue");
  hdr = MHD_get_response_header (response, "MyHeader");
  if (0 != strcmp ("MyValue", hdr))
    abort ();
  MHD_add_response_header (response, "MyHeader", "MyValueToo");
  if (MHD_YES != MHD_del_response_header (response, "MyHeader", "MyValue"))
    abort ();
  hdr = MHD_get_response_header (response, "MyHeader");
  if (0 != strcmp ("MyValueToo", hdr))
    abort ();
  if (1 != MHD_get_response_headers (response, NULL, NULL))
    abort ();
  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
  MHD_destroy_response (response);
  if (ret == MHD_NO)
    abort ();
  return ret;
}
示例#15
0
/**
 * http request handle
 */
inline int http_request_handle (void *cls, struct MHD_Connection *connection, const char *url,
                                const char *method, const char *version, const char *upload_data,
                                size_t * upload_data_size, void **con_cls)
{
#if ENABLE_AUTHENTICATE
	//check request authenticate(cookie)
	if (!(strstr(url , AUTHENTICATE_LOGIN_URL)))
	{
		if (check_authentication(connection) < 0)
			return MHD_YES;
	}
#endif

	if (!(*con_cls))
	{
		//process GET request or first POST request

		if (!strcmp(method, MHD_HTTP_METHOD_POST))	//POST
		{
			next_connection_info *next_connection;
			next_connection = calloc(sizeof(char),
			                         sizeof(next_connection_info));
			strcpy(next_connection->url, url);
			strcpy(next_connection->method, MHD_HTTP_METHOD_POST);
			next_connection->post_data_len
			    = atoi (MHD_lookup_connection_value (connection,
			            MHD_HEADER_KIND,
			            MHD_HTTP_HEADER_CONTENT_LENGTH));

			if (strstr(url, "upload"))
			{
				const char *name = MHD_lookup_connection_value(connection,
				                   MHD_GET_ARGUMENT_KIND, "file_name");
				if (!name)
				{
					free(next_connection);
					return MHD_NO;
				}
				else
					strcpy(next_connection->file_name, name);


				next_connection->post_data = NULL;
			}
			else
			{
				next_connection->post_data = calloc(sizeof(char),
				                                    next_connection->post_data_len);
				if (!next_connection->post_data)
					return MHD_NO;
			}
			*con_cls = (void *)next_connection;
		}
		else if (!strcmp(method, MHD_HTTP_METHOD_GET))	//GET
			process_get_url_requert(url, connection);
	}
	else
	{
		next_connection_info *next_connection = ((next_connection_info *)(*con_cls));

		if (!strcmp(next_connection->method,  MHD_HTTP_METHOD_POST))
		{
			if (*upload_data_size)
			{
				if (next_connection->post_data_len == *upload_data_size)
				{
					if (strstr(next_connection->url, "upload"))
						upload_Begin_proc(next_connection,
						                  (char *)upload_data, *upload_data_size);
					else
						memcpy(next_connection->post_data, upload_data,
						       next_connection->post_data_len);

					*upload_data_size = 0;
				}
				else
				{
					if (strstr(next_connection->url, "upload"))
						upload_Other_proc(next_connection,
						                  (char *)upload_data, *upload_data_size);
					else
						memcpy((next_connection->post_data + next_connection->offset),
						       upload_data, *upload_data_size);

					next_connection->offset += *upload_data_size;
					*upload_data_size = 0;
				}
			}
			else
			{
				url_to_api(url, connection, true,
				           next_connection->post_data,
				           next_connection->post_data_len,
				           next_connection->file_name);

				if (next_connection->post_data)
				{
					free(next_connection->post_data);
					free(next_connection);
				}
			}
		}
		else
			return_404(connection);
	}

	return MHD_YES;
}
示例#16
0
文件: req.c 项目: RAttab/optics
const char *crest_req_get_header(struct crest_req *req, const char *key)
{
    return MHD_lookup_connection_value(req->conn, MHD_HEADER_KIND, key);
}
示例#17
0
const char* RESTRequestState::get_qsargv(const char* key) const
{
	return MHD_lookup_connection_value(conn_, MHD_GET_ARGUMENT_KIND, key);
}
static int url_handler(void *cls, struct MHD_Connection *connection,
        const char *url, const char *method, const char *version,
        const char *upload_data, size_t *upload_data_size, void **con_cls)
{
    char *me;
    struct MHD_Response *response;
    int ret;
    std::map<std::string, std::string> url_args;
    std::string respdata;

    // HTTP access control (CORS)
    // https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control
    // some times a preflight check is required which uses the OPTIONS HTTP method to check for permission to
    // call cross-domain requests
    if (0 == strcmp(method, MHD_HTTP_METHOD_OPTIONS))
        return sendAccessControl(connection, url, method, version);

    // we only need to deal with GET requests
    /*  FIXME -- don't need this since the HTTP options/preflight will ensure non-supported methods are rejected?
    if (0 != strcmp(method, MHD_HTTP_METHOD_GET))
        return MHD_NO;*/

    // set up out connection information on the first pass through.
    if (NULL == *con_cls)
    {
        struct connection_info *con_info;
        con_info = (connection_info*) malloc (sizeof (struct connection_info));
        if (NULL == con_info) return MHD_NO;
        static int idCounter = 1;
        con_info->id = idCounter++;
        // FIXME: for some reason this line causes segfaults under linux?
        //con_info->url = std::string(url ? url : "");
        con_info->data = NULL;
        con_info->biomapsId = NULL;
        con_info->dataSize = 0;
        if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
        {
            std::cout << "Setting up con_cls for POST: " << con_info->id << std::endl;
            std::cout << " - with url: " << url << std::endl;
            const char* tmp = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-type");
            std::string contentType(tmp ? tmp : "");
            if (contentType.find(JSON_CONTENT_TYPE) == std::string::npos)
            {
                std::cerr << "Error creating POST processor?! Unhandled content type: "
                          << MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-type")
                          << std::endl;
                free (con_info);
                return MHD_NO;
            }
            con_info->connectiontype = POST;
        }
        else con_info->connectiontype = GET;
        *con_cls = (void *) con_info;
        return MHD_YES;
    }

    // intercept POST requests for now to test stuff
    if (0 == strcmp(method, MHD_HTTP_METHOD_POST))
    {
        // post recieved, do stuff.
        struct connection_info *con_info = (connection_info*)(*con_cls);
        std::cout << "Received a POST for connection: " << con_info->id << std::endl;
        if (*upload_data_size != 0)
        {
            std::cout << "Processed some data: " << *upload_data_size << std::endl;
            //std::cout << "Data: " << upload_data << std::endl;
            con_info->data = (char*)realloc(con_info->data, con_info->dataSize + *upload_data_size);
            memcpy(con_info->data + con_info->dataSize, upload_data, *upload_data_size);
            con_info->dataSize += *upload_data_size;
            //std::string bob(upload_data, *upload_data_size);
            //con_info->data += bob.c_str();
            //std::cout << "con_info->data: " << con_info->data << std::endl;
            *upload_data_size = 0; // set to 0 to indicate all data considered/handled.
            return MHD_YES;
        }
        else
        {
        }
    }
    else if (0 == strcmp(method, MHD_HTTP_METHOD_GET))
    {
        if (MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND,
                get_url_args, &url_args) < 0)
        {
            return MHD_NO;
        }

        API api;
        respdata = api.executeAPI(url, url_args);
    }

    if (respdata == "BAD RESPONSE")
    {
        return send_bad_response(connection);
    }
    //val = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "q");
    me = (char *) malloc(respdata.size() + 1);
    if (me == 0)
        return MHD_NO;
    strncpy(me, respdata.c_str(), respdata.size() + 1);
    response = MHD_create_response_from_buffer(strlen(me), me,
            MHD_RESPMEM_MUST_FREE);
    if (response == 0)
    {
        free(me);
        return MHD_NO;
    }

    /*it = url_args.find("type");
     if (it != url_args.end() && strcasecmp(it->second.c_str(), "xml") == 0)
     type = typexml;*/

    MHD_add_response_header(response, "Content-Type", "application/json");
    MHD_add_response_header(response, "Content-Range", "items 0-5/5");
    MHD_add_response_header(response, "Access-Control-Allow-Origin", "*");
    // need to make sure we always expose the (non-simple) headers that we use
    MHD_add_response_header(response, "Access-Control-Expose-Headers",
            "Content-Range");
    //MHD_add_response_header(response, "OurHeader", type);

    ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
    MHD_destroy_response(response);
    return ret;
}
示例#19
0
int
http_cb_request (void *cls,
                struct MHD_Connection *connection,
                const char *url,
                const char *method,
                const char *version,
                const char *upload_data,
                size_t *upload_data_size,
                void **ptr)
{
  (void)cls;
  (void)url;
  (void)upload_data;
  (void)upload_data_size;
  
  int ret;
  struct Proxy *proxy;
  struct SPDY_Headers spdy_headers;
  bool with_body = false;
  struct HTTP_URI *http_uri;
  const char *header_value;

  if (NULL == ptr || NULL == *ptr)
    return MHD_NO;
    
  http_uri = (struct HTTP_URI *)*ptr;
    
  if(NULL == http_uri->proxy)
  {
    //first call for this request
    if (0 != strcmp (method, MHD_HTTP_METHOD_GET) && 0 != strcmp (method, MHD_HTTP_METHOD_POST))
    {
      free(http_uri->uri);
      free(http_uri);
      PRINT_INFO2("unexpected method %s", method);
      return MHD_NO;
    }
    
    if(NULL == (proxy = au_malloc(sizeof(struct Proxy))))
    {
      free(http_uri->uri);
      free(http_uri);
      PRINT_INFO("No memory");
      return MHD_NO; 
    }
    
    ++glob_opt.responses_pending;
    proxy->id = rand();
    proxy->http_active = true;
    proxy->http_connection = connection;
    http_uri->proxy = proxy;
    return MHD_YES;
  }
  
  proxy = http_uri->proxy;
  
  if(proxy->spdy_error || proxy->http_error)
    return MHD_NO; // handled at different place TODO? leaks?

  if(proxy->spdy_active)
  {
    if(0 == strcmp (method, MHD_HTTP_METHOD_POST))
    {
      PRINT_INFO("POST processing");
        
      int rc= spdylay_session_resume_data(proxy->spdy_connection->session, proxy->stream_id);
      PRINT_INFO2("rc is %i stream is %i", rc, proxy->stream_id);
      proxy->spdy_connection->want_io |= WANT_WRITE;
      
      if(0 == *upload_data_size)
      {
      PRINT_INFO("POST http EOF");
        proxy->receiving_done = true;
        return MHD_YES;
      }
      
      if(!copy_buffer(upload_data, *upload_data_size, &proxy->received_body, &proxy->received_body_size))
      {
        //TODO handle it better?
        PRINT_INFO("not enough memory (malloc/realloc returned NULL)");
        return MHD_NO;
      }
      
      *upload_data_size = 0;
                               
      return MHD_YES;
    }
  
    //already handled
    PRINT_INFO("unnecessary call to http_cb_request");
    return MHD_YES;
  }
  
  //second call for this request

  PRINT_INFO2("received request for '%s %s %s'", method, http_uri->uri, version);

  proxy->url = http_uri->uri;
  
  header_value = MHD_lookup_connection_value(connection,
    MHD_HEADER_KIND, MHD_HTTP_HEADER_CONTENT_LENGTH);
  
  with_body = 0 == strcmp (method, MHD_HTTP_METHOD_POST)
    && (NULL == header_value || 0 != strcmp ("0", header_value));
    
  PRINT_INFO2("body will be sent %i", with_body);
    
  ret = parse_uri(&glob_opt.uri_preg, proxy->url, &proxy->uri);
  if(ret != 0)
    DIE("parse_uri failed");
  proxy->http_uri = http_uri;

  spdy_headers.num = MHD_get_connection_values (connection,
                       MHD_HEADER_KIND,
                       NULL,
                       NULL);
  if(NULL == (spdy_headers.nv = au_malloc(((spdy_headers.num + 5) * 2 + 1) * sizeof(char *))))
    DIE("no memory");
  spdy_headers.nv[0] = ":method";     spdy_headers.nv[1] = method;
  spdy_headers.nv[2] = ":path";       spdy_headers.nv[3] = proxy->uri->path_and_more;
  spdy_headers.nv[4] = ":version";    spdy_headers.nv[5] = (char *)version;
  spdy_headers.nv[6] = ":scheme";     spdy_headers.nv[7] = proxy->uri->scheme;
  spdy_headers.nv[8] = ":host";       spdy_headers.nv[9] = NULL;
  //nv[14] = NULL;
  spdy_headers.cnt = 10;
  MHD_get_connection_values (connection,
                       MHD_HEADER_KIND,
                       &http_cb_iterate,
                       &spdy_headers);
                       
  spdy_headers.nv[spdy_headers.cnt] = NULL;
  if(NULL == spdy_headers.nv[9])
    spdy_headers.nv[9] = proxy->uri->host_and_port;

  if(0 != spdy_request(spdy_headers.nv, proxy, with_body))
  {
    free(spdy_headers.nv);
    //free_proxy(proxy);
    
    return MHD_NO;
  }
  free(spdy_headers.nv);
  
  proxy->http_response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
                         4096,
                         &http_cb_response,
                         proxy,
                         &http_cb_response_done);

  if (NULL == proxy->http_response)
    DIE("no response");
  
  if(MHD_NO == MHD_add_response_header (proxy->http_response,
                 "Proxy-Connection", "keep-alive"))
    PRINT_INFO("SPDY_name_value_add failed: ");
  if(MHD_NO == MHD_add_response_header (proxy->http_response,
                 "Connection", "Keep-Alive"))
    PRINT_INFO("SPDY_name_value_add failed: ");
  if(MHD_NO == MHD_add_response_header (proxy->http_response,
                 "Keep-Alive", "timeout=5, max=100"))
    PRINT_INFO("SPDY_name_value_add failed: ");
    
  proxy->spdy_active = true;
  
  return MHD_YES;
}
示例#20
0
文件: httpapi.c 项目: boothj5/stabber
int
connection_cb(void* cls, struct MHD_Connection* conn, const char* url, const char* method, const char* version,
    const char* data, size_t* size, void** con_cls)
{
#ifdef PLATFORM_OSX
    pthread_setname_np("http");
#else
    prctl(PR_SET_NAME, "http");
#endif

    if (*con_cls == NULL) {
        ConnectionInfo *con_info = create_connection_info();

        if (g_strcmp0(method, "POST") == 0 && g_strcmp0(url, "/send") == 0) {
            con_info->stbbr_op = STBBR_OP_SEND;
        } else if (g_strcmp0(method, "POST") == 0 && g_strcmp0(url, "/for") == 0) {
            con_info->stbbr_op = STBBR_OP_FOR;
        } else if (g_strcmp0(method, "POST") == 0 && g_strcmp0(url, "/verify") == 0) {
            con_info->stbbr_op = STBBR_OP_VERIFY;
        } else {
            con_info->stbbr_op = STBBR_OP_UNKNOWN;
            return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST);
        }

        *con_cls = (void*) con_info;

        return MHD_YES;
    }

    ConnectionInfo *con_info = (ConnectionInfo*) *con_cls;

    if (*size != 0) {
        g_string_append_len(con_info->body, data, *size);
        *size = 0;

        return MHD_YES;
    }

    const char *id = NULL;
    const char *query = NULL;
    int res = 0;

    switch (con_info->stbbr_op) {
        case STBBR_OP_SEND:
            server_send(con_info->body->str);

            return send_response(conn, NULL, MHD_HTTP_OK);
        case STBBR_OP_FOR:
            id = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "id");
            query = MHD_lookup_connection_value(conn, MHD_GET_ARGUMENT_KIND, "query");
            if (id && query) {
                return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST);
            }

            if (id) {
                prime_for_id(id, con_info->body->str);
                return send_response(conn, NULL, MHD_HTTP_CREATED);
            }

            if (query) {
                prime_for_query(query, con_info->body->str);
                return send_response(conn, NULL, MHD_HTTP_CREATED);
            }

            return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST);
        case STBBR_OP_VERIFY:
            res = verify_any(con_info->body->str, TRUE);
            if (res) {
                return send_response(conn, "true", MHD_HTTP_OK);
            } else {
                return send_response(conn, "false", MHD_HTTP_OK);
            }
        default:
            return send_response(conn, NULL, MHD_HTTP_BAD_REQUEST);
    }
}
示例#21
0
/**
 * Main request handler.
 */
static int
access_handler_callback (void *cls, struct MHD_Connection *connection,
                         const char *url, const char *method,
                         const char *version, const char *upload_data,
                         size_t * upload_data_size, void **con_cls)
{
  static int dummy;
  static const struct Entry map[] = {
    { "prefix", "prefix" },
    { "name", "name" },
    { "suffix", "suffix" },
    { "street", "street" },
    { "city", "city" },
    { "phone", "phone" },
    { "fax", "fax" },
    { "email", "email"},
    { "homepage", "homepage" },
    { "orga", "orga"},
    { "departmenti18n", "departmentde"},
    { "departmenten", "departmenten"},
    { "subdepartmenti18n", "subdepartmentde"},
    { "subdepartmenten", "subdepartmenten"},
    { "jobtitlei18n", "jobtitlegerman"},
    { "jobtitleen", "jobtitleenglish"},
    { "subdepartmenten", "subdepartmenten"},
    { NULL, NULL }
  };

  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Refusing `%s' request to HTTP server\n"),
                method);
    return MHD_NO;
  }
  if (NULL == *con_cls)
  {
    (*con_cls) = &dummy;
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Sending 100 CONTINUE reply\n");
    return MHD_YES;             /* send 100 continue */
  }
  if (0 == strcasecmp (url, "/"))
    return MHD_queue_response (connection,
                               MHD_HTTP_OK,
                               main_response);
  if (0 == strcasecmp (url, "/submit.pdf"))
  {
    unsigned int i;
    char *p;
    char *tmp;
    char *deffile;
    struct GNUNET_CRYPTO_EcdsaPublicKey pub;
    size_t slen;
    FILE *f;
    struct stat st;
    struct MHD_Response *response;
    int fd;
    int ret;

    const char *gpg_fp = MHD_lookup_connection_value (connection,
                                                      MHD_GET_ARGUMENT_KIND,
                                                      "gpgfingerprint");
    const char *gns_nick = MHD_lookup_connection_value (connection,
                                                        MHD_GET_ARGUMENT_KIND,
                                                        "gnsnick");
    const char *gnskey = MHD_lookup_connection_value (connection,
                                                      MHD_GET_ARGUMENT_KIND,
                                                      "gnskey");
    if ( (NULL == gnskey) ||
         (GNUNET_OK !=
          GNUNET_CRYPTO_ecdsa_public_key_from_string (gnskey,
                                                      strlen (gnskey),
                                                      &pub)))
    {
      return MHD_queue_response (connection,
                                 MHD_HTTP_OK,
                                 invalid_gnskey_response);
    }
    tmp = GNUNET_DISK_mkdtemp (gnskey);
    if (NULL == tmp)
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mktemp", gnskey);
      return MHD_NO;
    }
    GNUNET_asprintf (&deffile,
                     "%s%s%s",
                     tmp, DIR_SEPARATOR_STR, "def.tex");
    f = FOPEN (deffile, "w");
    if (NULL == f)
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", deffile);
      GNUNET_free (deffile);
      GNUNET_DISK_directory_remove (tmp);
      GNUNET_free (tmp);
      return MHD_NO;
    }
    for (i=0; NULL != map[i].formname; i++)
    {
      const char *val =  MHD_lookup_connection_value (connection,
                                                      MHD_GET_ARGUMENT_KIND,
                                                      map[i].formname);
      if (NULL != val)
        FPRINTF (f,
                 "\\def\\%s{%s}\n",
                 map[i].texname, val);
      else
        FPRINTF (f,
                 "\\def\\%s{}\n",
                 map[i].texname);
    }
    if (NULL != gpg_fp)
    {
      char *gpg1;
      char *gpg2;

      slen = strlen (gpg_fp);
      gpg1 = GNUNET_strndup (gpg_fp, slen / 2);
      gpg2 = GNUNET_strdup (&gpg_fp[slen / 2]);
      FPRINTF (f,
               "\\def\\gpglineone{%s}\n\\def\\gpglinetwo{%s}\n",
               gpg1, gpg2);
      GNUNET_free (gpg2);
      GNUNET_free (gpg1);
    }
    FPRINTF (f,
             "\\def\\gns{%s/%s}\n",
             gnskey,
             (NULL == gns_nick) ? "" : gns_nick);
    FCLOSE (f);
    GNUNET_asprintf (&p,
                     "cd %s; cp %s gns-bcd.tex | pdflatex --enable-write18 gns-bcd.tex > /dev/null 2> /dev/null",
                     tmp,
                     resfile);
    GNUNET_free (deffile);
    ret = system (p);
    if (WIFSIGNALED (ret) || (0 != WEXITSTATUS(ret)))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                                "system",
                                p);
    GNUNET_asprintf (&deffile,
                     "%s%s%s",
                     tmp, DIR_SEPARATOR_STR, "gns-bcd.pdf");
    fd = OPEN (deffile, O_RDONLY);
    if (-1 == fd)
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                                "open",
                                deffile);
      GNUNET_free (deffile);
      GNUNET_free (p);
      GNUNET_DISK_directory_remove (tmp);
      GNUNET_free (tmp);
      return MHD_NO;
    }
    GNUNET_break (0 == STAT (deffile, &st));
    if (NULL == (response = MHD_create_response_from_fd ((size_t) st.st_size, fd)))
    {
      GNUNET_break (0);
      GNUNET_break (0 == CLOSE (fd));
      GNUNET_free (deffile);
      GNUNET_free (p);
      GNUNET_DISK_directory_remove (tmp);
      GNUNET_free (tmp);
      return MHD_NO;
    }
    (void) MHD_add_response_header (response,
                                    MHD_HTTP_HEADER_CONTENT_TYPE,
                                    "application/pdf");
    ret = MHD_queue_response (connection,
                              MHD_HTTP_OK,
                              response);
    MHD_destroy_response (response);
    GNUNET_free (deffile);
    GNUNET_free (p);
    GNUNET_DISK_directory_remove (tmp);
    GNUNET_free (tmp);
    return ret;
  }
  return MHD_queue_response (connection,
                             MHD_HTTP_NOT_FOUND,
                             not_found_response);
}
示例#22
0
int web_main(void * _ed, struct MHD_Connection * con, const char * url,
		      const char * method, const char * version,
		      const char *upload_data, size_t * upload_data_size,
		     void ** con_cls){
  UNUSED(url); UNUSED(version); UNUSED(upload_data); UNUSED(upload_data_size);
  UNUSED(method); UNUSED(con_cls); UNUSED(_ed);
  const char * file = "page.html";

  bool style_loc = strcmp((char *) url + 1, "style.css") == 0;
  if(style_loc)
    file = "style.css";
  else if(0 == strcmp((char *) url + 1, (char *) "favicon.png"))
    file = "favicon.png";
  
  char fnamebuffer[100];
  logd("'%s' %s %s %i\n", url, method, version, upload_data_size);
  logd("File: %s\n", file);
  if(url == strstr(url, "/sharesinfo")){
    // Send back json code describing all the available shares.

    file = "shareinfo_data";
    
    dirscan dir = scan_directories("shareinfo");
    
    FILE * outfile = fopen(file, "w");
    fprintf(outfile, "[");
    for(size_t i = 0; i < dir.cnt; i++){
      logd("looking in: %s\n", dir.files[i]);
      char fnamebuffer2[100];
      sprintf(fnamebuffer2, "shareinfo/%s", dir.files[i]);
      void * rdbuffer = read_file_to_string(fnamebuffer2);
      ASSERT(rdbuffer != NULL);
      void *ptr = rdbuffer;
      char * dirname = udpc_unpack_string(&ptr);
      char * name = udpc_unpack_string(&ptr);
      char * user = udpc_unpack_string(&ptr);
      fprintf(outfile, "{\"path\": \"%s\", \"name\":\"%s\", \"user\":\"%s\"}%s\n",dirname, name, user, (i == dir.cnt -1) ? "" : ",");
      dealloc(rdbuffer);
    }
    fprintf(outfile, "]");
    fclose(outfile);
    dirscan_clean(&dir);
  }else if(url == strstr(url,"/shares/")){
    // fetch the active shares item inside the shares folder
    
    char * shareid = (char *) url + strlen("/shares/");
    logd("Shareid: %s\n", shareid);
    char * shareinfo_filename = fmtstr("shareinfo/%s", shareid);
    void * buffer = read_file_to_string(shareinfo_filename);
    if(buffer == NULL)
      goto error;
    void * bufptr = buffer;
    char * dir = udpc_unpack_string(&bufptr);
    char * name = udpc_unpack_string(&bufptr);
    char * user = udpc_unpack_string(&bufptr);
    service_descriptor sd;
    if(!udpc_get_service_descriptor(user, &sd)){
      logd("Unable to parse service name: '%s'\n", user);
      dealloc(buffer);
      goto error;
    }

    logd("path: %s, name: %s, user: %s\n", dir, name, user);
    update_dirfile(dir, name, user);
    sprintf(fnamebuffer, "shares/%s.json", name);
    dealloc(buffer);
    logd("Sending: %s\n", fnamebuffer);
    file = fnamebuffer;
  }
  if(strcmp(url, "/add_share") == 0){ 
    const char * path = MHD_lookup_connection_value(con, MHD_GET_ARGUMENT_KIND, "path");
    const char * name = MHD_lookup_connection_value(con, MHD_GET_ARGUMENT_KIND, "name");
    const char * user = MHD_lookup_connection_value(con, MHD_GET_ARGUMENT_KIND, "user");
    logd("path: %s, name: %s, user: %s\n", path, name, user);
    if(path == NULL || name == NULL || user == NULL){
      goto error;
    }
    service_descriptor sd;
    if(!udpc_get_service_descriptor(user, &sd)){
      logd("Unable to parse service name: '%s'\n", user);
      goto error;
    }
    logd("Service descriptor seems ok \n");
    ensure_directory("shareinfo/");
    char * sharepath = fmtstr("shareinfo/%s", name);
    struct stat filest;
    stat(sharepath, &filest);
    dealloc(sharepath);
    
    if(S_ISREG(filest.st_mode)){
      logd("File exists!\n");
    }else{
      struct stat dirst;
      stat(path, &dirst);
      if(!S_ISDIR(dirst.st_mode)){
	logd("Dir does not exist.. creating a new one..\n");
	int path_len = strlen(path);
	if(path[path_len] !='/'){
	  char * npath = fmtstr("%s/", path);
	  ensure_directory(npath);
	  dealloc(npath);
	}else{
	  ensure_directory(path);
	}
      }
      logd("Updating dirfile!\n");
      update_dirfile(path, name, user);
      logd("Done..\n");
    }
    const char * r = "\"OK\"";
    struct MHD_Response * response = MHD_create_response_from_data(strlen(r),
								   (void *) r,
								   0,
								   MHD_NO);
    int ret = MHD_queue_response(con, MHD_HTTP_OK, response);
    MHD_destroy_response(response);
    return ret;
  }

  size_t filesize = 0;
  void * pg = read_file_to_buffer(file, &filesize);
  struct MHD_Response * response = MHD_create_response_from_data(filesize,
					   pg,
					   1,
					   MHD_NO);
  int ret = MHD_queue_response(con, MHD_HTTP_OK, response);
  MHD_destroy_response(response);
  return ret;

 error:;
  const char * error_str = "<html><body>400</body></html>";
  response = MHD_create_response_from_data(strlen(error_str) + 1,
					   (void *) error_str,
					   0,
					   MHD_NO);
  ret = MHD_queue_response(con, MHD_HTTP_BAD_REQUEST, response);
  MHD_destroy_response(response);
  return ret;
}
示例#23
0
int request_handler (void * dbv,
		     struct MHD_Connection *connection,
		     const char *url,
		     const char *method,
		     const char *version,
		     const char *upload_data, size_t *upload_data_size,
		     void **con_cls) {
  static int con_cls0;
  struct MHD_Response* response;
  int ret;
  char* result;
  sqlite3* db = (sqlite3*) dbv;

#ifdef DEBUG
  fprintf (stderr, "%s %s %s\n", method, url, version);
#endif
  
  // Unexpected method
  if (0 != strcmp(method, "GET")){
    if(0 == strcmp(method, "OPTIONS"))
        return options200(connection);
    else
        return http400(connection);
  }
  
  // Do never respond on first call
  if (&con_cls0 != *con_cls) {
    *con_cls = &con_cls0;
    return MHD_YES;
  }
  *con_cls = NULL; // reset when done
  
  if (strcmp(url, "/last") == 0) {
    const char* count_s = MHD_lookup_connection_value(connection,
						      MHD_GET_ARGUMENT_KIND,
						      "count");
    if (count_s == NULL)
      return http400(connection);
    int count = atoi(count_s);
    if (count <= 0)
      return http400(connection);
    ret = base_load_last(db, (unsigned int)count, &result);
    if (ret != 0)
      return http400(connection);
  } else if (strcmp(url, "/between") == 0) {
    const char* from_s = MHD_lookup_connection_value(connection,
					       MHD_GET_ARGUMENT_KIND,
					       "from");
    const char* to_s = MHD_lookup_connection_value(connection,
					     MHD_GET_ARGUMENT_KIND,
					     "to");
    if ((from_s == NULL) || (to_s == NULL))
      return http400(connection);
    ret = base_load_between(db, from_s, to_s, &result);
    if (ret != 0)
      return http400(connection);
  } else
    return http400(connection);

  response = MHD_create_response_from_buffer (strlen (result),
					      (void *) result,
					      MHD_RESPMEM_MUST_COPY);
  MHD_add_response_header (response, CORS_HEADER, CORS_ORIGIN);
  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
  MHD_destroy_response (response);
  return ret;
}
示例#24
0
/**
 * Create a PostProcessor.
 *
 * A PostProcessor can be used to (incrementally)
 * parse the data portion of a POST request.
 *
 * @param connection the connection on which the POST is
 *        happening (used to determine the POST format)
 * @param buffer_size maximum number of bytes to use for
 *        internal buffering (used only for the parsing,
 *        specifically the parsing of the keys).  A
 *        tiny value (256-1024) should be sufficient.
 *        Do NOT use 0.
 * @param ikvi iterator to be called with the parsed data
 * @param cls first argument to ikvi
 * @return NULL on error (out of memory, unsupported encoding),
 *         otherwise a PP handle
 */
struct MHD_PostProcessor *
MHD_create_post_processor (struct MHD_Connection *connection,
                           size_t buffer_size,
                           MHD_PostDataIterator ikvi, void *cls)
{
  struct MHD_PostProcessor *ret;
  const char *encoding;
  const char *boundary;
  size_t blen;

  if ((buffer_size < 256) || (connection == NULL) || (ikvi == NULL))
    mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
  encoding = MHD_lookup_connection_value (connection,
                                          MHD_HEADER_KIND,
                                          MHD_HTTP_HEADER_CONTENT_TYPE);
  if (encoding == NULL)
    return NULL;
  boundary = NULL;
  if (0 != strncasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, encoding,
                        strlen (MHD_HTTP_POST_ENCODING_FORM_URLENCODED)))
    {
      if (0 !=
          strncasecmp (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, encoding,
                       strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)))
        return NULL;
      boundary =
        &encoding[strlen (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA)];
      /* Q: should this be "strcasestr"? */
      boundary = strstr (boundary, "boundary=");
      if (NULL == boundary)
	return NULL; /* failed to determine boundary */
      boundary += strlen ("boundary=");
      blen = strlen (boundary);
      if ((blen == 0) || (blen * 2 + 2 > buffer_size))
        return NULL;            /* (will be) out of memory or invalid boundary */
      if ( (boundary[0] == '"') && (boundary[blen - 1] == '"') )
	{
	  /* remove enclosing quotes */
	  ++boundary;
	  blen -= 2;
	} 
    }
  else
    blen = 0;
  buffer_size += 4; /* round up to get nice block sizes despite boundary search */

  /* add +1 to ensure we ALWAYS have a zero-termination at the end */
  if (NULL == (ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1)))
    return NULL;
  memset (ret, 0, sizeof (struct MHD_PostProcessor) + buffer_size + 1);
  ret->connection = connection;
  ret->ikvi = ikvi;
  ret->cls = cls;
  ret->encoding = encoding;
  ret->buffer_size = buffer_size;
  ret->state = PP_Init;
  ret->blen = blen;
  ret->boundary = boundary;
  ret->skip_rn = RN_Inactive;
  return ret;
}
示例#25
0
int RudeTweaker::HttpHandler(void * cls,
							 struct MHD_Connection * connection,
							 const char * url,
							 const char * method,
							 const char * version,
							 const char * upload_data,
							 unsigned int * upload_data_size,
							 void ** ptr)
{
	static int dummy;
	struct MHD_Response * response;
	int ret;
	
	if (&dummy != *ptr) 
    {
		/* The first time only the headers are valid,
         do not respond in the first round... */
		*ptr = &dummy;
		return MHD_YES;
    }
	*ptr = NULL; /* clear context pointer */
	
	if(url)
		printf("URL: %s\n", url);
	if(upload_data)
		printf("Data: %s\n", upload_data);
	
	strcpy(text, "<html><head><title>Rude Tweaker</title></head>\r\n");
	strcat(text, "\n");
	strcat(text, "\n");
	
	for(tTweakerList::iterator i = m_tweaks.begin(); i != m_tweaks.end(); ++i)
	{
		RudeTweak *it = *i;
		
		const int kItemLen = 512;
		char item[kItemLen];
		char value[kItemLen];
		
		const char *invalue = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, it->m_name);
		if(invalue)
			printf("Value: %s\n", invalue);
		
		switch(it->m_type)
		{
			case kBool:
				if(invalue)
				{
					int parsedvalue = 0;
					int results = sscanf(invalue, "%d", &parsedvalue);
					if(results == 1)
						*((bool *) it->m_data) = parsedvalue;
				}
				
				snprintf(value, kItemLen, "%d", *((bool *) it->m_data));
				break;
			case kFloat:
				if(invalue)
					sscanf(invalue, "%f", ((float *) it->m_data));
				
				snprintf(value, kItemLen, "%f", *((float *) it->m_data));
				break;
		}
		
		snprintf(item, kItemLen, "<form method=\"get\">%s: <input type=\"text\" name=\"%s\" value=\"%s\"></form><br>\n", it->m_name, it->m_name, value);
		
		
		
		strcat(text, item);
	}
	
	strcat(text, "<br><a href=\"/\">Refresh</a>\n");
	
	int textlen = strlen(text);
	RUDE_ASSERT(textlen < sizeof(text), "Tweaker exceeded text buffer bounds (%d / %d)", textlen, sizeof(text));
	
	//printf(text);
	
	response = MHD_create_response_from_data(strlen(text),
											 text,
											 MHD_NO,
											 MHD_NO);
	ret = MHD_queue_response(connection,
							 MHD_HTTP_OK,
							 response);
	MHD_destroy_response(response);
	return ret;
}