Giter Site home page Giter Site logo

req's People

Contributors

danielkrizian avatar flyingoe avatar jonathonmcmurray avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

req's Issues

Make default behaviours more configurable

Make it possible to disable parsing with a flag e.g. .req.PARSE (similar to .req.VERBOSE flag).

Also .req.SIGNAL for controlling signalling if HTTP error response received.

Possibly also allow defining a "custom parse" function that receives headers & body and can do whatever necessary.

Also, for .req.VERBOSE allow defining as an int i.e. a handle to write to, so it's possible to configure this to write to stderr instead of stdout etc. - ensure backwards compatibility, cast booleans to int

Cookie tailmatching

Currently, the reQ cookie functionality will perform "tailmatching" for any cookie received with a Host attribute. For example, if a cookie is received with Host=example.com, it will (and should) match e.g. good.example.com subdomain. However, it will also match badexample.com, which is incorrect.

cURL suffered from a similar bug a few years back: https://daniel.haxx.se/blog/2013/04/15/tailmatching-them-cookies/

Add support for DNS-over-HTTPS

DNS-over-HTTPS provides the functionality to perform DNS lookups over HTTPS rather than in plaintext, giving increased security.

APIs for this are provided by Google and CloudFlare, support should be added for these (disabled by default)

Google: https://developers.google.com/speed/public-dns/docs/dns-over-https#api_specification
CloudFlare: https://developers.cloudflare.com/1.1.1.1/dns-over-https/json-format/

CloudFlare also provide a version accepting & returning DNS wireformat rather than JSON, support for that could also be added: https://developers.cloudflare.com/1.1.1.1/dns-over-https/wireformat/

  • Google JSON
  • CloudFlare JSON
  • CloudFlare wireformat
  • TTL/cache invalidation
  • Fallback to system DNS

RFCs

https://tools.ietf.org/html/rfc7858
https://tools.ietf.org/html/rfc8310
https://tools.ietf.org/html/rfc8484

Move decompression to before display for verbose mode

Currently, decompression (i.e. gzip decompression in kdb 4.0+) happens in .req.parseresp, meaning that verbose mode shows compressed response.

Should be done in .req.send as soon as response is received.

Should also make it simple to plug in additional handlers for different Content-Encoding types, probably via a dictionary of handlers that can be extended by users.

Cache basic authentication credentials

As of 7750c99 reQ supports prompting for Basic auth credentials where server requests them.

In order to prevent re-prompting, reQ should cache the entered credentials for automatic use in future requests

Add caching support

HTTP clients should implement caching as per RFC 7234

The goal of caching in HTTP/1.1 is to significantly improve
performance by reusing a prior response message to satisfy a current
request.

Caching results makes our "requests" faster & reduces load on the server. Should handle Cache-Control & Expires response headers & cache if these are present.

Should also support If-Modified-Since & ETag on HTTP requests, handling the subsequent 304 HTTP status code for unchanged content

  • Define cache in-memory object
  • Cache responses with Cache-Control & Expires headers
  • Detect requests with a cached response & use it
  • If-Modified-Since & ETag support
  • Handle 304 status code

Restructure library into component parts

Separate out separate components (e.g. cookies) into separate q scripts

Create init.q for loading via qutil (.utl.pkg each component) & req.q for loading in vanilla q (\l each component)

  • Separate scripts for each component
  • init.q script
  • req.q script
  • build script - not everyone uses qutil, make an easy to load "monoscript" compiled from others

Ignore case in HTTP response headers

In several places in code (e.g. setting cookies, redirections, content parsing) we rely on response headers having Title-Case - if headers are instead sent lower-case, code doesn't work correctly.

Simple fix is to convert all headers to lower case when received & reference them in this way throughout

"Protocol not available" error over https

First off, thanks so much for the reQ package!

I tried to follow your blog article and get this error when trying https protocol. http works fine.

q).utl.require"req"
q).req.g"https://httpbin.org/get"
'conn. OS reports: Protocol not available
  [2]  /opt/miniconda3/envs/build/q/pkg/req/req.q:164: .req.send:
  d:headers[us;pr;hd;p];                                                            //get dictionary of HTTP headers for request
  r:hs d:buildquery[m;pr;nu;h;d;p];                                                 //build query and execute
    ^
  if[v;-1"-- REQUEST --\n",string[hs],"\n",d];                                      //if verbose, log request
