Beispiel #1
0
int main(void) {

    char req[] = "Post /test?name=value&name2=value2 HTTP/1.1\r\n"
                 "Content-Length: 12345\r\n"
                 "Host:   www.example.com  \r\n"
                 "Pragma: no-cache\r\n"
                 "Accept-Encoding: text/plain\r\n"
                 "\r\nTHIS_IS_THE_BODY";
    int len = strlen(req);

    printf("Body: %s\n", http_parse_body(req, len));
    printf("Method: %d (%s)\n", http_parse_method(req), http_method_str[http_parse_method(req)]);
    printf("URI: '%s' (path is '%s')\n", http_parse_uri(req), http_parse_path(http_parse_uri(req)));
    printf("Pragma: '%s'\n", http_parse_header_field(req, len, "Pragma"));
    printf("Content-length: '%s'\n", http_parse_header_field(req, len, "Content-length"));
    printf("Accept-Encoding: '%s'\n", http_parse_header_field(req, len, "Accept-Encoding"));
    printf("Host: '%s'\n", http_parse_header_field(req, len, "Host"));

    printf("Body: %s\n", http_parse_body(req, len));
    printf("Method: %d (%s)\n", http_parse_method(req), http_method_str[http_parse_method(req)]);
    printf("URI: '%s' (path is '%s')\n", http_parse_uri(req), http_parse_path(http_parse_uri(req)));
    printf("Pragma: '%s'\n", http_parse_header_field(req, len, "Pragma"));
    printf("Content-length: '%s'\n", http_parse_header_field(req, len, "Content-length"));
    printf("Accept-Encoding: '%s'\n", http_parse_header_field(req, len, "Accept-Encoding"));
    printf("Host: '%s'\n", http_parse_header_field(req, len, "Host"));

    return 0;
}
Beispiel #2
0
void init_req_header(req_header * req, char * header){
	int len = strlen(header);
	req->body = http_parse_body(header, len);
	req->method = http_parse_method((char *) header);
	req->uri = http_parse_uri(header);
	req->path = http_parse_path(http_parse_uri(header));
	cookie * cookies = parse_cookies(header);
	req->cookies = cookies;
	req->connection = http_parse_header_field(header, len, "Connection");
}
Beispiel #3
0
void init_req_header(req_header * req, char * header){
	char * cookie_header = malloc(strlen(header));
	strcpy(cookie_header, header);
	int len = strlen(header);
	req->body = http_parse_body(header, len);
	req->method = http_parse_method((char *) header);
	req->uri = http_parse_uri(header);
	req->path = http_parse_path(http_parse_uri(header));
	req->connection = http_parse_header_field( header, len, "Connection");
	req->cache_control = http_parse_header_field(header, len, "Cache-Control");

	cookie * cookies = parse_cookies(cookie_header, &(req->num_cookies));
	req->cookies = cookies;
}
Beispiel #4
0
/* Run the help command for the engine responsible for URI.  */
gpg_error_t
ks_action_help (ctrl_t ctrl, const char *url)
{
  gpg_error_t err;
  parsed_uri_t parsed_uri;  /* The broken down URI.  */

  if (!url || !*url)
    {
      ks_print_help (ctrl, "Known schemata:\n");
      parsed_uri = NULL;
    }
  else
    {
      err = http_parse_uri (&parsed_uri, url, 1);
      if (err)
        return err;
    }

  /* Call all engines to give them a chance to print a help sting.  */
  err = ks_hkp_help (ctrl, parsed_uri);
  if (!err)
    err = ks_http_help (ctrl, parsed_uri);
  if (!err)
    err = ks_finger_help (ctrl, parsed_uri);
  if (!err)
    err = ks_kdns_help (ctrl, parsed_uri);

  if (!parsed_uri)
    ks_print_help (ctrl,
                   "(Use an URL for engine specific help.)");
  else
    http_release_parsed_uri (parsed_uri);
  return err;
}
Beispiel #5
0
/* Retrieve keys from URL and write the result to the provided output
   stream OUTFP.  */
