2748 |
2755 |
2749 eread <X> |
2756 eread <X> |
2750 --------- |
2757 --------- |
2751 |
2758 |
2752 ``read()`` N bytes from the server's stderr pipe, if available. |
2759 ``read()`` N bytes from the server's stderr pipe, if available. |
|
2760 |
|
2761 Specifying Unified Frame-Based Protocol Frames |
|
2762 ---------------------------------------------- |
|
2763 |
|
2764 It is possible to emit a *Unified Frame-Based Protocol* by using special |
|
2765 syntax. |
|
2766 |
|
2767 A frame is composed as a type, flags, and payload. These can be parsed |
|
2768 from a string of the form ``<type> <flags> <payload>``. That is, 3 |
|
2769 space-delimited strings. |
|
2770 |
|
2771 ``payload`` is the simplest: it is evaluated as a Python byte string |
|
2772 literal. |
|
2773 |
|
2774 ``type`` can be an integer value for the frame type or the string name |
|
2775 of the type. The strings are defined in ``wireprotoframing.py``. e.g. |
|
2776 ``command-name``. |
|
2777 |
|
2778 ``flags`` is a ``|`` delimited list of flag components. Each component |
|
2779 (and there can be just one) can be an integer or a flag name for the |
|
2780 specified frame type. Values are resolved to integers and then bitwise |
|
2781 OR'd together. |
2753 """ |
2782 """ |
2754 opts = pycompat.byteskwargs(opts) |
2783 opts = pycompat.byteskwargs(opts) |
2755 |
2784 |
2756 if opts['localssh'] and not repo: |
2785 if opts['localssh'] and not repo: |
2757 raise error.Abort(_('--localssh requires a repository')) |
2786 raise error.Abort(_('--localssh requires a repository')) |
2951 '"httprequest <method> <path>')) |
2980 '"httprequest <method> <path>')) |
2952 |
2981 |
2953 method, httppath = request[1:] |
2982 method, httppath = request[1:] |
2954 headers = {} |
2983 headers = {} |
2955 body = None |
2984 body = None |
|
2985 frames = [] |
2956 for line in lines: |
2986 for line in lines: |
2957 line = line.lstrip() |
2987 line = line.lstrip() |
2958 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line) |
2988 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line) |
2959 if m: |
2989 if m: |
2960 headers[m.group(1)] = m.group(2) |
2990 headers[m.group(1)] = m.group(2) |
2961 continue |
2991 continue |
2962 |
2992 |
2963 if line.startswith(b'BODYFILE '): |
2993 if line.startswith(b'BODYFILE '): |
2964 with open(line.split(b' ', 1), 'rb') as fh: |
2994 with open(line.split(b' ', 1), 'rb') as fh: |
2965 body = fh.read() |
2995 body = fh.read() |
|
2996 elif line.startswith(b'frame '): |
|
2997 frame = wireprotoframing.makeframefromhumanstring( |
|
2998 line[len(b'frame '):]) |
|
2999 |
|
3000 frames.append(frame) |
2966 else: |
3001 else: |
2967 raise error.Abort(_('unknown argument to httprequest: %s') % |
3002 raise error.Abort(_('unknown argument to httprequest: %s') % |
2968 line) |
3003 line) |
2969 |
3004 |
2970 url = path + httppath |
3005 url = path + httppath |
|
3006 |
|
3007 if frames: |
|
3008 body = b''.join(bytes(f) for f in frames) |
|
3009 |
2971 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers) |
3010 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers) |
2972 |
3011 |
2973 # urllib.Request insists on using has_data() as a proxy for |
3012 # urllib.Request insists on using has_data() as a proxy for |
2974 # determining the request method. Override that to use our |
3013 # determining the request method. Override that to use our |
2975 # explicitly requested method. |
3014 # explicitly requested method. |