Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100755 171 lines (142 sloc) 4.772 kB
4daea5e @decklin Initial commit
decklin authored
1 #!/bin/sh
2
b84db49 @decklin Add some comments and an MIT license
decklin authored
3 # Curlicue - an OAuth wrapper for curl
4 #
5 # Copyright © 2010 Decklin Foster <decklin@red-bean.com>
6 # Please see README for usage information and LICENSE for license.
7
8 # Because HTTP responses from the OAuth "dance" will be percent-encoded,
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
9 # and we want to round-trip this data, we require that credentials files
10 # are also percent-encoded. Therefore, no decoding is done here. $1 is
11 # the name of another function that processes each pair (as two args).
b84db49 @decklin Add some comments and an MIT license
decklin authored
12
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
13 load_cred_file() {
14 foreach_query_pair parse_cred "$(cat "$1" 2>/dev/null)"
4daea5e @decklin Initial commit
decklin authored
15 }
16
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
17 foreach_query_pair() {
4daea5e @decklin Initial commit
decklin authored
18 local IFS='&'
19 for i in $2; do
20 $1 "${i%%=*}" "${i#*=}"
21 done
22 }
23
b84db49 @decklin Add some comments and an MIT license
decklin authored
24 # This list is tiring, but we can't just let random files set any old
03d1dca @decklin Make Netflix work (big ugly auth URL, no PIN)
decklin authored
25 # variable. The ones that don't start with oauth_ are extensions from
26 # one provider or another.
b84db49 @decklin Add some comments and an MIT license
decklin authored
27
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
28 parse_cred() {
4daea5e @decklin Initial commit
decklin authored
29 case "$1" in
30 oauth_consumer_key) oauth_consumer_key="$2";;
31 oauth_consumer_secret) oauth_consumer_secret="$2";;
32 oauth_token) oauth_token="$2";;
33 oauth_token_secret) oauth_token_secret="$2";;
ee7a756 @decklin Read in user_id and screen_name for -e purposes
decklin authored
34 user_id) user_id="$2";;
35 screen_name) screen_name="$2";;
03d1dca @decklin Make Netflix work (big ugly auth URL, no PIN)
decklin authored
36 application_name) application_name="$2";;
4daea5e @decklin Initial commit
decklin authored
37 esac
38 }
39
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
40 # This is incredibly inefficient if printf is not a builtin. I'm not
41 # sure if there's a good way to do it without passing the buck.
4daea5e @decklin Initial commit
decklin authored
42
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
43 url_encode() {
44 string="$1"
45 while [ "$string" ]; do
b5bdade photo vs status issue
rex@Dell authored
46 case "$string" in
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
47 [A-Za-z0-9._~-]*) printf '%c' "$string";;
48 *) printf '%%%X' "'$string";;
49 esac
b5bdade photo vs status issue
rex@Dell authored
50 string="${string#?}"
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
51 done
b5bdade photo vs status issue
rex@Dell authored
52 echo
4daea5e @decklin Initial commit
decklin authored
53 }
54
2b468b1 space and chinese issue fixed.
rex@Dell authored
55 #special for utf-8 Chinese
56 chinese_status()
57 {
58 line="$*"
5fbe53a @zhasm minor
authored
59 if [ `echo "$line" |grep -Po '%26status%3D'` ];then
b5bdade photo vs status issue
rex@Dell authored
60 olds=`echo $line | grep -oP "(?<=status%3D).*$"`
442324c @zhasm minor
authored
61 news=`echo $olds |sed -e "s#%252b#%2520#g" `
b5bdade photo vs status issue
rex@Dell authored
62 result=`echo $line | sed -e "s#$olds#$news#" 2>/dev/null`
63 echo "$result"
64 else
65 echo "$line"
66 fi
2b468b1 space and chinese issue fixed.
rex@Dell authored
67 }
68
4daea5e @decklin Initial commit
decklin authored
69 quote_vals() {
70 sed 's/=\(.*\)/="\1"/'
71 }
72
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
73 echo_pair() {
74 echo "$1=$2"
75 }
76
77 join_params() {
164e951 @decklin BSD portability and factor out unsep
decklin authored
78 paste -s -d '&' - | sed "s/&/$1/g"
4daea5e @decklin Initial commit
decklin authored
79 }
80
11d5e92 @decklin Deal with percent-encoding properly
decklin authored
81 # The first four values come from this script, so they need to be
82 # percent-encoded. (Never mind that e.g. "1.0" is obviously fine... some
83 # day it might be "3.0~beta2".) The others are read in from form-encoded
84 # files or parameters, so they should *not* be encoded again.
85
4daea5e @decklin Initial commit
decklin authored
86 mk_params() {
87 for i in \
88 oauth_version="$(url_encode "1.0")" \
89 oauth_signature_method="$(url_encode "HMAC-SHA1")" \
90 oauth_timestamp="$(url_encode "$oauth_timestamp")" \
91 oauth_nonce="$(url_encode "$oauth_nonce")" \
11d5e92 @decklin Deal with percent-encoding properly
decklin authored
92 oauth_consumer_key="$oauth_consumer_key" \
93 ${oauth_token:+oauth_token="$oauth_token"} \
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
94 $(foreach_query_pair echo_pair "$extra_params") \
95 $(foreach_query_pair echo_pair "$1")
4daea5e @decklin Initial commit
decklin authored
96 do
b5bdade photo vs status issue
rex@Dell authored
97 echo "$i"
4daea5e @decklin Initial commit
decklin authored
98 done | sort
99 }
100
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
101 # This is bad; it leaks the secret on the command line. The right thing
102 # would be to use -passin, but it doesn't seem to affect -hmac.
103
104 hmac_sha1() {
105 printf '%s' "$2" | openssl dgst -sha1 -hmac "$1" -binary | openssl base64
106 }
107
108 # Here's where we start.
109
4daea5e @decklin Initial commit
decklin authored
110 method=GET
111 oauth_timestamp="$(date +%s)"
112 oauth_nonce="$(openssl rand -base64 12)"
113
6f993bc @decklin Add -v option for debugging (prints base string)
decklin authored
114 while getopts 'e:f:p:vu:' OPTION; do
b5bdade photo vs status issue
rex@Dell authored
115 case $OPTION in
a180b23 @decklin Quote! *smacks forehead*
decklin authored
116 e) eval "echo \"$OPTARG\""; exit 0;;
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
117 f) load_cred_file "$OPTARG"; loaded=1;;
4daea5e @decklin Initial commit
decklin authored
118 p) extra_params="$OPTARG";;
b563338 @decklin Remove duplicated code by adding a secret -u option
decklin authored
119 u) echo "$(url_encode "$OPTARG")"; exit 0;;
6f993bc @decklin Add -v option for debugging (prints base string)
decklin authored
120 v) verbose=1;;
44b2f7c @decklin Fix wordage
decklin authored
121 *) echo "Unknown option: $OPTION"; exit 2;;
4daea5e @decklin Initial commit
decklin authored
122 esac
123 done
124 shift $(($OPTIND-1))
125
b84db49 @decklin Add some comments and an MIT license
decklin authored
126 # The remaining args in $@ go directly to curl. Fools that we are, we
127 # attempt to parse them here. Only one URL is supported.
128
4daea5e @decklin Initial commit
decklin authored
129 for i; do
b5bdade photo vs status issue
rex@Dell authored
130 case "$prev" in
131 -d|--data) url_params="$i";;
610a6e1 @decklin Support setting method with -X
decklin authored
132 -X) method="$i";;
4daea5e @decklin Initial commit
decklin authored
133 esac
b5bdade photo vs status issue
rex@Dell authored
134 case "$i" in
168eeb5 @zhasm Curlicue client for Fanfou
authored
135 -d|--data|-F) method=POST;;
4daea5e @decklin Initial commit
decklin authored
136 http*\?*) url="${i%%\?*}"; url_params="${i#*\?}";;
137 http*) url="$i";;
138 esac
b5bdade photo vs status issue
rex@Dell authored
139 prev="$i"
4daea5e @decklin Initial commit
decklin authored
140 done
141
f621254 @decklin Fall back to loading ~/.curlicue/HOST
decklin authored
142 if [ -z "$loaded" ]; then
b5bdade photo vs status issue
rex@Dell authored
143 cropped_url="${url#*://}"
f621254 @decklin Fall back to loading ~/.curlicue/HOST
decklin authored
144 host="${cropped_url%%/*}"
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
145 load_cred_file "$HOME/.curlicue/$host"
f621254 @decklin Fall back to loading ~/.curlicue/HOST
decklin authored
146 fi
147
148 if [ -z "$oauth_consumer_key" ]; then
b5bdade photo vs status issue
rex@Dell authored
149 echo "Couldn't load a consumer key! Exiting." 1>&2
f621254 @decklin Fall back to loading ~/.curlicue/HOST
decklin authored
150 exit 1
151 fi
152
b84db49 @decklin Add some comments and an MIT license
decklin authored
153 # This is where the magic happens.
2b468b1 space and chinese issue fixed.
rex@Dell authored
154 url_params=`echo "$url_params" |sed -e "s# #%20#g" -e"s#\+#%2b#g"`
b5bdade photo vs status issue
rex@Dell authored
155
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
156 params="$(mk_params "$url_params" | join_params '&')"
4daea5e @decklin Initial commit
decklin authored
157 base_string="$method&$(url_encode "$url")&$(url_encode "$params")"
2b468b1 space and chinese issue fixed.
rex@Dell authored
158 base_string=`chinese_status $base_string`
4daea5e @decklin Initial commit
decklin authored
159 signing_key="$oauth_consumer_secret&$oauth_token_secret"
160 oauth_signature="$(hmac_sha1 "$signing_key" "$base_string")"
161 sig_params="oauth_signature=$(url_encode "$oauth_signature")"
f9d1d0d @decklin Better names for functions, less wishy-washy comments
decklin authored
162 auth_header="$(mk_params "$sig_params" | quote_vals | join_params ', ')"
4daea5e @decklin Initial commit
decklin authored
163
6f993bc @decklin Add -v option for debugging (prints base string)
decklin authored
164 if [ "$verbose" ]; then
b5bdade photo vs status issue
rex@Dell authored
165 echo "Base string: $base_string" 1>&2
cad203a @decklin Include OAuth header in verbose output
decklin authored
166 echo "Authorization: OAuth $auth_header" 1>&2
6f993bc @decklin Add -v option for debugging (prints base string)
decklin authored
167 fi
168
1df0648 @zhasm curl -s
authored
169 curl -s -H "Authorization: OAuth $auth_header" "$@"
b5bdade photo vs status issue
rex@Dell authored
170
Something went wrong with that request. Please try again.