Class: Winhttp::Request

Inherits:
Object
  • Object
show all
Defined in:
ext/winhttp/winhttp.c

Instance Method Summary collapse

Instance Method Details

#_abortObject

Request#_abort / #_finish — WinHttpCloseHandle(hreq), idempotent. Teardown is async; the pump's EV_CLOSING settles os_done + the connect handle.



921
922
923
924
925
926
927
928
929
930
# File 'ext/winhttp/winhttp.c', line 921

static VALUE
req_abort(VALUE self)
{
    whreq *r = req_ptr(self);
    if (r && !r->handles_closed && r->hreq) {
        WinHttpCloseHandle(r->hreq);
        r->handles_closed = 1;
    }
    return Qnil;
}

#_finishObject

Request#_abort / #_finish — WinHttpCloseHandle(hreq), idempotent. Teardown is async; the pump's EV_CLOSING settles os_done + the connect handle.



921
922
923
924
925
926
927
928
929
930
# File 'ext/winhttp/winhttp.c', line 921

static VALUE
req_abort(VALUE self)
{
    whreq *r = req_ptr(self);
    if (r && !r->handles_closed && r->hreq) {
        WinHttpCloseHandle(r->hreq);
        r->handles_closed = 1;
    }
    return Qnil;
}

#_headersObject

Query a raw-headers / status / url / protocol bundle, GVL held. Returns [status(Integer), raw_headers(String UTF-8), final_url(String), http2(bool)].



854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
# File 'ext/winhttp/winhttp.c', line 854

static VALUE
req_headers(VALUE self)
{
    whreq *r = req_live(self);
    DWORD status = 0, size = 0, gle;
    DWORD idx = 0; /* WINHTTP_NO_HEADER_INDEX is NULL; we pass &idx, reset per call */
    VALUE raw, url, ret;
    WCHAR *buf;
    DWORD proto = 0, psz = sizeof(proto);

    /* status code (numeric) */
    size = sizeof(status);
    if (!WinHttpQueryHeaders(r->hreq,
                             WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
                             WINHTTP_HEADER_NAME_BY_INDEX, &status, &size, &idx)) {
        gle = GetLastError();
        raise_code(class_for_code(gle), "WinHttpQueryHeaders(STATUS_CODE)", gle);
    }

    /* raw headers (CRLF) — two-call size pattern */
    size = 0; idx = 0;
    WinHttpQueryHeaders(r->hreq, WINHTTP_QUERY_RAW_HEADERS_CRLF,
                        WINHTTP_HEADER_NAME_BY_INDEX, NULL, &size, &idx);
    gle = GetLastError();
    if (gle != ERROR_INSUFFICIENT_BUFFER && size == 0) {
        raise_code(class_for_code(gle), "WinHttpQueryHeaders(RAW_HEADERS)", gle);
    }
    buf = (WCHAR *)xmalloc(size + sizeof(WCHAR));
    idx = 0;
    if (!WinHttpQueryHeaders(r->hreq, WINHTTP_QUERY_RAW_HEADERS_CRLF,
                             WINHTTP_HEADER_NAME_BY_INDEX, buf, &size, &idx)) {
        gle = GetLastError();
        xfree(buf);
        raise_code(class_for_code(gle), "WinHttpQueryHeaders(RAW_HEADERS)", gle);
    }
    raw = wide_to_str(buf, (int)(size / sizeof(WCHAR)));
    xfree(buf);

    /* final URL (after redirects) — two-call size pattern */
    size = 0;
    WinHttpQueryOption(r->hreq, WINHTTP_OPTION_URL, NULL, &size);
    if (size == 0) {
        url = rb_utf8_str_new("", 0);
    } else {
        buf = (WCHAR *)xmalloc(size + sizeof(WCHAR));
        if (!WinHttpQueryOption(r->hreq, WINHTTP_OPTION_URL, buf, &size)) {
            xfree(buf);
            url = rb_utf8_str_new("", 0);
        } else {
            url = wide_to_str(buf, -1);
            xfree(buf);
        }
    }

    /* protocol used (best-effort; 0 on failure) */
    if (!WinHttpQueryOption(r->hreq, WINHTTP_OPTION_HTTP_PROTOCOL_USED,
                            &proto, &psz)) {
        proto = 0;
    }

    ret = rb_ary_new3(4, UINT2NUM(status), raw, url,
                      (proto & WINHTTP_PROTOCOL_FLAG_HTTP2) ? Qtrue : Qfalse);
    return ret;
}

#_read_startObject



826
827
828
829
830
831
832
833
834
835
# File 'ext/winhttp/winhttp.c', line 826

static VALUE
req_read_start(VALUE self)
{
    whreq *r = req_live(self);
    if (!WinHttpReadData(r->hreq, r->rbuf, RBUF_CAP, NULL)) {
        DWORD gle = GetLastError();
        raise_code(class_for_code(gle), "WinHttpReadData", gle);
    }
    return Qnil;
}

#_read_take(vn) ⇒ Object

Request#_read_take(n) -> fresh ASCII-8BIT String of the first n bytes.



838
839
840
841
842
843
844
845
846
847
848
849
# File 'ext/winhttp/winhttp.c', line 838

static VALUE
req_read_take(VALUE self, VALUE vn)
{
    whreq *r = req_live(self);
    long n = (long)NUM2LL(vn);
    VALUE out;
    if (n < 0) n = 0;
    if (n > RBUF_CAP) n = RBUF_CAP;
    out = rb_str_new((const char *)r->rbuf, n);
    rb_enc_associate(out, rb_ascii8bit_encoding());
    return out;
}

#_receiveObject



815
816
817
818
819
820
821
822
823
824
# File 'ext/winhttp/winhttp.c', line 815

static VALUE
req_receive(VALUE self)
{
    whreq *r = req_live(self);
    if (!WinHttpReceiveResponse(r->hreq, NULL)) {
        DWORD gle = GetLastError();
        raise_code(class_for_code(gle), "WinHttpReceiveResponse", gle);
    }
    return Qnil;
}

#_sendObject

Request#_send — WinHttpSendRequest (async). Immediate FALSE => no callback, raise now.



800
801
802
803
804
805
806
807
808
809
810
811
812
813
# File 'ext/winhttp/winhttp.c', line 800

static VALUE
req_send(VALUE self)
{
    whreq *r = req_live(self);
    DWORD_PTR ctxv = (DWORD_PTR)r->id;
    LPVOID body = r->body ? (LPVOID)r->body : WINHTTP_NO_REQUEST_DATA;
    DWORD blen = (DWORD)r->body_len;
    if (!WinHttpSendRequest(r->hreq, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                            body, blen, blen, ctxv)) {
        DWORD gle = GetLastError();
        raise_code(class_for_code(gle), "WinHttpSendRequest", gle);
    }
    return Qnil;
}