gpg_error_t
ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp)
{
  gpg_error_t err = 0;
  estream_t infp;
  parsed_uri_t parsed_uri;  /* The broken down URI.  */

  if (!url)
    return gpg_error (GPG_ERR_INV_URI);

  err = http_parse_uri (&parsed_uri, url, 1);
  if (err)
    return err;

  if (parsed_uri->is_http)
    {
      err = ks_http_fetch (ctrl, url, &infp);
      if (!err)
        {
          err = copy_stream (infp, outfp);
          es_fclose (infp);
        }
    }
  else if (!parsed_uri->opaque)
    {
      err = gpg_error (GPG_ERR_INV_URI);
    }
  else if (!strcmp (parsed_uri->scheme, "finger"))
    {
      err = ks_finger_fetch (ctrl, parsed_uri, &infp);
      if (!err)
        {
          err = copy_stream (infp, outfp);
          es_fclose (infp);
        }
    }
  else if (!strcmp (parsed_uri->scheme, "kdns"))
    {
      err = ks_kdns_fetch (ctrl, parsed_uri, &infp);
      if (!err)
        {
          err = copy_stream (infp, outfp);
          es_fclose (infp);
        }
    }
  else
    err = gpg_error (GPG_ERR_INV_URI);

  http_release_parsed_uri (parsed_uri);
  return err;
}
Beispiel #6
0
/* Mark the host NAME as dead.  NAME may be given as an URL.  Returns
   true if a host was really marked as dead or was already marked dead
   (e.g. by a concurrent session).  */
