added frameworks entities
This commit is contained in:
252
FRAMEWORKS/STPROC/HTTP_PICTURE_SERVICES.txt
Normal file
252
FRAMEWORKS/STPROC/HTTP_PICTURE_SERVICES.txt
Normal file
@ -0,0 +1,252 @@
|
||||
Function HTTP_Picture_Services(RemainingURL)
|
||||
/***********************************************************************************************************************
|
||||
|
||||
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
||||
permission from SRP Computer Solutions, Inc.
|
||||
|
||||
Name : HTTP_Picture_Services
|
||||
|
||||
Description : Handler program for the HTTP Picture service module.
|
||||
|
||||
Notes : All HTTP web services should include the HTTP_SERVICE_SETUP insert. This will provide several useful
|
||||
variables:
|
||||
|
||||
HTTPMethod - The HTTP Method (Verb) submitted by the client (e.g., GET, POST, etc.)
|
||||
APIURL - The URL for the API entry point (e.g., api.mysite.com/v1).
|
||||
SelfURL - The URL path representing the current service.
|
||||
FullEndPointURL - The URL submitted by the client. This can be the same or longer than
|
||||
the SelfURL.
|
||||
NextSegment - The URL segment immediately following the SelfURL (if any). This
|
||||
could contain the name of the next service or it could contain the
|
||||
Item ID for the current service (aka resource).
|
||||
CurrentServiceHandler - The name of this stored procedure.
|
||||
|
||||
Parameters :
|
||||
RemainingURL [in] -- The remaining portion of the URL that follows the URL that launched this current
|
||||
service. This information is used in the HTTP_SERVICE_SETUP insert to populate other
|
||||
useful variables (see Notes above).
|
||||
Response [out] -- Response to be sent back to the Controller (HTTP_MCP) or requesting procedure. Web API
|
||||
services do not rely upon anything being returned in the response. This is what the
|
||||
various services like SetResponseBody and SetResponseStatus services are for. A response
|
||||
value is only helpful if the developers want to use it for debug purposes.
|
||||
|
||||
History : (Date, Initials, Notes)
|
||||
03/27/16 dmb Original programmer. - [SRPFW-96]
|
||||
07/06/17 dmb Refactor using Enhanced BASIC+ syntax. - [SRPFW-184]
|
||||
|
||||
***********************************************************************************************************************/
|
||||
|
||||
#pragma precomp SRP_PreCompiler
|
||||
|
||||
$insert APP_INSERTS
|
||||
$insert HTTP_SERVICE_SETUP
|
||||
$insert HTTP_INSERTS
|
||||
$insert CONTACTS_EQUATES
|
||||
|
||||
// Assume the current HTTP method is valid until proven otherwise.
|
||||
ValidMethod = True$
|
||||
// Assume the current web service is valid until provent otherwise.
|
||||
ValidService = True$
|
||||
// Assume no HTTP methods are valid until proven otherwise.
|
||||
AllowedMethods = ''
|
||||
// A list of all services able to be called from this URL.
|
||||
AllowedServices = ''
|
||||
|
||||
PictureFolder = '\WebAppData\ContactPictures\'
|
||||
|
||||
// Handle the HTTP request as needed.
|
||||
Begin Case
|
||||
Case RemainingURL _EQC ''
|
||||
// This means the URL ends with /contacts/{KeyID}/picture, which means this is the end point.
|
||||
AllowedMethods = 'PUT,GET,OPTIONS'
|
||||
Locate HTTPMethod in AllowedMethods using ',' setting MethodPos then
|
||||
On MethodPos GoSub Put, Get, Options
|
||||
end else
|
||||
ValidMethod = False$
|
||||
end
|
||||
|
||||
Case Otherwise$
|
||||
ValidService = False$
|
||||
End Case
|
||||
|
||||
// Resolve any invalid conditions with the HTTP request.
|
||||
Begin Case
|
||||
Case Not(ValidService)
|
||||
HTTP_Services('SetResponseStatus', 404, NextSegment : ' is not a valid service request within the ' : CurrentServiceHandler : ' module.')
|
||||
|
||||
Case Not(ValidMethod)
|
||||
HTTP_Services('SetResponseStatus', 405, HTTPMethod : ' is not valid for this service.')
|
||||
|
||||
GoSub SetAllowedMethods
|
||||
End Case
|
||||
|
||||
Return Response OR ''
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Service Parameter Options
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Options BOOLEAN = True$, False$
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Web Services
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Put
|
||||
//
|
||||
// Attempts to update the picture resource at this URL end point.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Put:
|
||||
|
||||
NumSegments = DCount(SelfURL, '/')
|
||||
KeyID = Field(SelfURL, '/', NumSegments - 1, 1)
|
||||
TableName = 'CONTACTS'
|
||||
|
||||
Open TableName to hTable then
|
||||
Lock hTable, KeyID then
|
||||
ResponseStatus = 200 ; // Updating an existing resource.
|
||||
Read DataRow from hTable, KeyID else
|
||||
DataRow = ''
|
||||
ResponseStatus = 201 ; // Creating a new resource.
|
||||
end
|
||||
|
||||
// A URI scheme of the Base64 encoded image will be in the Data variable.
|
||||
HTTPPostString = HTTP_Services('GetHTTPPostString')
|
||||
HTTPPostString = HTTP_Services('DecodePercentString', HTTPPostString)
|
||||
Scheme = HTTPPostString[1, 'F:']
|
||||
If Scheme _EQC 'data' then
|
||||
MediaType = HTTPPostString[Col2() + 1, 'F;'] ; // Should be "image/png" or "image/jpg"
|
||||
Encoding = HTTPPostString[Col2() + 1, 'F,'] ; // Should be "base64"
|
||||
EncodedData = HTTPPostString[Col2() + 1, Len(HTTPPostString)] ; // Should be the actual Base64 encoded content.
|
||||
DecodedData = SRP_Decode(EncodedData, 'BASE64')
|
||||
FileType = MediaType[-1, 'B/']
|
||||
FileName = KeyID : '.' : FileType
|
||||
FilePath = Drive() : PictureFolder : FileName
|
||||
Status() = 0
|
||||
OSWrite DecodedData to FilePath
|
||||
StatusCode = Status()
|
||||
If StatusCode then
|
||||
Begin Case
|
||||
Case StatusCode EQ 1 ; Error = 'Bad OS filename. Code: ' : StatusCode
|
||||
Case StatusCode EQ 2 ; Error = 'Access denied by operating system. Code: ' : StatusCode
|
||||
Case StatusCode EQ 3 ; Error = 'Disk or directory full. Code: ' : StatusCode
|
||||
Case StatusCode EQ 4 ; Error = 'File does not exist. Code: ' : StatusCode
|
||||
Case StatusCode EQ 5 ; Error = 'Unknown error. Code: ' : StatusCode
|
||||
Case StatusCode EQ 6 ; Error = 'Attempt to write to read-only file. Code: ' : StatusCode
|
||||
Case Otherwise$ ; Error = 'Unknown error. Code: ' : StatusCode
|
||||
End Case
|
||||
HTTP_Services('SetResponseStatus', '501', Error)
|
||||
end else
|
||||
DataRow<CONTACTS_PICTURE$> = PictureFolder : FileName
|
||||
Write DataRow to hTable, KeyID then
|
||||
HTTP_Services('SetResponseStatus', ResponseStatus)
|
||||
HTTP_Services('SetResponseHeaderField', 'Content-Location', SelfURL)
|
||||
end else
|
||||
HTTP_Services('SetResponseStatus', 500, 'Error writing ' : KeyID : ' to the ' : TableName : ' table.')
|
||||
end
|
||||
end
|
||||
end else
|
||||
HTTP_Services('SetResponseStatus', '415')
|
||||
end
|
||||
Unlock hTable, KeyID else Null
|
||||
end else
|
||||
HTTP_Services('SetResponseStatus', 423, KeyID : ' is currently locked.')
|
||||
end
|
||||
end else
|
||||
HTTP_Services('SetResponseStatus', 500, 'Error opening the ' : TableName : ' table.')
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Get
|
||||
//
|
||||
// Attempts to return the picture resource from this URL end point.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Get:
|
||||
|
||||
// Get the picture's physical file path from the CONTACT database row.
|
||||
NumSegments = DCount(SelfURL, '/')
|
||||
KeyID = Field(SelfURL, '/', NumSegments - 1, 1)
|
||||
PicturePath = Drive() : HTTP_Resource_Services('GetColumnValues', 'CONTACTS', 'picture', KeyID)
|
||||
|
||||
If PicturePath NE '' then
|
||||
// Verify the picture actually exists.
|
||||
If Dir(PicturePath) NE '' then
|
||||
// Get the image extension.
|
||||
ImageExt = PicturePath[-1, 'B.']
|
||||
If ImageExt _EQC 'jpg' then ImageExt = 'jpeg'
|
||||
// Get the best content type that matches the client's and server's ability.
|
||||
ContentType = HTTP_Services('GetBestContentNegotiation', 'Accept', 'text/plain' : @FM : 'image/' : ImageExt)
|
||||
If ContentType NE '' then
|
||||
OSRead PictureBinary from PicturePath then
|
||||
Begin Case
|
||||
Case ContentType _EQC 'text/plain'
|
||||
PictureBody = SRP_Encode(PictureBinary, 'BASE64')
|
||||
PictureBody = 'data:' : 'image/' : ImageExt : ';base64,' : PictureBody
|
||||
HTTP_Services('SetResponseHeaderField', 'Content-Encoding', 'base64')
|
||||
HTTP_Services('SetResponseBody', PictureBody, False$, 'text/plain')
|
||||
|
||||
Case ContentType[1, 6] _EQC 'image/'
|
||||
HTTP_Services('SetResponseBody', PictureBinary, True$, ContentType)
|
||||
|
||||
End Case
|
||||
end
|
||||
end
|
||||
end else
|
||||
HTTP_Services('SetResponseStatus', '404', 'Picture for contact ' : KeyID : ' does not exist.')
|
||||
end
|
||||
end else
|
||||
HTTP_Services('SetResponseStatus', '404', 'Picture for contact ' : KeyID : ' does not exist.')
|
||||
end
|
||||
|
||||
return
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Options
|
||||
//
|
||||
// Sets the appropriate response header fields for an OPTIONS request.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Options:
|
||||
|
||||
GoSub SetCommonOptionResponseHeaders
|
||||
|
||||
return
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Internal GoSubs
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// SetCommonOptionResponseHeaders
|
||||
//
|
||||
// Sets the response headers that will be common for all OPTIONS methods.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
SetCommonOptionResponseHeaders:
|
||||
|
||||
HTTP_Services('SetResponseHeaderField', 'Access-Control-Allow-Headers', 'authorization', True$)
|
||||
HTTP_Services('SetResponseHeaderField', 'Access-Control-Allow-Headers', 'x-authorization', True$)
|
||||
HTTP_Services('SetResponseHeaderField', 'Access-Control-Max-Age', 1728000)
|
||||
|
||||
GoSub SetAllowedMethods
|
||||
|
||||
return
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// SetAllowedMethods
|
||||
//
|
||||
// Sets the Allow response header field as appropriate for the requested URL.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
SetAllowedMethods:
|
||||
|
||||
If AllowedMethods NE '' then
|
||||
For Each Method in AllowedMethods using ','
|
||||
HTTP_Services('SetResponseHeaderField', 'Allow', Method, True$)
|
||||
Next Method
|
||||
end
|
||||
|
||||
return
|
Reference in New Issue
Block a user