Example #1
0
int
send_response(struct http_response *resp)
{
	struct MHD_Response *response;
	struct http_header *hdr;
	char *origin;
	int ret;

	response = MHD_create_response_from_data(resp->ndata,
	    (void *)resp->data, MHD_NO, MHD_YES);
	assert(response);
	for (hdr = resp->headers; hdr; hdr = hdr->next)
		MHD_add_response_header(response, hdr->key, hdr->value);
	MHD_add_response_header(response, "Access-Control-Allow-Headers",
	    "Authorization, Origin");
	MHD_add_response_header(response, "Access-Control-Allow-Methods",
	    "GET, POST, PUT, DELETE, OPTIONS");
	origin = http_get_header(resp->connection, "Origin");
	MHD_add_response_header(response, "Access-Control-Allow-Origin",
	    origin ? origin : "*");
	free(origin);
	ret = MHD_queue_response(resp->connection, resp->status, response);
	MHD_destroy_response(response);
	return (ret);
}
Example #2
0
static int
check_auth(struct MHD_Connection *connection, struct agent_core_t *core,
    struct connection_info_struct *con_info)
{
	char passwd[1024];
	char *auth;

	assert(con_info);
	if (con_info->authed == 0) {
		auth = http_get_header(connection, "Authorization");
		/*
		 * XXX: Should be stored somewhere...
		 */
		base64_encode(BASE64, core->config->userpass,
		    strlen(core->config->userpass), passwd,
		    sizeof(passwd));
		if (!auth || strncmp(auth, "Basic ", strlen("Basic ")) ||
		    strcmp(auth + strlen("Basic "), passwd)) {
			send_auth_response(connection);
			free(auth);
			return (1);
		}
		free(auth);
		con_info->authed = 1;
	}
	return (0);
}
Example #3
0
void * conn_handler(void * arr)
{
    int client_fd = *((int*)arr);
    int keep_alive = 1;
    while (keep_alive)
    {


	http_t req;
	if (http_read(&req,client_fd) == -1)
	{
	    http_free(&req);
	    break;
	}
	const char * rh = http_get_status(&req);
	char * uri = process_http_header_request(rh);
	const char * conn_type = http_get_header(&req, "Connection");
	if (conn_type)
	{
	    if (strcasecmp("keep-alive",conn_type))
		keep_alive = 0;
	    //free(conn_type);
	}
	else
	{
	    keep_alive = 0;
	}
	char * output = NULL;
	if (uri)
	{
	    size_t size;
	    const char * body = http_get_body(&req,&size);
            jsonreq_t request;
            request.key = NULL;
            request.value = NULL;
            parsereq(body,&request);

            jsonres_t response = process_request(uri,request);

	    
            generateres(&output,&response,uri);
            if (request.key) free(request.key);
            if (request.value) free(request.value);
            //if (request) free(request);
	    free(uri);
	}
	char * ret_str = "";
        asprintf(&ret_str,"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: %zu\r\n\r\n",strlen(output));
	send(client_fd,ret_str,strlen(ret_str),0);
	send(client_fd,output,strlen(output),0);
	if (output) free(output);
        if (ret_str) free(ret_str);
	http_free(&req);
    }
    free(arr);
    close(client_fd);
    return NULL;
}
Example #4
0
//cgi that adds CORS ( Cross Origin Resource Sharing ) to our server
int ICACHE_FLASH_ATTR cgi_cors(http_connection *connData) {
	
	http_server_config *config = (http_server_config*)connData->cgi.argument;;
	if(config==NULL)
		return HTTPD_CGI_NEXT_RULE;

	if(!config->enable_cors)
		return HTTPD_CGI_NEXT_RULE;


	if(connData->state==HTTPD_STATE_ON_URL){

		//save cors headers 
		http_set_save_header(connData,HTTP_ACCESS_CONTROL_REQUEST_HEADERS);
		http_set_save_header(connData,HTTP_ACCESS_CONTROL_REQUEST_METHOD);
		
		return HTTPD_CGI_NEXT_RULE;
	}
	
	if(connData->state==HTTPD_STATE_HEADERS_END){

		//SET CORS Allow Origin for every request
		http_SET_HEADER(connData,HTTP_ACCESS_CONTROL_ALLOW_ORIGIN,"*");

		header * allow_headers = http_get_header(connData,HTTP_ACCESS_CONTROL_REQUEST_HEADERS);
		header * allow_methods = http_get_header(connData,HTTP_ACCESS_CONTROL_REQUEST_METHOD);
		
		if(allow_headers!=NULL)
			http_SET_HEADER(connData,HTTP_ACCESS_CONTROL_ALLOW_HEADERS,allow_headers->value);
		if(allow_methods!=NULL)
			http_SET_HEADER(connData,HTTP_ACCESS_CONTROL_ALLOW_METHODS,allow_methods->value);

		// Browsers will send an OPTIONS pre-flight request when posting data on a cross-domain situation
		// If that's the case here, we can safely return 200 OK with our CORS headers set
		if(connData->parser.method==HTTP_OPTIONS)
		{
			http_response_OK(connData);
			return HTTPD_CGI_DONE;
		}
	}

	return HTTPD_CGI_NEXT_RULE;
}
Example #5
0
int http_get_contlen(h_head_info *info)
{
    char * buff;

	buff = http_get_header(info,"Content-Length");
	if(buff == NULL)
		return -1;
	
	return atoi(buff);
}
Example #6
0
File: http.c Project: Dridi/vagent2
static int check_auth(struct MHD_Connection *connection, struct agent_core_t *core, struct connection_info_struct *con_info)
{
	_cleanup_free_ char *auth = NULL;
	char base64pw[1024];
	assert(con_info);
	if (con_info->authed == 0) {
		auth = http_get_header(connection, "Authorization");
		/*
		 * XXX: Should be stored somewhere...
		 */
		base64_encode(BASE64, core->config->userpass, strlen(core->config->userpass), base64pw, sizeof(base64pw));
		if (!auth || strncmp(auth,"Basic ", strlen("Basic ")) || strcmp(auth + strlen("Basic "), base64pw)) {
			send_auth_response(connection);
			return 1;
		}
		con_info->authed = 1;
	}
	return 0;
}
int ICACHE_FLASH_ATTR http_ws_handle_connect(http_connection *c) {	

	NODE_DBG("http_ws_handle_connect c =%p",c);

	if(c->state == HTTPD_STATE_ON_URL){
		http_set_save_header(c,HTTP_ORIGIN);	
		http_set_save_header(c,HTTP_CONNECTION);	
		http_set_save_header(c,HTTP_UPGRADE);		
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_KEY);
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_PROTOCOL);
		http_set_save_header(c,HTTP_SEC_WEBSOCKET_VERSION);

		return HTTP_WS_CGI_MORE;
	}

	//wait handshake request complete
	if(c->state != HTTPD_STATE_BODY_END)
		return HTTP_WS_CGI_MORE;


	header * upgrade_header = http_get_header(c,HTTP_UPGRADE);
	header * connection_header = http_get_header(c,HTTP_CONNECTION);
	header * origin_header = http_get_header(c,HTTP_ORIGIN);
	header * key_header = http_get_header(c,HTTP_SEC_WEBSOCKET_KEY);

	if(upgrade_header==NULL) goto badrequest;
	if(connection_header==NULL) goto badrequest;
	if(origin_header==NULL) goto badrequest;
	if(key_header==NULL) goto badrequest;

	NODE_DBG("headers ok");

	if(os_strcasecmp(upgrade_header->value,"websocket")!=0) goto badrequest;

	// Following (https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17)
	//calculate sha1 of concatenetion key+uuid
	uint8_t digest[20]; //sha1 is always 20 byte long
	SHA1_CTX ctx;
	SHA1_Init(&ctx);
	SHA1_Update(&ctx,key_header->value,os_strlen(key_header->value));
	SHA1_Update(&ctx,ws_uuid,os_strlen(ws_uuid));
	SHA1_Final(digest,&ctx);
		
	char base64Digest[31]; // 
	Base64encode(base64Digest,(const char*)digest,20);

	//accept the handshake
	http_SET_HEADER(c,HTTP_UPGRADE,"WebSocket");
	http_SET_HEADER(c,HTTP_CONNECTION,"Upgrade");
	
	http_SET_HEADER(c,HTTP_WEBSOCKET_ACCEPT,base64Digest);

	http_websocket_HANDSHAKE(c);
	c->handshake_ok=1;

	if(client_connected_callback!=NULL)
		client_connected_callback(c);

	return HTTP_WS_CGI_MORE;

