Skip to content

Commit

Permalink
[Bugfix][Regression][Server] JPEG output for WMS GetPrint request has…
Browse files Browse the repository at this point in the history
… gone

In QGIS Server 2.* the WMS GetPrint request could genrate JPEG image. QGIS Server 3.4 has lost this capabilities.
```
<ServiceExceptionReport xmlns="http://www.opengis.net/ogc" version="1.3.0" capture-installed="true">
    <ServiceException code="InvalidFormat">
        Output format jpg is not supported by the GetPrint request
    </ServiceException>
</ServiceExceptionReport>
```
To fix this regression, it is necessary to accept JPEG output format.

And to avoid this regression to come back, the QGIS Server tests has been updated to accept jpg image test.
  • Loading branch information
rldhont committed Mar 21, 2019
1 parent 4a9d2d4 commit 8c515f9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 25 deletions.
22 changes: 15 additions & 7 deletions src/server/services/wms/qgswmsgetprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,36 @@ namespace QgsWms
QgsWmsParameters wmsParameters( QUrlQuery( request.url() ) );
QgsRenderer renderer( serverIface, project, wmsParameters );

QString format = params.value( "FORMAT" );
QString format = params.value( QStringLiteral( "FORMAT" ) );
QString contentType;

// GetPrint supports svg/png/pdf
if ( format.compare( QLatin1String( "image/png" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "png" ), Qt::CaseInsensitive ) == 0 )
{
format = "png";
contentType = "image/png";
format = QStringLiteral( "png" );
contentType = QStringLiteral( "image/png" );
}
else if ( format.compare( QLatin1String( "image/jpg" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "image/jpeg" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "jpeg" ), Qt::CaseInsensitive ) == 0 )
{
format = QStringLiteral( "jpg" );
contentType = QStringLiteral( "image/jpeg" );
}
else if ( format.compare( QLatin1String( "image/svg" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "image/svg+xml" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "svg" ), Qt::CaseInsensitive ) == 0 )
{
format = "svg";
contentType = "image/svg+xml";
format = QStringLiteral( "svg" );
contentType = QStringLiteral( "image/svg+xml" );
}
else if ( format.compare( QLatin1String( "application/pdf" ), Qt::CaseInsensitive ) == 0 ||
format.compare( QLatin1String( "pdf" ), Qt::CaseInsensitive ) == 0 )
{
format = "pdf";
contentType = "application/pdf";
format = QStringLiteral( "pdf" );
contentType = QStringLiteral( "application/pdf" );
}
else
{
Expand Down
46 changes: 30 additions & 16 deletions tests/src/python/test_qgsserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,20 @@ def _result(self, data):

return data[1], headers

def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
temp_image = os.path.join(tempfile.gettempdir(), "%s_result.png" % control_image)
def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize(), outputJpg=False):

extFile = 'png'
if outputJpg:
extFile = 'jpg'

temp_image = os.path.join(tempfile.gettempdir(), "%s_result.%s" % (control_image, extFile))

with open(temp_image, "wb") as f:
f.write(image)

if outputJpg:
return (True, "QgsRenderChecker can't be used for JPG images")

control = QgsRenderChecker()
control.setControlPathPrefix("qgis_server")
control.setControlName(control_image)
Expand All @@ -190,35 +198,41 @@ def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
control.setSizeTolerance(max_size_diff.width(), max_size_diff.height())
return control.compareImages(control_image, max_diff), control.report()

def _img_diff_error(self, response, headers, image, max_diff=100, max_size_diff=QSize(), unittest_data_path='control_images'):
def _img_diff_error(self, response, headers, image, max_diff=100, max_size_diff=QSize(), unittest_data_path='control_images', outputJpg=False):

extFile = 'png'
contentType = 'image/png'
if outputJpg:
extFile = 'jpg'
contentType = 'image/jpeg'

