Hello Dan Kenigsberg,

I'd like you to do a code review.  Please visit

    http://gerrit.ovirt.org/29553

to review the following change.

Change subject: core: GET requests - use Range header
......................................................................

core: GET requests - use Range header

This patch replaces the use of the custom Size header with use of http
Range header.
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35)
Note that the use is similar to the use that was done with the Size header.
The motivation is to use the standard http header (instead of supporting a
custom header) and not to fully comply with the spec (as there are existing
gaps).

After this change the Range header is mandatory to issue a get request for an
image and support ranges between zero and specified last byte position.

Change-Id: I8164867347b1cf800efd2a78cc98dbc10c02ee0d
Signed-off-by: Liron Aravot <[email protected]>
Reviewed-on: http://gerrit.ovirt.org/28465
Reviewed-by: Dan Kenigsberg <[email protected]>
Tested-by: Dan Kenigsberg <[email protected]>
---
M vdsm/rpc/BindingXMLRPC.py
1 file changed, 29 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/53/29553/1

diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py
index c1c7490..e944993 100644
--- a/vdsm/rpc/BindingXMLRPC.py
+++ b/vdsm/rpc/BindingXMLRPC.py
@@ -24,6 +24,7 @@
 import logging
 import libvirt
 import threading
+import re
 import sys
 
 from vdsm import utils
@@ -101,9 +102,10 @@
             HEADER_IMAGE = 'Image-Id'
             HEADER_VOLUME = 'Volume-Id'
             HEADER_TASK_ID = 'Task-Id'
-            HEADER_SIZE = 'Size'
+            HEADER_RANGE = 'Range'
             HEADER_CONTENT_LENGTH = 'content-length'
             HEADER_CONTENT_TYPE = 'content-type'
+            HEADER_CONTENT_RANGE = 'content-range'
 
             class RequestException():
                 def __init__(self, httpStatusCode, errorMessage):
@@ -117,8 +119,7 @@
 
             def do_GET(self):
                 try:
-                    length = self._getIntHeader(self.HEADER_SIZE,
-                                                httplib.BAD_REQUEST)
+                    length = self._getLength()
                     img = self._createImage()
                     startEvent = threading.Event()
                     methodArgs = {'fileObj': self.wfile,
@@ -135,10 +136,12 @@
                                                   startEvent, volUUID)
 
                     if response['status']['code'] == 0:
-                        self.send_response(httplib.OK)
+                        self.send_response(httplib.PARTIAL_CONTENT)
                         self.send_header(self.HEADER_CONTENT_TYPE,
                                          'application/octet-stream')
                         self.send_header(self.HEADER_CONTENT_LENGTH, length)
+                        self.send_header(self.HEADER_CONTENT_RANGE,
+                                         "bytes 0-%d" % (length - 1))
                         self.send_header(self.HEADER_TASK_ID, response['uuid'])
                         self.end_headers()
                         startEvent.set()
@@ -220,21 +223,40 @@
                     event.wait()
 
             def _getIntHeader(self, headerName, missingError):
+                value = self._getRequiredHeader(headerName, missingError)
+
+                return self._getInt(value)
+
+            def _getRequiredHeader(self, headerName, missingError):
                 value = self.headers.getheader(
                     headerName)
                 if not value:
                     raise self.RequestException(
                         missingError,
                         "missing header %s" % headerName)
+                return value
 
+            def _getInt(self, value):
                 try:
-                    value = int(value)
+                    return int(value)
                 except ValueError:
                     raise self.RequestException(
                         httplib.BAD_REQUEST,
-                        "invalid header value %r" % value)
+                        "not int value %r" % value)
 
-                return value
+            def _getLength(self):
+                value = self._getRequiredHeader(self.HEADER_RANGE,
+                                                httplib.BAD_REQUEST)
+
+                m = re.match(r'^bytes=0-(\d+)$', value)
+                if m is None:
+                    raise self.RequestException(
+                        httplib.BAD_REQUEST,
+                        "Unsupported range: %r , expected: bytes=0-last_byte" %
+                        value)
+
+                last_byte = m.group(1)
+                return self._getInt(last_byte) + 1
 
             def send_error(self, error, message, exc_info=False):
                 try:


-- 
To view, visit http://gerrit.ovirt.org/29553
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8164867347b1cf800efd2a78cc98dbc10c02ee0d
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.5
Gerrit-Owner: Liron Aravot <[email protected]>
Gerrit-Reviewer: Dan Kenigsberg <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to