badrequest:
	http_response_BAD_REQUEST(c);
	return HTTP_WS_CGI_DONE;

}
Example #8
0
/* Get the key from URL which is expected to specify a http style
   scheme.  On success R_FP has an open stream to read the data.  */
gpg_error_t
ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
{
  gpg_error_t err;
  http_session_t session = NULL;
  http_t http = NULL;
  int redirects_left = MAX_REDIRECTS;
  estream_t fp = NULL;
  char *request_buffer = NULL;

  err = http_session_new (&session, NULL);
  if (err)
    goto leave;
  http_session_set_log_cb (session, cert_log_cb);

  *r_fp = NULL;
 once_more:
  err = http_open (&http,
                   HTTP_REQ_GET,
                   url,
                   /* httphost */ NULL,
                   /* fixme: AUTH */ NULL,
                   0,
                   /* fixme: proxy*/ NULL,
                   session,
                   NULL,
                   /*FIXME curl->srvtag*/NULL);
  if (!err)
    {
      fp = http_get_write_ptr (http);
      /* Avoid caches to get the most recent copy of the key.  We set
         both the Pragma and Cache-Control versions of the header, so
         we're good with both HTTP 1.0 and 1.1.  */
      es_fputs ("Pragma: no-cache\r\n"
                "Cache-Control: no-cache\r\n", fp);
      http_start_data (http);
      if (es_ferror (fp))
        err = gpg_error_from_syserror ();
    }
  if (err)
    {
      /* Fixme: After a redirection we show the old host name.  */
      log_error (_("error connecting to '%s': %s\n"),
                 url, gpg_strerror (err));
      goto leave;
    }

  /* Wait for the response.  */
  dirmngr_tick (ctrl);
  err = http_wait_response (http);
  if (err)
    {
      log_error (_("error reading HTTP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      goto leave;
    }

  switch (http_get_status_code (http))
    {
    case 200:
      err = 0;
      break; /* Success.  */

    case 301:
    case 302:
    case 307:
      {
        const char *s = http_get_header (http, "Location");

        log_info (_("URL '%s' redirected to '%s' (%u)\n"),
                  url, s?s:"[none]", http_get_status_code (http));
        if (s && *s && redirects_left-- )
          {
            xfree (request_buffer);
            request_buffer = xtrystrdup (s);
            if (request_buffer)
              {
                url = request_buffer;
                http_close (http, 0);
                http = NULL;
                goto once_more;
              }
            err = gpg_error_from_syserror ();
          }
        else
          err = gpg_error (GPG_ERR_NO_DATA);
        log_error (_("too many redirections\n"));
      }
      goto leave;

    default:
      log_error (_("error accessing '%s': http status %u\n"),
                 url, http_get_status_code (http));
      err = gpg_error (GPG_ERR_NO_DATA);
      goto leave;
    }

  fp = http_get_read_ptr (http);
  if (!fp)
    {
      err = gpg_error (GPG_ERR_BUG);
      goto leave;
    }

  /* Return the read stream and close the HTTP context.  */
  *r_fp = fp;
  http_close (http, 1);
  http = NULL;

 leave:
  http_close (http, 0);
  http_session_release (session);
  xfree (request_buffer);
  return err;
}
Example #9
0
//Cgi that check the request has the correct HOST header
//Using it we can ensure our server has a domain of our choice
int ICACHE_FLASH_ATTR cgi_check_host(http_connection *connData) {
	
	http_server_config *config = (http_server_config*)connData->cgi.argument;
	if(config==NULL)
		return HTTPD_CGI_NEXT_RULE;

	if(config->host_domain==NULL)
		return HTTPD_CGI_NEXT_RULE;

	
	if(connData->state==HTTPD_STATE_ON_URL){

		http_set_save_header(connData,HTTP_HOST);
		return HTTPD_CGI_NEXT_RULE;
	}

	if(connData->state==HTTPD_STATE_HEADERS_END){

		header *hostHeader = http_get_header(connData,HTTP_HOST);
		if(hostHeader==NULL){
			NODE_DBG("Host header not found");
			http_response_BAD_REQUEST(connData);
			return HTTPD_CGI_DONE;
		}

		const char * domain = config->host_domain;

		NODE_DBG("Host header found: %s, domain: %s",hostHeader->value,domain);


		if(os_strncmp(hostHeader->value,domain,strlen(domain))==0) //compare ignoring http:// and last /
		{
			NODE_DBG("Hosts match");
			return HTTPD_CGI_NEXT_RULE;
		}
		else{
			NODE_DBG("Hosts don't match");
			
			if(config->enable_captive){
				//to enable a captive portal we should redirect here

				char * redirectUrl = (char *)os_zalloc(strlen(domain)+9); // domain lenght + http:// + / + \0
				os_strcpy(redirectUrl,"http://");
				os_strcat(redirectUrl,domain);
				os_strcat(redirectUrl,"/");

				http_response_REDIRECT(connData, redirectUrl);

				os_free(redirectUrl);

			}
			else{
				//bad request
				http_response_BAD_REQUEST(connData);

			}
			
			

			return HTTPD_CGI_DONE;
		}
		

	}

	
	return HTTPD_CGI_NEXT_RULE;

}
Example #10
0
int
main (int argc, char **argv)
{
  int last_argc = -1;
  gpg_error_t err;
  int rc;  parsed_uri_t uri;
  uri_tuple_t r;
  http_t hd;
  int c;
  unsigned int my_http_flags = 0;
  int no_out = 0;
  int tls_dbg = 0;
  int no_crl = 0;
  const char *cafile = NULL;
  http_session_t session = NULL;
  unsigned int timeout = 0;

  gpgrt_init ();
  log_set_prefix (PGM, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_PID);
  if (argc)
    { argc--; argv++; }
  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--help"))
        {
          fputs ("usage: " PGM " URL\n"
                 "Options:\n"
                 "  --verbose         print timings etc.\n"
                 "  --debug           flyswatter\n"
                 "  --tls-debug N     use TLS debug level N\n"
                 "  --cacert FNAME    expect CA certificate in file FNAME\n"
                 "  --timeout MS      timeout for connect in MS\n"
                 "  --no-verify       do not verify the certificate\n"
                 "  --force-tls       use HTTP_FLAG_FORCE_TLS\n"
                 "  --force-tor       use HTTP_FLAG_FORCE_TOR\n"
                 "  --no-out          do not print the content\n"
                 "  --no-crl          do not consuilt a CRL\n",
                 stdout);
          exit (0);
        }
      else if (!strcmp (*argv, "--verbose"))
        {
          verbose++;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--debug"))
        {
          verbose += 2;
          debug++;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--tls-debug"))
        {
          argc--; argv++;
          if (argc)
            {
              tls_dbg = atoi (*argv);
              argc--; argv++;
            }
        }
      else if (!strcmp (*argv, "--cacert"))
        {
          argc--; argv++;
          if (argc)
            {
              cafile = *argv;
              argc--; argv++;
            }
        }
      else if (!strcmp (*argv, "--timeout"))
        {
          argc--; argv++;
          if (argc)
            {
              timeout = strtoul (*argv, NULL, 10);
              argc--; argv++;
            }
        }
      else if (!strcmp (*argv, "--no-verify"))
        {
          no_verify = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--force-tls"))
        {
          my_http_flags |= HTTP_FLAG_FORCE_TLS;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--force-tor"))
        {
          my_http_flags |= HTTP_FLAG_FORCE_TOR;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--no-out"))
        {
          no_out = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--no-crl"))
        {
          no_crl = 1;
          argc--; argv++;
        }
      else if (!strncmp (*argv, "--", 2))
        {
          fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
          exit (1);
        }
    }
  if (argc != 1)
    {
      fprintf (stderr, PGM ": no or too many URLS given\n");
      exit (1);
    }

  if (!cafile)
    cafile = prepend_srcdir ("tls-ca.pem");

  if (verbose)
    my_http_flags |= HTTP_FLAG_LOG_RESP;

  if (verbose || debug)
    http_set_verbose (verbose, debug);

  /* http.c makes use of the assuan socket wrapper.  */
  assuan_sock_init ();

  if ((my_http_flags & HTTP_FLAG_FORCE_TOR))
    {
      enable_dns_tormode (1);
      if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
        {
          log_error ("error enabling Tor mode: %s\n", strerror (errno));
          log_info ("(is your Libassuan recent enough?)\n");
        }
    }

#if HTTP_USE_NTBTLS
  log_info ("new session.\n");
  err = http_session_new (&session, NULL,
                          ((no_crl? HTTP_FLAG_NO_CRL : 0)
                           | HTTP_FLAG_TRUST_DEF),
                          my_http_tls_verify_cb, NULL);
  if (err)
    log_error ("http_session_new failed: %s\n", gpg_strerror (err));
  ntbtls_set_debug (tls_dbg, NULL, NULL);

#elif HTTP_USE_GNUTLS

  rc = gnutls_global_init ();
  if (rc)
    log_error ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));

  http_register_tls_callback (verify_callback);
  http_register_tls_ca (cafile);

  err = http_session_new (&session, NULL,
                          ((no_crl? HTTP_FLAG_NO_CRL : 0)
                           | HTTP_FLAG_TRUST_DEF),
                          NULL, NULL);
  if (err)
    log_error ("http_session_new failed: %s\n", gpg_strerror (err));

  /* rc = gnutls_dh_params_init(&dh_params); */
  /* if (rc) */
  /*   log_error ("gnutls_dh_params_init failed: %s\n", gnutls_strerror (rc)); */
  /* read_dh_params ("dh_param.pem"); */

  /* rc = gnutls_certificate_set_x509_trust_file */
  /*   (certcred, "ca.pem", GNUTLS_X509_FMT_PEM); */
  /* if (rc) */
  /*   log_error ("gnutls_certificate_set_x509_trust_file failed: %s\n", */
  /*              gnutls_strerror (rc)); */

  /* gnutls_certificate_set_dh_params (certcred, dh_params); */

  gnutls_global_set_log_function (my_gnutls_log);
  if (tls_dbg)
    gnutls_global_set_log_level (tls_dbg);

#else
  (void)err;
  (void)tls_dbg;
  (void)no_crl;
#endif /*HTTP_USE_GNUTLS*/

  rc = http_parse_uri (&uri, *argv, 1);
  if (rc)
    {
      log_error ("'%s': %s\n", *argv, gpg_strerror (rc));
      return 1;
    }

  printf ("Scheme: %s\n", uri->scheme);
  if (uri->opaque)
    printf ("Value : %s\n", uri->path);
  else
    {
      printf ("Auth  : %s\n", uri->auth? uri->auth:"[none]");
      printf ("Host  : %s\n", uri->host);
      printf ("Port  : %u\n", uri->port);
      printf ("Path  : %s\n", uri->path);
      for (r = uri->params; r; r = r->next)
        {
          printf ("Params: %s", r->name);
          if (!r->no_value)
            {
              printf ("=%s", r->value);
              if (strlen (r->value) != r->valuelen)
                printf (" [real length=%d]", (int) r->valuelen);
            }
          putchar ('\n');
        }
      for (r = uri->query; r; r = r->next)
        {
          printf ("Query : %s", r->name);
          if (!r->no_value)
            {
              printf ("=%s", r->value);
              if (strlen (r->value) != r->valuelen)
                printf (" [real length=%d]", (int) r->valuelen);
            }
          putchar ('\n');
        }
      printf ("Flags :%s%s%s%s\n",
              uri->is_http? " http":"",
              uri->opaque?  " opaque":"",
              uri->v6lit?   " v6lit":"",
              uri->onion?   " onion":"");
      printf ("TLS   : %s\n",
              uri->use_tls? "yes":
              (my_http_flags&HTTP_FLAG_FORCE_TLS)? "forced" : "no");
      printf ("Tor   : %s\n",
              (my_http_flags&HTTP_FLAG_FORCE_TOR)? "yes" : "no");

    }
  fflush (stdout);
  http_release_parsed_uri (uri);
  uri = NULL;

  if (session)
    http_session_set_timeout (session, timeout);

  rc = http_open_document (NULL, &hd, *argv, NULL, my_http_flags,
                           NULL, session, NULL, NULL);
  if (rc)
    {
      log_error ("can't get '%s': %s\n", *argv, gpg_strerror (rc));
      return 1;
    }
  log_info ("open_http_document succeeded; status=%u\n",
            http_get_status_code (hd));

  {
    const char **names;
    int i;

    names = http_get_header_names (hd);
    if (!names)
      log_fatal ("http_get_header_names failed: %s\n",
                 gpg_strerror (gpg_error_from_syserror ()));
    for (i = 0; names[i]; i++)
      printf ("HDR: %s: %s\n", names[i], http_get_header (hd, names[i]));
    xfree (names);
  }
  fflush (stdout);

  switch (http_get_status_code (hd))
    {
    case 200:
    case 400:
    case 401:
    case 403:
    case 404:
      {
        unsigned long count = 0;
        while ((c = es_getc (http_get_read_ptr (hd))) != EOF)
          {
            count++;
            if (!no_out)
              putchar (c);
          }
        log_info ("Received bytes: %lu\n", count);
      }
      break;
    case 301:
    case 302:
    case 307:
      log_info ("Redirected to: %s\n", http_get_header (hd, "Location"));
      break;
    }
  http_close (hd, 0);

  http_session_release (session);
#ifdef HTTP_USE_GNUTLS
  gnutls_global_deinit ();
#endif /*HTTP_USE_GNUTLS*/

  return 0;
}
Example #11
0
/* Send an HTTP request.  On success returns an estream object at
   R_FP.  HOSTPORTSTR is only used for diagnostics.  If HTTPHOST is
   not NULL it will be used as HTTP "Host" header.  If POST_CB is not
   NULL a post request is used and that callback is called to allow
   writing the post data.  */
static gpg_error_t
send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
              const char *httphost, unsigned int httpflags,
              gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value,
              estream_t *r_fp)
{
  gpg_error_t err;
  http_session_t session = NULL;
  http_t http = NULL;
  int redirects_left = MAX_REDIRECTS;
  estream_t fp = NULL;
  char *request_buffer = NULL;

  *r_fp = NULL;

  err = http_session_new (&session, NULL);
  if (err)
    goto leave;
  http_session_set_log_cb (session, cert_log_cb);

 once_more:
  err = http_open (&http,
                   post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
                   request,
                   httphost,
                   /* fixme: AUTH */ NULL,
                   (httpflags | (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)),
                   ctrl->http_proxy,
                   session,
                   NULL,
                   /*FIXME curl->srvtag*/NULL);
  if (!err)
    {
      fp = http_get_write_ptr (http);
      /* Avoid caches to get the most recent copy of the key.  We set
         both the Pragma and Cache-Control versions of the header, so
         we're good with both HTTP 1.0 and 1.1.  */
      es_fputs ("Pragma: no-cache\r\n"
                "Cache-Control: no-cache\r\n", fp);
      if (post_cb)
        err = post_cb (post_cb_value, http);
      if (!err)
        {
          http_start_data (http);
          if (es_ferror (fp))
            err = gpg_error_from_syserror ();
        }
    }
  if (err)
    {
      /* Fixme: After a redirection we show the old host name.  */
      log_error (_("error connecting to '%s': %s\n"),
                 hostportstr, gpg_strerror (err));
      goto leave;
    }

  /* Wait for the response.  */
  dirmngr_tick (ctrl);
  err = http_wait_response (http);
  if (err)
    {
      log_error (_("error reading HTTP response for '%s': %s\n"),
                 hostportstr, gpg_strerror (err));
      goto leave;
    }

  if (http_get_tls_info (http, NULL))
    {
      /* Update the httpflags so that a redirect won't fallback to an
         unencrypted connection.  */
      httpflags |= HTTP_FLAG_FORCE_TLS;
    }

  switch (http_get_status_code (http))
    {
    case 200:
      err = 0;
      break; /* Success.  */

    case 301:
    case 302:
    case 307:
      {
        const char *s = http_get_header (http, "Location");

        log_info (_("URL '%s' redirected to '%s' (%u)\n"),
                  request, s?s:"[none]", http_get_status_code (http));
        if (s && *s && redirects_left-- )
          {
            xfree (request_buffer);
            request_buffer = xtrystrdup (s);
            if (request_buffer)
              {
                request = request_buffer;
                http_close (http, 0);
                http = NULL;
                goto once_more;
              }
            err = gpg_error_from_syserror ();
          }
        else
          err = gpg_error (GPG_ERR_NO_DATA);
        log_error (_("too many redirections\n"));
      }
      goto leave;

    default:
      log_error (_("error accessing '%s': http status %u\n"),
                 request, http_get_status_code (http));
      err = gpg_error (GPG_ERR_NO_DATA);
      goto leave;
    }

  /* FIXME: We should register a permanent redirection and whether a
     host has ever used TLS so that future calls will always use
     TLS. */

  fp = http_get_read_ptr (http);
  if (!fp)
    {
      err = gpg_error (GPG_ERR_BUG);
      goto leave;
    }

  /* Return the read stream and close the HTTP context.  */
  *r_fp = fp;
  http_close (http, 1);
  http = NULL;

 leave:
  http_close (http, 0);
  http_session_release (session);
  xfree (request_buffer);
  return err;
}
Example #12
0
static int connection_get_reply(struct connection *c, char *resp, int resp_sz)
{
	struct http_request *r;
	int used = 0;

	/* 
	 * Currently, this doesn't do anything interesting.  In the
	 * future it will call the content provider and get the
	 * (ready) response.
	 */
	r = c->pending_reqs;
	if (NULL == r) return 0;
	while (r) {
		struct http_request *next;
		char *local_resp;
		cbuf_t cb;
		int consumed, ret, local_resp_sz;

		assert(r->c == c);
		if (r->flags & HTTP_REQ_PENDING) break;
		assert(r->flags & HTTP_REQ_PROCESSED);
		assert(r->content_id >= 0);

		/* Previously saved response? */
		if (NULL != r->resp.resp) {
			local_resp = r->resp.resp;
			local_resp_sz = r->resp.resp_len;
		} else {
			int sz;
			/* Make the request to the content
			 * component */
			sz         = resp_sz - used;
			local_resp = cbuf_alloc(sz, &cb);
			if (!local_resp) BUG();

			ret = server_tread(cos_spd_id(), r->content_id, cb, sz);
			if (ret < 0) {
				cbuf_free(local_resp);
				printc("https get reply returning %d.\n", ret);
				return ret;
			}
			local_resp_sz = ret;
		}

		/* no more data */
		if (local_resp_sz == 0) {
			cbuf_free(local_resp);
			break;
		}

		/* If the header and data couldn't fit into the
		 * provided buffer, then we need to save the response,
		 * so that we can send it out later... */
		if (http_get_header(resp+used, resp_sz-used, local_resp_sz, &consumed)) {
			if (NULL == r->resp.resp) {
				char *save;
			
				save = malloc(local_resp_sz);
				assert(save);
				assert(local_resp);
				memcpy(save, local_resp, local_resp_sz);
				cbuf_free(local_resp);
				local_resp = NULL;

				r->resp.resp = save;
				r->resp.resp_len = local_resp_sz;
			}
			if (0 == used) {
				printc("https: could not allocate either header or response of sz %d:%s\n", local_resp_sz, local_resp);
				if (local_resp) cbuf_free(local_resp);
				return -ENOMEM;
			}
			break;
		}

		memcpy(resp+used+consumed, local_resp, local_resp_sz);
		
		assert(local_resp);
		cbuf_free(local_resp);
		local_resp = NULL;

		used += local_resp_sz + consumed;
		next = r->next;
		/* bookkeeping */
		http_req_cnt++;

		http_free_request(r);
		r = c->pending_reqs;
		assert(r == next || NULL == r);
	}

	return used;
}
static int connection_get_reply(struct connection *c, char *resp, int resp_sz)
{
	struct http_request *r;
	int used = 0;

	/* 
	 * Currently, this doesn't do anything interesting.  In the
	 * future it will call the content provider and get the
	 * (ready) response.
	 */
	r = c->pending_reqs;
	if (NULL == r) return 0;
	while (r) {
		struct http_request *next;
		struct cos_array *arr = NULL;
		char *local_resp;
		int *more = NULL; 
		int local_more, consumed, ret, local_resp_sz;

		assert(r->c == c);
		if (r->flags & HTTP_REQ_PENDING) break;
		assert(r->flags & HTTP_REQ_PROCESSED);
		assert(r->content_id >= 0);

		/* Previously saved response? */
		if (NULL != r->resp.resp) {
			local_resp = r->resp.resp;
			local_resp_sz = r->resp.resp_len;
			local_more = r->resp.more;
		} else {
			/* Make the request to the content
			 * component */
			more = cos_argreg_alloc(sizeof(int));
			assert(more);
			arr = cos_argreg_alloc(sizeof(struct cos_array) + resp_sz - used);
			assert(arr);

			arr->sz = resp_sz - used;
			if ((ret = content_retrieve(cos_spd_id(), r->content_id, arr, more))) {
				cos_argreg_free(arr);
				cos_argreg_free(more);
				if (0 > ret) {
					BUG();
					/* FIXME send an error message. */
				}
				printc("https get reply returning %d.\n", ret);
				return ret;
			}
			local_more = *more;
			local_resp_sz = arr->sz;
			local_resp = arr->mem;
		}
		
		/* still more date, but not available now... */
		if (local_resp_sz == 0) {
			cos_argreg_free(arr);
			cos_argreg_free(more);
			break;
		}

		/* If the header and data couldn't fit into the
		 * provided buffer, then we need to save the response,
		 * so that we can send it out later... */
		if (http_get_header(resp+used, resp_sz-used, local_resp_sz, &consumed)) {
			if (NULL == r->resp.resp) {
				char *save;
			
				save = malloc(local_resp_sz);
				assert(save);
				assert(arr);
				memcpy(save, arr->mem, local_resp_sz);
				cos_argreg_free(arr);
				r->resp.more = *more;
				cos_argreg_free(more);

				r->resp.resp = save;
				r->resp.resp_len = local_resp_sz;
			}
			if (0 == used) {
				printc("https: could not allocate either header or response of sz %d:%s\n", local_resp_sz, local_resp);
				if (arr) cos_argreg_free(arr);
				if (more) cos_argreg_free(more);
				return -ENOMEM;
			}
			break;
		}

		memcpy(resp+used+consumed, local_resp, local_resp_sz);
		
		if (arr)  cos_argreg_free(arr);
		if (more) cos_argreg_free(more);
		more = NULL;
		arr  = NULL;

		used += local_resp_sz + consumed;

		next = r->next;

		/* bookkeeping */
		http_req_cnt++;

		http_free_request(r);
		r = c->pending_reqs;
		assert(r == next || NULL == r);
	}

	return used;
}
Example #14
0
int cgi_ng_pld(http_socket *socket)
{
  u32   content_length;
  char *file;
  int   mph_len;
  char *pnt;
  int   len;
  int   i;
  
  if (socket->content_priv == 0)
  {
    uart_puts("CGI: Start loading PLD.\r\n");
  
    pld_init();
    for (i = 0; i < 7500; i++)
      ;
    pld_load_start();
    
    pnt = 0;
    for (i = 0; i < 16; i++)
    {
      char arg[16];
      pnt = http_get_header(socket, pnt);
      if (pnt == 0)
        break;
      if (strncmp(pnt, "Content-Length:", 15) == 0)
      {
        pnt += 16;
        for (i = 0; i < 7; i++)
        {
          if ( (*pnt < '0') || (*pnt > '9') )
            break;
          arg[i] = *pnt;
          pnt++;
        }
        arg[i] = 0;
        content_length = atoi(arg);
        break;
      }
    }
    
    pnt = (char *)socket->rx;
    while(pnt != 0)
    {
      if ( (pnt[0] == 0x0d) && (pnt[1] == 0x0a) &&
           (pnt[2] == 0x0d) && (pnt[3] == 0x0a) )
      {
    	/* Get a pointer on datas (after multipart header) */
    	file = (pnt + 4);
  	break;
      }
      /* Search the next CR */
      pnt = strchr(pnt + 1, 0x0d);
    }
    /* Multipart header length */
    mph_len = ((u32)file - (u32)socket->rx);
    /* Received length */
    len = socket->rx_len - mph_len;
    
    pld_load((const u8 *)file, len);
    
    if (len < content_length)
      socket->state = HTTP_STATE_RECV_MORE;
    socket->content_priv = (void *)(content_length - mph_len - len);
  }
  else
  {
    content_length = (u32)socket->content_priv;
    
    pld_load((u8 *)socket->rx, socket->rx_len);
    
    if (socket->rx_len < content_length)
    {
      socket->content_priv = (void *)(content_length - socket->rx_len);
    }
    else
    {
      uart_puts("CGI: PLD bitstream loaded !\r\n");
      pld_load_end();
      
      socket->content_priv = 0;
      http_send_header(socket, 200, 0);
      socket->state = HTTP_STATE_SEND;
    }
  }
  return(0);
}
Example #15
0
File: ocsp.c Project: FMayzek/gnupg
/* Construct an OCSP request, send it to the configured OCSP responder
   and parse the response. On success the OCSP context may be used to
   further process the reponse. */
static gpg_error_t
do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
                 const char *url, ksba_cert_t cert, ksba_cert_t issuer_cert)
{
  gpg_error_t err;
  unsigned char *request, *response;
  size_t requestlen, responselen;
  http_t http;
  ksba_ocsp_response_status_t response_status;
  const char *t;
  int redirects_left = 2;
  char *free_this = NULL;

  (void)ctrl;

  if (opt.disable_http)
    {
      log_error (_("OCSP request not possible due to disabled HTTP\n"));
      return gpg_error (GPG_ERR_NOT_SUPPORTED);
    }

  err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
  if (err)
    {
      log_error (_("error setting OCSP target: %s\n"), gpg_strerror (err));
      return err;
    }

  {
    size_t n;
    unsigned char nonce[32];

    n = ksba_ocsp_set_nonce (ocsp, NULL, 0);
    if (n > sizeof nonce)
      n = sizeof nonce;
    gcry_create_nonce (nonce, n);
    ksba_ocsp_set_nonce (ocsp, nonce, n);
  }

  err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
  if (err)
    {
      log_error (_("error building OCSP request: %s\n"), gpg_strerror (err));
      return err;
    }

 once_more:
  err = http_open (&http, HTTP_REQ_POST, url, NULL,
                   (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0),
                   opt.http_proxy, NULL, NULL, NULL);
  if (err)
    {
      log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err));
      xfree (free_this);
      return err;
    }

  es_fprintf (http_get_write_ptr (http),
	      "Content-Type: application/ocsp-request\r\n"
	      "Content-Length: %lu\r\n",
	      (unsigned long)requestlen );
  http_start_data (http);
  if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1)
    {
      err = gpg_error_from_errno (errno);
      log_error ("error sending request to '%s': %s\n", url, strerror (errno));
      http_close (http, 0);
      xfree (request);
      xfree (free_this);
      return err;
    }
  xfree (request);
  request = NULL;

  err = http_wait_response (http);
  if (err || http_get_status_code (http) != 200)
    {
      if (err)
        log_error (_("error reading HTTP response for '%s': %s\n"),
                   url, gpg_strerror (err));
      else
        {
          switch (http_get_status_code (http))
            {
            case 301:
            case 302:
              {
                const char *s = http_get_header (http, "Location");

                log_info (_("URL '%s' redirected to '%s' (%u)\n"),
                          url, s?s:"[none]", http_get_status_code (http));
                if (s && *s && redirects_left-- )
                  {
                    xfree (free_this); url = NULL;
                    free_this = xtrystrdup (s);
                    if (!free_this)
                      err = gpg_error_from_errno (errno);
                    else
                      {
                        url = free_this;
                        http_close (http, 0);
                        goto once_more;
                      }
                  }
                else
                  err = gpg_error (GPG_ERR_NO_DATA);
                log_error (_("too many redirections\n"));
              }
              break;

            default:
              log_error (_("error accessing '%s': http status %u\n"),
                         url, http_get_status_code (http));
              err = gpg_error (GPG_ERR_NO_DATA);
              break;
            }
        }
      http_close (http, 0);
      xfree (free_this);
      return err;
    }

  err = read_response (http_get_read_ptr (http), &response, &responselen);
  http_close (http, 0);
  if (err)
    {
      log_error (_("error reading HTTP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      xfree (free_this);
      return err;
    }

  err = ksba_ocsp_parse_response (ocsp, response, responselen,
                                  &response_status);
  if (err)
    {
      log_error (_("error parsing OCSP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      xfree (response);
      xfree (free_this);
      return err;
    }

  switch (response_status)
    {
    case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
    case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;
    case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;
    case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;
    case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;
    case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
    case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;
    case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;
    case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
    default:                               t = "[unknown status]"; break;
    }
  if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
    {
      if (opt.verbose)
        log_info (_("OCSP responder at '%s' status: %s\n"), url, t);

      err = ksba_ocsp_hash_response (ocsp, response, responselen,
                                     HASH_FNC, md);
      if (err)
        log_error (_("hashing the OCSP response for '%s' failed: %s\n"),
                   url, gpg_strerror (err));
    }
  else
    {
      log_error (_("OCSP responder at '%s' status: %s\n"), url, t);
      err = gpg_error (GPG_ERR_GENERAL);
    }

  xfree (response);
  xfree (free_this);
  return err;
}
Example #16
0
//Cgi that check the request has the correct HOST header
//Using it we can ensure our server has a domain of our choice
int cgi_check_host(http_connection *connData)
{
	http_server_config *config = (http_server_config*)connData->cgi.argument;
	if(config==NULL)
		return HTTPD_CGI_NEXT_RULE;

	if(config->host_domain==NULL)
		return HTTPD_CGI_NEXT_RULE;


	if(connData->state==HTTPD_STATE_ON_URL)
	{
		http_set_save_header(connData,HTTP_HOST);
		return HTTPD_CGI_NEXT_RULE;
	}

	if(connData->state==HTTPD_STATE_HEADERS_END)
	{
		header *hostHeader = http_get_header(connData,HTTP_HOST);
		if(hostHeader==NULL)
		{
         NODE_ERR("Host header not found\n");
			http_response_BAD_REQUEST(connData);
			return HTTPD_CGI_DONE;
		}
		const char * domain = config->host_domain;

      HTTP_CGI_DBG("Host header: %s, domain: %s\n",hostHeader->value,domain);

		if(strncmp(hostHeader->value,domain,strlen(domain))==0) //compare ignoring http:// and last /
		{
         HTTP_CGI_DBG("Domain match\n");
			return HTTPD_CGI_NEXT_RULE;
		}
		else{
			uint8_t op = wifi_get_opmode();
			char ipaddrstr[17];
			os_bzero(ipaddrstr, sizeof(ipaddrstr));
			struct ip_info ipConfig;
			switch (op)
			{
				case STATIONAP_MODE:
				{
					wifi_get_ip_info(SOFTAP_IF,&ipConfig); //0x01
					ipaddr_ntoa_r(&ipConfig.ip,ipaddrstr, sizeof(ipaddrstr));

					if(strncmp(hostHeader->value,ipaddrstr,strlen(ipaddrstr))==0)
						{ HTTP_CGI_DBG("SoftAp ip match"); return HTTPD_CGI_NEXT_RULE; }
				}
				case STATION_MODE:
				{
					os_bzero(ipaddrstr, sizeof(ipaddrstr));
					wifi_get_ip_info(STATION_IF,&ipConfig); //0x00
					ipaddr_ntoa_r(&ipConfig.ip,ipaddrstr, sizeof(ipaddrstr));

					if(strncmp(hostHeader->value,ipaddrstr,strlen(ipaddrstr))==0)
						{ HTTP_CGI_DBG("Station ip match"); return HTTPD_CGI_NEXT_RULE; }
				}
			}
         HTTP_CGI_DBG("Hosts don't match\n");

			if(config->enable_captive)
			{
				//to enable a captive portal we should redirect here
				char * redirectUrl = (char *)os_zalloc(strlen(domain)+9); // domain length + http:// + / + \0
				strcpy(redirectUrl,"http://");
				os_strcat(redirectUrl,domain);
				os_strcat(redirectUrl,"/");
				http_response_REDIRECT(connData, redirectUrl);
				os_free(redirectUrl);
            HTTP_CGI_DBG("Redirect URL = %s\n", redirectUrl);

			} else {
			//bad request else
			http_response_BAD_REQUEST(connData);
			}
		return HTTPD_CGI_DONE;
		}
	}
	return HTTPD_CGI_NEXT_RULE;
}
Example #17
0
const char *
nni_http_res_get_header(nni_http_res *res, const char *key)
{
	return (http_get_header(&res->hdrs, key));
}
Example #18
0
const char *
nni_http_req_get_header(nni_http_req *req, const char *key)
{
	return (http_get_header(&req->hdrs, key));
}
Example #19
0
int
main (int argc, char **argv)
{
  int last_argc = -1;
  gpg_error_t err;
  int rc;
  parsed_uri_t uri;
  uri_tuple_t r;
  http_t hd;
  int c;
  unsigned int my_http_flags = 0;
  int no_out = 0;
  int tls_dbg = 0;
  const char *cafile = NULL;
  http_session_t session = NULL;

  gpgrt_init ();
  log_set_prefix (PGM, 1 | 4);
  if (argc)
    { argc--; argv++; }
  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--help"))
        {
          fputs ("usage: " PGM " URL\n"
                 "Options:\n"
                 "  --verbose         print timings etc.\n"
                 "  --debug           flyswatter\n"
                 "  --gnutls-debug N  use GNUTLS debug level N\n"
                 "  --cacert FNAME    expect CA certificate in file FNAME\n"
                 "  --no-verify       do not verify the certificate\n"
                 "  --force-tls       use HTTP_FLAG_FORCE_TLS\n"
                 "  --no-out          do not print the content\n",
                 stdout);
          exit (0);
        }
      else if (!strcmp (*argv, "--verbose"))
        {
          verbose++;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--debug"))
        {
          verbose += 2;
          debug++;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--gnutls-debug"))
        {
          argc--; argv++;
          if (argc)
            {
              tls_dbg = atoi (*argv);
              argc--; argv++;
            }
        }
      else if (!strcmp (*argv, "--cacert"))
        {
          argc--; argv++;
          if (argc)
            {
              cafile = *argv;
              argc--; argv++;
            }
        }
      else if (!strcmp (*argv, "--no-verify"))
        {
          no_verify = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--force-tls"))
        {
          my_http_flags |= HTTP_FLAG_FORCE_TLS;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--no-out"))
        {
          no_out = 1;
          argc--; argv++;
        }
      else if (!strncmp (*argv, "--", 2))
        {
          fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
          exit (1);
        }
    }
  if (argc != 1)
    {
      fprintf (stderr, PGM ": no or too many URLS given\n");
      exit (1);
    }

  if (!cafile)
    cafile = prepend_srcdir ("tls-ca.pem");

#if HTTP_USE_NTBTLS

  (void)err;

  ntbtls_set_debug (tls_dbg, NULL, NULL);

#elif HTTP_USE_GNUTLS

  rc = gnutls_global_init ();
  if (rc)
    log_error ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));

  http_register_tls_callback (verify_callback);
  http_register_tls_ca (cafile);

  err = http_session_new (&session, NULL);
  if (err)
    log_error ("http_session_new failed: %s\n", gpg_strerror (err));

  /* rc = gnutls_dh_params_init(&dh_params); */
  /* if (rc) */
  /*   log_error ("gnutls_dh_params_init failed: %s\n", gnutls_strerror (rc)); */
  /* read_dh_params ("dh_param.pem"); */

  /* rc = gnutls_certificate_set_x509_trust_file */
  /*   (certcred, "ca.pem", GNUTLS_X509_FMT_PEM); */
  /* if (rc) */
  /*   log_error ("gnutls_certificate_set_x509_trust_file failed: %s\n", */
  /*              gnutls_strerror (rc)); */

  /* gnutls_certificate_set_dh_params (certcred, dh_params); */

  gnutls_global_set_log_function (my_gnutls_log);
  if (tls_dbg)
    gnutls_global_set_log_level (tls_dbg);

#endif /*HTTP_USE_GNUTLS*/

  rc = http_parse_uri (&uri, *argv, 1);
  if (rc)
    {
      log_error ("'%s': %s\n", *argv, gpg_strerror (rc));
      return 1;
    }

  printf ("Scheme: %s\n", uri->scheme);
  if (uri->opaque)
    printf ("Value : %s\n", uri->path);
  else
    {
      printf ("Auth  : %s\n", uri->auth? uri->auth:"[none]");
      printf ("Host  : %s\n", uri->host);
      printf ("Port  : %u\n", uri->port);
      printf ("Path  : %s\n", uri->path);
      for (r = uri->params; r; r = r->next)
        {
          printf ("Params: %s", r->name);
          if (!r->no_value)
            {
              printf ("=%s", r->value);
              if (strlen (r->value) != r->valuelen)
                printf (" [real length=%d]", (int) r->valuelen);
            }
          putchar ('\n');
        }
      for (r = uri->query; r; r = r->next)
        {
          printf ("Query : %s", r->name);
          if (!r->no_value)
            {
              printf ("=%s", r->value);
              if (strlen (r->value) != r->valuelen)
                printf (" [real length=%d]", (int) r->valuelen);
            }
          putchar ('\n');
        }
      printf ("TLS   : %s\n",
              uri->use_tls? "yes":
              (my_http_flags&HTTP_FLAG_FORCE_TLS)? "forced" : "no");

    }
  fflush (stdout);
  http_release_parsed_uri (uri);
  uri = NULL;

  rc = http_open_document (&hd, *argv, NULL, my_http_flags,
                           NULL, session, NULL, NULL);
  if (rc)
    {
      log_error ("can't get '%s': %s\n", *argv, gpg_strerror (rc));
      return 1;
    }
  log_info ("open_http_document succeeded; status=%u\n",
            http_get_status_code (hd));

  {
    const char **names;
    int i;

    names = http_get_header_names (hd);
    if (!names)
      log_fatal ("http_get_header_names failed: %s\n",
                 gpg_strerror (gpg_error_from_syserror ()));
    for (i = 0; names[i]; i++)
      printf ("HDR: %s: %s\n", names[i], http_get_header (hd, names[i]));
    xfree (names);
  }
  fflush (stdout);

  switch (http_get_status_code (hd))
    {
    case 200:
    case 400:
    case 401:
    case 403:
    case 404:
      {
        unsigned long count = 0;
        while ((c = es_getc (http_get_read_ptr (hd))) != EOF)
          {
            count++;
            if (!no_out)
              putchar (c);
          }
        log_info ("Received bytes: %lu\n", count);
      }
      break;
    case 301:
    case 302:
    case 307:
      log_info ("Redirected to: %s\n", http_get_header (hd, "Location"));
      break;
    }
  http_close (hd, 0);

  http_session_release (session);
#ifdef HTTP_USE_GNUTLS
  gnutls_global_deinit ();
#endif /*HTTP_USE_GNUTLS*/

  return 0;
}
Example #20
0
File: t-http.c Project: gpg/payproc
int
main (int argc, char **argv)
{
  gpg_error_t err;
  int rc;
  parsed_uri_t uri;
  uri_tuple_t r;
  http_t hd;
  int c;
  http_session_t session = NULL;

  gpgrt_init ();
  log_set_prefix ("t-http", 1 | 4);
  if (argc != 2)
    {
      fprintf (stderr, "usage: t-http uri\n");
      return 1;
    }
  argc--;
  argv++;

#ifdef HTTP_USE_GNUTLS
  rc = gnutls_global_init ();
  if (rc)
    log_error ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));

  http_register_tls_callback (verify_callback);
  http_register_tls_ca ("tls-ca.pem");

  err = http_session_new (&session, NULL);
  if (err)
    log_error ("http_session_new failed: %s\n", gpg_strerror (err));

  /* rc = gnutls_dh_params_init(&dh_params); */
  /* if (rc) */
  /*   log_error ("gnutls_dh_params_init failed: %s\n", gnutls_strerror (rc)); */
  /* read_dh_params ("dh_param.pem"); */

  /* rc = gnutls_certificate_set_x509_trust_file */
  /*   (certcred, "ca.pem", GNUTLS_X509_FMT_PEM); */
  /* if (rc) */
  /*   log_error ("gnutls_certificate_set_x509_trust_file failed: %s\n", */
  /*              gnutls_strerror (rc)); */

  /* gnutls_certificate_set_dh_params (certcred, dh_params); */

  gnutls_global_set_log_function (my_gnutls_log);
  /* gnutls_global_set_log_level (2); */

#endif /*HTTP_USE_GNUTLS*/

  rc = http_parse_uri (&uri, *argv, 1);
  if (rc)
    {
      log_error ("'%s': %s\n", *argv, gpg_strerror (rc));
      return 1;
    }

  printf ("Scheme: %s\n", uri->scheme);
  if (uri->opaque)
    printf ("Value : %s\n", uri->path);
  else
    {
      printf ("Auth  : %s\n", uri->auth? uri->auth:"[none]");
      printf ("Host  : %s\n", uri->host);
      printf ("Port  : %u\n", uri->port);
      printf ("Path  : %s\n", uri->path);
      for (r = uri->params; r; r = r->next)
        {
          printf ("Params: %s", r->name);
          if (!r->no_value)
            {
              printf ("=%s", r->value);
              if (strlen (r->value) != r->valuelen)
                printf (" [real length=%d]", (int) r->valuelen);
            }
          putchar ('\n');
        }
      for (r = uri->query; r; r = r->next)
        {
          printf ("Query : %s", r->name);
          if (!r->no_value)
            {
              printf ("=%s", r->value);
              if (strlen (r->value) != r->valuelen)
                printf (" [real length=%d]", (int) r->valuelen);
            }
          putchar ('\n');
        }
    }
  http_release_parsed_uri (uri);
  uri = NULL;

  rc = http_open_document (&hd, *argv, NULL, 0, NULL, session, NULL, NULL);
  if (rc)
    {
      log_error ("can't get '%s': %s\n", *argv, gpg_strerror (rc));
      return 1;
    }
  log_info ("open_http_document succeeded; status=%u\n",
            http_get_status_code (hd));

  {
    const char **names;
    int i;

    names = http_get_header_names (hd);
    if (!names)
      log_fatal ("http_get_header_names failed: %s\n",
                 gpg_strerror (gpg_error_from_syserror ()));
    for (i = 0; names[i]; i++)
      printf ("HDR: %s: %s\n", names[i], http_get_header (hd, names[i]));
    xfree (names);
  }

  switch (http_get_status_code (hd))
    {
    case 200:
    case 400:
    case 401:
    case 403:
    case 404:
      while ((c = es_getc (http_get_read_ptr (hd))) != EOF)
        putchar (c);
      break;
    case 301:
    case 302:
      printf ("Redirected to '%s'\n", http_get_header (hd, "Location"));
      break;
    }
  http_close (hd, 0);

  http_session_release (session);
#ifdef HTTP_USE_GNUTLS
  gnutls_global_deinit ();
#endif /*HTTP_USE_GNUTLS*/

  return 0;
}