boB Rudis
3 years ago
14 changed files with 682 additions and 13 deletions
@ -0,0 +1,2 @@ |
|||||
|
YEAR: 2021 |
||||
|
COPYRIGHT HOLDER: Bob Rudis |
@ -0,0 +1,21 @@ |
|||||
|
# MIT License |
||||
|
|
||||
|
Copyright (c) 2021 Bob Rudis |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
|
SOFTWARE. |
@ -1,4 +1,7 @@ |
|||||
# Generated by roxygen2: do not edit by hand |
# Generated by roxygen2: do not edit by hand |
||||
|
|
||||
|
export("%>%") |
||||
|
export(h2c) |
||||
import(httr) |
import(httr) |
||||
importFrom(jsonlite,fromJSON) |
import(processx) |
||||
|
importFrom(magrittr,"%>%") |
||||
|
@ -0,0 +1,48 @@ |
|||||
|
#' Convert an 'httr' call to 'curl' command line |
||||
|
#' |
||||
|
#' @param complete_httr_verb_call wrap an `httr` `VERB` call with this function |
||||
|
#' and it will return the text of a working `curl` command line |
||||
|
#' @export |
||||
|
#' @examples \dontrun{ |
||||
|
#' h2c( |
||||
|
#' httr::GET( |
||||
|
#' url = "https://rud.is/", |
||||
|
#' httr::user_agent(splashr::ua_apple_tv), |
||||
|
#' query = list( |
||||
|
#' a = "b", |
||||
|
#' c = 1 |
||||
|
#' ) |
||||
|
#' ) |
||||
|
#' ) |
||||
|
#' } |
||||
|
h2c <- function(complete_httr_verb_call) { |
||||
|
|
||||
|
ƒ_call <- substitute(complete_httr_verb_call) |
||||
|
|
||||
|
perl <- find_perl() |
||||
|
|
||||
|
args <- system.file("bin", "h2c.pl", package = "httr2curl") |
||||
|
|
||||
|
capture.output( |
||||
|
capture.output( |
||||
|
httr::with_verbose( |
||||
|
eval(ƒ_call) |
||||
|
), type = "message") -> res |
||||
|
) -> junk |
||||
|
|
||||
|
out <- tempfile() |
||||
|
|
||||
|
res[grepl("^->", res)] %>% |
||||
|
sub("^-> ", "", .) %>% |
||||
|
paste0(collapse = "\n") %>% |
||||
|
writeLines(out) |
||||
|
|
||||
|
processx::run( |
||||
|
command = perl, |
||||
|
args = args, |
||||
|
stdin = out |
||||
|
) -> res |
||||
|
|
||||
|
res$stdout |
||||
|
|
||||
|
} |
@ -1,9 +1,12 @@ |
|||||
#' ... |
#' Turn 'httr' Web Requests Into 'curl' Command Line Calls |
||||
#' |
#' |
||||
|
#' When provided with an 'httr' "VERB" call, the request will be made |
||||
|
#' and 'libcurl' headers will be captured and post-processed to provide a working |
||||
|
#' 'curl' command line call. |
||||
|
#' |
||||
#' @md |
#' @md |
||||
#' @name httr2curl |
#' @name httr2curl |
||||
#' @keywords internal |
#' @keywords internal |
||||
#' @author Bob Rudis (bob@@rud.is) |
#' @author Bob Rudis (bob@@rud.is) |
||||
#' @import httr |
#' @import httr processx |
||||
#' @importFrom jsonlite fromJSON |
|
||||
"_PACKAGE" |
"_PACKAGE" |
||||
|
@ -0,0 +1,11 @@ |
|||||
|
#' Pipe operator |
||||
|
#' |
||||
|
#' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. |
||||
|
#' |
||||
|
#' @name %>% |
||||
|
#' @rdname pipe |
||||
|
#' @keywords internal |
||||
|
#' @export |
||||
|
#' @importFrom magrittr %>% |
||||
|
#' @usage lhs \%>\% rhs |
||||
|
NULL |
@ -0,0 +1,14 @@ |
|||||
|
find_perl <- function() { |
||||
|
|
||||
|
perl <- Sys.which("perl") |
||||
|
|
||||
|
if (perl == "") { |
||||
|
stop( |
||||
|
"Cannot find 'perl'. httr2curl requires perl to be installed and on the PATH.", |
||||
|
call. = FALSE |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
return(perl) |
||||
|
|
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
|
||||
|
[![Project Status: Active – The project has reached a stable, usable |
||||
|
state and is being actively |
||||
|
developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) |
||||
|
[![Signed |
||||
|
by](https://img.shields.io/badge/Keybase-Verified-brightgreen.svg)](https://keybase.io/hrbrmstr) |
||||
|
![Signed commit |
||||
|
%](https://img.shields.io/badge/Signed_Commits-100%25-lightgrey.svg) |
||||
|
[![R-CMD-check](https://github.com/hrbrmstr/httr2curl/workflows/R-CMD-check/badge.svg)](https://github.com/hrbrmstr/httr2curl/actions?query=workflow%3AR-CMD-check) |
||||
|
[![Linux build |
||||
|
Status](https://travis-ci.org/hrbrmstr/httr2curl.svg?branch=master)](https://travis-ci.org/hrbrmstr/httr2curl) |
||||
|
![Minimal R |
||||
|
Version](https://img.shields.io/badge/R%3E%3D-3.6.0-blue.svg) |
||||
|
![License](https://img.shields.io/badge/License-MIT-blue.svg) |
||||
|
|
||||
|
# httr2curl |
||||
|
|
||||
|
Turn ‘httr’ Web Requests Into ‘curl’ Command Line Calls |
||||
|
|
||||
|
## Description |
||||
|
|
||||
|
When provided with an ‘httr’ “VERB” call, the request will be made and |
||||
|
‘libcurl’ headers will be captured and post-processed to provide a |
||||
|
working ‘curl’ command line call. |
||||
|
|
||||
|
## What’s Inside The Tin |
||||
|
|
||||
|
The following functions are implemented: |
||||
|
|
||||
|
- `h2c`: Convert an ‘httr’ call to ‘curl’ command line |
||||
|
|
||||
|
## Installation |
||||
|
|
||||
|
``` r |
||||
|
remotes::install_git("https://git.rud.is/hrbrmstr/httr2curl.git") |
||||
|
``` |
||||
|
|
||||
|
NOTE: To use the ‘remotes’ install options you will need to have the |
||||
|
[{remotes} package](https://github.com/r-lib/remotes) installed. |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
``` r |
||||
|
library(httr2curl) |
||||
|
|
||||
|
# current version |
||||
|
packageVersion("httr2curl") |
||||
|
## [1] '0.1.0' |
||||
|
``` |
||||
|
|
||||
|
``` r |
||||
|
h2c( |
||||
|
httr::GET( |
||||
|
url = "https://rud.is/", |
||||
|
httr::user_agent(splashr::ua_apple_tv), |
||||
|
query = list( |
||||
|
a = "b", |
||||
|
c = 1 |
||||
|
) |
||||
|
) |
||||
|
) |
||||
|
## [1] "curl --http2 --header \"Accept: application/json, text/xml, application/xml, */*\" --compressed --user-agent \"AppleTV6,2/11.1\" \"https://rud.is/?a=b&c=1\"\n" |
||||
|
``` |
||||
|
|
||||
|
## httr2curl Metrics |
||||
|
|
||||
|
| Lang | \# Files | (%) | LoC | (%) | Blank lines | (%) | \# Lines | (%) | |
||||
|
|:-----|---------:|-----:|----:|-----:|------------:|-----:|---------:|-----:| |
||||
|
| R | 5 | 0.36 | 37 | 0.24 | 15 | 0.23 | 38 | 0.27 | |
||||
|
| YAML | 1 | 0.07 | 22 | 0.14 | 2 | 0.03 | 2 | 0.01 | |
||||
|
| Rmd | 1 | 0.07 | 18 | 0.12 | 16 | 0.24 | 31 | 0.22 | |
||||
|
| SUM | 7 | 0.50 | 77 | 0.50 | 33 | 0.50 | 71 | 0.50 | |
||||
|
|
||||
|
clock Package Metrics for httr2curl |
||||
|
|
||||
|
## Code of Conduct |
||||
|
|
||||
|
Please note that this project is released with a Contributor Code of |
||||
|
Conduct. By participating in this project you agree to abide by its |
||||
|
terms. |
@ -0,0 +1,426 @@ |
|||||
|
#!/usr/bin/perl |
||||
|
|
||||
|
use MIME::Base64; |
||||
|
|
||||
|
sub usage { |
||||
|
print "h2c.pl [options] < file \n", |
||||
|
" -a Allow curl's default headers\n", |
||||
|
" -d Output man page HTML links after command line\n", |
||||
|
" -h Show short help\n", |
||||
|
" -H Output HTTP generated URLs instead\n", |
||||
|
" -i Ignore HTTP version\n", |
||||
|
" --libcurl Output libcurl code instead\n", |
||||
|
" -n Output notes after command line\n", |
||||
|
" -s Use short command line options\n", |
||||
|
" -v Add a verbose option to the command line\n"; |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
sub manpage { |
||||
|
my ($p, $n, $desc) = @_; |
||||
|
if(!$n) { |
||||
|
$n = $p; |
||||
|
} |
||||
|
return sprintf("%s;%s;$desc", $p, $n); |
||||
|
} |
||||
|
|
||||
|
my $usesamehttpversion = 1; |
||||
|
my $disableheadersnotseen = 1; |
||||
|
my $shellcompatible = 1; # may not been windows command prompt compat |
||||
|
my $uselongoptions = 1; # instead of short |
||||
|
my $uselibcurl = 0; # --libcurl |
||||
|
my $usehttp = 0; |
||||
|
|
||||
|
while($ARGV[0]) { |
||||
|
if(($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) { |
||||
|
usage(); |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-a") { |
||||
|
$disableheadersnotseen = 0; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-d") { |
||||
|
$usedocs = 1; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-H") { |
||||
|
$usehttp = 1; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-i") { |
||||
|
$usesamehttpversion = 0; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "--libcurl") { |
||||
|
$uselibcurl = 1; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-n") { |
||||
|
$usenotes = 1; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-s") { |
||||
|
$uselongoptions = 0; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
elsif($ARGV[0] eq "-v") { |
||||
|
$useverbose = 1; |
||||
|
shift @ARGV; |
||||
|
} |
||||
|
else { |
||||
|
usage(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
my $state; # 0 is request-line, 1-headers, 2-body |
||||
|
my $line = 1; |
||||
|
while(<STDIN>) { |
||||
|
my $l = $_; |
||||
|
# discard CRs completely |
||||
|
$l =~ s/\r//g; |
||||
|
if(!$state) { |
||||
|
chomp $l; |
||||
|
if($l =~ /([^ ]*) +(.*) +(HTTP\/.*)/) { |
||||
|
$method = $1; |
||||
|
$path = $2; |
||||
|
$http = $3; |
||||
|
} |
||||
|
else { |
||||
|
$error="bad request-line"; |
||||
|
last; |
||||
|
} |
||||
|
$state++; |
||||
|
} |
||||
|
elsif(1 == $state) { |
||||
|
chomp $l; |
||||
|
if($l =~ /([^:]*): *(.*)/) { |
||||
|
$header{lc($1)}=$2; |
||||
|
$exactcase{lc($1)}=$1; # to allow us to use it as read |
||||
|
} |
||||
|
elsif(length($l)<2) { |
||||
|
# body time |
||||
|
$state++; |
||||
|
} |
||||
|
else { |
||||
|
$error="illegal HTTP header on line $line"; |
||||
|
last; |
||||
|
} |
||||
|
} |
||||
|
elsif(2 == $state) { |
||||
|
push @body, $l; |
||||
|
} |
||||
|
$line++; |
||||
|
} |
||||
|
|
||||
|
if(!$header{'host'}) { |
||||
|
$error = "No Host: header makes it impossible to tell URL\n"; |
||||
|
} |
||||
|
|
||||
|
error: |
||||
|
if($error) { |
||||
|
print "Error: $error\n"; |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
if($uselongoptions) { |
||||
|
$opt_data = "--data"; |
||||
|
$opt_request = "--request"; |
||||
|
$opt_head = "--head"; |
||||
|
$opt_header = "--header"; |
||||
|
$opt_user_agent = "--user-agent"; |
||||
|
$opt_cookie = "--cookie"; |
||||
|
$opt_verbose = "--verbose"; |
||||
|
$opt_form = "--form"; |
||||
|
$opt_user = "--user"; |
||||
|
} |
||||
|
else { |
||||
|
$opt_data = "-d"; |
||||
|
$opt_request = "-X"; |
||||
|
$opt_head = "-I"; |
||||
|
$opt_header = "-H"; |
||||
|
$opt_user_agent = "-A"; |
||||
|
$opt_cookie = "-b"; |
||||
|
$opt_verbose = "-v"; |
||||
|
$opt_form = "-F"; |
||||
|
$opt_user = "-u"; |
||||
|
} |
||||
|
|
||||
|
my $httpver=""; |
||||
|
my $disabledheaders=""; |
||||
|
my $addedheaders=""; |
||||
|
|
||||
|
if($header{"content-type"} =~ /^multipart\/form-data;/) { |
||||
|
# multipart formpost, this is special |
||||
|
my $type = $header{"content-type"}; |
||||
|
my $boundary = $type; |
||||
|
$boundary =~ s/.*boundary=(.*)/$1/; |
||||
|
my $inbound = $body[0]; |
||||
|
chomp $inbound; |
||||
|
# a body MUST start with dash-dash-boundary |
||||
|
if("--$boundary" ne $inbound) { |
||||
|
$error = "unexpected multipart format"; |
||||
|
goto error; |
||||
|
} |
||||
|
my $bline=1; |
||||
|
|
||||
|
my %fheader; |
||||
|
my $fstate = 0; |
||||
|
my @fbody; |
||||
|
while($body[$bline]) { |
||||
|
my $l = $body[$bline]; |
||||
|
if(0 == $fstate) { |
||||
|
# headers |
||||
|
chomp $l; |
||||
|
if($l =~ /([^:]*): *(.*)/) { |
||||
|
$fheader{lc($1)}=$2; |
||||
|
} |
||||
|
elsif(length($l)<2) { |
||||
|
# body time |
||||
|
$fstate++; |
||||
|
} |
||||
|
} |
||||
|
elsif($fstate) { |
||||
|
if($l =~ /^--$boundary/) { |
||||
|
# end of this part |
||||
|
my $cd = $fheader{'content-disposition'}; |
||||
|
if(!$cd) { |
||||
|
$error = "multi-part without Content-Disposition: header!"; |
||||
|
goto error; |
||||
|
} |
||||
|
# Content-Disposition: form-data; name="name" |
||||
|
# Content-Disposition: form-data; name="file"; filename="README.md" |
||||
|
if($cd =~ /^form-data; name=([^;]*)[;]? *(.*)/i) { |
||||
|
my ($n, $f)=($1, $2); |
||||
|
# name is with or without quotes |
||||
|
$n =~ s/\"//g; |
||||
|
if($f =~ /^filename=(.*)/) { |
||||
|
# filename is with or without quotes |
||||
|
$f = $1; |
||||
|
$f =~ s/\"//g; |
||||
|
} |
||||
|
if(!$multipart) { |
||||
|
push @docs, manpage("-F", $opt_form, "send a multipart formpost"); |
||||
|
} |
||||
|
if(!$f) { |
||||
|
my $fbody = join("", @fbody); |
||||
|
$fbody =~ s/[ \n\r]+\z//g; |
||||
|
$fbody =~ s/([\\\$\"\'\`])/\\$1/g; |
||||
|
$multipart .= "$opt_form $n=\"$fbody\" "; |
||||
|
@fbody=""; |
||||
|
} |
||||
|
else { |
||||
|
# file name was present |
||||
|
$multipart .= "$opt_form $n=\@$f "; |
||||
|
} |
||||
|
} |
||||
|
$fstate = 0; |
||||
|
%fheader = 0; |
||||
|
$bline++; |
||||
|
next; |
||||
|
} |
||||
|
push @fbody, $l; |
||||
|
} |
||||
|
$bline++; |
||||
|
} |
||||
|
if($body[$bline-1] !~ /^--$boundary--/) { |
||||
|
print STDERR "bad last line?"; |
||||
|
} |
||||
|
|
||||
|
$header{"content-type"} = ""; # blank it |
||||
|
$do_multipart = 1; |
||||
|
|
||||
|
} |
||||
|
elsif(length(join("", @body))) { |
||||
|
# TODO: escape the body |
||||
|
my $esc = join("", @body); |
||||
|
chomp $esc; # trim the final newline |
||||
|
if($shellcompatible) { |
||||
|
$esc =~ s/\n/ /g; # turn newlines into space! |
||||
|
$esc =~ s/\"/\\"/g; # escape double quotes |
||||
|
if(!$unixescaped) { |
||||
|
push @notes, "uses quotes suitable for *nix command lines"; |
||||
|
$unixescaped++; |
||||
|
} |
||||
|
} |
||||
|
$usebody= sprintf("--data-binary \"%s\" ", $esc); |
||||
|
push @docs, manpage("--data-binary", "", "send this string as a body with POST"); |
||||
|
} |
||||
|
if(uc($method) eq "HEAD") { |
||||
|
$usemethod = "$opt_head "; |
||||
|
push @docs, manpage("-I", $opt_head, "send a HEAD request"); |
||||
|
} |
||||
|
elsif(uc($method) eq "POST") { |
||||
|
if(!$usebody && !$do_multipart) { |
||||
|
$usebody= sprintf("$opt_data \"\" "); |
||||
|
push @docs, manpage("-d", $opt_data, "send this string as a body with POST"); |
||||
|
} |
||||
|
} |
||||
|
elsif(uc($method) eq "PUT") { |
||||
|
if(!$usebody) { |
||||
|
$usebody= sprintf("$opt_data \"\" "); |
||||
|
push @docs, manpage("-d", $opt_data, "send this string as a body with POST"); |
||||
|
} |
||||
|
$usebody .= "$opt_request PUT "; |
||||
|
push @docs, manpage("-X", $opt_request, "replace the request method with this string"); |
||||
|
} |
||||
|
elsif(uc($method) eq "OPTIONS") { |
||||
|
$usemethod .= "$opt_request OPTIONS "; |
||||
|
if($path !~ /^\//) { |
||||
|
# very special case |
||||
|
$requesttarget="--request-target \"$path\" "; |
||||
|
push @docs, manpage("--request-target", "", |
||||
|
"specify request target to use instead of using the URL's"); |
||||
|
$path = ""; |
||||
|
} |
||||
|
} |
||||
|
elsif(uc($method) ne "GET") { |
||||
|
$error = "unsupported HTTP method $method"; |
||||
|
goto error; |
||||
|
} |
||||
|
|
||||
|
if($usebody) { |
||||
|
# body is set, handle the content-type |
||||
|
if(!$header{"content-type"}) { |
||||
|
$disabledheaders .= "$opt_header Content-Type: "; |
||||
|
} |
||||
|
elsif(lc($header{"content-type"}) ne |
||||
|
"application/x-www-form-urlencoded") { |
||||
|
# custom |
||||
|
$ignore_contenttype = 1; |
||||
|
$addedheaders .= sprintf("$opt_header \"Content-Type: %s\" ", |
||||
|
$header{"content-type"}); |
||||
|
} |
||||
|
elsif((lc($header{"content-type"}) eq |
||||
|
"application/x-www-form-urlencoded") && !$do_multipart && |
||||
|
($method eq "POST")) { |
||||
|
# default for normal POST |
||||
|
$ignore_contenttype = 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if($usesamehttpversion) { |
||||
|
if(uc($http) eq "HTTP/1.1") { |
||||
|
$httpver = "--http1.1 "; |
||||
|
push @docs, manpage("--http1.1", "", "use HTTP protocol version 1.1"); |
||||
|
} |
||||
|
elsif(uc($http) eq "HTTP/2") { |
||||
|
$httpver = "--http2 "; |
||||
|
push @docs, manpage("--http2", "", "use HTTP protocol version 2"); |
||||
|
} |
||||
|
else { |
||||
|
$error = "unsupported HTTP version $http"; |
||||
|
goto error; |
||||
|
} |
||||
|
} |
||||
|
if($disableheadersnotseen) { |
||||
|
if(!$header{'accept'}) { |
||||
|
$disabledheaders .= "$opt_header Accept: "; |
||||
|
} |
||||
|
if(!$header{'user-agent'}) { |
||||
|
$disabledheaders .= "$opt_header User-Agent: "; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if($do_multipart) { |
||||
|
if(!$header{lc("expect")}) { |
||||
|
# no expect header, disable it for us too since curl -F defaults to |
||||
|
# Expect: 100-continue |
||||
|
$disabledheaders .= "$opt_header Expect: "; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# go through the headers alphabetically just to make the order fixed |
||||
|
foreach my $h (sort keys %header) { |
||||
|
if(lc($h) eq "host") { |
||||
|
# We use Host: for the URL creation |
||||
|
} |
||||
|
elsif((lc($h) eq "authorization") && |
||||
|
($header{'authorization'} =~ /^Basic (.*)/)) { |
||||
|
my $decoded = decode_base64($1); |
||||
|
$addedheaders .= sprintf("%s \"%s\" ", $opt_user, $decoded); |
||||
|
push @docs, manpage("-u", $opt_user, "use this user and password for Basic auth"); |
||||
|
} |
||||
|
elsif(lc($h) eq "expect") { |
||||
|
# let curl do expect on its own |
||||
|
} |
||||
|
elsif(lc($h) eq "content-type" && |
||||
|
($do_multipart || $ignore_contenttype)) { |
||||
|
# skip this for multipart |
||||
|
} |
||||
|
elsif(($h eq "accept-encoding") && |
||||
|
($header{$h} =~ /gzip/)) { |
||||
|
push @docs, manpage("--compressed", "", "request a compressed response"); |
||||
|
$addedheaders .= "--compressed "; |
||||
|
} |
||||
|
elsif((lc($h) eq "accept") && |
||||
|
($header{"accept"} eq "*/*")) { |
||||
|
# ignore if set to */* as that's a curl default |
||||
|
} |
||||
|
elsif(lc($h) eq "content-length") { |
||||
|
# we don't set custom size, just usebody |
||||
|
} |
||||
|
else { |
||||
|
$exact = $exactcase{$h}; |
||||
|
my $opt = sprintf("$opt_header \"%s: ", $exact); |
||||
|
if(lc($h) eq "user-agent") { |
||||
|
$opt = "$opt_user_agent \""; |
||||
|
push @docs, manpage("-A", $opt_user_agent, "use this custom User-Agent request header"); |
||||
|
} |
||||
|
elsif(lc($h) eq "cookie") { |
||||
|
$opt = "$opt_cookie \""; |
||||
|
push @docs, manpage("-b", $opt_cookie, "pass on this custom Cookie: request header"); |
||||
|
} |
||||
|
$addedheaders .= sprintf("%s%s\" ", $opt, $header{$h}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if($path =~ /[ &?]/) { |
||||
|
$url = sprintf "\"%s://%s%s\"", $usehttp ? "http" : "https", $header{'host'}, $path; |
||||
|
} |
||||
|
else { |
||||
|
$url = sprintf "%s://%s%s", $usehttp ? "http" : "https", $header{'host'}, $path; |
||||
|
} |
||||
|
|
||||
|
if($disabledheaders || $addedheaders) { |
||||
|
push @docs, manpage("-H", $opt_header, "add, replace or remove HTTP headers from the request"); |
||||
|
} |
||||
|
|
||||
|
if($useverbose) { |
||||
|
$useverbose = "$opt_verbose "; |
||||
|
push @docs, manpage("-v", $opt_verbose, "show verbose output"); |
||||
|
} |
||||
|
|
||||
|
# This adds the -x option to prevent a curl request to actually go out to any |
||||
|
# remote server |
||||
|
my $lib="--libcurl - -x localhost:0 " if($uselibcurl); |
||||
|
my $curlcmd = sprintf "curl ${useverbose}${usemethod}${httpver}${disabledheaders}${addedheaders}${usebody}${multipart}${requesttarget}${lib}${url}"; |
||||
|
|
||||
|
if($uselibcurl) { |
||||
|
# this actually runs curl which will fail to connect so ignore errors |
||||
|
open(C, "$curlcmd 2>/dev/null|"); |
||||
|
while(<C>) { |
||||
|
# skip CURLOPT_PROXY since that's only used to avoid network |
||||
|
if($_ !~ /CURLOPT_PROXY, /) { |
||||
|
print $_; |
||||
|
} |
||||
|
} |
||||
|
close(C); |
||||
|
} |
||||
|
else { |
||||
|
print "$curlcmd\n"; |
||||
|
} |
||||
|
|
||||
|
if($usenotes) { |
||||
|
print "---\n"; |
||||
|
foreach my $n (@notes) { |
||||
|
print "$n\n"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if($usedocs) { |
||||
|
print "---\n"; |
||||
|
foreach my $d (@docs) { |
||||
|
print "$d\n"; |
||||
|
} |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
% Generated by roxygen2: do not edit by hand |
||||
|
% Please edit documentation in R/h2c.R |
||||
|
\name{h2c} |
||||
|
\alias{h2c} |
||||
|
\title{Convert an 'httr' call to 'curl' command line} |
||||
|
\usage{ |
||||
|
h2c(complete_httr_verb_call) |
||||
|
} |
||||
|
\arguments{ |
||||
|
\item{complete_httr_verb_call}{wrap an \code{httr} \code{VERB} call with this function |
||||
|
and it will return the text of a working \code{curl} command line} |
||||
|
} |
||||
|
\description{ |
||||
|
Convert an 'httr' call to 'curl' command line |
||||
|
} |
||||
|
\examples{ |
||||
|
\dontrun{ |
||||
|
h2c( |
||||
|
httr::GET( |
||||
|
url = "https://rud.is/", |
||||
|
httr::user_agent(splashr::ua_apple_tv), |
||||
|
query = list( |
||||
|
a = "b", |
||||
|
c = 1 |
||||
|
) |
||||
|
) |
||||
|
) |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
% Generated by roxygen2: do not edit by hand |
||||
|
% Please edit documentation in R/utils-pipe.R |
||||
|
\name{\%>\%} |
||||
|
\alias{\%>\%} |
||||
|
\title{Pipe operator} |
||||
|
\usage{ |
||||
|
lhs \%>\% rhs |
||||
|
} |
||||
|
\description{ |
||||
|
See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. |
||||
|
} |
||||
|
\keyword{internal} |
Loading…
Reference in new issue