reference_path = unitTestDataPath(unittest_data_path) + '/qgis_server/' + image + '/' + image + '.png'
reference_path = unitTestDataPath(unittest_data_path) + '/qgis_server/' + image + '/' + image + '.' + extFile
self.store_reference(reference_path, response)

self.assertEqual(
headers.get("Content-Type"), "image/png",
"Content type is wrong: %s\n%s" % (headers.get("Content-Type"), response))
headers.get("Content-Type"), contentType,
"Content type is wrong: %s instead of %s\n%s" % (headers.get("Content-Type"), contentType, response))

test, report = self._img_diff(response, image, max_diff, max_size_diff)
test, report = self._img_diff(response, image, max_diff, max_size_diff, outputJpg)

with open(os.path.join(tempfile.gettempdir(), image + "_result.png"), "rb") as rendered_file:
with open(os.path.join(tempfile.gettempdir(), image + "_result." + extFile), "rb") as rendered_file:
encoded_rendered_file = base64.b64encode(rendered_file.read())
if not os.environ.get('ENCODED_OUTPUT'):
message = "Image is wrong\: rendered file %s/%s_result.png" % (tempfile.gettempdir(), image)
message = "Image is wrong\: rendered file %s/%s_result.%s" % (tempfile.gettempdir(), image, extFile)
else:
message = "Image is wrong\n%s\nImage:\necho '%s' | base64 -d >%s/%s_result.png" % (
report, encoded_rendered_file.strip().decode('utf8'), tempfile.gettempdir(), image
message = "Image is wrong\n%s\nImage:\necho '%s' | base64 -d >%s/%s_result.%s" % (
report, encoded_rendered_file.strip().decode('utf8'), tempfile.gettempdir(), image, extFile
)

# If the failure is in image sizes the diff file will not exists.
if os.path.exists(os.path.join(tempfile.gettempdir(), image + "_result_diff.png")):
with open(os.path.join(tempfile.gettempdir(), image + "_result_diff.png"), "rb") as diff_file:
if os.path.exists(os.path.join(tempfile.gettempdir(), image + "_result_diff." + extFile)):
with open(os.path.join(tempfile.gettempdir(), image + "_result_diff." + extFile), "rb") as diff_file:
if not os.environ.get('ENCODED_OUTPUT'):
message = "Image is wrong\: diff file %s/%s_result_diff.png" % (tempfile.gettempdir(), image)
message = "Image is wrong\: diff file %s/%s_result_diff.%s" % (tempfile.gettempdir(), image, extFile)
else:
encoded_diff_file = base64.b64encode(diff_file.read())
message += "\nDiff:\necho '%s' | base64 -d > %s/%s_result_diff.png" % (
encoded_diff_file.strip().decode('utf8'), tempfile.gettempdir(), image
message += "\nDiff:\necho '%s' | base64 -d > %s/%s_result_diff.%s" % (
encoded_diff_file.strip().decode('utf8'), tempfile.gettempdir(), image, extFile
)

self.assertTrue(test, message)
Expand Down
9 changes: 7 additions & 2 deletions tests/src/python/test_qgsserver_accesscontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,13 @@ def _post_restricted(self, data, query_string=None):
self._server.putenv("QGIS_PROJECT_FILE", '')
return result

def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
temp_image = os.path.join(tempfile.gettempdir(), "%s_result.png" % control_image)
def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize(), outputJpg=False):

extFile = 'png'
if outputJpg:
extFile = 'jpg'

temp_image = os.path.join(tempfile.gettempdir(), "%s_result.%s" % (control_image, extFile))

with open(temp_image, "wb") as f:
f.write(image)
Expand Down
16 changes: 16 additions & 0 deletions tests/src/python/test_qgsserver_wms_getprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ def test_wms_getprint_basic(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Basic")

# Output JPEG
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "jpeg",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"LAYERS": "Country,Hello",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Basic", outputJpg=True)

def test_wms_getprint_style(self):
# default style
qs = "?" + "&".join(["%s=%s" % i for i in list({
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8c515f9

Please sign in to comment.