11# SPDX-License-Identifier: AGPL-3.0-only
2- import httpclient, asyncdispatch, options, strutils, uri
3- import jsony, packedjson, zippy
2+ import httpclient, asyncdispatch, options, strutils, uri, times, math
3+ import jsony, packedjson, zippy, oauth1
44import types, tokens, consts, parserutils, http_pool
55import experimental/ types/ common
66
@@ -29,12 +29,30 @@ proc genParams*(pars: openArray[(string, string)] = @[]; cursor="";
2929 else :
3030 result &= (" cursor" , cursor)
3131
32- proc genHeaders * (token: Token = nil ): HttpHeaders =
32+ proc getOauthHeader (url, oauthToken, oauthTokenSecret: string ): string =
33+ let
34+ encodedUrl = url.replace (" ," , " %2C" ).replace (" +" , " %20" )
35+ params = OAuth1Parameters (
36+ consumerKey: consumerKey,
37+ signatureMethod: " HMAC-SHA1" ,
38+ timestamp: $ int (round (epochTime ())),
39+ nonce: " 0" ,
40+ isIncludeVersionToHeader: true ,
41+ token: oauthToken
42+ )
43+ signature = getSignature (HttpGet , encodedUrl, " " , params, consumerSecret, oauthTokenSecret)
44+
45+ params.signature = percentEncode (signature)
46+
47+ return getOauth1RequestHeader (params)[" authorization" ]
48+
49+ proc genHeaders * (url, oauthToken, oauthTokenSecret: string ): HttpHeaders =
50+ let header = getOauthHeader (url, oauthToken, oauthTokenSecret)
51+
3352 result = newHttpHeaders ({
3453 " connection" : " keep-alive" ,
35- " authorization" : auth ,
54+ " authorization" : header ,
3655 " content-type" : " application/json" ,
37- " x-guest-token" : if token == nil : " " else : token.tok,
3856 " x-twitter-active-user" : " yes" ,
3957 " authority" : " api.twitter.com" ,
4058 " accept-encoding" : " gzip" ,
@@ -43,24 +61,24 @@ proc genHeaders*(token: Token = nil): HttpHeaders =
4361 " DNT" : " 1"
4462 })
4563
46- template updateToken () =
64+ template updateAccount () =
4765 if resp.headers.hasKey (rlRemaining):
4866 let
4967 remaining = parseInt (resp.headers[rlRemaining])
5068 reset = parseInt (resp.headers[rlReset])
51- token .setRateLimit (api, remaining, reset)
69+ account .setRateLimit (api, remaining, reset)
5270
5371template fetchImpl (result, fetchBody) {.dirty .} =
5472 once:
5573 pool = HttpPool ()
5674
57- var token = await getToken (api)
58- if token.tok .len == 0 :
75+ var account = await getGuestAccount (api)
76+ if account.oauthToken .len == 0 :
5977 raise rateLimitError ()
6078
6179 try :
6280 var resp: AsyncResponse
63- pool.use (genHeaders (token )):
81+ pool.use (genHeaders ($ url, account.oauthToken, account.oauthSecret )):
6482 template getContent =
6583 resp = await c.get ($ url)
6684 result = await resp.body
@@ -79,19 +97,19 @@ template fetchImpl(result, fetchBody) {.dirty.} =
7997
8098 fetchBody
8199
82- release (token , used= true )
100+ release (account , used= true )
83101
84102 if resp.status == $ Http400 :
85103 raise newException (InternalError , $ url)
86104 except InternalError as e:
87105 raise e
88106 except BadClientError as e:
89- release (token , used= true )
107+ release (account , used= true )
90108 raise e
91109 except Exception as e:
92- echo " error: " , e.name, " , msg: " , e.msg, " , token : " , token[] , " , url: " , url
110+ echo " error: " , e.name, " , msg: " , e.msg, " , accountId : " , account.id , " , url: " , url
93111 if " length" notin e.msg and " descriptor" notin e.msg:
94- release (token , invalid= true )
112+ release (account , invalid= true )
95113 raise rateLimitError ()
96114
97115proc fetch * (url: Uri ; api: Api ): Future [JsonNode ] {.async .} =
@@ -103,12 +121,12 @@ proc fetch*(url: Uri; api: Api): Future[JsonNode] {.async.} =
103121 echo resp.status, " : " , body, " --- url: " , url
104122 result = newJNull ()
105123
106- updateToken ()
124+ updateAccount ()
107125
108126 let error = result .getError
109127 if error in {invalidToken, badToken}:
110128 echo " fetch error: " , result .getError
111- release (token , invalid= true )
129+ release (account , invalid= true )
112130 raise rateLimitError ()
113131
114132proc fetchRaw * (url: Uri ; api: Api ): Future [string ] {.async .} =
@@ -117,11 +135,11 @@ proc fetchRaw*(url: Uri; api: Api): Future[string] {.async.} =
117135 echo resp.status, " : " , result , " --- url: " , url
118136 result .setLen (0 )
119137
120- updateToken ()
138+ updateAccount ()
121139
122140 if result .startsWith (" {\" errors" ):
123141 let errors = result .fromJson (Errors )
124142 if errors in {invalidToken, badToken}:
125143 echo " fetch error: " , errors
126- release (token , invalid= true )
144+ release (account , invalid= true )
127145 raise rateLimitError ()
0 commit comments