)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"2b5e3b07f84f7d74369e820c605fc2211d2a3b78","unresolved":false,"context_lines":[{"line_number":20,"context_line":"   requesting download of range of bytes 10 to 50 bytes when there are only 48"},{"line_number":21,"context_line":"   bytes), status code is set to 416 and HTTPRequestRangeNotSatisfiable is"},{"line_number":22,"context_line":"   raised."},{"line_number":23,"context_line":" * If the content range is valid, but the request is not satisfiable due to"},{"line_number":24,"context_line":"   glance_store side erros or privacy issues, appropriate exceptions are"},{"line_number":25,"context_line":"   raised but content range set to the requested range that was valid."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Change-Id: I3cd47b998be79604511b3cd4879209820cf776b7"},{"line_number":28,"context_line":"Closes-Bug: #1417069"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7a8ec9b2_aac1c430","line":25,"range":{"start_line":23,"start_character":1,"end_line":25,"end_character":70},"updated":"2016-09-13 23:45:25.000000000","message":"I don\u0027t believe that\u0027s the case. Based on my understanding of the code, if an exception is raised, the content-length header will not be set.","commit_id":"63dbba5e11d36aab331279d822f4667f2667e7d6"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"d3fe7577a1d186086091fa76b19caf0997abc894","unresolved":false,"context_lines":[{"line_number":20,"context_line":"   requesting download of range of bytes 10 to 50 bytes when there are only 48"},{"line_number":21,"context_line":"   bytes), status code is set to 416 and HTTPRequestRangeNotSatisfiable is"},{"line_number":22,"context_line":"   raised."},{"line_number":23,"context_line":" * If the content range is valid, but the request is not satisfiable due to"},{"line_number":24,"context_line":"   glance_store side erros or privacy issues, appropriate exceptions are"},{"line_number":25,"context_line":"   raised but content range set to the requested range that was valid."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Change-Id: I3cd47b998be79604511b3cd4879209820cf776b7"},{"line_number":28,"context_line":"Closes-Bug: #1417069"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7a8ec9b2_aa4624bd","line":25,"range":{"start_line":23,"start_character":1,"end_line":25,"end_character":70},"in_reply_to":"7a8ec9b2_aac1c430","updated":"2016-09-13 23:50:30.000000000","message":"My bad. Thanks for pointing it out Alex.","commit_id":"63dbba5e11d36aab331279d822f4667f2667e7d6"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Handling HTTP range requests in Glance"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Currently Glance does not send Partial response codes while"},{"line_number":10,"context_line":"handling HTTP range requests. Also, content length is not"},{"line_number":11,"context_line":"appropriately set."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"7a8ec9b2_66349bfb","line":9,"range":{"start_line":9,"start_character":31,"end_line":9,"end_character":53},"updated":"2016-09-16 22:13:10.000000000","message":"for example?","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":11,"context_line":"appropriately set."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch is to send partial response code and to set the correct"},{"line_number":14,"context_line":"content length based on the range request for image download."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Upon success status code 206 is sent and the content length is set to the"},{"line_number":17,"context_line":"requested range."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"7a8ec9b2_a63a23e5","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":14},"updated":"2016-09-16 22:13:10.000000000","message":"it is supposed to be:\n\n\"Content-Length\" header","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":17,"context_line":"requested range."},{"line_number":18,"context_line":"Upon failure, there can be 2 cases:"},{"line_number":19,"context_line":" * If the HTTP range request for the image download is bad (For example,"},{"line_number":20,"context_line":"   requesting download of range of bytes 10 to 50 bytes when there are only 48"},{"line_number":21,"context_line":"   bytes), status code is set to 416 and HTTPRequestRangeNotSatisfiable is"},{"line_number":22,"context_line":"   raised."},{"line_number":23,"context_line":" * If the content range is valid, but the request is not satisfiable due to"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"7a8ec9b2_81027108","line":20,"range":{"start_line":20,"start_character":71,"end_line":20,"end_character":75},"updated":"2016-09-16 22:13:10.000000000","message":"have you editor auto wrap at 72 for git commit messages","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":20,"context_line":"   requesting download of range of bytes 10 to 50 bytes when there are only 48"},{"line_number":21,"context_line":"   bytes), status code is set to 416 and HTTPRequestRangeNotSatisfiable is"},{"line_number":22,"context_line":"   raised."},{"line_number":23,"context_line":" * If the content range is valid, but the request is not satisfiable due to"},{"line_number":24,"context_line":"   glance_store side erros or privacy issues, appropriate exceptions are"},{"line_number":25,"context_line":"   raised."},{"line_number":26,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"7a8ec9b2_e12255a2","line":23,"range":{"start_line":23,"start_character":10,"end_line":23,"end_character":23},"updated":"2016-09-16 22:13:10.000000000","message":"\"Content-Range\" header value","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":21,"context_line":"   bytes), status code is set to 416 and HTTPRequestRangeNotSatisfiable is"},{"line_number":22,"context_line":"   raised."},{"line_number":23,"context_line":" * If the content range is valid, but the request is not satisfiable due to"},{"line_number":24,"context_line":"   glance_store side erros or privacy issues, appropriate exceptions are"},{"line_number":25,"context_line":"   raised."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Change-Id: I3cd47b998be79604511b3cd4879209820cf776b7"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"7a8ec9b2_a153ed15","line":24,"range":{"start_line":24,"start_character":16,"end_line":24,"end_character":44},"updated":"2016-09-16 22:13:10.000000000","message":"and lack of capability","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"60e26d9c2051d3aa6256e311d132c2767acd4fea","unresolved":false,"context_lines":[{"line_number":27,"context_line":"Change-Id: I3cd47b998be79604511b3cd4879209820cf776b7"},{"line_number":28,"context_line":"Closes-Bug: #1417069"},{"line_number":29,"context_line":"Closes-Bug: #1624508"},{"line_number":30,"context_line":"Related-Bug: #1399851"},{"line_number":31,"context_line":"Related-Bug: #1618928"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"7a8ec9b2_c1f2b905","line":31,"range":{"start_line":30,"start_character":0,"end_line":31,"end_character":21},"updated":"2016-09-16 22:15:15.000000000","message":"can you comment on the bug why your fix is \"Related\" and not complete (Closes)?","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"}],"glance/api/v2/image_data.py":[{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"cf7e7069cb99ed5d72e076ce0e76ac6bd59ecce5","unresolved":false,"context_lines":[{"line_number":282,"context_line":"    def download(self, response, image):"},{"line_number":283,"context_line":"        offset, chunk_size \u003d 0, None"},{"line_number":284,"context_line":"        range_val \u003d response.request.get_content_range()"},{"line_number":285,"context_line":"        if range_val:"},{"line_number":286,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":287,"context_line":"            # and stop, will be None."},{"line_number":288,"context_line":"            if range_val.start is not None:"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_03eab3da","line":285,"range":{"start_line":285,"start_character":11,"end_line":285,"end_character":20},"updated":"2016-09-08 20:00:25.000000000","message":"I\u0027m wondering if it\u0027s appropriate to add sanity validation to range_val here?","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"b4eca9d7e4857468bd7380ece4829581120488e4","unresolved":false,"context_lines":[{"line_number":282,"context_line":"    def download(self, response, image):"},{"line_number":283,"context_line":"        offset, chunk_size \u003d 0, None"},{"line_number":284,"context_line":"        range_val \u003d response.request.get_content_range()"},{"line_number":285,"context_line":"        if range_val:"},{"line_number":286,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":287,"context_line":"            # and stop, will be None."},{"line_number":288,"context_line":"            if range_val.start is not None:"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a8ec9b2_1e776dd5","line":285,"range":{"start_line":285,"start_character":11,"end_line":285,"end_character":20},"in_reply_to":"9a89bdaa_03eab3da","updated":"2016-09-13 19:23:29.000000000","message":"It looks like no additional validation is needed here.","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"cf7e7069cb99ed5d72e076ce0e76ac6bd59ecce5","unresolved":false,"context_lines":[{"line_number":308,"context_line":"            flag \u003d 0"},{"line_number":309,"context_line":"            if range_val:"},{"line_number":310,"context_line":"                # Return satisfiable range and pass with 206"},{"line_number":311,"context_line":"                for c in range(chunk_size, -1, -1):"},{"line_number":312,"context_line":"                    try:"},{"line_number":313,"context_line":"                        response.app_iter \u003d iter(image.get_data(offset\u003doffset,"},{"line_number":314,"context_line":"                                                 chunk_size\u003dc))"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_e3a6af0d","line":311,"range":{"start_line":311,"start_character":43,"end_line":311,"end_character":45},"updated":"2016-09-08 20:00:25.000000000","message":"are you really intending to try a chunk size of -1 on the last iteration here?","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"cf7e7069cb99ed5d72e076ce0e76ac6bd59ecce5","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                        response.headers[\u0027Content-Length\u0027] \u003d str(c)"},{"line_number":318,"context_line":"                        break"},{"line_number":319,"context_line":"                    except Exception:"},{"line_number":320,"context_line":"                        # NOTE(dharinic): 416 gets translated and the"},{"line_number":321,"context_line":"                        # appropriate exception is raised; Hence, continue."},{"line_number":322,"context_line":"                        response.status_int \u003d 416"},{"line_number":323,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_83dfa30b","line":320,"range":{"start_line":320,"start_character":41,"end_line":320,"end_character":45},"updated":"2016-09-08 20:00:25.000000000","message":"Have you tried throwing webob.exc.HTTPRequestRangeNotSatisfiable directly?","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"c66f6318695bac27970d3595384a863c8a32046f","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                        response.headers[\u0027Content-Length\u0027] \u003d str(c)"},{"line_number":318,"context_line":"                        break"},{"line_number":319,"context_line":"                    except Exception:"},{"line_number":320,"context_line":"                        # NOTE(dharinic): 416 gets translated and the"},{"line_number":321,"context_line":"                        # appropriate exception is raised; Hence, continue."},{"line_number":322,"context_line":"                        response.status_int \u003d 416"},{"line_number":323,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a8ec9b2_cab530d1","line":320,"range":{"start_line":320,"start_character":41,"end_line":320,"end_character":45},"in_reply_to":"7a8ec9b2_0d49fd8b","updated":"2016-09-13 23:43:16.000000000","message":"Done","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"b4eca9d7e4857468bd7380ece4829581120488e4","unresolved":false,"context_lines":[{"line_number":317,"context_line":"                        response.headers[\u0027Content-Length\u0027] \u003d str(c)"},{"line_number":318,"context_line":"                        break"},{"line_number":319,"context_line":"                    except Exception:"},{"line_number":320,"context_line":"                        # NOTE(dharinic): 416 gets translated and the"},{"line_number":321,"context_line":"                        # appropriate exception is raised; Hence, continue."},{"line_number":322,"context_line":"                        response.status_int \u003d 416"},{"line_number":323,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a8ec9b2_0d49fd8b","line":320,"range":{"start_line":320,"start_character":41,"end_line":320,"end_character":45},"in_reply_to":"9a89bdaa_83dfa30b","updated":"2016-09-13 19:23:29.000000000","message":"+1","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"cf7e7069cb99ed5d72e076ce0e76ac6bd59ecce5","unresolved":false,"context_lines":[{"line_number":320,"context_line":"                        # NOTE(dharinic): 416 gets translated and the"},{"line_number":321,"context_line":"                        # appropriate exception is raised; Hence, continue."},{"line_number":322,"context_line":"                        response.status_int \u003d 416"},{"line_number":323,"context_line":"                        continue"},{"line_number":324,"context_line":"            if flag !\u003d 1:"},{"line_number":325,"context_line":"                if isinstance(e, glance_store.NotFound):"},{"line_number":326,"context_line":"                    raise webob.exc.HTTPNoContent(explanation\u003de.msg)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a89bdaa_c3552bfa","line":323,"range":{"start_line":323,"start_character":24,"end_line":323,"end_character":32},"updated":"2016-09-08 20:00:25.000000000","message":"Technically don\u0027t need this \u0027continue\u0027 statement","commit_id":"84a8de7a26a60dbf5ab7e394c44f2c42e6628f47"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d611cc5c952b48f22b2a5d81ff56dbc1e65f38c0","unresolved":false,"context_lines":[{"line_number":290,"context_line":"                offset \u003d range_val.start"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"            if range_val.stop is not None:"},{"line_number":293,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_cda44059","side":"PARENT","line":293,"updated":"2016-09-14 15:23:02.000000000","message":"if range_val.stop *is* None, then chunk_size will be equal to None, and we will not get the right Content-Length at line 329.","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"87a286b7933c42f7b40fff18ba1be06633e27d95","unresolved":false,"context_lines":[{"line_number":290,"context_line":"                offset \u003d range_val.start"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"            if range_val.stop is not None:"},{"line_number":293,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_fa323ef1","side":"PARENT","line":293,"in_reply_to":"7a8ec9b2_0c5ff8e5","updated":"2016-09-15 23:41:24.000000000","message":"Did some digging on this.. The if conditions are required here as presence of range_val could mean 2 things here.\n\n1. Strictly both range_val.start and range_val.stop being present. doc reference: [1] or\n\n2. The request being of the format example: \"bytes: */32\". Here range_val would be returned from glance/common/wsgi.py, but range_val.start and range_val.stop would be None.\nHence the need to retain the conditional checks and add an else condition to make sure chunk_size is set here in order to get the correct content-length.\nAlso, we cannot set chunk_size to image.size before get_data (line 308) cos  chunk_size of None means full image download in get_data with the iter method. \n\n[1] http://docs.webob.org/en/stable/api/webob.html#webob.byterange.ContentRange","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"555ba391adb19f0c370cb39c111356df65219ed3","unresolved":false,"context_lines":[{"line_number":290,"context_line":"                offset \u003d range_val.start"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"            if range_val.stop is not None:"},{"line_number":293,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_0c5ff8e5","side":"PARENT","line":293,"in_reply_to":"7a8ec9b2_5f40cfa5","updated":"2016-09-14 19:12:23.000000000","message":"@Alex\nI think, line 288 returns a valid range if present, raises an exception if the range is present but is malformed.\nHowever, there could be a case where the range is present and is a valid range but, the start and stop may be None. (See [1] calling the parse method  of the webob ContentRange class explained in [2])\n\nSo I think, we need to retain the if conditions for checking if the range has a start and stop.  Let me know what you think.\n\n[1]: https://github.com/openstack/glance/blob/master/glance/common/wsgi.py#L979\n[2] http://docs.webob.org/en/stable/api/webob.html#webob.byterange.ContentRange \n\n@Cyril, ack. Working on it. Thank you. :)","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"4b5463865f2df9509caec9be74499a994d9d4944","unresolved":false,"context_lines":[{"line_number":290,"context_line":"                offset \u003d range_val.start"},{"line_number":291,"context_line":""},{"line_number":292,"context_line":"            if range_val.stop is not None:"},{"line_number":293,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_5f40cfa5","side":"PARENT","line":293,"in_reply_to":"7a8ec9b2_cda44059","updated":"2016-09-14 16:34:58.000000000","message":"Based on line 288 and flapper87\u0027s comment on line 294, I think we\u0027re guaranteed to not have a malformed range. So we should probably re-factor this logic to take advantage of that. My suggestion:\n\nif range_val:\n    try:\n        offset \u003d range_val.start\n        chunk_size \u003d range_val.stop - offset\n    except KeyError: # sanity check\n        raise webob.exc.HTTPBadRequest\nelse:\n    chunk_size \u003d image.size\n\nThen, line 329 becomes simply:\nresponse.headers[\u0027Content-Length\u0027] \u003d str(chunk_size)","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d611cc5c952b48f22b2a5d81ff56dbc1e65f38c0","unresolved":false,"context_lines":[{"line_number":316,"context_line":"        if image.checksum:"},{"line_number":317,"context_line":"            response.headers[\u0027Content-MD5\u0027] \u003d image.checksum"},{"line_number":318,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":319,"context_line":"        # content-length"},{"line_number":320,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(image.size)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def upload(self, response, result):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_ed7c9c22","side":"PARENT","line":319,"updated":"2016-09-14 15:23:02.000000000","message":"Why would you remove this note?","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"87a286b7933c42f7b40fff18ba1be06633e27d95","unresolved":false,"context_lines":[{"line_number":316,"context_line":"        if image.checksum:"},{"line_number":317,"context_line":"            response.headers[\u0027Content-MD5\u0027] \u003d image.checksum"},{"line_number":318,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":319,"context_line":"        # content-length"},{"line_number":320,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(image.size)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def upload(self, response, result):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_0b0237b4","side":"PARENT","line":319,"in_reply_to":"7a8ec9b2_9f2177fe","updated":"2016-09-15 23:41:24.000000000","message":"Done","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"4b5463865f2df9509caec9be74499a994d9d4944","unresolved":false,"context_lines":[{"line_number":316,"context_line":"        if image.checksum:"},{"line_number":317,"context_line":"            response.headers[\u0027Content-MD5\u0027] \u003d image.checksum"},{"line_number":318,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":319,"context_line":"        # content-length"},{"line_number":320,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(image.size)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def upload(self, response, result):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_9f2177fe","side":"PARENT","line":319,"in_reply_to":"7a8ec9b2_ed7c9c22","updated":"2016-09-14 16:34:58.000000000","message":"+1","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d611cc5c952b48f22b2a5d81ff56dbc1e65f38c0","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":319,"context_line":"        # content-length"},{"line_number":320,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(image.size)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def upload(self, response, result):"},{"line_number":323,"context_line":"        response.status_int \u003d 204"},{"line_number":324,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_ad445474","side":"PARENT","line":321,"updated":"2016-09-14 15:23:02.000000000","message":"Maybe we could make the code easier to read by setting \"chunk_size\" to \"image.size\" when the user requested the whole image, and get rid of this if/else.","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"87a286b7933c42f7b40fff18ba1be06633e27d95","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":319,"context_line":"        # content-length"},{"line_number":320,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(image.size)"},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    def upload(self, response, result):"},{"line_number":323,"context_line":"        response.status_int \u003d 204"},{"line_number":324,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_4b9d1fbb","side":"PARENT","line":321,"in_reply_to":"7a8ec9b2_ad445474","updated":"2016-09-15 23:41:24.000000000","message":"Done","commit_id":"34b34a806afd960bc85fdbd1d9cfc49cfa530a78"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"4990b7b2a02ed4d2979738e246fc57b47aa8923b","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_96acf936","line":289,"updated":"2016-09-14 18:50:49.000000000","message":"It is not safe to assume that all 400s coming from store are caused by a bad request Range.\n\nRFC says we SHOULD (not MUST) return a 416 under this condition so safer to leave the response as a 400 if there is no further information used to distinguish the reason for the 400 from store.","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"3fe6bdb00127e930e214a39f27237b41cdd59de3","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_0faa1519","line":289,"in_reply_to":"7a8ec9b2_1190f342","updated":"2016-09-16 18:11:27.000000000","message":"You are correct, I got myself confused on another code path.","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"555ba391adb19f0c370cb39c111356df65219ed3","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_1190f342","line":289,"in_reply_to":"7a8ec9b2_96acf936","updated":"2016-09-14 19:12:23.000000000","message":"Steve, the 400 coming is from wsgi\u0027s get_content_range method.\nIt is a 400 specifically raised for malformed content range with the message and not a generic 400. So I think it is safe to translate it to 416 here.\nPlease correct me if I am wrong.\n\nIncluding the stack trace that shows that:\n\nFile \"glance/common/wsgi.py\", line 781, in get_content_range\n        raise webob.exc.HTTPBadRequest(explanation\u003dmsg)\n    webob.exc.HTTPBadRequest: Malformed Content-Range header: bytes 2-4/3\n\nhttps://github.com/openstack/glance/blob/master/glance/common/wsgi.py#L975","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d611cc5c952b48f22b2a5d81ff56dbc1e65f38c0","unresolved":false,"context_lines":[{"line_number":319,"context_line":"        except exception.Forbidden as e:"},{"line_number":320,"context_line":"            LOG.debug(\"User not permitted to download image \u0027%s\u0027\", image)"},{"line_number":321,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003de.msg)"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"        # NOTE(saschpe): \"response.app_iter \u003d ...\" currently resets Content-MD5"},{"line_number":324,"context_line":"        # (https://github.com/Pylons/webob/issues/86), so it should be set"},{"line_number":325,"context_line":"        # afterwards for the time being."}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_0d7aa824","line":322,"updated":"2016-09-14 15:23:02.000000000","message":"Not needed :)","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"87a286b7933c42f7b40fff18ba1be06633e27d95","unresolved":false,"context_lines":[{"line_number":319,"context_line":"        except exception.Forbidden as e:"},{"line_number":320,"context_line":"            LOG.debug(\"User not permitted to download image \u0027%s\u0027\", image)"},{"line_number":321,"context_line":"            raise webob.exc.HTTPForbidden(explanation\u003de.msg)"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":"        # NOTE(saschpe): \"response.app_iter \u003d ...\" currently resets Content-MD5"},{"line_number":324,"context_line":"        # (https://github.com/Pylons/webob/issues/86), so it should be set"},{"line_number":325,"context_line":"        # afterwards for the time being."}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_ebf8abc5","line":322,"in_reply_to":"7a8ec9b2_0d7aa824","updated":"2016-09-15 23:41:24.000000000","message":"Done","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"a90a35ecb8435f65c7d544d9e987c81d79ed94c3","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_ba2241a1","line":289,"updated":"2016-09-16 18:16:24.000000000","message":"Any particular reason not to fix the implementation of glance.common.wsgi.get_content_range() to raise webob.exc.HTTPRequestRangeNotSatisfiable instead?\n\nThis is the only caller I can find, besides 2 tests for the method.","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"a75bfc6030c5d88805debbc32b7d6de7646d28ba","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_fac20984","line":289,"in_reply_to":"7a8ec9b2_ba2241a1","updated":"2016-09-16 18:22:03.000000000","message":"We can fix it there too Steve. So it would directly return a webob.exc.HTTPRequestRangeNotSatisfiable .\nI however felt I should be sticking to what we want with respect to this code instead of modifying a commonly written method in common/wsgi.py ..","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"67eb66a1a243822fd0f0dc37467811879319b011","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_06403733","line":289,"in_reply_to":"7a8ec9b2_d5b27e4b","updated":"2016-09-16 21:38:22.000000000","message":"I agree with Steve to moving this to wsgi.py","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"7c0fd7541f2afeb61b4b6e7ef1918bd83735f005","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        # HTTPRequestRangeNotSatisfiable and setting status_code"},{"line_number":287,"context_line":"        try:"},{"line_number":288,"context_line":"            range_val \u003d response.request.get_content_range()"},{"line_number":289,"context_line":"        except webob.exc.HTTPBadRequest:"},{"line_number":290,"context_line":"            response.status_int \u003d 416"},{"line_number":291,"context_line":"            raise webob.exc.HTTPRequestRangeNotSatisfiable"},{"line_number":292,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_d5b27e4b","line":289,"in_reply_to":"7a8ec9b2_fac20984","updated":"2016-09-16 18:49:48.000000000","message":"I would strongly prefer we fix the common method but not raising as a -1. The common method is not used anywhere else at this time, so this is a fine time to fix it. \n\nThe change would reduce the lines of code and simplify the solution. Alternatively, do not transform the 400 into a 416.\n\nI am happy to see others weigh in with any counter.","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"9798377da5cbd9f1b6c7e06bd341b55cb6ac5fa5","unresolved":false,"context_lines":[{"line_number":293,"context_line":"        if range_val:"},{"line_number":294,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":295,"context_line":"            # and stop, will be None."},{"line_number":296,"context_line":"            # NOTE(dharinic): if range_val if not None, could either have"},{"line_number":297,"context_line":"            # values for both start and stop, or it would have None for both"},{"line_number":298,"context_line":"            # in case of a request like \u0027bytes: */3\u0027"},{"line_number":299,"context_line":"            if range_val.start is not None:"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_371f51b8","line":296,"range":{"start_line":296,"start_character":43,"end_line":296,"end_character":45},"updated":"2016-09-16 06:23:51.000000000","message":"nit: s/if/is/","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"9798377da5cbd9f1b6c7e06bd341b55cb6ac5fa5","unresolved":false,"context_lines":[{"line_number":314,"context_line":"            response.app_iter \u003d iter(image.get_data(offset\u003doffset,"},{"line_number":315,"context_line":"                                                    chunk_size\u003dchunk_size))"},{"line_number":316,"context_line":"            if range_val:"},{"line_number":317,"context_line":"                response.status_int \u003d 206"},{"line_number":318,"context_line":"            else:"},{"line_number":319,"context_line":"                chunk_size \u003d image.size"},{"line_number":320,"context_line":"        except glance_store.NotFound as e:"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_b7e601ae","line":317,"range":{"start_line":317,"start_character":16,"end_line":317,"end_character":41},"updated":"2016-09-16 06:23:51.000000000","message":"nit: this line can be moved to under line 293","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"9798377da5cbd9f1b6c7e06bd341b55cb6ac5fa5","unresolved":false,"context_lines":[{"line_number":315,"context_line":"                                                    chunk_size\u003dchunk_size))"},{"line_number":316,"context_line":"            if range_val:"},{"line_number":317,"context_line":"                response.status_int \u003d 206"},{"line_number":318,"context_line":"            else:"},{"line_number":319,"context_line":"                chunk_size \u003d image.size"},{"line_number":320,"context_line":"        except glance_store.NotFound as e:"},{"line_number":321,"context_line":"            raise webob.exc.HTTPNoContent(explanation\u003de.msg)"},{"line_number":322,"context_line":"        except glance_store.RemoteServiceUnavailable as e:"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_37fbd148","line":319,"range":{"start_line":318,"start_character":0,"end_line":319,"end_character":39},"updated":"2016-09-16 06:23:51.000000000","message":"nit: these two lines can be moved under line 306","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"92ec920afe77d8c75e54e10d884c5d5dcb7c6c36","unresolved":false,"context_lines":[{"line_number":315,"context_line":"                                                    chunk_size\u003dchunk_size))"},{"line_number":316,"context_line":"            if range_val:"},{"line_number":317,"context_line":"                response.status_int \u003d 206"},{"line_number":318,"context_line":"            else:"},{"line_number":319,"context_line":"                chunk_size \u003d image.size"},{"line_number":320,"context_line":"        except glance_store.NotFound as e:"},{"line_number":321,"context_line":"            raise webob.exc.HTTPNoContent(explanation\u003de.msg)"},{"line_number":322,"context_line":"        except glance_store.RemoteServiceUnavailable as e:"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_6a2712ca","line":319,"range":{"start_line":318,"start_character":0,"end_line":319,"end_character":39},"in_reply_to":"7a8ec9b2_37fbd148","updated":"2016-09-16 15:03:42.000000000","message":"Alex, setting chunk_size here to image.size is to set the content-length. It is when there is no range specified at all and we need to download the entire image.So we set it after the image download happens from line 314.\nWhereas, setting chunk_size to image.size in line 306 is when there exists a range and is of the form \"Bytes */64\" or something.. Both play a different role. \nMoving line 319  after the else statements in line 306 and 307 will cause failure in download as line 314 uses chunk_size to download an image and chunk_size needs to be None for a full image download. \nLet me know if this explanation is not clear.","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"94ad34f3718ad5f3d257e9866012d6caf171f514","unresolved":false,"context_lines":[{"line_number":315,"context_line":"                                                    chunk_size\u003dchunk_size))"},{"line_number":316,"context_line":"            if range_val:"},{"line_number":317,"context_line":"                response.status_int \u003d 206"},{"line_number":318,"context_line":"            else:"},{"line_number":319,"context_line":"                chunk_size \u003d image.size"},{"line_number":320,"context_line":"        except glance_store.NotFound as e:"},{"line_number":321,"context_line":"            raise webob.exc.HTTPNoContent(explanation\u003de.msg)"},{"line_number":322,"context_line":"        except glance_store.RemoteServiceUnavailable as e:"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_7d943e42","line":319,"range":{"start_line":318,"start_character":0,"end_line":319,"end_character":39},"in_reply_to":"7a8ec9b2_6a2712ca","updated":"2016-09-16 15:13:34.000000000","message":"And since this has to be here anyway, I set the status_int here too.","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"aa344d9b8ff6add42b17f386e9ba7c2bb08311d3","unresolved":false,"context_lines":[{"line_number":315,"context_line":"                                                    chunk_size\u003dchunk_size))"},{"line_number":316,"context_line":"            if range_val:"},{"line_number":317,"context_line":"                response.status_int \u003d 206"},{"line_number":318,"context_line":"            else:"},{"line_number":319,"context_line":"                chunk_size \u003d image.size"},{"line_number":320,"context_line":"        except glance_store.NotFound as e:"},{"line_number":321,"context_line":"            raise webob.exc.HTTPNoContent(explanation\u003de.msg)"},{"line_number":322,"context_line":"        except glance_store.RemoteServiceUnavailable as e:"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_ddbb92e3","line":319,"range":{"start_line":318,"start_character":0,"end_line":319,"end_character":39},"in_reply_to":"7a8ec9b2_6a2712ca","updated":"2016-09-16 15:12:28.000000000","message":"I get it now. +1","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"a0463540aaf9536b21a1648591102eed9c1257bd","unresolved":false,"context_lines":[{"line_number":334,"context_line":"            response.headers[\u0027Content-MD5\u0027] \u003d image.checksum"},{"line_number":335,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":336,"context_line":"        # content-length"},{"line_number":337,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(chunk_size)"},{"line_number":338,"context_line":""},{"line_number":339,"context_line":"    def upload(self, response, result):"},{"line_number":340,"context_line":"        response.status_int \u003d 204"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a8ec9b2_c3b641f8","line":337,"range":{"start_line":337,"start_character":45,"end_line":337,"end_character":48},"updated":"2016-09-16 21:37:25.000000000","message":"you can change this to six.text_type","commit_id":"d080d10be24d0953967f5f925026720f8fb06ab8"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":291,"context_line":"            # and stop, will be None."},{"line_number":292,"context_line":"            # NOTE(dharinic): if range_val is not None, could either have"},{"line_number":293,"context_line":"            # values for both start and stop, or it would have None for both in"},{"line_number":294,"context_line":"            # case of a request like \u0027bytes: */3\u0027 (else statement in line 301)"},{"line_number":295,"context_line":"            if range_val.start is not None:"},{"line_number":296,"context_line":"                offset \u003d range_val.start"},{"line_number":297,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7a8ec9b2_06f7578b","line":294,"range":{"start_line":294,"start_character":50,"end_line":294,"end_character":78},"updated":"2016-09-16 22:13:10.000000000","message":"this may get outdated. add note below and link these two notes by an identifier (you can think of a funny identified like \u0027hemanthm007\u0027 that way it\u0027s not a irc nick)","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":299,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"            else:"},{"line_number":302,"context_line":"                chunk_size \u003d image.size"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"            response.status_int \u003d 206"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7a8ec9b2_e6050b46","line":302,"updated":"2016-09-16 22:13:10.000000000","message":"can you add your note about chunk size required to be None for full image download from https://review.openstack.org/#/c/367370/1/glance/api/v2/image_data.py@298 ?\n\n...\n\non second thought, why do we need to set this here?\n\nMay be set it after image.get_data?","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":311,"context_line":"            # an iterator very strange"},{"line_number":312,"context_line":"            response.app_iter \u003d iter(image.get_data(offset\u003doffset,"},{"line_number":313,"context_line":"                                                    chunk_size\u003dchunk_size))"},{"line_number":314,"context_line":"            if not range_val:"},{"line_number":315,"context_line":"                chunk_size \u003d image.size"},{"line_number":316,"context_line":"        except glance_store.NotFound as e:"},{"line_number":317,"context_line":"            raise webob.exc.HTTPNoContent(explanation\u003de.msg)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7a8ec9b2_a66ce308","line":314,"updated":"2016-09-16 22:13:10.000000000","message":"if you change line 302 as per suggestions, this if clause will be:\n\n\n    if not chunk_size:\n        chunk_size \u003d image.size","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":330,"context_line":"            response.headers[\u0027Content-MD5\u0027] \u003d image.checksum"},{"line_number":331,"context_line":"        # NOTE(markwash): \"response.app_iter \u003d ...\" also erroneously resets the"},{"line_number":332,"context_line":"        # content-length"},{"line_number":333,"context_line":"        response.headers[\u0027Content-Length\u0027] \u003d str(chunk_size)"},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"    def upload(self, response, result):"},{"line_number":336,"context_line":"        response.status_int \u003d 204"}],"source_content_type":"text/x-python","patch_set":6,"id":"7a8ec9b2_c6464f7a","line":333,"range":{"start_line":333,"start_character":45,"end_line":333,"end_character":48},"updated":"2016-09-16 22:13:10.000000000","message":"as per my comment from earlier PS, please use six.text_type","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"6f187ba2400f5ad01114226fb68e5275a95fe410","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            if range_val.stop is not None:"},{"line_number":297,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"            response.status_int \u003d 206"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":302,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"fa6399be_8effcba9","line":299,"updated":"2016-10-17 15:14:55.000000000","message":"So we now have \"get_content_range\" on the request object. Would it be possible to also pass it the response object so that helper can set this appropriately in the case where it doesn\u0027t raise that exception?","commit_id":"19ce4055506f475fee3c847f5777f1bfce6e25f3"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"7eaee99fead4e5b3f70f435530fd92426995ab1e","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            if range_val.stop is not None:"},{"line_number":297,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"            response.status_int \u003d 206"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":302,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_761bd71c","line":299,"in_reply_to":"da6895a0_4e21dc4c","updated":"2016-11-22 18:07:27.000000000","message":"Steve, we can definitely refactor lines 291-297. However setting Content-Length can be done only after the image download due to the assignments in line 309,310. This is because the chunk_size needs to be None in case of a full image download..\nIn that case, I am not sure if we really need to have a helping function. Would you still suggest introducing a helping function?\nThanks. :)","commit_id":"19ce4055506f475fee3c847f5777f1bfce6e25f3"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"49ba8f8f775c4ddacb8eeb87fc76d3443ed86898","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            if range_val.stop is not None:"},{"line_number":297,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"            response.status_int \u003d 206"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":302,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"da6895a0_4e21dc4c","line":299,"in_reply_to":"fa6399be_8effcba9","updated":"2016-10-24 20:31:01.000000000","message":"I would generally be against introducing a side effect on an otherwise unneeded param in a function named \"get\". I\u0027m not sure I see value in doing so here.\n\nI do like the idea of factoring lines 291-299 plus setting the Content-Length response header together, possibly in a well named helping function. These two response elements belong together so having them applied close to one another makes the behavior clear and it could improve the readability of the download function.","commit_id":"19ce4055506f475fee3c847f5777f1bfce6e25f3"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"7eaee99fead4e5b3f70f435530fd92426995ab1e","unresolved":false,"context_lines":[{"line_number":296,"context_line":"            if range_val.stop is not None:"},{"line_number":297,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":298,"context_line":""},{"line_number":299,"context_line":"            response.status_int \u003d 206"},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        response.headers[\u0027Content-Type\u0027] \u003d \u0027application/octet-stream\u0027"},{"line_number":302,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_961a3316","line":299,"in_reply_to":"fa6399be_8effcba9","updated":"2016-11-22 18:07:27.000000000","message":"Ian, While we can pass the response object to wsgi.py to the get_content_range() method, I feel it might introduce an unnecessary overhead. Cos, here in line 290, we anyway have to be checking for the presence of a content range response to appropriately set the chunk size. In that case, why not set the status code here without having to introduce additional parameter passing?\nLet me know what you think.\nI am refactoring lines 291-297 as per suggestions. :) Thank you.","commit_id":"19ce4055506f475fee3c847f5777f1bfce6e25f3"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"feba421175c0c3288a8b6d7c56cb8248d701fcff","unresolved":false,"context_lines":[{"line_number":290,"context_line":"        if range_val:"},{"line_number":291,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":292,"context_line":"            # and stop, will be None."},{"line_number":293,"context_line":"            if range_val.start is not None and range_val.stop is not None:"},{"line_number":294,"context_line":"                offset \u003d range_val.start"},{"line_number":295,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"1a6eadb0_f0f11002","line":293,"updated":"2016-12-16 23:13:29.000000000","message":"I agree with Dharini here.","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":18462,"name":"Rahul U Nair","email":"rahulunair@gmail.com","username":"rahulunair"},"change_message_id":"02d5f3947217664ed76121c99571e6e7c97477b2","unresolved":false,"context_lines":[{"line_number":290,"context_line":"        if range_val:"},{"line_number":291,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":292,"context_line":"            # and stop, will be None."},{"line_number":293,"context_line":"            if range_val.start is not None and range_val.stop is not None:"},{"line_number":294,"context_line":"                offset \u003d range_val.start"},{"line_number":295,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a71b18c_a246be4c","line":293,"range":{"start_line":293,"start_character":15,"end_line":293,"end_character":73},"updated":"2016-12-05 18:20:23.000000000","message":"I feel this could be written as all([range_val.start, range_val.stop])","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"9dc56fb759993573b499a9d69c8b35e23219f581","unresolved":false,"context_lines":[{"line_number":290,"context_line":"        if range_val:"},{"line_number":291,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":292,"context_line":"            # and stop, will be None."},{"line_number":293,"context_line":"            if range_val.start is not None and range_val.stop is not None:"},{"line_number":294,"context_line":"                offset \u003d range_val.start"},{"line_number":295,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":296,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a71b18c_7e727a12","line":293,"range":{"start_line":293,"start_character":15,"end_line":293,"end_character":73},"in_reply_to":"3a71b18c_a246be4c","updated":"2016-12-05 21:16:17.000000000","message":"I think we need to keep it less subtle and do a more strong check of \"not None\"","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":18462,"name":"Rahul U Nair","email":"rahulunair@gmail.com","username":"rahulunair"},"change_message_id":"02d5f3947217664ed76121c99571e6e7c97477b2","unresolved":false,"context_lines":[{"line_number":291,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":292,"context_line":"            # and stop, will be None."},{"line_number":293,"context_line":"            if range_val.start is not None and range_val.stop is not None:"},{"line_number":294,"context_line":"                offset \u003d range_val.start"},{"line_number":295,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"            response.status_int \u003d 206"},{"line_number":298,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a71b18c_624ae627","line":295,"range":{"start_line":294,"start_character":7,"end_line":295,"end_character":52},"updated":"2016-12-05 18:20:23.000000000","message":"Didn\u0027t see offset being used anywhere else (may be I missed it), then,\n\nchunk_size \u003d range_val.stop - range_val.start","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"feba421175c0c3288a8b6d7c56cb8248d701fcff","unresolved":false,"context_lines":[{"line_number":292,"context_line":"            # and stop, will be None."},{"line_number":293,"context_line":"            if range_val.start is not None and range_val.stop is not None:"},{"line_number":294,"context_line":"                offset \u003d range_val.start"},{"line_number":295,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"            response.status_int \u003d 206"},{"line_number":298,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"1a6eadb0_10f5aceb","line":295,"updated":"2016-12-16 23:13:29.000000000","message":"Rahul, offset is used below. Please be more thorough","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"9dc56fb759993573b499a9d69c8b35e23219f581","unresolved":false,"context_lines":[{"line_number":291,"context_line":"            # NOTE(flaper87): if not present, both, start"},{"line_number":292,"context_line":"            # and stop, will be None."},{"line_number":293,"context_line":"            if range_val.start is not None and range_val.stop is not None:"},{"line_number":294,"context_line":"                offset \u003d range_val.start"},{"line_number":295,"context_line":"                chunk_size \u003d range_val.stop - offset"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"            response.status_int \u003d 206"},{"line_number":298,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a71b18c_fe0e8a8a","line":295,"range":{"start_line":294,"start_character":7,"end_line":295,"end_character":52},"in_reply_to":"3a71b18c_624ae627","updated":"2016-12-05 21:16:17.000000000","message":"offset is used for the image fetch in line 305. There it uses whatever is stored to appropriately fetch the image (either partly or full)","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"}],"glance/common/wsgi.py":[{"author":{"_account_id":2537,"name":"Nikhil Komawar","email":"nik.komawar@gmail.com","username":"nikhil-komawar"},"change_message_id":"641293ffff8316119609cf05075053dba69fcfed","unresolved":false,"context_lines":[{"line_number":773,"context_line":""},{"line_number":774,"context_line":"    def get_content_range(self):"},{"line_number":775,"context_line":"        \"\"\"Return the `Range` in a request.\"\"\""},{"line_number":776,"context_line":"        range_str \u003d self.headers.get(\u0027Content-Range\u0027)"},{"line_number":777,"context_line":"        if range_str is not None:"},{"line_number":778,"context_line":"            range_ \u003d webob.byterange.ContentRange.parse(range_str)"},{"line_number":779,"context_line":"            if range_ is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"7a8ec9b2_e698ab7a","line":776,"range":{"start_line":776,"start_character":8,"end_line":776,"end_character":53},"updated":"2016-09-16 22:13:10.000000000","message":"we are doing it wrong (most likely)\n\nrequests which do not have an entire body, GET on /file in our case, should not have \"Content-Range\" they need to have \"Range\" header.\n\nI figured as you are fixing stuff around this domain, might as well fix it here?\n\nhttps://tools.ietf.org/html/rfc7233#section-4.2\n\n(see second answer) http://stackoverflow.com/questions/716680/difference-between-content-range-and-range-headers","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"091cf820b254fbac90e5ecf8fade82dccb319ffa","unresolved":false,"context_lines":[{"line_number":773,"context_line":""},{"line_number":774,"context_line":"    def get_content_range(self):"},{"line_number":775,"context_line":"        \"\"\"Return the `Range` in a request.\"\"\""},{"line_number":776,"context_line":"        range_str \u003d self.headers.get(\u0027Content-Range\u0027)"},{"line_number":777,"context_line":"        if range_str is not None:"},{"line_number":778,"context_line":"            range_ \u003d webob.byterange.ContentRange.parse(range_str)"},{"line_number":779,"context_line":"            if range_ is None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a8bc5a2_327a6c25","line":776,"range":{"start_line":776,"start_character":8,"end_line":776,"end_character":53},"in_reply_to":"7a8ec9b2_e698ab7a","updated":"2016-09-22 19:21:16.000000000","message":"Nikhil, You are right. We should be parsing the range header and not Content-Range header. Content-Range is generally sent as a response to the user. (our code currently does not have that facility yet)\nBut comes with that, some issues:\nUnlike Content-Range header\u0027s webob parser, the parser for Range header does not have a way to use the length of the image. Meaning, we have to explicitly pass it. (http://docs.webob.org/en/stable/api/webob.html#webob.byterange.Range.parse)\nie, the webob parser will throw a 416 only if if the format of range request if wrong. Not if a user is requesting 2-4 bytes of a 3 byte image.\nWhich means we have to add that on our checks explicitly.\nAlso, we will have to edit few test cases (apart form the ones I have added with this patch) to suit this change.\nSince this seems to me like a significant change, I wanted to confirm with you and others before I submitted a patch with this change incorporated.\nThanks.","commit_id":"d87aa3ebfd2eace7bf6406bf8f8dc6528635a28b"},{"author":{"_account_id":12807,"name":"Steve Lewis (stevelle)","email":"stevelle@gmail.com","username":"stevelle"},"change_message_id":"49ba8f8f775c4ddacb8eeb87fc76d3443ed86898","unresolved":false,"context_lines":[{"line_number":778,"context_line":"            range_ \u003d webob.byterange.ContentRange.parse(range_str)"},{"line_number":779,"context_line":"            # NOTE(dharinic): Ensure that a range like 1-4/* for an image"},{"line_number":780,"context_line":"            # size of 3 is invalidated."},{"line_number":781,"context_line":"            if range_ is None or (not range_.length and"},{"line_number":782,"context_line":"                                  range_.stop \u003e image_size):"},{"line_number":783,"context_line":"                msg \u003d _(\u0027Malformed Content-Range header: %s\u0027) % range_str"},{"line_number":784,"context_line":"                raise webob.exc.HTTPRequestRangeNotSatisfiable(explanation\u003dmsg)"}],"source_content_type":"text/x-python","patch_set":8,"id":"da6895a0_2eb828e5","line":781,"updated":"2016-10-24 20:31:01.000000000","message":"this may be a bit of a nit but\n\n    not range_.length \n\nis unnecessarily subtle, would be better to simply use a comparison","commit_id":"19ce4055506f475fee3c847f5777f1bfce6e25f3"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"7eaee99fead4e5b3f70f435530fd92426995ab1e","unresolved":false,"context_lines":[{"line_number":778,"context_line":"            range_ \u003d webob.byterange.ContentRange.parse(range_str)"},{"line_number":779,"context_line":"            # NOTE(dharinic): Ensure that a range like 1-4/* for an image"},{"line_number":780,"context_line":"            # size of 3 is invalidated."},{"line_number":781,"context_line":"            if range_ is None or (not range_.length and"},{"line_number":782,"context_line":"                                  range_.stop \u003e image_size):"},{"line_number":783,"context_line":"                msg \u003d _(\u0027Malformed Content-Range header: %s\u0027) % range_str"},{"line_number":784,"context_line":"                raise webob.exc.HTTPRequestRangeNotSatisfiable(explanation\u003dmsg)"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a77a97e_d6fe6b04","line":781,"in_reply_to":"da6895a0_2eb828e5","updated":"2016-11-22 18:07:27.000000000","message":"Done","commit_id":"19ce4055506f475fee3c847f5777f1bfce6e25f3"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"feba421175c0c3288a8b6d7c56cb8248d701fcff","unresolved":false,"context_lines":[{"line_number":779,"context_line":"            # NOTE(dharinic): Ensure that a range like 1-4/* for an image"},{"line_number":780,"context_line":"            # size of 3 is invalidated."},{"line_number":781,"context_line":"            if range_ is None or (range_.length is None and"},{"line_number":782,"context_line":"                                  range_.stop \u003e image_size):"},{"line_number":783,"context_line":"                msg \u003d _(\u0027Malformed Content-Range header: %s\u0027) % range_str"},{"line_number":784,"context_line":"                raise webob.exc.HTTPRequestRangeNotSatisfiable(explanation\u003dmsg)"},{"line_number":785,"context_line":"            return range_"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a6eadb0_d0eed420","line":782,"updated":"2016-12-16 23:13:29.000000000","message":"Rahul, in the future, you could do this research yourself.","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":18462,"name":"Rahul U Nair","email":"rahulunair@gmail.com","username":"rahulunair"},"change_message_id":"02d5f3947217664ed76121c99571e6e7c97477b2","unresolved":false,"context_lines":[{"line_number":777,"context_line":"        if range_str is not None:"},{"line_number":778,"context_line":"            range_ \u003d webob.byterange.ContentRange.parse(range_str)"},{"line_number":779,"context_line":"            # NOTE(dharinic): Ensure that a range like 1-4/* for an image"},{"line_number":780,"context_line":"            # size of 3 is invalidated."},{"line_number":781,"context_line":"            if range_ is None or (range_.length is None and"},{"line_number":782,"context_line":"                                  range_.stop \u003e image_size):"},{"line_number":783,"context_line":"                msg \u003d _(\u0027Malformed Content-Range header: %s\u0027) % range_str"},{"line_number":784,"context_line":"                raise webob.exc.HTTPRequestRangeNotSatisfiable(explanation\u003dmsg)"},{"line_number":785,"context_line":"            return range_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a71b18c_82a8e221","line":782,"range":{"start_line":780,"start_character":1,"end_line":782,"end_character":60},"updated":"2016-12-05 18:20:23.000000000","message":"Two questions here, \n\n- what will be the response is range_.stop is None , for example if something like Range: bytes\u003d0-  is received, I assume that this would be considered valid, as many clients like Firefox, chrome etc have implemented Range this way?\n\n- what will happen if the start range is a invalid, is this automatically handled?","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"9dc56fb759993573b499a9d69c8b35e23219f581","unresolved":false,"context_lines":[{"line_number":777,"context_line":"        if range_str is not None:"},{"line_number":778,"context_line":"            range_ \u003d webob.byterange.ContentRange.parse(range_str)"},{"line_number":779,"context_line":"            # NOTE(dharinic): Ensure that a range like 1-4/* for an image"},{"line_number":780,"context_line":"            # size of 3 is invalidated."},{"line_number":781,"context_line":"            if range_ is None or (range_.length is None and"},{"line_number":782,"context_line":"                                  range_.stop \u003e image_size):"},{"line_number":783,"context_line":"                msg \u003d _(\u0027Malformed Content-Range header: %s\u0027) % range_str"},{"line_number":784,"context_line":"                raise webob.exc.HTTPRequestRangeNotSatisfiable(explanation\u003dmsg)"},{"line_number":785,"context_line":"            return range_"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a71b18c_1eb26694","line":782,"range":{"start_line":780,"start_character":1,"end_line":782,"end_character":60},"in_reply_to":"3a71b18c_82a8e221","updated":"2016-12-05 21:16:17.000000000","message":"Both are taken care of by webob\u0027s byterange. Please see [1]\nThe one case that was not covered there was something like 1-4/* (my Note in line 779), for which I added the additional conditional check. \n\nYou can also refer to the tests here [2] for the exact behaviors accepted and rejected. \n\nLet me know if you have any more questions. :)\n\n[1] http://docs.webob.org/en/stable/api/webob.html#webob.byterange.ContentRange\n[2] https://review.openstack.org/#/c/367528/9/glance/tests/unit/v2/test_image_data_resource.py","commit_id":"400230cd9d72f00caf6c1d5824da906ea335a1ad"}],"glance/tests/functional/v2/test_images.py":[{"author":{"_account_id":22448,"name":"Alexander Bashmakov","email":"abashmak@yahoo.com","username":"abashmak"},"change_message_id":"67df1f56d99493cd94abadb91527d0d6db89eccb","unresolved":false,"context_lines":[{"line_number":768,"context_line":"            headers \u003d self._headers({\u0027Content-Range\u0027: content_range})"},{"line_number":769,"context_line":"            path \u003d self._url(\u0027/v2/images/%s/file\u0027 % image_id)"},{"line_number":770,"context_line":"            response \u003d requests.get(path, headers\u003dheaders)"},{"line_number":771,"context_line":"            self.assertEqual(206, response.status_code)"},{"line_number":772,"context_line":"            result_body +\u003d response.text"},{"line_number":773,"context_line":""},{"line_number":774,"context_line":"        self.assertEqual(result_body, image_data)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_7b74edce","line":771,"range":{"start_line":771,"start_character":12,"end_line":771,"end_character":55},"updated":"2016-09-14 03:55:12.000000000","message":"nit: I know there is a unit test already doing this, but perhaps also check for correct Content-Length here?","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"}],"glance/tests/unit/v2/test_image_data_resource.py":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"d611cc5c952b48f22b2a5d81ff56dbc1e65f38c0","unresolved":false,"context_lines":[{"line_number":571,"context_line":"        self.assertRaises(webob.exc.HTTPNoContent,"},{"line_number":572,"context_line":"                          self.serializer.download,"},{"line_number":573,"context_line":"                          response, image)"},{"line_number":574,"context_line":""},{"line_number":575,"context_line":"    def test_download_with_checksum(self):"},{"line_number":576,"context_line":"        request \u003d wsgi.Request.blank(\u0027/\u0027)"},{"line_number":577,"context_line":"        request.environ \u003d {}"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_b0a58b05","line":574,"updated":"2016-09-14 15:23:02.000000000","message":"We might want to add a test with an invalid range here.","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"},{"author":{"_account_id":21722,"name":"Dharini Chandrasekar","email":"dharini.chandrasekar@intel.com","username":"dharinic"},"change_message_id":"87a286b7933c42f7b40fff18ba1be06633e27d95","unresolved":false,"context_lines":[{"line_number":571,"context_line":"        self.assertRaises(webob.exc.HTTPNoContent,"},{"line_number":572,"context_line":"                          self.serializer.download,"},{"line_number":573,"context_line":"                          response, image)"},{"line_number":574,"context_line":""},{"line_number":575,"context_line":"    def test_download_with_checksum(self):"},{"line_number":576,"context_line":"        request \u003d wsgi.Request.blank(\u0027/\u0027)"},{"line_number":577,"context_line":"        request.environ \u003d {}"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a8ec9b2_cbfbefbf","line":574,"in_reply_to":"7a8ec9b2_b0a58b05","updated":"2016-09-15 23:41:24.000000000","message":"Done","commit_id":"22184109e0a853ef92b24633de1e58042bd6283d"}]}