static int
mark_host_dead (const char *name)
{
  const char *host;
  char *host_buffer = NULL;
  parsed_uri_t parsed_uri = NULL;
  int done = 0;

  if (name && *name && !http_parse_uri (&parsed_uri, name, 1))
    {
      if (parsed_uri->v6lit)
        {
          host_buffer = strconcat ("[", parsed_uri->host, "]", NULL);
          if (!host_buffer)
            log_error ("out of core in mark_host_dead");
          host = host_buffer;
        }
      else
        host = parsed_uri->host;
    }
  else
    host = name;

  if (host && *host && strcmp (host, "localhost"))
    {
      hostinfo_t hi;
      int idx;

      idx = find_hostinfo (host);
      if (idx != -1)
        {
          hi = hosttable[idx];
          log_info ("marking host '%s' as dead%s\n",
                    hi->name, hi->dead? " (again)":"");
          hi->dead = 1;
          hi->died_at = gnupg_get_time ();
          if (!hi->died_at)
            hi->died_at = 1;
          done = 1;
        }
    }

  http_release_parsed_uri (parsed_uri);
  xfree (host_buffer);
  return done;
}
Beispiel #7
0
Request parse_request(char *reqstr)
{
	http_method method = http_parse_method(reqstr);
	char *uri = http_parse_uri(reqstr);
	char *path = http_parse_path(uri);
	// field 1
	// field 2
	// field n
	// body;
	
	Request reqobj;
	
	reqobj.uri = uri;
	reqobj.path = path;
	
	return reqobj;
}
Beispiel #8
0
int http_open(struct http_get *hg, int timeout_ms)
{
	struct hostent *hostent;
	union {
		struct sockaddr sa;
		struct sockaddr_in in;
	} addr;
	struct timeval tv;
	int save, flags;

	char *proxy = getenv("http_proxy");
	if (proxy) {
		hg->proxy = xnew(struct http_uri, 1);
		if (http_parse_uri(proxy, hg->proxy)) {
			d_print("Failed to parse HTTP proxy URI '%s'\n", proxy);
			return -1;
		}
	} else {
/**
 * This function initializes the tcp context global instance to 0 except for
 * file descriptor descriptor for stdin, stdout and stderr.
 *
 * @author    Mohd Naushad Ahmed
 * @version   1.0
 * @param     none
 * @return    none
 */
int http_parse_req ( int conn_id, char *http_req, int http_req_len )
{
  char *http_header_string;
  int mime_idx = 0;

  if (NULL != (http_header_string = strtok(http_req,"\r\n")))
  {
    strcpy(g_http_ctx[conn_id].uri, http_header_string);
  }
  while (NULL != (http_header_string = strtok(NULL,"\r\n")))
  {
    mime_idx++;
    /* starts the scanning until : is encountered & store them into global */
    sscanf(http_header_string,"%[^:]:%s",
           g_http_ctx[conn_id].mime_header[mime_idx].mime_tag_name,
           g_http_ctx[conn_id].mime_header[mime_idx].mime_value);
  }
  g_http_ctx[conn_id].max_mime_header_num = mime_idx;
  http_parse_uri(conn_id);
  return ( 0 );
}/* http_parse_req */
Beispiel #10
0
int http_parse(h_parser_ctx * ctx)
{
    h_head_info * info;
    lx_buffer *  orig_buff;
    char * end, *buff,temp_buff;
    int parser_index,maxlen,tint;
    lx_kvlist_node * headers,*header ; 

 loop:
    orig_buff = &ctx->orig_buff;

    buff = orig_buff->base;
    maxlen = orig_buff->len;
    parser_index = orig_buff->offset;
    info = (h_head_info *)&ctx->info;

    if(orig_buff->offset >=  orig_buff->len )
        goto need_more;

    switch(ctx->cur_stat)
    {
    case S_NONE:

        if(ctx->type == T_REQ){
            ctx->cur_stat = S_REQ_METHOD;
        }else{
            ctx->cur_stat = S_RESP_PROTOCAL;
        }

        info->type = ctx->type;
        info->base = orig_buff->base;
        goto loop;

    case S_REQ_METHOD:
        
        //if(info->mtod_str.offset == 0)
          //  info->mtod_str.offset = parser_index;
        
        if((end = read2space(buff +parser_index , maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        if( (tint=match_str(buff+ parser_index, h_mtod_str,sizeof(h_mtod_str)/sizeof(h_mtod_str[0]) -1 )  ) == -1)
            return HEC_INVALID_METHOD;
        info->mtod = tint;    
        orig_buff->offset = end - buff;
        ctx->cur_stat = S_ITEM_SPACE;
        ctx->next_stat = S_REQ_URI;
        goto loop;
        
    case S_REQ_URI:
         
        if(info->uri.offset == 0)
            info->uri.offset =  parser_index;
        
        if((end = read2space(buff + parser_index, maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        orig_buff->offset = end - buff;
        ctx->last_stat = S_REQ_URI;
        ctx->cur_stat = S_ITEM_SPACE;
        ctx->next_stat = S_REQ_PROTOCAL;
        goto loop;
    
    case S_REQ_PROTOCAL:
        if(ctx->type ==T_REQ && info->prot_str.offset == 0)
            info->prot_str.offset = parser_index;
        
        if((end = read2nl(buff + parser_index , maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        if( tint = get_http_prot(buff + parser_index,end - buff - parser_index) == -1)
            return HEC_INVALID_PROT;
        info->prot = tint;

        orig_buff->offset = end - buff;
                
        ctx->cur_stat = S_NEW_LINE;
        ctx->next_stat = S_HEADER_KEY;
        
        goto loop;

    case S_RESP_PROTOCAL: 
        //if(info->prot_str.offset == 0)
          //  info->prot_str.offset = parser_index;
        
        if((end = read2space(buff + parser_index , maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        if( tint = get_http_prot(buff + parser_index,end - buff - parser_index) == -1)
            return HEC_INVALID_PROT;
        info->prot = tint;

        orig_buff->offset = end - buff;
        
        ctx->cur_stat = S_ITEM_SPACE;
        ctx->next_stat = S_RESP_CODE;
        
        goto loop;

    case S_RESP_CODE:
         if(ctx->temp_buff.offset == 0)
            ctx->temp_buff.offset = parser_index;
        
        if((end = read2space(buff +parser_index , maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        if( ((tint = atoi(buff+ parser_index)) < 0))
            return HEC_INVALID_CODE;
        info->resp_code = tint;   

        orig_buff->offset = end - buff;
        ctx->cur_stat = S_ITEM_SPACE;
        ctx->next_stat = S_RESP_STR;
        goto loop;
        
    case S_RESP_STR:
         if(info->code_str.offset == 0)
            info->code_str.offset = parser_index;
        
        if((end = read2nl(buff + parser_index , maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        orig_buff->offset = end - buff;
        
        ctx->cur_stat = S_NEW_LINE;
        ctx->next_stat = S_HEADER_KEY;
        goto loop;
 
    case S_HEADER_KEY:
        if(info->header_key.offset == 0)
            info->header_key.offset = parser_index;
        
        if( (end = read2str(buff+parser_index, maxlen - parser_index,HTTP_HEADER_SEP_STR)) == NULL)
            goto need_more;
        
        orig_buff->offset = end - buff;
        ctx->cur_stat = S_HEADER_SEP;
        goto loop;

    case S_HEADER_VALUE:
        if(info->header_value.offset == 0 )
            info->header_value.offset = parser_index;

        if((end = read2nl(buff + parser_index , maxlen - parser_index ))
               == NULL )
            goto need_more;
        
        header =(lx_kvlist_node *)list_append((lx_list_node **)&info->headers,sizeof(lx_kvlist_node),ctx->hmalloc); 
        if(header == NULL)
            return HEC_APPNODE_ERR;
       
        header->key =  info->header_key;   
        header->value = info->header_value;
        
        info->header_key.offset = 0;
        info->header_value.offset = 0;

        orig_buff->offset = end - buff;
        ctx->cur_stat = S_NEW_LINE;
        ctx->next_stat = S_HEADER_KEY; 
        
        goto loop;

    case S_HEADER_SEP:
        orig_buff->base[ orig_buff->offset] = 0;
        orig_buff->offset += strlen(HTTP_HEADER_SEP_STR);
        ctx->cur_stat = S_HEADER_VALUE;
        goto loop;

    case S_BODY:
        break;
    case S_ITEM_SPACE:
        orig_buff->base[ orig_buff->offset] = 0;
        orig_buff->offset++;

        if(ctx->last_stat == S_REQ_URI)
            if(http_parse_uri(ctx))
                return HEC_PARSE_URI_ERR;
        ctx ->last_stat = S_NONE;

        ctx->cur_stat = ctx->next_stat;
        goto loop;

    case S_NEW_LINE:
        if(maxlen - orig_buff->offset <(int)(2 * strlen(HTTP_NEW_LINE_STR)) )
            goto need_more;
        
        orig_buff->base[ orig_buff->offset] = 0;
        orig_buff->offset +=2;
        
        if( strncmp(orig_buff->base + orig_buff->offset
            , HTTP_NEW_LINE_STR,strlen(HTTP_NEW_LINE_STR ) ) == 0 )
        {
            orig_buff->offset += 2; 
            return HEC_OK;
        }

        ctx->cur_stat = ctx->next_stat;
        goto loop;
    default: 
        ;
    }

    return 0;    

need_more:
    if(orig_buff->len == orig_buff->maxlen)
    {
        if( ctx->hextend(orig_buff) )
            return HEC_EXTEND_ERR;
        info->base = orig_buff->base;    
    }
    return HEC_NEED_MORE;
};
/*
** parse http message:
**  http_eoh                          - end of headers
**  {http_header,   Key, Value}       - Key = atom() | string()
**  {http_request,  Method,Url,Version}
**  {http_response, Version, Status, Message}
**  {http_error,    Error-Line}
*/
int packet_parse_http(const char* buf, int len, int* statep,
                      PacketCallbacks* pcb, void* arg)
{
    const char* ptr = buf;
    const char* p0;
    int n = len;

    /* remove trailing CRNL (accept NL as well) */
    if ((n >= 2) && (buf[n-2] == '\r'))
        n -= 2;
    else if ((n >= 1) && (buf[n-1] == '\n'))
        n -= 1;

    if (*statep == 0) {
        /* start-line = Request-Line | Status-Line */

        if (n >= 5 && (strncmp(buf, "HTTP/", 5) == 0)) {
            int major  = 0;
            int minor  = 0;
            int status = 0;
            /* Status-Line = HTTP-Version SP
             *              Status-Code SP Reason-Phrase
             *              CRNL
             * HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
             */
            ptr += 5;
            n -= 5;
            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                major = 10*major + (*ptr - '0');
                ptr++;
                n--;
            }
            if (ptr==p0 || !n || (*ptr != '.'))
                return -1;
            ptr++;
            n--;
            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                minor = 10*minor + (*ptr - '0');
                ptr++;
                n--;
            }
            if (ptr==p0) return -1;
            p0 = ptr;
            while (n && SP(ptr)) {
                ptr++; n--;
            }
            if (ptr==p0) return -1;
            
            while (n && isdigit((int) *ptr)) {
                status = 10*status + (*ptr - '0');
                ptr++;
                n--;
            }
            p0 = ptr;
            while (n && SP(ptr)) {
                ptr++; n--;
            }
            if (ptr==p0 && n>0) return -1;
            
            /* NOTE: the syntax allows empty reason phrases */
            (*statep) = !0;
            
            return pcb->http_response(arg, major, minor, status,
                                      ptr, n);
        }
        else {
            /* Request-Line = Method SP Request-URI SP HTTP-Version CRLF */
            http_atom_t* meth;
            const char* meth_ptr = buf;
            int         meth_len;
            PacketHttpURI uri;
            const char*   uri_ptr;
            int           uri_len;
            int major  = 0;
            int minor  = 0;
            unsigned long h = 0;

            while (n && !is_tspecial((unsigned char)*ptr)) {
                hash_update(h, (int)*ptr);
                ptr++;
                n--;
            }
            meth_len = ptr - meth_ptr;
            if (n == 0 || meth_len == 0 || !SP(ptr)) return -1;

            meth = http_hash_lookup(meth_ptr, meth_len, h,
                                    http_meth_hash, HTTP_METH_HASH_SIZE);

            while (n && SP(ptr)) {
                ptr++; n--;
            }
            uri_ptr = ptr;
            while (n && !SP(ptr)) {
                ptr++; n--;
            }
            if ((uri_len = (ptr - uri_ptr)) == 0)
                return -1;
            while (n && SP(ptr)) {
                ptr++; n--;
            }
            if (n == 0) {
                (*statep) = !0;
                http_parse_uri(&uri, uri_ptr, uri_len);
                return pcb->http_request(arg, meth, meth_ptr, meth_len,
                                         &uri, 0, 9);
            }
            if (n < 8)
                return -1;
            if (strncmp(ptr, "HTTP/", 5) != 0)
                return -1;
            ptr += 5;
            n   -= 5;

            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                major = 10*major + (*ptr - '0');
                ptr++;
                n--;
            }            
            if (ptr==p0 || !n || (*ptr != '.'))
                return -1;
            ptr++;
            n--;
            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                minor = 10*minor + (*ptr - '0');
                ptr++;
                n--;
            }
            if (ptr==p0) return -1;

            (*statep) = !0;
            http_parse_uri(&uri, uri_ptr, uri_len);
            return pcb->http_request(arg, meth, meth_ptr, meth_len,
                                     &uri, major, minor);
        }
    }
    else {
        int up = 1;      /* make next char uppercase */
        http_atom_t* name;
        char name_buf[HTTP_MAX_NAME_LEN];
        const char* name_ptr = name_buf;
        int  name_len;
        unsigned long h;

        if (n == 0) {
            /* end of headers */
            *statep = 0;  /* reset state (for next request) */
            return pcb->http_eoh(arg);
        }
        h = 0;
        name_len = 0;
        while (!is_tspecial((unsigned char)*ptr)) {
            if (name_len < HTTP_MAX_NAME_LEN) {
                int c = *ptr;
                if (up) {
                    if (islower(c)) {
                        c = toupper(c);
                    }
                    up = 0;
                }
                else {
                    if (isupper(c))
                        c = tolower(c);
                    else if (c == '-')
                        up = 1;
                }                            
                name_buf[name_len] = c;
                hash_update(h, c);
            }
            name_len++;
            ptr++;
            if (--n == 0) return -1;
        }
        while (n && SP(ptr)) { /* Skip white space before ':' */
            ptr++; n--;
        } 
        if (*ptr != ':') {
            return -1;
        }
        if (name_len <= HTTP_MAX_NAME_LEN) {
            name = http_hash_lookup(name_buf, name_len, h,
                                    http_hdr_hash, HTTP_HDR_HASH_SIZE);
        } 
        else {
            /* Is it ok to return original name without case adjustments? */
            name_ptr = buf;
            name = NULL;
        }
        ptr++;
        n--;
        /* Skip white space after ':' */
        while (n && SP(ptr)) {
            ptr++; n--;
        }
        return pcb->http_header(arg, name, name_ptr, name_len,
                                ptr, n);
    }
    return -1;
}   
Beispiel #12
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;
}
Beispiel #13
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.  If R_HTTP_STATUS is not NULL, the http
   status code will be stored there.  */
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, unsigned int *r_http_status)
{
  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;
  parsed_uri_t uri = NULL;
  int is_onion;

  *r_fp = NULL;

  err = http_parse_uri (&uri, request, 0);
  if (err)
    goto leave;
  is_onion = uri->onion;

  err = http_session_new (&session, httphost,
                          ((ctrl->http_no_crl? HTTP_FLAG_NO_CRL : 0)
                           | HTTP_FLAG_TRUST_DEF),
                          gnupg_http_tls_verify_cb, ctrl);
  if (err)
    goto leave;
  http_session_set_log_cb (session, cert_log_cb);
  http_session_set_timeout (session, ctrl->timeout);

 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)
                    |(dirmngr_use_tor ()? HTTP_FLAG_FORCE_TOR:0)
                    |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)
                    |(opt.disable_ipv6? HTTP_FLAG_IGNORE_IPv6 : 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;
    }

  if (r_http_status)
    *r_http_status = http_get_status_code (http);

  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-- )
          {
            if (is_onion)
              {
                /* Make sure that an onion address only redirects to
                 * another onion address.  */
                http_release_parsed_uri (uri);
                uri = NULL;
                err = http_parse_uri (&uri, s, 0);
                if (err)
                  goto leave;

                if (! uri->onion)
                  {
                    err = gpg_error (GPG_ERR_FORBIDDEN);
                    goto leave;
                  }
              }

            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;

    case 501:
      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
      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);
  http_release_parsed_uri (uri);
  return err;
}
Beispiel #14
0
static void work_http( connection* conn )
{
	int i;
	virtual_host * host;
	//check if the connection cannot work.
	if( conn->state != C_READY )
		return;
	conn->state = C_REQUESTING;
	http_request( conn );
	if( conn->state != C_REQUESTING )
		return;
	//response
	conn->code = 200;
	conn->state = C_RESPONSING;
	/* Check Host and then set root directory. */
	host = loop_search( &conn->server->loop_vhost, conn->host, vhost_searcher );
	if( !host ){
		host = loop_search( &conn->server->loop_vhost, "*", vhost_searcher );
	}
	if( host ){
		//read root
		conn->root_dir = host->root_dir;
		if( !loop_is_empty( &host->loop_rewrite ) )
			loop_search( &host->loop_rewrite, (void*)conn, loop_rewrite_match );
		http_parse_uri( conn );
		DBG("[%s]%s%s", conn->client->ip_string, conn->host, conn->uri );
_RESPONSE:	
		http_parse_path( conn );
		conn->document_type = http_doctype( conn->server, conn->extension );
		if( !conn->document_type ){
			http_error( conn, 404, "<h1>File not found.</h1>" );
		}else if( conn->extension[0] &&
			strstr( conn->server->asp_exts, conn->extension ) )
		{
			//php  do ...
			exec_asp( conn );
		}else if( host->proxy && ( !host->proxy_exts[0] ||
			strstr( host->proxy_exts, conn->extension ) ) )
		{
			// uses proxy server
			proxy_request( conn, host->proxy_ip, host->proxy_port );
		}else if( access(conn->full_path, 0)==0 ){
			if( is_dir(conn->full_path) ){
				char* tmp;
				NEW( tmp, PATH_LEN+32 );
				if( conn->script_name[strlen(conn->script_name)-1] != '/' ){
					//Are you sure that script starts with '/'?
					sprintf( tmp, "http://%s%s/", conn->host, conn->script_name );  
					http_redirect( conn, tmp );
				}else{
					if( tmp ){
						for( i = 0; i<10; i++ )
						{
							if( !conn->server->default_pages[i][0] ) {
								i=10;
								break;
							}
							sprintf( tmp, "%s/%s", conn->full_path, conn->server->default_pages[i] );
							if( access( tmp, 0 ) == 0 )
							{
								//091004 by Huang Guan.
								sprintf( conn->script_name, "%s%s", conn->script_name, 
									conn->server->default_pages[i] );
								DEL( tmp );
								goto _RESPONSE;
							}
						}
					}
					if( i == 10 ){
						// List Directory
						if( host->list ){
							int ret;
							NEW( conn->data_send, MAX_DATASEND+4 );
							strcpy( conn->extension, "html" );
							conn->document_type = http_doctype( conn->server, conn->extension );
							ret = listdir( conn->data_send, MAX_DATASEND, conn->full_path, 
								conn->script_name );
							conn->data_size = ret;
						}else{
							http_error( conn, 403, "<h1>Forbidden</h1>" );
						}
					}
				}
				DEL( tmp );
			}else{
				http_sendfile( conn, conn->full_path );
			}
		}else if( strncmp(conn->current_dir, "/system", 7)==0 && conn->root_dir==host->root_dir ){
			strcpy(conn->script_name, conn->script_name+7);
			conn->root_dir = conn->client->server->root_dir;
			goto _RESPONSE;
		}else{
			http_error( conn, 404, "<h1>File not found.</h1>" );
		}
	}else{
		http_error( conn, 403, "<h1>Unknown host name.</h1>" );
	}

	if( conn->state == C_RESPONSING )
		http_response( conn );
	conn->requests ++;
	if( conn->form_data )
		DEL( conn->form_data );
	if( conn->data_send )
		DEL( conn->data_send );
	
	if( conn->session )
		conn->session->reference --;
	conn->session = NULL;
		
	//next request
	if( conn->keep_alive ){
		conn->state = C_READY;
	}else{
		conn->state = C_END;
	}
}
Beispiel #15
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;
}
Beispiel #16
0
void handle_client(int socket) {
  node *cookie, *param;
  service cmd;
  http_method method;
  http_response resp;
  int bytes, s, expected_len, header_len;
  char req[BUFFER_SIZE], buf[BUFFER_SIZE];
  const char *path;
  char *connection, *req_body_len;
  time_t since_time;

  /* TODO Loop receiving requests and sending appropriate responses,
   *      until one of the conditions to close the connection is
   *      met.
   */
  cookie = param = resp.expire = resp.cookie = NULL;

  do {
    // New request
    free_list(resp.cookie);
    free_list(resp.expire);
    if (cookie) free_list(cookie);
    if (param) free_list(param);
    cookie = param = NULL;
    memset(&resp, 0, sizeof(http_response));
    memset(req, 0, BUFFER_SIZE);
    bytes = 0;

    // Wait for HTTP header to complete
    do {
      bytes += recv(socket, req + bytes, BUFFER_SIZE, 0);
      header_len = http_header_complete(req, bytes);
    } while (header_len == -1);
    
    // Receive body if there is content length
    if (strstr(req, HDR_CONTENT_LEN)) {
      strcpy(buf, req);
      req_body_len = get_header_value_from_req(buf, HDR_CONTENT_LEN);
      expected_len = atoi(req_body_len) + header_len;
      while (bytes < expected_len) {
         bytes += recv(socket, req + bytes, BUFFER_SIZE, 0);
      }
    }
    // printf("recv %i bytes\n", bytes);

    // Get HTTP method
    method = http_parse_method(req);

    // Get path
    strcpy(buf, req);
    path = http_parse_path(http_parse_uri(buf));
    // printf("Request: %s\n", path);

    // Parse cookies 
    if (strstr(req, HDR_COOKIE)) {
      strcpy(buf, req);
      cookie = get_cookies_from_header(get_header_value_from_req(buf, HDR_COOKIE));
    } else {
      cookie = NULL;
    }

    // Match service command
    cmd = SERV_UNKNOWN;
    for (s= 0; s < SERV_UNKNOWN; s++) {
      if (strncasecmp(path, service_str[s], strlen(service_str[s])) == 0) {
        cmd = s;
        break;
      }
    }

    // Handle command
    switch(cmd) {
      case SERV_KNOCK:
      case SERV_LOGIN:
      case SERV_LOGOUT:
      case SERV_GETFILE:
      case SERV_ADDCART:
      case SERV_DELCART:
      case SERV_CHECKOUT:
        if (method == METHOD_GET) {
          param = get_params_from_query(get_query_str_from_path(path));
          if (cmd == SERV_KNOCK) {
            knock_handler(&resp, cookie);
          } else if (cmd == SERV_LOGIN) {
            login_handler(&resp, param);
          } else if (cmd == SERV_LOGOUT) {
            logout_handler(&resp, cookie);
          } else if (cmd == SERV_GETFILE) {
            since_time = 0;
            strcpy(buf, req);
            if (strstr(buf, HDR_IF_MOD_SINCE)) {
              if (!RFC_822_to_time(strstr(buf, HDR_IF_MOD_SINCE) + 
                    strlen(HDR_IF_MOD_SINCE), &since_time)) {
                since_time = 0;
              }
            }
            getfile_handler(&resp, param, since_time);
          } else if (cmd == SERV_ADDCART) {
            addcart_handler(&resp, param, cookie);
          } else if (cmd == SERV_DELCART) {
            delcart_handler(&resp, param, cookie);
          } else if (cmd == SERV_CHECKOUT) {
            checkout_handler(&resp, cookie);
          } else {
            resp.status = NOT_FOUND;
          }
        } else {
          resp.allow = METHOD_GET;
          resp.status = METHOD_NOT_ALLOWED;
        }
        break;
      case SERV_PUTFILE:
        if (method == METHOD_POST) {
          strcpy(buf, req);
          param = get_params_from_query((char*) http_parse_body(buf, bytes));
          putfile_handler(&resp, cookie, param);
        } else {
          resp.allow = METHOD_POST;
          resp.status = METHOD_NOT_ALLOWED;
        }
        break;
      default:
        resp.status = NOT_FOUND;
        break;
    }

    // Check if status not ok or 
    // client wants to close connection after completing request
    if (resp.status != OK) {
      resp.connection = CLOSE;
    } else if (strstr(req, "Connection:")) {
      connection = http_parse_header_field(buf, bytes, "Connection");
      if (strcmp(connection, "close") == 0) {
        resp.connection = CLOSE;
      }
    }

    send_response(socket, &resp);  
  } while (resp.connection != CLOSE);
}
Beispiel #17
0
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;
}