q.req))
q).req.g"http://httpbin.org/get"
args   | (`symbol$())!()
headers| `Accept`Connection`Host`User-Agent!("*/*";"close";"httpbin.org";"kdb..
origin | "208.110.70.170"
url    | "http://httpbin.org/get"

I think I installed all dependencies:

(build) [dk@s110519 /home/dk/conda-pkgs]$ conda list
# packages in environment at /opt/miniconda3/envs/build:
#
# Name                    Version                   Build  Channel
ca-certificates           2018.03.07                    0  
json                      0.1.1                         0    file://opt/channel
q                         3.6                           0    file://opt/channel
qhttps                    0.0.1                         0    local
qlic                      2018.11.25                    0    file://opt/channel
qutil                     3.2.1                         0    file://opt/channel
req                       0.1.2                         0    file://opt/channel

Add support for timeouts

Most HTTP clients implement timeout functionality for slow responding servers. In q, the -T cmd line arg or \T command can set a timeout for remotely executed commands, which we can use to timeout a local command by sending it to ourselves over handle 0 e.g.

q)\T 1
q)0(`.req.g;"http://httpbin.org/delay/10")
'stop
  [2]  /home/jmcmurray/miniconda3/q/packages/req/req.q:164: .req.send:
  d:headers[us;pr;hd;p];                                                            //get dictionary of HTTP headers for request
  r:hs d:buildquery[m;pr;nu;h;d;p];                                                 //build query and execute
    ^
  if[v;-1"-- REQUEST --\n",string[hs],"\n",d];                                      //if verbose, log request
q.req))

As an initial version, I'll implement a wrapper that

(i) sets timeout
(ii) performs request (with error trap) over handle 0
(iii) resets timeout
(iv) signals if timeout was hit

Future rewrites may allow a more sophisticated approach.

Add DELETE functions

Add a set of functions to issue DELETE requests, with projections for no body and no custom header scenarios

.req.hap fails if there is an @ in URL path

For example:

.req.hap"wss://stream.binance.com:9443/ws/btcusdt@depth"
"wss://"
"stream.binance.com:9443/ws/btcusdt"
"depth"
,"/"

host should be stream.binance.com:9443 and path /ws/btcusdt@depth

Record permanent redirects

When 301 status code is received, we need to log that this is a permanent URL change, as opposed to temporary with 302.

So we should keep a record when we receive 301s and automatically substitute replaced URLs in future HTTP requests

  • Record permanent redirects
  • Substitute URLs as necessary in future requests

.req.auth broken on 3.3 and below

With 01ed1d6 backwards compatibility was added for older versions of q (.Q.k>=2.8 tested). However, .req.auth (i.e. base64 encode) was not properly tested and this is broken on .Q.k<=3.3 e.g. on 3.2

λ q req.q
KDB+ 3.2 2015.04.07 Copyright (C) 1993-2015 Kx Systems
w32/ 4()core 4095MB jonat laptop-o8a8co1o 169.254.46.92 NONEXPIRE

q).req.auth "user:pass"
k){x\:y}
'nyi
@
64\:
7697253
q.q))

.req.b64decode is also broken:

q).req.b64decode "aGVsbG8gd29ybGQ="
k){x\:y}
'nyi
@
256\:
6841708
q.q))

Improve usability of .req.post

Currently it's a little cumbersome to pass e.g. a JSON body to a request. We should accept something like

.req.post[url;`json;`a`b`c!1 2 3]

to auto-convert to JSON & put correct Content-Type

Need to consider how it should work with custom headers required as well

Parse URLs without a forward slash before query

Currently, URL parsing splits hostname from path by searching for /

e.g. foo://example.com:8042/over/there?name=ferret

  • here, the path (including query) is /over/there?name=ferret

In rare circumstances, it could be possible that a URL has no "path" but does have a query e.g.

foo://example.com:8042?name=ferret

In current implementation, a / is required before the ? to properly parse the path as /?name=ferret.

Should handle this automatically & insert leading / to path if necessary

Update Advent of Code example to use cookiejar

The current Advent of Code example manually adds the Cookie header to each request, this should be changed to add the cookie to .req.cookiejar and let it be sent automatically with requests

.req.enchd does not accept non-string values

Currently, .req.enchd is broken for non-string values or keys:

q).req.enchd`abc`def!("abc";"def")
'type
  [1]  /home/jmcmurray/git/reQ/req.q:113: .req.enchd:
  /* convert KDB dictionary to HTTP headers */
  :("\r\n" sv ": " sv/:flip (key;value)@\:d),"\r\n\r\n";                            //encode headers dict to HTTP headers
                     ^
 }
q.req))\
q).req.enchd("abc";"def")!"ab"
'type
  [1]  /home/jmcmurray/git/reQ/req.q:113: .req.enchd:
  /* convert KDB dictionary to HTTP headers */
  :("\r\n" sv ": " sv/:flip (key;value)@\:d),"\r\n\r\n";                            //encode headers dict to HTTP headers
                     ^
 }
q.req))\
q).req.enchd("abc";"def")!1 2
'type
  [1]  /home/jmcmurray/git/reQ/req.q:113: .req.enchd:
  /* convert KDB dictionary to HTTP headers */
  :("\r\n" sv ": " sv/:flip (key;value)@\:d),"\r\n\r\n";                            //encode headers dict to HTTP headers
                     ^
 }
q.req))

All of these should work, with keys/values being converted to strings if necessary

Currently keys will be converted in .req.headers if all keys are symbols (which should never happen given default headers are specified in .req.def with string keys)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.